@sixthshift/design-system 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.
Files changed (123) hide show
  1. package/README.md +5 -4
  2. package/dist/components/Badge/Badge.d.ts +17 -35
  3. package/dist/components/Badge/Badge.d.ts.map +1 -1
  4. package/dist/components/Badge/Badge.js +19 -22
  5. package/dist/components/Badge/Badge.js.map +1 -1
  6. package/dist/components/Badge/index.d.ts +1 -1
  7. package/dist/components/Badge/index.d.ts.map +1 -1
  8. package/dist/components/Badge/index.js +1 -1
  9. package/dist/components/Badge/index.js.map +1 -1
  10. package/dist/components/Button/Button.d.ts +23 -41
  11. package/dist/components/Button/Button.d.ts.map +1 -1
  12. package/dist/components/Button/Button.js +28 -35
  13. package/dist/components/Button/Button.js.map +1 -1
  14. package/dist/components/Button/index.d.ts +1 -1
  15. package/dist/components/Button/index.d.ts.map +1 -1
  16. package/dist/components/Button/index.js +1 -1
  17. package/dist/components/Button/index.js.map +1 -1
  18. package/dist/components/Card/Card.d.ts +2 -2
  19. package/dist/components/Card/Card.js +1 -1
  20. package/dist/components/Card/Card.js.map +1 -1
  21. package/dist/components/CheckboxGroup/CheckboxGroup.d.ts +20 -16
  22. package/dist/components/CheckboxGroup/CheckboxGroup.d.ts.map +1 -1
  23. package/dist/components/CheckboxGroup/CheckboxGroup.js +12 -10
  24. package/dist/components/CheckboxGroup/CheckboxGroup.js.map +1 -1
  25. package/dist/components/Code/Workspace/Toolbar.d.ts +2 -1
  26. package/dist/components/Code/Workspace/Toolbar.d.ts.map +1 -1
  27. package/dist/components/Code/Workspace/Toolbar.js.map +1 -1
  28. package/dist/components/FormField/FormField.d.ts +3 -1
  29. package/dist/components/FormField/FormField.d.ts.map +1 -1
  30. package/dist/components/FormField/FormField.js.map +1 -1
  31. package/dist/components/Input/Input.d.ts +3 -3
  32. package/dist/components/Input/Input.js +3 -3
  33. package/dist/components/Markdown/Markdown.js +1 -1
  34. package/dist/components/Markdown/Markdown.js.map +1 -1
  35. package/dist/components/NumberStepper/NumberStepper.d.ts +1 -1
  36. package/dist/components/ProgressBar/ProgressBar.d.ts +11 -0
  37. package/dist/components/ProgressBar/ProgressBar.d.ts.map +1 -1
  38. package/dist/components/ProgressBar/ProgressBar.js +6 -2
  39. package/dist/components/ProgressBar/ProgressBar.js.map +1 -1
  40. package/dist/components/ProgressBar/index.d.ts +1 -1
  41. package/dist/components/ProgressBar/index.d.ts.map +1 -1
  42. package/dist/components/ProgressBar/index.js.map +1 -1
  43. package/dist/components/RadioButtonGroup/RadioButtonGroup.d.ts +19 -16
  44. package/dist/components/RadioButtonGroup/RadioButtonGroup.d.ts.map +1 -1
  45. package/dist/components/RadioButtonGroup/RadioButtonGroup.js +13 -12
  46. package/dist/components/RadioButtonGroup/RadioButtonGroup.js.map +1 -1
  47. package/dist/components/SearchInput/SearchInput.d.ts +3 -2
  48. package/dist/components/SearchInput/SearchInput.d.ts.map +1 -1
  49. package/dist/components/SearchInput/SearchInput.js +13 -8
  50. package/dist/components/SearchInput/SearchInput.js.map +1 -1
  51. package/dist/components/Sparkline/Sparkline.d.ts +8 -4
  52. package/dist/components/Sparkline/Sparkline.d.ts.map +1 -1
  53. package/dist/components/Sparkline/Sparkline.js +1 -1
  54. package/dist/components/Sparkline/Sparkline.js.map +1 -1
  55. package/dist/components/Sparkline/index.d.ts +1 -1
  56. package/dist/components/Sparkline/index.d.ts.map +1 -1
  57. package/dist/components/Sparkline/index.js.map +1 -1
  58. package/dist/components/TagChip/TagChip.d.ts +0 -13
  59. package/dist/components/TagChip/TagChip.d.ts.map +1 -1
  60. package/dist/components/TagChip/TagChip.js +10 -4
  61. package/dist/components/TagChip/TagChip.js.map +1 -1
  62. package/dist/components/TextInline/TextInline.d.ts +2 -2
  63. package/dist/components/Toast/Toast.js +1 -1
  64. package/dist/components/Toast/Toast.js.map +1 -1
  65. package/dist/components/Toggle/Toggle.d.ts +29 -18
  66. package/dist/components/Toggle/Toggle.d.ts.map +1 -1
  67. package/dist/components/Toggle/Toggle.js +48 -11
  68. package/dist/components/Toggle/Toggle.js.map +1 -1
  69. package/dist/components/Toggle/index.d.ts +1 -1
  70. package/dist/components/Toggle/index.d.ts.map +1 -1
  71. package/dist/components/Toggle/index.js +1 -1
  72. package/dist/components/Toggle/index.js.map +1 -1
  73. package/dist/components/ToggleGroup/ToggleGroup.d.ts +4 -4
  74. package/dist/components/ToggleGroup/ToggleGroup.js +4 -4
  75. package/dist/components/ToggleGroup/ToggleGroupItem.d.ts +1 -1
  76. package/dist/components/ToggleGroup/ToggleGroupItem.d.ts.map +1 -1
  77. package/dist/components/ToggleGroup/ToggleGroupItem.js +37 -7
  78. package/dist/components/ToggleGroup/ToggleGroupItem.js.map +1 -1
  79. package/dist/components/ToggleGroup/ToggleGroupMultiple.d.ts +3 -3
  80. package/dist/components/ToggleGroup/ToggleGroupSingle.d.ts +3 -3
  81. package/dist/components/ToggleGroup/index.d.ts +1 -1
  82. package/dist/components/ToggleGroup/index.d.ts.map +1 -1
  83. package/dist/components/ToggleGroup/toggleGroup.types.d.ts +18 -16
  84. package/dist/components/ToggleGroup/toggleGroup.types.d.ts.map +1 -1
  85. package/dist/typography/Code.js +1 -1
  86. package/dist/typography/Code.js.map +1 -1
  87. package/package.json +2 -1
  88. package/src/components/Badge/Badge.tsx +38 -45
  89. package/src/components/Badge/badge.recipe.css +20 -101
  90. package/src/components/Badge/index.ts +0 -1
  91. package/src/components/Button/Button.tsx +57 -51
  92. package/src/components/Button/button.recipe.css +39 -122
  93. package/src/components/Button/index.ts +0 -1
  94. package/src/components/Card/Card.tsx +1 -1
  95. package/src/components/CheckboxGroup/CheckboxGroup.tsx +17 -15
  96. package/src/components/Code/Workspace/Toolbar.tsx +2 -2
  97. package/src/components/FormField/FormField.tsx +3 -2
  98. package/src/components/Input/Input.tsx +3 -3
  99. package/src/components/Markdown/Markdown.tsx +1 -1
  100. package/src/components/Message/message.recipe.css +13 -28
  101. package/src/components/ProgressBar/ProgressBar.tsx +16 -4
  102. package/src/components/ProgressBar/index.ts +1 -1
  103. package/src/components/ProgressBar/progress-bar.recipe.css +29 -0
  104. package/src/components/RadioButtonGroup/RadioButtonGroup.tsx +18 -17
  105. package/src/components/SearchInput/SearchInput.tsx +34 -20
  106. package/src/components/SearchInput/search-input.recipe.css +14 -6
  107. package/src/components/Sparkline/Sparkline.tsx +9 -4
  108. package/src/components/Sparkline/index.ts +1 -1
  109. package/src/components/TagChip/TagChip.tsx +17 -8
  110. package/src/components/TagChip/tag-chip.recipe.css +12 -12
  111. package/src/components/Toast/Toast.tsx +1 -1
  112. package/src/components/Toggle/Toggle.tsx +67 -21
  113. package/src/components/Toggle/index.ts +9 -1
  114. package/src/components/Toggle/toggle.recipe.css +45 -73
  115. package/src/components/ToggleGroup/ToggleGroup.tsx +4 -4
  116. package/src/components/ToggleGroup/ToggleGroupItem.tsx +46 -11
  117. package/src/components/ToggleGroup/index.ts +9 -1
  118. package/src/components/ToggleGroup/toggle-group.recipe.css +62 -0
  119. package/src/components/ToggleGroup/toggleGroup.types.ts +18 -16
  120. package/src/theme/linen/theme.css +21 -0
  121. package/src/theming/intents.css +112 -0
  122. package/src/theming/tailwind.css +17 -1
  123. package/src/typography/Code.tsx +1 -1
