Improve layout components

Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
This commit is contained in:
Charles de Dreuille
2024-11-23 13:30:17 +00:00
parent a524f7cf16
commit cc7a706683
27 changed files with 862 additions and 452 deletions
+2 -3
View File
@@ -1,5 +1,5 @@
import type { StorybookConfig } from '@storybook/react-webpack5';
const { VanillaExtractPlugin } = require('@vanilla-extract/webpack-plugin');
import { VanillaExtractPlugin } from '@vanilla-extract/webpack-plugin';
import { merge } from 'webpack-merge';
import { join, dirname } from 'path';
@@ -20,11 +20,10 @@ const config: StorybookConfig = {
staticDirs: ['../static'],
addons: [
getAbsolutePath('@storybook/addon-webpack5-compiler-swc'),
getAbsolutePath('@storybook/addon-onboarding'),
getAbsolutePath('@storybook/addon-essentials'),
getAbsolutePath('@chromatic-com/storybook'),
getAbsolutePath('@storybook/addon-interactions'),
// getAbsolutePath("@storybook/addon-styling-webpack")
getAbsolutePath('@storybook/addon-themes'),
],
framework: {
name: getAbsolutePath('@storybook/react-webpack5'),
+1 -4
View File
@@ -1,9 +1,6 @@
import React from 'react';
import type { Preview, ReactRenderer } from '@storybook/react';
import {
withThemeByClassName,
withThemeByDataAttribute,
} from '@storybook/addon-themes';
import { withThemeByDataAttribute } from '@storybook/addon-themes';
import '../src/theme/styles.css';
+9 -10
View File
@@ -47,16 +47,15 @@
"@backstage/cli": "workspace:^",
"@chromatic-com/storybook": "^3.2.2",
"@eslint/js": "^9.13.0",
"@storybook/addon-essentials": "^8.4.4",
"@storybook/addon-interactions": "^8.4.4",
"@storybook/addon-onboarding": "^8.4.4",
"@storybook/addon-essentials": "^8.4.5",
"@storybook/addon-interactions": "^8.4.5",
"@storybook/addon-styling-webpack": "^1.0.1",
"@storybook/addon-themes": "^8.4.4",
"@storybook/addon-themes": "^8.4.5",
"@storybook/addon-webpack5-compiler-swc": "^1.0.5",
"@storybook/blocks": "^8.4.4",
"@storybook/react": "^8.4.4",
"@storybook/react-webpack5": "^8.4.4",
"@storybook/test": "^8.4.4",
"@storybook/blocks": "^8.4.5",
"@storybook/react": "^8.4.5",
"@storybook/react-webpack5": "^8.4.5",
"@storybook/test": "^8.4.5",
"@testing-library/jest-dom": "^6.0.0",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.1",
@@ -65,10 +64,10 @@
"eslint": "^9.13.0",
"eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-react-refresh": "^0.4.13",
"eslint-plugin-storybook": "^0.11.0",
"eslint-plugin-storybook": "^0.11.1",
"globals": "^15.11.0",
"mini-css-extract-plugin": "^2.9.2",
"storybook": "^8.4.4",
"storybook": "^8.4.5",
"typescript": "~5.6.2",
"typescript-eslint": "^8.10.0",
"webpack-merge": "^6.0.1"
+258 -27
View File
@@ -1,59 +1,231 @@
import { Canvas, Meta, Unstyled } from '@storybook/blocks';
import * as BoxStories from './box.stories';
import { PropsTable } from '../../storybook/props-table';
import { Chip } from '../../storybook/chip';
import * as Table from '../../storybook/table';
import { Box } from './box';
import { Stack } from '../stack/stack';
import { Title, Text } from '../../storybook';
import {
alignItems,
backgroundColors,
boxShadows,
borderRadius,
display,
} from './properties';
<Meta of={BoxStories} />
# Box
Box is the lowest-level component in Canon. We use it internally to build all of our components.
<Canvas of={BoxStories.Basic} />
<Unstyled>
<Title type="h1">Box</Title>
<Text>
Box is the lowest-level component in Canon. We use it internally to build all
of our components.
</Text>
<Stack
direction="column"
items="center"
justify="center"
borderRadius="small"
mb="xxl"
gap="xl"
py="xl"
style={{ border: '1px solid #e7e7e7' }}
>
<Stack items="center" gap="xl">
<Stack
items="center"
justify="center"
borderRadius="small"
p="md"
style={{ background: '#c4cafb', color: 'white' }}
>
<Stack
px="md"
py="sm"
borderRadius="small"
style={{ background: '#1f47ff', color: 'white' }}
>
<span>padding</span>
</Stack>
</Stack>
<Stack
items="center"
justify="center"
borderRadius="small"
px="md"
style={{ background: '#c4cafb', color: 'white' }}
>
<Stack
px="md"
py="sm"
borderRadius="small"
style={{ background: '#1f47ff', color: 'white' }}
>
<span>paddingX</span>
</Stack>
</Stack>
<Stack
items="center"
justify="center"
borderRadius="small"
py="md"
style={{ background: '#c4cafb', color: 'white' }}
>
<Stack
px="md"
py="sm"
borderRadius="small"
style={{ background: '#1f47ff', color: 'white' }}
>
<span>paddingY</span>
</Stack>
</Stack>
</Stack>
<Stack items="center" gap="xl">
<Stack
items="center"
justify="center"
borderRadius="small"
pt="md"
style={{ background: '#c4cafb', color: 'white' }}
>
<Stack
px="md"
py="sm"
borderRadius="small"
style={{ background: '#1f47ff', color: 'white' }}
>
<span>paddingTop</span>
</Stack>
</Stack>
<Stack
items="center"
justify="center"
borderRadius="small"
pb="md"
style={{ background: '#c4cafb', color: 'white' }}
>
<Stack
px="md"
py="sm"
borderRadius="small"
style={{ background: '#1f47ff', color: 'white' }}
>
<span>paddingBottom</span>
</Stack>
</Stack>
<Stack
items="center"
justify="center"
borderRadius="small"
pl="md"
style={{ background: '#c4cafb', color: 'white' }}
>
<Stack
px="md"
py="sm"
borderRadius="small"
style={{ background: '#1f47ff', color: 'white' }}
>
<span>paddingLeft</span>
</Stack>
</Stack>
<Stack
items="center"
justify="center"
borderRadius="small"
pr="md"
style={{ background: '#c4cafb', color: 'white' }}
>
<Stack
px="md"
py="sm"
borderRadius="small"
style={{ background: '#1f47ff', color: 'white' }}
>
<span>paddingRight</span>
</Stack>
</Stack>
</Stack>
</Stack>
<Table.Root>
<Table.Header>
<Table.HeaderRow>
<Table.HeaderCell>Prop</Table.HeaderCell>
<Table.HeaderCell>Type</Table.HeaderCell>
<Table.HeaderCell>Default</Table.HeaderCell>
<Table.HeaderCell>Description</Table.HeaderCell>
</Table.HeaderRow>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>
<Chip>background</Chip>
<Chip head>alignItems</Chip>
</Table.Cell>
<Table.Cell>
<Chip>string</Chip>
{alignItems.map(n => (
<Chip>{n}</Chip>
))}
</Table.Cell>
<Table.Cell>
<Chip>stretch</Chip>
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>background</Chip>
</Table.Cell>
<Table.Cell>
{Object.keys(backgroundColors).map(n => (
<Chip>{n}</Chip>
))}
</Table.Cell>
<Table.Cell>
<Chip>transparent</Chip>
</Table.Cell>
<Table.Cell>The background color of the box.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip>display</Chip>
<Chip head>borderRadius</Chip>
</Table.Cell>
<Table.Cell>
<Chip>block</Chip>
<Chip>flex</Chip>
<Chip>inline-block</Chip>
<Chip>inline-flex</Chip>
{Object.keys(borderRadius).map(n => (
<Chip>{n}</Chip>
))}
</Table.Cell>
<Table.Cell>
<Chip>none</Chip>
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>boxShadow</Chip>
</Table.Cell>
<Table.Cell>
{Object.keys(boxShadows).map(n => (
<Chip>{n}</Chip>
))}
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>display</Chip>
</Table.Cell>
<Table.Cell>
{display.map(n => (
<Chip>{n}</Chip>
))}
</Table.Cell>
<Table.Cell>
<Chip>block</Chip>
</Table.Cell>
<Table.Cell>The display property of the box.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip>padding</Chip>
<Chip head>padding</Chip>
<Chip head>p</Chip>
</Table.Cell>
<Table.Cell>
<Chip>number</Chip>
@@ -61,11 +233,11 @@ Box is the lowest-level component in Canon. We use it internally to build all of
<Table.Cell>
<Chip>0</Chip>
</Table.Cell>
<Table.Cell>The padding of the box.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip>paddingX</Chip>
<Chip head>paddingX</Chip>
<Chip head>px</Chip>
</Table.Cell>
<Table.Cell>
<Chip>number</Chip>
@@ -73,11 +245,11 @@ Box is the lowest-level component in Canon. We use it internally to build all of
<Table.Cell>
<Chip>0</Chip>
</Table.Cell>
<Table.Cell>The horizontal padding of the box.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip>paddingY</Chip>
<Chip head>paddingY</Chip>
<Chip head>py</Chip>
</Table.Cell>
<Table.Cell>
<Chip>number</Chip>
@@ -85,11 +257,11 @@ Box is the lowest-level component in Canon. We use it internally to build all of
<Table.Cell>
<Chip>0</Chip>
</Table.Cell>
<Table.Cell>The vertical padding of the box.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip>paddingLeft</Chip>
<Chip head>paddingLeft</Chip>
<Chip head>pl</Chip>
</Table.Cell>
<Table.Cell>
<Chip>number</Chip>
@@ -97,11 +269,71 @@ Box is the lowest-level component in Canon. We use it internally to build all of
<Table.Cell>
<Chip>0</Chip>
</Table.Cell>
<Table.Cell>The left padding of the box.</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip>paddingRight</Chip>
<Chip head>paddingRight</Chip>
<Chip head>pr</Chip>
</Table.Cell>
<Table.Cell>
<Chip>number</Chip>
</Table.Cell>
<Table.Cell>
<Chip>0</Chip>
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>margin</Chip>
<Chip head>m</Chip>
</Table.Cell>
<Table.Cell>
<Chip>number</Chip>
</Table.Cell>
<Table.Cell>
<Chip>0</Chip>
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>marginX</Chip>
<Chip head>mx</Chip>
</Table.Cell>
<Table.Cell>
<Chip>number</Chip>
</Table.Cell>
<Table.Cell>
<Chip>0</Chip>
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>marginY</Chip>
<Chip head>my</Chip>
</Table.Cell>
<Table.Cell>
<Chip>number</Chip>
</Table.Cell>
<Table.Cell>
<Chip>0</Chip>
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>marginLeft</Chip>
<Chip head>ml</Chip>
</Table.Cell>
<Table.Cell>
<Chip>number</Chip>
</Table.Cell>
<Table.Cell>
<Chip>0</Chip>
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
<Chip head>marginRight</Chip>
<Chip head>mr</Chip>
</Table.Cell>
<Table.Cell>
<Chip>number</Chip>
@@ -109,7 +341,6 @@ Box is the lowest-level component in Canon. We use it internally to build all of
<Table.Cell>
<Chip>0</Chip>
</Table.Cell>
<Table.Cell>The right padding of the box.</Table.Cell>
</Table.Row>
</Table.Body>
</Table.Root>
@@ -18,7 +18,7 @@ import type { Meta, StoryObj } from '@storybook/react';
import { Box } from './box';
const meta = {
title: 'Components/Box',
title: 'Layout/Box',
component: Box,
parameters: {
layout: 'centered',
@@ -31,7 +31,13 @@ type Story = StoryObj<typeof meta>;
export const Basic: Story = {
render: () => (
<Box padding="medium" background="background">
<Box
padding="medium"
background="background"
paddingX="large"
paddingY="medium"
borderRadius="small"
>
Basic Box
</Box>
),
+1 -1
View File
@@ -22,7 +22,7 @@ type HTMLProperties = Omit<
keyof Sprinkles
>;
type BoxProps = Sprinkles &
export type BoxProps = Sprinkles &
HTMLProperties & {
as?: keyof JSX.IntrinsicElements;
};
@@ -0,0 +1,64 @@
export const alignItems = ['stretch', 'flex-start', 'center', 'flex-end'];
export const breakpoints = {
xs: {},
sm: { '@media': 'screen and (min-width: 640px)' },
md: { '@media': 'screen and (min-width: 768px)' },
lg: { '@media': 'screen and (min-width: 1024px)' },
xl: { '@media': 'screen and (min-width: 1280px)' },
'2xl': { '@media': 'screen and (min-width: 1536px)' },
};
export const borderRadius = {
none: 0,
small: '4px',
medium: '8px',
full: '9999px',
};
export const backgroundColors = {
background: 'var(--canon-color-background)',
elevation1: 'var(--canon-color-elevation1)',
elevation2: 'var(--canon-color-elevation2)',
transparent: 'transparent',
};
export const border = {
none: 'none',
thin: '1px solid var(--canon-outline)',
error: '1px solid var(--canon-error)',
};
export const boxShadows = {
small: 'var(--canon-box-shadow-small)',
medium: 'var(--canon-box-shadow-medium)',
large: 'var(--canon-box-shadow-large)',
};
export const colors = {
background: '#eff6ff',
};
export const display = ['none', 'flex', 'block', 'inline'];
export const flexDirection = ['row', 'column'] as const;
export const justifyContent = [
'stretch',
'flex-start',
'center',
'flex-end',
'space-around',
'space-between',
];
export const space = {
none: 0,
xxs: 'var(--space-xxs)',
xs: 'var(--space-xs)',
sm: 'var(--space-sm)',
md: 'var(--space-md)',
lg: 'var(--space-lg)',
xl: 'var(--space-xl)',
xxl: 'var(--space-xxl)',
};
@@ -14,66 +14,83 @@
* limitations under the License.
*/
import { defineProperties, createSprinkles } from '@vanilla-extract/sprinkles';
import {
alignItems,
borderRadius,
breakpoints,
colors,
backgroundColors,
display,
flexDirection,
justifyContent,
space,
boxShadows,
border,
} from './properties';
const space = {
none: 0,
small: '4px',
medium: '8px',
large: '16px',
// etc.
export const commonProperties = {
flexDirection,
justifyContent,
alignItems,
borderRadius,
boxShadow: boxShadows,
border,
paddingTop: space,
paddingBottom: space,
paddingLeft: space,
paddingRight: space,
marginTop: space,
marginBottom: space,
marginLeft: space,
marginRight: space,
gap: space,
};
const colors = {
background: '#eff6ff',
export const boxShorthands: Record<string, string[]> = {
padding: ['paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight'],
paddingX: ['paddingLeft', 'paddingRight'],
paddingY: ['paddingTop', 'paddingBottom'],
p: ['paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight'],
pt: ['paddingTop'],
pr: ['paddingRight'],
pb: ['paddingBottom'],
pl: ['paddingLeft'],
px: ['paddingLeft', 'paddingRight'],
py: ['paddingTop', 'paddingBottom'],
margin: ['marginTop', 'marginBottom', 'marginLeft', 'marginRight'],
marginX: ['marginLeft', 'marginRight'],
marginY: ['marginTop', 'marginBottom'],
m: ['marginTop', 'marginBottom', 'marginLeft', 'marginRight'],
mt: ['marginTop'],
mr: ['marginRight'],
mb: ['marginBottom'],
ml: ['marginLeft'],
mx: ['marginLeft', 'marginRight'],
my: ['marginTop', 'marginBottom'],
};
const responsiveProperties = defineProperties({
conditions: {
xs: {},
sm: { '@media': 'screen and (min-width: 640px)' },
md: { '@media': 'screen and (min-width: 768px)' },
lg: { '@media': 'screen and (min-width: 1024px)' },
xl: { '@media': 'screen and (min-width: 1280px)' },
'2xl': { '@media': 'screen and (min-width: 1536px)' },
},
conditions: breakpoints,
defaultCondition: 'xs',
properties: {
display: ['none', 'flex', 'block', 'inline'],
flexDirection: ['row', 'column'],
justifyContent: [
'stretch',
'flex-start',
'center',
'flex-end',
'space-around',
'space-between',
],
alignItems: ['stretch', 'flex-start', 'center', 'flex-end'],
paddingTop: space,
paddingBottom: space,
paddingLeft: space,
paddingRight: space,
// fontFamily: font,
gap: space,
// etc.
...commonProperties,
display,
},
shorthands: {
padding: ['paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight'],
paddingX: ['paddingLeft', 'paddingRight'],
paddingY: ['paddingTop', 'paddingBottom'],
...boxShorthands,
placeItems: ['justifyContent', 'alignItems'],
},
});
const colorProperties = defineProperties({
conditions: {
lightMode: {},
darkMode: { '@media': '(prefers-color-scheme: dark)' },
light: { selector: '[data-theme="light"] &' },
dark: { selector: '[data-theme="dark"] &' },
},
defaultCondition: 'lightMode',
defaultCondition: ['light', 'dark'],
properties: {
color: colors,
background: colors,
background: backgroundColors,
},
});
@@ -19,7 +19,8 @@ import { recipe } from '@vanilla-extract/recipes';
export const button = recipe({
base: {
all: 'unset',
display: 'inline-block',
display: 'inline-flex',
alignItems: 'center',
userSelect: 'none',
fontFamily: 'var(--canon-font-sans)',
fontWeight: 600,
@@ -16,6 +16,7 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './button';
import { Box } from '../box/box';
const meta = {
title: 'Components/Button',
@@ -63,6 +64,32 @@ export const Sizes: Story = {
),
};
export const WithIcons: Story = {
args: {
children: 'Button',
},
render: args => (
<div style={{ display: 'flex', gap: '10px' }}>
<Button {...args} iconStart="Cloud" />
<Button {...args} iconEnd="ArrowRight" />
<Button {...args} iconStart="Cloud" iconEnd="ArrowRight" />
</div>
),
};
export const FullWidth: Story = {
args: {
children: 'Button',
},
render: args => (
<Box>
<Button {...args} iconStart="Cloud" />
<Button {...args} iconEnd="ArrowRight" />
<Button {...args} iconStart="Cloud" iconEnd="ArrowRight" />
</Box>
),
};
export const Disabled: Story = {
args: {
children: 'Button',
@@ -16,12 +16,16 @@
import React from 'react';
import { button } from './button.css';
import { Box } from '../box/box';
import { Icon } from '../icon/icon';
import { IconNames } from '../icon/context';
export interface ButtonProps {
size?: 'small' | 'medium';
variant?: 'primary' | 'secondary';
children: React.ReactNode;
disabled?: boolean;
iconStart?: IconNames;
iconEnd?: IconNames;
}
export const Button = ({
@@ -29,6 +33,8 @@ export const Button = ({
variant = 'primary',
children,
disabled,
iconStart,
iconEnd,
...props
}: ButtonProps) => {
return (
@@ -38,7 +44,9 @@ export const Button = ({
disabled={disabled}
className={button({ size, variant, disabled })}
>
{iconStart && <Icon name={iconStart} />}
{children}
{iconEnd && <Icon name={iconEnd} />}
</Box>
);
};
+13 -4
View File
@@ -1,9 +1,15 @@
import React, { createContext, useContext, ReactNode } from 'react';
import { MoveUp, MoveDown } from 'lucide-react';
import { ArrowUp, ArrowDown, ArrowLeft, ArrowRight, Cloud } from 'lucide-react';
import { CustomIcon } from './custom-icon';
// List of icons available that can also be overridden.
export type IconNames = 'MoveDown' | 'MoveUp' | 'CustomIcon';
export type IconNames =
| 'ArrowDown'
| 'ArrowLeft'
| 'ArrowRight'
| 'ArrowUp'
| 'Cloud'
| 'CustomIcon';
type IconMap = Partial<Record<IconNames, React.ComponentType>>;
@@ -13,8 +19,11 @@ interface IconContextProps {
// Create a default icon map with only the necessary icons
const defaultIcons: IconMap = {
MoveUp,
MoveDown,
ArrowDown,
ArrowLeft,
ArrowRight,
ArrowUp,
Cloud,
CustomIcon,
};
@@ -18,7 +18,7 @@ const meta = {
},
},
args: {
name: 'MoveDown',
name: 'ArrowDown',
},
} satisfies Meta<typeof Icon>;
@@ -27,7 +27,7 @@ type Story = StoryObj<typeof meta>;
export const Primary: Story = {
args: {
name: 'MoveDown',
name: 'ArrowDown',
},
};
@@ -39,11 +39,11 @@ export const CustomIcon: Story = {
export const WithCustomIcon: Story = {
args: {
name: 'MoveDown',
name: 'ArrowDown',
},
decorators: [
Story => (
<IconProvider overrides={{ MoveDown: () => <div>Custom Icon</div> }}>
<IconProvider overrides={{ ArrowDown: () => <div>Custom Icon</div> }}>
<Story />
</IconProvider>
),
@@ -0,0 +1,37 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { defineProperties, createSprinkles } from '@vanilla-extract/sprinkles';
import { breakpoints } from '../box/properties';
import { boxShorthands, commonProperties } from '../box/sprinkles.css';
const responsiveProperties = defineProperties({
conditions: breakpoints,
defaultCondition: 'xs',
properties: {
...commonProperties,
},
shorthands: {
...boxShorthands,
direction: ['flexDirection'],
items: ['alignItems'],
justify: ['justifyContent'],
},
});
export const sprinkles = createSprinkles(responsiveProperties);
// It's a good idea to export the Sprinkles type too
export type Sprinkles = Parameters<typeof sprinkles>[0];
@@ -0,0 +1,21 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { style } from '@vanilla-extract/css';
export const stackStyles = style({
fontFamily: 'var(--canon-font-sans)',
display: 'flex',
});
@@ -0,0 +1,62 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { Stack } from './stack';
import { Box } from '../box/box';
const meta = {
title: 'Layout/Stack',
component: Stack,
parameters: {
layout: 'centered',
},
// tags: ['autodocs'],
} satisfies Meta<typeof Stack>;
const FakeBox = () => (
<Box
background="background"
paddingX="large"
paddingY="medium"
borderRadius="small"
>
Fake Box
</Box>
);
export default meta;
type Story = StoryObj<typeof meta>;
export const Column: Story = {
render: () => (
<Stack gap="medium" direction="column">
<FakeBox />
<FakeBox />
<FakeBox />
</Stack>
),
};
export const Row: Story = {
render: () => (
<Stack gap="medium" direction="row">
<FakeBox />
<FakeBox />
<FakeBox />
</Stack>
),
};
@@ -0,0 +1,59 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createElement } from 'react';
import { sprinkles, Sprinkles } from './sprinkles.css';
import { stackStyles } from './stack.css';
type HTMLProperties = Omit<
React.AllHTMLAttributes<HTMLElement>,
keyof Sprinkles
>;
export type StackProps = Sprinkles &
HTMLProperties & {
as?: keyof JSX.IntrinsicElements;
};
export const Stack = ({
as = 'div',
className,
style,
...props
}: StackProps) => {
const sprinklesProps: Record<string, unknown> = {};
const nativeProps: Record<string, unknown> = {};
// Split props between sprinkles and native HTML props
Object.entries(props).forEach(([key, value]) => {
if (value === undefined) return;
if (sprinkles.properties.has(key as keyof Sprinkles)) {
sprinklesProps[key] = value;
} else {
nativeProps[key] = value;
}
});
const sprinklesClassName = sprinkles(sprinklesProps);
return createElement(as, {
className: [stackStyles, sprinklesClassName, className]
.filter(Boolean)
.join(' '),
style,
...nativeProps,
});
};
+2 -2
View File
@@ -3,10 +3,10 @@ import { Text } from '../storybook/text';
import { ComponentStatus } from '../storybook/component-status';
import { Columns } from '../storybook/columns';
![Canon Header](header.png)
<Unstyled>
<img src="header.png" style={{ width: '100%', marginTop: '-16px' }} />
<Text style={{ marginTop: '64px' }}>
Welcome to the Canon, the new library for building Backstage plugins. This
project is still under active development but we will make sure to document
+1 -3
View File
@@ -1,7 +1,5 @@
import { Unstyled, Source } from '@storybook/blocks';
import { Title } from '../storybook/title';
import { Text } from '../storybook/text';
import { Chip } from '../storybook/chip';
import { Title, Text, Chip } from '../storybook';
import * as Table from '../storybook/table';
<Unstyled>
+24 -12
View File
@@ -13,17 +13,29 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { style } from '@vanilla-extract/css';
import { recipe } from '@vanilla-extract/recipes';
export const chipStyles = style({
display: 'inline-flex',
alignItems: 'center',
fontFamily: 'Geist Mono, monospace',
fontSize: '13px',
borderRadius: '6px',
padding: '0px 8px',
height: '24px',
backgroundColor: '#eaf2fd',
color: '#2563eb',
marginRight: '4px',
export const chipStyles = recipe({
base: {
display: 'inline-flex',
alignItems: 'center',
fontFamily: 'Geist Mono, monospace',
fontSize: '13px',
borderRadius: '6px',
padding: '0px 8px',
height: '24px',
marginRight: '4px',
},
variants: {
head: {
true: {
backgroundColor: '#eaf2fd',
color: '#2563eb',
},
false: {
backgroundColor: '#f0f0f0',
color: '#5d5d5d',
},
},
},
});
+8 -2
View File
@@ -16,6 +16,12 @@
import React from 'react';
import { chipStyles } from './chip.css';
export const Chip = ({ children }: { children: React.ReactNode }) => {
return <span className={chipStyles}>{children}</span>;
export const Chip = ({
children,
head = false,
}: {
children: React.ReactNode;
head?: boolean;
}) => {
return <span className={chipStyles({ head })}>{children}</span>;
};
+4
View File
@@ -0,0 +1,4 @@
export * from './chip';
export * from './table';
export * from './title';
export * from './text';
@@ -1,74 +0,0 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import {
tableStyles,
cellStyles,
headerCellStyles,
rowStyles,
wrapperStyles,
chipStyles,
headerRowStyles,
typeStyles,
} from './props-table.css';
type PropsTableData = {
prop: string;
type: string | string[];
default: string;
description: string;
};
export const PropsTable = ({ data }: { data: PropsTableData[] }) => {
return (
<div className={wrapperStyles}>
<table className={tableStyles}>
<thead className={headerRowStyles}>
<tr className={rowStyles}>
<th className={`${cellStyles} ${headerCellStyles}`}>Prop</th>
<th className={`${cellStyles} ${headerCellStyles}`}>Type</th>
<th className={`${cellStyles} ${headerCellStyles}`}>Default</th>
<th className={`${cellStyles} ${headerCellStyles}`}>Description</th>
</tr>
</thead>
<tbody>
{data.map(item => (
<tr className={rowStyles}>
<td className={cellStyles}>
<span className={chipStyles}>{item.prop}</span>
</td>
<td className={cellStyles}>
<div className={typeStyles}>
{Array.isArray(item.type) ? (
item.type.map(type => (
<span className={chipStyles}>{type}</span>
))
) : (
<span className={chipStyles}>{item.type}</span>
)}
</div>
</td>
<td className={cellStyles}>
<span className={chipStyles}>{item.default}</span>
</td>
<td className={cellStyles}>{item.description}</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
@@ -1,70 +0,0 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { style } from '@vanilla-extract/css';
export const wrapperStyles = style({
border: '1px solid #e7e7e7',
borderRadius: '4px',
overflow: 'hidden',
});
export const tableStyles = style({
width: '100%',
margin: '0 !important',
padding: '0 !important',
});
export const cellStyles = style({
padding: '12px 16px !important',
border: 'none !important',
textAlign: 'left',
backgroundColor: 'white !important',
});
export const headerCellStyles = style({
backgroundColor: '#f5f5f5 !important',
fontWeight: 'bold',
});
export const rowStyles = style({
border: 'none !important',
borderBottom: '1px solid #e7e7e7 !important',
selectors: {
'&:last-child': {
borderBottom: 'none !important',
},
},
});
export const chipStyles = style({
display: 'inline-block',
fontSize: '14px !important',
border: '1px solid #e7e7e7',
borderRadius: '6px',
padding: '0px 6px',
height: '24px',
});
export const headerRowStyles = style({
borderBottom: '1px solid #e7e7e7 !important',
});
export const typeStyles = style({
display: 'flex',
flexWrap: 'wrap',
flexDirection: 'row',
gap: '8px',
});
@@ -47,6 +47,7 @@ export const headerCellStyles = style({
backgroundColor: '#f5f5f5 !important',
borderBottom: '1px solid #e7e7e7 !important',
fontWeight: '500',
fontSize: '14px',
});
export const rowStyles = style({
+13 -5
View File
@@ -6,13 +6,26 @@
--canon-surface-2: #000;
--canon-outline: #666;
--canon-outline-focus: #ccc;
--canon-error: #f50000;
--canon-text-primary: #f0f0f0;
--canon-text-secondary: #666;
--canon-box-shadow-small: 0 0 0 1px rgba(0, 0, 0, 0.05);
--canon-box-shadow-medium: 0 0 0 1px rgba(0, 0, 0, 0.1);
--canon-box-shadow-large: 0 0 0 1px rgba(0, 0, 0, 0.2);
--canon-font-sans: 'Geist', serif;
--canon-font-monospace: 'Monospace', monospace;
--canon-font-emoji: 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
'Noto Color Emoji';
--space-unit: 1em;
--space-xxs: calc(0.25 * var(--space-unit));
--space-xs: calc(0.5 * var(--space-unit));
--space-sm: calc(0.75 * var(--space-unit));
--space-md: calc(1.25 * var(--space-unit));
--space-lg: calc(2 * var(--space-unit));
--space-xl: calc(3.25 * var(--space-unit));
--space-xxl: calc(5.25 * var(--space-unit));
}
/* Dark theme */
@@ -25,9 +38,4 @@
--canon-outline-focus: #ccc;
--canon-text-primary: #f0f0f0;
--canon-text-secondary: #666;
--canon-font-sans: 'Geist', serif;
--canon-font-monospace: 'Monospace', monospace;
--canon-font-emoji: 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
'Noto Color Emoji';
}
+175 -187
View File
@@ -4120,16 +4120,15 @@ __metadata:
"@base_ui/react": ^1.0.0-alpha.3
"@chromatic-com/storybook": ^3.2.2
"@eslint/js": ^9.13.0
"@storybook/addon-essentials": ^8.4.4
"@storybook/addon-interactions": ^8.4.4
"@storybook/addon-onboarding": ^8.4.4
"@storybook/addon-essentials": ^8.4.5
"@storybook/addon-interactions": ^8.4.5
"@storybook/addon-styling-webpack": ^1.0.1
"@storybook/addon-themes": ^8.4.4
"@storybook/addon-themes": ^8.4.5
"@storybook/addon-webpack5-compiler-swc": ^1.0.5
"@storybook/blocks": ^8.4.4
"@storybook/react": ^8.4.4
"@storybook/react-webpack5": ^8.4.4
"@storybook/test": ^8.4.4
"@storybook/blocks": ^8.4.5
"@storybook/react": ^8.4.5
"@storybook/react-webpack5": ^8.4.5
"@storybook/test": ^8.4.5
"@testing-library/jest-dom": ^6.0.0
"@types/react": ^18.3.11
"@types/react-dom": ^18.3.1
@@ -4142,11 +4141,11 @@ __metadata:
eslint: ^9.13.0
eslint-plugin-react-hooks: ^5.0.0
eslint-plugin-react-refresh: ^0.4.13
eslint-plugin-storybook: ^0.11.0
eslint-plugin-storybook: ^0.11.1
globals: ^15.11.0
lucide-react: ^0.460.0
mini-css-extract-plugin: ^2.9.2
storybook: ^8.4.4
storybook: ^8.4.5
typescript: ~5.6.2
typescript-eslint: ^8.10.0
webpack-merge: ^6.0.1
@@ -17540,9 +17539,9 @@ __metadata:
languageName: node
linkType: hard
"@storybook/addon-actions@npm:8.4.4":
version: 8.4.4
resolution: "@storybook/addon-actions@npm:8.4.4"
"@storybook/addon-actions@npm:8.4.5":
version: 8.4.5
resolution: "@storybook/addon-actions@npm:8.4.5"
dependencies:
"@storybook/global": ^5.0.0
"@types/uuid": ^9.0.1
@@ -17550,132 +17549,121 @@ __metadata:
polished: ^4.2.2
uuid: ^9.0.0
peerDependencies:
storybook: ^8.4.4
checksum: 1d9df025ec0012e8ce8e529f877d1b0df21bae35fb3d9bb442d544826641710ee800a57699f0847e7b7f561b2c5f638cfbf0c7959e5b4e28a8e36dbf8031307f
storybook: ^8.4.5
checksum: 7bc9b3091b62419170aa841d2006b88cffa111557f3451b96f9f61310c83138a131f3e400b05fbd5c774d5e93b15ebd629844844b6ba099ee968fed2e5085d54
languageName: node
linkType: hard
"@storybook/addon-backgrounds@npm:8.4.4":
version: 8.4.4
resolution: "@storybook/addon-backgrounds@npm:8.4.4"
"@storybook/addon-backgrounds@npm:8.4.5":
version: 8.4.5
resolution: "@storybook/addon-backgrounds@npm:8.4.5"
dependencies:
"@storybook/global": ^5.0.0
memoizerific: ^1.11.3
ts-dedent: ^2.0.0
peerDependencies:
storybook: ^8.4.4
checksum: ed094a4b62a5a0a68b11b88544969a3aa5ed9ea47b3e369c8f84d5b53ce0f88008912a790a3a8783a39b9698c5ca7d8089028a019b47d6f82fe43741151297fc
storybook: ^8.4.5
checksum: a8b68fc20463087cc66d52c933825c9ba73f81c4ab14eea607271f20ad0e108581bb75dddd06fd01a8a55637b48a14342543174bbacbc7609388c659f0257906
languageName: node
linkType: hard
"@storybook/addon-controls@npm:8.4.4":
version: 8.4.4
resolution: "@storybook/addon-controls@npm:8.4.4"
"@storybook/addon-controls@npm:8.4.5":
version: 8.4.5
resolution: "@storybook/addon-controls@npm:8.4.5"
dependencies:
"@storybook/global": ^5.0.0
dequal: ^2.0.2
ts-dedent: ^2.0.0
peerDependencies:
storybook: ^8.4.4
checksum: 46abe5cbd484c70fe757d99535157a07e75493a76b2c4a3aa08f48bb3e547330059d24ef978cd85933dd3b5602b9abc2836a12baef61ea521636d1cfa6585be3
storybook: ^8.4.5
checksum: 673cdec1c5b174a317c295bcbbcb464f0d2778e6c403b3ae591a96d59510a96b9a97121b250d13e83886168396e5ee6877104e04da957950c3d87145ec76007b
languageName: node
linkType: hard
"@storybook/addon-docs@npm:8.4.4":
version: 8.4.4
resolution: "@storybook/addon-docs@npm:8.4.4"
"@storybook/addon-docs@npm:8.4.5":
version: 8.4.5
resolution: "@storybook/addon-docs@npm:8.4.5"
dependencies:
"@mdx-js/react": ^3.0.0
"@storybook/blocks": 8.4.4
"@storybook/csf-plugin": 8.4.4
"@storybook/react-dom-shim": 8.4.4
"@storybook/blocks": 8.4.5
"@storybook/csf-plugin": 8.4.5
"@storybook/react-dom-shim": 8.4.5
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
ts-dedent: ^2.0.0
peerDependencies:
storybook: ^8.4.4
checksum: 10154624ca94018b0a51b19915b05cde7953f22d84739e263360072fcd7e46dab94d041575e040148c8250fc4f78a0b46962eb317d7d4d256da27b1bdb513eee
storybook: ^8.4.5
checksum: 04b15137c082e5b6f6d55f5a251a4a34a08c44f7ad926615f5a99093bd26b044ad40cbdb314a3a76154de00dd2434c61f893ca2ce697193addd03e0650c6d4da
languageName: node
linkType: hard
"@storybook/addon-essentials@npm:^8.4.4":
version: 8.4.4
resolution: "@storybook/addon-essentials@npm:8.4.4"
"@storybook/addon-essentials@npm:^8.4.5":
version: 8.4.5
resolution: "@storybook/addon-essentials@npm:8.4.5"
dependencies:
"@storybook/addon-actions": 8.4.4
"@storybook/addon-backgrounds": 8.4.4
"@storybook/addon-controls": 8.4.4
"@storybook/addon-docs": 8.4.4
"@storybook/addon-highlight": 8.4.4
"@storybook/addon-measure": 8.4.4
"@storybook/addon-outline": 8.4.4
"@storybook/addon-toolbars": 8.4.4
"@storybook/addon-viewport": 8.4.4
"@storybook/addon-actions": 8.4.5
"@storybook/addon-backgrounds": 8.4.5
"@storybook/addon-controls": 8.4.5
"@storybook/addon-docs": 8.4.5
"@storybook/addon-highlight": 8.4.5
"@storybook/addon-measure": 8.4.5
"@storybook/addon-outline": 8.4.5
"@storybook/addon-toolbars": 8.4.5
"@storybook/addon-viewport": 8.4.5
ts-dedent: ^2.0.0
peerDependencies:
storybook: ^8.4.4
checksum: c8dfe7be1eac6280e4ae801a33a02f99f47e0430920d22505b80fe8684eaabaa9c977a34f90c3265185f11ded930c5b29cdc11fbaa715eec57cab95ad4343750
storybook: ^8.4.5
checksum: a00c0e13763076b2bdf9923b75ff57b3f88c9ef64cebc405bb129f02fb9e69a4e69aa0d277a4d98cb181c11681eb8db488585a1dcf8f92f1ff8b371b4c6810fb
languageName: node
linkType: hard
"@storybook/addon-highlight@npm:8.4.4":
version: 8.4.4
resolution: "@storybook/addon-highlight@npm:8.4.4"
"@storybook/addon-highlight@npm:8.4.5":
version: 8.4.5
resolution: "@storybook/addon-highlight@npm:8.4.5"
dependencies:
"@storybook/global": ^5.0.0
peerDependencies:
storybook: ^8.4.4
checksum: d465e096de2cf5850b29a15dafd1e18f5f82905a164eef483aa40bfd6423aa6746dde1a01d25d71b711eed9cd24eed059874512fae174b758442c6060f1f667f
storybook: ^8.4.5
checksum: 8caa57aaee1a6704e757d4711899683d83778ad426015871f93cbb4e44ffb07a7a5e81a1bed7c36b335fa3687ce36f7a6f41738aa040bfbeea623100ed831090
languageName: node
linkType: hard
"@storybook/addon-interactions@npm:^8.4.4":
version: 8.4.4
resolution: "@storybook/addon-interactions@npm:8.4.4"
"@storybook/addon-interactions@npm:^8.4.5":
version: 8.4.5
resolution: "@storybook/addon-interactions@npm:8.4.5"
dependencies:
"@storybook/global": ^5.0.0
"@storybook/instrumenter": 8.4.4
"@storybook/test": 8.4.4
"@storybook/instrumenter": 8.4.5
"@storybook/test": 8.4.5
polished: ^4.2.2
ts-dedent: ^2.2.0
peerDependencies:
storybook: ^8.4.4
checksum: edd0086f06bef702bc13bfd6700dd771312f01a2f07c5019171865a24cdda44d154bf8ec5e8e57b317a281e2d2fed83ad483a6f08c138e2954e1939f4cc7fe87
storybook: ^8.4.5
checksum: ded85ef9b78e657a919bfaf7de4b616419e28d89ea74d9990016f699194ad02bb65116a950d6a5b6de6127c44932066ad020898be0fdf50a19dea4e9a662f2bd
languageName: node
linkType: hard
"@storybook/addon-measure@npm:8.4.4":
version: 8.4.4
resolution: "@storybook/addon-measure@npm:8.4.4"
"@storybook/addon-measure@npm:8.4.5":
version: 8.4.5
resolution: "@storybook/addon-measure@npm:8.4.5"
dependencies:
"@storybook/global": ^5.0.0
tiny-invariant: ^1.3.1
peerDependencies:
storybook: ^8.4.4
checksum: 2b47ac51d35365776f527ed316aad028b88b6e75471614dc17adb8f5efa5a6d2cf0718f6ab166f86fea4b1483db5871142a3e68130995fc422c787548dceed00
storybook: ^8.4.5
checksum: c6e177f8c2ae68984cde8502cf303c4ee69798cd3b9453aea9a8df5c30d42f4ec8b58d416ee8fdd2f5110c3d837c871e96953bf62225b13476da0dc8cfe6e7e0
languageName: node
linkType: hard
"@storybook/addon-onboarding@npm:^8.4.4":
version: 8.4.4
resolution: "@storybook/addon-onboarding@npm:8.4.4"
dependencies:
react-confetti: ^6.1.0
peerDependencies:
storybook: ^8.4.4
checksum: 182ecbe65830132adbc4f87cde2c4dc562e0cd2417d60064d50f47e37e5b0259b3928c78f46cfe083bd485b51a27bdddaaa036bbfe8eb38ebe0f236e620923c1
languageName: node
linkType: hard
"@storybook/addon-outline@npm:8.4.4":
version: 8.4.4
resolution: "@storybook/addon-outline@npm:8.4.4"
"@storybook/addon-outline@npm:8.4.5":
version: 8.4.5
resolution: "@storybook/addon-outline@npm:8.4.5"
dependencies:
"@storybook/global": ^5.0.0
ts-dedent: ^2.0.0
peerDependencies:
storybook: ^8.4.4
checksum: 41fcccfa5d97271d014073a75d84aa04b8c626bd7f5403b50fa9d2782ae0c6f85a9ed5821f34f9c551db6e580a1e5d079a3c9c2698cf6a7e5dc909177da25299
storybook: ^8.4.5
checksum: 41567f91cee84920d66f657b40f262c95a9a046aed6e9db161624d6adcf77ce9acb7d433c7f9e929da4dee048e0842015d0bc51a63fb8468f69f560067e5234f
languageName: node
linkType: hard
@@ -17690,34 +17678,34 @@ __metadata:
languageName: node
linkType: hard
"@storybook/addon-themes@npm:^8.4.4":
version: 8.4.4
resolution: "@storybook/addon-themes@npm:8.4.4"
"@storybook/addon-themes@npm:^8.4.5":
version: 8.4.5
resolution: "@storybook/addon-themes@npm:8.4.5"
dependencies:
ts-dedent: ^2.0.0
peerDependencies:
storybook: ^8.4.4
checksum: b7961e1b78cd7374b47b920dbbd475d3f626f5fa98a8c43e7dadf286ba8007f194e573375dc3e6dafbc952d749134d7e6f8db0ea28f361d5986ea2f34eb8a93b
storybook: ^8.4.5
checksum: 0f76936ce687d126d886cc8f7080a15717cee3fe4ff7286f4a0a5da302edf38c14d5feb9c536078d982d268b118a9f38ea97ad310ce43326da959210450995f7
languageName: node
linkType: hard
"@storybook/addon-toolbars@npm:8.4.4":
version: 8.4.4
resolution: "@storybook/addon-toolbars@npm:8.4.4"
"@storybook/addon-toolbars@npm:8.4.5":
version: 8.4.5
resolution: "@storybook/addon-toolbars@npm:8.4.5"
peerDependencies:
storybook: ^8.4.4
checksum: fd18dd42833304dad2a87c27f8013187da2ebaaa219bec1bae0a269ae5c8e5696584ad5d49d8f3938dee8f29906c87b8b3db21a23aae7caacab4e878b579794f
storybook: ^8.4.5
checksum: fa914838d23b68199c355672674ad6f84bd3db0f2b961fd05ebba916a8c1dd1026ed9568ae97b34e9b0d657d4d4d9d64d69431d6c6a04b2e4bb39d4ddc93446c
languageName: node
linkType: hard
"@storybook/addon-viewport@npm:8.4.4":
version: 8.4.4
resolution: "@storybook/addon-viewport@npm:8.4.4"
"@storybook/addon-viewport@npm:8.4.5":
version: 8.4.5
resolution: "@storybook/addon-viewport@npm:8.4.5"
dependencies:
memoizerific: ^1.11.3
peerDependencies:
storybook: ^8.4.4
checksum: da66546f70c437c2a0da184c76c587a526ee325931849e706518a06d598fb272ecf5838b9db52066e0548de5738efde54bd9c024a5ac626c5ca95ad1ec42bc42
storybook: ^8.4.5
checksum: 72d70129e8d4c223608a66a7e6630be21ee05f403ef54afc72344489655e38256d644503f74ed9f363a18d967f22fa9da36ce4bc082b6a464c4fdb5e50d598ce
languageName: node
linkType: hard
@@ -17731,9 +17719,9 @@ __metadata:
languageName: node
linkType: hard
"@storybook/blocks@npm:8.4.4, @storybook/blocks@npm:^8.4.4":
version: 8.4.4
resolution: "@storybook/blocks@npm:8.4.4"
"@storybook/blocks@npm:8.4.5, @storybook/blocks@npm:^8.4.5":
version: 8.4.5
resolution: "@storybook/blocks@npm:8.4.5"
dependencies:
"@storybook/csf": ^0.1.11
"@storybook/icons": ^1.2.12
@@ -17741,21 +17729,21 @@ __metadata:
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
storybook: ^8.4.4
storybook: ^8.4.5
peerDependenciesMeta:
react:
optional: true
react-dom:
optional: true
checksum: 65a68772c0a43a3b82b4b3fce10c6e0e324482a26020d48d1906517a9e94fcee53b63b93dbba8a796969ca957bc6b1855ea09fc440734867922f6be546fee801
checksum: f80d320d75fc74cd15c7b3a4d58de286f617120829bb5c319f845d2e2310ef2f2e159e69cf3fd3906c8be47e34cd95e879c565d09f0bfe360e73df694c90bd79
languageName: node
linkType: hard
"@storybook/builder-webpack5@npm:8.4.4":
version: 8.4.4
resolution: "@storybook/builder-webpack5@npm:8.4.4"
"@storybook/builder-webpack5@npm:8.4.5":
version: 8.4.5
resolution: "@storybook/builder-webpack5@npm:8.4.5"
dependencies:
"@storybook/core-webpack": 8.4.4
"@storybook/core-webpack": 8.4.5
"@types/node": ^22.0.0
"@types/semver": ^7.3.4
browser-assert: ^1.2.1
@@ -17781,38 +17769,38 @@ __metadata:
webpack-hot-middleware: ^2.25.1
webpack-virtual-modules: ^0.6.0
peerDependencies:
storybook: ^8.4.4
storybook: ^8.4.5
peerDependenciesMeta:
typescript:
optional: true
checksum: 5682f34de0fb6eb3179c773773b82407d3f23b8647a31628c51678f928f178286db1c81f9a01b8e357b11ddd8c1d59e50bd147c5dca059994eb6f9a0f204cb4d
checksum: 7cc0ae634687d75a0a955b9182ddf3341c4eb3197c8e9e772029a5a3c7da8018da9484361fa2a44e1fcaa43728432cd1bc842b05acb7595e929c6850d48d09f7
languageName: node
linkType: hard
"@storybook/components@npm:8.4.4":
version: 8.4.4
resolution: "@storybook/components@npm:8.4.4"
"@storybook/components@npm:8.4.5":
version: 8.4.5
resolution: "@storybook/components@npm:8.4.5"
peerDependencies:
storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0
checksum: ca60bd5911669112af8d59e1b424e564a681e37c3f6ac59bceea69a08adddb478b965a7207f266591ec0daca74c8f674fdf3e21fdba5c794b80f13331667913a
checksum: dd14e0a2d40f6590fd92204f3b40d4437403b7be311fa797250bd71fe4b38ade78389d41d2617fa5e75cfa0e1538366ca1154149c0894433245c23cebc4dfc73
languageName: node
linkType: hard
"@storybook/core-webpack@npm:8.4.4":
version: 8.4.4
resolution: "@storybook/core-webpack@npm:8.4.4"
"@storybook/core-webpack@npm:8.4.5":
version: 8.4.5
resolution: "@storybook/core-webpack@npm:8.4.5"
dependencies:
"@types/node": ^22.0.0
ts-dedent: ^2.0.0
peerDependencies:
storybook: ^8.4.4
checksum: 0e1c130af8893d3e1d76d212ca534e93f948e2a7e57ffa0cb7879eb49b9cf3a9a3306d690c0831bc9e9fe4ead3c9b3127eb9a01a229db18d811c7cb0b7356f7f
storybook: ^8.4.5
checksum: 72760a54f3b6c7e87889e773e062ea8d7543375a950396f03e8a979fa586ebbe766b9d629432cbc8a07f74e24b0d9fdbe4bbdc39fe1269d706fce0ce3c0aeeae
languageName: node
linkType: hard
"@storybook/core@npm:8.4.4":
version: 8.4.4
resolution: "@storybook/core@npm:8.4.4"
"@storybook/core@npm:8.4.5":
version: 8.4.5
resolution: "@storybook/core@npm:8.4.5"
dependencies:
"@storybook/csf": ^0.1.11
better-opn: ^3.0.2
@@ -17830,18 +17818,18 @@ __metadata:
peerDependenciesMeta:
prettier:
optional: true
checksum: c31995bca74d8c364046bc3f6bbe891331f8e779adaf4b113f57fd9f0c5007f23fa6bb338ffc7cb72ee39e8eec16001cd267de347f90b9aeeb42d6e712d6605e
checksum: cfc7c93508befaed12314c61a64d892f543c16cff61b841ab5d74f666b88f6778aa3dd84095325074d4bc85bfde99a69ffc674e93200b457e33784b3ceccf730
languageName: node
linkType: hard
"@storybook/csf-plugin@npm:8.4.4":
version: 8.4.4
resolution: "@storybook/csf-plugin@npm:8.4.4"
"@storybook/csf-plugin@npm:8.4.5":
version: 8.4.5
resolution: "@storybook/csf-plugin@npm:8.4.5"
dependencies:
unplugin: ^1.3.1
peerDependencies:
storybook: ^8.4.4
checksum: 109c54af8aabaa64c2eeb8b0b6f1379b3588b8c1c3d4da828e0a0c8f6479960d64adc4635e911484915ac651061aa15e218cde1dd7be27562ce8e6ba79be7cae
storybook: ^8.4.5
checksum: df59430f3f212ad8a11efdfa3ef01d8fa73322233338488fb97a9e2e031c4846a6b307acbf16edd72ab8edb02e86740b5a0fff0e0dec4dd15850573a92831c98
languageName: node
linkType: hard
@@ -17871,24 +17859,24 @@ __metadata:
languageName: node
linkType: hard
"@storybook/instrumenter@npm:8.4.4":
version: 8.4.4
resolution: "@storybook/instrumenter@npm:8.4.4"
"@storybook/instrumenter@npm:8.4.5":
version: 8.4.5
resolution: "@storybook/instrumenter@npm:8.4.5"
dependencies:
"@storybook/global": ^5.0.0
"@vitest/utils": ^2.1.1
peerDependencies:
storybook: ^8.4.4
checksum: ec76f93b04471536b76134de083483369f44e5414d766a7d183b50e588a846461d5bae59fb3f6a72621c65ee9b907b43c1fb47fcbe5e56040cdf7d8c33a9050a
storybook: ^8.4.5
checksum: 14093e36b14871e74331074b7261f9103ddfe1233dffa7f722a8e36c955cb5812d7e3a202b8a7673dbdceb10853d0989cef1ff8e928b058635b2032188905842
languageName: node
linkType: hard
"@storybook/manager-api@npm:8.4.4":
version: 8.4.4
resolution: "@storybook/manager-api@npm:8.4.4"
"@storybook/manager-api@npm:8.4.5":
version: 8.4.5
resolution: "@storybook/manager-api@npm:8.4.5"
peerDependencies:
storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0
checksum: 9eac4488f55e1860940e0e850a48f4278a7b6e6325c7381007447626715a8f8e52d6f876f6caaa2597787fb19c40a33f96d34b56558190f7be4772cac7805ebc
checksum: f6bc0ef3703afceedb862b77f22e169a173525c6d0483ba4ae5d1daf5b19c8077b33ef3fd634571e3ded93b2d4bd4a9e182c23d4395d1bfe8fdb6c98bdcc119f
languageName: node
linkType: hard
@@ -17901,12 +17889,12 @@ __metadata:
languageName: node
linkType: hard
"@storybook/preset-react-webpack@npm:8.4.4":
version: 8.4.4
resolution: "@storybook/preset-react-webpack@npm:8.4.4"
"@storybook/preset-react-webpack@npm:8.4.5":
version: 8.4.5
resolution: "@storybook/preset-react-webpack@npm:8.4.5"
dependencies:
"@storybook/core-webpack": 8.4.4
"@storybook/react": 8.4.4
"@storybook/core-webpack": 8.4.5
"@storybook/react": 8.4.5
"@storybook/react-docgen-typescript-plugin": 1.0.6--canary.9.0c3f3b7.0
"@types/node": ^22.0.0
"@types/semver": ^7.3.4
@@ -17920,20 +17908,20 @@ __metadata:
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
storybook: ^8.4.4
storybook: ^8.4.5
peerDependenciesMeta:
typescript:
optional: true
checksum: 9fd0eb36925decb1625d2075ecb92deb35faf56b9de02da1a98e26036c021d11b13b0b991496f797042b03a292476bdeaac9fdfa2aa9d869b41ebf4912eb592d
checksum: 059e35135c7770daf49338bf72d999b277cadec1c7f21175eac962448789fc1c2964e37973d8c18bf4a374a8838bdf369e0c2935cb188ffbd860d60cadda3c2e
languageName: node
linkType: hard
"@storybook/preview-api@npm:8.4.4":
version: 8.4.4
resolution: "@storybook/preview-api@npm:8.4.4"
"@storybook/preview-api@npm:8.4.5":
version: 8.4.5
resolution: "@storybook/preview-api@npm:8.4.5"
peerDependencies:
storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0
checksum: ad95ce132d598e8b13da70a319ffdfaf41e5f8629cfb4552a577f3624a92d4a168e1de5220fe7c735babbd5945dd2182448a910b246a458cddde2afe7378461e
checksum: 832bee373583fb55102459445ae7f3e8bca0ff80a4220aa656bf6baf8661e0c65184f080b1e10695f8fbb948fd8d48cc9728d19d1bc6993418251126380d4818
languageName: node
linkType: hard
@@ -17955,86 +17943,86 @@ __metadata:
languageName: node
linkType: hard
"@storybook/react-dom-shim@npm:8.4.4":
version: 8.4.4
resolution: "@storybook/react-dom-shim@npm:8.4.4"
"@storybook/react-dom-shim@npm:8.4.5":
version: 8.4.5
resolution: "@storybook/react-dom-shim@npm:8.4.5"
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
storybook: ^8.4.4
checksum: a1d556058ba1cb047113c60b7d0f44f00681635442ecf65cf9784907c735e44196f8daf77b5292de16f4e9a5f8c0f0342ceaf182081003945af08f721648308d
storybook: ^8.4.5
checksum: b1f176b85783bfa9c43f49a7ef69c04ff92079e5ba8ca76b1b9f46b814c19db6e882137c35ebd91424e2e51bfa0d34eb3f0b84d4ed9e8a2b93875b7f5563b310
languageName: node
linkType: hard
"@storybook/react-webpack5@npm:^8.4.4":
version: 8.4.4
resolution: "@storybook/react-webpack5@npm:8.4.4"
"@storybook/react-webpack5@npm:^8.4.5":
version: 8.4.5
resolution: "@storybook/react-webpack5@npm:8.4.5"
dependencies:
"@storybook/builder-webpack5": 8.4.4
"@storybook/preset-react-webpack": 8.4.4
"@storybook/react": 8.4.4
"@storybook/builder-webpack5": 8.4.5
"@storybook/preset-react-webpack": 8.4.5
"@storybook/react": 8.4.5
"@types/node": ^22.0.0
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
storybook: ^8.4.4
storybook: ^8.4.5
typescript: ">= 4.2.x"
peerDependenciesMeta:
typescript:
optional: true
checksum: 9961fa3d3c49496a25e1b208882896cdd8b586f146ba246e7d95c4ac074d9f7a3fca47b30e15c5b0414e2662463055f79f51e5fbc7128914fecb0b5afe548193
checksum: d15986993f0353b7a4a88945f560e47b24849cc202f16e5ab7ce469bfdc507377d58d638f1ae04c34a506ec6343327920fdb225be5621b44f659ca4073da3d24
languageName: node
linkType: hard
"@storybook/react@npm:8.4.4, @storybook/react@npm:^8.4.4":
version: 8.4.4
resolution: "@storybook/react@npm:8.4.4"
"@storybook/react@npm:8.4.5, @storybook/react@npm:^8.4.5":
version: 8.4.5
resolution: "@storybook/react@npm:8.4.5"
dependencies:
"@storybook/components": 8.4.4
"@storybook/components": 8.4.5
"@storybook/global": ^5.0.0
"@storybook/manager-api": 8.4.4
"@storybook/preview-api": 8.4.4
"@storybook/react-dom-shim": 8.4.4
"@storybook/theming": 8.4.4
"@storybook/manager-api": 8.4.5
"@storybook/preview-api": 8.4.5
"@storybook/react-dom-shim": 8.4.5
"@storybook/theming": 8.4.5
peerDependencies:
"@storybook/test": 8.4.4
"@storybook/test": 8.4.5
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
storybook: ^8.4.4
storybook: ^8.4.5
typescript: ">= 4.2.x"
peerDependenciesMeta:
"@storybook/test":
optional: true
typescript:
optional: true
checksum: b155747739dcae8951b76f83938c032ab6a2e793e434dc738dd3d9e547e3d806efe76cecb2c4d0a1716bf83e54953f3f0a920dc501b687356457f522924cd943
checksum: ea3f2008186d7b3556cdb1b0942ce2cb0b7d52ee322e3680f6f32f5a723a2d676fe4ba2bc2ea0060112453cd8652861c0b2d154a5c34e7d5b69ead9603c2ce68
languageName: node
linkType: hard
"@storybook/test@npm:8.4.4, @storybook/test@npm:^8.4.4":
version: 8.4.4
resolution: "@storybook/test@npm:8.4.4"
"@storybook/test@npm:8.4.5, @storybook/test@npm:^8.4.5":
version: 8.4.5
resolution: "@storybook/test@npm:8.4.5"
dependencies:
"@storybook/csf": ^0.1.11
"@storybook/global": ^5.0.0
"@storybook/instrumenter": 8.4.4
"@storybook/instrumenter": 8.4.5
"@testing-library/dom": 10.4.0
"@testing-library/jest-dom": 6.5.0
"@testing-library/user-event": 14.5.2
"@vitest/expect": 2.0.5
"@vitest/spy": 2.0.5
peerDependencies:
storybook: ^8.4.4
checksum: 28cd3e1b26f5b2b411988f5f55d7bcb0d2e15909c0ed425d099a45d47ecd9cdb9104577083f00e5129283e0ea1a73916c3bb98d748651a9c586dd29eb3c0787c
storybook: ^8.4.5
checksum: b04d3ee38cf60557d9ac1fe58f4cdbaee72d3fe2818530fc360fae7edfb18794e2b7be4748d00511c4682727743f8828efefe1bae7fffb28ad05b53f821bb5e9
languageName: node
linkType: hard
"@storybook/theming@npm:8.4.4":
version: 8.4.4
resolution: "@storybook/theming@npm:8.4.4"
"@storybook/theming@npm:8.4.5":
version: 8.4.5
resolution: "@storybook/theming@npm:8.4.5"
peerDependencies:
storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0
checksum: 8a39c0c0c519a98491de3c8f29d3c9ab2d2bb5ee616933dd07aaed276cd46635e1b3019902b40dc073e7ee0679b5760234c920e455817a13e8d1d753811553ee
checksum: 0eefd3a3bea58e557f1e303270910046f05aa971ceba6ca6c1cd706c25b537243be6663dba5b2b3aa2edb7fc40279e93403131d76eae7da26da70f8a1c8d1c96
languageName: node
linkType: hard
@@ -28761,16 +28749,16 @@ __metadata:
languageName: node
linkType: hard
"eslint-plugin-storybook@npm:^0.11.0":
version: 0.11.0
resolution: "eslint-plugin-storybook@npm:0.11.0"
"eslint-plugin-storybook@npm:^0.11.1":
version: 0.11.1
resolution: "eslint-plugin-storybook@npm:0.11.1"
dependencies:
"@storybook/csf": ^0.1.11
"@typescript-eslint/utils": ^8.8.1
ts-dedent: ^2.2.0
peerDependencies:
eslint: ">=6"
checksum: 52baa35ed4f49bc46bd323784ac2a48a615f0fd929b66dfec11bb2cbceded1a9978b68cbb1165aa36f078190651f93243f871ead368bb2f1ee131c7d00e265e9
checksum: 8b8eb30b598f3c44c2bbf921e318215338f1159c1fba2d2f6cd5bc0b2ec14515655cf1760b5e11355baddabc2ac8446d4dc18ee6df6d2252555b126ff649a421
languageName: node
linkType: hard
@@ -44236,11 +44224,11 @@ __metadata:
languageName: node
linkType: hard
"storybook@npm:^8.4.4":
version: 8.4.4
resolution: "storybook@npm:8.4.4"
"storybook@npm:^8.4.5":
version: 8.4.5
resolution: "storybook@npm:8.4.5"
dependencies:
"@storybook/core": 8.4.4
"@storybook/core": 8.4.5
peerDependencies:
prettier: ^2 || ^3
peerDependenciesMeta:
@@ -44250,7 +44238,7 @@ __metadata:
getstorybook: ./bin/index.cjs
sb: ./bin/index.cjs
storybook: ./bin/index.cjs
checksum: 5e307e0e3af9f1f687388b9040a4a5d040fc48a7af346d19bd0eaf26e22bad49f5048e18a60d2e6122c613a1d40413114a39b908f670daf3f3a9cce1e4cc95cb
checksum: 3495183749b760da077b2ede7607884c62f6707412e91defbe20328b275b78528fcef350453ad95642a52b97eded50f2c5374e94fb422a3b39587de364d87ee8
languageName: node
linkType: hard