@kalink-ui/seedly 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/package.json +78 -0
  2. package/src/components/.DS_Store +0 -0
  3. package/src/components/box/box.css.ts +47 -0
  4. package/src/components/box/box.stories.tsx +29 -0
  5. package/src/components/box/box.tsx +55 -0
  6. package/src/components/box/index.ts +2 -0
  7. package/src/components/button/button.css.ts +33 -0
  8. package/src/components/button/button.stories.tsx +31 -0
  9. package/src/components/button/button.tsx +33 -0
  10. package/src/components/button/index.ts +2 -0
  11. package/src/components/center/.DS_Store +0 -0
  12. package/src/components/center/center.css.ts +35 -0
  13. package/src/components/center/center.stories.tsx +31 -0
  14. package/src/components/center/center.tsx +46 -0
  15. package/src/components/center/index.ts +2 -0
  16. package/src/components/cluster/.DS_Store +0 -0
  17. package/src/components/cluster/cluster.css.ts +60 -0
  18. package/src/components/cluster/cluster.stories.tsx +37 -0
  19. package/src/components/cluster/cluster.tsx +46 -0
  20. package/src/components/cluster/index.ts +2 -0
  21. package/src/components/cover/.DS_Store +0 -0
  22. package/src/components/cover/cover.css.ts +60 -0
  23. package/src/components/cover/cover.stories.tsx +45 -0
  24. package/src/components/cover/cover.tsx +55 -0
  25. package/src/components/cover/index.ts +2 -0
  26. package/src/components/frame/.DS_Store +0 -0
  27. package/src/components/frame/frame.css.ts +61 -0
  28. package/src/components/frame/frame.stories.tsx +39 -0
  29. package/src/components/frame/frame.tsx +28 -0
  30. package/src/components/frame/index.ts +2 -0
  31. package/src/components/grid/.DS_Store +0 -0
  32. package/src/components/grid/grid.css.ts +26 -0
  33. package/src/components/grid/grid.stories.tsx +50 -0
  34. package/src/components/grid/grid.tsx +48 -0
  35. package/src/components/grid/index.ts +2 -0
  36. package/src/components/layout.mdx +206 -0
  37. package/src/components/sidebar/.DS_Store +0 -0
  38. package/src/components/sidebar/index.ts +2 -0
  39. package/src/components/sidebar/sidebar.css.ts +68 -0
  40. package/src/components/sidebar/sidebar.stories.tsx +60 -0
  41. package/src/components/sidebar/sidebar.tsx +77 -0
  42. package/src/components/stack/.DS_Store +0 -0
  43. package/src/components/stack/index.ts +2 -0
  44. package/src/components/stack/stack.css.ts +36 -0
  45. package/src/components/stack/stack.stories.tsx +72 -0
  46. package/src/components/stack/stack.tsx +44 -0
  47. package/src/components/switcher/.DS_Store +0 -0
  48. package/src/components/switcher/index.ts +2 -0
  49. package/src/components/switcher/switcher.css.ts +93 -0
  50. package/src/components/switcher/switcher.stories.tsx +66 -0
  51. package/src/components/switcher/switcher.tsx +53 -0
  52. package/src/styles/index.ts +2 -0
  53. package/src/styles/seed/.DS_Store +0 -0
  54. package/src/styles/seed/index.ts +1 -0
  55. package/src/styles/seed/seed.stories.tsx +52 -0
  56. package/src/styles/seed/seed.tsx +53 -0
  57. package/src/styles/styles.mdx +98 -0
  58. package/src/styles/system-contract.css.ts +144 -0
  59. package/src/types/index.ts +5 -0
  60. package/src/types/utils.types.ts +15 -0
  61. package/src/utils/__tests__/extract-sprinkles-props.test.ts +101 -0
  62. package/src/utils/__tests__/is-object.test.ts +24 -0
  63. package/src/utils/__tests__/map-contract-vars.test.ts +34 -0
  64. package/src/utils/arg-types/.DS_Store +0 -0
  65. package/src/utils/arg-types/arg-types-from-recipe.ts +37 -0
  66. package/src/utils/arg-types/arg-types-from-sprinkles.ts +43 -0
  67. package/src/utils/arg-types/common/composable.ts +13 -0
  68. package/src/utils/arg-types/common/index.ts +4 -0
  69. package/src/utils/arg-types/common/polymorphic.ts +14 -0
  70. package/src/utils/arg-types/common/referable.ts +10 -0
  71. package/src/utils/arg-types/common/stylable.ts +14 -0
  72. package/src/utils/arg-types/common-args.ts +26 -0
  73. package/src/utils/arg-types/index.ts +3 -0
  74. package/src/utils/extract-sprinkles-props.ts +46 -0
  75. package/src/utils/index.ts +3 -0
  76. package/src/utils/is-object.ts +3 -0
  77. package/src/utils/map-contract-vars.ts +10 -0
