diff --git a/packages/canon/docs/Home.mdx b/packages/canon/docs/Home.mdx index 51574f57a1..cbe84fcfb1 100644 --- a/packages/canon/docs/Home.mdx +++ b/packages/canon/docs/Home.mdx @@ -48,6 +48,11 @@ import { list } from './components/Roadmap/list'; link="/?path=/docs/components-button--docs" /> + Layout Helpers -TBD + + Sometimes you want to use global tokens dynamically outside of React + components. To help you with that we would like to provide a set of helpers + that you can use in your code. These helpers are not available just yet but we + are working on it. + diff --git a/packages/canon/docs/components/LayoutComponents/box.tsx b/packages/canon/docs/components/LayoutComponents/box.tsx new file mode 100644 index 0000000000..1749b38c6f --- /dev/null +++ b/packages/canon/docs/components/LayoutComponents/box.tsx @@ -0,0 +1,54 @@ +/* + * 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'; + +export const BoxSvg = () => { + return ( + + + + + + + + ); +}; diff --git a/packages/canon/docs/components/LayoutComponents/container.tsx b/packages/canon/docs/components/LayoutComponents/container.tsx new file mode 100644 index 0000000000..62fe4ce266 --- /dev/null +++ b/packages/canon/docs/components/LayoutComponents/container.tsx @@ -0,0 +1,373 @@ +/* + * 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'; + +export const ContainerSvg = () => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/packages/canon/docs/components/LayoutComponents/grid.tsx b/packages/canon/docs/components/LayoutComponents/grid.tsx new file mode 100644 index 0000000000..5527d1f3e2 --- /dev/null +++ b/packages/canon/docs/components/LayoutComponents/grid.tsx @@ -0,0 +1,91 @@ +/* + * 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'; + +export const GridSvg = () => { + return ( + + + + + + + + + + + + ); +}; diff --git a/packages/canon/docs/components/LayoutComponents/index.tsx b/packages/canon/docs/components/LayoutComponents/index.tsx index 9e0b039684..16a7a1726c 100644 --- a/packages/canon/docs/components/LayoutComponents/index.tsx +++ b/packages/canon/docs/components/LayoutComponents/index.tsx @@ -21,88 +21,50 @@ import { content, title, description, - whiteBox, - whiteBoxStack, - stack, - verticalDivider, - horizontalDivider, - columns, - inline, - tiles, - whiteBoxColumns, - whiteBoxInline, - whiteBoxTiles, } from './layout-components.css'; +import { BoxSvg } from './box'; +import { StackSvg } from './stack'; +import { GridSvg } from './grid'; +import { InlineSvg } from './inline'; +import { ContainerSvg } from './container'; export const LayoutComponents = () => { return (
-
+
Box
-
The most basic layout component.
+
The most basic layout component
- -
-
-
+ +
Stack
-
Arrange your components vertically.
+
Arrange your components vertically
- -
-
-
+ + -
Columns
-
Arrange your components horizontally.
+
Grid
+
Arrange your components in a grid
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
Inline
-
Arrange your components in a row.
+
Arrange your components in a row
-
-
-
-
-
-
- ); diff --git a/packages/canon/docs/components/LayoutComponents/inline.tsx b/packages/canon/docs/components/LayoutComponents/inline.tsx new file mode 100644 index 0000000000..fadb9bfc1b --- /dev/null +++ b/packages/canon/docs/components/LayoutComponents/inline.tsx @@ -0,0 +1,92 @@ +/* + * 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'; + +export const InlineSvg = () => { + return ( + + + + + + + + + + + + ); +}; diff --git a/packages/canon/docs/components/LayoutComponents/layout-components.css.ts b/packages/canon/docs/components/LayoutComponents/layout-components.css.ts index a8440dd01f..62fd3a634f 100644 --- a/packages/canon/docs/components/LayoutComponents/layout-components.css.ts +++ b/packages/canon/docs/components/LayoutComponents/layout-components.css.ts @@ -33,19 +33,18 @@ export const box = style({ export const content = style({ flex: 'none', - background: '#f2f2f2', + background: 'linear-gradient(180deg, #F3F3F3 0%, #FFF 100%)', borderRadius: '4px', width: '100%', height: '180px', - border: '1px solid #e0e0e0', - transition: 'border-color 0.2s ease-in-out', + transition: 'all 0.2s ease-in-out', marginBottom: '0.75rem', display: 'flex', alignItems: 'center', justifyContent: 'center', selectors: { [`${box}:hover &`]: { - borderColor: '#1f47ff', + transform: 'translateY(-4px)', }, }, }); @@ -55,11 +54,6 @@ export const title = style({ fontFamily: 'var(--canon-font-sans)', transition: 'color 0.2s ease-in-out', marginBottom: '0.25rem', - selectors: { - [`${box}:hover &`]: { - color: '#1f47ff', - }, - }, }); export const description = style({ @@ -67,132 +61,3 @@ export const description = style({ fontFamily: 'var(--canon-font-sans)', color: '#9e9e9e', }); - -export const whiteBox = style({ - background: '#fff', - width: '40px', - height: '40px', - borderRadius: '4px', - boxShadow: '0px 2px 4px rgba(0, 0, 0, 0.1)', -}); - -export const whiteBoxStack = style([ - whiteBox, - { - width: '40%', - height: '28px', - }, -]); - -export const whiteBoxColumns = style([ - whiteBox, - { - width: '30%', - height: '32px', - }, -]); - -export const whiteBoxInline = style([ - whiteBox, - { - width: '32px', - height: '32px', - }, -]); - -export const whiteBoxTiles = style([ - whiteBox, - { - width: '100%', - height: '32px', - }, -]); - -export const stack = style({ - display: 'flex', - flexDirection: 'column', -}); - -export const columns = style({ - display: 'flex', - flexDirection: 'row', -}); - -export const inline = style({ - display: 'flex', - flexWrap: 'wrap', - flexDirection: 'row', - justifyContent: 'flex-start', - alignItems: 'flex-start', - gap: '0.5rem', - paddingLeft: '1rem', -}); - -export const tiles = style({ - display: 'grid', - gridTemplateColumns: 'repeat(4, 1fr)', - gap: '0.5rem', - paddingLeft: '1rem', - paddingRight: '1rem', - width: '100%', -}); - -export const verticalDivider = style({ - display: 'flex', - flexShrink: 0, - flexDirection: 'column', - position: 'relative', - height: '20px', - width: '2px', - backgroundColor: '#1f47ff', - selectors: { - '&::before': { - content: '""', - position: 'absolute', - top: 0, - left: '-9px', - width: '20px', - height: '2px', - backgroundColor: '#1f47ff', - }, - '&::after': { - content: '""', - position: 'absolute', - bottom: 0, - left: '-9px', - width: '20px', - height: '2px', - backgroundColor: '#1f47ff', - }, - }, -}); - -export const horizontalDivider = style({ - flexShrink: 0, - display: 'flex', - flexDirection: 'row', - position: 'relative', - height: '2px', - width: '20px', - backgroundColor: '#1f47ff', - selectors: { - '&::before': { - content: '""', - position: 'absolute', - left: 0, - top: '-9px', - width: '2px', - height: '20px', - backgroundColor: '#1f47ff', - }, - '&::after': { - content: '""', - position: 'absolute', - right: 0, - top: '-9px', - width: '2px', - height: '20px', - backgroundColor: '#1f47ff', - }, - }, -}); diff --git a/packages/canon/docs/components/LayoutComponents/stack.tsx b/packages/canon/docs/components/LayoutComponents/stack.tsx new file mode 100644 index 0000000000..aeda998d2e --- /dev/null +++ b/packages/canon/docs/components/LayoutComponents/stack.tsx @@ -0,0 +1,82 @@ +/* + * 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'; + +export const StackSvg = () => { + return ( + + + + + + + + + + + + ); +}; diff --git a/packages/canon/docs/components/PropsTable/PropsTable.tsx b/packages/canon/docs/components/PropsTable/PropsTable.tsx new file mode 100644 index 0000000000..a3dc9e271c --- /dev/null +++ b/packages/canon/docs/components/PropsTable/PropsTable.tsx @@ -0,0 +1,57 @@ +/* + * 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 * as Table from '..'; +import { Chip } from '..'; + +// Modify the PropsTable component to accept a generic type +export const PropsTable = >({ + data, +}: { + data: T; +}) => { + return ( + + + + Prop + Type + Responsive + + + + {Object.keys(data).map(n => ( + + + {n} + + + {Array.isArray(data[n].type) ? ( + data[n].type.map((t: any) => {t}) + ) : ( + {data[n].type} + )} + + + {data[n].responsive ? 'Yes' : 'No'} + + + ))} + + + ); +}; diff --git a/packages/canon/docs/components/PropsTable/getProps.ts b/packages/canon/docs/components/PropsTable/getProps.ts new file mode 100644 index 0000000000..866dcb9d10 --- /dev/null +++ b/packages/canon/docs/components/PropsTable/getProps.ts @@ -0,0 +1,43 @@ +/* + * 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 function getBoxProps(styles: Record) { + return Object.keys(styles).reduce( + (acc: Record, n) => { + const style = styles[n]; + + let values: string[] = []; + + if (style.values) { + // If values exist, use them + values = Object.keys(style.values); + } else if (style.mappings && style.mappings.length > 0) { + // If mappings exist, use the first mapping's values + const firstMapping = style.mappings[0]; + values = Object.keys(styles[firstMapping].values); + } else { + // Default to an empty array if neither values nor mappings exist + values = []; + } + + acc[n] = { + type: values, + responsive: true, + }; + return acc; + }, + {} as Record, + ); +} diff --git a/packages/canon/docs/components/PropsTable/index.ts b/packages/canon/docs/components/PropsTable/index.ts new file mode 100644 index 0000000000..010452ee2a --- /dev/null +++ b/packages/canon/docs/components/PropsTable/index.ts @@ -0,0 +1,17 @@ +/* + * 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 { PropsTable } from './PropsTable'; +export { getBoxProps } from './getProps'; diff --git a/packages/canon/docs/components/Text/text.css.ts b/packages/canon/docs/components/Text/text.css.ts index 01b4cb8fc8..fbbc427362 100644 --- a/packages/canon/docs/components/Text/text.css.ts +++ b/packages/canon/docs/components/Text/text.css.ts @@ -22,7 +22,7 @@ export const textStyles = style({ lineHeight: '28px', margin: '0', fontWeight: 300, - paddingBottom: '16px', + marginBottom: '16px', }); globalStyle(`${textStyles} p`, { diff --git a/packages/canon/docs/components/Title/title.css.ts b/packages/canon/docs/components/Title/title.css.ts index 5ca0394af6..6618ad80be 100644 --- a/packages/canon/docs/components/Title/title.css.ts +++ b/packages/canon/docs/components/Title/title.css.ts @@ -28,7 +28,7 @@ export const titleStyles = recipe({ h1: { fontSize: '36px', lineHeight: '44px', - marginBottom: '32px', + marginBottom: '8px', marginTop: '0px', }, h2: { @@ -41,7 +41,7 @@ export const titleStyles = recipe({ fontSize: '20px', lineHeight: '28px', marginBottom: '12px', - marginTop: '52px', + marginTop: '40px', }, }, }, diff --git a/packages/canon/docs/utils/argTypes.ts b/packages/canon/docs/utils/argTypes.ts index ff5a159677..e6a68008f8 100644 --- a/packages/canon/docs/utils/argTypes.ts +++ b/packages/canon/docs/utils/argTypes.ts @@ -24,6 +24,11 @@ export const listResponsiveValues = ( ) => { const values = boxProperties.styles[value]; + if (!values) { + console.warn(`Value "${value}" not found in boxProperties.styles`); + return []; + } + if ('values' in values) { return Object.keys(values.values); } diff --git a/packages/canon/src/components/Box/Docs.mdx b/packages/canon/src/components/Box/Docs.mdx index dac10952cf..3f78ba3a76 100644 --- a/packages/canon/src/components/Box/Docs.mdx +++ b/packages/canon/src/components/Box/Docs.mdx @@ -2,8 +2,9 @@ import { Canvas, Meta, Unstyled } from '@storybook/blocks'; import * as BoxStories from './Box.stories'; import { Title, Text } from '../../../docs/components'; import { Padding } from './docs/padding'; -import { PropsTable } from './docs/props-table'; -import { SpacingTable } from './docs/spacing-table'; +import { PropsTable, getBoxProps } from '../../../docs/components/PropsTable'; +import { boxProperties } from './sprinkles.css'; +import { spacingProperties } from '../../layout/sprinkles.css'; @@ -16,7 +17,23 @@ import { SpacingTable } from './docs/spacing-table'; provides a consistent API for styling and layout. You'll find below a list of all the available properties. - + Padding & Margin @@ -27,6 +44,6 @@ import { SpacingTable } from './docs/spacing-table'; - + diff --git a/packages/canon/src/components/Box/docs/props-table.tsx b/packages/canon/src/components/Box/docs/props-table.tsx deleted file mode 100644 index 9979701f2e..0000000000 --- a/packages/canon/src/components/Box/docs/props-table.tsx +++ /dev/null @@ -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 React from 'react'; -import * as Table from '../../../../docs/components'; -import { Chip } from '../../../../docs/components'; -import { listResponsiveValues } from '../../../../docs/utils/argTypes'; -import { boxProperties } from '../sprinkles.css'; - -export const PropsTable = () => { - return ( - - - - Prop - Type - - - - {Object.keys(boxProperties.styles) - .filter( - n => - ![ - 'padding', - 'paddingX', - 'paddingY', - 'paddingLeft', - 'paddingRight', - 'paddingTop', - 'paddingBottom', - 'margin', - 'marginX', - 'marginY', - 'marginLeft', - 'marginRight', - 'marginTop', - 'marginBottom', - ].includes(n), - ) - .map(n => ( - - - {n} - - - {listResponsiveValues( - n as keyof typeof boxProperties.styles, - ).map(value => ( - {value} - ))} - - - ))} - - - ); -}; diff --git a/packages/canon/src/components/Box/docs/spacing-table.tsx b/packages/canon/src/components/Box/docs/spacing-table.tsx deleted file mode 100644 index 93c38457d4..0000000000 --- a/packages/canon/src/components/Box/docs/spacing-table.tsx +++ /dev/null @@ -1,67 +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 * as Table from '../../../../docs/components'; -import { Chip } from '../../../../docs/components'; -import { spacingProperties } from '../../../layout/sprinkles.css'; -import { space } from '../../../layout/properties'; - -export const SpacingTable = () => { - return ( - - - - Prop - Type - - - - {Object.keys(spacingProperties.styles) - .filter(n => - [ - 'padding', - 'paddingX', - 'paddingY', - 'paddingLeft', - 'paddingRight', - 'paddingTop', - 'paddingBottom', - 'margin', - 'marginX', - 'marginY', - 'marginLeft', - 'marginRight', - 'marginTop', - 'marginBottom', - ].includes(n), - ) - .map(n => ( - - - {n} - - - {Object.keys(space).map(value => ( - {value} - ))} - - - ))} - - - ); -}; diff --git a/packages/canon/src/components/Grid/Docs.mdx b/packages/canon/src/components/Grid/Docs.mdx new file mode 100644 index 0000000000..c37d083ef1 --- /dev/null +++ b/packages/canon/src/components/Grid/Docs.mdx @@ -0,0 +1,211 @@ +import { Canvas, Meta, Unstyled, Source } from '@storybook/blocks'; +import * as GridStories from './Grid.stories'; +import { Title, Text } from '../../../docs/components'; +import { PropsTable, getBoxProps } from '../../../docs/components/PropsTable'; +import { spacingProperties } from '../../layout/sprinkles.css'; + + + + + +Grid + + A layout component that helps to create simple column-based layouts as well as + more complex ones. + + +Installation + + +Anatomy + + The grid component is made of two parts: the grid container and the grid item. Import all parts and piece them together. + + ( + + + +);`} + language="tsx" + dark +/> + +API reference + +Grid + + This is the grid 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. + + + + + + The grid component also accepts all the spacing props from the Box component. + + + + +Grid Item + + If you need more control over the columns, you can use the grid item + component. This will give you access to `rowSpan`, `colSpan`, `start` and + `end`. All values are responsive. This component is optional, you can use any + elements directly if you prefer. + + + + +Examples + +Simple grid +This is a simple grid with 3 columns and a gap of md. + + Hello World + Hello World + Hello World + +`} + language="tsx" + dark +/> + +Complex grid + + You can also use the grid item to create more complex layouts. In this example + the first column will span 1 column and the second column will span 2 columns. + + + + + Hello World + + + Hello World + + +`} + language="tsx" + dark +/> + +Mixing rows and columns + + The grid item component also supports the `rowSpan` prop, which allows you to + span multiple rows within the grid layout. In this example, the first item + will span 2 rows to achieve a dynamic and flexible grid structure. + + + + + Hello World + + + Hello World + + + Hello World + + +`} + language="tsx" + dark +/> + +Responsive + + The grid component also supports responsive values. In this example the grid + will have 1 column on small screens and 3 on large screens, with a gap of xs + on small screens and md on large screens. + + + + Hello World + + + Hello World + + +`} + language="tsx" + dark +/> + +Start and End + + The start and end props can be used to position the item in the grid. + + + + Hello World + + +`} + language="tsx" + dark +/> + + diff --git a/packages/canon/src/components/Grid/Grid.stories.tsx b/packages/canon/src/components/Grid/Grid.stories.tsx index e9833a0325..bf1bcecfd7 100644 --- a/packages/canon/src/components/Grid/Grid.stories.tsx +++ b/packages/canon/src/components/Grid/Grid.stories.tsx @@ -51,20 +51,25 @@ const FakeBox = () => ( ); export const Default: Story = { + args: {}, + render: args => ( + + + + + + ), +}; + +export const LargeGap: Story = { args: { - columns: 3, + gap: 'lg', }, render: args => ( - - - - - - - - - + + + ), }; @@ -78,10 +83,10 @@ export const ColumnSizes: Story = { {Array.from({ length: 11 }, (_, i) => ( - + - + @@ -89,3 +94,28 @@ export const ColumnSizes: Story = { ), }; + +export const RowAndColumns: Story = { + args: { + columns: 12, + gap: 'md', + }, + render: args => ( + + + + + + + + + + + + + + ), +}; diff --git a/packages/canon/src/components/Grid/Grid.tsx b/packages/canon/src/components/Grid/Grid.tsx index 28c49d87b1..9ac23e9371 100644 --- a/packages/canon/src/components/Grid/Grid.tsx +++ b/packages/canon/src/components/Grid/Grid.tsx @@ -20,7 +20,7 @@ import { gridItemSprinkles, gridSprinkles } from './sprinkles.css'; export const Grid = ({ children, - columns = 1, + columns, gap = 'xs', className, style, @@ -29,7 +29,7 @@ export const Grid = ({ const sprinklesClassName = gridSprinkles({ ...restProps, gap, - gridTemplateColumns: columns, + gridTemplateColumns: columns ? columns : 'auto', }); const classNames = ['grid', sprinklesClassName, className] @@ -48,14 +48,16 @@ export const Grid = ({ const GridItem = ({ children, - span = 1, + rowSpan, + colSpan, start, end, className, style, }: GridItemProps) => { const sprinklesClassName = gridItemSprinkles({ - span, + rowSpan, + colSpan, start, end, }); diff --git a/packages/canon/src/components/Grid/sprinkles.css.ts b/packages/canon/src/components/Grid/sprinkles.css.ts index a2ac056d61..aff5a340ed 100644 --- a/packages/canon/src/components/Grid/sprinkles.css.ts +++ b/packages/canon/src/components/Grid/sprinkles.css.ts @@ -35,6 +35,7 @@ const gridProperties = defineProperties({ 10: 'repeat(10, minmax(0, 1fr))', 11: 'repeat(11, minmax(0, 1fr))', 12: 'repeat(12, minmax(0, 1fr))', + auto: 'repeat(auto-fit, minmax(0, 1fr))', }, }, shorthands: { @@ -67,6 +68,21 @@ const gridItemProperties = defineProperties({ 12: 'span 12 / span 12', full: '1 / -1', }, + gridRow: { + 1: 'span 1 / span 1', + 2: 'span 2 / span 2', + 3: 'span 3 / span 3', + 4: 'span 4 / span 4', + 5: 'span 5 / span 5', + 6: 'span 6 / span 6', + 7: 'span 7 / span 7', + 8: 'span 8 / span 8', + 9: 'span 9 / span 9', + 10: 'span 10 / span 10', + 11: 'span 11 / span 11', + 12: 'span 12 / span 12', + full: '1 / -1', + }, gridColumnStart: { 1: '1', 2: '2', @@ -101,7 +117,8 @@ const gridItemProperties = defineProperties({ }, }, shorthands: { - span: ['gridColumn'], + colSpan: ['gridColumn'], + rowSpan: ['gridRow'], start: ['gridColumnStart'], end: ['gridColumnEnd'], }, diff --git a/packages/canon/src/components/Grid/types.ts b/packages/canon/src/components/Grid/types.ts index 6432a8312c..8400e61830 100644 --- a/packages/canon/src/components/Grid/types.ts +++ b/packages/canon/src/components/Grid/types.ts @@ -16,33 +16,21 @@ import { Breakpoint, ColorProps } from '../../layout/types'; import { SpaceProps } from '../../layout/types'; +type Columns = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12; + export interface GridProps extends SpaceProps, ColorProps { children?: React.ReactNode; - columns?: - | 1 - | 2 - | 3 - | 4 - | 5 - | 6 - | 7 - | 8 - | 9 - | 10 - | 11 - | 12 - | Partial< - Record - >; + columns?: Columns | Partial>; className?: string; style?: React.CSSProperties; } export interface GridItemProps { children: React.ReactNode; - span?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 'full'; - start?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 'auto'; - end?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 'auto'; + rowSpan?: Columns | 'full'; + colSpan?: Columns | 'full'; + start?: Columns | 'auto'; + end?: Columns | 'auto'; className?: string; style?: React.CSSProperties; } diff --git a/packages/canon/src/components/Stack/Docs.mdx b/packages/canon/src/components/Stack/Docs.mdx new file mode 100644 index 0000000000..4f63d7114e --- /dev/null +++ b/packages/canon/src/components/Stack/Docs.mdx @@ -0,0 +1,65 @@ +import { Meta, Unstyled, Source } from '@storybook/blocks'; +import * as StackStories from './Stack.stories'; +import { Title, Text } from '../../../docs/components'; +import { PropsTable } from '../../../docs/components/PropsTable'; + + + + + +Stack + + + This is the stack 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. + + + + Hello World + Hello World + Hello World +`} + language="tsx" + dark +/> + + + +How to stack horizontally? + + The Stack component only allows for stacking elements vertically. If you want + to create a column layout, please use the Grid component. + + +Responsive +TBD + +Start and End +TBD + +