@kalink-ui/seedly 0.8.0 → 0.9.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/CHANGELOG.md +12 -0
- package/package.json +18 -16
- package/src/components/box/box.css.ts +4 -13
- package/src/components/box/box.tsx +2 -2
- package/src/components/box/index.ts +1 -1
- package/src/components/card/card.css.ts +42 -0
- package/src/components/card/card.tsx +73 -0
- package/src/components/card/index.ts +1 -0
- package/src/components/center/center.css.ts +1 -1
- package/src/components/cluster/cluster.css.ts +1 -1
- package/src/components/cluster/cluster.tsx +2 -2
- package/src/components/cluster/index.ts +1 -1
- package/src/components/cover/cover.css.ts +1 -1
- package/src/components/grid/grid.css.ts +1 -1
- package/src/components/heading/heading.css.ts +49 -2
- package/src/components/heading/heading.tsx +80 -61
- package/src/components/heading/index.ts +2 -1
- package/src/components/index.ts +4 -3
- package/src/components/seed/index.ts +1 -1
- package/src/components/seed/seed.tsx +38 -1
- package/src/components/text/text.css.ts +146 -7
- package/src/components/text/text.tsx +19 -27
- package/src/styles/system-contract.css.ts +0 -2
- package/src/styles/typography.css.ts +10 -5
- package/src/utils/arg-types/arg-types-from-recipe.ts +36 -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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @kalink-ui/seedly
|
|
2
2
|
|
|
3
|
+
## 0.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 7fe5a15: Fix issues with TypeScript config and setup Github Actions
|
|
8
|
+
|
|
9
|
+
## 0.8.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 6670251: Do not ignore arg-types files from npm package
|
|
14
|
+
|
|
3
15
|
## 0.8.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kalink-ui/seedly",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "A set of components for building UIs with React and TypeScript",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@chromatic-com/storybook": "^3.2.5",
|
|
20
|
-
"@storybook/addon-docs": "^8.6.
|
|
21
|
-
"@storybook/addon-essentials": "^8.6.
|
|
22
|
-
"@storybook/addon-interactions": "^8.6.
|
|
23
|
-
"@storybook/addon-onboarding": "^8.6.
|
|
24
|
-
"@storybook/blocks": "^8.6.
|
|
25
|
-
"@storybook/react": "^8.6.
|
|
26
|
-
"@storybook/react-vite": "^8.6.
|
|
27
|
-
"@storybook/test": "^8.6.
|
|
20
|
+
"@storybook/addon-docs": "^8.6.9",
|
|
21
|
+
"@storybook/addon-essentials": "^8.6.9",
|
|
22
|
+
"@storybook/addon-interactions": "^8.6.9",
|
|
23
|
+
"@storybook/addon-onboarding": "^8.6.9",
|
|
24
|
+
"@storybook/blocks": "^8.6.9",
|
|
25
|
+
"@storybook/react": "^8.6.9",
|
|
26
|
+
"@storybook/react-vite": "^8.6.9",
|
|
27
|
+
"@storybook/test": "^8.6.9",
|
|
28
28
|
"@turbo/gen": "^2.4.4",
|
|
29
29
|
"@types/node": "^22.13.9",
|
|
30
30
|
"@types/react": "19.0.10",
|
|
@@ -40,15 +40,15 @@
|
|
|
40
40
|
"react": "^19.0.0",
|
|
41
41
|
"react-docgen-typescript": "^2.2.2",
|
|
42
42
|
"react-dom": "^19.0.0",
|
|
43
|
-
"storybook": "^8.6.
|
|
43
|
+
"storybook": "^8.6.9",
|
|
44
44
|
"type-fest": "^4.37.0",
|
|
45
45
|
"typescript": "5.8.2",
|
|
46
46
|
"vite": "^6.2.1",
|
|
47
47
|
"vite-tsconfig-paths": "^5.1.4",
|
|
48
48
|
"vitest": "^3.0.8",
|
|
49
|
-
"@kalink-ui/dibbly": "0.
|
|
50
|
-
"@kalink-ui/
|
|
51
|
-
"@kalink-ui/
|
|
49
|
+
"@kalink-ui/dibbly": "0.3.0",
|
|
50
|
+
"@kalink-ui/typescript-config": "0.4.0",
|
|
51
|
+
"@kalink-ui/eslint-config": "0.8.0"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"@vanilla-extract/css": "^1.17.1",
|
|
@@ -66,10 +66,12 @@
|
|
|
66
66
|
"access": "public"
|
|
67
67
|
},
|
|
68
68
|
"scripts": {
|
|
69
|
-
"lint": "eslint
|
|
69
|
+
"lint": "eslint --max-warnings 0",
|
|
70
|
+
"lint:fix": "pnpm lint --fix",
|
|
70
71
|
"build-storybook": "storybook build",
|
|
71
72
|
"dev": "storybook dev -p 6006 --no-open",
|
|
72
|
-
"test": "vitest",
|
|
73
|
-
"
|
|
73
|
+
"test": "vitest run",
|
|
74
|
+
"test:watch": "vitest",
|
|
75
|
+
"tsc": "tsc -b"
|
|
74
76
|
}
|
|
75
77
|
}
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import { createVar } from '@vanilla-extract/css';
|
|
2
1
|
import { recipe, type RecipeVariants } from '@vanilla-extract/recipes';
|
|
3
2
|
|
|
4
3
|
import { mapContractVars, sys } from '../../styles';
|
|
5
4
|
import { components } from '../../styles/layers.css';
|
|
6
5
|
|
|
7
|
-
export const colorForeground = createVar();
|
|
8
|
-
export const colorBackground = createVar();
|
|
9
|
-
|
|
10
6
|
export const boxRecipe = recipe({
|
|
11
7
|
variants: {
|
|
12
8
|
/**
|
|
@@ -16,13 +12,8 @@ export const boxRecipe = recipe({
|
|
|
16
12
|
solid: {
|
|
17
13
|
'@layer': {
|
|
18
14
|
[components]: {
|
|
19
|
-
color:
|
|
20
|
-
backgroundColor:
|
|
21
|
-
},
|
|
22
|
-
|
|
23
|
-
vars: {
|
|
24
|
-
[colorForeground]: sys.color.foreground,
|
|
25
|
-
[colorBackground]: sys.color.background,
|
|
15
|
+
color: sys.color.foreground,
|
|
16
|
+
backgroundColor: sys.color.background,
|
|
26
17
|
},
|
|
27
18
|
},
|
|
28
19
|
},
|
|
@@ -30,10 +21,10 @@ export const boxRecipe = recipe({
|
|
|
30
21
|
outline: {
|
|
31
22
|
'@layer': {
|
|
32
23
|
[components]: {
|
|
33
|
-
color:
|
|
24
|
+
color: sys.color.foreground,
|
|
34
25
|
backgroundColor: 'transparent',
|
|
35
26
|
|
|
36
|
-
borderColor:
|
|
27
|
+
borderColor: sys.color.foreground,
|
|
37
28
|
borderStyle: 'solid',
|
|
38
29
|
borderWidth: '1px',
|
|
39
30
|
},
|
|
@@ -4,8 +4,8 @@ import { ElementType } from 'react';
|
|
|
4
4
|
|
|
5
5
|
import { BoxVariants, boxRecipe } from './box.css';
|
|
6
6
|
|
|
7
|
-
type BoxProps<TUse extends ElementType> =
|
|
8
|
-
BoxVariants;
|
|
7
|
+
export type BoxProps<TUse extends ElementType> =
|
|
8
|
+
PolymorphicComponentProps<TUse> & BoxVariants;
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* A evenly spaced container for grouping related elements. Can
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { Box } from './box';
|
|
1
|
+
export { Box, type BoxProps } from './box';
|
|
2
2
|
export { boxRecipe, type BoxVariants } from './box.css';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { style } from '@vanilla-extract/css';
|
|
2
|
+
import { recipe } from '@vanilla-extract/recipes';
|
|
3
|
+
|
|
4
|
+
import { components } from '../../styles/layers.css';
|
|
5
|
+
|
|
6
|
+
export const card = style({});
|
|
7
|
+
export const cardHeader = style({});
|
|
8
|
+
export const cardBody = style({});
|
|
9
|
+
export const cardFooter = recipe({
|
|
10
|
+
base: {
|
|
11
|
+
'@layer': {
|
|
12
|
+
[components]: {
|
|
13
|
+
display: 'flex',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
variants: {
|
|
18
|
+
align: {
|
|
19
|
+
start: {
|
|
20
|
+
'@layer': {
|
|
21
|
+
[components]: {
|
|
22
|
+
justifyContent: 'flex-start',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
center: {
|
|
27
|
+
'@layer': {
|
|
28
|
+
[components]: {
|
|
29
|
+
justifyContent: 'center',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
end: {
|
|
34
|
+
'@layer': {
|
|
35
|
+
[components]: {
|
|
36
|
+
justifyContent: 'flex-end',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { PolymorphicComponentProps } from '@kalink-ui/dibbly';
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { ElementType } from 'react';
|
|
4
|
+
|
|
5
|
+
import { Box, Cluster, Stack } from '@kalink-ui/seedly';
|
|
6
|
+
import { Spacing } from '@kalink-ui/seedly/styles';
|
|
7
|
+
|
|
8
|
+
import { BoxProps } from '../box';
|
|
9
|
+
import { ClusterProps } from '../cluster';
|
|
10
|
+
|
|
11
|
+
import { card, cardBody, cardFooter, cardHeader } from './card.css';
|
|
12
|
+
|
|
13
|
+
export type CardProps<TUse extends ElementType = 'article'> = BoxProps<TUse> & {
|
|
14
|
+
verticalSpacing?: Spacing;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export function Card<TUse extends ElementType = 'article'>(
|
|
18
|
+
props: CardProps<TUse>,
|
|
19
|
+
) {
|
|
20
|
+
const {
|
|
21
|
+
use = 'article',
|
|
22
|
+
variant = 'solid',
|
|
23
|
+
className,
|
|
24
|
+
spacing = 4,
|
|
25
|
+
verticalSpacing,
|
|
26
|
+
children,
|
|
27
|
+
...rest
|
|
28
|
+
} = props;
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<Box
|
|
32
|
+
use={use as CardProps['use']}
|
|
33
|
+
variant={variant}
|
|
34
|
+
spacing={spacing}
|
|
35
|
+
className={clsx(card, className)}
|
|
36
|
+
{...rest}
|
|
37
|
+
>
|
|
38
|
+
<Stack spacing={verticalSpacing ?? spacing}>{children}</Stack>
|
|
39
|
+
</Box>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
Card.Header = function CardHeader<TUse extends ElementType = 'header'>(
|
|
44
|
+
props: PolymorphicComponentProps<TUse>,
|
|
45
|
+
) {
|
|
46
|
+
const { use: Comp = 'header', className, ...rest } = props;
|
|
47
|
+
|
|
48
|
+
return <Comp className={clsx(cardHeader, className)} {...rest} />;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
Card.Body = function CardBody<TUse extends ElementType = 'div'>(
|
|
52
|
+
props: PolymorphicComponentProps<TUse>,
|
|
53
|
+
) {
|
|
54
|
+
const { use: Comp = 'div', className, ...rest } = props;
|
|
55
|
+
|
|
56
|
+
return <Comp className={clsx(cardBody, className)} {...rest} />;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
type CardFooterProps<TUse extends ElementType = 'footer'> = ClusterProps<TUse>;
|
|
60
|
+
|
|
61
|
+
Card.Footer = function CardFooter<TUse extends ElementType = 'footer'>(
|
|
62
|
+
props: CardFooterProps<TUse>,
|
|
63
|
+
) {
|
|
64
|
+
const { use = 'footer', className, ...rest } = props;
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<Cluster
|
|
68
|
+
use={use as CardFooterProps['use']}
|
|
69
|
+
className={clsx(cardFooter, className)}
|
|
70
|
+
{...rest}
|
|
71
|
+
/>
|
|
72
|
+
);
|
|
73
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Card } from './card';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { recipe, type RecipeVariants } from '@vanilla-extract/recipes';
|
|
2
2
|
|
|
3
|
-
import { mapContractVars
|
|
3
|
+
import { mapContractVars, sys } from '../../styles';
|
|
4
4
|
import { components } from '../../styles/layers.css';
|
|
5
5
|
|
|
6
6
|
export const centerRecipe = recipe({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { recipe, type RecipeVariants } from '@vanilla-extract/recipes';
|
|
2
2
|
|
|
3
|
-
import { mapContractVars
|
|
3
|
+
import { mapContractVars, sys } from '../../styles';
|
|
4
4
|
import { components } from '../../styles/layers.css';
|
|
5
5
|
|
|
6
6
|
export const clusterRecipe = recipe({
|
|
@@ -4,8 +4,8 @@ import { ElementType } from 'react';
|
|
|
4
4
|
|
|
5
5
|
import { clusterRecipe, ClusterVariants } from './cluster.css';
|
|
6
6
|
|
|
7
|
-
type ClusterProps<TUse extends ElementType> =
|
|
8
|
-
ClusterVariants;
|
|
7
|
+
export type ClusterProps<TUse extends ElementType> =
|
|
8
|
+
PolymorphicComponentProps<TUse> & ClusterVariants;
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* A custom element for grouping items, with control over the margin between them
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { Cluster } from './cluster';
|
|
1
|
+
export { Cluster, type ClusterProps } from './cluster';
|
|
2
2
|
export { clusterRecipe, type ClusterVariants } from './cluster.css';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createVar, globalStyle } from '@vanilla-extract/css';
|
|
2
2
|
import { recipe, type RecipeVariants } from '@vanilla-extract/recipes';
|
|
3
3
|
|
|
4
|
-
import { sys
|
|
4
|
+
import { sys, mapContractVars } from '../../styles';
|
|
5
5
|
import { components } from '../../styles/layers.css';
|
|
6
6
|
|
|
7
7
|
const spaceVar = createVar();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createVar } from '@vanilla-extract/css';
|
|
2
2
|
import { recipe, type RecipeVariants } from '@vanilla-extract/recipes';
|
|
3
3
|
|
|
4
|
-
import { sys
|
|
4
|
+
import { sys, mapContractVars } from '../../styles';
|
|
5
5
|
import { components } from '../../styles/layers.css';
|
|
6
6
|
|
|
7
7
|
export const minSizeVar = createVar();
|
|
@@ -1,5 +1,52 @@
|
|
|
1
1
|
import { recipe, type RecipeVariants } from '@vanilla-extract/recipes';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import { mapContractVars, sys } from '../../styles';
|
|
4
|
+
import { components } from '../../styles/layers.css';
|
|
4
5
|
|
|
5
|
-
export
|
|
6
|
+
export const headingRoot = recipe({
|
|
7
|
+
base: {
|
|
8
|
+
display: 'flex',
|
|
9
|
+
flexDirection: 'column',
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
variants: {
|
|
13
|
+
align: {
|
|
14
|
+
start: {
|
|
15
|
+
'@layer': {
|
|
16
|
+
[components]: {
|
|
17
|
+
alignItems: 'flex-start',
|
|
18
|
+
textAlign: 'start',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
center: {
|
|
23
|
+
'@layer': {
|
|
24
|
+
[components]: {
|
|
25
|
+
alignItems: 'center',
|
|
26
|
+
textAlign: 'center',
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
end: {
|
|
31
|
+
'@layer': {
|
|
32
|
+
[components]: {
|
|
33
|
+
alignItems: 'flex-end',
|
|
34
|
+
textAlign: 'end',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
spacing: mapContractVars(sys.spacing, (key) => ({
|
|
41
|
+
'@layer': {
|
|
42
|
+
[components]: {
|
|
43
|
+
gap: sys.spacing[key],
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
})),
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export type HeadingRootVariants = NonNullable<
|
|
51
|
+
RecipeVariants<typeof headingRoot>
|
|
52
|
+
>;
|
|
@@ -1,83 +1,102 @@
|
|
|
1
|
-
import { getProp, PolymorphicComponentProps } from '@kalink-ui/dibbly';
|
|
2
1
|
import { clsx } from 'clsx';
|
|
2
|
+
import { ElementType, ReactElement } from 'react';
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
typography,
|
|
6
|
-
Spacing,
|
|
7
|
-
TypographySize,
|
|
8
|
-
TypographyVariant,
|
|
9
|
-
} from '../../styles';
|
|
4
|
+
import { Spacing, TypographySize, TypographyVariant } from '../../styles';
|
|
10
5
|
import { ConditionalWrapper } from '../conditional-wrapper';
|
|
11
|
-
import {
|
|
6
|
+
import { Text, TextProps } from '../text';
|
|
12
7
|
|
|
13
|
-
import {
|
|
8
|
+
import { headingRoot } from './heading.css';
|
|
14
9
|
|
|
15
|
-
type HeadingTypes = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
10
|
+
export type HeadingTypes = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
16
11
|
|
|
17
|
-
type HeadingProps<TUse extends
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
12
|
+
export type HeadingProps<TUse extends ElementType = 'h2'> = Omit<
|
|
13
|
+
TextProps<TUse>,
|
|
14
|
+
'variant' | 'children'
|
|
15
|
+
> & {
|
|
16
|
+
/**
|
|
17
|
+
* The typography used to render the text.
|
|
18
|
+
*/
|
|
19
|
+
variant: Extract<TypographyVariant, 'display' | 'headline' | 'title'>;
|
|
23
20
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
/**
|
|
22
|
+
* If provided, the text will be rendered before the title.
|
|
23
|
+
*/
|
|
24
|
+
pretitle?: ReactElement<TextProps<'p'>>;
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
/**
|
|
27
|
+
* If provided, the text will be rendered after the title.
|
|
28
|
+
*/
|
|
29
|
+
subtitle?: ReactElement<TextProps<'p'>>;
|
|
33
30
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
/**
|
|
32
|
+
* The spacing between the title and the pretitle or subtitle.
|
|
33
|
+
*/
|
|
34
|
+
spacing?: Spacing;
|
|
38
35
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
/**
|
|
37
|
+
* The text to render.
|
|
38
|
+
*/
|
|
39
|
+
children: string;
|
|
40
|
+
};
|
|
43
41
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
use: Comp = 'h1',
|
|
56
|
-
variant,
|
|
57
|
-
pretitle,
|
|
58
|
-
subtitle,
|
|
59
|
-
spacing,
|
|
60
|
-
...rest
|
|
61
|
-
} = props;
|
|
42
|
+
const headingMapping: Record<
|
|
43
|
+
HeadingTypes,
|
|
44
|
+
{ variant: TypographyVariant; size: TypographySize }
|
|
45
|
+
> = {
|
|
46
|
+
h1: { variant: 'display', size: 'large' },
|
|
47
|
+
h2: { variant: 'display', size: 'medium' },
|
|
48
|
+
h3: { variant: 'display', size: 'small' },
|
|
49
|
+
h4: { variant: 'headline', size: 'large' },
|
|
50
|
+
h5: { variant: 'headline', size: 'medium' },
|
|
51
|
+
h6: { variant: 'headline', size: 'small' },
|
|
52
|
+
};
|
|
62
53
|
|
|
54
|
+
export function Heading<TUse extends HeadingTypes>({
|
|
55
|
+
children,
|
|
56
|
+
use = 'h2',
|
|
57
|
+
size,
|
|
58
|
+
variant,
|
|
59
|
+
align,
|
|
60
|
+
spacing,
|
|
61
|
+
pretitle,
|
|
62
|
+
subtitle,
|
|
63
|
+
...rest
|
|
64
|
+
}: HeadingProps<TUse>) {
|
|
63
65
|
return (
|
|
64
66
|
<ConditionalWrapper
|
|
65
|
-
use={
|
|
66
|
-
spacing={spacing}
|
|
67
|
+
use={'hgroup'}
|
|
67
68
|
condition={!!pretitle || !!subtitle}
|
|
69
|
+
className={clsx(headingRoot({ align, spacing }))}
|
|
68
70
|
>
|
|
69
|
-
{pretitle
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
{pretitle}
|
|
72
|
+
|
|
73
|
+
<Text
|
|
74
|
+
use={use}
|
|
75
|
+
align={align}
|
|
76
|
+
variant={variant ?? headingMapping[use].variant}
|
|
77
|
+
size={size ?? headingMapping[use].size}
|
|
76
78
|
{...rest}
|
|
77
79
|
>
|
|
78
80
|
{children}
|
|
79
|
-
</
|
|
80
|
-
|
|
81
|
+
</Text>
|
|
82
|
+
|
|
83
|
+
{subtitle}
|
|
81
84
|
</ConditionalWrapper>
|
|
82
85
|
);
|
|
83
86
|
}
|
|
87
|
+
|
|
88
|
+
Heading.Pretitle = function HeadingPretitle({
|
|
89
|
+
variant = 'title',
|
|
90
|
+
size = 'medium',
|
|
91
|
+
...rest
|
|
92
|
+
}: TextProps<'p'>) {
|
|
93
|
+
return <Text use="p" variant={variant} size={size} {...rest} />;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
Heading.Subtitle = function HeadingSubtitle({
|
|
97
|
+
variant = 'title',
|
|
98
|
+
size = 'medium',
|
|
99
|
+
...rest
|
|
100
|
+
}: TextProps<'p'>) {
|
|
101
|
+
return <Text use="p" variant={variant} size={size} {...rest} />;
|
|
102
|
+
};
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { Heading } from './heading';
|
|
1
|
+
export { Heading, type HeadingTypes, type HeadingProps } from './heading';
|
|
2
|
+
export { headingRoot, type HeadingRootVariants } from './heading.css';
|
package/src/components/index.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
export { Box } from './box';
|
|
2
2
|
export { Button } from './button';
|
|
3
|
+
export { Card } from './card';
|
|
3
4
|
export { Center } from './center';
|
|
4
5
|
export { Cluster } from './cluster';
|
|
5
|
-
export { ConditionalWrapper } from
|
|
6
|
+
export { ConditionalWrapper } from './conditional-wrapper';
|
|
6
7
|
export { Cover } from './cover';
|
|
7
8
|
export { Frame } from './frame';
|
|
8
9
|
export { Grid } from './grid';
|
|
9
|
-
export { Heading } from
|
|
10
|
-
export { plantSeed } from './seed';
|
|
10
|
+
export { Heading } from './heading';
|
|
11
|
+
export { plantSeed, withSeed } from './seed';
|
|
11
12
|
export { Sidebar } from './sidebar';
|
|
12
13
|
export { Stack } from './stack';
|
|
13
14
|
export { Switcher } from './switcher';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { plantSeed } from './seed';
|
|
1
|
+
export { plantSeed, withSeed } from './seed';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type PolymorphicComponentProps } from '@kalink-ui/dibbly';
|
|
2
2
|
import { clsx } from 'clsx';
|
|
3
|
-
import { type ElementType } from 'react';
|
|
3
|
+
import { ComponentType, type ElementType } from 'react';
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
extractSprinklesProps,
|
|
@@ -48,3 +48,40 @@ export function plantSeed<SprinklesFn extends SprinklesFnBase>({
|
|
|
48
48
|
|
|
49
49
|
return Seed;
|
|
50
50
|
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* A higher-order component that injects sprinkles and default className.
|
|
54
|
+
*/
|
|
55
|
+
export function withSeed<SprinklesFn extends SprinklesFnBase>({
|
|
56
|
+
sprinkles,
|
|
57
|
+
defaultClassName,
|
|
58
|
+
}: CreateSeedParams<SprinklesFn>) {
|
|
59
|
+
return function wrapWithSprinkles<TProps, TUse extends ElementType>(
|
|
60
|
+
WrappedComponent: ComponentType<PolymorphicComponentProps<TUse> & TProps>,
|
|
61
|
+
) {
|
|
62
|
+
const ComponentWithSeed = (
|
|
63
|
+
props: SeedProps<TUse, SprinklesFn> & TProps,
|
|
64
|
+
) => {
|
|
65
|
+
const { className, ...rest } = props;
|
|
66
|
+
|
|
67
|
+
const [sprinklesProps, componentProps] = extractSprinklesProps(
|
|
68
|
+
rest,
|
|
69
|
+
sprinkles,
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
// @ts-expect-error - TODO: fix this
|
|
74
|
+
<WrappedComponent
|
|
75
|
+
className={clsx(
|
|
76
|
+
sprinkles(sprinklesProps),
|
|
77
|
+
defaultClassName,
|
|
78
|
+
className,
|
|
79
|
+
)}
|
|
80
|
+
{...componentProps}
|
|
81
|
+
/>
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
return ComponentWithSeed;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -1,25 +1,164 @@
|
|
|
1
|
-
import { style } from '@vanilla-extract/css';
|
|
1
|
+
import { createVar, style } from '@vanilla-extract/css';
|
|
2
2
|
import { recipe, type RecipeVariants } from '@vanilla-extract/recipes';
|
|
3
3
|
|
|
4
|
+
import { components } from '../../styles/layers.css';
|
|
5
|
+
|
|
6
|
+
const lineClampNumber = createVar();
|
|
7
|
+
|
|
8
|
+
const lineClamp = style({
|
|
9
|
+
'@layer': {
|
|
10
|
+
[components]: {
|
|
11
|
+
display: '-webkit-box',
|
|
12
|
+
WebkitLineClamp: lineClampNumber,
|
|
13
|
+
WebkitBoxOrient: 'vertical',
|
|
14
|
+
overflow: 'hidden',
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
|
|
4
19
|
export const textRecipe = recipe({
|
|
5
20
|
variants: {
|
|
21
|
+
/**
|
|
22
|
+
* Controls the wrapping of the text.
|
|
23
|
+
*/
|
|
24
|
+
wrap: {
|
|
25
|
+
true: {
|
|
26
|
+
'@layer': {
|
|
27
|
+
[components]: {
|
|
28
|
+
textWrap: 'wrap',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
false: {
|
|
33
|
+
'@layer': {
|
|
34
|
+
[components]: {
|
|
35
|
+
textWrap: 'nowrap',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
balance: {
|
|
40
|
+
'@layer': {
|
|
41
|
+
[components]: {
|
|
42
|
+
textWrap: 'balance',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
pretty: {
|
|
47
|
+
'@layer': {
|
|
48
|
+
[components]: {
|
|
49
|
+
textWrap: 'pretty',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
|
|
6
55
|
/**
|
|
7
56
|
* If true, use an ellipsis when the text overflows the element.
|
|
8
57
|
*/
|
|
9
|
-
|
|
58
|
+
truncate: {
|
|
10
59
|
true: {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
60
|
+
'@layer': {
|
|
61
|
+
[components]: {
|
|
62
|
+
display: 'inline-block',
|
|
63
|
+
maxWidth: '100%',
|
|
64
|
+
overflow: 'hidden',
|
|
65
|
+
|
|
66
|
+
textOverflow: 'ellipsis',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* If provided, the text will be truncated and displayed with a maximum of
|
|
74
|
+
* the provided number of lines.
|
|
75
|
+
*/
|
|
76
|
+
lineClamp: {
|
|
77
|
+
2: [
|
|
78
|
+
lineClamp,
|
|
79
|
+
{
|
|
80
|
+
'@layer': {
|
|
81
|
+
[components]: {
|
|
82
|
+
vars: {
|
|
83
|
+
[lineClampNumber]: '2',
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
3: [
|
|
90
|
+
lineClamp,
|
|
91
|
+
{
|
|
92
|
+
'@layer': {
|
|
93
|
+
[components]: {
|
|
94
|
+
vars: {
|
|
95
|
+
[lineClampNumber]: '3',
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
4: [
|
|
102
|
+
lineClamp,
|
|
103
|
+
{
|
|
104
|
+
'@layer': {
|
|
105
|
+
[components]: {
|
|
106
|
+
vars: {
|
|
107
|
+
[lineClampNumber]: '4',
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
5: [
|
|
114
|
+
lineClamp,
|
|
115
|
+
{
|
|
116
|
+
'@layer': {
|
|
117
|
+
[components]: {
|
|
118
|
+
vars: {
|
|
119
|
+
[lineClampNumber]: '5',
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
},
|
|
14
126
|
|
|
15
|
-
|
|
127
|
+
/**
|
|
128
|
+
* Controls the alignment of the text.
|
|
129
|
+
*/
|
|
130
|
+
align: {
|
|
131
|
+
start: {
|
|
132
|
+
'@layer': {
|
|
133
|
+
[components]: {
|
|
134
|
+
textAlign: 'start',
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
center: {
|
|
139
|
+
'@layer': {
|
|
140
|
+
[components]: {
|
|
141
|
+
textAlign: 'center',
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
end: {
|
|
146
|
+
'@layer': {
|
|
147
|
+
[components]: {
|
|
148
|
+
textAlign: 'end',
|
|
149
|
+
},
|
|
150
|
+
},
|
|
16
151
|
},
|
|
17
152
|
},
|
|
18
153
|
},
|
|
19
154
|
});
|
|
20
155
|
|
|
21
156
|
export const textEllipsisWrapper = style({
|
|
22
|
-
|
|
157
|
+
'@layer': {
|
|
158
|
+
[components]: {
|
|
159
|
+
whiteSpace: 'nowrap',
|
|
160
|
+
},
|
|
161
|
+
},
|
|
23
162
|
});
|
|
24
163
|
|
|
25
164
|
export type TextVariants = NonNullable<RecipeVariants<typeof textRecipe>>;
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DistributiveOmit,
|
|
3
|
-
PolymorphicComponentProps,
|
|
4
|
-
getProp,
|
|
5
|
-
} from '@kalink-ui/dibbly';
|
|
1
|
+
import { PolymorphicComponentProps, getProp } from '@kalink-ui/dibbly';
|
|
6
2
|
import { clsx } from 'clsx';
|
|
7
3
|
import { ElementType } from 'react';
|
|
8
4
|
|
|
@@ -10,48 +6,44 @@ import { TypographySize, TypographyVariant, typography } from '../../styles';
|
|
|
10
6
|
|
|
11
7
|
import { TextVariants, textRecipe, textEllipsisWrapper } from './text.css';
|
|
12
8
|
|
|
13
|
-
export type TextProps<TUse extends React.ElementType> =
|
|
14
|
-
PolymorphicComponentProps<TUse
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
*/
|
|
21
|
-
size?: TypographySize;
|
|
9
|
+
export type TextProps<TUse extends React.ElementType> =
|
|
10
|
+
PolymorphicComponentProps<TUse> &
|
|
11
|
+
TextVariants & {
|
|
12
|
+
/**
|
|
13
|
+
* The size of the typography used to render the text.
|
|
14
|
+
*/
|
|
15
|
+
size?: TypographySize;
|
|
22
16
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* The text to render.
|
|
30
|
-
*/
|
|
31
|
-
children: string;
|
|
32
|
-
};
|
|
17
|
+
/**
|
|
18
|
+
* The typography variant used to render the text.
|
|
19
|
+
*/
|
|
20
|
+
variant?: TypographyVariant;
|
|
21
|
+
};
|
|
33
22
|
|
|
34
23
|
export function Text<TUse extends ElementType>(props: TextProps<TUse>) {
|
|
35
24
|
const {
|
|
36
25
|
children,
|
|
37
26
|
className,
|
|
38
|
-
|
|
27
|
+
truncate,
|
|
28
|
+
lineClamp,
|
|
39
29
|
size = 'medium',
|
|
40
30
|
use: Comp = 'span',
|
|
41
31
|
variant = 'body',
|
|
32
|
+
wrap,
|
|
33
|
+
align,
|
|
42
34
|
...rest
|
|
43
35
|
} = props;
|
|
44
36
|
|
|
45
37
|
return (
|
|
46
38
|
<Comp
|
|
47
39
|
className={clsx(
|
|
48
|
-
textRecipe({ ellipsis }),
|
|
49
40
|
getProp(typography, `${variant}.${size}`),
|
|
41
|
+
textRecipe({ truncate, lineClamp, align, wrap }),
|
|
50
42
|
className,
|
|
51
43
|
)}
|
|
52
44
|
{...rest}
|
|
53
45
|
>
|
|
54
|
-
{
|
|
46
|
+
{truncate ? (
|
|
55
47
|
<span className={textEllipsisWrapper}>{children}</span>
|
|
56
48
|
) : (
|
|
57
49
|
children
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { styleVariants } from '@vanilla-extract/css';
|
|
2
2
|
|
|
3
|
+
import { base } from './layers.css';
|
|
3
4
|
import { sys, TypographySize, TypographyVariant } from './system-contract.css';
|
|
4
5
|
|
|
5
6
|
export const typography = Object.entries(sys.typography).reduce(
|
|
@@ -8,11 +9,15 @@ export const typography = Object.entries(sys.typography).reduce(
|
|
|
8
9
|
...acc,
|
|
9
10
|
[key]: styleVariants(value, (variant) => {
|
|
10
11
|
return {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
'@layer': {
|
|
13
|
+
[base]: {
|
|
14
|
+
fontFamily: variant.font,
|
|
15
|
+
fontWeight: variant.weight,
|
|
16
|
+
lineHeight: variant.lineHeight,
|
|
17
|
+
letterSpacing: variant.tracking,
|
|
18
|
+
fontSize: variant.size,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
16
21
|
};
|
|
17
22
|
}),
|
|
18
23
|
};
|
|
@@ -0,0 +1,36 @@
|
|
|
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
|
+
},
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
{},
|
|
35
|
+
);
|
|
36
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { isObject } from '@kalink-ui/dibbly';
|
|
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
|
+
}
|