@@ -1,9 +1,17 @@
1
1
  import type * as React from "react";
2
- import type { ButtonIntentName, ButtonVariantName } from "../Button/Button";
3
- import type { ToggleProps } from "../Toggle/Toggle";
4
2
 
5
- /** Extract a prop's union type from ToggleProps, stripping null added by CVA */
6
- type ToggleProp<K extends keyof ToggleProps> = NonNullable<ToggleProps[K]>;
3
+ /**
4
+ * ToggleGroup's own axes. They match Toggle's and Button's, deliberately
5
+ * duplicated rather than imported: a group of toggle buttons is its own
6
+ * component, and importing it must not pull in either.
7
+ */
8
+ type Loose<T extends string> = T | (string & {});
9
+ export type ToggleGroupVariantName = "solid" | "outline" | "ghost";
10
+ export type ToggleGroupIntentName = "neutral" | "brand" | "danger" | "success" | "warning";
11
+ export type ToggleGroupVariant = Loose<ToggleGroupVariantName>;
12
+ export type ToggleGroupIntent = Loose<ToggleGroupIntentName>;
13
+ /** `xl` is left out — too large for grouped toggles. */
14
+ export type ToggleGroupSize = "xs" | "sm" | "md" | "lg";
7
15
 
8
16
  export type ToggleGroupOption = {
9
17
  /** Unique value for the option */
@@ -23,24 +31,18 @@ export type ToggleGroupBaseProps = Omit<React.HTMLAttributes<HTMLDivElement>, "o
23
31
  appearance?: "segmented" | "separate";
24
32
  /** Layout orientation */
25
33
  orientation?: "vertical" | "horizontal";
26
- /**
27
- * Button variant (link excluded as it has no clear pressed state in groups).
28
- *
29
- * Deliberately the closed union, not Button's widened `ButtonVariant`: an
30
- * `Exclude` cannot remove `link` from a type that already admits any string,
31
- * so narrowing here requires narrowing from the closed names.
32
- */
33
- variant?: Exclude<ButtonVariantName, "link">;
34
- /** Color intent */
35
- intent?: ButtonIntentName;
34
+ /** The items' treatment. */
35
+ variant?: ToggleGroupVariant;
36
+ /** Colour intent — widened, so a consumer-defined intent reaches the group. */
37
+ intent?: ToggleGroupIntent;
36
38
  /**
37
39
  * Name of a brand the theme defines. Rendered once, as `data-brand` on the
38
40
  * group element, so every item inherits it. Omitted, the group follows the
39
41
  * nearest `data-brand` ancestor.
40
42
  */
41
43
  brand?: string | undefined;
42
- /** Button size (xl excluded — too large for grouped toggles) */
43
- size?: Exclude<ToggleProp<"size">, "xl">;
44
+ /** Item size (xl excluded — too large for grouped toggles) */
45
+ size?: ToggleGroupSize;
44
46
  /** Square every item at the current size, for icon-only options */
45
47
  iconOnly?: boolean;
46
48
  /** Disable all options */
@@ -1,12 +1,33 @@
1
1
  /*
2
2
  * Linen — the semantic layer (layer 1). This file is the theme.
3
3
  *
4
+ * What a theme defines, and so what any theme replacing this one must define:
5
+ * - the radius scale, `--border-radius-{xs,sm,md,lg,xl}`, in a mode-free
6
+ * `:root` block — miss a step and every corner on it renders square;
7
+ * - the semantic colour tokens, the same names in both mode blocks.
8
+ * Everything else — recipes, intent slots, the Tailwind bridge — is
9
+ * theme-independent and comes from src/theming/tailwind.css.
10
+ *
4
11
  * Trade-off, accepted: the warm cast is a commitment. A consumer whose brand
5
12
  * fights the temperature replaces the neutral, not just the accent.
6
13
  */
7
14
 
8
15
  @import "./palette.css";
9
16
 
17
+ /* Corner radius — five steps, `md` the middle and the default. Mode-free: a
18
+ corner is the same shape in light and dark. Tailwind's `rounded-*`
19
+ utilities read these (src/theming/tailwind.css), so a theme reshapes every
20
+ corner in the library here. The values are Tailwind's own, unchanged.
21
+ `rounded-none` and `rounded-full` are geometry, not steps, and are not
22
+ themed; `bun run check:radius` keeps component source on the scale. */
23
+ :root {
24
+ --border-radius-xs: 0.125rem;
25
+ --border-radius-sm: 0.25rem;
26
+ --border-radius-md: 0.375rem;
27
+ --border-radius-lg: 0.5rem;
28
+ --border-radius-xl: 0.75rem;
29
+ }
30
+
10
31
  :root:not([data-theme]),
11
32
  :root[data-theme="light"] {
12
33
  --bg-strong: var(--color-sand-800);
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Intent slots — each intent defined once, for every component.
3
+ *
4
+ * `intent` and `variant` are independent axes (docs/component-axes.md, rule 3),
5
+ * but a recipe that writes one cell per `(variant, intent)` pair couples them
6
+ * again: every component repeats the intent list, and adding an intent means
7
+ * editing every recipe. This layer sits between the semantic tokens and the
8
+ * recipes and breaks that product apart:
9
+ *
10
+ * - here, each intent names its colour family once, as a fixed set of slots;
11
+ * - in a recipe, each variant picks which slots it paints with.
12
+ *
13
+ * A new intent is one block below and every component picks it up. A new
14
+ * variant is one cell per component, and works in every intent.
15
+ *
16
+ * Slots are named for the treatment they serve, not for a weight:
17
+ *
18
+ * --intent-solid-bg[-hovered|-pressed] a filled surface in the family
19
+ * --intent-solid-fg text read on that fill
20
+ * --intent-tint-bg[-hovered|-pressed] a light wash of the family
21
+ * --intent-tint-fg[-pressed] text read on that wash
22
+ * --intent-fg the family's text on a resting surface
23
+ * --intent-border the family's border
24
+ *
25
+ * The slots are declared on the element carrying `data-intent`, which every
26
+ * intent-bearing component renders on its own element. That matters twice over.
27
+ * A `var()` inside a custom property resolves on the element that declares it,
28
+ * so `--intent-solid-bg: var(--bg-brand)` sees that element's own `data-brand`
29
+ * mapping (see the Scoped brands docs). And each intent-bearing element resets
30
+ * the whole set, so a component never inherits its parent's intent — a
31
+ * neutral Badge inside a danger Message stays neutral.
32
+ *
33
+ * `@layer components`, like the recipes: a consumer's unlayered
34
+ * `[data-intent="info"] { … }` outranks everything here without `!important`.
35
+ */
36
+
37
+ @layer components {
38
+ /* neutral — no colour family, the grey ramp. It is also the floor: this
39
+ selector matches any `data-intent`, so an intent a consumer has named but
40
+ not yet defined renders as neutral, legibly, rather than unstyled. The
41
+ `neutral` spelling is listed too so tooling can find it by name. */
42
+ [data-intent],
43
+ [data-intent="neutral"] {
44
+ --intent-solid-bg: var(--bg-strong);
45
+ --intent-solid-bg-hovered: var(--bg-strong-hovered);
46
+ --intent-solid-bg-pressed: var(--bg-strong-pressed);
47
+ --intent-solid-fg: var(--fg-on-strong);
48
+ --intent-tint-bg: var(--bg-subtle);
49
+ --intent-tint-bg-hovered: var(--bg-subtle-hovered);
50
+ --intent-tint-bg-pressed: var(--bg-subtle-pressed);
51
+ --intent-tint-fg: var(--fg-normal);
52
+ --intent-tint-fg-pressed: var(--fg-normal);
53
+ --intent-fg: var(--fg-normal);
54
+ --intent-border: var(--border-normal);
55
+ }
56
+
57
+ [data-intent="brand"] {
58
+ --intent-solid-bg: var(--bg-brand);
59
+ --intent-solid-bg-hovered: var(--bg-brand-hovered);
60
+ --intent-solid-bg-pressed: var(--bg-brand-pressed);
61
+ --intent-solid-fg: var(--fg-on-brand);
62
+ --intent-tint-bg: var(--bg-brand-subtle);
63
+ --intent-tint-bg-hovered: var(--bg-brand-subtle-hovered);
64
+ --intent-tint-bg-pressed: var(--bg-brand-subtle-pressed);
65
+ --intent-tint-fg: var(--fg-on-brand-subtle);
66
+ --intent-tint-fg-pressed: var(--fg-on-brand-subtle-pressed);
67
+ --intent-fg: var(--fg-brand);
68
+ --intent-border: var(--border-brand);
69
+ }
70
+
71
+ [data-intent="danger"] {
72
+ --intent-solid-bg: var(--bg-danger);
73
+ --intent-solid-bg-hovered: var(--bg-danger-hovered);
74
+ --intent-solid-bg-pressed: var(--bg-danger-pressed);
75
+ --intent-solid-fg: var(--fg-on-danger);
76
+ --intent-tint-bg: var(--bg-danger-subtle);
77
+ --intent-tint-bg-hovered: var(--bg-danger-subtle-hovered);
78
+ --intent-tint-bg-pressed: var(--bg-danger-subtle-pressed);
79
+ --intent-tint-fg: var(--fg-on-danger-subtle);
80
+ --intent-tint-fg-pressed: var(--fg-on-danger-subtle-pressed);
81
+ --intent-fg: var(--fg-danger);
82
+ --intent-border: var(--border-danger);
83
+ }
84
+
85
+ [data-intent="success"] {
86
+ --intent-solid-bg: var(--bg-success);
87
+ --intent-solid-bg-hovered: var(--bg-success-hovered);
88
+ --intent-solid-bg-pressed: var(--bg-success-pressed);
89
+ --intent-solid-fg: var(--fg-on-success);
90
+ --intent-tint-bg: var(--bg-success-subtle);
91
+ --intent-tint-bg-hovered: var(--bg-success-subtle-hovered);
92
+ --intent-tint-bg-pressed: var(--bg-success-subtle-pressed);
93
+ --intent-tint-fg: var(--fg-on-success-subtle);
94
+ --intent-tint-fg-pressed: var(--fg-on-success-subtle-pressed);
95
+ --intent-fg: var(--fg-success);
96
+ --intent-border: var(--border-success);
97
+ }
98
+
99
+ [data-intent="warning"] {
100
+ --intent-solid-bg: var(--bg-warning);
101
+ --intent-solid-bg-hovered: var(--bg-warning-hovered);
102
+ --intent-solid-bg-pressed: var(--bg-warning-pressed);
103
+ --intent-solid-fg: var(--fg-on-warning);
104
+ --intent-tint-bg: var(--bg-warning-subtle);
105
+ --intent-tint-bg-hovered: var(--bg-warning-subtle-hovered);
106
+ --intent-tint-bg-pressed: var(--bg-warning-subtle-pressed);
107
+ --intent-tint-fg: var(--fg-on-warning-subtle);
108
+ --intent-tint-fg-pressed: var(--fg-on-warning-subtle-pressed);
109
+ --intent-fg: var(--fg-warning);
110
+ --intent-border: var(--border-warning);
111
+ }
112
+ }
@@ -3,7 +3,8 @@
3
3
  * folder does NOT contain. A theme imports its own theme.css plus this file,
4
4
  * and is complete:
5
5
  *
6
- * - the component recipes (layer 2), imported first: every component's
6
+ * - the intent slots (intents.css), then the component recipes (layer 2),
7
+ * imported first: every component's
7
8
  * `*.recipe.css`, each inside `@layer components`. Adding a component
8
9
  * adds one import line here; `check:recipes` fails the build on a recipe
9
10
  * nobody imports, or an import pointing at nothing.
@@ -23,12 +24,16 @@
23
24
 
24
25
  @layer theme, base, components, utilities, overrides;
25
26
 
27
+ /* The intent slots every recipe paints with — one block per intent. */
28
+ @import "./intents.css";
29
+
26
30
  @import "../components/Button/button.recipe.css";
27
31
  @import "../components/Badge/badge.recipe.css";
28
32
  @import "../components/Message/message.recipe.css";
29
33
  @import "../components/Spinner/spinner.recipe.css";
30
34
  @import "../components/Tabs/tabs.recipe.css";
31
35
  @import "../components/Toggle/toggle.recipe.css";
36
+ @import "../components/ToggleGroup/toggle-group.recipe.css";
32
37
  @import "../components/Input/input.recipe.css";
33
38
  @import "../components/Textarea/textarea.recipe.css";
34
39
  @import "../components/SearchInput/search-input.recipe.css";
@@ -46,6 +51,7 @@
46
51
  @import "../components/ImageGallery/image-gallery.recipe.css";
47
52
  @import "../components/DataTable/data-table.recipe.css";
48
53
  @import "../components/FileDropzone/file-dropzone.recipe.css";
54
+ @import "../components/ProgressBar/progress-bar.recipe.css";
49
55
 
50
56
  /* =============================================================================
51
57
  3. TAILWIND THEME
@@ -62,6 +68,16 @@
62
68
  --color-white: #ffffff;
63
69
  --color-black: #000000;
64
70
 
71
+ /* Radius — the theme's five steps, and only those. Resetting Tailwind's own
72
+ scale first means `rounded-2xl` generates nothing instead of a corner no
73
+ theme can reach; `check:radius` turns that silence into a failure. */
74
+ --radius-*: initial;
75
+ --radius-xs: var(--border-radius-xs);
76
+ --radius-sm: var(--border-radius-sm);
77
+ --radius-md: var(--border-radius-md);
78
+ --radius-lg: var(--border-radius-lg);
79
+ --radius-xl: var(--border-radius-xl);
80
+
65
81
  /* Background */
66
82
  --color-bg-strong: var(--bg-strong);
67
83
  --color-bg-strong-hovered: var(--bg-strong-hovered);
@@ -3,6 +3,6 @@ import { cn } from "@sixthshift/design-system/utils";
3
3
  import * as React from "react";
4
4
 
5
5
  export const Code = React.forwardRef<HTMLElement, TextProps>(({ className, ...props }, ref) => (
6
- <Text ref={ref} as="code" className={cn("rounded bg-bg-subtle px-1.5 py-0.5 font-mono text-sm", className)} {...props} />
6
+ <Text ref={ref} as="code" className={cn("rounded-sm bg-bg-subtle px-1.5 py-0.5 font-mono text-sm", className)} {...props} />
7
7
  ));
8
8
  Code.displayName = "Code";