@@ -0,0 +1,45 @@
1
+ import { argTypesFromRecipe, CommonArgs, commonArgs } from '@/utils/arg-types';
2
+
3
+ import { Cover } from './cover';
4
+ import { coverRecipe } from './cover.css';
5
+
6
+ import type { Meta, StoryObj } from '@storybook/react';
7
+
8
+ const meta = {
9
+ title: 'Layout/Cover',
10
+ component: Cover,
11
+ tags: ['autodocs'],
12
+ argTypes: {
13
+ ...argTypesFromRecipe(coverRecipe),
14
+
15
+ ...commonArgs([
16
+ CommonArgs.COMPOSABLE,
17
+ CommonArgs.POLYMORPHIC,
18
+ CommonArgs.STYLABLE,
19
+ CommonArgs.REFERABLE,
20
+ ]),
21
+
22
+ minSize: {
23
+ table: {
24
+ category: 'Recipe props',
25
+ },
26
+ },
27
+ },
28
+ args: {
29
+ minSize: '30vh',
30
+
31
+ children: (
32
+ <>
33
+ <div>Cover element one</div>
34
+ <div data-cover-center>Cover element two</div>
35
+ <div>Cover element three</div>
36
+ </>
37
+ ),
38
+ },
39
+ } satisfies Meta<typeof Cover>;
40
+
41
+ export default meta;
42
+
43
+ type Story = StoryObj<typeof Cover>;
44
+
45
+ export const Default: Story = {};
@@ -0,0 +1,55 @@
1
+ 'use client';
2
+
3
+ import { assignInlineVars } from '@vanilla-extract/dynamic';
4
+ import { clsx } from 'clsx';
5
+ import { ElementType } from 'react';
6
+
7
+ import { PolymorphicComponentProps } from '@/types/utils.types';
8
+
9
+ import { coverRecipe, CoverVariants, minSizeVar } from './cover.css';
10
+
11
+ type CoverProps<TUse extends ElementType> = PolymorphicComponentProps<TUse> & {
12
+ /**
13
+ * The spacing between items
14
+ */
15
+ spacing?: CoverVariants['spacing'];
16
+
17
+ /**
18
+ * True if the cover should have no padding
19
+ */
20
+ noPad?: CoverVariants['noPad'];
21
+
22
+ /**
23
+ * The minimum height of the cover
24
+ */
25
+ minSize?: string;
26
+ };
27
+
28
+ /**
29
+ * A custom element for covering a block-level element horizontally,
30
+ * with a max-width value representing the typographic measure.
31
+ *
32
+ * The element that should be towards the vertical center of the space
33
+ * is identified with a simple `data-cover-center` attribute.
34
+ *
35
+ * https://every-layout.dev/layouts/cover
36
+ */
37
+ export const Cover = <TUse extends ElementType>({
38
+ spacing,
39
+ noPad,
40
+ minSize,
41
+ className,
42
+ ...props
43
+ }: CoverProps<TUse>) => {
44
+ const { use: Comp = 'div', ...rest } = props;
45
+
46
+ return (
47
+ <Comp
48
+ className={clsx(coverRecipe({ spacing, noPad }), className)}
49
+ style={assignInlineVars({
50
+ ...(minSize && { [minSizeVar]: minSize }),
51
+ })}
52
+ {...rest}
53
+ />
54
+ );
55
+ };
@@ -0,0 +1,2 @@
1
+ export { Cover } from './cover';
2
+ export { coverRecipe, type CoverVariants } from './cover.css';
Binary file
@@ -0,0 +1,61 @@
1
+ import { createVar, globalStyle, style } from '@vanilla-extract/css';
2
+ import { recipe, type RecipeVariants } from '@vanilla-extract/recipes';
3
+
4
+ const ratioVar = createVar();
5
+
6
+ const baseFrame = style({
7
+ display: 'flex',
8
+ justifyContent: 'center',
9
+ alignItems: 'center',
10
+
11
+ overflow: 'hidden',
12
+
13
+ aspectRatio: ratioVar,
14
+ });
15
+
16
+ export const frameRecipe = recipe({
17
+ base: baseFrame,
18
+
19
+ variants: {
20
+ ratio: {
21
+ '1:1': {
22
+ vars: {
23
+ [ratioVar]: '1 / 1',
24
+ },
25
+ },
26
+ '3:2': {
27
+ vars: {
28
+ [ratioVar]: '3 / 2',
29
+ },
30
+ },
31
+ '2:3': {
32
+ vars: {
33
+ [ratioVar]: '2 / 3',
34
+ },
35
+ },
36
+ '4:3': {
37
+ vars: {
38
+ [ratioVar]: '4 / 3',
39
+ },
40
+ },
41
+ '16:9': {
42
+ vars: {
43
+ [ratioVar]: '16 / 9',
44
+ },
45
+ },
46
+ '9:16': {
47
+ vars: {
48
+ [ratioVar]: '9 / 16',
49
+ },
50
+ },
51
+ },
52
+ },
53
+ });
54
+
55
+ globalStyle(`${baseFrame} > img, ${baseFrame} > video`, {
56
+ inlineSize: '100%',
57
+ blockSize: '100%',
58
+ objectFit: 'cover',
59
+ });
60
+
61
+ export type FrameVariants = NonNullable<RecipeVariants<typeof frameRecipe>>;
@@ -0,0 +1,39 @@
1
+ import { argTypesFromRecipe, CommonArgs, commonArgs } from '@/utils/arg-types';
2
+
3
+ import { Frame } from './frame';
4
+ import { frameRecipe } from './frame.css';
5
+
6
+ import type { Meta, StoryObj } from '@storybook/react';
7
+
8
+ const meta = {
9
+ title: 'Layout/Frame',
10
+ component: Frame,
11
+ tags: ['autodocs'],
12
+ argTypes: {
13
+ ...argTypesFromRecipe(frameRecipe),
14
+
15
+ ...commonArgs([
16
+ CommonArgs.COMPOSABLE,
17
+ CommonArgs.POLYMORPHIC,
18
+ CommonArgs.STYLABLE,
19
+ CommonArgs.REFERABLE,
20
+ ]),
21
+
22
+ ratio: {
23
+ table: {
24
+ category: 'Recipe props',
25
+ },
26
+ },
27
+ },
28
+ args: {
29
+ ratio: '16:9',
30
+
31
+ children: <div>Frame element</div>,
32
+ },
33
+ } satisfies Meta<typeof Frame>;
34
+
35
+ export default meta;
36
+
37
+ type Story = StoryObj<typeof Frame>;
38
+
39
+ export const Default: Story = {};
@@ -0,0 +1,28 @@
1
+ import { clsx } from 'clsx';
2
+ import { ElementType } from 'react';
3
+
4
+ import { PolymorphicComponentProps } from '@/types/utils.types';
5
+
6
+ import { frameRecipe, FrameVariants } from './frame.css';
7
+
8
+ type FrameProps<TUse extends ElementType> = PolymorphicComponentProps<TUse> & {
9
+ /**
10
+ * The ratio of the frame
11
+ */
12
+ ratio?: FrameVariants['ratio'];
13
+ };
14
+
15
+ /**
16
+ * A custom element for augmenting image ratios
17
+ *
18
+ * https://every-layout.dev/layouts/frame
19
+ */
20
+ export const Frame = <TUse extends ElementType>({
21
+ ratio,
22
+ className,
23
+ ...props
24
+ }: FrameProps<TUse>) => {
25
+ const { use: Comp = 'div', ...rest } = props;
26
+
27
+ return <Comp className={clsx(frameRecipe({ ratio }), className)} {...rest} />;
28
+ };
@@ -0,0 +1,2 @@
1
+ export { Frame } from './frame';
2
+ export { frameRecipe, type FrameVariants } from './frame.css';
Binary file
@@ -0,0 +1,26 @@
1
+ import { createVar } from '@vanilla-extract/css';
2
+ import { recipe, type RecipeVariants } from '@vanilla-extract/recipes';
3
+
4
+ import { sys } from '@/styles/system-contract.css';
5
+ import { mapContractVars } from '@/utils/map-contract-vars';
6
+
7
+ export const minSizeVar = createVar();
8
+
9
+ export const gridRecipe = recipe({
10
+ base: {
11
+ display: 'grid',
12
+ gridTemplateColumns: `repeat(auto-fill, minmax(min(${minSizeVar}, 100%), 1fr))`,
13
+
14
+ vars: {
15
+ [minSizeVar]: '250px',
16
+ },
17
+ },
18
+
19
+ variants: {
20
+ spacing: mapContractVars(sys.spacing, (key) => ({
21
+ gridGap: sys.spacing[key],
22
+ })),
23
+ },
24
+ });
25
+
26
+ export type GridVariants = NonNullable<RecipeVariants<typeof gridRecipe>>;
@@ -0,0 +1,50 @@
1
+ import { argTypesFromRecipe, CommonArgs, commonArgs } from '@/utils/arg-types';
2
+
3
+ import { Grid } from './grid';
4
+ import { gridRecipe } from './grid.css';
5
+
6
+ import type { Meta, StoryObj } from '@storybook/react';
7
+
8
+ const meta = {
9
+ title: 'Layout/Grid',
10
+ component: Grid,
11
+ tags: ['autodocs'],
12
+ argTypes: {
13
+ ...argTypesFromRecipe(gridRecipe),
14
+
15
+ ...commonArgs([
16
+ CommonArgs.COMPOSABLE,
17
+ CommonArgs.POLYMORPHIC,
18
+ CommonArgs.STYLABLE,
19
+ CommonArgs.REFERABLE,
20
+ ]),
21
+
22
+ minSize: {
23
+ table: {
24
+ category: 'Recipe props',
25
+ },
26
+ },
27
+ },
28
+ args: {
29
+ minSize: '250px',
30
+
31
+ children: (
32
+ <>
33
+ <div>Grid cell one</div>
34
+ <div>Grid cell two</div>
35
+ <div>Grid cell three</div>
36
+ <div>Grid cell four</div>
37
+ <div>Grid cell five</div>
38
+ <div>Grid cell six</div>
39
+ <div>Grid cell seven</div>
40
+ <div>Grid cell eight</div>
41
+ </>
42
+ ),
43
+ },
44
+ } satisfies Meta<typeof Grid>;
45
+
46
+ export default meta;
47
+
48
+ type Story = StoryObj<typeof Grid>;
49
+
50
+ export const Default: Story = {};
@@ -0,0 +1,48 @@
1
+ 'use client';
2
+
3
+ import { assignInlineVars } from '@vanilla-extract/dynamic';
4
+ import { clsx } from 'clsx';
5
+ import { ElementType } from 'react';
6
+
7
+ import { PolymorphicComponentProps } from '@/types/utils.types';
8
+
9
+ import { gridRecipe, GridVariants, minSizeVar } from './grid.css';
10
+
11
+ type GridProps<TUse extends ElementType> = PolymorphicComponentProps<TUse> & {
12
+ /**
13
+ * The minimum size of a grid cell
14
+ */
15
+ minSize?: string;
16
+
17
+ /**
18
+ * The spacing between the grid cell
19
+ */
20
+ spacing?: GridVariants['spacing'];
21
+ };
22
+
23
+ /**
24
+ * The Grid layout provides a flexible, responsive grid system that
25
+ * arranges elements in a structured, multi-column format, automatically
26
+ * adjusting the number of columns based on the available space and
27
+ * predefined constraints.
28
+ *
29
+ * https://every-layout.dev/layouts/grid/
30
+ */
31
+ export const Grid = <TUse extends ElementType>({
32
+ spacing,
33
+ minSize,
34
+ className,
35
+ ...props
36
+ }: GridProps<TUse>) => {
37
+ const { use: Comp = 'div', ...rest } = props;
38
+
39
+ return (
40
+ <Comp
41
+ className={clsx(gridRecipe({ spacing }), className)}
42
+ style={assignInlineVars({
43
+ ...(minSize && { [minSizeVar]: minSize }),
44
+ })}
45
+ {...rest}
46
+ />
47
+ );
48
+ };
@@ -0,0 +1,2 @@
1
+ export { Grid } from './grid';
2
+ export { gridRecipe, type GridVariants } from './grid.css';
@@ -0,0 +1,206 @@
1
+ import { Meta } from '@storybook/addon-docs';
2
+
3
+ <Meta title="Layout/Layout Components" />
4
+
5
+ # Layout Components
6
+
7
+ This section provides implementations of various layout components inspired by [Every Layout](https://every-layout.dev/). These components are designed to create responsive, adaptable, and minimal CSS layouts, solving common design problems with composable and flexible solutions.
8
+
9
+ ## The Box
10
+
11
+ The Box layout provides a simple way to add padding and a border to its content, useful for creating visually distinct sections. It's a fundamental building block for creating consistent spacing and visual separation in your designs.
12
+
13
+ Use cases:
14
+
15
+ - Creating card-like components
16
+ - Highlighting important content
17
+ - Separating sections in a form
18
+
19
+ [Box documentation page](?path=/docs/layout-box--docs)
20
+
21
+ ```jsx
22
+ import { Box } from '@kalink-studio/ui/layout';
23
+
24
+ <Box padding="md" variant="plain">
25
+ <p>This is a box.</p>
26
+ </Box>;
27
+ ```
28
+
29
+ ## The Stack
30
+
31
+ The Stack layout arranges its children vertically with a consistent gap between them. It's perfect for creating a vertical flow of elements, eliminating the need for manual margin management between elements.
32
+
33
+ Use cases:
34
+
35
+ - Organizing form fields
36
+ - Creating a vertical list of articles or comments
37
+ - Structuring content in a sidebar
38
+
39
+ [Stack documentation page](?path=/docs/layout-stack--docs)
40
+
41
+ ```jsx
42
+ import { Stack } from '@kalink-studio/ui/layout';
43
+
44
+ <Stack spacing="md" recursive>
45
+ <div>Item 1</div>
46
+ <div>Item 2</div>
47
+ <div>
48
+ <div>Nested item 2.1</div>
49
+ <div>Nested item 2.2</div>
50
+ </div>
51
+ <div>Item 3</div>
52
+ </Stack>;
53
+ ```
54
+
55
+ ## The Center
56
+
57
+ The Center layout is designed to center its content both horizontally and optionally vertically. It's particularly useful for creating visually balanced layouts and focusing attention on specific content.
58
+
59
+ Use cases:
60
+
61
+ - Creating hero sections
62
+ - Creating a centered column of content
63
+ - Designing error pages or "empty state" screens
64
+
65
+ [Center documentation page](?path=/docs/layout-center--docs)
66
+
67
+ ```jsx
68
+ import { Center } from '@kalink-studio/ui/layout';
69
+
70
+ <Center gutters="md" intrinsic>
71
+ <p>This content is centered.</p>
72
+ </Center>;
73
+ ```
74
+
75
+ ## The Cluster
76
+
77
+ The Cluster layout arranges elements in a flexible row that wraps to accommodate available space. It's ideal for layouts that need to manage many small items while maintaining consistent spacing and alignment.
78
+
79
+ Use cases:
80
+
81
+ - Displaying tags or categories
82
+ - Creating a flexible navigation menu
83
+ - Showing a group of action buttons
84
+
85
+ [Cluster documentation page](?path=/docs/layout-cluster--docs)
86
+
87
+ ```jsx
88
+ import { Cluster } from '@kalink-studio/ui/layout';
89
+
90
+ <Cluster spacing="md" justify="center">
91
+ <div>Item 1</div>
92
+ <div>Item 2</div>
93
+ <div>Item 3</div>
94
+ <div>Item 4</div>
95
+ </Cluster>;
96
+ ```
97
+
98
+ ## The Sidebar
99
+
100
+ The Sidebar layout divides content into a main section and a sidebar, which can be positioned on either side and resized according to the layout requirements. It's crucial for creating responsive layouts that adapt to different screen sizes.
101
+
102
+ Use cases:
103
+
104
+ - Creating a layout with a navigation sidebar
105
+ - Displaying additional information alongside main content
106
+ - Building dashboard layouts
107
+
108
+ [Sidebar documentation page](?path=/docs/layout-sidebar--docs)
109
+
110
+ ```jsx
111
+ import { Sidebar } from '@kalink-studio/ui/layout';
112
+
113
+ <Sidebar sideWidth="250px" contentMinWidth="300px" spacing="md" side="left">
114
+ <div>Sidebar content</div>
115
+ <div>Main content</div>
116
+ </Sidebar>;
117
+ ```
118
+
119
+ ## The Switcher
120
+
121
+ The Switcher layout allows elements to switch between a horizontal and vertical arrangement based on the available space. It's ideal for responsive design scenarios where content needs to adapt to different screen sizes seamlessly.
122
+
123
+ Use cases:
124
+
125
+ - Creating responsive navigation menus
126
+ - Designing flexible card layouts
127
+ - Building adaptable form layouts
128
+
129
+ [Switcher documentation page](?path=/docs/layout-switcher--docs)
130
+
131
+ ```jsx
132
+ import { Switcher } from '@kalink-studio/ui/layout';
133
+
134
+ <Switcher threshold="300px" spacing="md">
135
+ <div>Item 1</div>
136
+ <div>Item 2</div>
137
+ <div>Item 3</div>
138
+ </Switcher>;
139
+ ```
140
+
141
+ ## The Cover
142
+
143
+ The Cover layout helps create a vertically centered layout with a header, main content, and footer, ensuring that the main content stays centered. It's particularly useful for creating full-page layouts or sections that need to utilize the full viewport height.
144
+
145
+ Use cases:
146
+
147
+ - Designing landing pages
148
+ - Creating login or signup screens
149
+ - Building "coming soon" pages
150
+
151
+ [Cover documentation page](?path=/docs/layout-cover--docs)
152
+
153
+ ```jsx
154
+ import { Cover } from '@kalink-studio/ui/layout';
155
+
156
+ <Cover minSize="60vh" spacing="md" noPad>
157
+ <header>Header</header>
158
+ <main>Main content</main>
159
+ <footer>Footer</footer>
160
+ </Cover>;
161
+ ```
162
+
163
+ ## The Grid
164
+
165
+ The Grid layout provides a responsive grid system that adapts the number of columns based on available space, with defined gaps between columns and rows. It's perfect for creating complex, responsive layouts without the need for media queries.
166
+
167
+ Use cases:
168
+
169
+ - Displaying a gallery of images
170
+ - Creating a responsive product listing
171
+ - Organizing dashboard widgets
172
+
173
+ [Grid documentation page](?path=/docs/layout-grid--docs)
174
+
175
+ ```jsx
176
+ import { Grid } from '@kalink-studio/ui/layout';
177
+
178
+ <Grid minSize="200px" spacing="md">
179
+ <div>Item 1</div>
180
+ <div>Item 2</div>
181
+ <div>Item 3</div>
182
+ <div>Item 4</div>
183
+ </Grid>;
184
+ ```
185
+
186
+ ## The Frame
187
+
188
+ The Frame layout is used to maintain aspect ratios of embedded content, such as videos or iframes, ensuring that content scales appropriately while preserving its aspect ratio. It's crucial for responsive design and preventing layout shifts.
189
+
190
+ Use cases:
191
+
192
+ - Embedding responsive videos
193
+ - Displaying images with consistent aspect ratios
194
+ - Creating responsive data visualizations
195
+
196
+ [Frame documentation page](?path=/docs/layout-frame--docs)
197
+
198
+ ```jsx
199
+ import { Frame } from '@kalink-studio/ui/layout';
200
+
201
+ <Frame ratio="16:9">
202
+ <img src="...">
203
+ </Frame>;
204
+ ```
205
+
206
+ Each of these components is designed to solve specific layout challenges while promoting responsive and adaptable designs. By combining these layout primitives, you can create complex, flexible layouts that work across various screen sizes and devices, all while minimizing the amount of custom CSS required.
Binary file
@@ -0,0 +1,2 @@
1
+ export { Sidebar } from './sidebar';
2
+ export { sidebarRecipe, type SidebarVariants } from './sidebar.css';
@@ -0,0 +1,68 @@
1
+ import { createVar, globalStyle } from '@vanilla-extract/css';
2
+ import { recipe, type RecipeVariants } from '@vanilla-extract/recipes';
3
+
4
+ import { sys } from '@/styles/system-contract.css';
5
+ import { mapContractVars } from '@/utils/map-contract-vars';
6
+
7
+ export const sideWidthVar = createVar();
8
+ export const contentMinWidthVar = createVar();
9
+
10
+ export const sidebarRecipe = recipe({
11
+ base: {
12
+ display: 'flex',
13
+ flexWrap: 'wrap',
14
+
15
+ vars: {
16
+ [contentMinWidthVar]: '50%',
17
+ },
18
+ },
19
+
20
+ variants: {
21
+ spacing: mapContractVars(sys.spacing, (key) => ({
22
+ gap: sys.spacing[key],
23
+ })),
24
+
25
+ noStretch: {
26
+ true: {
27
+ alignItems: 'flex-start',
28
+ },
29
+ },
30
+
31
+ /**
32
+ * The width of the sidebar (empty means not set; defaults to the content width)
33
+ */
34
+ sideWidth: {
35
+ true: {},
36
+ },
37
+
38
+ /**
39
+ * Whether the sided element is the :last-child
40
+ */
41
+ side: {
42
+ right: {},
43
+ left: {},
44
+ },
45
+ },
46
+ });
47
+
48
+ globalStyle(`${sidebarRecipe.classNames.base} > *`, {
49
+ flexGrow: 1,
50
+ });
51
+
52
+ globalStyle(`${sidebarRecipe.classNames.variants.sideWidth.true} > *`, {
53
+ flexBasis: sideWidthVar,
54
+ });
55
+
56
+ globalStyle(`${sidebarRecipe.classNames.variants.side.left} > :last-child`, {
57
+ flexBasis: 0,
58
+ flexGrow: 999,
59
+ minInlineSize: contentMinWidthVar,
60
+ });
61
+
62
+ globalStyle(`${sidebarRecipe.classNames.variants.side.right} > :first-child`, {
63
+ flexBasis: 0,
64
+ flexGrow: 999,
65
+ minInlineSize: contentMinWidthVar,
66
+ });
67
+
68
+ export type SidebarVariants = NonNullable<RecipeVariants<typeof sidebarRecipe>>;