From a5a7e6f761b15fcd36672aa44a32f3651917e7e0 Mon Sep 17 00:00:00 2001 From: Alfred J Lin Date: Wed, 5 Feb 2025 13:47:53 -0500 Subject: [PATCH] create CardOverlay, create links, update storybook settings --- .storybook/UmdLib.js | 3 +- app/globals.css | 12 ++ components/buttons/ButtonPrimary.jsx | 2 +- components/buttons/ButtonSecondary.jsx | 2 +- components/cards/CardOverlay.jsx | 0 components/cards/CardStandard.css | 42 +++++++ components/cards/CardStandard.jsx | 66 ++++++++++ components/cards/CardStandard.mdx | 127 ++++++++++++++++++++ components/cards/CardStandard.stories.jsx | 74 ++++++++++++ components/links/LinkBody.jsx | 25 ++++ components/links/LinkBody.mdx | 42 +++++++ components/links/LinkBody.stories.jsx | 16 +++ components/links/LinkNavigation.jsx | 25 ++++ components/links/LinkNavigation.mdx | 42 +++++++ components/links/LinkNavigation.stories.jsx | 16 +++ components/links/LinkTitle.jsx | 25 ++++ components/links/LinkTitle.mdx | 42 +++++++ components/links/LinkTitle.stories.jsx | 16 +++ 18 files changed, 574 insertions(+), 3 deletions(-) create mode 100644 components/cards/CardOverlay.jsx create mode 100644 components/cards/CardStandard.css create mode 100644 components/cards/CardStandard.jsx create mode 100644 components/cards/CardStandard.mdx create mode 100644 components/cards/CardStandard.stories.jsx create mode 100644 components/links/LinkBody.jsx create mode 100644 components/links/LinkBody.mdx create mode 100644 components/links/LinkBody.stories.jsx create mode 100644 components/links/LinkNavigation.jsx create mode 100644 components/links/LinkNavigation.mdx create mode 100644 components/links/LinkNavigation.stories.jsx create mode 100644 components/links/LinkTitle.jsx create mode 100644 components/links/LinkTitle.mdx create mode 100644 components/links/LinkTitle.stories.jsx diff --git a/.storybook/UmdLib.js b/.storybook/UmdLib.js index 7a567a6..1cd0782 100644 --- a/.storybook/UmdLib.js +++ b/.storybook/UmdLib.js @@ -4,6 +4,7 @@ export default create({ base: "light", brandTitle: "Unversity Libraries", brandUrl: "https://lib.umd.edu", - brandImage: "/lib_logo.svg", + // brandImage: "/lib_logo.svg", + brandImage: "https://www.lib.umd.edu/sites/default/files/2021-06/logo.svg", brandTarget: "_self", }); diff --git a/app/globals.css b/app/globals.css index 2762550..94cf053 100644 --- a/app/globals.css +++ b/app/globals.css @@ -550,3 +550,15 @@ body { padding-right: 7.5rem; } } + +/* defatult element */ +/* a { + color: var(--dark-gray); + text-decoration: underline; + transition: all 0.5s; +} + +a:hover, +a:focus { + color: var(--maryland-red); +} */ diff --git a/components/buttons/ButtonPrimary.jsx b/components/buttons/ButtonPrimary.jsx index 96a9745..c1c2ac6 100644 --- a/components/buttons/ButtonPrimary.jsx +++ b/components/buttons/ButtonPrimary.jsx @@ -6,7 +6,7 @@ const cn = (...classes) => { }; const BASE_BUTTON_CLASSES = - "t-body-small t-interactive-sub button--primary c-content-interactive-primary c-bg-interactive-primary ani-background"; + "button--primary t-body-small t-interactive-sub c-content-interactive-primary c-bg-interactive-primary ani-background"; const ButtonPrimary = forwardRef(({ children, className, ...props }, ref) => { const buttonClasses = cn(BASE_BUTTON_CLASSES, className); diff --git a/components/buttons/ButtonSecondary.jsx b/components/buttons/ButtonSecondary.jsx index b9856f2..5fae261 100644 --- a/components/buttons/ButtonSecondary.jsx +++ b/components/buttons/ButtonSecondary.jsx @@ -6,7 +6,7 @@ const cn = (...classes) => { }; const BASE_BUTTON_CLASSES = - "t-body-small t-interactive-sub button--secondary c-content-primary c-underline-primary ani-underline"; + "button--secondary t-body-small t-interactive-sub c-content-primary c-underline-primary ani-underline"; const ButtonSecondary = forwardRef(({ children, className, ...props }, ref) => { const buttonClasses = cn(BASE_BUTTON_CLASSES, className); diff --git a/components/cards/CardOverlay.jsx b/components/cards/CardOverlay.jsx new file mode 100644 index 0000000..e69de29 diff --git a/components/cards/CardStandard.css b/components/cards/CardStandard.css new file mode 100644 index 0000000..aadf691 --- /dev/null +++ b/components/cards/CardStandard.css @@ -0,0 +1,42 @@ +.card--image img { + aspect-ratio: 5/4; + object-fit: cover; + object-position: center; + width: 100%; + height: 100%; +} + +.card--content { + flex-grow: 1; + + display: flex; + flex-direction: column; +} + +.card--details { + margin-bottom: auto; +} + +.card--title, +a { + width: fit-content; +} + +.card--overlay { + min-height: 334px; + + width: fit-content; + + display: flex; + flex-direction: column; +} + +.card--overlay img { + display: none; +} + +@media (min-width: 768px) { + .card--overlay { + min-height: 456px; + } +} diff --git a/components/cards/CardStandard.jsx b/components/cards/CardStandard.jsx new file mode 100644 index 0000000..3e25dc9 --- /dev/null +++ b/components/cards/CardStandard.jsx @@ -0,0 +1,66 @@ +import React, { forwardRef } from "react"; +import "./CardStandard.css"; + +import ButtonSecondary from "../buttons/ButtonSecondary"; +import LinkTitle from "../links/LinkTitle"; + +const cn = (...classes) => { + return classes.filter(Boolean).join(" "); +}; + +const BASE_CARD_CLASSES = "card-standard"; + +const CardStandard = forwardRef( + ( + { + title, + eyebrow, + description, + date, + link, + variant = "standard", + className, + ...props + }, + ref + ) => { + const cardClasses = cn(BASE_CARD_CLASSES, className); + + return ( +
+
+ Example Image +
+
+
+
+

{eyebrow}

+
+ +

+ {title} + {/* {title} + + {title} + */} +

+
+
+
+

{description}

+
+ +
+ +
+
+ {link} +
+
+ ); + } +); + +CardStandard.displayName = "Card - Standard"; + +export default CardStandard; diff --git a/components/cards/CardStandard.mdx b/components/cards/CardStandard.mdx new file mode 100644 index 0000000..fb128e4 --- /dev/null +++ b/components/cards/CardStandard.mdx @@ -0,0 +1,127 @@ +import { + Meta, + Canvas, + Title, + Subtitle, + Description, + Primary, + Controls, + Stories, + ArgTypes, + Source, +} from "@storybook/blocks"; + +import * as CardStandardStories from "./CardStandard.stories"; + + + + +<Subtitle /> +<Description /> +<Primary /> +<Controls /> + +### Note + +The main difference between standard and overlay cards is whether they have images or not. Here using the CSS to hide the image in overlay card to reduce the difference in twig, but it might have better solution when implementing it. + +### Text Fields + +<table> + <tr> + <td>Field</td> + <td>Requirement</td> + <td>Description</td> + </tr> + <tr> + <td>Eyebrow</td> + <td>Optional</td> + <td>A short description or category.</td> + </tr> + <tr> + <td>Title</td> + <td>Required</td> + <td>The title of the card.</td> + </tr> + <tr> + <td>Description</td> + <td>Optional</td> + <td>A short description of the card.</td> + </tr> + <tr> + <td>Date</td> + <td>Optional</td> + <td>The date of the card.</td> + </tr> + <tr> + <td>CTA</td> + <td>Optional</td> + <td>The text for the call to action button.</td> + </tr> +</table> + +- **Eyebrow**: [Optional] A short description or category. +- **Title**: [Required] The title of the card. +- **Description**: [Required] A short description of the card. +- **Date**: [Optional] The date of the card. +- **CTA Text**: [Optional] The text for the call to action button. + +### Twig + +#### Standard Card + +```twig +{% set classes = [ + 'c-bg-primary', + 'c-content-primary', + 'card--standard', +] %} + +<div{{ attributes.addClass(classes) }} role="contentinfo"> + {% if image %} + <div class="card--image"> + {{ image }} + </div> + {% endif %} + + <div class="card--content s-box-small-v s-box-small-h"> + <div class="card--title"> + {% if eyebrow %} + <div class="card--eyebrow t-eyebrow s-stack-small"> + <p>{{ eyebrow }}</p> + </div> + {% endif %} + + {% if title %} + <h3 class="card--headline t-title-medium c-underline-secondary ani-underline s-stack-default"> + <a href="{{ url }}"> + <span class="sr-only">{{ title }}</span> + <span aria-hidden="true">{{ title }}</span> + </a> + </h3> + {% endif %} + </div> + + <div class="card--details"> + {% if description %} + <div class="card--text t-body-small c-content-secondary s-stack-default"> + <p>{{ description }}</p> + </div> + {% endif %} + + {% if date %} + <div class="card--date t-label c-content-tertiary s-stack-large"> + <time datetime="{{ date|date('Y-m-d') }}">{{ date|date('F j, Y') }}</time> + </div> + {% endif %} + </div> + + {% if cta_text %} + <a href="{{ url }}" class="t-body-small t-interactive-sub button--secondary c-content-primary c-underline-primary ani-underline"> + <div class="i-chevron"></div> + {{ cta_text }} + </a> + {% endif %} + </div> +</div> +``` diff --git a/components/cards/CardStandard.stories.jsx b/components/cards/CardStandard.stories.jsx new file mode 100644 index 0000000..2feaaab --- /dev/null +++ b/components/cards/CardStandard.stories.jsx @@ -0,0 +1,74 @@ +import CardStandard from "./CardStandard"; + +export default { + title: "Component/Cards/Standard", + component: CardStandard, + parameters: { + layout: "centered", + viewport: { + viewports: { + mobile: { + name: "Mobile", + styles: { + width: "390px", + height: "844px", + }, + }, + tablet: { + name: "Tablet", + styles: { + width: "768px", + height: "1024px", + }, + }, + laptop: { + name: "Laptop", + styles: { + width: "1024px", + height: "768px", + }, + }, + desktop: { + name: "Desktop", + styles: { + width: "1680px", + height: "900px", + }, + }, + }, + }, + }, + argTypes: { + title: { + control: "text", + description: "The title in the card", + }, + eyebrow: { + control: "text", + description: "The optional eyebrow above title", + }, + description: { + control: "text", + description: "The content inside the card", + }, + date: { + control: "text", + description: "The optional date information under card description", + }, + link: { + control: "text", + description: "The optional link", + }, + }, +}; + +export const Standard = { + args: { + title: "Digital Collections", + eyebrow: "Optional Tagline", + description: + "Access digitized material, including photographs, archives and manuscripts, film and audio, and more from our specialized collections.", + date: "September 31, 2023", + link: "Explore Digital Collections", + }, +}; diff --git a/components/links/LinkBody.jsx b/components/links/LinkBody.jsx new file mode 100644 index 0000000..9753863 --- /dev/null +++ b/components/links/LinkBody.jsx @@ -0,0 +1,25 @@ +import React, { forwardRef } from "react"; + +// Utility function to merge classnames +const cn = (...classes) => { + return classes.filter(Boolean).join(" "); +}; + +const BASE_LINK_CLASSES = + "link--body c-content-interactive-secondary d-underline t-body-medium"; + +const LinkBody = forwardRef( + ({ children, className, variant = "title", ...props }, ref) => { + const linkClasses = cn(BASE_LINK_CLASSES, className); + + return ( + <a ref={ref} className={linkClasses} {...props}> + {children} + </a> + ); + } +); + +LinkBody.displayName = "Link - Body"; + +export default LinkBody; diff --git a/components/links/LinkBody.mdx b/components/links/LinkBody.mdx new file mode 100644 index 0000000..736c5a1 --- /dev/null +++ b/components/links/LinkBody.mdx @@ -0,0 +1,42 @@ +import { + Meta, + Canvas, + Title, + Subtitle, + Description, + Primary, + Controls, + Stories, + ArgTypes, + Source, +} from "@storybook/blocks"; + +import * as LinkBodyStories from "./LinkBody.stories"; + +<Meta of={LinkBodyStories} /> + +<Title /> +<Subtitle /> +<Description /> +<Primary /> +<Controls /> + +### Note + +Currently, only 3 types of the links are included in the design system, which are: + +- Titlte +- Body +- Navigation + +### Features + +The differences between the three types of links are mainly stylistic, such as color, text decoration, and animation. The typography is interchangeable within each type; for example, a Title link can be used with any title typography. + +### Twig + +#### Body Link + +```twig +<a class="link--body c-content-interactive-secondary d-underline t-body-medium">{{ text }}</a> +``` diff --git a/components/links/LinkBody.stories.jsx b/components/links/LinkBody.stories.jsx new file mode 100644 index 0000000..61263d3 --- /dev/null +++ b/components/links/LinkBody.stories.jsx @@ -0,0 +1,16 @@ +import LinkBody from "./LinkBody"; + +export default { + title: "Component/Links/Body", + component: LinkBody, + parameters: { + layout: "centered", + }, +}; + +// Title Stories +export const Body = { + args: { + children: "This is a body link.", + }, +}; diff --git a/components/links/LinkNavigation.jsx b/components/links/LinkNavigation.jsx new file mode 100644 index 0000000..5deaf5e --- /dev/null +++ b/components/links/LinkNavigation.jsx @@ -0,0 +1,25 @@ +import React, { forwardRef } from "react"; + +// Utility function to merge classnames +const cn = (...classes) => { + return classes.filter(Boolean).join(" "); +}; + +const BASE_LINK_CLASSES = + "link--navigation c-content-interactive-secondary t-interactive"; + +const LinkNavigation = forwardRef( + ({ children, className, variant = "title", ...props }, ref) => { + const linkClasses = cn(BASE_LINK_CLASSES, className); + + return ( + <a ref={ref} className={linkClasses} {...props}> + {children} + </a> + ); + } +); + +LinkNavigation.displayName = "Link - Navigation"; + +export default LinkNavigation; diff --git a/components/links/LinkNavigation.mdx b/components/links/LinkNavigation.mdx new file mode 100644 index 0000000..ec0d7b7 --- /dev/null +++ b/components/links/LinkNavigation.mdx @@ -0,0 +1,42 @@ +import { + Meta, + Canvas, + Title, + Subtitle, + Description, + Primary, + Controls, + Stories, + ArgTypes, + Source, +} from "@storybook/blocks"; + +import * as LinkNavigationStories from "./LinkNavigation.stories"; + +<Meta of={LinkNavigationStories} /> + +<Title /> +<Subtitle /> +<Description /> +<Primary /> +<Controls /> + +### Note + +Currently, only 3 types of the links are included in the design system, which are: + +- Titlte +- Body +- Navigation + +### Features + +The differences between the three types of links are mainly stylistic, such as color, text decoration, and animation. The typography is interchangeable within each type; for example, a Title link can be used with any title typography. + +### Twig + +#### Navigation Link + +```twig +<a class="link--body c-content-interactive-secondary d-underline t-body-medium">{{ text }}</a> +``` diff --git a/components/links/LinkNavigation.stories.jsx b/components/links/LinkNavigation.stories.jsx new file mode 100644 index 0000000..ef21317 --- /dev/null +++ b/components/links/LinkNavigation.stories.jsx @@ -0,0 +1,16 @@ +import LinkNavigation from "./LinkNavigation"; + +export default { + title: "Component/Links/Navigation", + component: LinkNavigation, + parameters: { + layout: "centered", + }, +}; + +// Title Stories +export const Navigation = { + args: { + children: "Find a Space", + }, +}; diff --git a/components/links/LinkTitle.jsx b/components/links/LinkTitle.jsx new file mode 100644 index 0000000..32aeadb --- /dev/null +++ b/components/links/LinkTitle.jsx @@ -0,0 +1,25 @@ +import React, { forwardRef } from "react"; + +// Utility function to merge classnames +const cn = (...classes) => { + return classes.filter(Boolean).join(" "); +}; + +const BASE_LINK_CLASSES = + "link--title c-content-primary c-underline-secondary ani-underline t-title-medium"; + +const LinkTitle = forwardRef( + ({ children, className, variant = "title", ...props }, ref) => { + const linkClasses = cn(BASE_LINK_CLASSES, className); + + return ( + <a ref={ref} className={linkClasses} {...props}> + {children} + </a> + ); + } +); + +LinkTitle.displayName = "Link - Title"; + +export default LinkTitle; diff --git a/components/links/LinkTitle.mdx b/components/links/LinkTitle.mdx new file mode 100644 index 0000000..e1df622 --- /dev/null +++ b/components/links/LinkTitle.mdx @@ -0,0 +1,42 @@ +import { + Meta, + Canvas, + Title, + Subtitle, + Description, + Primary, + Controls, + Stories, + ArgTypes, + Source, +} from "@storybook/blocks"; + +import * as LinkTitleStories from "./LinkTitle.stories"; + +<Meta of={LinkTitleStories} /> + +<Title /> +<Subtitle /> +<Description /> +<Primary /> +<Controls /> + +### Note + +Currently, only 3 types of the links are included in the design system, which are: + +- Titlte +- Body +- Navigation + +### Features + +The differences between the three types of links are mainly stylistic, such as color, text decoration, and animation. The typography is interchangeable within each type; for example, a Title link can be used with any title typography. + +### Twig + +#### Title Link + +```twig +<a class="link--body c-content-interactive-secondary d-underline t-body-medium">{{ text }}</a> +``` diff --git a/components/links/LinkTitle.stories.jsx b/components/links/LinkTitle.stories.jsx new file mode 100644 index 0000000..06d3c4f --- /dev/null +++ b/components/links/LinkTitle.stories.jsx @@ -0,0 +1,16 @@ +import LinkTitle from "./LinkTitle"; + +export default { + title: "Component/Links/Title", + component: LinkTitle, + parameters: { + layout: "centered", + }, +}; + +// Title Stories +export const Title = { + args: { + children: "Digital Collections", + }, +};