@kalink-ui/seedly 0.24.0 → 0.26.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 (50) hide show
  1. package/CHANGELOG.md +24 -1
  2. package/package.json +2 -2
  3. package/src/components/box/box.css.ts +21 -8
  4. package/src/components/box/box.responsive.ts +9 -0
  5. package/src/components/box/box.tsx +9 -3
  6. package/src/components/button/button.css.ts +199 -177
  7. package/src/components/button/button.responsive.ts +11 -0
  8. package/src/components/button/button.tsx +31 -10
  9. package/src/components/card/card.tsx +3 -1
  10. package/src/components/center/center.css.ts +23 -10
  11. package/src/components/center/center.responsive.ts +9 -0
  12. package/src/components/center/center.tsx +12 -3
  13. package/src/components/cluster/cluster.css.ts +116 -89
  14. package/src/components/cluster/cluster.responsive.ts +9 -0
  15. package/src/components/cluster/cluster.tsx +14 -3
  16. package/src/components/command/command-list.css.ts +24 -10
  17. package/src/components/command/command-list.responsive.ts +9 -0
  18. package/src/components/command/command-list.tsx +2 -2
  19. package/src/components/command/command.tsx +2 -2
  20. package/src/components/cover/cover.css.ts +23 -10
  21. package/src/components/cover/cover.responsive.ts +9 -0
  22. package/src/components/cover/cover.tsx +7 -3
  23. package/src/components/grid/grid.css.ts +21 -8
  24. package/src/components/grid/grid.responsive.ts +9 -0
  25. package/src/components/grid/grid.tsx +7 -3
  26. package/src/components/heading/heading.css.ts +75 -41
  27. package/src/components/heading/heading.responsive.ts +28 -0
  28. package/src/components/heading/heading.tsx +65 -53
  29. package/src/components/loader/loader.css.ts +31 -18
  30. package/src/components/loader/moon-loader.responsive.ts +9 -0
  31. package/src/components/loader/moon-loader.tsx +12 -3
  32. package/src/components/menu/menu-separator.css.ts +26 -10
  33. package/src/components/menu/menu-separator.responsive.ts +9 -0
  34. package/src/components/sheet/sheet-title.tsx +16 -1
  35. package/src/components/sidebar/sidebar.css.ts +21 -8
  36. package/src/components/sidebar/sidebar.responsive.ts +9 -0
  37. package/src/components/sidebar/sidebar.tsx +6 -3
  38. package/src/components/stack/stack.css.ts +61 -39
  39. package/src/components/stack/stack.responsive.ts +9 -0
  40. package/src/components/stack/stack.tsx +10 -3
  41. package/src/components/switcher/index.ts +1 -1
  42. package/src/components/switcher/switcher.css.ts +21 -8
  43. package/src/components/switcher/switcher.responsive.ts +9 -0
  44. package/src/components/switcher/switcher.tsx +14 -9
  45. package/src/components/text/text.css.ts +78 -39
  46. package/src/components/text/text.responsive.ts +62 -0
  47. package/src/components/text/text.tsx +35 -8
  48. package/src/styles/breakpoints.ts +25 -0
  49. package/src/styles/index.ts +12 -0
  50. package/src/styles/responsive.ts +180 -0
@@ -3,6 +3,10 @@ import { recipe, type RecipeVariants } from '@vanilla-extract/recipes';
3
3
 
4
4
  import { sys, mapContractVars } from '../../styles';
5
5
  import { components } from '../../styles/layers.css';
6
+ import {
7
+ createResponsiveVariants,
8
+ defaultMedia,
9
+ } from '../../styles/responsive';
6
10
 
