Use composeStories() from Storybook 🔅

Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
This commit is contained in:
Charles de Dreuille
2025-01-04 08:52:09 +01:00
parent a8d1bd5b02
commit a193e7f631
24 changed files with 450 additions and 453 deletions
+13 -13
View File
@@ -3,12 +3,12 @@ import { Snippet } from '../components/Snippet';
import { Tabs } from '../components/Tabs';
import { CodeBlock } from '../components/CodeBlock';
import {
Button1,
Button2,
Button3,
Button4,
Button5,
Button6,
ButtonPreview,
ButtonSizes,
ButtonWithIcons,
ButtonFullWidth,
ButtonDisabled,
ButtonResponsive,
} from '../snippets/button';
import { buttonVariants } from './_snippets';
@@ -19,7 +19,7 @@ A button component that can be used to trigger actions.
<Snippet
align="center"
py={4}
preview={<Button1 />}
preview={<ButtonPreview />}
code={`<Inline alignY="center">
<Button iconStart="cloud" variant="primary">
Button
@@ -97,7 +97,7 @@ Here's a view when buttons have different variants.
align="center"
py={4}
open
preview={<Button1 />}
preview={<ButtonPreview />}
code={buttonVariants}
/>
@@ -109,7 +109,7 @@ Here's a view when buttons have different sizes.
align="center"
py={4}
open
preview={<Button2 />}
preview={<ButtonSizes />}
code={`<Inline alignY="center">
<Button size="small">Small</Button>
<Button size="medium">Medium</Button>
@@ -124,7 +124,7 @@ Here's a view when buttons have icons.
align="center"
py={4}
open
preview={<Button3 />}
preview={<ButtonWithIcons />}
code={`<Inline alignY="center">
<Button iconStart="cloud">Button</Button>
<Button iconEnd="chevronRight">Button</Button>
@@ -140,7 +140,7 @@ Here's a view when buttons are full width.
align="center"
py={4}
open
preview={<Button4 />}
preview={<ButtonFullWidth />}
code={`<Stack style={{ width: '300px' }}>
<Button fullWidth>Full width</Button>
</Stack>`}
@@ -154,7 +154,7 @@ Here's a view when buttons are disabled.
align="center"
py={4}
open
preview={<Button5 />}
preview={<ButtonDisabled />}
code={`<Button disabled>Button</Button>`}
/>
@@ -166,7 +166,7 @@ Here's a view when buttons are responsive.
align="center"
py={4}
open
preview={<Button6 />}
preview={<ButtonResponsive />}
code={`<Button
variant={{ xs: 'primary', sm: 'secondary', md: 'tertiary' }}
size={{ xs: 'small', sm: 'medium' }}>
+1
View File
@@ -19,6 +19,7 @@ columns. All values are responsive.
<Snippet
py={4}
align="center"
preview={<StackPreview />}
code={`<Stack>
<DecorativeBox />
+1
View File
@@ -17,6 +17,7 @@
"@mdx-js/loader": "^3.1.0",
"@mdx-js/react": "^3.1.0",
"@next/mdx": "^15.1.3",
"@storybook/react": "^8.4.7",
"@types/mdx": "^2.0.13",
"motion": "^11.15.0",
"next": "15.1.3",
+7 -7
View File
@@ -1,10 +1,10 @@
import { Box } from '@backstage/canon';
import { DecorativeBox } from '../components/DecorativeBox';
'use client';
import * as BoxStories from '../../packages/canon/src/components/Box/Box.stories';
import { composeStories } from '@storybook/react';
export const BoxPreview = () => {
return (
<Box>
<DecorativeBox />
</Box>
);
const { Default } = composeStories(BoxStories);
return <Default />;
};
+27 -94
View File
@@ -1,115 +1,48 @@
'use client';
import { ButtonProps, Text } from '@backstage/canon';
import { Stack, Inline, Button } from '@backstage/canon';
import * as ButtonStories from '../../packages/canon/src/components/Button/Button.stories';
import { composeStories } from '@storybook/react';
const variants: string[] = ['primary', 'secondary', 'tertiary'];
export const ButtonPreview = () => {
const { Variants } = composeStories(ButtonStories);
const capitalizeFirstLetter = (string: string): string => {
return string.charAt(0).toUpperCase() + string.slice(1);
return <Variants />;
};
export const Button1 = () => {
return (
<Inline alignY="center">
<Button iconStart="cloud" variant="primary">
Button
</Button>
<Button iconStart="cloud" variant="secondary">
Button
</Button>
<Button iconStart="cloud" variant="tertiary">
Button
</Button>
</Inline>
);
export const ButtonSizes = () => {
const { Sizes } = composeStories(ButtonStories);
return <Sizes />;
};
export const Button2 = () => {
return (
<Inline alignY="center">
<Button size="small">Small</Button>
<Button size="medium">Medium</Button>
</Inline>
);
export const ButtonWithIcons = () => {
const { WithIcons } = composeStories(ButtonStories);
return <WithIcons />;
};
export const Button3 = () => {
return (
<Inline alignY="center">
<Button iconStart="cloud">Button</Button>
<Button iconEnd="chevronRight">Button</Button>
<Button
iconStart="cloud"
iconEnd="chevronRight"
style={{ width: '200px' }}
>
Button
</Button>
</Inline>
);
export const ButtonFullWidth = () => {
const { FullWidth } = composeStories(ButtonStories);
return <FullWidth />;
};
export const Button4 = () => {
return (
<Stack style={{ width: '300px' }}>
<Button>Full width</Button>
</Stack>
);
export const ButtonDisabled = () => {
const { Disabled } = composeStories(ButtonStories);
return <Disabled />;
};
export const Button5 = () => {
return <Button disabled>Button</Button>;
};
export const ButtonResponsive = () => {
const { Responsive } = composeStories(ButtonStories);
export const Button6 = () => {
// TODO: Add responsive button
return null;
return (
<Button
variant={{ xs: 'primary', sm: 'secondary', md: 'tertiary' }}
size={{ xs: 'small', sm: 'medium' }}
>
Button
</Button>
);
return <Responsive />;
};
export const ButtonPlayground = () => {
return (
<Stack>
{variants.map(variant => (
<Stack key={variant}>
<Text>{capitalizeFirstLetter(variant as string)}</Text>
{['small', 'medium'].map(size => (
<Inline alignY="center" key={size}>
<Button
iconStart="cloud"
variant={variant as ButtonProps['variant']}
size={size as ButtonProps['size']}
>
Button
</Button>
<Button
iconEnd="chevronRight"
variant={variant as ButtonProps['variant']}
size={size as ButtonProps['size']}
>
Button
</Button>
<Button
iconStart="cloud"
iconEnd="chevronRight"
style={{ width: '200px' }}
variant={variant as ButtonProps['variant']}
size={size as ButtonProps['size']}
>
Button
</Button>
</Inline>
))}
</Stack>
))}
</Stack>
);
const { Playground } = composeStories(ButtonStories);
return <Playground />;
};
+13 -22
View File
@@ -1,31 +1,22 @@
import { Text } from '@backstage/canon';
import { Stack, Inline, Checkbox } from '@backstage/canon';
'use client';
import * as CheckboxStories from '../../packages/canon/src/components/Checkbox/Checkbox.stories';
import { composeStories } from '@storybook/react';
export const CheckboxPreview = () => {
return <Checkbox label="Accept terms and conditions" />;
const { Default } = composeStories(CheckboxStories);
return <Default />;
};
export const CheckboxAllVariants = () => {
return (
<Inline alignY="center">
<Checkbox />
<Checkbox checked />
<Checkbox label="Checkbox" />
<Checkbox label="Checkbox" checked />
</Inline>
);
const { AllVariants } = composeStories(CheckboxStories);
return <AllVariants />;
};
export const CheckboxPlayground = () => {
return (
<Stack>
<Text>All variants</Text>
<Inline alignY="center">
<Checkbox />
<Checkbox checked />
<Checkbox label="Checkbox" />
<Checkbox label="Checkbox" checked />
</Inline>
</Stack>
);
const { Playground } = composeStories(CheckboxStories);
return <Playground />;
};
+7 -7
View File
@@ -1,10 +1,10 @@
import { Container } from '@backstage/canon';
import { DecorativeBox } from '../components/DecorativeBox';
'use client';
import { composeStories } from '@storybook/react';
import * as ContainerStories from '../../packages/canon/src/components/Container/Container.stories';
export const ContainerPreview = () => {
return (
<div style={{ maxWidth: '600px', margin: '0 auto' }}>
<DecorativeBox />
</div>
);
const { Preview } = composeStories(ContainerStories);
return <Preview />;
};
+7 -9
View File
@@ -1,12 +1,10 @@
import { Grid } from '@backstage/canon';
import { DecorativeBox } from '../components/DecorativeBox';
'use client';
import { composeStories } from '@storybook/react';
import * as GridStories from '../../packages/canon/src/components/Grid/Grid.stories';
export const GridPreview = () => {
return (
<Grid>
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
</Grid>
);
const { Default } = composeStories(GridStories);
return <Default />;
};
+16 -25
View File
@@ -1,39 +1,30 @@
import { Text, Heading } from '@backstage/canon';
import { Stack } from '@backstage/canon';
'use client';
import * as HeadingStories from '../../packages/canon/src/components/Heading/Heading.stories';
import { composeStories } from '@storybook/react';
export const HeadingPreview = () => {
return <Heading variant="title1">Look mum, no hands!</Heading>;
const { Title1 } = composeStories(HeadingStories);
return <Title1 />;
};
export const HeadingAllVariants = () => {
return (
<Stack>
<Heading variant="display">Display</Heading>
<Heading variant="title1">Title 1</Heading>
<Heading variant="title2">Title 2</Heading>
<Heading variant="title3">Title 3</Heading>
<Heading variant="title4">Title 4</Heading>
<Heading variant="title5">Title 5</Heading>
</Stack>
);
const { AllVariants } = composeStories(HeadingStories);
return <AllVariants />;
};
export const HeadingResponsive = () => {
const { Responsive } = composeStories(HeadingStories);
// TODO: Add responsive heading
return null;
return <Heading variant={{ xs: 'title1', md: 'title2' }}>Responsive</Heading>;
return <Responsive />;
};
export const HeadingPlayground = () => {
return (
<Stack>
<Text>All variants</Text>
<Heading variant="display">Display</Heading>
<Heading variant="title1">Title 1</Heading>
<Heading variant="title2">Title 2</Heading>
<Heading variant="title3">Title 3</Heading>
<Heading variant="title4">Title 4</Heading>
<Heading variant="title5">Title 5</Heading>
</Stack>
);
const { Playground } = composeStories(HeadingStories);
return <Playground />;
};
+7 -7
View File
@@ -1,10 +1,10 @@
import { Icon } from '@backstage/canon';
import { Stack } from '@backstage/canon';
'use client';
import * as IconStories from '../../packages/canon/src/components/Icon/Icon.stories';
import { composeStories } from '@storybook/react';
export const IconPreview = () => {
return (
<Stack>
<Icon name="heart" />
</Stack>
);
const { Default } = composeStories(IconStories);
return <Default />;
};
+7 -23
View File
@@ -1,26 +1,10 @@
import { Inline } from '@backstage/canon';
import { DecorativeBox } from '../components/DecorativeBox';
'use client';
import * as InlineStories from '../../packages/canon/src/components/Inline/Inline.stories';
import { composeStories } from '@storybook/react';
export const InlinePreview = () => {
return (
<Inline>
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
</Inline>
);
const { Default } = composeStories(InlineStories);
return <Default />;
};
+7 -11
View File
@@ -1,14 +1,10 @@
import { Stack } from '@backstage/canon';
import { DecorativeBox } from '../components/DecorativeBox';
'use client';
import * as StackStories from '../../packages/canon/src/components/Stack/Stack.stories';
import { composeStories } from '@storybook/react';
export const StackPreview = () => {
return (
<div style={{ maxWidth: '320px', margin: '0 auto' }}>
<Stack>
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
</Stack>
</div>
);
const { Default } = composeStories(StackStories);
return <Default />;
};
+19 -76
View File
@@ -1,93 +1,36 @@
import { Text } from '@backstage/canon';
import { Stack } from '@backstage/canon';
'use client';
import * as TextStories from '../../packages/canon/src/components/Text/Text.stories';
import { composeStories } from '@storybook/react';
export const TextPreview = () => {
return (
<Text style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is in
the painting?
</Text>
);
const { Default } = composeStories(TextStories);
return <Default />;
};
export const TextAllVariants = () => {
return (
<Stack gap="md">
<Text variant="subtitle" style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is
in the painting?
</Text>
<Text variant="body" style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is
in the painting?
</Text>
<Text variant="caption" style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is
in the painting?
</Text>
<Text variant="label" style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is
in the painting?
</Text>
</Stack>
);
const { AllVariants } = composeStories(TextStories);
return <AllVariants />;
};
export const TextAllWeights = () => {
return (
<Stack gap="md">
<Text weight="regular" style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is
in the painting?
</Text>
<Text weight="bold" style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is
in the painting?
</Text>
</Stack>
);
const { AllWeights } = composeStories(TextStories);
return <AllWeights />;
};
export const TextResponsive = () => {
const { Responsive } = composeStories(TextStories);
// TODO: Add responsive text
return null;
return <Text variant={{ xs: 'label', md: 'body' }}>Responsive</Text>;
return <Responsive />;
};
export const TextPlayground = () => {
return (
<Stack>
<Text>Subtitle</Text>
<Text variant="subtitle" style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is
in the painting?
</Text>
<Text>Body</Text>
<Text variant="body" style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is
in the painting?
</Text>
<Text>Caption</Text>
<Text variant="caption" style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is
in the painting?
</Text>
<Text>Label</Text>
<Text variant="label" style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is
in the painting?
</Text>
</Stack>
);
const { Playground } = composeStories(TextStories);
return <Playground />;
};
@@ -40,22 +40,28 @@ const meta = {
export default meta;
type Story = StoryObj<typeof meta>;
export const Basic: Story = {
export const Default: Story = {
args: {
style: {
background: '#1f47ff',
color: 'white',
padding: '4px 8px',
width: '64px',
height: '64px',
background: '#eaf2fd',
borderRadius: '4px',
border: '1px solid #2563eb',
color: '#2563eb',
backgroundImage:
'url("data:image/svg+xml,%3Csvg%20width%3D%226%22%20height%3D%226%22%20viewBox%3D%220%200%206%206%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%3Cg%20fill%3D%22%232563eb%22%20fill-opacity%3D%220.3%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22M5%200h1L0%206V5zM6%205v1H5z%22/%3E%3C/g%3E%3C/svg%3E")',
},
children: 'Basic Box',
},
};
export const Display: Story = {
args: {
style: {
...Basic.args?.style,
...Default.args?.style,
width: 'auto',
height: 'auto',
padding: '8px',
},
},
render: args => (
@@ -84,7 +90,10 @@ export const Display: Story = {
export const FlexDirection: Story = {
args: {
style: {
...Basic.args?.style,
...Default.args?.style,
width: 'auto',
height: 'auto',
padding: '8px',
},
display: 'flex',
gap: 'xs',
@@ -110,8 +119,10 @@ export const FlexDirection: Story = {
export const JustifyContent: Story = {
args: {
style: {
...Basic.args?.style,
...Default.args?.style,
width: '200px',
height: 'auto',
padding: '8px',
},
display: 'flex',
gap: 'xs',
@@ -153,9 +164,10 @@ export const JustifyContent: Story = {
export const AlignItems: Story = {
args: {
style: {
...Basic.args?.style,
...Default.args?.style,
width: '200px',
height: '100px',
padding: '8px',
},
display: 'flex',
gap: 'xs',
@@ -289,8 +301,10 @@ export const Margin: Story = {
export const FlexWrap: Story = {
args: {
style: {
...Basic.args?.style,
...Default.args?.style,
width: '200px',
height: 'auto',
padding: '8px',
},
display: 'flex',
gap: 'xs',
@@ -328,11 +342,14 @@ export const FlexWrap: Story = {
export const BorderRadius: Story = {
args: {
style: {
background: '#1f47ff',
color: 'white',
padding: '4px 8px',
width: '64px',
height: '64px',
background: '#eaf2fd',
border: '1px solid #2563eb',
color: '#2563eb',
backgroundImage:
'url("data:image/svg+xml,%3Csvg%20width%3D%226%22%20height%3D%226%22%20viewBox%3D%220%200%206%206%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%3Cg%20fill%3D%22%232563eb%22%20fill-opacity%3D%220.3%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22M5%200h1L0%206V5zM6%205v1H5z%22/%3E%3C/g%3E%3C/svg%3E")',
padding: '4px 8px',
},
display: 'flex',
alignItems: 'center',
@@ -20,6 +20,8 @@ import { Button } from './Button';
import { Inline } from '../Inline';
import { Stack } from '../Stack';
import { Text } from '../Text';
import { ButtonProps } from './types';
const meta = {
title: 'Button',
component: Button,
@@ -37,12 +39,6 @@ const meta = {
export default meta;
type Story = StoryObj<typeof meta>;
export const Primary: Story = {
args: {
children: 'Primary button',
},
};
export const Variants: Story = {
args: {
children: 'Button',
@@ -56,9 +52,15 @@ export const Variants: Story = {
},
render: () => (
<Inline alignY="center">
<Button variant="primary">Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="tertiary">Tertiary</Button>
<Button iconStart="cloud" variant="primary">
Button
</Button>
<Button iconStart="cloud" variant="secondary">
Button
</Button>
<Button iconStart="cloud" variant="tertiary">
Button
</Button>
</Inline>
),
};
@@ -123,20 +125,46 @@ export const Responsive: Story = {
},
};
const variants: string[] = ['primary', 'secondary', 'tertiary'];
export const Playground: Story = {
args: {
children: 'Button',
},
render: args => (
render: () => (
<Stack>
<Stack>
<Text>Primary</Text>
<Inline alignY="center">
<Button {...args} iconStart="cloud" />
<Button {...args} iconEnd="chevronRight" />
<Button {...args} iconStart="cloud" iconEnd="chevronRight" />
</Inline>
</Stack>
{variants.map(variant => (
<Stack key={variant}>
<Text>{variant}</Text>
{['small', 'medium'].map(size => (
<Inline alignY="center" key={size}>
<Button
iconStart="cloud"
variant={variant as ButtonProps['variant']}
size={size as ButtonProps['size']}
>
Button
</Button>
<Button
iconEnd="chevronRight"
variant={variant as ButtonProps['variant']}
size={size as ButtonProps['size']}
>
Button
</Button>
<Button
iconStart="cloud"
iconEnd="chevronRight"
style={{ width: '200px' }}
variant={variant as ButtonProps['variant']}
size={size as ButtonProps['size']}
>
Button
</Button>
</Inline>
))}
</Stack>
))}
</Stack>
),
};
@@ -14,8 +14,12 @@
* limitations under the License.
*/
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { Checkbox } from './Checkbox';
import { Inline } from '../Inline';
import { Stack } from '../Stack';
import { Text } from '../Text';
const meta = {
title: 'Checkbox',
@@ -28,8 +32,33 @@ const meta = {
export default meta;
type Story = StoryObj<typeof meta>;
export const Primary: Story = {
export const Default: Story = {
args: {
label: 'Accept terms and conditions',
},
};
export const AllVariants: Story = {
render: () => (
<Inline alignY="center">
<Checkbox />
<Checkbox checked />
<Checkbox label="Checkbox" />
<Checkbox label="Checkbox" checked />
</Inline>
),
};
export const Playground: Story = {
render: () => (
<Stack>
<Text>All variants</Text>
<Inline alignY="center">
<Checkbox />
<Checkbox checked />
<Checkbox label="Checkbox" />
<Checkbox label="Checkbox" checked />
</Inline>
</Stack>
),
};
@@ -30,26 +30,40 @@ const meta = {
control: 'text',
},
},
parameters: {
layout: 'fullscreen',
},
} satisfies Meta<typeof Container>;
export default meta;
type Story = StoryObj<typeof meta>;
const FakeBox = () => (
const DecorativeBox = () => (
<Box
borderRadius="xs"
style={{ background: '#1f47ff', color: 'white', height: '400px' }}
style={{
height: '64px',
background: '#eaf2fd',
borderRadius: '4px',
border: '1px solid #2563eb',
backgroundImage:
'url("data:image/svg+xml,%3Csvg%20width%3D%226%22%20height%3D%226%22%20viewBox%3D%220%200%206%206%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%3Cg%20fill%3D%22%232563eb%22%20fill-opacity%3D%220.3%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22M5%200h1L0%206V5zM6%205v1H5z%22/%3E%3C/g%3E%3C/svg%3E")',
}}
/>
);
export const Default: Story = {
args: {},
parameters: {
layout: 'fullscreen',
},
render: args => (
<Container {...args}>
<FakeBox />
<DecorativeBox />
</Container>
),
};
export const Preview: Story = {
render: () => (
<div style={{ maxWidth: '600px', margin: '0 auto' }}>
<DecorativeBox />
</div>
),
};
@@ -43,7 +43,14 @@ type Story = StoryObj<typeof meta>;
const FakeBox = () => (
<Box
borderRadius="xs"
style={{ background: '#1f47ff', color: 'white', height: '64px' }}
style={{
background: '#eaf2fd',
borderRadius: '4px',
boxShadow: '0 0 0 1px #2563eb',
height: '64px',
backgroundImage:
'url("data:image/svg+xml,%3Csvg%20width%3D%226%22%20height%3D%226%22%20viewBox%3D%220%200%206%206%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%3Cg%20fill%3D%22%232563eb%22%20fill-opacity%3D%220.3%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22M5%200h1L0%206V5zM6%205v1H5z%22/%3E%3C/g%3E%3C/svg%3E")',
}}
/>
);
@@ -103,7 +110,14 @@ export const RowAndColumns: Story = {
<Grid.Item colSpan={1} rowSpan={2}>
<Box
borderRadius="xs"
style={{ background: '#1f47ff', color: 'white', height: '100%' }}
style={{
height: '100%',
background: '#eaf2fd',
borderRadius: '4px',
boxShadow: '0 0 0 1px #2563eb',
backgroundImage:
'url("data:image/svg+xml,%3Csvg%20width%3D%226%22%20height%3D%226%22%20viewBox%3D%220%200%206%206%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%3Cg%20fill%3D%22%232563eb%22%20fill-opacity%3D%220.3%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22M5%200h1L0%206V5zM6%205v1H5z%22/%3E%3C/g%3E%3C/svg%3E")',
}}
/>
</Grid.Item>
<Grid.Item colSpan={2}>
@@ -18,20 +18,19 @@ import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { Heading } from './Heading';
import { Stack } from '../Stack';
import { Text } from '../Text';
const meta = {
title: 'Heading',
component: Heading,
args: {
children: 'Heading',
},
} satisfies Meta<typeof Heading>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
args: {
children: 'Heading',
},
};
export const Default: Story = {};
export const Title1: Story = {
args: {
@@ -41,11 +40,8 @@ export const Title1: Story = {
};
export const AllVariants: Story = {
args: {
children: 'Heading',
},
render: () => (
<Stack gap="md">
<Stack>
<Heading variant="display">Display</Heading>
<Heading variant="title1">Title 1</Heading>
<Heading variant="title2">Title 2</Heading>
@@ -57,7 +53,6 @@ export const AllVariants: Story = {
export const Responsive: Story = {
args: {
...Default.args,
variant: {
xs: 'title4',
md: 'display',
@@ -67,8 +62,21 @@ export const Responsive: Story = {
export const CustomTag: Story = {
args: {
...Default.args,
variant: 'title5',
as: 'h2',
},
};
export const Playground: Story = {
render: () => (
<Stack>
<Text>All variants</Text>
<Heading variant="display">Display</Heading>
<Heading variant="title1">Title 1</Heading>
<Heading variant="title2">Title 2</Heading>
<Heading variant="title3">Title 3</Heading>
<Heading variant="title4">Title 4</Heading>
<Heading variant="title5">Title 5</Heading>
</Stack>
),
};
@@ -40,7 +40,7 @@ const meta = {
export default meta;
type Story = StoryObj<typeof meta>;
export const Primary: Story = {
export const Default: Story = {
args: {
name: 'heart',
},
@@ -41,6 +41,9 @@ const meta = {
control: 'text',
},
},
args: {
children: 'hello world',
},
} satisfies Meta<typeof Inline>;
export default meta;
@@ -52,33 +55,12 @@ const fakeBlockList = [
{ width: 80, height: 50 },
{ width: 120, height: 70 },
{ width: 95, height: 65 },
{ width: 110, height: 55 },
{ width: 80, height: 32 },
{ width: 130, height: 60 },
{ width: 100, height: 80 },
{ width: 140, height: 45 },
{ width: 85, height: 70 },
{ width: 125, height: 50 },
{ width: 105, height: 75 },
{ width: 115, height: 65 },
{ width: 135, height: 55 },
{ width: 90, height: 60 },
{ width: 145, height: 80 },
{ width: 75, height: 45 },
{ width: 155, height: 70 },
{ width: 60, height: 50 },
{ width: 160, height: 75 },
{ width: 70, height: 65 },
{ width: 150, height: 55 },
{ width: 95, height: 60 },
{ width: 120, height: 80 },
{ width: 85, height: 45 },
{ width: 130, height: 70 },
{ width: 100, height: 50 },
{ width: 140, height: 75 },
{ width: 110, height: 65 },
{ width: 125, height: 55 },
{ width: 105, height: 60 },
{ width: 145, height: 80 },
];
const FakeBox = ({
@@ -90,67 +72,66 @@ const FakeBox = ({
}) => (
<Box
borderRadius="xs"
style={{ background: '#1f47ff', color: 'white', width, height }}
style={{
background: '#eaf2fd',
borderRadius: '4px',
boxShadow: '0 0 0 1px #2563eb',
width,
height,
backgroundImage:
'url("data:image/svg+xml,%3Csvg%20width%3D%226%22%20height%3D%226%22%20viewBox%3D%220%200%206%206%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%3Cg%20fill%3D%22%232563eb%22%20fill-opacity%3D%220.3%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22M5%200h1L0%206V5zM6%205v1H5z%22/%3E%3C/g%3E%3C/svg%3E")',
}}
/>
);
export const Default: Story = {
args: {
children: (
<>
{fakeBlockList.map((block, index) => (
<FakeBox key={index} width={block.width} height={block.height} />
))}
</>
),
},
render: () => (
<Inline>
{fakeBlockList.map((block, index) => (
<FakeBox key={index} width={block.width} height={block.height} />
))}
</Inline>
),
};
export const AlignLeft: Story = {
args: {
...Default.args,
align: 'left',
},
};
export const AlignCenter: Story = {
args: {
...Default.args,
align: 'center',
},
};
export const AlignRight: Story = {
args: {
...Default.args,
align: 'right',
},
};
export const VerticalAlignTop: Story = {
args: {
...Default.args,
alignY: 'top',
},
};
export const VerticalAlignCenter: Story = {
args: {
...Default.args,
alignY: 'center',
},
};
export const VerticalAlignBottom: Story = {
args: {
...Default.args,
alignY: 'bottom',
},
};
export const LargeGap: Story = {
args: {
...Default.args,
gap: 'xl',
},
};
@@ -17,7 +17,6 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { Stack } from './Stack';
import { Box } from '../Box/Box';
const meta = {
title: 'Stack',
@@ -40,81 +39,97 @@ const meta = {
args: {
align: 'left',
gap: 'xs',
children: 'hello world',
},
} satisfies Meta<typeof Stack>;
export default meta;
type Story = StoryObj<typeof meta>;
const FakeBox = () => (
<Box
paddingX="xl"
paddingY="md"
borderRadius="xs"
style={{ background: '#1f47ff', color: 'white' }}
>
Fake Box
</Box>
);
const DecorativeBox = () => {
return (
<div
style={{
background: '#eaf2fd',
borderRadius: '4px',
boxShadow: '0 0 0 1px #2563eb',
height: '32px',
minWidth: '100px',
backgroundImage:
'url("data:image/svg+xml,%3Csvg%20width%3D%226%22%20height%3D%226%22%20viewBox%3D%220%200%206%206%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%3Cg%20fill%3D%22%232563eb%22%20fill-opacity%3D%220.3%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22M5%200h1L0%206V5zM6%205v1H5z%22/%3E%3C/g%3E%3C/svg%3E")',
}}
/>
);
};
export const Default: Story = {
args: {
children: (
<>
<FakeBox />
<FakeBox />
<FakeBox />
</>
),
},
render: () => (
<div style={{ width: '320px' }}>
<Stack>
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
</Stack>
</div>
),
};
export const AlignLeft: Story = {
args: {
...Default.args,
align: 'left',
},
render: () => (
<Stack align="left">
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
</Stack>
),
};
export const AlignCenter: Story = {
args: {
...Default.args,
align: 'center',
},
render: () => (
<Stack align="center">
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
</Stack>
),
};
export const AlignRight: Story = {
args: {
...Default.args,
align: 'right',
},
render: () => (
<Stack align="right">
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
</Stack>
),
};
export const ResponsiveAlign: Story = {
args: {
...Default.args,
align: {
xs: 'left',
md: 'center',
lg: 'right',
},
},
render: () => (
<Stack align={{ xs: 'left', md: 'center', lg: 'right' }}>
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
</Stack>
),
};
export const ResponsiveGap: Story = {
args: {
...Default.args,
gap: {
xs: 'xs',
md: 'md',
lg: '2xl',
},
},
render: () => (
<Stack gap={{ xs: 'xs', md: 'md', lg: '2xl' }}>
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
</Stack>
),
};
export const LargeGap: Story = {
args: {
...Default.args,
gap: 'xl',
},
render: () => (
<Stack gap="xl">
<DecorativeBox />
<DecorativeBox />
<DecorativeBox />
</Stack>
),
};
@@ -22,6 +22,9 @@ import { Stack } from '../Stack';
const meta = {
title: 'Text',
component: Text,
args: {
children: 'Text',
},
} satisfies Meta<typeof Text>;
export default meta;
@@ -30,42 +33,91 @@ type Story = StoryObj<typeof meta>;
export const Default: Story = {
args: {
children:
'Lorem ipsum dolor sit amet consectetur. Nec arcu vel lacus magna adipiscing nisi mauris tortor viverra. Enim rhoncus quisque consectetur ligula diam ac lacus massa. Id interdum id pellentesque justo ut massa nibh amet. Odio massa in scelerisque tortor massa integer purus amet enim. Eros sit neque nullam facilisis. Purus massa dignissim aliquet purus eu in. Urna consequat ullamcorper arcu amet dictumst. Commodo praesent turpis fringilla tristique congue volutpat in. Nulla in nulla ultrices lacus. In ultrices id tellus ut.',
"A man looks at a painting in a museum and says, “Brothers and sisters I have none, but that man's father is my father's son.” Who is in the painting?",
style: { maxWidth: '600px' },
},
};
export const AllVariants: Story = {
args: {
children: 'Text',
},
render: () => (
<Stack gap="md">
<Text variant="subtitle">Subtitle {Default.args?.children}</Text>
<Text variant="body">Body {Default.args?.children}</Text>
<Text variant="caption">Caption {Default.args?.children}</Text>
<Text variant="label">Label {Default.args?.children}</Text>
<Text variant="subtitle" style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is
in the painting?
</Text>
<Text variant="body" style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is
in the painting?
</Text>
<Text variant="caption" style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is
in the painting?
</Text>
<Text variant="label" style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is
in the painting?
</Text>
</Stack>
),
};
export const AllWeights: Story = {
args: {
children: 'Text',
},
render: () => (
<Stack gap="md">
<Text weight="regular">Regular {Default.args?.children}</Text>
<Text weight="bold">Bold {Default.args?.children}</Text>
<Text weight="regular" style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is
in the painting?
</Text>
<Text weight="bold" style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is
in the painting?
</Text>
</Stack>
),
};
export const Responsive: Story = {
args: {
...Default.args,
variant: {
xs: 'label',
md: 'body',
},
},
};
export const Playground: Story = {
render: () => (
<Stack>
<Text>Subtitle</Text>
<Text variant="subtitle" style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is
in the painting?
</Text>
<Text>Body</Text>
<Text variant="body" style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is
in the painting?
</Text>
<Text>Caption</Text>
<Text variant="caption" style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is
in the painting?
</Text>
<Text>Label</Text>
<Text variant="label" style={{ maxWidth: '600px' }}>
A man looks at a painting in a museum and says, Brothers and sisters I
have none, but that man&apos;s father is my father&apos;s son. Who is
in the painting?
</Text>
</Stack>
),
};
+1
View File
@@ -24623,6 +24623,7 @@ __metadata:
"@mdx-js/loader": ^3.1.0
"@mdx-js/react": ^3.1.0
"@next/mdx": ^15.1.3
"@storybook/react": ^8.4.7
"@types/mdx": ^2.0.13
"@types/node": ^20
"@types/react": ^19