@kalink-ui/seedly 0.1.2 → 0.3.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 (39) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/package.json +14 -17
  3. package/src/.npmignore +0 -7
  4. package/src/components/.DS_Store +0 -0
  5. package/src/components/box/box.stories.tsx +0 -29
  6. package/src/components/button/button.stories.tsx +0 -31
  7. package/src/components/center/.DS_Store +0 -0
  8. package/src/components/center/center.stories.tsx +0 -31
  9. package/src/components/cluster/.DS_Store +0 -0
  10. package/src/components/cluster/cluster.stories.tsx +0 -37
  11. package/src/components/cover/.DS_Store +0 -0
  12. package/src/components/cover/cover.stories.tsx +0 -45
  13. package/src/components/frame/.DS_Store +0 -0
  14. package/src/components/frame/frame.stories.tsx +0 -39
  15. package/src/components/grid/.DS_Store +0 -0
  16. package/src/components/grid/grid.stories.tsx +0 -50
  17. package/src/components/layout.mdx +0 -206
  18. package/src/components/sidebar/.DS_Store +0 -0
  19. package/src/components/sidebar/sidebar.stories.tsx +0 -60
  20. package/src/components/stack/.DS_Store +0 -0
  21. package/src/components/stack/stack.stories.tsx +0 -72
  22. package/src/components/switcher/.DS_Store +0 -0
  23. package/src/components/switcher/switcher.stories.tsx +0 -66
  24. package/src/styles/seed/.DS_Store +0 -0
  25. package/src/styles/seed/seed.stories.tsx +0 -52
  26. package/src/styles/styles.mdx +0 -98
  27. package/src/utils/__tests__/extract-sprinkles-props.test.ts +0 -101
  28. package/src/utils/__tests__/is-object.test.ts +0 -24
  29. package/src/utils/__tests__/map-contract-vars.test.ts +0 -34
  30. package/src/utils/arg-types/.DS_Store +0 -0
  31. package/src/utils/arg-types/arg-types-from-recipe.ts +0 -37
  32. package/src/utils/arg-types/arg-types-from-sprinkles.ts +0 -43
  33. package/src/utils/arg-types/common/composable.ts +0 -13
  34. package/src/utils/arg-types/common/index.ts +0 -4
  35. package/src/utils/arg-types/common/polymorphic.ts +0 -14
  36. package/src/utils/arg-types/common/referable.ts +0 -10
  37. package/src/utils/arg-types/common/stylable.ts +0 -14
  38. package/src/utils/arg-types/common-args.ts +0 -26
  39. package/src/utils/arg-types/index.ts +0 -3
package/CHANGELOG.md ADDED
@@ -0,0 +1,31 @@
1
+ # @kalink-ui/seedly
2
+
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Remove config files and tools folders from published package bundle
8
+
9
+ ## 0.2.0
10
+
11
+ ### Minor Changes
12
+
13
+ - Update dependencies and correctly include files in package bundle
14
+
15
+ ## 0.1.2
16
+
17
+ ### Patch Changes
18
+
19
+ - Correctly place the npmignore file so it override the package.json config
20
+
21
+ ## 0.1.1
22
+
23
+ ### Patch Changes
24
+
25
+ - Filter out unwanted files from the package bundle
26
+
27
+ ## 0.1.0
28
+
29
+ ### Minor Changes
30
+
31
+ - Initial publish of @kalink-ui packages
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kalink-ui/seedly",
3
- "version": "0.1.2",
3
+ "version": "0.3.0",
4
4
  "sideEffects": false,
5
5
  "license": "MIT",
6
6
  "exports": {
@@ -19,7 +19,7 @@
19
19
  "./utils": "./src/utils/index.ts"
20
20
  },