7
11
  const spacing = createVar({
8
12
  syntax: '<length>',
@@ -10,6 +14,48 @@ const spacing = createVar({
10
14
  inherits: false,
11
15
  });
12
16
 
17
+ // Shared variant style maps so we can reuse them for responsive overrides
18
+ export const stackSpacingStyles = mapContractVars(sys.spacing, (key) => ({
19
+ '@layer': {
20
+ [components]: {
21
+ vars: {
22
+ [spacing]: sys.spacing[key],
23
+ },
24
+ },
25
+ },
26
+ }));
27
+
28
+ export const stackAlignStyles = {
29
+ start: {
30
+ '@layer': {
31
+ [components]: {
32
+ alignItems: 'flex-start',
33
+ },
34
+ },
35
+ },
36
+ center: {
37
+ '@layer': {
38
+ [components]: {
39
+ alignItems: 'center',
40
+ },
41
+ },
42
+ },
43
+ end: {
44
+ '@layer': {
45
+ [components]: {
46
+ alignItems: 'flex-end',
47
+ },
48
+ },
49
+ },
50
+ stretch: {
51
+ '@layer': {
52
+ [components]: {
53
+ alignItems: 'stretch',
54
+ },
55
+ },
56
+ },
57
+ } as const;
58
+
13
59
  export const stackRecipe = recipe({
14
60
  base: {
15
61
  '@layer': {
@@ -26,47 +72,23 @@ export const stackRecipe = recipe({
26
72
  /**
27
73
  * The spacing between items
28
74
  */
29
- spacing: mapContractVars(sys.spacing, (key) => ({
30
- '@layer': {
31
- [components]: {
32
- vars: {
33
- [spacing]: sys.spacing[key],
34
- },
35
- },
36
- },
37
- })),
75
+ spacing: stackSpacingStyles,
38
76
 
39
- align: {
40
- start: {
41
- '@layer': {
42
- [components]: {
43
- alignItems: 'flex-start',
44
- },
45
- },
46
- },
47
- center: {
48
- '@layer': {
49
- [components]: {
50
- alignItems: 'center',
51
- },
52
- },
53
- },
54
- end: {
55
- '@layer': {
56
- [components]: {
57
- alignItems: 'flex-end',
58
- },
59
- },
60
- },
61
- stretch: {
62
- '@layer': {
63
- [components]: {
64
- alignItems: 'stretch',
65
- },
66
- },
67
- },
68
- },
77
+ /**
78
+ * The alignment of items along the cross axis
79
+ */
80
+ align: stackAlignStyles,
69
81
  },
70
82
  });
71
83
 
72
84
  export type StackVariants = NonNullable<RecipeVariants<typeof stackRecipe>>;
85
+
86
+ export const spacingAt = createResponsiveVariants({
87
+ styles: stackSpacingStyles,
88
+ media: defaultMedia,
89
+ });
90
+
91
+ export const alignAt = createResponsiveVariants({
92
+ styles: stackAlignStyles,
93
+ media: defaultMedia,
94
+ });
@@ -0,0 +1,9 @@
1
+ import { defaultOrder, responsiveRecipe } from '../../styles/responsive';
2
+
3
+ import { alignAt, spacingAt, stackRecipe } from './stack.css';
4
+
5
+ export const stackResponsive = responsiveRecipe({
6
+ recipe: stackRecipe,
7
+ at: { spacing: spacingAt, align: alignAt },
8
+ order: defaultOrder,
9
+ });
@@ -2,10 +2,17 @@ import { PolymorphicComponentProps } from '@kalink-ui/dibbly';
2
2
  import { clsx } from 'clsx';
3
3
  import { ElementType } from 'react';
4
4
 
5
- import { stackRecipe, StackVariants } from './stack.css';
5
+ import { StackVariants } from './stack.css';
6
+ import { stackResponsive } from './stack.responsive';
7
+
8
+ import type { Responsive } from '../../styles/responsive';
6
9
 
7
10
  export type StackProps<TUse extends ElementType> =
8
- PolymorphicComponentProps<TUse> & StackVariants;
11
+ PolymorphicComponentProps<TUse> &
12
+ Omit<StackVariants, 'spacing' | 'align'> & {
13
+ spacing?: Responsive<NonNullable<StackVariants['spacing']>>;
14
+ align?: Responsive<NonNullable<StackVariants['align']>>;
15
+ };
9
16
 
10
17
  /**
11
18
  * A custom element for injecting white space (margin) between flow
@@ -27,7 +34,7 @@ export function Stack<TUse extends ElementType = 'div'>({
27
34
 
28
35
  return (
29
36
  <Comp
30
- className={clsx(stackRecipe({ spacing, align }), className)}
37
+ className={clsx(stackResponsive({ spacing, align }), className)}
31
38
  {...rest}
32
39
  />
33
40
  );
@@ -1,2 +1,2 @@
1
- export { Switcher } from './switcher';
1
+ export { Switcher, type SwitcherProps } from './switcher';
2
2
  export { switcherRecipe, type SwitcherVariants } from './switcher.css';
@@ -1,12 +1,26 @@
1
1
  import { createVar, globalStyle } from '@vanilla-extract/css';
2
2
  import { recipe, type RecipeVariants } from '@vanilla-extract/recipes';
3
3
 
4
- import { sys, mapContractVars } from '../../styles';
4
+ import {
5
+ createResponsiveVariants,
6
+ defaultMedia,
7
+ sys,
8
+ mapContractVars,
9
+ } from '../../styles';
5
10
  import { components } from '../../styles/layers.css';
6
11
 
7
12
  export const thresholdVar = createVar();
8
13
  export const limitVar = createVar();
9
14
 
15
+ // Shared variant styles to support responsive overrides
16
+ export const switcherSpacingStyles = mapContractVars(sys.spacing, (key) => ({
17
+ '@layer': {
18
+ [components]: {
19
+ gap: sys.spacing[key],
20
+ },
21
+ },
22
+ }));
23
+
10
24
  export const switcherRecipe = recipe({
11
25
  base: {
12
26
  '@layer': {
@@ -25,13 +39,7 @@ export const switcherRecipe = recipe({
25
39
  /**
26
40
  * The space (margin) between the child elements
27
41
  */
28
- spacing: mapContractVars(sys.spacing, (key) => ({
29
- '@layer': {
30
- [components]: {
31
- gap: sys.spacing[key],
32
- },
33
- },
34
- })),
42
+ spacing: switcherSpacingStyles,
35
43
 
36
44
  /**
37
45
  * The maximum number of elements allowed to appear in the horizontal configuration
@@ -123,3 +131,8 @@ globalStyle(
123
131
  export type SwitcherVariants = NonNullable<
124
132
  RecipeVariants<typeof switcherRecipe>
125
133
  >;
134
+
135
+ export const spacingAt = createResponsiveVariants({
136
+ styles: switcherSpacingStyles,
137
+ media: defaultMedia,
138
+ });
@@ -0,0 +1,9 @@
1
+ import { defaultOrder, responsiveRecipe } from '../../styles/responsive';
2
+
3
+ import { spacingAt, switcherRecipe } from './switcher.css';
4
+
5
+ export const switcherResponsive = responsiveRecipe({
6
+ recipe: switcherRecipe,
7
+ at: { spacing: spacingAt },
8
+ order: defaultOrder,
9
+ });
@@ -5,15 +5,20 @@ import { assignInlineVars } from '@vanilla-extract/dynamic';
5
5
  import { clsx } from 'clsx';
6
6
  import { ElementType } from 'react';
7
7
 
8
- import { switcherRecipe, SwitcherVariants, thresholdVar } from './switcher.css';
8
+ import { SwitcherVariants, thresholdVar } from './switcher.css';
9
+ import { switcherResponsive } from './switcher.responsive';
9
10
 
10
- type SwitcherProps<TUse extends ElementType> = PolymorphicComponentProps<TUse> &
11
- SwitcherVariants & {
12
- /**
13
- * The threshold at which to switch between horizontal and vertical layouts
14
- */
15
- threshold?: string;
16
- };
11
+ import type { Responsive } from '../../styles/responsive';
12
+
13
+ export type SwitcherProps<TUse extends ElementType> =
14
+ PolymorphicComponentProps<TUse> &
15
+ Omit<SwitcherVariants, 'spacing'> & {
16
+ /**
17
+ * The threshold at which to switch between horizontal and vertical layouts
18
+ */
19
+ threshold?: string;
20
+ spacing?: Responsive<NonNullable<SwitcherVariants['spacing']>>;
21
+ };
17
22
 
18
23
  /**
19
24
  * Switch directly between horizontal and vertical layouts
@@ -32,7 +37,7 @@ export function Switcher<TUse extends ElementType>({
32
37
 
33
38
  return (
34
39
  <Comp
35
- className={clsx(switcherRecipe({ spacing, limit }), className)}
40
+ className={clsx(switcherResponsive({ spacing, limit }), className)}
36
41
  style={assignInlineVars({
37
42
  ...(threshold && { [thresholdVar]: threshold }),
38
43
  })}
@@ -1,6 +1,7 @@
1
- import { createVar, style } from '@vanilla-extract/css';
1
+ import { createVar, style, type StyleRule } from '@vanilla-extract/css';
2
2
  import { recipe, type RecipeVariants } from '@vanilla-extract/recipes';
3
3
 
4
+ import { createResponsiveVariants, defaultMedia, sys } from '../../styles';
4
5
  import { components } from '../../styles/layers.css';
5
6
 
6
7
  export const lineClampNumber = createVar();
@@ -17,6 +18,46 @@ const lineClamp = style({
17
18
  },
18
19
  });
19
20
 
21
+ // Extract align styles for responsive overrides
22
+ export const textAlignStyles = {
23
+ start: {
24
+ '@layer': {
25
+ [components]: {
26
+ vars: {
27
+ [textAlign]: 'start',
28
+ },
29
+ },
30
+ },
31
+ },
32
+ center: {
33
+ '@layer': {
34
+ [components]: {
35
+ vars: {
36
+ [textAlign]: 'center',
37
+ },
38
+ },
39
+ },
40
+ },
41
+ end: {
42
+ '@layer': {
43
+ [components]: {
44
+ vars: {
45
+ [textAlign]: 'end',
46
+ },
47
+ },
48
+ },
49
+ },
50
+ justify: {
51
+ '@layer': {
52
+ [components]: {
53
+ vars: {
54
+ [textAlign]: 'justify',
55
+ },
56
+ },
57
+ },
58
+ },
59
+ } as const;
60
+
20
61
  export const textRecipe = recipe({
21
62
  base: {
22
63
  '@layer': {
@@ -139,44 +180,7 @@ export const textRecipe = recipe({
139
180
  /**
140
181
  * Controls the alignment of the text.
141
182
  */
142
- align: {
143
- start: {
144
- '@layer': {
145
- [components]: {
146
- vars: {
147
- [textAlign]: 'start',
148
- },
149
- },
150
- },
151
- },
152
- center: {
153
- '@layer': {
154
- [components]: {
155
- vars: {
156
- [textAlign]: 'center',
157
- },
158
- },
159
- },
160
- },
161
- end: {
162
- '@layer': {
163
- [components]: {
164
- vars: {
165
- [textAlign]: 'end',
166
- },
167
- },
168
- },
169
- },
170
- justify: {
171
- '@layer': {
172
- [components]: {
173
- vars: {
174
- [textAlign]: 'justify',
175
- },
176
- },
177
- },
178
- },
179
- },
183
+ align: textAlignStyles,
180
184
  },
181
185
  });
182
186
 
@@ -189,3 +193,38 @@ export const textEllipsisWrapper = style({
189
193
  });
190
194
 
191
195
  export type TextVariants = NonNullable<RecipeVariants<typeof textRecipe>>;
196
+
197
+ export const alignAt = createResponsiveVariants({
198
+ styles: textAlignStyles,
199
+ media: defaultMedia,
200
+ });
201
+
202
+ // Responsive typography overrides for variant+size combos
203
+ const typographyComboEntries = Object.entries(sys.typography).flatMap(
204
+ ([variantKey, sizes]) => {
205
+ return Object.entries(sizes).map(([sizeKey, v]) => {
206
+ const k = `${variantKey}.${sizeKey}`;
207
+ const rule: StyleRule = {
208
+ '@layer': {
209
+ [components]: {
210
+ fontFamily: v.font,
211
+ fontWeight: v.weight,
212
+ lineHeight: v.lineHeight,
213
+ letterSpacing: v.tracking,
214
+ fontSize: v.size,
215
+ },
216
+ },
217
+ };
218
+
219
+ return [k, rule] as const;
220
+ });
221
+ },
222
+ );
223
+
224
+ export const typographyAt = createResponsiveVariants({
225
+ styles: Object.fromEntries(typographyComboEntries) as Record<
226
+ string,
227
+ StyleRule
228
+ >,
229
+ media: defaultMedia,
230
+ });
@@ -0,0 +1,62 @@
1
+ import {
2
+ defaultOrder,
3
+ resolveResponsive,
4
+ responsiveRecipe,
5
+ TypographySize,
6
+ TypographyVariant,
7
+ type BreakpointWithBase,
8
+ type Responsive,
9
+ } from '../../styles';
10
+
11
+ import { alignAt, textRecipe, typographyAt } from './text.css';
12
+
13
+ export const textResponsive = responsiveRecipe({
14
+ recipe: textRecipe,
15
+ at: { align: alignAt },
16
+ order: defaultOrder,
17
+ });
18
+
19
+ export function buildTypographyOverrides(opts: {
20
+ variant?: Responsive<TypographyVariant>;
21
+ size?: Responsive<TypographySize>;
22
+ }) {
23
+ const { variant, size } = opts;
24
+ const varMap = resolveResponsive<TypographyVariant, BreakpointWithBase>(
25
+ variant,
26
+ defaultOrder,
27
+ );
28
+ const sizeMap = resolveResponsive<TypographySize, BreakpointWithBase>(
29
+ size,
30
+ defaultOrder,
31
+ );
32
+
33
+ const baseVariant = varMap.xs ?? variant;
34
+ const baseSize = sizeMap.xs ?? size;
35
+
36
+ const classes: string[] = [];
37
+
38
+ for (const bp of defaultOrder) {
39
+ if (bp === 'xs') {
40
+ continue;
41
+ }
42
+
43
+ const v = varMap[bp] ?? baseVariant;
44
+ const s = sizeMap[bp] ?? baseSize;
45
+
46
+ if (v && s) {
47
+ const key = `${String(v)}.${String(s)}`;
48
+ const cls = (
49
+ typographyAt as Record<
50
+ Exclude<BreakpointWithBase, 'xs'>,
51
+ Record<string, string>
52
+ >
53
+ )[bp]?.[key];
54
+
55
+ if (cls) {
56
+ classes.push(cls);
57
+ }
58
+ }
59
+ }
60
+
61
+ return classes;
62
+ }
@@ -4,20 +4,42 @@ import { ElementType } from 'react';
4
4
 
5
5
  import { TypographySize, TypographyVariant, typography } from '../../styles';
6
6
 
7
- import { TextVariants, textRecipe, textEllipsisWrapper } from './text.css';
7
+ import { TextVariants, textEllipsisWrapper } from './text.css';
8
+ import { buildTypographyOverrides, textResponsive } from './text.responsive';
9
+
10
+ import type { Responsive } from '../../styles/responsive';
11
+
12
+ function getBase<T extends string | number>(value: Responsive<T> | undefined) {
13
+ if (value == null) {
14
+ return undefined;
15
+ }
16
+
17
+ if (Array.isArray(value)) {
18
+ return value[0] ?? undefined;
19
+ }
20
+
21
+ if (typeof value === 'object') {
22
+ const obj = value as Partial<Record<string, T>> & { xs?: T };
23
+
24
+ return obj.xs;
25
+ }
26
+
27
+ return value;
28
+ }
8
29
 
9
30
  export type TextProps<TUse extends React.ElementType> =
10
31
  PolymorphicComponentProps<TUse> &
11
- TextVariants & {
32
+ Omit<TextVariants, 'align'> & {
12
33
  /**
13
34
  * The size of the typography used to render the text.
14
35
  */
15
- size?: TypographySize;
36
+ size?: Responsive<TypographySize>;
16
37
 
17
38
  /**
18
39
  * The typography variant used to render the text.
19
40
  */
20
- variant?: TypographyVariant;
41
+ variant?: Responsive<TypographyVariant>;
42
+ align?: Responsive<NonNullable<TextVariants['align']>>;
21
43
  };
22
44
 
23
45
  export function Text<TUse extends ElementType>(props: TextProps<TUse>) {
@@ -26,19 +48,24 @@ export function Text<TUse extends ElementType>(props: TextProps<TUse>) {
26
48
  className,
27
49
  truncate,
28
50
  lineClamp,
29
- size = 'medium',
51
+ size,
30
52
  use: Comp = 'span',
31
- variant = 'body',
53
+ variant,
32
54
  wrap,
33
55
  align,
34
56
  ...rest
35
57
  } = props;
36
58
 
59
+ const typographyOverrides = buildTypographyOverrides({ variant, size });
60
+ const baseVariant = getBase(variant) ?? 'body';
61
+ const baseSize = getBase(size) ?? 'medium';
62
+
37
63
  return (
38
64
  <Comp
39
65
  className={clsx(
40
- getProp(typography, `${variant}.${size}`),
41
- textRecipe({ truncate, lineClamp, align, wrap }),
66
+ getProp(typography, `${baseVariant}.${baseSize}`),
67
+ typographyOverrides,
68
+ textResponsive({ truncate, lineClamp, align, wrap }),
42
69
  className,
43
70
  )}
44
71
  {...rest}
@@ -0,0 +1,25 @@
1
+ export const breakpoints = {
2
+ sm: 568,
3
+ md: 768,
4
+ lg: 1024,
5
+ xl: 1280,
6
+ '2xl': 1600,
7
+ '3xl': 1920,
8
+ } as const;
9
+
10
+ export type BreakpointKey = keyof typeof breakpoints;
11
+
12
+ export const screen = {
13
+ maxXs: `(max-width: ${breakpoints.sm - 1}px)`,
14
+ sm: `(min-width: ${breakpoints.sm}px)`,
15
+ maxSm: `(max-width: ${breakpoints.md - 1}px)`,
16
+ md: `(min-width: ${breakpoints.md}px)`,
17
+ maxMd: `(max-width: ${breakpoints.lg - 1}px)`,
18
+ lg: `(min-width: ${breakpoints.lg}px)`,
19
+ maxLg: `(max-width: ${breakpoints.xl - 1}px)`,
20
+ xl: `(min-width: ${breakpoints.xl}px)`,
21
+ maxXl: `(max-width: ${breakpoints['2xl'] - 1}px)`,
22
+ '2xl': `(min-width: ${breakpoints['2xl']}px)`,
23
+ max2xl: `(max-width: ${breakpoints['3xl'] - 1}px)`,
24
+ '3xl': `(min-width: ${breakpoints['3xl']}px)`,
25
+ } as const;
@@ -22,3 +22,15 @@ export {
22
22
  export { transition, type CreateTransitionFn } from './transition';
23
23
 
24
24
  export { visuallyHidden } from './visually-hidden.css';
25
+
26
+ export {
27
+ responsiveRecipe,
28
+ createResponsiveVariants,
29
+ resolveResponsive,
30
+ defaultMedia,
31
+ defaultOrder,
32
+ type Responsive,
33
+ type BreakpointWithBase,
34
+ } from './responsive';
35
+
36
+ export { breakpoints, screen, type BreakpointKey } from './breakpoints';