Merge pull request #28634 from backstage/canon-flex
Canon - Merge Stack + Inline into Flex
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/canon': minor
|
||||
---
|
||||
|
||||
**BREAKING**: Merged the Stack and Inline component into a single component called Flex.
|
||||
@@ -141,9 +141,9 @@ Here's a view when buttons are full width.
|
||||
py={4}
|
||||
open
|
||||
preview={<ButtonFullWidth />}
|
||||
code={`<Stack style={{ width: '300px' }}>
|
||||
code={`<Flex style={{ width: '300px' }}>
|
||||
<Button fullWidth>Full width</Button>
|
||||
</Stack>`}
|
||||
</Flex>`}
|
||||
/>
|
||||
|
||||
### Disabled
|
||||
|
||||
+20
-20
@@ -3,29 +3,29 @@ import { spacePropsList } from '@/utils/spaceProps';
|
||||
import { Tabs } from '@/components/Tabs';
|
||||
import { CodeBlock } from '@/components/CodeBlock';
|
||||
import {
|
||||
stackFAQ1,
|
||||
stackSimple,
|
||||
stackResponsive,
|
||||
stackAlign,
|
||||
flexFAQ1,
|
||||
flexSimple,
|
||||
flexResponsive,
|
||||
flexAlign,
|
||||
} from '@/snippets/_snippets';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { StackPreview } from '@/snippets/stack';
|
||||
import { FlexPreview } from '@/snippets/flex';
|
||||
|
||||
# Stack
|
||||
# Flex
|
||||
|
||||
This is the stack container component. It will help to define the number of
|
||||
This is the flex container component. It will help to define the number of
|
||||
columns that will be used in the grid. You can also define the gap between the
|
||||
columns. All values are responsive.
|
||||
|
||||
<Snippet
|
||||
py={4}
|
||||
align="center"
|
||||
preview={<StackPreview />}
|
||||
code={`<Stack>
|
||||
preview={<FlexPreview />}
|
||||
code={`<Flex>
|
||||
<DecorativeBox />
|
||||
<DecorativeBox />
|
||||
<DecorativeBox />
|
||||
</Stack>`}
|
||||
</Flex>`}
|
||||
/>
|
||||
|
||||
<Tabs.Root>
|
||||
@@ -34,9 +34,9 @@ columns. All values are responsive.
|
||||
</Tabs.List>
|
||||
<Tabs.Panel>
|
||||
<CodeBlock
|
||||
code={`import { Stack } from '@backstage/canon';
|
||||
code={`import { Flex } from '@backstage/canon';
|
||||
|
||||
<Stack />
|
||||
<Flex />
|
||||
`}
|
||||
/>
|
||||
</Tabs.Panel>
|
||||
@@ -73,29 +73,29 @@ The grid component also accepts all the spacing props from the Box component.
|
||||
|
||||
### Can I stack horizontally?
|
||||
|
||||
The Stack component only allows for stacking elements vertically. If you want
|
||||
The Flex component only allows for stacking elements vertically. If you want
|
||||
to create a column layout, please use the Grid component.
|
||||
|
||||
<CodeBlock code={stackFAQ1} />
|
||||
<CodeBlock code={flexFAQ1} />
|
||||
|
||||
## Examples
|
||||
|
||||
### Simple
|
||||
|
||||
A simple example of how to use the Stack component.
|
||||
A simple example of how to use the Flex component.
|
||||
|
||||
<CodeBlock code={stackSimple} />
|
||||
<CodeBlock code={flexSimple} />
|
||||
|
||||
### Responsive
|
||||
|
||||
The Stack component also supports responsive values, making it easy to create
|
||||
The Flex component also supports responsive values, making it easy to create
|
||||
responsive designs.
|
||||
|
||||
<CodeBlock code={stackResponsive} />
|
||||
<CodeBlock code={flexResponsive} />
|
||||
|
||||
### Align
|
||||
|
||||
The Stack component also supports responsive alignment, making it easy to
|
||||
The Flex component also supports responsive alignment, making it easy to
|
||||
create responsive designs.
|
||||
|
||||
<CodeBlock code={stackAlign} />
|
||||
<CodeBlock code={flexAlign} />
|
||||
@@ -75,13 +75,13 @@ appearance of the heading.
|
||||
py={2}
|
||||
open
|
||||
preview={<HeadingAllVariants />}
|
||||
code={`<Stack gap="md">
|
||||
code={`<Flex direction="column" gap="4">
|
||||
<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>
|
||||
</Stack>`}
|
||||
</Flex>`}
|
||||
/>
|
||||
|
||||
### Responsive
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
import { CodeBlock } from '@/components/CodeBlock';
|
||||
import { PropsTable } from '@/components/PropsTable';
|
||||
import { spacePropsList } from '@/utils/spaceProps';
|
||||
import { Tabs } from '@/components/Tabs';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { InlinePreview } from '@/snippets/inline';
|
||||
|
||||
# Inline
|
||||
|
||||
The Inline component is used to create a horizontal layout of elements.
|
||||
|
||||
<Snippet
|
||||
py={4}
|
||||
preview={<InlinePreview />}
|
||||
code={`<Inline>
|
||||
<DecorativeBox />
|
||||
<DecorativeBox />
|
||||
<DecorativeBox />
|
||||
</Inline>`}
|
||||
/>
|
||||
|
||||
<Tabs.Root>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab>Usage</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel>
|
||||
<CodeBlock
|
||||
code={`import { Inline } from '@backstage/canon';
|
||||
|
||||
<Inline />
|
||||
`}
|
||||
/>
|
||||
</Tabs.Panel>
|
||||
</Tabs.Root>
|
||||
|
||||
## API reference
|
||||
|
||||
<PropsTable
|
||||
data={{
|
||||
align: {
|
||||
type: 'start | center | end',
|
||||
responsive: true,
|
||||
},
|
||||
alignY: {
|
||||
type: 'start | center | end',
|
||||
responsive: true,
|
||||
},
|
||||
children: {
|
||||
type: 'ReactNode',
|
||||
responsive: false,
|
||||
},
|
||||
className: {
|
||||
type: 'string',
|
||||
responsive: false,
|
||||
},
|
||||
style: {
|
||||
type: 'CSSProperties',
|
||||
responsive: false,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
The grid component also accepts all the spacing props from the Box component.
|
||||
|
||||
<PropsTable data={spacePropsList} />
|
||||
|
||||
## Examples
|
||||
|
||||
### Simple
|
||||
|
||||
A simple example of how to use the Inline component.
|
||||
|
||||
<CodeBlock
|
||||
code={`<Inline>
|
||||
<Box>Hello World</Box>
|
||||
<Box>Hello World</Box>
|
||||
<Box>Hello World</Box>
|
||||
</Inline>`}
|
||||
/>
|
||||
|
||||
### Responsive
|
||||
|
||||
The Inline component also supports responsive values, making it easy to create
|
||||
responsive designs.
|
||||
|
||||
<CodeBlock
|
||||
code={`<Inline gap={{ xs: 'sm', md: 'md' }}>
|
||||
<Box>Hello World</Box>
|
||||
<Box>Hello World</Box>
|
||||
<Box>Hello World</Box>
|
||||
</Inline>`}
|
||||
/>
|
||||
|
||||
### Align
|
||||
|
||||
The Inline component also supports responsive alignment, making it easy to
|
||||
create responsive designs.
|
||||
|
||||
<CodeBlock
|
||||
code={`<Inline align={{ xs: 'left', md: 'center' }}>
|
||||
<Box>Hello World</Box>
|
||||
<Box>Hello World</Box>
|
||||
<Box>Hello World</Box>
|
||||
</Inline>`}
|
||||
/>
|
||||
|
||||
### Align vertically
|
||||
|
||||
The Inline component also supports responsive vertical alignment, making it
|
||||
easy to create responsive designs.
|
||||
|
||||
<CodeBlock
|
||||
code={`<Inline alignY={{ xs: 'top', md: 'center' }}>
|
||||
<Box>Hello World</Box>
|
||||
<Box>Hello World</Box>
|
||||
<Box>Hello World</Box>
|
||||
</Inline>`}
|
||||
/>
|
||||
@@ -83,7 +83,7 @@ appearance of the text.
|
||||
<Snippet
|
||||
open
|
||||
preview={<TextAllVariants />}
|
||||
code={`<Stack gap="md">
|
||||
code={`<Flex direction="column" gap="4">
|
||||
<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's father is my father's son.” Who is
|
||||
@@ -104,7 +104,7 @@ appearance of the text.
|
||||
have none, but that man's father is my father's son.” Who is
|
||||
in the painting?
|
||||
</Text>
|
||||
</Stack>`}
|
||||
</Flex>`}
|
||||
/>
|
||||
|
||||
### All weights
|
||||
@@ -115,7 +115,7 @@ appearance of the text.
|
||||
<Snippet
|
||||
open
|
||||
preview={<TextAllWeights />}
|
||||
code={`<Stack gap="md">
|
||||
code={`<Flex direction="column" gap="4">
|
||||
<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's father is my father's son.” Who is
|
||||
@@ -126,7 +126,7 @@ appearance of the text.
|
||||
have none, but that man's father is my father's son.” Who is
|
||||
in the painting?
|
||||
</Text>
|
||||
</Stack>`}
|
||||
</Flex>`}
|
||||
/>
|
||||
|
||||
### Responsive
|
||||
|
||||
@@ -45,12 +45,12 @@ import { ThemeProvider } from '@backstage/canon';
|
||||
Now you can start building your plugin using the new design system.
|
||||
|
||||
```tsx
|
||||
import { Stack, Button } from '@backstage/canon';
|
||||
import { Flex, Button, Text } from '@backstage/canon';
|
||||
|
||||
<Stack>
|
||||
<Flex>
|
||||
<Text>Hello World</Text>
|
||||
<Button>Click me</Button>
|
||||
</Stack>;
|
||||
</Flex>;
|
||||
```
|
||||
|
||||
## Roadmap
|
||||
|
||||
@@ -22,13 +22,13 @@ provide are the ones coming from the theme.
|
||||
|
||||
<CodeBlock
|
||||
title="Layout components"
|
||||
code={`<Stack direction="column" gap="md">
|
||||
code={`<Flex direction="column" gap="4">
|
||||
<Box>Hello World</Box>
|
||||
<Inline gap="sm">
|
||||
<Box>Project 1</Box>
|
||||
<Box>Project 2</Box>
|
||||
</Inline>
|
||||
</Stack>
|
||||
</Flex>
|
||||
`}
|
||||
/>
|
||||
|
||||
|
||||
@@ -21,13 +21,13 @@ component](?path=/docs/components-heading--docs).
|
||||
py={2}
|
||||
open
|
||||
preview={<HeadingAllVariants />}
|
||||
code={`<Stack gap="md">
|
||||
code={`<Flex direction="column" gap="4">
|
||||
<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>
|
||||
</Stack>`}
|
||||
</Flex>`}
|
||||
/>
|
||||
|
||||
## Text
|
||||
@@ -41,7 +41,7 @@ page.
|
||||
<Snippet
|
||||
open
|
||||
preview={<TextAllVariants />}
|
||||
code={`<Stack gap="md">
|
||||
code={`<Flex direction="column" gap="4">
|
||||
<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's father is my father's son.” Who is
|
||||
@@ -62,5 +62,5 @@ page.
|
||||
have none, but that man's father is my father's son.” Who is
|
||||
in the painting?
|
||||
</Text>
|
||||
</Stack>`}
|
||||
</Flex>`}
|
||||
/>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { ReactNode } from 'react';
|
||||
import { Grid, Stack, Text } from '../../../../../packages/canon';
|
||||
import { Grid, Flex, Text } from '../../../../../packages/canon';
|
||||
import { screenSizes } from '@/utils/data';
|
||||
import { Frame } from '@/components/Frame';
|
||||
import { usePlayground } from '@/utils/playground-context';
|
||||
@@ -53,7 +53,7 @@ const Content = () => {
|
||||
const { selectedComponents } = usePlayground();
|
||||
|
||||
return (
|
||||
<Stack gap="xl">
|
||||
<Flex direction="column" gap="4">
|
||||
{selectedComponents.find(c => c === 'button') && (
|
||||
<Line content={<ButtonPlayground />} title="Button" />
|
||||
)}
|
||||
@@ -69,17 +69,17 @@ const Content = () => {
|
||||
{/* {selectedComponents.find(c => c === 'input') && (
|
||||
<Line content={<InputPlayground />} title="Input" />
|
||||
)} */}
|
||||
</Stack>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
const Line = ({ content, title }: { content: ReactNode; title: string }) => {
|
||||
return (
|
||||
<Grid gap={{ xs: 'xs', md: 'xl' }}>
|
||||
<Grid.Item colSpan={2}>
|
||||
<Grid gap={{ xs: '2', md: '4' }}>
|
||||
<Grid.Item colSpan="2">
|
||||
<Text>{title}</Text>
|
||||
</Grid.Item>
|
||||
<Grid.Item colSpan={10}>{content}</Grid.Item>
|
||||
<Grid.Item colSpan="10">{content}</Grid.Item>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { BoxSvg } from './svgs/box';
|
||||
import { StackSvg } from './svgs/stack';
|
||||
import { FlexSvg } from './svgs/flex';
|
||||
import { GridSvg } from './svgs/grid';
|
||||
import { InlineSvg } from './svgs/inline';
|
||||
import { ContainerSvg } from './svgs/container';
|
||||
@@ -20,10 +20,10 @@ export const LayoutComponents = () => {
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.box}>
|
||||
<Link className={styles.content} href="/components/stack">
|
||||
<StackSvg />
|
||||
<Link className={styles.content} href="/components/flex">
|
||||
<FlexSvg />
|
||||
</Link>
|
||||
<div className={styles.title}>Stack</div>
|
||||
<div className={styles.title}>Flex</div>
|
||||
<div className={styles.description}>
|
||||
Arrange your components vertically
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
import React from 'react';
|
||||
|
||||
export const StackSvg = () => {
|
||||
export const FlexSvg = () => {
|
||||
return (
|
||||
<svg
|
||||
width="100"
|
||||
@@ -51,26 +51,26 @@ export const buttonVariants = `<Inline alignY="center">
|
||||
</Inline>
|
||||
`;
|
||||
|
||||
export const stackFAQ1 = `<Grid columns={3} gap="md">
|
||||
export const flexFAQ1 = `<Grid columns={3} gap="4">
|
||||
<Box>Hello World</Box>
|
||||
<Box>Hello World</Box>
|
||||
<Box>Hello World</Box>
|
||||
</Grid>`;
|
||||
|
||||
export const stackSimple = `<Stack>
|
||||
export const flexSimple = `<Flex>
|
||||
<Box>Hello World</Box>
|
||||
<Box>Hello World</Box>
|
||||
<Box>Hello World</Box>
|
||||
</Stack>`;
|
||||
</Flex>`;
|
||||
|
||||
export const stackResponsive = `<Stack gap={{ xs: 'sm', md: 'md' }}>
|
||||
export const flexResponsive = `<Flex gap={{ xs: 'sm', md: 'md' }}>
|
||||
<Box>Hello World</Box>
|
||||
<Box>Hello World</Box>
|
||||
<Box>Hello World</Box>
|
||||
</Stack>`;
|
||||
</Flex>`;
|
||||
|
||||
export const stackAlign = `<Stack align={{ xs: 'left', md: 'center' }}>
|
||||
export const flexAlign = `<Flex align={{ xs: 'left', md: 'center' }}>
|
||||
<Box>Hello World</Box>
|
||||
<Box>Hello World</Box>
|
||||
<Box>Hello World</Box>
|
||||
</Stack>`;
|
||||
</Flex>`;
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
'use client';
|
||||
|
||||
import {
|
||||
Inline,
|
||||
Button,
|
||||
Stack,
|
||||
ButtonProps,
|
||||
Text,
|
||||
} from '../../../packages/canon';
|
||||
import { Button, Flex, ButtonProps, Text } from '../../../packages/canon';
|
||||
|
||||
export const ButtonPreview = () => {
|
||||
return (
|
||||
<Inline alignY="center">
|
||||
<Flex align="center">
|
||||
<Button iconStart="cloud" variant="primary">
|
||||
Button
|
||||
</Button>
|
||||
@@ -20,40 +14,40 @@ export const ButtonPreview = () => {
|
||||
<Button iconStart="cloud" variant="tertiary">
|
||||
Button
|
||||
</Button>
|
||||
</Inline>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export const ButtonSizes = () => {
|
||||
return (
|
||||
<Inline alignY="center">
|
||||
<Flex align="center">
|
||||
<Button size="medium">Medium</Button>
|
||||
<Button size="small">Small</Button>
|
||||
</Inline>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export const ButtonWithIcons = () => {
|
||||
return (
|
||||
<Inline alignY="center">
|
||||
<Flex align="center">
|
||||
<Button iconStart="cloud">Button</Button>
|
||||
<Button iconEnd="chevronRight">Button</Button>
|
||||
<Button iconStart="cloud" iconEnd="chevronRight">
|
||||
Button
|
||||
</Button>
|
||||
</Inline>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export const ButtonFullWidth = () => {
|
||||
return (
|
||||
<Stack style={{ width: '300px' }}>
|
||||
<Flex direction="column" style={{ width: '300px' }}>
|
||||
<Button iconStart="cloud">Button</Button>
|
||||
<Button iconEnd="chevronRight">Button</Button>
|
||||
<Button iconStart="cloud" iconEnd="chevronRight">
|
||||
Button
|
||||
</Button>
|
||||
</Stack>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -73,12 +67,12 @@ export const ButtonPlayground = () => {
|
||||
const variants: string[] = ['primary', 'secondary', 'tertiary'];
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<Flex direction="column">
|
||||
{variants.map(variant => (
|
||||
<Stack key={variant}>
|
||||
<Flex direction="column" key={variant}>
|
||||
<Text>{variant}</Text>
|
||||
{['small', 'medium'].map(size => (
|
||||
<Inline alignY="center" key={size}>
|
||||
<Flex align="center" key={size}>
|
||||
<Button
|
||||
iconStart="cloud"
|
||||
variant={variant as ButtonProps['variant']}
|
||||
@@ -102,10 +96,10 @@ export const ButtonPlayground = () => {
|
||||
>
|
||||
Button
|
||||
</Button>
|
||||
</Inline>
|
||||
</Flex>
|
||||
))}
|
||||
</Stack>
|
||||
</Flex>
|
||||
))}
|
||||
</Stack>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { Inline, Checkbox, Stack, Text } from '../../../packages/canon';
|
||||
import { Checkbox, Flex, Text } from '../../../packages/canon';
|
||||
|
||||
export const CheckboxPreview = () => {
|
||||
return <Checkbox label="Accept terms and conditions" />;
|
||||
@@ -8,25 +8,25 @@ export const CheckboxPreview = () => {
|
||||
|
||||
export const CheckboxAllVariants = () => {
|
||||
return (
|
||||
<Inline alignY="center">
|
||||
<Flex align="center">
|
||||
<Checkbox />
|
||||
<Checkbox checked />
|
||||
<Checkbox label="Checkbox" />
|
||||
<Checkbox label="Checkbox" checked />
|
||||
</Inline>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export const CheckboxPlayground = () => {
|
||||
return (
|
||||
<Stack>
|
||||
<Flex direction="column">
|
||||
<Text>All variants</Text>
|
||||
<Inline alignY="center">
|
||||
<Flex align="center">
|
||||
<Checkbox />
|
||||
<Checkbox checked />
|
||||
<Checkbox label="Checkbox" />
|
||||
<Checkbox label="Checkbox" checked />
|
||||
</Inline>
|
||||
</Stack>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { Stack } from '../../../packages/canon';
|
||||
import { Flex } from '../../../packages/canon';
|
||||
|
||||
const DecorativeBox = () => {
|
||||
return (
|
||||
@@ -18,14 +18,14 @@ const DecorativeBox = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export const StackPreview = () => {
|
||||
export const FlexPreview = () => {
|
||||
return (
|
||||
<div style={{ width: '320px' }}>
|
||||
<Stack>
|
||||
<Flex>
|
||||
<DecorativeBox />
|
||||
<DecorativeBox />
|
||||
<DecorativeBox />
|
||||
</Stack>
|
||||
</Flex>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { Heading, Stack, Text } from '../../../packages/canon';
|
||||
import { Heading, Flex, Text } from '../../../packages/canon';
|
||||
|
||||
export const HeadingPreview = () => {
|
||||
return <Heading>Look mum, no hands!</Heading>;
|
||||
@@ -8,35 +8,35 @@ export const HeadingPreview = () => {
|
||||
|
||||
export const HeadingAllVariants = () => {
|
||||
return (
|
||||
<Stack>
|
||||
<Flex direction="column">
|
||||
<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>
|
||||
</Stack>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export const HeadingResponsive = () => {
|
||||
return (
|
||||
<Stack>
|
||||
<Flex direction="column">
|
||||
<Heading variant={{ initial: 'title2', lg: 'title1' }}>
|
||||
Responsive heading
|
||||
</Heading>
|
||||
</Stack>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export const HeadingPlayground = () => {
|
||||
return (
|
||||
<Stack>
|
||||
<Flex direction="column">
|
||||
<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>
|
||||
</Stack>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { Stack, Text } from '../../../packages/canon';
|
||||
import { Flex, Text } from '../../../packages/canon';
|
||||
|
||||
export const TextPreview = () => {
|
||||
return (
|
||||
@@ -14,7 +14,7 @@ export const TextPreview = () => {
|
||||
|
||||
export const TextAllVariants = () => {
|
||||
return (
|
||||
<Stack gap="md">
|
||||
<Flex direction="column">
|
||||
<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's father is my father's son.” Who is
|
||||
@@ -35,13 +35,13 @@ export const TextAllVariants = () => {
|
||||
have none, but that man's father is my father's son.” Who is
|
||||
in the painting?
|
||||
</Text>
|
||||
</Stack>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export const TextAllWeights = () => {
|
||||
return (
|
||||
<Stack gap="md">
|
||||
<Flex direction="column">
|
||||
<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's father is my father's son.” Who is
|
||||
@@ -52,7 +52,7 @@ export const TextAllWeights = () => {
|
||||
have none, but that man's father is my father's son.” Who is
|
||||
in the painting?
|
||||
</Text>
|
||||
</Stack>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -64,7 +64,7 @@ export const TextResponsive = () => {
|
||||
|
||||
export const TextPlayground = () => {
|
||||
return (
|
||||
<Stack>
|
||||
<Flex direction="column">
|
||||
<Text>Subtitle</Text>
|
||||
<Text variant="subtitle" style={{ maxWidth: '600px' }}>
|
||||
A man looks at a painting in a museum and says, “Brothers and sisters I
|
||||
@@ -89,6 +89,6 @@ export const TextPlayground = () => {
|
||||
have none, but that man's father is my father's son.” Who is
|
||||
in the painting?
|
||||
</Text>
|
||||
</Stack>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -55,13 +55,8 @@ export const layoutComponents: Page[] = [
|
||||
status: 'alpha',
|
||||
},
|
||||
{
|
||||
title: 'Inline',
|
||||
slug: 'inline',
|
||||
status: 'alpha',
|
||||
},
|
||||
{
|
||||
title: 'Stack',
|
||||
slug: 'stack',
|
||||
title: 'Flex',
|
||||
slug: 'flex',
|
||||
status: 'alpha',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -283,9 +283,57 @@ export const Field: {
|
||||
}) => React_2.JSX.Element;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export const Flex: ForwardRefExoticComponent<
|
||||
FlexProps & RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
|
||||
// @public (undocumented)
|
||||
export type FlexDirection = 'row' | 'column';
|
||||
|
||||
// @public (undocumented)
|
||||
export type FlexOwnProps = GetPropDefTypes<typeof flexPropDefs>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const flexPropDefs: {
|
||||
align: {
|
||||
type: 'enum';
|
||||
className: string;
|
||||
values: readonly ['start', 'center', 'end', 'baseline', 'stretch'];
|
||||
responsive: true;
|
||||
};
|
||||
direction: {
|
||||
type: 'enum';
|
||||
className: string;
|
||||
values: readonly ['row', 'column', 'row-reverse', 'column-reverse'];
|
||||
responsive: true;
|
||||
};
|
||||
justify: {
|
||||
type: 'enum';
|
||||
className: string;
|
||||
values: readonly ['start', 'center', 'end', 'between'];
|
||||
responsive: true;
|
||||
};
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export interface FlexProps extends SpaceProps {
|
||||
// (undocumented)
|
||||
align?: FlexOwnProps['align'];
|
||||
// (undocumented)
|
||||
children: React.ReactNode;
|
||||
// (undocumented)
|
||||
className?: string;
|
||||
// (undocumented)
|
||||
direction?: FlexOwnProps['direction'];
|
||||
// (undocumented)
|
||||
gap?: GapProps['gap'];
|
||||
// (undocumented)
|
||||
justify?: FlexOwnProps['justify'];
|
||||
// (undocumented)
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export type FlexWrap = 'wrap' | 'nowrap' | 'wrap-reverse';
|
||||
|
||||
@@ -589,37 +637,6 @@ export type IconProps = {
|
||||
// @public (undocumented)
|
||||
export const icons: IconMap;
|
||||
|
||||
// @public (undocumented)
|
||||
export const Inline: ForwardRefExoticComponent<
|
||||
InlineProps & RefAttributes<HTMLElement>
|
||||
>;
|
||||
|
||||
// @public (undocumented)
|
||||
export interface InlineProps extends SpaceProps {
|
||||
// (undocumented)
|
||||
align?:
|
||||
| 'left'
|
||||
| 'center'
|
||||
| 'right'
|
||||
| Partial<Record<Breakpoint, 'left' | 'center' | 'right'>>;
|
||||
// (undocumented)
|
||||
alignY?:
|
||||
| 'top'
|
||||
| 'center'
|
||||
| 'bottom'
|
||||
| Partial<Record<Breakpoint, 'top' | 'center' | 'bottom'>>;
|
||||
// (undocumented)
|
||||
as?: AsProps;
|
||||
// (undocumented)
|
||||
children: React.ReactNode;
|
||||
// (undocumented)
|
||||
className?: string;
|
||||
// (undocumented)
|
||||
gap?: UtilityProps['gap'];
|
||||
// (undocumented)
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const Input: React_2.ForwardRefExoticComponent<
|
||||
InputProps & React_2.RefAttributes<HTMLInputElement>
|
||||
@@ -853,39 +870,6 @@ export interface SpaceProps {
|
||||
py?: Responsive<Space>;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const Stack: ForwardRefExoticComponent<
|
||||
StackProps & RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
|
||||
// @public (undocumented)
|
||||
export type StackOwnProps = GetPropDefTypes<typeof stackPropDefs>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const stackPropDefs: {
|
||||
align: {
|
||||
type: 'enum';
|
||||
className: string;
|
||||
values: readonly ['start', 'center', 'end', 'baseline', 'stretch'];
|
||||
responsive: true;
|
||||
default: 'stretch';
|
||||
};
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export interface StackProps extends SpaceProps {
|
||||
// (undocumented)
|
||||
align?: StackOwnProps['align'];
|
||||
// (undocumented)
|
||||
children: React.ReactNode;
|
||||
// (undocumented)
|
||||
className?: string;
|
||||
// (undocumented)
|
||||
gap?: GapProps['gap'];
|
||||
// (undocumented)
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export type StringPropDef = {
|
||||
type: 'string';
|
||||
|
||||
@@ -17,8 +17,7 @@
|
||||
import React from 'react';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { Box } from './Box';
|
||||
import { Stack } from '../Stack';
|
||||
import { Inline } from '../Inline';
|
||||
import { Flex } from '../Flex';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/Box',
|
||||
@@ -81,8 +80,8 @@ const CardDisplay = ({ children }: { children?: React.ReactNode }) => {
|
||||
|
||||
export const Display: Story = {
|
||||
render: args => (
|
||||
<Stack align="center">
|
||||
<Inline>
|
||||
<Flex direction="column" align="center">
|
||||
<Flex>
|
||||
<Box display="block" {...args}>
|
||||
<CardDisplay>Block</CardDisplay>
|
||||
</Box>
|
||||
@@ -92,11 +91,11 @@ export const Display: Story = {
|
||||
<Box display="none" {...args}>
|
||||
<CardDisplay>None</CardDisplay>
|
||||
</Box>
|
||||
</Inline>
|
||||
</Flex>
|
||||
<Box display={{ initial: 'block', md: 'inline' }} {...args}>
|
||||
<CardDisplay>Responsive</CardDisplay>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -116,8 +115,8 @@ export const Padding: Story = {
|
||||
},
|
||||
},
|
||||
render: args => (
|
||||
<Stack align="center" gap="md">
|
||||
<Inline alignY="center" gap="md">
|
||||
<Flex direction="column" align="center" gap="4">
|
||||
<Flex gap="4" align="center">
|
||||
<Box p="3" style={styleInsideBox}>
|
||||
<Box {...args}>Padding</Box>
|
||||
</Box>
|
||||
@@ -127,8 +126,8 @@ export const Padding: Story = {
|
||||
<Box py="3" style={styleInsideBox}>
|
||||
<Box {...args}>Padding Y</Box>
|
||||
</Box>
|
||||
</Inline>
|
||||
<Inline alignY="center" gap="md">
|
||||
</Flex>
|
||||
<Flex gap="4" align="center">
|
||||
<Box pt="3" style={styleInsideBox}>
|
||||
<Box {...args}>Padding Top</Box>
|
||||
</Box>
|
||||
@@ -141,8 +140,8 @@ export const Padding: Story = {
|
||||
<Box pl="3" style={styleInsideBox}>
|
||||
<Box {...args}>Padding Left</Box>
|
||||
</Box>
|
||||
</Inline>
|
||||
</Stack>
|
||||
</Flex>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -156,8 +155,8 @@ export const Margin: Story = {
|
||||
},
|
||||
},
|
||||
render: args => (
|
||||
<Stack align="center" gap="md">
|
||||
<Inline alignY="center" gap="md">
|
||||
<Flex direction="column" align="center" gap="4">
|
||||
<Flex align="center" gap="4">
|
||||
<Box style={styleInsideBox}>
|
||||
<Box m="3" {...args}>
|
||||
Margin
|
||||
@@ -173,8 +172,8 @@ export const Margin: Story = {
|
||||
Margin Y
|
||||
</Box>
|
||||
</Box>
|
||||
</Inline>
|
||||
<Inline alignY="center" gap="md">
|
||||
</Flex>
|
||||
<Flex align="center" gap="4">
|
||||
<Box style={styleInsideBox}>
|
||||
<Box mt="3" {...args}>
|
||||
Margin Top
|
||||
@@ -195,7 +194,7 @@ export const Margin: Story = {
|
||||
Margin Left
|
||||
</Box>
|
||||
</Box>
|
||||
</Inline>
|
||||
</Stack>
|
||||
</Flex>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -17,8 +17,7 @@
|
||||
import React from 'react';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { Button } from './Button';
|
||||
import { Inline } from '../Inline';
|
||||
import { Stack } from '../Stack';
|
||||
import { Flex } from '../Flex';
|
||||
import { Text } from '../Text';
|
||||
import { ButtonProps } from './types';
|
||||
|
||||
@@ -51,7 +50,7 @@ export const Variants: Story = {
|
||||
},
|
||||
},
|
||||
render: () => (
|
||||
<Inline alignY="center">
|
||||
<Flex align="center">
|
||||
<Button iconStart="cloud" variant="primary">
|
||||
Button
|
||||
</Button>
|
||||
@@ -61,7 +60,7 @@ export const Variants: Story = {
|
||||
<Button iconStart="cloud" variant="tertiary">
|
||||
Button
|
||||
</Button>
|
||||
</Inline>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -70,10 +69,10 @@ export const Sizes: Story = {
|
||||
children: 'Button',
|
||||
},
|
||||
render: () => (
|
||||
<Inline alignY="center">
|
||||
<Flex align="center">
|
||||
<Button size="medium">Medium</Button>
|
||||
<Button size="small">Small</Button>
|
||||
</Inline>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -82,11 +81,11 @@ export const WithIcons: Story = {
|
||||
children: 'Button',
|
||||
},
|
||||
render: args => (
|
||||
<Inline alignY="center">
|
||||
<Flex align="center">
|
||||
<Button {...args} iconStart="cloud" />
|
||||
<Button {...args} iconEnd="chevronRight" />
|
||||
<Button {...args} iconStart="cloud" iconEnd="chevronRight" />
|
||||
</Inline>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -95,11 +94,11 @@ export const FullWidth: Story = {
|
||||
children: 'Button',
|
||||
},
|
||||
render: args => (
|
||||
<Stack style={{ width: '300px' }}>
|
||||
<Flex style={{ width: '300px' }}>
|
||||
<Button {...args} iconStart="cloud" />
|
||||
<Button {...args} iconEnd="chevronRight" />
|
||||
<Button {...args} iconStart="cloud" iconEnd="chevronRight" />
|
||||
</Stack>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -132,12 +131,12 @@ export const Playground: Story = {
|
||||
children: 'Button',
|
||||
},
|
||||
render: () => (
|
||||
<Stack>
|
||||
<Flex direction="column">
|
||||
{variants.map(variant => (
|
||||
<Stack key={variant}>
|
||||
<Flex direction="column" key={variant}>
|
||||
<Text>{variant}</Text>
|
||||
{['small', 'medium'].map(size => (
|
||||
<Inline alignY="center" key={size}>
|
||||
<Flex align="center" key={size}>
|
||||
<Button
|
||||
iconStart="cloud"
|
||||
variant={variant as ButtonProps['variant']}
|
||||
@@ -161,10 +160,10 @@ export const Playground: Story = {
|
||||
>
|
||||
Button
|
||||
</Button>
|
||||
</Inline>
|
||||
</Flex>
|
||||
))}
|
||||
</Stack>
|
||||
</Flex>
|
||||
))}
|
||||
</Stack>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -17,8 +17,7 @@
|
||||
import React from 'react';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { Checkbox } from './Checkbox';
|
||||
import { Inline } from '../Inline';
|
||||
import { Stack } from '../Stack';
|
||||
import { Flex } from '../Flex';
|
||||
import { Text } from '../Text';
|
||||
|
||||
const meta = {
|
||||
@@ -40,25 +39,25 @@ export const Default: Story = {
|
||||
|
||||
export const AllVariants: Story = {
|
||||
render: () => (
|
||||
<Inline alignY="center">
|
||||
<Flex align="center">
|
||||
<Checkbox />
|
||||
<Checkbox checked />
|
||||
<Checkbox label="Checkbox" />
|
||||
<Checkbox label="Checkbox" checked />
|
||||
</Inline>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
export const Playground: Story = {
|
||||
render: () => (
|
||||
<Stack>
|
||||
<Flex>
|
||||
<Text>All variants</Text>
|
||||
<Inline alignY="center">
|
||||
<Flex align="center">
|
||||
<Checkbox />
|
||||
<Checkbox checked />
|
||||
<Checkbox label="Checkbox" />
|
||||
<Checkbox label="Checkbox" checked />
|
||||
</Inline>
|
||||
</Stack>
|
||||
</Flex>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
+25
-5
@@ -17,22 +17,42 @@
|
||||
import type { PropDef, GetPropDefTypes } from '../../props/prop-def';
|
||||
|
||||
const alignValues = ['start', 'center', 'end', 'baseline', 'stretch'] as const;
|
||||
const directionValues = [
|
||||
'row',
|
||||
'column',
|
||||
'row-reverse',
|
||||
'column-reverse',
|
||||
] as const;
|
||||
const justifyValues = ['start', 'center', 'end', 'between'] as const;
|
||||
|
||||
/** @public */
|
||||
const stackPropDefs = {
|
||||
const flexPropDefs = {
|
||||
align: {
|
||||
type: 'enum',
|
||||
className: 'cu-align',
|
||||
values: alignValues,
|
||||
responsive: true,
|
||||
default: 'stretch',
|
||||
},
|
||||
direction: {
|
||||
type: 'enum',
|
||||
className: 'cu-fd',
|
||||
values: directionValues,
|
||||
responsive: true,
|
||||
},
|
||||
justify: {
|
||||
type: 'enum',
|
||||
className: 'cu-jc',
|
||||
values: justifyValues,
|
||||
responsive: true,
|
||||
},
|
||||
} satisfies {
|
||||
align: PropDef<(typeof alignValues)[number]>;
|
||||
direction: PropDef<(typeof directionValues)[number]>;
|
||||
justify: PropDef<(typeof justifyValues)[number]>;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
type StackOwnProps = GetPropDefTypes<typeof stackPropDefs>;
|
||||
type FlexOwnProps = GetPropDefTypes<typeof flexPropDefs>;
|
||||
|
||||
export { stackPropDefs };
|
||||
export type { StackOwnProps };
|
||||
export { flexPropDefs };
|
||||
export type { FlexOwnProps };
|
||||
+30
-16
@@ -16,11 +16,11 @@
|
||||
|
||||
import React from 'react';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { Stack } from './Stack';
|
||||
import { Flex } from './Flex';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/Stack',
|
||||
component: Stack,
|
||||
title: 'Components/Flex',
|
||||
component: Flex,
|
||||
argTypes: {
|
||||
align: {
|
||||
control: 'inline-radio',
|
||||
@@ -38,7 +38,7 @@ const meta = {
|
||||
gap: '4',
|
||||
children: 'hello world',
|
||||
},
|
||||
} satisfies Meta<typeof Stack>;
|
||||
} satisfies Meta<typeof Flex>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
@@ -65,62 +65,76 @@ export const Default: Story = {
|
||||
},
|
||||
};
|
||||
|
||||
export const ColumnDirection: Story = {
|
||||
args: {
|
||||
direction: 'column',
|
||||
children: [<DecorativeBox />, <DecorativeBox />, <DecorativeBox />],
|
||||
},
|
||||
};
|
||||
|
||||
export const RowDirection: Story = {
|
||||
args: {
|
||||
direction: 'row',
|
||||
children: [<DecorativeBox />, <DecorativeBox />, <DecorativeBox />],
|
||||
},
|
||||
};
|
||||
|
||||
export const AlignLeft: Story = {
|
||||
render: () => (
|
||||
<Stack align="start">
|
||||
<Flex align="start">
|
||||
<DecorativeBox />
|
||||
<DecorativeBox />
|
||||
<DecorativeBox />
|
||||
</Stack>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
export const AlignCenter: Story = {
|
||||
render: () => (
|
||||
<Stack align="center">
|
||||
<Flex align="center">
|
||||
<DecorativeBox />
|
||||
<DecorativeBox />
|
||||
<DecorativeBox />
|
||||
</Stack>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
export const AlignRight: Story = {
|
||||
render: () => (
|
||||
<Stack align="end">
|
||||
<Flex align="end">
|
||||
<DecorativeBox />
|
||||
<DecorativeBox />
|
||||
<DecorativeBox />
|
||||
</Stack>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
export const ResponsiveAlign: Story = {
|
||||
render: () => (
|
||||
<Stack align={{ xs: 'start', md: 'center', lg: 'end' }}>
|
||||
<Flex align={{ xs: 'start', md: 'center', lg: 'end' }}>
|
||||
<DecorativeBox />
|
||||
<DecorativeBox />
|
||||
<DecorativeBox />
|
||||
</Stack>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
export const ResponsiveGap: Story = {
|
||||
render: () => (
|
||||
<Stack gap={{ xs: '4', md: '8', lg: '12' }}>
|
||||
<Flex gap={{ xs: '4', md: '8', lg: '12' }}>
|
||||
<DecorativeBox />
|
||||
<DecorativeBox />
|
||||
<DecorativeBox />
|
||||
</Stack>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
export const LargeGap: Story = {
|
||||
render: () => (
|
||||
<Stack gap="8">
|
||||
<Flex gap="8">
|
||||
<DecorativeBox />
|
||||
<DecorativeBox />
|
||||
<DecorativeBox />
|
||||
</Stack>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
+5
-5
@@ -15,24 +15,24 @@
|
||||
*/
|
||||
|
||||
import { createElement, forwardRef } from 'react';
|
||||
import { StackProps } from './types';
|
||||
import { FlexProps } from './types';
|
||||
import clsx from 'clsx';
|
||||
import { stackPropDefs } from './Stack.props';
|
||||
import { flexPropDefs } from './Flex.props';
|
||||
import { extractProps } from '../../utils/extractProps';
|
||||
import { gapPropDefs } from '../../props/gap-props';
|
||||
|
||||
/** @public */
|
||||
export const Stack = forwardRef<HTMLDivElement, StackProps>((props, ref) => {
|
||||
export const Flex = forwardRef<HTMLDivElement, FlexProps>((props, ref) => {
|
||||
const propDefs = {
|
||||
...gapPropDefs,
|
||||
...stackPropDefs,
|
||||
...flexPropDefs,
|
||||
};
|
||||
|
||||
const { className, style } = extractProps(props, propDefs);
|
||||
|
||||
return createElement('div', {
|
||||
ref,
|
||||
className: clsx('canon-Stack', className),
|
||||
className: clsx('canon-Flex', className),
|
||||
style,
|
||||
children: props.children,
|
||||
});
|
||||
+4
-2
@@ -13,5 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export { Inline } from './Inline';
|
||||
export type { InlineProps } from './types';
|
||||
export { Flex } from './Flex';
|
||||
export { flexPropDefs } from './Flex.props';
|
||||
export type { FlexProps } from './types';
|
||||
export type { FlexOwnProps } from './Flex.props';
|
||||
+1
-2
@@ -14,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
.canon-Inline {
|
||||
.canon-Flex {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
+5
-3
@@ -15,14 +15,16 @@
|
||||
*/
|
||||
|
||||
import type { SpaceProps } from '../../types';
|
||||
import { StackOwnProps } from './Stack.props';
|
||||
import { FlexOwnProps } from './Flex.props';
|
||||
import type { GapProps } from '../../props/gap-props';
|
||||
|
||||
/** @public */
|
||||
export interface StackProps extends SpaceProps {
|
||||
export interface FlexProps extends SpaceProps {
|
||||
children: React.ReactNode;
|
||||
gap?: GapProps['gap'];
|
||||
align?: StackOwnProps['align'];
|
||||
align?: FlexOwnProps['align'];
|
||||
justify?: FlexOwnProps['justify'];
|
||||
direction?: FlexOwnProps['direction'];
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
@@ -19,7 +19,7 @@ import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { Grid } from './Grid';
|
||||
import type { GridItemProps } from './types';
|
||||
import { Box } from '../Box/Box';
|
||||
import { Stack } from '../Stack';
|
||||
import { Flex } from '../Flex';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/Grid',
|
||||
@@ -82,7 +82,7 @@ export const ColumnSizes: Story = {
|
||||
columns: '12',
|
||||
},
|
||||
render: args => (
|
||||
<Stack gap="4">
|
||||
<Flex gap="4">
|
||||
{Array.from({ length: 11 }, (_, i) => (
|
||||
<Grid {...args} key={i}>
|
||||
<Grid.Item colSpan={String(i + 1) as GridItemProps['colSpan']}>
|
||||
@@ -93,7 +93,7 @@ export const ColumnSizes: Story = {
|
||||
</Grid.Item>
|
||||
</Grid>
|
||||
))}
|
||||
</Stack>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -102,7 +102,7 @@ export const RowAndColumns: Story = {
|
||||
columns: '12',
|
||||
},
|
||||
render: args => (
|
||||
<Stack gap="md">
|
||||
<Flex gap="4">
|
||||
<Grid {...args} columns="3">
|
||||
<Grid.Item colSpan="1" rowSpan="2">
|
||||
<Box
|
||||
@@ -123,6 +123,6 @@ export const RowAndColumns: Story = {
|
||||
<FakeBox />
|
||||
</Grid.Item>
|
||||
</Grid>
|
||||
</Stack>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
import React from 'react';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { Heading } from './Heading';
|
||||
import { Stack } from '../Stack';
|
||||
import { Flex } from '../Flex';
|
||||
import { Text } from '../Text';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/Heading',
|
||||
component: Heading,
|
||||
@@ -41,13 +42,13 @@ export const Title1: Story = {
|
||||
|
||||
export const AllVariants: Story = {
|
||||
render: () => (
|
||||
<Stack>
|
||||
<Flex>
|
||||
<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>
|
||||
</Stack>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -69,7 +70,7 @@ export const CustomTag: Story = {
|
||||
|
||||
export const Playground: Story = {
|
||||
render: () => (
|
||||
<Stack>
|
||||
<Flex>
|
||||
<Text>All variants</Text>
|
||||
<Heading variant="display">Display</Heading>
|
||||
<Heading variant="title1">Title 1</Heading>
|
||||
@@ -77,6 +78,6 @@ export const Playground: Story = {
|
||||
<Heading variant="title3">Title 3</Heading>
|
||||
<Heading variant="title4">Title 4</Heading>
|
||||
<Heading variant="title5">Title 5</Heading>
|
||||
</Stack>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -1,136 +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 type { Meta, StoryObj } from '@storybook/react';
|
||||
import { Inline } from './Inline';
|
||||
import { Box } from '../Box/Box';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/Inline',
|
||||
component: Inline,
|
||||
argTypes: {
|
||||
align: {
|
||||
control: 'inline-radio',
|
||||
options: ['left', 'center', 'right'],
|
||||
},
|
||||
alignY: {
|
||||
control: 'inline-radio',
|
||||
options: ['top', 'center', 'bottom'],
|
||||
},
|
||||
children: {
|
||||
control: false,
|
||||
},
|
||||
as: {
|
||||
control: false,
|
||||
},
|
||||
className: {
|
||||
control: 'text',
|
||||
},
|
||||
},
|
||||
args: {
|
||||
children: 'hello world',
|
||||
},
|
||||
} satisfies Meta<typeof Inline>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
const fakeBlockList = [
|
||||
{ width: 45, height: 60 },
|
||||
{ width: 150, height: 75 },
|
||||
{ width: 80, height: 50 },
|
||||
{ width: 120, height: 70 },
|
||||
{ width: 95, height: 65 },
|
||||
{ width: 80, height: 32 },
|
||||
{ width: 130, height: 60 },
|
||||
{ width: 100, height: 80 },
|
||||
{ width: 140, height: 45 },
|
||||
{ width: 85, height: 70 },
|
||||
{ width: 125, height: 50 },
|
||||
];
|
||||
|
||||
const FakeBox = ({
|
||||
width = 120,
|
||||
height = 80,
|
||||
}: {
|
||||
width?: number;
|
||||
height?: number;
|
||||
}) => (
|
||||
<Box
|
||||
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 = {
|
||||
render: () => (
|
||||
<Inline>
|
||||
{fakeBlockList.map((block, index) => (
|
||||
<FakeBox key={index} width={block.width} height={block.height} />
|
||||
))}
|
||||
</Inline>
|
||||
),
|
||||
};
|
||||
|
||||
export const AlignLeft: Story = {
|
||||
args: {
|
||||
align: 'left',
|
||||
},
|
||||
};
|
||||
|
||||
export const AlignCenter: Story = {
|
||||
args: {
|
||||
align: 'center',
|
||||
},
|
||||
};
|
||||
|
||||
export const AlignRight: Story = {
|
||||
args: {
|
||||
align: 'right',
|
||||
},
|
||||
};
|
||||
|
||||
export const VerticalAlignTop: Story = {
|
||||
args: {
|
||||
alignY: 'top',
|
||||
},
|
||||
};
|
||||
|
||||
export const VerticalAlignCenter: Story = {
|
||||
args: {
|
||||
alignY: 'center',
|
||||
},
|
||||
};
|
||||
|
||||
export const VerticalAlignBottom: Story = {
|
||||
args: {
|
||||
alignY: 'bottom',
|
||||
},
|
||||
};
|
||||
|
||||
export const LargeGap: Story = {
|
||||
args: {
|
||||
gap: 'xl',
|
||||
},
|
||||
};
|
||||
@@ -1,85 +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 { createElement, forwardRef } from 'react';
|
||||
import type { InlineProps } from './types';
|
||||
import { getClassNames } from '../../utils/getClassNames';
|
||||
import { JustifyContent, Breakpoint, AlignItems } from '../../types';
|
||||
import clsx from 'clsx';
|
||||
|
||||
// Function to map align values
|
||||
const mapAlignValue = (value?: InlineProps['align']) => {
|
||||
if (typeof value === 'string') {
|
||||
let returnedValue: JustifyContent = 'stretch';
|
||||
if (value === 'left') returnedValue = 'start';
|
||||
if (value === 'center') returnedValue = 'center';
|
||||
if (value === 'right') returnedValue = 'end';
|
||||
return returnedValue;
|
||||
} else if (typeof value === 'object') {
|
||||
const returnedValue: Partial<Record<Breakpoint, JustifyContent>> = {};
|
||||
for (const [key, val] of Object.entries(value)) {
|
||||
returnedValue[key as Breakpoint] = mapAlignValue(val) as JustifyContent;
|
||||
}
|
||||
return returnedValue;
|
||||
}
|
||||
return 'stretch';
|
||||
};
|
||||
|
||||
const mapAlignYValue = (value?: InlineProps['alignY']) => {
|
||||
if (typeof value === 'string') {
|
||||
let returnedValue: AlignItems = 'stretch';
|
||||
if (value === 'top') returnedValue = 'start';
|
||||
if (value === 'center') returnedValue = 'center';
|
||||
if (value === 'bottom') returnedValue = 'end';
|
||||
return returnedValue;
|
||||
} else if (typeof value === 'object') {
|
||||
const returnedValue: Partial<Record<Breakpoint, AlignItems>> = {};
|
||||
for (const [key, val] of Object.entries(value)) {
|
||||
returnedValue[key as Breakpoint] = mapAlignYValue(val) as AlignItems;
|
||||
}
|
||||
return returnedValue;
|
||||
}
|
||||
return 'stretch';
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export const Inline = forwardRef<HTMLElement, InlineProps>((props, ref) => {
|
||||
const {
|
||||
as = 'div',
|
||||
children,
|
||||
align = 'left',
|
||||
alignY = 'top',
|
||||
gap = 'xs',
|
||||
className,
|
||||
style,
|
||||
...restProps
|
||||
} = props;
|
||||
|
||||
// Generate utility class names
|
||||
const utilityClassNames = getClassNames({
|
||||
gap,
|
||||
alignItems: mapAlignYValue(alignY),
|
||||
justifyContent: mapAlignValue(align),
|
||||
...restProps,
|
||||
});
|
||||
|
||||
return createElement(as, {
|
||||
ref,
|
||||
className: clsx('canon-Inline', utilityClassNames, className),
|
||||
style,
|
||||
children,
|
||||
});
|
||||
});
|
||||
@@ -1,41 +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 type {
|
||||
SpaceProps,
|
||||
UtilityProps,
|
||||
AsProps,
|
||||
Breakpoint,
|
||||
} from '../../types';
|
||||
|
||||
/** @public */
|
||||
export interface InlineProps extends SpaceProps {
|
||||
children: React.ReactNode;
|
||||
as?: AsProps;
|
||||
gap?: UtilityProps['gap'];
|
||||
align?:
|
||||
| 'left'
|
||||
| 'center'
|
||||
| 'right'
|
||||
| Partial<Record<Breakpoint, 'left' | 'center' | 'right'>>;
|
||||
alignY?:
|
||||
| 'top'
|
||||
| 'center'
|
||||
| 'bottom'
|
||||
| Partial<Record<Breakpoint, 'top' | 'center' | 'bottom'>>;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
import React from 'react';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { Input } from './Input';
|
||||
import { Inline } from '../Inline';
|
||||
import { Flex } from '../Flex';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/Input',
|
||||
@@ -33,9 +33,9 @@ export const Primary: Story = {
|
||||
|
||||
export const Sizes: Story = {
|
||||
render: () => (
|
||||
<Inline>
|
||||
<Flex>
|
||||
<Input size="sm" />
|
||||
<Input size="md" />
|
||||
</Inline>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -1,19 +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.
|
||||
*/
|
||||
export { Stack } from './Stack';
|
||||
export { stackPropDefs } from './Stack.props';
|
||||
export type { StackProps } from './types';
|
||||
export type { StackOwnProps } from './Stack.props';
|
||||
@@ -1,20 +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.
|
||||
*/
|
||||
|
||||
.canon-Stack {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
import React from 'react';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { Text } from './Text';
|
||||
import { Stack } from '../Stack';
|
||||
import { Flex } from '../Flex';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/Text',
|
||||
@@ -40,7 +40,7 @@ export const Default: Story = {
|
||||
|
||||
export const AllVariants: Story = {
|
||||
render: () => (
|
||||
<Stack gap="md">
|
||||
<Flex gap="4">
|
||||
<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's father is my father's son.” Who is
|
||||
@@ -61,13 +61,13 @@ export const AllVariants: Story = {
|
||||
have none, but that man's father is my father's son.” Who is
|
||||
in the painting?
|
||||
</Text>
|
||||
</Stack>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
export const AllWeights: Story = {
|
||||
render: () => (
|
||||
<Stack gap="md">
|
||||
<Flex gap="4">
|
||||
<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's father is my father's son.” Who is
|
||||
@@ -78,7 +78,7 @@ export const AllWeights: Story = {
|
||||
have none, but that man's father is my father's son.” Who is
|
||||
in the painting?
|
||||
</Text>
|
||||
</Stack>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -93,7 +93,7 @@ export const Responsive: Story = {
|
||||
|
||||
export const Playground: Story = {
|
||||
render: () => (
|
||||
<Stack>
|
||||
<Flex>
|
||||
<Text>Subtitle</Text>
|
||||
<Text variant="subtitle" style={{ maxWidth: '600px' }}>
|
||||
A man looks at a painting in a museum and says, “Brothers and sisters I
|
||||
@@ -118,6 +118,6 @@ export const Playground: Story = {
|
||||
have none, but that man's father is my father's son.” Who is
|
||||
in the painting?
|
||||
</Text>
|
||||
</Stack>
|
||||
</Flex>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -17,8 +17,7 @@
|
||||
/* Components */
|
||||
@import '../components/Box/styles.css';
|
||||
@import '../components/Button/styles.css';
|
||||
@import '../components/Stack/styles.css';
|
||||
@import '../components/Inline/styles.css';
|
||||
@import '../components/Flex/styles.css';
|
||||
@import '../components/Grid/styles.css';
|
||||
@import '../components/Container/styles.css';
|
||||
@import '../components/Icon/styles.css';
|
||||
|
||||
@@ -14,24 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* Default utilities */
|
||||
@import './utilities/xs.css';
|
||||
|
||||
/* Min 640px */
|
||||
@import './utilities/sm.css';
|
||||
|
||||
/* Min 768px */
|
||||
@import './utilities/md.css';
|
||||
|
||||
/* Min 1024px */
|
||||
@import './utilities/lg.css';
|
||||
|
||||
/* Min 1280px */
|
||||
@import './utilities/xl.css';
|
||||
|
||||
/* Min 1536px */
|
||||
@import './utilities/2xl.css';
|
||||
|
||||
/* Padding */
|
||||
@import './utilities/p.css';
|
||||
@import './utilities/pl.css';
|
||||
|
||||
@@ -1,164 +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.
|
||||
*/
|
||||
|
||||
@layer utilities {
|
||||
@media (min-width: 1536px) {
|
||||
.cu-2xl-block {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.cu-2xl-border-base {
|
||||
border-color: var(--canon-border);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.cu-2xl-border-error {
|
||||
border-color: var(--canon-border-danger);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.cu-2xl-border-none {
|
||||
border-color: transparent;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.cu-2xl-border-selected {
|
||||
border-color: var(--canon-border-focus);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.cu-2xl-border-warning {
|
||||
border-color: var(--canon-border-warning);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.cu-2xl-flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.cu-2xl-flex-col {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.cu-2xl-flex-nowrap {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.cu-2xl-flex-row {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.cu-2xl-flex-wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.cu-2xl-flex-wrap-reverse {
|
||||
flex-wrap: wrap-reverse;
|
||||
}
|
||||
|
||||
.cu-2xl-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cu-2xl-inline {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.cu-2xl-inline-block {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.cu-2xl-items-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.cu-2xl-items-end {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.cu-2xl-items-start {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.cu-2xl-items-stretch {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.cu-2xl-justify-around {
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.cu-2xl-justify-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.cu-2xl-justify-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.cu-2xl-justify-end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.cu-2xl-justify-start {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.cu-2xl-justify-stretch {
|
||||
justify-content: stretch;
|
||||
}
|
||||
|
||||
.cu-2xl-rounded-2xl {
|
||||
border-radius: var(--canon-radius-full);
|
||||
}
|
||||
|
||||
.cu-2xl-rounded-2xs {
|
||||
border-radius: var(--canon-radius-1);
|
||||
}
|
||||
|
||||
.cu-2xl-rounded-lg {
|
||||
border-radius: var(--canon-radius-5);
|
||||
}
|
||||
|
||||
.cu-2xl-rounded-md {
|
||||
border-radius: var(--canon-radius-4);
|
||||
}
|
||||
|
||||
.cu-2xl-rounded-none {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.cu-2xl-rounded-sm {
|
||||
border-radius: var(--canon-radius-3);
|
||||
}
|
||||
|
||||
.cu-2xl-rounded-xl {
|
||||
border-radius: var(--canon-radius-6);
|
||||
}
|
||||
|
||||
.cu-2xl-rounded-xs {
|
||||
border-radius: var(--canon-radius-2);
|
||||
}
|
||||
|
||||
.cu-2xl-wrap-reverse {
|
||||
flex-wrap: wrap-reverse;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,42 @@
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.cu-align-stretch {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.cu-jc-start {
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
.cu-jc-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.cu-jc-end {
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.cu-jc-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.cu-fd-row {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.cu-fd-column {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.cu-fd-row-reverse {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.cu-fd-column-reverse {
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
|
||||
/* Breakpoint xs */
|
||||
@media (min-width: 640px) {
|
||||
.xs\:cu-align-start {
|
||||
@@ -23,6 +59,42 @@
|
||||
.xs\:cu-align-end {
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.xs\:cu-align-stretch {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.xs\:cu-jc-start {
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
.xs\:cu-jc-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.xs\:cu-jc-end {
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.xs\:cu-jc-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.xs\:cu-fd-row {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.xs\:cu-fd-column {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.xs\:cu-fd-row-reverse {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.xs\:cu-fd-column-reverse {
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
}
|
||||
|
||||
/* Breakpoint sm */
|
||||
@@ -38,6 +110,42 @@
|
||||
.sm\:cu-align-end {
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.sm\:cu-align-stretch {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.sm\:cu-jc-start {
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
.sm\:cu-jc-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.sm\:cu-jc-end {
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.sm\:cu-jc-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.sm\:cu-fd-row {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.sm\:cu-fd-column {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sm\:cu-fd-row-reverse {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.sm\:cu-fd-column-reverse {
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
}
|
||||
|
||||
/* Breakpoint md */
|
||||
@@ -53,6 +161,42 @@
|
||||
.md\:cu-align-end {
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.md\:cu-align-stretch {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.md\:cu-jc-start {
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
.md\:cu-jc-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.md\:cu-jc-end {
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.md\:cu-jc-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.md\:cu-fd-row {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.md\:cu-fd-column {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.md\:cu-fd-row-reverse {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.md\:cu-fd-column-reverse {
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
}
|
||||
|
||||
/* Breakpoint lg */
|
||||
@@ -68,6 +212,42 @@
|
||||
.lg\:cu-align-end {
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.lg\:cu-align-stretch {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.lg\:cu-jc-start {
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
.lg\:cu-jc-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.lg\:cu-jc-end {
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.lg\:cu-jc-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.lg\:cu-fd-row {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.lg\:cu-fd-column {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.lg\:cu-fd-row-reverse {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.lg\:cu-fd-column-reverse {
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
}
|
||||
|
||||
/* Breakpoint xl */
|
||||
@@ -83,4 +263,40 @@
|
||||
.xl\:cu-align-end {
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.xl\:cu-align-stretch {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.xl\:cu-jc-start {
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
.xl\:cu-jc-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.xl\:cu-jc-end {
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.xl\:cu-jc-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.xl\:cu-fd-row {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.xl\:cu-fd-column {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.xl\:cu-fd-row-reverse {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.xl\:cu-fd-column-reverse {
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,164 +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.
|
||||
*/
|
||||
|
||||
@layer utilities {
|
||||
@media (min-width: 1024px) {
|
||||
.cu-lg-block {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.cu-lg-border-base {
|
||||
border-color: var(--canon-border);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.cu-lg-border-error {
|
||||
border-color: var(--canon-border-danger);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.cu-lg-border-none {
|
||||
border-color: transparent;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.cu-lg-border-selected {
|
||||
border-color: var(--canon-border-focus);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.cu-lg-border-warning {
|
||||
border-color: var(--canon-border-warning);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.cu-lg-flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.cu-lg-flex-col {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.cu-lg-flex-nowrap {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.cu-lg-flex-row {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.cu-lg-flex-wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.cu-lg-flex-wrap-reverse {
|
||||
flex-wrap: wrap-reverse;
|
||||
}
|
||||
|
||||
.cu-lg-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cu-lg-inline {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.cu-lg-inline-block {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.cu-lg-items-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.cu-lg-items-end {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.cu-lg-items-start {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.cu-lg-items-stretch {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.cu-lg-justify-around {
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.cu-lg-justify-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.cu-lg-justify-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.cu-lg-justify-end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.cu-lg-justify-start {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.cu-lg-justify-stretch {
|
||||
justify-content: stretch;
|
||||
}
|
||||
|
||||
.cu-lg-rounded-2xl {
|
||||
border-radius: var(--canon-radius-full);
|
||||
}
|
||||
|
||||
.cu-lg-rounded-2xs {
|
||||
border-radius: var(--canon-radius-1);
|
||||
}
|
||||
|
||||
.cu-lg-rounded-lg {
|
||||
border-radius: var(--canon-radius-5);
|
||||
}
|
||||
|
||||
.cu-lg-rounded-md {
|
||||
border-radius: var(--canon-radius-4);
|
||||
}
|
||||
|
||||
.cu-lg-rounded-none {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.cu-lg-rounded-sm {
|
||||
border-radius: var(--canon-radius-3);
|
||||
}
|
||||
|
||||
.cu-lg-rounded-xl {
|
||||
border-radius: var(--canon-radius-6);
|
||||
}
|
||||
|
||||
.cu-lg-rounded-xs {
|
||||
border-radius: var(--canon-radius-2);
|
||||
}
|
||||
|
||||
.cu-lg-wrap-reverse {
|
||||
flex-wrap: wrap-reverse;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,164 +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.
|
||||
*/
|
||||
|
||||
@layer utilities {
|
||||
@media (min-width: 768px) {
|
||||
.cu-md-block {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.cu-md-border-base {
|
||||
border-color: var(--canon-border);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.cu-md-border-error {
|
||||
border-color: var(--canon-border-danger);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.cu-md-border-none {
|
||||
border-color: transparent;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.cu-md-border-selected {
|
||||
border-color: var(--canon-border-focus);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.cu-md-border-warning {
|
||||
border-color: var(--canon-border-warning);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.cu-md-flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.cu-md-flex-col {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.cu-md-flex-nowrap {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.cu-md-flex-row {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.cu-md-flex-wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.cu-md-flex-wrap-reverse {
|
||||
flex-wrap: wrap-reverse;
|
||||
}
|
||||
|
||||
.cu-md-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cu-md-inline {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.cu-md-inline-block {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.cu-md-items-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.cu-md-items-end {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.cu-md-items-start {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.cu-md-items-stretch {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.cu-md-justify-around {
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.cu-md-justify-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.cu-md-justify-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.cu-md-justify-end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.cu-md-justify-start {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.cu-md-justify-stretch {
|
||||
justify-content: stretch;
|
||||
}
|
||||
|
||||
.cu-md-rounded-2xl {
|
||||
border-radius: var(--canon-radius-full);
|
||||
}
|
||||
|
||||
.cu-md-rounded-2xs {
|
||||
border-radius: var(--canon-radius-1);
|
||||
}
|
||||
|
||||
.cu-md-rounded-lg {
|
||||
border-radius: var(--canon-radius-5);
|
||||
}
|
||||
|
||||
.cu-md-rounded-md {
|
||||
border-radius: var(--canon-radius-4);
|
||||
}
|
||||
|
||||
.cu-md-rounded-none {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.cu-md-rounded-sm {
|
||||
border-radius: var(--canon-radius-3);
|
||||
}
|
||||
|
||||
.cu-md-rounded-xl {
|
||||
border-radius: var(--canon-radius-6);
|
||||
}
|
||||
|
||||
.cu-md-rounded-xs {
|
||||
border-radius: var(--canon-radius-2);
|
||||
}
|
||||
|
||||
.cu-md-wrap-reverse {
|
||||
flex-wrap: wrap-reverse;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,164 +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.
|
||||
*/
|
||||
|
||||
@layer utilities {
|
||||
@media (min-width: 1280px) {
|
||||
.cu-xl-block {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.cu-xl-border-base {
|
||||
border-color: var(--canon-border);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.cu-xl-border-error {
|
||||
border-color: var(--canon-border-danger);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.cu-xl-border-none {
|
||||
border-color: transparent;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.cu-xl-border-selected {
|
||||
border-color: var(--canon-border-focus);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.cu-xl-border-warning {
|
||||
border-color: var(--canon-border-warning);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.cu-xl-flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.cu-xl-flex-col {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.cu-xl-flex-nowrap {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.cu-xl-flex-row {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.cu-xl-flex-wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.cu-xl-flex-wrap-reverse {
|
||||
flex-wrap: wrap-reverse;
|
||||
}
|
||||
|
||||
.cu-xl-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cu-xl-inline {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.cu-xl-inline-block {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.cu-xl-items-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.cu-xl-items-end {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.cu-xl-items-start {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.cu-xl-items-stretch {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.cu-xl-justify-around {
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.cu-xl-justify-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.cu-xl-justify-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.cu-xl-justify-end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.cu-xl-justify-start {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.cu-xl-justify-stretch {
|
||||
justify-content: stretch;
|
||||
}
|
||||
|
||||
.cu-xl-rounded-2xl {
|
||||
border-radius: var(--canon-radius-full);
|
||||
}
|
||||
|
||||
.cu-xl-rounded-2xs {
|
||||
border-radius: var(--canon-radius-1);
|
||||
}
|
||||
|
||||
.cu-xl-rounded-lg {
|
||||
border-radius: var(--canon-radius-5);
|
||||
}
|
||||
|
||||
.cu-xl-rounded-md {
|
||||
border-radius: var(--canon-radius-4);
|
||||
}
|
||||
|
||||
.cu-xl-rounded-none {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.cu-xl-rounded-sm {
|
||||
border-radius: var(--canon-radius-3);
|
||||
}
|
||||
|
||||
.cu-xl-rounded-xl {
|
||||
border-radius: var(--canon-radius-6);
|
||||
}
|
||||
|
||||
.cu-xl-rounded-xs {
|
||||
border-radius: var(--canon-radius-2);
|
||||
}
|
||||
|
||||
.cu-xl-wrap-reverse {
|
||||
flex-wrap: wrap-reverse;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,8 +26,7 @@ export * from './contexts/canon';
|
||||
// Layout components
|
||||
export * from './components/Box';
|
||||
export * from './components/Grid';
|
||||
export * from './components/Stack';
|
||||
export * from './components/Inline';
|
||||
export * from './components/Flex';
|
||||
export * from './components/Container';
|
||||
export * from './components/Text';
|
||||
export * from './components/Heading';
|
||||
|
||||
@@ -1,206 +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 type { Breakpoint, UtilityProps } from '../types';
|
||||
|
||||
const spaceMap = (type: string) => ({
|
||||
none: `${type}-none`,
|
||||
'2xs': `${type}-2xs`,
|
||||
xs: `${type}-xs`,
|
||||
sm: `${type}-sm`,
|
||||
md: `${type}-md`,
|
||||
lg: `${type}-lg`,
|
||||
xl: `${type}-xl`,
|
||||
'2xl': `${type}-2xl`,
|
||||
});
|
||||
|
||||
const valueMap: Record<string, Record<string, string>> = {
|
||||
alignItems: {
|
||||
stretch: 'items-stretch',
|
||||
start: 'items-start',
|
||||
center: 'items-center',
|
||||
end: 'items-end',
|
||||
},
|
||||
border: {
|
||||
none: 'border-none',
|
||||
base: 'border-base',
|
||||
error: 'border-error',
|
||||
warning: 'border-warning',
|
||||
selected: 'border-selected',
|
||||
},
|
||||
borderRadius: {
|
||||
none: 'rounded-none',
|
||||
'2xs': 'rounded-2xs',
|
||||
xs: 'rounded-xs',
|
||||
sm: 'rounded-sm',
|
||||
md: 'rounded-md',
|
||||
lg: 'rounded-lg',
|
||||
xl: 'rounded-xl',
|
||||
'2xl': 'rounded-2xl',
|
||||
},
|
||||
colEnd: {
|
||||
1: 'col-end-1',
|
||||
2: 'col-end-2',
|
||||
3: 'col-end-3',
|
||||
4: 'col-end-4',
|
||||
5: 'col-end-5',
|
||||
6: 'col-end-6',
|
||||
7: 'col-end-7',
|
||||
8: 'col-end-8',
|
||||
9: 'col-end-9',
|
||||
10: 'col-end-10',
|
||||
11: 'col-end-11',
|
||||
12: 'col-end-12',
|
||||
auto: 'col-end-auto',
|
||||
},
|
||||
colSpan: {
|
||||
1: 'col-span-1',
|
||||
2: 'col-span-2',
|
||||
3: 'col-span-3',
|
||||
4: 'col-span-4',
|
||||
5: 'col-span-5',
|
||||
6: 'col-span-6',
|
||||
7: 'col-span-7',
|
||||
8: 'col-span-8',
|
||||
9: 'col-span-9',
|
||||
10: 'col-span-10',
|
||||
11: 'col-span-11',
|
||||
12: 'col-span-12',
|
||||
auto: 'col-span-auto',
|
||||
},
|
||||
colStart: {
|
||||
1: 'col-start-1',
|
||||
2: 'col-start-2',
|
||||
3: 'col-start-3',
|
||||
4: 'col-start-4',
|
||||
5: 'col-start-5',
|
||||
6: 'col-start-6',
|
||||
7: 'col-start-7',
|
||||
8: 'col-start-8',
|
||||
9: 'col-start-9',
|
||||
10: 'col-start-10',
|
||||
11: 'col-start-11',
|
||||
12: 'col-start-12',
|
||||
auto: 'col-start-auto',
|
||||
},
|
||||
columns: {
|
||||
1: 'grid-cols-1',
|
||||
2: 'grid-cols-2',
|
||||
3: 'grid-cols-3',
|
||||
4: 'grid-cols-4',
|
||||
5: 'grid-cols-5',
|
||||
6: 'grid-cols-6',
|
||||
7: 'grid-cols-7',
|
||||
8: 'grid-cols-8',
|
||||
9: 'grid-cols-9',
|
||||
10: 'grid-cols-10',
|
||||
11: 'grid-cols-11',
|
||||
12: 'grid-cols-12',
|
||||
auto: 'grid-cols-auto',
|
||||
},
|
||||
display: {
|
||||
none: 'hidden',
|
||||
flex: 'flex',
|
||||
block: 'block',
|
||||
inline: 'inline',
|
||||
},
|
||||
flexDirection: {
|
||||
row: 'flex-row',
|
||||
column: 'flex-col',
|
||||
},
|
||||
flexWrap: {
|
||||
wrap: 'flex-wrap',
|
||||
nowrap: 'flex-nowrap',
|
||||
'wrap-reverse': 'flex-wrap-reverse',
|
||||
},
|
||||
gap: spaceMap('gap'),
|
||||
justifyContent: {
|
||||
stretch: 'justify-stretch',
|
||||
start: 'justify-start',
|
||||
center: 'justify-center',
|
||||
end: 'justify-end',
|
||||
around: 'justify-around',
|
||||
between: 'justify-between',
|
||||
},
|
||||
margin: spaceMap('m'),
|
||||
marginBottom: spaceMap('mb'),
|
||||
marginLeft: spaceMap('ml'),
|
||||
marginRight: spaceMap('mr'),
|
||||
marginTop: spaceMap('mt'),
|
||||
marginX: spaceMap('mx'),
|
||||
marginY: spaceMap('my'),
|
||||
padding: spaceMap('p'),
|
||||
paddingBottom: spaceMap('pb'),
|
||||
paddingLeft: spaceMap('pl'),
|
||||
paddingRight: spaceMap('pr'),
|
||||
paddingTop: spaceMap('pt'),
|
||||
paddingX: spaceMap('px'),
|
||||
paddingY: spaceMap('py'),
|
||||
rowSpan: {
|
||||
1: 'row-span-1',
|
||||
2: 'row-span-2',
|
||||
3: 'row-span-3',
|
||||
4: 'row-span-4',
|
||||
5: 'row-span-5',
|
||||
6: 'row-span-6',
|
||||
7: 'row-span-7',
|
||||
8: 'row-span-8',
|
||||
9: 'row-span-9',
|
||||
10: 'row-span-10',
|
||||
11: 'row-span-11',
|
||||
12: 'row-span-12',
|
||||
full: 'row-span-full',
|
||||
},
|
||||
};
|
||||
|
||||
const generateClassNames = (propName: string, propValue: any) => {
|
||||
const classNames: string[] = [];
|
||||
|
||||
// If the property name is not in the valueMap, return an empty array
|
||||
if (!valueMap.hasOwnProperty(propName)) {
|
||||
return classNames;
|
||||
}
|
||||
|
||||
if (typeof propValue === 'string' || typeof propValue === 'number') {
|
||||
// If the property value is a string, map it to the valueMap
|
||||
const value = valueMap[propName]?.[propValue] || propValue;
|
||||
classNames.push(`cu-${value}`);
|
||||
} else if (typeof propValue === 'object') {
|
||||
// If the property value is an object, map each key-value pair
|
||||
Object.entries(propValue as Record<Breakpoint, string>).forEach(
|
||||
([breakpoint, value]) => {
|
||||
const mappedValue = valueMap[propName]?.[value] || value;
|
||||
|
||||
if (breakpoint === 'xs') {
|
||||
classNames.push(`cu-${mappedValue}`);
|
||||
} else {
|
||||
classNames.push(`cu-${breakpoint}-${mappedValue}`);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
return classNames;
|
||||
};
|
||||
|
||||
export const getClassNames = (props: UtilityProps) => {
|
||||
const classNames: string[] = [];
|
||||
|
||||
Object.entries(props).forEach(([propName, propValue]) => {
|
||||
classNames.push(...generateClassNames(propName, propValue));
|
||||
});
|
||||
|
||||
return classNames.filter(Boolean).join(' ');
|
||||
};
|
||||
Reference in New Issue
Block a user