@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.
- package/package.json +78 -0
- package/src/components/.DS_Store +0 -0
- package/src/components/box/box.css.ts +47 -0
- package/src/components/box/box.stories.tsx +29 -0
- package/src/components/box/box.tsx +55 -0
- package/src/components/box/index.ts +2 -0
- package/src/components/button/button.css.ts +33 -0
- package/src/components/button/button.stories.tsx +31 -0
- package/src/components/button/button.tsx +33 -0
- package/src/components/button/index.ts +2 -0
- package/src/components/center/.DS_Store +0 -0
- package/src/components/center/center.css.ts +35 -0
- package/src/components/center/center.stories.tsx +31 -0
- package/src/components/center/center.tsx +46 -0
- package/src/components/center/index.ts +2 -0
- package/src/components/cluster/.DS_Store +0 -0
- package/src/components/cluster/cluster.css.ts +60 -0
- package/src/components/cluster/cluster.stories.tsx +37 -0
- package/src/components/cluster/cluster.tsx +46 -0
- package/src/components/cluster/index.ts +2 -0
- package/src/components/cover/.DS_Store +0 -0
- package/src/components/cover/cover.css.ts +60 -0
- package/src/components/cover/cover.stories.tsx +45 -0
- package/src/components/cover/cover.tsx +55 -0
- package/src/components/cover/index.ts +2 -0
- package/src/components/frame/.DS_Store +0 -0
- package/src/components/frame/frame.css.ts +61 -0
- package/src/components/frame/frame.stories.tsx +39 -0
- package/src/components/frame/frame.tsx +28 -0
- package/src/components/frame/index.ts +2 -0
- package/src/components/grid/.DS_Store +0 -0
- package/src/components/grid/grid.css.ts +26 -0
- package/src/components/grid/grid.stories.tsx +50 -0
- package/src/components/grid/grid.tsx +48 -0
- package/src/components/grid/index.ts +2 -0
- package/src/components/layout.mdx +206 -0
- package/src/components/sidebar/.DS_Store +0 -0
- package/src/components/sidebar/index.ts +2 -0
- package/src/components/sidebar/sidebar.css.ts +68 -0
- package/src/components/sidebar/sidebar.stories.tsx +60 -0
- package/src/components/sidebar/sidebar.tsx +77 -0
- package/src/components/stack/.DS_Store +0 -0
- package/src/components/stack/index.ts +2 -0
- package/src/components/stack/stack.css.ts +36 -0
- package/src/components/stack/stack.stories.tsx +72 -0
- package/src/components/stack/stack.tsx +44 -0
- package/src/components/switcher/.DS_Store +0 -0
- package/src/components/switcher/index.ts +2 -0
- package/src/components/switcher/switcher.css.ts +93 -0
- package/src/components/switcher/switcher.stories.tsx +66 -0
- package/src/components/switcher/switcher.tsx +53 -0
- package/src/styles/index.ts +2 -0
- package/src/styles/seed/.DS_Store +0 -0
- package/src/styles/seed/index.ts +1 -0
- package/src/styles/seed/seed.stories.tsx +52 -0
- package/src/styles/seed/seed.tsx +53 -0
- package/src/styles/styles.mdx +98 -0
- package/src/styles/system-contract.css.ts +144 -0
- package/src/types/index.ts +5 -0
- package/src/types/utils.types.ts +15 -0
- package/src/utils/__tests__/extract-sprinkles-props.test.ts +101 -0
- package/src/utils/__tests__/is-object.test.ts +24 -0
- package/src/utils/__tests__/map-contract-vars.test.ts +34 -0
- package/src/utils/arg-types/.DS_Store +0 -0
- package/src/utils/arg-types/arg-types-from-recipe.ts +37 -0
- package/src/utils/arg-types/arg-types-from-sprinkles.ts +43 -0
- package/src/utils/arg-types/common/composable.ts +13 -0
- package/src/utils/arg-types/common/index.ts +4 -0
- package/src/utils/arg-types/common/polymorphic.ts +14 -0
- package/src/utils/arg-types/common/referable.ts +10 -0
- package/src/utils/arg-types/common/stylable.ts +14 -0
- package/src/utils/arg-types/common-args.ts +26 -0
- package/src/utils/arg-types/index.ts +3 -0
- package/src/utils/extract-sprinkles-props.ts +46 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/is-object.ts +3 -0
- package/src/utils/map-contract-vars.ts +10 -0
|
@@ -0,0 +1,98 @@
|
|
|
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.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { createThemeContract } from '@vanilla-extract/css';
|
|
2
|
+
|
|
3
|
+
const typeContract = {
|
|
4
|
+
font: null,
|
|
5
|
+
weight: null,
|
|
6
|
+
lineHeight: null,
|
|
7
|
+
tracking: null,
|
|
8
|
+
size: null,
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const sys = createThemeContract({
|
|
12
|
+
layout: {
|
|
13
|
+
direction: null,
|
|
14
|
+
measure: null,
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
color: {
|
|
18
|
+
background: null,
|
|
19
|
+
foreground: null,
|
|
20
|
+
muted: null,
|
|
21
|
+
outline: null,
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
state: {
|
|
25
|
+
hovered: {
|
|
26
|
+
opacity: null,
|
|
27
|
+
},
|
|
28
|
+
focused: {
|
|
29
|
+
opacity: null,
|
|
30
|
+
},
|
|
31
|
+
pressed: {
|
|
32
|
+
opacity: null,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
shape: {
|
|
37
|
+
corner: {
|
|
38
|
+
none: null,
|
|
39
|
+
sharp: null,
|
|
40
|
+
small: null,
|
|
41
|
+
medium: null,
|
|
42
|
+
rounded: null,
|
|
43
|
+
circle: null,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
elevation: {
|
|
48
|
+
none: null,
|
|
49
|
+
minimal: null,
|
|
50
|
+
low: null,
|
|
51
|
+
moderate: null,
|
|
52
|
+
high: null,
|
|
53
|
+
peak: null,
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
motion: {
|
|
57
|
+
duration: {
|
|
58
|
+
short: {
|
|
59
|
+
1: null,
|
|
60
|
+
2: null,
|
|
61
|
+
3: null,
|
|
62
|
+
4: null,
|
|
63
|
+
},
|
|
64
|
+
medium: {
|
|
65
|
+
1: null,
|
|
66
|
+
2: null,
|
|
67
|
+
3: null,
|
|
68
|
+
4: null,
|
|
69
|
+
},
|
|
70
|
+
long: {
|
|
71
|
+
1: null,
|
|
72
|
+
2: null,
|
|
73
|
+
3: null,
|
|
74
|
+
4: null,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
easing: {
|
|
79
|
+
standard: null,
|
|
80
|
+
decelerate: {
|
|
81
|
+
standard: null,
|
|
82
|
+
emphasized: null,
|
|
83
|
+
},
|
|
84
|
+
accelerate: {
|
|
85
|
+
standard: null,
|
|
86
|
+
emphasized: null,
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
typography: {
|
|
92
|
+
display: {
|
|
93
|
+
large: typeContract,
|
|
94
|
+
medium: typeContract,
|
|
95
|
+
small: typeContract,
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
headline: {
|
|
99
|
+
large: typeContract,
|
|
100
|
+
medium: typeContract,
|
|
101
|
+
small: typeContract,
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
title: {
|
|
105
|
+
large: typeContract,
|
|
106
|
+
medium: typeContract,
|
|
107
|
+
small: typeContract,
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
label: {
|
|
111
|
+
large: typeContract,
|
|
112
|
+
medium: typeContract,
|
|
113
|
+
small: typeContract,
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
body: {
|
|
117
|
+
large: typeContract,
|
|
118
|
+
medium: typeContract,
|
|
119
|
+
small: typeContract,
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
spacing: {
|
|
124
|
+
0: null,
|
|
125
|
+
1: null,
|
|
126
|
+
2: null,
|
|
127
|
+
3: null,
|
|
128
|
+
4: null,
|
|
129
|
+
5: null,
|
|
130
|
+
6: null,
|
|
131
|
+
7: null,
|
|
132
|
+
8: null,
|
|
133
|
+
9: null,
|
|
134
|
+
10: null,
|
|
135
|
+
11: null,
|
|
136
|
+
12: null,
|
|
137
|
+
13: null,
|
|
138
|
+
14: null,
|
|
139
|
+
15: null,
|
|
140
|
+
16: null,
|
|
141
|
+
17: null,
|
|
142
|
+
18: null,
|
|
143
|
+
},
|
|
144
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ComponentPropsWithRef, ElementType } from 'react';
|
|
2
|
+
|
|
3
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
4
|
+
export type DistributiveOmit<T, TOmitted extends PropertyKey> = T extends any
|
|
5
|
+
? Omit<T, TOmitted>
|
|
6
|
+
: never;
|
|
7
|
+
|
|
8
|
+
export type UnwrapArray<R> = R extends unknown[] ? UnwrapArray<R[number]> : R;
|
|
9
|
+
|
|
10
|
+
export type PolymorphicComponentProps<TUse extends ElementType> = {
|
|
11
|
+
use?: TUse;
|
|
12
|
+
} & DistributiveOmit<
|
|
13
|
+
ComponentPropsWithRef<ElementType extends TUse ? 'div' : TUse>,
|
|
14
|
+
'use'
|
|
15
|
+
>;
|
|
@@ -0,0 +1,101 @@
|
|
|
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
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
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
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
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
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
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
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { SprinklesProperties } from '@vanilla-extract/sprinkles';
|
|
2
|
+
import type { UnknownRecord } from 'type-fest';
|
|
3
|
+
|
|
4
|
+
export interface SprinklesFnBase {
|
|
5
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
6
|
+
(...args: any): string;
|
|
7
|
+
properties: Set<string>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type GetSprinkles<T extends SprinklesFnBase> = Parameters<T>[0];
|
|
11
|
+
|
|
12
|
+
export type SprinklesProps<TSprinklesFnBase extends SprinklesFnBase> =
|
|
13
|
+
TSprinklesFnBase['properties'] extends Set<infer T>
|
|
14
|
+
? {
|
|
15
|
+
[KeyType in keyof T]: T[KeyType] extends SprinklesProperties
|
|
16
|
+
? KeyType
|
|
17
|
+
: never;
|
|
18
|
+
}
|
|
19
|
+
: never;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Extracts the sprinkles properties from the given component props,
|
|
23
|
+
* returning an array containing the extracted sprinkle props and
|
|
24
|
+
* the remaining component props.
|
|
25
|
+
*/
|
|
26
|
+
export const extractSprinklesProps = <
|
|
27
|
+
ComponentProps extends UnknownRecord,
|
|
28
|
+
SprinklesFn extends SprinklesFnBase,
|
|
29
|
+
>(
|
|
30
|
+
props: ComponentProps,
|
|
31
|
+
sprinkles: SprinklesFn,
|
|
32
|
+
) => {
|
|
33
|
+
const sprinkleProps: Record<string, unknown> = {};
|
|
34
|
+
const componentProps: Record<string, unknown> = {};
|
|
35
|
+
|
|
36
|
+
for (const prop of Object.keys(props)) {
|
|
37
|
+
if (sprinkles.properties.has(prop)) {
|
|
38
|
+
sprinkleProps[prop] = props[prop];
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
componentProps[prop] = props[prop];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return [sprinkleProps, componentProps];
|
|
46
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type MappedVars = Record<string, unknown>;
|
|
2
|
+
|
|
3
|
+
export const mapContractVars = <TContract extends Record<string, unknown>>(
|
|
4
|
+
contractVars: TContract,
|
|
5
|
+
mapFn: (key: keyof TContract) => MappedVars,
|
|
6
|
+
) => {
|
|
7
|
+
return Object.fromEntries(
|
|
8
|
+
Object.keys(contractVars).map((key) => [key, mapFn(key)]),
|
|
9
|
+
) as Record<keyof TContract, MappedVars>;
|
|
10
|
+
};
|