From f2a3a9dd2c4491e45a4ed8ed31460e8e288f57cc Mon Sep 17 00:00:00 2001 From: Alexandra Goff Date: Tue, 17 Dec 2024 14:01:45 -0500 Subject: [PATCH] feat: TagList molecule --- components/molecules/TagList/TagList.cy.js | 38 ++++++++++++++ components/molecules/TagList/index.tsx | 49 +++++++++++++++++++ .../molecules/TagList/styles.module.css | 18 +++++++ components/page/Aside/Tags/index.js | 27 ++++------ components/page/Aside/Tags/styles.js | 8 --- 5 files changed, 114 insertions(+), 26 deletions(-) create mode 100644 components/molecules/TagList/TagList.cy.js create mode 100644 components/molecules/TagList/index.tsx create mode 100644 components/molecules/TagList/styles.module.css delete mode 100644 components/page/Aside/Tags/styles.js diff --git a/components/molecules/TagList/TagList.cy.js b/components/molecules/TagList/TagList.cy.js new file mode 100644 index 00000000..7e964be6 --- /dev/null +++ b/components/molecules/TagList/TagList.cy.js @@ -0,0 +1,38 @@ +import TagList from "./index"; + +const tags = [ + { name: "Static Tag" }, + { name: "Linked Tag", destination: "https://rubinobservatory.org" }, +]; + +describe("", () => { + it("should render an unordered list", () => { + cy.mount(); + cy.get("ul").should("exist"); + }); + + it("should render tag names with a pound symbol by default", () => { + cy.mount(); + cy.get("ul > li").each(($el, i) => { + cy.wrap($el).contains(`#${tags[i].name}`); + }); + }); + + it("should omit pound symbol if specified", () => { + cy.mount(); + cy.get("ul > li").each(($el, i) => { + cy.wrap($el).contains(tags[i].name); + }); + }); + + it("should render links if provided", () => { + cy.mount(); + cy.get("ul > li").each(($el, i) => { + if (tags[i].destination) { + cy.wrap($el).children("a").should("exist"); + } else { + cy.wrap($el).children("a").should("not.exist"); + } + }); + }); +}); diff --git a/components/molecules/TagList/index.tsx b/components/molecules/TagList/index.tsx new file mode 100644 index 00000000..edd9204e --- /dev/null +++ b/components/molecules/TagList/index.tsx @@ -0,0 +1,49 @@ +import { FunctionComponent } from "react"; +import classNames from "classnames"; +import Link from "next/link"; +import styles from "./styles.module.css"; + +export type Tag = { + name: string; + destination?: string; +}; +interface TagListProps { + tags: Array; + showPound?: boolean; + withLinebreaks?: boolean; + className?: string; +} + +const TagList: FunctionComponent = ({ + tags = [], + showPound = true, + withLinebreaks = false, + className, +}) => { + return ( +
    + {tags.map(({ name, destination }) => { + const tagName = showPound ? `#${name}` : name; + + return ( +
  • + {destination ? ( + + {tagName} + + ) : ( + tagName + )} +
  • + ); + })} +
+ ); +}; + +TagList.displayName = "Molecule.TagList"; + +export default TagList; diff --git a/components/molecules/TagList/styles.module.css b/components/molecules/TagList/styles.module.css new file mode 100644 index 00000000..9de6fe3f --- /dev/null +++ b/components/molecules/TagList/styles.module.css @@ -0,0 +1,18 @@ +.tagList { + &[data-no-break="true"] { + display: flex; + flex-wrap: wrap; + column-gap: 1ex; + } +} + +.tag { + & a { + color: var(--color-font-accent); + } + + &[data-no-break="true"] { + display: inline-block; + white-space: nowrap; + } +} diff --git a/components/page/Aside/Tags/index.js b/components/page/Aside/Tags/index.js index d32e170f..bbddd3a9 100644 --- a/components/page/Aside/Tags/index.js +++ b/components/page/Aside/Tags/index.js @@ -1,8 +1,7 @@ import PropTypes from "prop-types"; -import Link from "next/link"; import { useTranslation } from "react-i18next"; import AsideSection from "../Section"; -import * as Styled from "./styles"; +import TagList from "@/components/molecules/TagList"; export default function Tags({ tags, rootHomeLink }) { const { t } = useTranslation(); @@ -10,24 +9,16 @@ export default function Tags({ tags, rootHomeLink }) { if (!tags) return null; if (tags.length <= 0) return null; + const tagsWithLinks = tags.map(({ slug, title }) => { + return { + name: title, + destination: `/${rootHomeLink?.uri}?search=${slug}`, + }; + }); + return ( - - {tags.map((tag, i) => { - if (rootHomeLink?.uri && tag.slug) { - return ( - - - {`#${tag.title}`} - - - ); - } - })} - + ); } diff --git a/components/page/Aside/Tags/styles.js b/components/page/Aside/Tags/styles.js deleted file mode 100644 index 83076d0f..00000000 --- a/components/page/Aside/Tags/styles.js +++ /dev/null @@ -1,8 +0,0 @@ -import styled from "styled-components"; - -export const TagList = styled.ul``; - -export const Tag = styled.li` - display: inline-block; - margin-inline-end: 1ch; -`;