From 13f6e862710b71b138b4252c77d525a0917ee3e3 Mon Sep 17 00:00:00 2001 From: Adam Rasheed Date: Tue, 18 Nov 2025 13:56:59 -0800 Subject: [PATCH 1/3] [LG-5747] feat: Card - update styles, deprecate clickability --- .changeset/vast-facts-press.md | 5 +++++ packages/card/src/Card.stories.tsx | 8 +------- packages/card/src/Card/Card.tsx | 12 ++---------- packages/card/src/Card/styles.ts | 16 +++++++--------- packages/card/src/Card/types.ts | 21 +++++++++++++++++++++ 5 files changed, 36 insertions(+), 26 deletions(-) create mode 100644 .changeset/vast-facts-press.md diff --git a/.changeset/vast-facts-press.md b/.changeset/vast-facts-press.md new file mode 100644 index 0000000000..a9771a2af5 --- /dev/null +++ b/.changeset/vast-facts-press.md @@ -0,0 +1,5 @@ +--- +'@leafygreen-ui/card': minor +--- + +deprecated clickable stlying and functionality, updated styles (removed shadows and added border) diff --git a/packages/card/src/Card.stories.tsx b/packages/card/src/Card.stories.tsx index 9ea6962227..0d322e6949 100644 --- a/packages/card/src/Card.stories.tsx +++ b/packages/card/src/Card.stories.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { storybookArgTypes, StoryMetaType } from '@lg-tools/storybook-utils'; import { StoryFn } from '@storybook/react'; -import { Card, CardProps, ContentStyle } from '.'; +import { Card, CardProps } from '.'; const loremIpsum = `Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy children ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.`; @@ -14,7 +14,6 @@ const meta: StoryMetaType = { generate: { combineArgs: { darkMode: [false, true], - contentStyle: ['none', 'clickable'], }, }, }, @@ -27,11 +26,6 @@ const meta: StoryMetaType = { as: storybookArgTypes.as, darkMode: storybookArgTypes.darkMode, children: storybookArgTypes.children, - contentStyle: { - options: Object.values(ContentStyle), - control: { type: 'radio' }, - defaultValue: ContentStyle.None, - }, }, }; export default meta; diff --git a/packages/card/src/Card/Card.tsx b/packages/card/src/Card/Card.tsx index 1ba03a3b05..3ae676d90f 100644 --- a/packages/card/src/Card/Card.tsx +++ b/packages/card/src/Card/Card.tsx @@ -8,7 +8,7 @@ import { useInferredPolymorphic, } from '@leafygreen-ui/polymorphic'; -import { colorSet, containerStyle } from './styles'; +import { getCardStyles } from './styles'; import { ContentStyle, InternalCardProps } from './types'; /** @@ -40,15 +40,7 @@ export const Card = InferredPolymorphic( return ( ); diff --git a/packages/card/src/Card/styles.ts b/packages/card/src/Card/styles.ts index 369207deb0..1bff440184 100644 --- a/packages/card/src/Card/styles.ts +++ b/packages/card/src/Card/styles.ts @@ -24,11 +24,10 @@ const darkHoverBoxShadow = boxShadows[Theme.Dark][2]; const lightFocusBoxShadow = focusRing.light.default; const darkFocusBoxShadow = focusRing.dark.default; -export const colorSet: Record = { +const colorSet: Record = { [Theme.Light]: { containerStyle: css` - border: 1px solid ${palette.gray.light2}; - box-shadow: ${lightBaseBoxShadow}; + border: 1px solid ${palette.gray.light1}; background-color: ${palette.white}; color: ${palette.gray.dark3}; `, @@ -37,7 +36,7 @@ export const colorSet: Record = { &:focus { outline: none; - box-shadow: ${lightFocusBoxShadow}, ${lightBaseBoxShadow}; + box-shadow: ${lightFocusBoxShadow}; } &:hover, @@ -54,7 +53,6 @@ export const colorSet: Record = { [Theme.Dark]: { containerStyle: css` border: 1px solid ${palette.gray.dark2}; - box-shadow: ${darkBaseBoxShadow}; background-color: ${palette.black}; color: ${palette.white}; `, @@ -70,14 +68,14 @@ export const colorSet: Record = { box-shadow: ${darkHoverBoxShadow}; &:focus { - box-shadow: ${darkBaseBoxShadow}, ${darkFocusBoxShadow}; + box-shadow: ${darkBaseBoxShadow}; } } `, }, }; -export const containerStyle = css` +const containerStyle = css` position: relative; transition: ${transitionDuration.default}ms ease-in-out; transition-property: border, box-shadow; @@ -95,13 +93,13 @@ export const getCardStyles = ({ className, }: { theme: Theme; - contentStyle: ContentStyle; + contentStyle?: ContentStyle; className?: string; }) => cx( containerStyle, + colorSet[theme].containerStyle, { - [colorSet[theme].containerStyle]: true, [colorSet[theme].clickableStyle]: contentStyle === ContentStyle.Clickable, }, className, diff --git a/packages/card/src/Card/types.ts b/packages/card/src/Card/types.ts index f3432b2092..c9e8b20370 100644 --- a/packages/card/src/Card/types.ts +++ b/packages/card/src/Card/types.ts @@ -4,11 +4,17 @@ import { PolymorphicAs, } from '@leafygreen-ui/polymorphic'; +/** + * @deprecated No longer supported. We don't want card to be clickable from a root level. + */ export const ContentStyle = { None: 'none', Clickable: 'clickable', } as const; +/** + * @deprecated No longer supported. We don't want card to be clickable from a root level. + */ export type ContentStyle = (typeof ContentStyle)[keyof typeof ContentStyle]; export interface InternalCardProps extends DarkModeProps { @@ -23,6 +29,7 @@ export interface InternalCardProps extends DarkModeProps { * Defaults to `'clickable'` (when a valid `onClick` handler or `href` link is provided * * @default 'clickable' | 'none' + * @deprecated No longer supported. We don't want card to be clickable from a root level. */ contentStyle?: ContentStyle; @@ -31,6 +38,20 @@ export interface InternalCardProps extends DarkModeProps { * */ title?: string; + + /** + * Click handler for the Card component. + * + * @deprecated No longer supported. We don't want card to be clickable from a root level. + */ + onClick?: React.MouseEventHandler; + + /** + * Link for the Card component. + * + * @deprecated No longer supported. We don't want card to be clickable from a root level. + */ + href?: string; } // External only From a6a781e4415ecba001f27e53a6b5a4be6f33280f Mon Sep 17 00:00:00 2001 From: Adam Rasheed Date: Tue, 18 Nov 2025 14:54:46 -0800 Subject: [PATCH 2/3] cleanup --- packages/card/src/Card/styles.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/card/src/Card/styles.ts b/packages/card/src/Card/styles.ts index 1bff440184..1020a7a2a0 100644 --- a/packages/card/src/Card/styles.ts +++ b/packages/card/src/Card/styles.ts @@ -36,7 +36,7 @@ const colorSet: Record = { &:focus { outline: none; - box-shadow: ${lightFocusBoxShadow}; + box-shadow: ${lightFocusBoxShadow}, ${lightBaseBoxShadow}; } &:hover, @@ -68,7 +68,7 @@ const colorSet: Record = { box-shadow: ${darkHoverBoxShadow}; &:focus { - box-shadow: ${darkBaseBoxShadow}; + box-shadow: ${darkBaseBoxShadow}, ${darkFocusBoxShadow}; } } `, From 438ddeada881cbecce8e25d73358a7bed76696cd Mon Sep 17 00:00:00 2001 From: Adam Rasheed Date: Tue, 18 Nov 2025 21:12:07 -0800 Subject: [PATCH 3/3] updated color tokens, updated readme --- .changeset/vast-facts-press.md | 3 +- packages/card/README.md | 29 ++++++++++++++++---- packages/card/src/Card/Card.tsx | 3 +- packages/card/src/Card/styles.ts | 5 ++-- packages/card/src/Card/types.ts | 6 ++-- packages/tokens/src/color/color.types.ts | 1 + packages/tokens/src/color/darkModeColors.ts | 5 ++++ packages/tokens/src/color/lightModeColors.ts | 5 ++++ 8 files changed, 43 insertions(+), 14 deletions(-) diff --git a/.changeset/vast-facts-press.md b/.changeset/vast-facts-press.md index a9771a2af5..f56730de5a 100644 --- a/.changeset/vast-facts-press.md +++ b/.changeset/vast-facts-press.md @@ -1,5 +1,6 @@ --- '@leafygreen-ui/card': minor +'@leafygreen-ui/tokens': minor --- -deprecated clickable stlying and functionality, updated styles (removed shadows and added border) +deprecated clickable styling and functionality, updated styles (removed shadows and added border). Added Tertiary Border color token diff --git a/packages/card/README.md b/packages/card/README.md index adf7f6801a..ee77c4a059 100644 --- a/packages/card/README.md +++ b/packages/card/README.md @@ -38,11 +38,28 @@ import Card from '@leafygreen-ui/card'; Card is a styled wrapper for the Box component. Any properties you would pass to Box can also be passed to Card. -| Prop | Type | Description | Default | -| -------------- | ----------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------------- | -| `children` | `React.ReactNode` | Content rendered inside of the `` component | | -| `className` | `string` | Adds a className to the class attribute | | -| `contentStyle` | `'none'`, `'clickable'` | Whether the card should display as a visually clickable element. | `'clickable'` when a valid `onClick` handler or `href` link is provided | -| `darkMode` | `boolean` | Determines whether or not the component will appear in dark mode. | `false` | +| Prop | Type | Description | Default | +| ----------- | ----------------- | ----------------------------------------------------------------- | ------- | +| `children` | `React.ReactNode` | Content rendered inside of the `` component | | +| `className` | `string` | Adds a className to the class attribute | | +| `darkMode` | `boolean` | Determines whether or not the component will appear in dark mode. | `false` | _Any other properties will be spread on the Box element._ + +## Usage and Interactivity + +This component is designed to be a container for other elements and content. Adding `onClick` or `href` directly to the component is discouraged. Instead, we recommend adding interactive elements inside the component. + +### DON'T + +```js +This is my card component +``` + +### DO + +```js + + + +``` diff --git a/packages/card/src/Card/Card.tsx b/packages/card/src/Card/Card.tsx index 3ae676d90f..b41922e5ee 100644 --- a/packages/card/src/Card/Card.tsx +++ b/packages/card/src/Card/Card.tsx @@ -1,6 +1,5 @@ import React from 'react'; -import { cx } from '@leafygreen-ui/emotion'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; import { InferredPolymorphic, @@ -40,7 +39,7 @@ export const Card = InferredPolymorphic( return ( ); diff --git a/packages/card/src/Card/styles.ts b/packages/card/src/Card/styles.ts index 1020a7a2a0..5b7349db7e 100644 --- a/packages/card/src/Card/styles.ts +++ b/packages/card/src/Card/styles.ts @@ -3,6 +3,7 @@ import { Theme } from '@leafygreen-ui/lib'; import { palette } from '@leafygreen-ui/palette'; import { boxShadows, + color, focusRing, fontFamilies, transitionDuration, @@ -27,7 +28,7 @@ const darkFocusBoxShadow = focusRing.dark.default; const colorSet: Record = { [Theme.Light]: { containerStyle: css` - border: 1px solid ${palette.gray.light1}; + border: 1px solid ${color[Theme.Light].border.tertiary.default}; background-color: ${palette.white}; color: ${palette.gray.dark3}; `, @@ -52,7 +53,7 @@ const colorSet: Record = { }, [Theme.Dark]: { containerStyle: css` - border: 1px solid ${palette.gray.dark2}; + border: 1px solid ${color[Theme.Dark].border.tertiary.default}; background-color: ${palette.black}; color: ${palette.white}; `, diff --git a/packages/card/src/Card/types.ts b/packages/card/src/Card/types.ts index c9e8b20370..897be9610b 100644 --- a/packages/card/src/Card/types.ts +++ b/packages/card/src/Card/types.ts @@ -29,7 +29,7 @@ export interface InternalCardProps extends DarkModeProps { * Defaults to `'clickable'` (when a valid `onClick` handler or `href` link is provided * * @default 'clickable' | 'none' - * @deprecated No longer supported. We don't want card to be clickable from a root level. + * @deprecated No longer supported. We don't want card to be clickable from a root level. Use interactive elements inside the card instead. */ contentStyle?: ContentStyle; @@ -42,14 +42,14 @@ export interface InternalCardProps extends DarkModeProps { /** * Click handler for the Card component. * - * @deprecated No longer supported. We don't want card to be clickable from a root level. + * @deprecated No longer supported. We don't want card to be clickable from a root level. Use interactive elements inside the card instead. */ onClick?: React.MouseEventHandler; /** * Link for the Card component. * - * @deprecated No longer supported. We don't want card to be clickable from a root level. + * @deprecated No longer supported. We don't want card to be clickable from a root level. Use interactive elements inside the card instead. */ href?: string; } diff --git a/packages/tokens/src/color/color.types.ts b/packages/tokens/src/color/color.types.ts index a467cb824c..953cd91ebd 100644 --- a/packages/tokens/src/color/color.types.ts +++ b/packages/tokens/src/color/color.types.ts @@ -17,6 +17,7 @@ const Variant = { Placeholder: 'placeholder', Primary: 'primary', Secondary: 'secondary', + Tertiary: 'tertiary', InversePrimary: 'inversePrimary', InverseSecondary: 'inverseSecondary', Info: 'info', diff --git a/packages/tokens/src/color/darkModeColors.ts b/packages/tokens/src/color/darkModeColors.ts index 5e19231cca..9c43a8d2b3 100644 --- a/packages/tokens/src/color/darkModeColors.ts +++ b/packages/tokens/src/color/darkModeColors.ts @@ -63,6 +63,11 @@ const darkModeBorderColors = { [InteractionState.Hover]: gray.dark2, [InteractionState.Focus]: blue.light1, }, + [Variant.Tertiary]: { + [InteractionState.Default]: gray.dark1, + [InteractionState.Hover]: gray.dark1, + [InteractionState.Focus]: blue.light1, + }, [Variant.Success]: { [InteractionState.Default]: green.dark1, [InteractionState.Hover]: green.dark1, diff --git a/packages/tokens/src/color/lightModeColors.ts b/packages/tokens/src/color/lightModeColors.ts index 3cfc0d48c7..c2fd2c3209 100644 --- a/packages/tokens/src/color/lightModeColors.ts +++ b/packages/tokens/src/color/lightModeColors.ts @@ -63,6 +63,11 @@ const lightModeBorderColors = { [InteractionState.Hover]: gray.light2, [InteractionState.Focus]: blue.light1, }, + [Variant.Tertiary]: { + [InteractionState.Default]: gray.light1, + [InteractionState.Hover]: gray.light1, + [InteractionState.Focus]: blue.light1, + }, [Variant.Success]: { [InteractionState.Default]: green.dark1, [InteractionState.Hover]: green.dark1,