From c20d2c97d3da354a25e6ef4994926ad137759a59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20PR=C3=89VOT?= Date: Tue, 22 Aug 2023 19:18:26 +0200 Subject: [PATCH] feat(paper): move elevated Card to dedicated Paper component --- packages/design-tokens/tokens/card.js | 15 -- packages/design-tokens/tokens/paper.js | 39 ++++ packages/fractal/fractal-panda.preset.ts | 5 + .../components/Card/BorderedCard.stories.tsx | 187 ------------------ .../src/components/Card/Card.constants.ts | 12 -- .../src/components/Card/Card.recipe.ts | 32 +-- .../src/components/Card/Card.stories.tsx | 82 +++++--- packages/fractal/src/components/Card/Card.tsx | 11 +- .../fractal/src/components/Card/Card.types.ts | 11 +- .../src/components/Card/FlatCard.stories.tsx | 187 ------------------ .../src/components/Card/HighCard.stories.tsx | 187 ------------------ .../src/components/Card/LowCard.stories.tsx | 187 ------------------ .../src/components/Paper/Paper.constants.ts | 8 + .../fractal/src/components/Paper/Paper.mdx | 37 ++++ .../src/components/Paper/Paper.recipe.ts | 53 +++++ .../src/components/Paper/Paper.stories.tsx | 64 ++++++ .../fractal/src/components/Paper/Paper.tsx | 38 ++++ .../src/components/Paper/Paper.types.ts | 15 ++ .../fractal/src/components/Paper/index.ts | 1 + packages/fractal/src/components/index.ts | 1 + 20 files changed, 328 insertions(+), 844 deletions(-) create mode 100644 packages/design-tokens/tokens/paper.js delete mode 100644 packages/fractal/src/components/Card/BorderedCard.stories.tsx delete mode 100644 packages/fractal/src/components/Card/FlatCard.stories.tsx delete mode 100644 packages/fractal/src/components/Card/HighCard.stories.tsx delete mode 100644 packages/fractal/src/components/Card/LowCard.stories.tsx create mode 100644 packages/fractal/src/components/Paper/Paper.constants.ts create mode 100644 packages/fractal/src/components/Paper/Paper.mdx create mode 100644 packages/fractal/src/components/Paper/Paper.recipe.ts create mode 100644 packages/fractal/src/components/Paper/Paper.stories.tsx create mode 100644 packages/fractal/src/components/Paper/Paper.tsx create mode 100644 packages/fractal/src/components/Paper/Paper.types.ts create mode 100644 packages/fractal/src/components/Paper/index.ts diff --git a/packages/design-tokens/tokens/card.js b/packages/design-tokens/tokens/card.js index 81230b464..5d88e4a90 100644 --- a/packages/design-tokens/tokens/card.js +++ b/packages/design-tokens/tokens/card.js @@ -37,11 +37,6 @@ module.exports = { value: '{color.feedback.warning.90.value}', }, - white: { - comment: 'Background color for white card.', - - value: '{color.base.white.value}', - }, yellow: { comment: 'Background color for yellow card.', @@ -87,11 +82,6 @@ module.exports = { value: '{color.feedback.warning.50.value}', }, - white: { - comment: 'Icon color for white card.', - - value: '{color.text.dark.value}', - }, yellow: { comment: 'Icon color for yellow card.', @@ -144,11 +134,6 @@ module.exports = { value: '{color.text.dark.value}', }, - white: { - comment: 'Text color for white card.', - - value: '{color.text.dark.value}', - }, yellow: { comment: 'Text color for yellow card.', diff --git a/packages/design-tokens/tokens/paper.js b/packages/design-tokens/tokens/paper.js new file mode 100644 index 000000000..cb1e8ba69 --- /dev/null +++ b/packages/design-tokens/tokens/paper.js @@ -0,0 +1,39 @@ +module.exports = { + color: { + background: { + paper: { + comment: 'Background color for paper.', + + value: '{color.base.white.value}', + }, + }, + + text: { + paper: { + body: { + comment: 'Text color for the body of any paper.', + + value: '{color.text.dark.value}', + }, + }, + }, + }, + + size: { + paper: { + padding: { + horizontal: { + comment: 'Horizontal padding for any paper.', + + value: '{size.spacing.2.value}', + }, + + vertical: { + comment: 'Vertical padding for any paper.', + + value: '{size.spacing.2.value}', + }, + }, + }, + }, +} diff --git a/packages/fractal/fractal-panda.preset.ts b/packages/fractal/fractal-panda.preset.ts index fec2ae00d..a521c51d4 100644 --- a/packages/fractal/fractal-panda.preset.ts +++ b/packages/fractal/fractal-panda.preset.ts @@ -22,6 +22,7 @@ import * as InputRadioRecipes from '@/components/InputRadio/InputRadio.recipe' import * as InputTextRecipes from '@/components/InputText/InputText.recipe' import * as LoaderRecipes from '@/components/Loader/Loader.recipe' import * as LogoRecipes from '@/components/Logo/Logo.recipe' +import * as PaperRecipes from '@/components/Paper/Paper.recipe' import * as ProgressRecipes from '@/components/Progress/Progress.recipe' import * as SelectRecipes from '@/components/Select/Select.recipe' import * as StepperRecipes from '@/components/Stepper/Stepper.recipe' @@ -47,6 +48,7 @@ const GROUPS = { inputText: `${PREFIX}-${InputTextRecipes.GROUP_NAME}`, loader: `${PREFIX}-${LoaderRecipes.GROUP_NAME}`, logo: `${PREFIX}-${LogoRecipes.GROUP_NAME}`, + paper: `${PREFIX}-${PaperRecipes.GROUP_NAME}`, progress: `${PREFIX}-${ProgressRecipes.GROUP_NAME}`, select: `${PREFIX}-${SelectRecipes.GROUP_NAME}`, selectTrigger: `${PREFIX}-${SelectRecipes.GROUP_NAME}-trigger`, @@ -112,6 +114,9 @@ const fractalPreset = definePreset({ cardTitle: CardRecipes.cardTitle, cardIcon: CardRecipes.cardIcon, + paper: PaperRecipes.paper, + paperContent: PaperRecipes.paperContent, + header: HeaderRecipes.header, headerLeft: HeaderRecipes.headerLeft, headerMiddle: HeaderRecipes.headerMiddle, diff --git a/packages/fractal/src/components/Card/BorderedCard.stories.tsx b/packages/fractal/src/components/Card/BorderedCard.stories.tsx deleted file mode 100644 index dbdc759a8..000000000 --- a/packages/fractal/src/components/Card/BorderedCard.stories.tsx +++ /dev/null @@ -1,187 +0,0 @@ -import CancelIcon from '@iconscout/react-unicons/dist/icons/uil-cancel' -import CheckCircleIcon from '@iconscout/react-unicons/dist/icons/uil-check-circle' -import StarIcon from '@iconscout/react-unicons/dist/icons/uil-envelope-star' -import ExclamationCircleIcon from '@iconscout/react-unicons/dist/icons/uil-exclamation-circle' -import SendIcon from '@iconscout/react-unicons/dist/icons/uil-message' -import type { Meta, StoryObj } from '@storybook/react' -import type { ComponentProps } from 'react' - -import Card from './Card' -import { Colors, DEFAULT_COLOR, Elevations } from './Card.constants' - -type CardProps = ComponentProps - -const perCardTypesStoriesParameters = { - controls: { - include: ['children', 'dismissable'], - }, -} - -const meta = { - argTypes: { - children: { control: 'text' }, - color: { - options: Object.values(Colors), - table: { - defaultValue: { summary: DEFAULT_COLOR }, - type: { summary: Object.values(Colors).join('|') }, - }, - }, - icon: { - mapping: { - Cancel: , - Check: , - Error: , - None: undefined, - Send: , - Star: , - }, - options: ['None', 'Cancel', 'Check', 'Error', 'Send', 'Star'], - }, - }, - args: { - children: - 'Size matters not. Look at me. Judge me by my size, do you? Hmm? Hmm. And well you should not. For my ally is the Force, and a powerful ally it is. Life creates it, makes it grow. Its energy surrounds us and binds us. Luminous beings are we, not this crude matter. You must feel the Force around you; here, between you, me, the tree, the rock, everywhere, yes. Even between the land and the ship.', - dismissable: false, - elevation: Elevations.Bordered, - icon: 'None', - title: '', - }, - component: Card, - parameters: { - componentSubtitle: `🐠 Let's play the "Let's Not Die" card - Marin - Finding Nemo`, - controls: { - exclude: ['elevation'], - }, - }, - - title: 'Molecules/Card/Bordered', -} satisfies Meta - -export default meta -type Story = StoryObj - -export const Playground: Story = { - args: { - color: DEFAULT_COLOR, - }, -} - -export const BasicCards: Story = { - parameters: { - ...perCardTypesStoriesParameters, - controls: { - ...perCardTypesStoriesParameters.controls, - include: [ - ...perCardTypesStoriesParameters.controls.include, - 'icon', - 'title', - ], - }, - }, - render: ({ children, dismissable = false, icon, title = '' }) => ( -
- - {children} - - - {children} - - - {children} - - - {children} - - - {children} - - - {children} - -
- ), -} - -export const FeedbackCards: Story = { - parameters: { ...perCardTypesStoriesParameters }, - render: ({ children, dismissable = false }) => ( -
- } - title="Oops, there have been an error" - > - {children} - - } - title="Be careful!" - > - {children} - - } - title="Congratulations" - > - {children} - -
- ), -} diff --git a/packages/fractal/src/components/Card/Card.constants.ts b/packages/fractal/src/components/Card/Card.constants.ts index c86ba267a..0b0285ed4 100644 --- a/packages/fractal/src/components/Card/Card.constants.ts +++ b/packages/fractal/src/components/Card/Card.constants.ts @@ -6,19 +6,7 @@ export enum Colors { Purple = 'purple', Success = 'success', Warning = 'warning', - White = 'white', Yellow = 'yellow', } export const DEFAULT_COLOR = Colors.Pink - -export enum Elevations { - /* eslint-disable perfectionist/sort-enums */ - Flat = '0', - Bordered = '1', - Low = '2', - High = '3', - /* eslint-enable perfectionist/sort-enums */ -} - -export const DEFAULT_ELEVATION = Elevations.Flat diff --git a/packages/fractal/src/components/Card/Card.recipe.ts b/packages/fractal/src/components/Card/Card.recipe.ts index 1cb320f3a..a62cee585 100644 --- a/packages/fractal/src/components/Card/Card.recipe.ts +++ b/packages/fractal/src/components/Card/Card.recipe.ts @@ -1,12 +1,7 @@ import { defineRecipe } from '@pandacss/dev' import type { SystemStyleObject } from '@snowball-tech/fractal-panda/types' -import { - Colors, - DEFAULT_COLOR, - DEFAULT_ELEVATION, - Elevations, -} from './Card.constants' +import { Colors, DEFAULT_COLOR } from './Card.constants' export const GROUP_NAME = 'card' @@ -29,7 +24,6 @@ export const card: ReturnType = defineRecipe({ defaultVariants: { color: DEFAULT_COLOR, - elevation: DEFAULT_ELEVATION, }, variants: { @@ -43,30 +37,6 @@ export const card: ReturnType = defineRecipe({ }), {} as Record, ), - - elevation: { - [Elevations.Flat]: { - border: 'var(--border-none)', - boxShadow: 'var(--shadow-none)', - }, - // eslint-disable-next-line sort-keys, sort-keys/sort-keys-fix, perfectionist/sort-objects - [Elevations.Bordered]: { - border: 'var(--border-1)', - borderRadius: 'var(--size-radius-s)', - boxShadow: 'var(--shadow-none)', - }, - [Elevations.Low]: { - border: 'var(--border-1)', - borderRadius: 'var(--size-radius-s)', - boxShadow: 'var(--shadow-brutal-1)', - }, - // eslint-disable-next-line sort-keys, sort-keys/sort-keys-fix, perfectionist/sort-objects - [Elevations.High]: { - border: 'var(--border-2)', - borderRadius: 'var(--size-radius-s)', - boxShadow: 'var(--shadow-brutal-2)', - }, - }, }, // eslint-disable-next-line sort-keys, sort-keys/sort-keys-fix, perfectionist/sort-objects diff --git a/packages/fractal/src/components/Card/Card.stories.tsx b/packages/fractal/src/components/Card/Card.stories.tsx index 9c93c1893..5595139aa 100644 --- a/packages/fractal/src/components/Card/Card.stories.tsx +++ b/packages/fractal/src/components/Card/Card.stories.tsx @@ -7,15 +7,16 @@ import type { Meta, StoryObj } from '@storybook/react' import type { ComponentProps } from 'react' import Card from './Card' -import { - Colors, - DEFAULT_COLOR, - DEFAULT_ELEVATION, - Elevations, -} from './Card.constants' +import { Colors, DEFAULT_COLOR } from './Card.constants' type CardProps = ComponentProps +const perCardTypesStoriesParameters = { + controls: { + include: ['children', 'dismissable', 'icon', 'title'], + }, +} + const meta = { argTypes: { children: { control: 'text' }, @@ -26,22 +27,6 @@ const meta = { type: { summary: Object.values(Colors).join('|') }, }, }, - elevation: { - control: 'select', - mapping: { - Flat: Elevations.Flat, - // eslint-disable-next-line sort-keys, sort-keys/sort-keys-fix, perfectionist/sort-objects - Bordered: Elevations.Bordered, - Low: Elevations.Low, - // eslint-disable-next-line sort-keys, sort-keys/sort-keys-fix, perfectionist/sort-objects - High: Elevations.High, - }, - options: ['Flat', 'Bordered', 'Low', 'High'], - table: { - defaultValue: { summary: DEFAULT_ELEVATION }, - type: { summary: Object.values(Elevations).join('|') }, - }, - }, icon: { mapping: { Cancel: , @@ -75,6 +60,57 @@ type Story = StoryObj export const Playground: Story = { args: { color: DEFAULT_COLOR, - elevation: DEFAULT_ELEVATION, }, } + +export const BasicCards: Story = { + parameters: { ...perCardTypesStoriesParameters }, + render: ({ children, dismissable = false, icon, title = '' }) => ( +
+ + {children} + + + {children} + + + {children} + + + {children} + + + {children} + +
+ ), +} + +export const FeedbackCards: Story = { + parameters: { ...perCardTypesStoriesParameters }, + render: ({ children, dismissable = false, icon, title = '' }) => ( +
+ + {children} + + + {children} + + + {children} + +
+ ), +} diff --git a/packages/fractal/src/components/Card/Card.tsx b/packages/fractal/src/components/Card/Card.tsx index 56e4797b2..389811051 100644 --- a/packages/fractal/src/components/Card/Card.tsx +++ b/packages/fractal/src/components/Card/Card.tsx @@ -16,19 +16,20 @@ import omit from 'lodash/fp/omit' import { Button } from '@/components/Button' import { PREFIX } from '@/constants' -import { DEFAULT_COLOR, DEFAULT_ELEVATION } from './Card.constants' +import { DEFAULT_COLOR } from './Card.constants' import { GROUP_NAME } from './Card.recipe' import type { CardProps } from './Card.types' /** - * `Card` component allow to build interface with level and hierarchy. - * experience. + * `Card` component allow to build nice interface by offering user colored + * blocks of contents. + * + * It's also useful for feedback and hierarchization of the content. */ export const Card = ({ children, color = DEFAULT_COLOR, dismissable = false, - elevation = DEFAULT_ELEVATION, icon, onDismiss, title, @@ -36,7 +37,7 @@ export const Card = ({ }: CardProps) => { const groupClassNames = cx( `${PREFIX}-${GROUP_NAME}`, - card({ color, elevation }), + card({ color }), props.className, dismissable ? 'dismissable' : '', typography({ variant: 'body-1' }), diff --git a/packages/fractal/src/components/Card/Card.types.ts b/packages/fractal/src/components/Card/Card.types.ts index 00ab79087..a2b169b8c 100644 --- a/packages/fractal/src/components/Card/Card.types.ts +++ b/packages/fractal/src/components/Card/Card.types.ts @@ -1,6 +1,6 @@ import type { AllHTMLAttributes, ReactNode } from 'react' -import { Colors, Elevations } from './Card.constants' +import { Colors } from './Card.constants' export interface CardProps extends AllHTMLAttributes { /** The content of the card. */ @@ -9,15 +9,6 @@ export interface CardProps extends AllHTMLAttributes { color?: `${Colors}` /** Indicates if we can dismiss the card. */ dismissable?: boolean - /** - * The elevation level of the card. - * - * 0 (flat) is a non elevated flat card - * 1 (bordered) is a non elevated bordered card - * 2 (low) is a lightly raised (small shadow) bordered card - * 3 (high) is a highly raised (big shadow) heavily bordered card - */ - elevation?: `${Elevations}` /** * An icon to display at the top of the card (to the left of the title if * there is one). diff --git a/packages/fractal/src/components/Card/FlatCard.stories.tsx b/packages/fractal/src/components/Card/FlatCard.stories.tsx deleted file mode 100644 index 6458038b8..000000000 --- a/packages/fractal/src/components/Card/FlatCard.stories.tsx +++ /dev/null @@ -1,187 +0,0 @@ -import CancelIcon from '@iconscout/react-unicons/dist/icons/uil-cancel' -import CheckCircleIcon from '@iconscout/react-unicons/dist/icons/uil-check-circle' -import StarIcon from '@iconscout/react-unicons/dist/icons/uil-envelope-star' -import ExclamationCircleIcon from '@iconscout/react-unicons/dist/icons/uil-exclamation-circle' -import SendIcon from '@iconscout/react-unicons/dist/icons/uil-message' -import type { Meta, StoryObj } from '@storybook/react' -import type { ComponentProps } from 'react' - -import Card from './Card' -import { Colors, DEFAULT_COLOR, DEFAULT_ELEVATION } from './Card.constants' - -type CardProps = ComponentProps - -const perCardTypesStoriesParameters = { - controls: { - include: ['children', 'dismissable'], - }, -} - -const meta = { - argTypes: { - children: { control: 'text' }, - color: { - options: Object.values(Colors), - table: { - defaultValue: { summary: DEFAULT_COLOR }, - type: { summary: Object.values(Colors).join('|') }, - }, - }, - icon: { - mapping: { - Cancel: , - Check: , - Error: , - None: undefined, - Send: , - Star: , - }, - options: ['None', 'Cancel', 'Check', 'Error', 'Send', 'Star'], - }, - }, - args: { - children: - 'Size matters not. Look at me. Judge me by my size, do you? Hmm? Hmm. And well you should not. For my ally is the Force, and a powerful ally it is. Life creates it, makes it grow. Its energy surrounds us and binds us. Luminous beings are we, not this crude matter. You must feel the Force around you; here, between you, me, the tree, the rock, everywhere, yes. Even between the land and the ship.', - dismissable: false, - elevation: DEFAULT_ELEVATION, - icon: 'None', - title: '', - }, - component: Card, - parameters: { - componentSubtitle: `🐠 Let's play the "Let's Not Die" card - Marin - Finding Nemo`, - controls: { - exclude: ['elevation'], - }, - }, - - title: 'Molecules/Card/Flat', -} satisfies Meta - -export default meta -type Story = StoryObj - -export const Playground: Story = { - args: { - color: DEFAULT_COLOR, - }, -} - -export const BasicCards: Story = { - parameters: { - ...perCardTypesStoriesParameters, - controls: { - ...perCardTypesStoriesParameters.controls, - include: [ - ...perCardTypesStoriesParameters.controls.include, - 'icon', - 'title', - ], - }, - }, - render: ({ children, dismissable = false, icon, title = '' }) => ( -
- - {children} - - - {children} - - - {children} - - - {children} - - - {children} - - - {children} - -
- ), -} - -export const FeedbackCards: Story = { - parameters: { ...perCardTypesStoriesParameters }, - render: ({ children, dismissable = false }) => ( -
- } - title="Oops, there have been an error" - > - {children} - - } - title="Be careful!" - > - {children} - - } - title="Congratulations" - > - {children} - -
- ), -} diff --git a/packages/fractal/src/components/Card/HighCard.stories.tsx b/packages/fractal/src/components/Card/HighCard.stories.tsx deleted file mode 100644 index e1de20fe9..000000000 --- a/packages/fractal/src/components/Card/HighCard.stories.tsx +++ /dev/null @@ -1,187 +0,0 @@ -import CancelIcon from '@iconscout/react-unicons/dist/icons/uil-cancel' -import CheckCircleIcon from '@iconscout/react-unicons/dist/icons/uil-check-circle' -import StarIcon from '@iconscout/react-unicons/dist/icons/uil-envelope-star' -import ExclamationCircleIcon from '@iconscout/react-unicons/dist/icons/uil-exclamation-circle' -import SendIcon from '@iconscout/react-unicons/dist/icons/uil-message' -import type { Meta, StoryObj } from '@storybook/react' -import type { ComponentProps } from 'react' - -import Card from './Card' -import { Colors, DEFAULT_COLOR, Elevations } from './Card.constants' - -type CardProps = ComponentProps - -const perCardTypesStoriesParameters = { - controls: { - include: ['children', 'dismissable'], - }, -} - -const meta = { - argTypes: { - children: { control: 'text' }, - color: { - options: Object.values(Colors), - table: { - defaultValue: { summary: DEFAULT_COLOR }, - type: { summary: Object.values(Colors).join('|') }, - }, - }, - icon: { - mapping: { - Cancel: , - Check: , - Error: , - None: undefined, - Send: , - Star: , - }, - options: ['None', 'Cancel', 'Check', 'Error', 'Send', 'Star'], - }, - }, - args: { - children: - 'Size matters not. Look at me. Judge me by my size, do you? Hmm? Hmm. And well you should not. For my ally is the Force, and a powerful ally it is. Life creates it, makes it grow. Its energy surrounds us and binds us. Luminous beings are we, not this crude matter. You must feel the Force around you; here, between you, me, the tree, the rock, everywhere, yes. Even between the land and the ship.', - dismissable: false, - elevation: Elevations.High, - icon: 'None', - title: '', - }, - component: Card, - parameters: { - componentSubtitle: `🐠 Let's play the "Let's Not Die" card - Marin - Finding Nemo`, - controls: { - exclude: ['elevation'], - }, - }, - - title: 'Molecules/Card/High', -} satisfies Meta - -export default meta -type Story = StoryObj - -export const HiPlayground: Story = { - args: { - color: DEFAULT_COLOR, - }, -} - -export const BasicCards: Story = { - parameters: { - ...perCardTypesStoriesParameters, - controls: { - ...perCardTypesStoriesParameters.controls, - include: [ - ...perCardTypesStoriesParameters.controls.include, - 'icon', - 'title', - ], - }, - }, - render: ({ children, dismissable = false, icon, title = '' }) => ( -
- - {children} - - - {children} - - - {children} - - - {children} - - - {children} - - - {children} - -
- ), -} - -export const FeedbackCards: Story = { - parameters: { ...perCardTypesStoriesParameters }, - render: ({ children, dismissable = false }) => ( -
- } - title="Oops, there have been an error" - > - {children} - - } - title="Be careful!" - > - {children} - - } - title="Congratulations" - > - {children} - -
- ), -} diff --git a/packages/fractal/src/components/Card/LowCard.stories.tsx b/packages/fractal/src/components/Card/LowCard.stories.tsx deleted file mode 100644 index e538a4099..000000000 --- a/packages/fractal/src/components/Card/LowCard.stories.tsx +++ /dev/null @@ -1,187 +0,0 @@ -import CancelIcon from '@iconscout/react-unicons/dist/icons/uil-cancel' -import CheckCircleIcon from '@iconscout/react-unicons/dist/icons/uil-check-circle' -import StarIcon from '@iconscout/react-unicons/dist/icons/uil-envelope-star' -import ExclamationCircleIcon from '@iconscout/react-unicons/dist/icons/uil-exclamation-circle' -import SendIcon from '@iconscout/react-unicons/dist/icons/uil-message' -import type { Meta, StoryObj } from '@storybook/react' -import type { ComponentProps } from 'react' - -import Card from './Card' -import { Colors, DEFAULT_COLOR, Elevations } from './Card.constants' - -type CardProps = ComponentProps - -const perCardTypesStoriesParameters = { - controls: { - include: ['children', 'dismissable'], - }, -} - -const meta = { - argTypes: { - children: { control: 'text' }, - color: { - options: Object.values(Colors), - table: { - defaultValue: { summary: DEFAULT_COLOR }, - type: { summary: Object.values(Colors).join('|') }, - }, - }, - icon: { - mapping: { - Cancel: , - Check: , - Error: , - None: undefined, - Send: , - Star: , - }, - options: ['None', 'Cancel', 'Check', 'Error', 'Send', 'Star'], - }, - }, - args: { - children: - 'Size matters not. Look at me. Judge me by my size, do you? Hmm? Hmm. And well you should not. For my ally is the Force, and a powerful ally it is. Life creates it, makes it grow. Its energy surrounds us and binds us. Luminous beings are we, not this crude matter. You must feel the Force around you; here, between you, me, the tree, the rock, everywhere, yes. Even between the land and the ship.', - dismissable: false, - elevation: Elevations.Low, - icon: 'None', - title: '', - }, - component: Card, - parameters: { - componentSubtitle: `🐠 Let's play the "Let's Not Die" card - Marin - Finding Nemo`, - controls: { - exclude: ['elevation'], - }, - }, - - title: 'Molecules/Card/Low', -} satisfies Meta - -export default meta -type Story = StoryObj - -export const Playground: Story = { - args: { - color: DEFAULT_COLOR, - }, -} - -export const BasicCards: Story = { - parameters: { - ...perCardTypesStoriesParameters, - controls: { - ...perCardTypesStoriesParameters.controls, - include: [ - ...perCardTypesStoriesParameters.controls.include, - 'icon', - 'title', - ], - }, - }, - render: ({ children, dismissable = false, icon, title = '' }) => ( -
- - {children} - - - {children} - - - {children} - - - {children} - - - {children} - - - {children} - -
- ), -} - -export const FeedbackCards: Story = { - parameters: { ...perCardTypesStoriesParameters }, - render: ({ children, dismissable = false }) => ( -
- } - title="Oops, there have been an error" - > - {children} - - } - title="Be careful!" - > - {children} - - } - title="Congratulations" - > - {children} - -
- ), -} diff --git a/packages/fractal/src/components/Paper/Paper.constants.ts b/packages/fractal/src/components/Paper/Paper.constants.ts new file mode 100644 index 000000000..7661e505d --- /dev/null +++ b/packages/fractal/src/components/Paper/Paper.constants.ts @@ -0,0 +1,8 @@ +export enum Elevations { + /* eslint-disable perfectionist/sort-enums */ + Bordered = '1', + Elevated = '2', + /* eslint-enable perfectionist/sort-enums */ +} + +export const DEFAULT_ELEVATION = Elevations.Bordered diff --git a/packages/fractal/src/components/Paper/Paper.mdx b/packages/fractal/src/components/Paper/Paper.mdx new file mode 100644 index 000000000..d73e0b9ac --- /dev/null +++ b/packages/fractal/src/components/Paper/Paper.mdx @@ -0,0 +1,37 @@ +import { + ArgTypes, + Controls, + Description, + Meta, + Primary, + Stories, + Subtitle, + Title, +} from '@storybook/blocks' + +import * as PaperStories from './Paper.stories' + + + + + +<Subtitle /> + +<Description /> + +--- + +## Props + +On top of all the props, attributes and event handler you can set on a +`<div />` element, component accepts the following props: + +<ArgTypes /> + +<Stories includePrimary={false} title="Papers" /> + +## Playground + +<Primary /> + +<Controls /> diff --git a/packages/fractal/src/components/Paper/Paper.recipe.ts b/packages/fractal/src/components/Paper/Paper.recipe.ts new file mode 100644 index 000000000..2a0342fae --- /dev/null +++ b/packages/fractal/src/components/Paper/Paper.recipe.ts @@ -0,0 +1,53 @@ +import { defineRecipe } from '@pandacss/dev' + +import { DEFAULT_ELEVATION, Elevations } from './Paper.constants' + +export const GROUP_NAME = 'paper' + +export const paper: ReturnType<typeof defineRecipe> = defineRecipe({ + base: { + backgroundColor: 'var(--color-background-paper)', + borderRadius: 'var(--size-radius-s)', + boxSizing: 'border-box', + color: 'var(--color-text-paper-body)', + display: 'flex', + flexDirection: 'column', + gap: 'var(--size-paper-gap)', + position: 'relative', + px: 'var(--size-paper-padding-horizontal)', + py: 'var(--size-paper-padding-vertical)', + }, + + defaultVariants: { + elevation: DEFAULT_ELEVATION, + }, + + variants: { + elevation: { + [Elevations.Bordered]: { + border: 'var(--border-1)', + borderRadius: 'var(--size-radius-s)', + boxShadow: 'var(--shadow-none)', + }, + [Elevations.Elevated]: { + border: 'var(--border-1)', + borderRadius: 'var(--size-radius-s)', + boxShadow: 'var(--shadow-brutal-1)', + }, + }, + }, + + // eslint-disable-next-line sort-keys, sort-keys/sort-keys-fix, perfectionist/sort-objects + className: 'paper', + description: 'Paper', + jsx: ['Paper'], +}) + +export const paperContent: ReturnType<typeof defineRecipe> = defineRecipe({ + base: {}, + + // eslint-disable-next-line sort-keys, sort-keys/sort-keys-fix, perfectionist/sort-objects + className: 'paperContent', + description: 'Paper content', + jsx: ['Paper'], +}) diff --git a/packages/fractal/src/components/Paper/Paper.stories.tsx b/packages/fractal/src/components/Paper/Paper.stories.tsx new file mode 100644 index 000000000..3a465829c --- /dev/null +++ b/packages/fractal/src/components/Paper/Paper.stories.tsx @@ -0,0 +1,64 @@ +import type { Meta, StoryObj } from '@storybook/react' +import type { ComponentProps } from 'react' + +import Paper from './Paper' +import { DEFAULT_ELEVATION, Elevations } from './Paper.constants' + +type PaperProps = ComponentProps<typeof Paper> + +const meta = { + argTypes: { + children: { control: 'text' }, + elevation: { + control: 'radio', + mapping: { + Bordered: Elevations.Bordered, + Elevated: Elevations.Elevated, + }, + options: ['Bordered', 'Elevated'], + table: { + defaultValue: { summary: DEFAULT_ELEVATION }, + type: { summary: Object.values(Elevations).join('|') }, + }, + }, + }, + args: { + children: + 'Size matters not. Look at me. Judge me by my size, do you? Hmm? Hmm. And well you should not. For my ally is the Force, and a powerful ally it is. Life creates it, makes it grow. Its energy surrounds us and binds us. Luminous beings are we, not this crude matter. You must feel the Force around you; here, between you, me, the tree, the rock, everywhere, yes. Even between the land and the ship.', + }, + component: Paper, + parameters: { + componentSubtitle: `πŸ¦Έβ€β™‚οΈ I've been nice, I've stood for photos, signed every scrap of paper you pushed at me... - Mr. Incredible - The Incredibles`, + }, + + title: 'Molecules/Paper', +} satisfies Meta<PaperProps> + +export default meta +type Story = StoryObj<typeof meta> + +export const Playground: Story = { + args: { + elevation: DEFAULT_ELEVATION, + }, +} + +export const Papers: Story = { + parameters: { + controls: { + include: ['children'], + }, + }, + render: ({ children }) => ( + <div + style={{ + display: 'flex', + flexDirection: 'column', + gap: 'var(--size-spacing-3)', + }} + > + <Paper elevation="1">{children}</Paper> + <Paper elevation="2">{children}</Paper> + </div> + ), +} diff --git a/packages/fractal/src/components/Paper/Paper.tsx b/packages/fractal/src/components/Paper/Paper.tsx new file mode 100644 index 000000000..3b5339235 --- /dev/null +++ b/packages/fractal/src/components/Paper/Paper.tsx @@ -0,0 +1,38 @@ +import { cx } from '@snowball-tech/fractal-panda/css' +import { + paper, + paperContent, + typography, +} from '@snowball-tech/fractal-panda/recipes' +import omit from 'lodash/fp/omit' + +import { PREFIX } from '@/constants' + +import { DEFAULT_ELEVATION } from './Paper.constants' +import { GROUP_NAME } from './Paper.recipe' +import type { PaperProps } from './Paper.types' + +/** + * `Paper` component allow to build interface with level and hierarchy. + */ +export const Paper = ({ + children, + elevation = DEFAULT_ELEVATION, + ...props +}: PaperProps) => { + const groupClassNames = cx( + `${PREFIX}-${GROUP_NAME}`, + paper({ elevation }), + props.className, + typography({ variant: 'body-1' }), + ) + + return ( + <div className={groupClassNames} {...omit(['className'], props)}> + <div className={paperContent()}>{children}</div> + </div> + ) +} +Paper.displayName = 'Paper' + +export default Paper diff --git a/packages/fractal/src/components/Paper/Paper.types.ts b/packages/fractal/src/components/Paper/Paper.types.ts new file mode 100644 index 000000000..cb46e53ed --- /dev/null +++ b/packages/fractal/src/components/Paper/Paper.types.ts @@ -0,0 +1,15 @@ +import type { AllHTMLAttributes, ReactNode } from 'react' + +import { Elevations } from './Paper.constants' + +export interface PaperProps extends AllHTMLAttributes<HTMLDivElement> { + /** The content of the paper. */ + children: ReactNode + /** + * The elevation level of the paper. + * + * 1 (bordered) is a non elevated bordered paper + * 2 (low) is a lightly raised (small shadow) bordered paper + */ + elevation?: `${Elevations}` +} diff --git a/packages/fractal/src/components/Paper/index.ts b/packages/fractal/src/components/Paper/index.ts new file mode 100644 index 000000000..44b139079 --- /dev/null +++ b/packages/fractal/src/components/Paper/index.ts @@ -0,0 +1 @@ +export { default as Paper } from './Paper.js' diff --git a/packages/fractal/src/components/index.ts b/packages/fractal/src/components/index.ts index f2a840a7d..eb25e3e5f 100644 --- a/packages/fractal/src/components/index.ts +++ b/packages/fractal/src/components/index.ts @@ -18,6 +18,7 @@ export { InputRadio, InputRadioGroup } from './InputRadio/index.js' export { InputText } from './InputText/index.js' export { Loader } from './Loader/index.js' export { Logo } from './Logo/index.js' +export { Paper } from './Paper/index.js' export { Progress } from './Progress/index.js' export { Select,