21
21
  "devDependencies": {
22
- "@chromatic-com/storybook": "^3.2.4",
22
+ "@chromatic-com/storybook": "^3.2.5",
23
23
  "@storybook/addon-docs": "^8.6.4",
24
24
  "@storybook/addon-essentials": "^8.6.4",
25
25
  "@storybook/addon-interactions": "^8.6.4",
@@ -28,28 +28,28 @@
28
28
  "@storybook/react": "^8.6.4",
29
29
  "@storybook/react-vite": "^8.6.4",
30
30
  "@storybook/test": "^8.6.4",
31
- "@turbo/gen": "^2.3.4",
32
- "@types/node": "^22.10.10",
33
- "@types/react": "19.0.8",
34
- "@types/react-dom": "19.0.3",
31
+ "@turbo/gen": "^2.4.4",
32
+ "@types/node": "^22.13.9",
33
+ "@types/react": "19.0.10",
34
+ "@types/react-dom": "19.0.4",
35
35
  "@vanilla-extract/css": "^1.17.1",
36
36
  "@vanilla-extract/css-utils": "^0.1.4",
37
37
  "@vanilla-extract/dynamic": "^2.1.2",
38
38
  "@vanilla-extract/recipes": "^0.5.5",
39
39
  "@vanilla-extract/sprinkles": "^1.6.3",
40
- "@vanilla-extract/vite-plugin": "^5.0.0",
40
+ "@vanilla-extract/vite-plugin": "^5.0.1",
41
41
  "@vitejs/plugin-react": "^4.3.4",
42
42
  "react": "^19.0.0",
43
43
  "react-dom": "^19.0.0",
44
44
  "storybook": "^8.6.4",
45
- "tsup": "^8.3.6",
46
- "type-fest": "^4.33.0",
47
- "typescript": "5.7.3",
48
- "vite": "^6.0.11",
45
+ "tsup": "^8.4.0",
46
+ "type-fest": "^4.37.0",
47
+ "typescript": "5.8.2",
48
+ "vite": "^6.2.1",
49
49
  "vite-tsconfig-paths": "^5.1.4",
50
- "vitest": "^3.0.4",
51
- "@kalink-ui/eslint-config": "0.1.0",
52
- "@kalink-ui/typescript-config": "0.0.0"
50
+ "vitest": "^3.0.8",
51
+ "@kalink-ui/eslint-config": "0.2.0",
52
+ "@kalink-ui/typescript-config": "0.1.0"
53
53
  },
54
54
  "peerDependencies": {
55
55
  "@vanilla-extract/css": "^1.17.1",
@@ -63,9 +63,6 @@
63
63
  "publishConfig": {
64
64
  "access": "public"
65
65
  },
66
- "files": [
67
- "./src/**/*"
68
- ],
69
66
  "dependencies": {
70
67
  "clsx": "^2.1.1"
71
68
  },
package/src/.npmignore DELETED
@@ -1,7 +0,0 @@
1
- **/*.stories.tsx
2
- **/*.test.tsx
3
- **/*.test.ts
4
- **/*.mdx
5
- **/arg-types/**/*
6
-
7
- .DS_Store
Binary file
@@ -1,29 +0,0 @@
1
- import { Box, boxRecipe } from '@/components/box';
2
- import { argTypesFromRecipe, CommonArgs, commonArgs } from '@/utils/arg-types';
3
-
4
- import type { Meta, StoryObj } from '@storybook/react';
5
-
6
- const meta = {
7
- title: 'Layout/Box',
8
- component: Box,
9
- tags: ['autodocs'],
10
- args: {
11
- children: 'Box content',
12
- },
13
- argTypes: {
14
- ...argTypesFromRecipe(boxRecipe),
15
-
16
- ...commonArgs([
17
- CommonArgs.COMPOSABLE,
18
- CommonArgs.POLYMORPHIC,
19
- CommonArgs.STYLABLE,
20
- CommonArgs.REFERABLE,
21
- ]),
22
- },
23
- } satisfies Meta<typeof Box>;
24
-
25
- export default meta;
26
-
27
- type Story = StoryObj<typeof Box>;
28
-
29
- export const Default: Story = {};
@@ -1,31 +0,0 @@
1
- import { CommonArgs, commonArgs, argTypesFromRecipe } from '@/utils/arg-types';
2
-
3
- import { Button } from './button';
4
- import { buttonRecipe } from './button.css';
5
-
6
- import type { Meta, StoryObj } from '@storybook/react';
7
-
8
- const meta = {
9
- title: 'Component/Button',
10
- component: Button,
11
- tags: ['autodocs'],
12
- args: {
13
- children: 'Button label',
14
- },
15
- argTypes: {
16
- ...argTypesFromRecipe(buttonRecipe),
17
-
18
- ...commonArgs([
19
- CommonArgs.COMPOSABLE,
20
- CommonArgs.POLYMORPHIC,
21
- CommonArgs.STYLABLE,
22
- CommonArgs.REFERABLE,
23
- ]),
24
- },
25
- } satisfies Meta<typeof Button>;
26
-
27
- export default meta;
28
-
29
- type Story = StoryObj<typeof Button>;
30
-
31
- export const Default: Story = {};
Binary file
@@ -1,31 +0,0 @@
1
- import { argTypesFromRecipe, CommonArgs, commonArgs } from '@/utils/arg-types';
2
-
3
- import { Center } from './center';
4
- import { centerRecipe } from './center.css';
5
-
6
- import type { Meta, StoryObj } from '@storybook/react';
7
-
8
- const meta = {
9
- title: 'Layout/Center',
10
- component: Center,
11
- tags: ['autodocs'],
12
- args: {
13
- children: 'Centered content',
14
- },
15
- argTypes: {
16
- ...argTypesFromRecipe(centerRecipe),
17
-
18
- ...commonArgs([
19
- CommonArgs.COMPOSABLE,
20
- CommonArgs.POLYMORPHIC,
21
- CommonArgs.STYLABLE,
22
- CommonArgs.REFERABLE,
23
- ]),
24
- },
25
- } satisfies Meta<typeof Center>;
26
-
27
- export default meta;
28
-
29
- type Story = StoryObj<typeof Center>;
30
-
31
- export const Default: Story = {};
Binary file
@@ -1,37 +0,0 @@
1
- import { argTypesFromRecipe, CommonArgs, commonArgs } from '@/utils/arg-types';
2
-
3
- import { Cluster } from './cluster';
4
- import { clusterRecipe } from './cluster.css';
5
-
6
- import type { Meta, StoryObj } from '@storybook/react';
7
-
8
- const meta = {
9
- title: 'Layout/Cluster',
10
- component: Cluster,
11
- tags: ['autodocs'],
12
- args: {
13
- children: (
14
- <>
15
- <div>Cluster element one</div>
16
- <div>Cluster element two</div>
17
- <div>Cluster element three</div>
18
- </>
19
- ),
20
- },
21
- argTypes: {
22
- ...argTypesFromRecipe(clusterRecipe),
23
-
24
- ...commonArgs([
25
- CommonArgs.COMPOSABLE,
26
- CommonArgs.POLYMORPHIC,
27
- CommonArgs.STYLABLE,
28
- CommonArgs.REFERABLE,
29
- ]),
30
- },
31
- } satisfies Meta<typeof Cluster>;
32
-
33
- export default meta;
34
-
35
- type Story = StoryObj<typeof Cluster>;
36
-
37
- export const Default: Story = {};
Binary file
@@ -1,45 +0,0 @@
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 = {};
Binary file
@@ -1,39 +0,0 @@
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 = {};
Binary file
@@ -1,50 +0,0 @@
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 = {};
@@ -1,206 +0,0 @@
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
@@ -1,60 +0,0 @@
1
- import { argTypesFromRecipe, CommonArgs, commonArgs } from '@/utils/arg-types';
2
-
3
- import { Sidebar } from './sidebar';
4
- import { sidebarRecipe } from './sidebar.css';
5
-
6
- import type { Meta, StoryObj } from '@storybook/react';
7
-
8
- const meta = {
9
- title: 'Layout/Sidebar',
10
- component: Sidebar,
11
- tags: ['autodocs'],
12
- args: {
13
- children: (
14
- <>
15
- <div>Sidebar</div>
16
- <div>Main content</div>
17
- </>
18
- ),
19
- },
20
- argTypes: {
21
- ...argTypesFromRecipe(sidebarRecipe),
22
-
23
- ...commonArgs([
24
- CommonArgs.COMPOSABLE,
25
- CommonArgs.POLYMORPHIC,
26
- CommonArgs.STYLABLE,
27
- CommonArgs.REFERABLE,
28
- ]),
29
-
30
- sideWidth: {
31
- table: {
32
- category: 'Recipe props',
33
- },
34
- control: { type: 'range', min: 1, max: 100, step: 1 },
35
- },
36
-
37
- contentMinWidth: {
38
- table: {
39
- category: 'Recipe props',
40
- },
41
- control: { type: 'range', min: 1, max: 100, step: 1 },
42
- },
43
- },
44
-
45
- render: ({ sideWidth, contentMinWidth, ...args }) => (
46
- <Sidebar
47
- {...{
48
- ...(sideWidth && { sideWidth: `${sideWidth}%` }),
49
- ...(contentMinWidth && { contentMinWidth: `${contentMinWidth}%` }),
50
- }}
51
- {...args}
52
- />
53
- ),
54
- } satisfies Meta<typeof Sidebar>;
55
-
56
- export default meta;
57
-
58
- type Story = StoryObj<typeof Sidebar>;
59
-
60
- export const Default: Story = {};
Binary file
@@ -1,72 +0,0 @@
1
- import { argTypesFromRecipe, CommonArgs, commonArgs } from '@/utils/arg-types';
2
-
3
- import { Stack } from './stack';
4
- import { stackRecipe } from './stack.css';
5
-
6
- import type { Meta, StoryObj } from '@storybook/react';
7
-
8
- const meta = {
9
- title: 'Layout/Stack',
10
- component: Stack,
11
- tags: ['autodocs'],
12
- parameters: {
13
- layout: 'fullscreen',
14
- },
15
- args: {
16
- children: (
17
- <>
18
- <div>Stack element one</div>
19
- <div>Stack element two</div>
20
- <div>Stack element three</div>
21
- </>
22
- ),
23
- },
24
- argTypes: {
25
- ...argTypesFromRecipe(stackRecipe),
26
-
27
- ...commonArgs([
28
- CommonArgs.COMPOSABLE,
29
- CommonArgs.POLYMORPHIC,
30
- CommonArgs.STYLABLE,
31
- CommonArgs.REFERABLE,
32
- ]),
33
- },
34
- } satisfies Meta<typeof Stack>;
35
-
36
- export default meta;
37
-
38
- type Story = StoryObj<typeof Stack>;
39
-
40
- export const Default: Story = {};
41
-
42
- export const Nested: Story = {
43
- args: {
44
- recursive: true,
45
- spacing: 4,
46
- children: (
47
- <>
48
- <div>Stack element one</div>
49
- <div>
50
- <div>Stack element two</div>
51
- <div>Stack element three</div>
52
- </div>
53
- <div>Stack element four</div>
54
- </>
55
- ),
56
- },
57
- };
58
-
59
- export const AsList: Story = {
60
- args: {
61
- spacing: 4,
62
- use: 'ol',
63
- children: (
64
- <>
65
- <li>Stack element one</li>
66
- <li>Stack element two</li>
67
- <li>Stack element three</li>
68
- <li>Stack element four</li>
69
- </>
70
- ),
71
- },
72
- };
Binary file
@@ -1,66 +0,0 @@
1
- import { ComponentPropsWithoutRef } from 'react';
2
-
3
- import { argTypesFromRecipe, CommonArgs, commonArgs } from '@/utils/arg-types';
4
-
5
- import { Switcher } from './switcher';
6
- import { switcherRecipe } from './switcher.css';
7
-
8
- import type { Meta, StoryObj } from '@storybook/react';
9
-
10
- type StoryArgs = ComponentPropsWithoutRef<typeof Switcher> & {
11
- childCount: number;
12
- };
13
-
14
- const meta = {
15
- title: 'Layout/Switcher',
16
- component: Switcher,
17
- tags: ['autodocs'],
18
- argTypes: {
19
- ...argTypesFromRecipe(switcherRecipe),
20
-
21
- ...commonArgs([
22
- CommonArgs.COMPOSABLE,
23
- CommonArgs.POLYMORPHIC,
24
- CommonArgs.STYLABLE,
25
- CommonArgs.REFERABLE,
26
- ]),
27
-
28
- threshold: {
29
- table: {
30
- category: 'Recipe props',
31
- },
32
- },
33
-
34
- limit: {
35
- table: {
36
- category: 'Recipe props',
37
- },
38
- },
39
-
40
- childCount: {
41
- control: { type: 'range', min: 1, max: 10, step: 1 },
42
- table: {
43
- category: 'Story args',
44
- },
45
- },
46
- },
47
-
48
- args: {
49
- childCount: 4,
50
- },
51
- render: ({ childCount, ...args }) => {
52
- return (
53
- <Switcher {...args}>
54
- {new Array(childCount).fill('').map((_, index) => (
55
- <div key={index}>{`Block ${index + 1}`}</div>
56
- ))}
57
- </Switcher>
58
- );
59
- },
60
- } satisfies Meta<StoryArgs>;
61
-
62
- export default meta;
63
-
64
- type Story = StoryObj<StoryArgs>;
65
-
66
- export const Default: Story = {};
Binary file
@@ -1,52 +0,0 @@
1
- import { sprinkles, sprinklesProps } from '@/storybook/theme/sprinkles.css';
2
- import {
3
- CommonArgs,
4
- commonArgs,
5
- argTypesFromSprinkles,
6
- } from '@/utils/arg-types';
7
-
8
- import { plantSeed } from './seed';
9
-
10
- import type { Meta, StoryObj } from '@storybook/react';
11
-
12
- const Sprout = plantSeed({ sprinkles });
13
-
14
- const meta = {
15
- title: 'Styles/Sprout',
16
- component: Sprout,
17
- tags: ['autodocs'],
18
- args: {
19
- children: 'Box content',
20
- },
21
- argTypes: {
22
- ...argTypesFromSprinkles({ props: sprinklesProps }),
23
-
24
- ...commonArgs([
25
- CommonArgs.COMPOSABLE,
26
- CommonArgs.POLYMORPHIC,
27
- CommonArgs.STYLABLE,
28
- CommonArgs.REFERABLE,
29
- ]),
30
- },
31
- } satisfies Meta<typeof Sprout>;
32
-
33
- export default meta;
34
-
35
- type Story = StoryObj<typeof Sprout>;
36
-
37
- export const Default: Story = {};
38
-
39
- export const WithSprinklesProps: Story = {
40
- args: {
41
- padding: 'medium',
42
- backgroundColor: 'blue',
43
- color: 'white',
44
- textAlign: 'center',
45
- },
46
- };
47
-
48
- export const UseElement: Story = {
49
- args: {
50
- use: 'h1',
51
- },
52
- };
@@ -1,98 +0,0 @@
1
- import { Meta } from '@storybook/addon-docs';
2
-
3
- <Meta title="Styles/Styles Documentation" />
4
-
5
- # Styles Documentation
6
-
7
- This document provides an overview of two important files in our styling system: `contract.css.ts` and `seed.tsx`.
8
-
9
- ## contract.css.ts
10
-
11
- The `contract.css.ts` file defines the type contract for our design system's typography. It establishes a consistent structure for different text styles across various sizes.
12
-
13
- ### Structure
14
-
15
- The type contract is organized into the following categories:
16
-
17
- - `display`
18
- - `headline`
19
- - `title`
20
- - `label`
21
- - `body`
22
-
23
- Each category has three size variants:
24
-
25
- - `large`
26
- - `medium`
27
- - `small`
28
-
29
- ### Usage
30
-
31
- This contract ensures that all typography in the application follows a consistent structure. It can be used to create theme variations and maintain a coherent typographic scale across the entire design system.
32
-
33
- Example of the structure:
34
-
35
- ```typescript
36
- type: {
37
- display: {
38
- large: typeContract,
39
- medium: typeContract,
40
- small: typeContract,
41
- },
42
- // ... other categories
43
- }
44
- ```
45
-
46
- ## seed.tsx
47
-
48
- The `seed.tsx` file provides a foundation for creating flexible, polymorphic components with built-in support for design system styles.
49
-
50
- ### Key Features
51
-
52
- 1. **Polymorphic Components**: Allows components to change their root HTML element.
53
- 2. **Sprinkles Integration**: Incorporates the Sprinkles CSS-in-JS solution for applying atomic styles.
54
- 3. **Type Safety**: Ensures type safety for props and element types.
55
-
56
- ### Main Functions
57
-
58
- #### `plantSeed`
59
-
60
- This function creates a base component (Seed) that can be used to build other components in the design system.
61
-
62
- Parameters:
63
-
64
- - `sprinkles`: A Sprinkles function for applying atomic styles.
65
- - `defaultClassName`: An optional default class name for the component.
66
-
67
- Usage:
68
-
69
- ```jsx
70
- import { plantSeed } from './seed';
71
- import { sprinkles } from './your-sprinkles-file';
72
-
73
- const Sprout = plantSeed({ sprinkles });
74
-
75
- // Use Sprout as a base for other components
76
- const Box = (props) => <Sprout {...props} />;
77
- ```
78
-
79
- ### Types
80
-
81
- #### `SeedProps`
82
-
83
- This type combines polymorphic component props with Sprinkles props:
84
-
85
- ```typescript
86
- type SeedProps<
87
- TUse extends ElementType,
88
- TSprinklesFn extends SprinklesFnBase,
89
- > = PolymorphicComponentProps<TUse> & GetSprinkles<TSprinklesFn>;
90
- ```
91
-
92
- ### Benefits
93
-
94
- - **Consistency**: Ensures all components built with `plantSeed` have consistent prop interfaces.
95
- - **Flexibility**: Allows easy creation of new components with full access to design system styles.
96
- - **Performance**: Leverages Sprinkles for efficient CSS generation and application.
97
-
98
- By using `contract.css.ts` and `seed.tsx` together, you can create a robust, type-safe, and flexible foundation for your design system components.
@@ -1,101 +0,0 @@
1
- import { describe, test } from '@std/testing/bdd';
2
- import { spy } from '@std/testing/mock';
3
- import { expect } from '@std/expect';
4
-
5
- import {
6
- extractSprinklesProps,
7
- type SprinklesFnBase,
8
- } from '@/utils/extract-sprinkles-props';
9
-
10
- describe('extractSprinklesProps', () => {
11
- const mockSprinkles: SprinklesFnBase = {
12
- properties: new Set(['color', 'fontSize', 'padding']),
13
- } as SprinklesFnBase;
14
-
15
- test('should correctly separate sprinkles props from component props', () => {
16
- const props = {
17
- color: 'red',
18
- fontSize: '16px',
19
- padding: '10px',
20
- onClick: spy(),
21
- className: 'custom-class',
22
- };
23
-
24
- const [sprinkleProps, componentProps] = extractSprinklesProps(
25
- props,
26
- mockSprinkles,
27
- );
28
-
29
- expect(sprinkleProps).toEqual({
30
- color: 'red',
31
- fontSize: '16px',
32
- padding: '10px',
33
- });
34
-
35
- expect(componentProps).toEqual({
36
- onClick: expect.any(Function),
37
- className: 'custom-class',
38
- });
39
- });
40
-
41
- test('should handle props with no sprinkles properties', () => {
42
- const props = {
43
- onClick: spy(),
44
- className: 'custom-class',
45
- };
46
-
47
- const [sprinkleProps, componentProps] = extractSprinklesProps(
48
- props,
49
- mockSprinkles,
50
- );
51
-
52
- expect(sprinkleProps).toEqual({});
53
- expect(componentProps).toEqual(props);
54
- });
55
-
56
- test('should handle props with only sprinkles properties', () => {
57
- const props = {
58
- color: 'blue',
59
- fontSize: '14px',
60
- };
61
-
62
- const [sprinkleProps, componentProps] = extractSprinklesProps(
63
- props,
64
- mockSprinkles,
65
- );
66
-
67
- expect(sprinkleProps).toEqual(props);
68
- expect(componentProps).toEqual({});
69
- });
70
-
71
- test('should handle empty props object', () => {
72
- const props = {};
73
-
74
- const [sprinkleProps, componentProps] = extractSprinklesProps(
75
- props,
76
- mockSprinkles,
77
- );
78
-
79
- expect(sprinkleProps).toEqual({});
80
- expect(componentProps).toEqual({});
81
- });
82
-
83
- test('should handle sprinkles function with empty properties set', () => {
84
- const emptySprinkles: SprinklesFnBase = {
85
- properties: new Set(),
86
- } as SprinklesFnBase;
87
-
88
- const props = {
89
- color: 'green',
90
- onClick: spy(),
91
- };
92
-
93
- const [sprinkleProps, componentProps] = extractSprinklesProps(
94
- props,
95
- emptySprinkles,
96
- );
97
-
98
- expect(sprinkleProps).toEqual({});
99
- expect(componentProps).toEqual(props);
100
- });
101
- });
@@ -1,24 +0,0 @@
1
- import { isObject } from "@/utils/is-object.ts";
2
- import { describe, it } from "@std/testing/bdd";
3
- import { expect } from "@std/expect";
4
-
5
- describe("isObject", () => {
6
- it("should return true if value is an object", () => {
7
- expect(isObject({})).toEqual(true);
8
- });
9
-
10
- it("should return false if value is an array", () => {
11
- expect(isObject([])).toEqual(false);
12
- });
13
-
14
- it("should return false if value is null or undefined", () => {
15
- expect(isObject(null)).toEqual(false);
16
- expect(isObject(undefined)).toEqual(false);
17
- });
18
-
19
- it("should return false if value is any scalar", () => {
20
- expect(isObject(1)).toEqual(false);
21
- expect(isObject("foo")).toEqual(false);
22
- expect(isObject(true)).toEqual(false);
23
- });
24
- });
@@ -1,34 +0,0 @@
1
- import { mapContractVars } from "@/utils/map-contract-vars.ts";
2
- import { describe, test } from "@std/testing/bdd";
3
- import { expect } from "@std/expect";
4
-
5
- describe("mapContractVars", () => {
6
- test("should map contract vars", () => {
7
- const contract = {
8
- foo: "foo",
9
- bar: "bar",
10
- };
11
-
12
- const result = mapContractVars(contract, (key) => ({
13
- padding: `var(--${key})`,
14
- vars: {
15
- [`--${key}`]: contract[key],
16
- },
17
- }));
18
-
19
- expect(result).toEqual({
20
- foo: {
21
- padding: "var(--foo)",
22
- vars: {
23
- "--foo": "foo",
24
- },
25
- },
26
- bar: {
27
- padding: "var(--bar)",
28
- vars: {
29
- "--bar": "bar",
30
- },
31
- },
32
- });
33
- });
34
- });
Binary file
@@ -1,37 +0,0 @@
1
- import { type ComplexStyleRule } from '@vanilla-extract/css';
2
- import { type RuntimeFn } from '@vanilla-extract/recipes';
3
-
4
- type RecipeStyleRule = ComplexStyleRule | string;
5
- type VariantDefinitions = Record<string, RecipeStyleRule>;
6
- type VariantGroups = Record<string, VariantDefinitions>;
7
-
8
- export function argTypesFromRecipe(
9
- recipe: RuntimeFn<VariantGroups>,
10
- excludes: string[] = [],
11
- ) {
12
- return Object.entries(recipe.classNames.variants).reduce(
13
- (acc, [name, variant]) => {
14
- if (excludes.includes(name)) {
15
- return acc;
16
- }
17
-
18
- const options = Object.keys(variant);
19
- let control = options.length > 5 ? 'select' : 'radio';
20
-
21
- if (options.length === 1 && options[0] === 'true') {
22
- options.push('false');
23
- control = 'boolean';
24
- }
25
-
26
- return {
27
- ...acc,
28
- [name]: {
29
- control,
30
- options,
31
- table: { category: 'Styling props' },
32
- },
33
- };
34
- },
35
- {},
36
- );
37
- }
@@ -1,43 +0,0 @@
1
- import { isObject } from '@kalink/ui/utils';
2
-
3
- type ArgTypesFromSprinklesProps = {
4
- /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
5
- props: Record<string, any>;
6
- excludes?: string[];
7
- category?: string;
8
- } & {};
9
-
10
- export function argTypesFromSprinkles({
11
- props,
12
- excludes = [],
13
- category = 'Sprinkles props',
14
- }: ArgTypesFromSprinklesProps) {
15
- return Object.entries(props).reduce((acc, [name]) => {
16
- if (Array.isArray(excludes) && excludes.includes(name)) {
17
- return acc;
18
- }
19
-
20
- let options = props[name] || [];
21
- let control = 'select';
22
-
23
- if (options.length === 1 && options[0] === 'true') {
24
- options.push('false');
25
- control = 'boolean';
26
- }
27
-
28
- if (isObject(options)) {
29
- options = Object.fromEntries(
30
- Object.keys(options).map((key) => [key, key]),
31
- );
32
- }
33
-
34
- return {
35
- ...acc,
36
- [name]: {
37
- control,
38
- options,
39
- table: { category },
40
- },
41
- };
42
- }, {});
43
- }
@@ -1,13 +0,0 @@
1
- export const composable = {
2
- children: {
3
- control: false,
4
- description: 'Content of the component.',
5
- defaultValue: '',
6
- table: {
7
- category: 'Intrinsic props',
8
- type: {
9
- summary: 'ReactNode',
10
- },
11
- },
12
- },
13
- };
@@ -1,4 +0,0 @@
1
- export { composable } from './composable';
2
- export { polymorphic } from './polymorphic';
3
- export { referable } from './referable';
4
- export { stylable } from './stylable';
@@ -1,14 +0,0 @@
1
- export const polymorphic = {
2
- use: {
3
- control: false,
4
- description:
5
- 'The component used to render the root node of the component. Either a string to use an `JSX.IntrinsicElements` or a component reference to use a `React.ComponentType`',
6
- defaultValue: '',
7
- table: {
8
- category: 'Intrinsic props',
9
- type: {
10
- summary: 'ElementType',
11
- },
12
- },
13
- },
14
- };
@@ -1,10 +0,0 @@
1
- export const referable = {
2
- ref: {
3
- control: false,
4
- description: 'Ref passed to the component root.',
5
- defaultValue: '',
6
- table: {
7
- category: 'Intrinsic props',
8
- },
9
- },
10
- };
@@ -1,14 +0,0 @@
1
- export const stylable = {
2
- className: {
3
- control: false,
4
- description:
5
- 'A class name string passed to the component. Merged with the inner class names.',
6
- defaultValue: '',
7
- table: {
8
- category: 'Intrinsic props',
9
- type: {
10
- summary: 'string',
11
- },
12
- },
13
- },
14
- };
@@ -1,26 +0,0 @@
1
- /* eslint-disable import/namespace */
2
- import * as CommonArgDefs from './common';
3
-
4
- export enum CommonArgs {
5
- COMPOSABLE = 'composable',
6
- POLYMORPHIC = 'polymorphic',
7
- STYLABLE = 'stylable',
8
- REFERABLE = 'referable',
9
- }
10
-
11
- export function commonArgs(args: CommonArgs[]) {
12
- const argTypes: Partial<Record<string, object>> = {};
13
- const knownArgs = Object.values(CommonArgs);
14
-
15
- for (const arg of args) {
16
- if (!knownArgs.includes(arg)) {
17
- continue;
18
- }
19
-
20
- for (const argDef in CommonArgDefs[arg]) {
21
- argTypes[argDef] = (CommonArgDefs[arg] as Record<string, object>)[argDef];
22
- }
23
- }
24
-
25
- return argTypes;
26
- }
@@ -1,3 +0,0 @@
1
- export { argTypesFromRecipe } from './arg-types-from-recipe';
2
- export { argTypesFromSprinkles } from './arg-types-from-sprinkles';
3
- export { commonArgs, CommonArgs } from './common-args';