@sixthshift/design-system 0.7.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 (177) 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/DataTable/DataTable.d.ts +89 -0
  29. package/dist/components/DataTable/DataTable.d.ts.map +1 -0
  30. package/dist/components/DataTable/DataTable.js +107 -0
  31. package/dist/components/DataTable/DataTable.js.map +1 -0
  32. package/dist/components/DataTable/index.d.ts +2 -0
  33. package/dist/components/DataTable/index.d.ts.map +1 -0
  34. package/dist/components/DataTable/index.js +2 -0
  35. package/dist/components/DataTable/index.js.map +1 -0
  36. package/dist/components/FileDropzone/FileDropzone.d.ts +87 -0
  37. package/dist/components/FileDropzone/FileDropzone.d.ts.map +1 -0
  38. package/dist/components/FileDropzone/FileDropzone.js +146 -0
  39. package/dist/components/FileDropzone/FileDropzone.js.map +1 -0
  40. package/dist/components/FileDropzone/index.d.ts +2 -0
  41. package/dist/components/FileDropzone/index.d.ts.map +1 -0
  42. package/dist/components/FileDropzone/index.js +2 -0
  43. package/dist/components/FileDropzone/index.js.map +1 -0
  44. package/dist/components/FormField/FormField.d.ts +3 -1
  45. package/dist/components/FormField/FormField.d.ts.map +1 -1
  46. package/dist/components/FormField/FormField.js.map +1 -1
  47. package/dist/components/ImageGallery/ImageGallery.d.ts +93 -0
  48. package/dist/components/ImageGallery/ImageGallery.d.ts.map +1 -0
  49. package/dist/components/ImageGallery/ImageGallery.js +121 -0
  50. package/dist/components/ImageGallery/ImageGallery.js.map +1 -0
  51. package/dist/components/ImageGallery/index.d.ts +2 -0
  52. package/dist/components/ImageGallery/index.d.ts.map +1 -0
  53. package/dist/components/ImageGallery/index.js +2 -0
  54. package/dist/components/ImageGallery/index.js.map +1 -0
  55. package/dist/components/Input/Input.d.ts +3 -3
  56. package/dist/components/Input/Input.js +3 -3
  57. package/dist/components/Markdown/Markdown.js +1 -1
  58. package/dist/components/Markdown/Markdown.js.map +1 -1
  59. package/dist/components/NumberStepper/NumberStepper.d.ts +78 -0
  60. package/dist/components/NumberStepper/NumberStepper.d.ts.map +1 -0
  61. package/dist/components/NumberStepper/NumberStepper.js +129 -0
  62. package/dist/components/NumberStepper/NumberStepper.js.map +1 -0
  63. package/dist/components/NumberStepper/index.d.ts +2 -0
  64. package/dist/components/NumberStepper/index.d.ts.map +1 -0
  65. package/dist/components/NumberStepper/index.js +2 -0
  66. package/dist/components/NumberStepper/index.js.map +1 -0
  67. package/dist/components/ProgressBar/ProgressBar.d.ts +11 -0
  68. package/dist/components/ProgressBar/ProgressBar.d.ts.map +1 -1
  69. package/dist/components/ProgressBar/ProgressBar.js +6 -2
  70. package/dist/components/ProgressBar/ProgressBar.js.map +1 -1
  71. package/dist/components/ProgressBar/index.d.ts +1 -1
  72. package/dist/components/ProgressBar/index.d.ts.map +1 -1
  73. package/dist/components/ProgressBar/index.js.map +1 -1
  74. package/dist/components/RadioButtonGroup/RadioButtonGroup.d.ts +19 -16
  75. package/dist/components/RadioButtonGroup/RadioButtonGroup.d.ts.map +1 -1
  76. package/dist/components/RadioButtonGroup/RadioButtonGroup.js +13 -12
  77. package/dist/components/RadioButtonGroup/RadioButtonGroup.js.map +1 -1
  78. package/dist/components/SearchInput/SearchInput.d.ts +3 -2
  79. package/dist/components/SearchInput/SearchInput.d.ts.map +1 -1
  80. package/dist/components/SearchInput/SearchInput.js +13 -8
  81. package/dist/components/SearchInput/SearchInput.js.map +1 -1
  82. package/dist/components/Sparkline/Sparkline.d.ts +8 -4
  83. package/dist/components/Sparkline/Sparkline.d.ts.map +1 -1
  84. package/dist/components/Sparkline/Sparkline.js +1 -1
  85. package/dist/components/Sparkline/Sparkline.js.map +1 -1
  86. package/dist/components/Sparkline/index.d.ts +1 -1
  87. package/dist/components/Sparkline/index.d.ts.map +1 -1
  88. package/dist/components/Sparkline/index.js.map +1 -1
  89. package/dist/components/Steps/Steps.d.ts +65 -0
  90. package/dist/components/Steps/Steps.d.ts.map +1 -0
  91. package/dist/components/Steps/Steps.js +62 -0
  92. package/dist/components/Steps/Steps.js.map +1 -0
  93. package/dist/components/Steps/index.d.ts +2 -0
  94. package/dist/components/Steps/index.d.ts.map +1 -0
  95. package/dist/components/Steps/index.js +2 -0
  96. package/dist/components/Steps/index.js.map +1 -0
  97. package/dist/components/TagChip/TagChip.d.ts +0 -13
  98. package/dist/components/TagChip/TagChip.d.ts.map +1 -1
  99. package/dist/components/TagChip/TagChip.js +10 -4
  100. package/dist/components/TagChip/TagChip.js.map +1 -1
  101. package/dist/components/TextInline/TextInline.d.ts +2 -2
  102. package/dist/components/Toast/Toast.js +1 -1
  103. package/dist/components/Toast/Toast.js.map +1 -1
  104. package/dist/components/Toggle/Toggle.d.ts +29 -18
  105. package/dist/components/Toggle/Toggle.d.ts.map +1 -1
  106. package/dist/components/Toggle/Toggle.js +48 -11
  107. package/dist/components/Toggle/Toggle.js.map +1 -1
  108. package/dist/components/Toggle/index.d.ts +1 -1
  109. package/dist/components/Toggle/index.d.ts.map +1 -1
  110. package/dist/components/Toggle/index.js +1 -1
  111. package/dist/components/Toggle/index.js.map +1 -1
  112. package/dist/components/ToggleGroup/ToggleGroup.d.ts +4 -4
  113. package/dist/components/ToggleGroup/ToggleGroup.js +4 -4
  114. package/dist/components/ToggleGroup/ToggleGroupItem.d.ts +1 -1
  115. package/dist/components/ToggleGroup/ToggleGroupItem.d.ts.map +1 -1
  116. package/dist/components/ToggleGroup/ToggleGroupItem.js +37 -7
  117. package/dist/components/ToggleGroup/ToggleGroupItem.js.map +1 -1
  118. package/dist/components/ToggleGroup/ToggleGroupMultiple.d.ts +3 -3
  119. package/dist/components/ToggleGroup/ToggleGroupSingle.d.ts +3 -3
  120. package/dist/components/ToggleGroup/index.d.ts +1 -1
  121. package/dist/components/ToggleGroup/index.d.ts.map +1 -1
  122. package/dist/components/ToggleGroup/toggleGroup.types.d.ts +18 -16
  123. package/dist/components/ToggleGroup/toggleGroup.types.d.ts.map +1 -1
  124. package/dist/typography/Code.js +1 -1
  125. package/dist/typography/Code.js.map +1 -1
  126. package/package.json +22 -1
  127. package/src/components/Badge/Badge.tsx +38 -45
  128. package/src/components/Badge/badge.recipe.css +20 -101
  129. package/src/components/Badge/index.ts +0 -1
  130. package/src/components/Button/Button.tsx +57 -51
  131. package/src/components/Button/button.recipe.css +39 -122
  132. package/src/components/Button/index.ts +0 -1
  133. package/src/components/Card/Card.tsx +1 -1
  134. package/src/components/CheckboxGroup/CheckboxGroup.tsx +17 -15
  135. package/src/components/Code/Workspace/Toolbar.tsx +2 -2
  136. package/src/components/DataTable/DataTable.tsx +261 -0
  137. package/src/components/DataTable/data-table.recipe.css +28 -0
  138. package/src/components/DataTable/index.ts +10 -0
  139. package/src/components/FileDropzone/FileDropzone.tsx +239 -0
  140. package/src/components/FileDropzone/file-dropzone.recipe.css +38 -0
  141. package/src/components/FileDropzone/index.ts +1 -0
  142. package/src/components/FormField/FormField.tsx +3 -2
  143. package/src/components/ImageGallery/ImageGallery.tsx +285 -0
  144. package/src/components/ImageGallery/image-gallery.recipe.css +50 -0
  145. package/src/components/ImageGallery/index.ts +7 -0
  146. package/src/components/Input/Input.tsx +3 -3
  147. package/src/components/Markdown/Markdown.tsx +1 -1
  148. package/src/components/Message/message.recipe.css +13 -28
  149. package/src/components/NumberStepper/NumberStepper.tsx +227 -0
  150. package/src/components/NumberStepper/index.ts +1 -0
  151. package/src/components/NumberStepper/number-stepper.recipe.css +31 -0
  152. package/src/components/ProgressBar/ProgressBar.tsx +16 -4
  153. package/src/components/ProgressBar/index.ts +1 -1
  154. package/src/components/ProgressBar/progress-bar.recipe.css +29 -0
  155. package/src/components/RadioButtonGroup/RadioButtonGroup.tsx +18 -17
  156. package/src/components/SearchInput/SearchInput.tsx +34 -20
  157. package/src/components/SearchInput/search-input.recipe.css +14 -6
  158. package/src/components/Sparkline/Sparkline.tsx +9 -4
  159. package/src/components/Sparkline/index.ts +1 -1
  160. package/src/components/Steps/Steps.tsx +149 -0
  161. package/src/components/Steps/index.ts +1 -0
  162. package/src/components/Steps/steps.recipe.css +51 -0
  163. package/src/components/TagChip/TagChip.tsx +17 -8
  164. package/src/components/TagChip/tag-chip.recipe.css +12 -12
  165. package/src/components/Toast/Toast.tsx +1 -1
  166. package/src/components/Toggle/Toggle.tsx +67 -21
  167. package/src/components/Toggle/index.ts +9 -1
  168. package/src/components/Toggle/toggle.recipe.css +45 -73
  169. package/src/components/ToggleGroup/ToggleGroup.tsx +4 -4
  170. package/src/components/ToggleGroup/ToggleGroupItem.tsx +46 -11
  171. package/src/components/ToggleGroup/index.ts +9 -1
  172. package/src/components/ToggleGroup/toggle-group.recipe.css +62 -0
  173. package/src/components/ToggleGroup/toggleGroup.types.ts +18 -16
  174. package/src/theme/linen/theme.css +21 -0
  175. package/src/theming/intents.css +112 -0
  176. package/src/theming/tailwind.css +22 -1
  177. package/src/typography/Code.tsx +1 -1
@@ -1,8 +1,44 @@
1
1
  import { cn } from "@sixthshift/design-system/utils";
2
+ import { cva } from "class-variance-authority";
2
3
  import * as React from "react";
3
- import { buttonRecipe } from "../Button/Button";
4
4
  import type { ToggleGroupBaseProps, ToggleGroupOption } from "./toggleGroup.types";
5
5
 
6
+ /**
7
+ * An item's geometry. Duplicated from Button's on purpose — ToggleGroup is its
8
+ * own component and imports neither Button nor Toggle. Every colour reads a
9
+ * `--toggle-group-item-*` token from toggle-group.recipe.css.
10
+ */
11
+ const itemVariants = cva(
12
+ // One literal, deliberately — see Button.tsx for the sorter trap.
13
+ "toggle-group-item border-(color:--toggle-group-item-border) focus-visible:ring-(color:--toggle-group-item-ring) inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md bg-(--toggle-group-item-bg) font-medium text-(--toggle-group-item-fg) text-sm transition-colors hover:bg-(--toggle-group-item-bg-hovered) focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-offset-2 active:bg-(--toggle-group-item-bg-pressed) disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
14
+ {
15
+ variants: {
16
+ size: {
17
+ xs: "h-7 rounded-md px-2 text-xs",
18
+ sm: "h-8 rounded-md px-3 text-xs",
19
+ md: "h-9 px-4 py-2",
20
+ lg: "h-10 rounded-md px-8",
21
+ },
22
+ },
23
+ defaultVariants: { size: "md" },
24
+ }
25
+ );
26
+
27
+ /** The non-colour half of `variant` — border width and elevation. */
28
+ const variantStructure: Record<string, string> = {
29
+ solid: "shadow",
30
+ outline: "border shadow-xs",
31
+ ghost: "",
32
+ };
33
+
34
+ /** Squares the item at whatever size is set, and drops the horizontal padding. */
35
+ const iconOnlyGeometry: Record<string, string> = {
36
+ xs: "w-7 px-0",
37
+ sm: "w-8 px-0",
38
+ md: "w-9 px-0",
39
+ lg: "w-10 px-0",
40
+ };
41
+
6
42
  type ItemProps = React.ButtonHTMLAttributes<HTMLButtonElement> &
7
43
  Required<Pick<ToggleGroupBaseProps, "appearance" | "orientation" | "variant" | "intent" | "size" | "iconOnly">> & {
8
44
  option: ToggleGroupOption;
@@ -20,24 +56,23 @@ const ToggleGroupItem = React.forwardRef<HTMLButtonElement, ItemProps>(
20
56
  const isVertical = orientation === "vertical";
21
57
  const isSegmented = appearance === "segmented";
22
58
 
23
- // Both modes share the same base: buttonVariants + the pressed-state cells
24
- // in recipes/toggle.css. Segmented just overrides border/shadow/rounding
25
- // so items join cleanly.
26
- const recipe = buttonRecipe({ variant, intent, size, iconOnly });
27
-
59
+ // Both appearances share the same base and the pressed-state cells in
60
+ // toggle-group.recipe.css. Segmented just overrides the rounding so items
61
+ // join cleanly.
28
62
  return (
29
63
  <button
30
64
  ref={ref}
31
- {...recipe}
65
+ data-variant={variant}
66
+ data-intent={intent}
32
67
  type="button"
33
- // Same attribute Toggle renders for `pressed` — recipes/toggle.css
34
- // selects on it, so selected/unselected items pick up the same cells.
68
+ // toggle-group.recipe.css selects the selected state on this.
35
69
  data-state={selected ? "on" : "off"}
36
70
  disabled={isDisabled}
37
71
  aria-label={option.ariaLabel}
38
72
  className={cn(
39
- recipe.className,
40
- // Segmented: only override rounding (let buttonVariants handle border/color).
73
+ variantStructure[variant],
74
+ itemVariants({ size, className: iconOnly ? iconOnlyGeometry[size] : undefined }),
75
+ // Segmented: only override rounding (the variant handles border/colour).
41
76
  // Negative margin collapses double borders between outline items.
42
77
  isSegmented &&
43
78
  (isVertical
@@ -1,2 +1,10 @@
1
1
  export { ToggleGroup } from "./ToggleGroup";
2
- export type { ToggleGroupOption, ToggleGroupProps } from "./toggleGroup.types";
2
+ export type {
3
+ ToggleGroupIntent,
4
+ ToggleGroupIntentName,
5
+ ToggleGroupOption,
6
+ ToggleGroupProps,
7
+ ToggleGroupSize,
8
+ ToggleGroupVariant,
9
+ ToggleGroupVariantName,
10
+ } from "./toggleGroup.types";
@@ -0,0 +1,62 @@
1
+ /**
2
+ * ToggleGroup recipe — the component-token layer for ToggleGroup's items.
3
+ *
4
+ * Its own `--toggle-group-item-*` tokens on its own `.toggle-group-item` hook.
5
+ * The cells start as copies of Toggle's, which start as copies of Button's —
6
+ * duplicated on purpose: each is a separate component, re-pointing one does
7
+ * not reach the others, and each is free to change alone.
8
+ *
9
+ * Every cell paints with the intent slots (src/theming/intents.css). The
10
+ * selected state is `[data-state="on"]`.
11
+ *
12
+ * `@layer components` is load-bearing, not tidiness — see button.recipe.css.
13
+ */
14
+
15
+ @layer components {
16
+ /* The floor — a plain, legible item when no cell below matches. */
17
+ .toggle-group-item {
18
+ --toggle-group-item-bg: transparent;
19
+ --toggle-group-item-bg-hovered: var(--toggle-group-item-bg); /* no shift on hover */
20
+ --toggle-group-item-bg-pressed: var(--toggle-group-item-bg-hovered);
21
+ --toggle-group-item-fg: var(--fg-normal);
22
+ --toggle-group-item-border: var(--border-normal);
23
+ --toggle-group-item-ring: var(--focus-ring);
24
+ }
25
+
26
+ /* solid — a filled surface, with text read on top of it. */
27
+ .toggle-group-item[data-variant="solid"] {
28
+ --toggle-group-item-bg: var(--intent-solid-bg);
29
+ --toggle-group-item-bg-hovered: var(--intent-solid-bg-hovered);
30
+ --toggle-group-item-bg-pressed: var(--intent-solid-bg-pressed);
31
+ --toggle-group-item-fg: var(--intent-solid-fg);
32
+ }
33
+
34
+ /* outline and ghost share the family's text colour and its tint wash. */
35
+ .toggle-group-item[data-variant="outline"],
36
+ .toggle-group-item[data-variant="ghost"] {
37
+ --toggle-group-item-bg-hovered: var(--intent-tint-bg-hovered);
38
+ --toggle-group-item-bg-pressed: var(--intent-tint-bg-pressed);
39
+ --toggle-group-item-fg: var(--intent-fg);
40
+ }
41
+
42
+ /* outline alone carries a resting surface and a border. */
43
+ .toggle-group-item[data-variant="outline"] {
44
+ --toggle-group-item-bg: var(--bg-normal);
45
+ --toggle-group-item-border: var(--intent-border);
46
+ }
47
+
48
+ /* On. Every cell repeats its resting value into `-hovered`: a selected item
49
+ deliberately does not shift on hover. solid holds the fill's -pressed
50
+ step; outline and ghost hold the tint's, with its text partner. */
51
+ .toggle-group-item[data-state="on"][data-variant="solid"] {
52
+ --toggle-group-item-bg: var(--intent-solid-bg-pressed);
53
+ --toggle-group-item-bg-hovered: var(--intent-solid-bg-pressed);
54
+ }
55
+
56
+ .toggle-group-item[data-state="on"][data-variant="outline"],
57
+ .toggle-group-item[data-state="on"][data-variant="ghost"] {
58
+ --toggle-group-item-bg: var(--intent-tint-bg-pressed);
59
+ --toggle-group-item-bg-hovered: var(--intent-tint-bg-pressed);
60
+ --toggle-group-item-fg: var(--intent-tint-fg-pressed);
61
+ }
62
+ }
@@ -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";
@@ -41,6 +46,12 @@
41
46
  @import "../components/Sheet/sheet.recipe.css";
42
47
  @import "../components/Select/select.recipe.css";
43
48
  @import "../components/TagChip/tag-chip.recipe.css";
49
+ @import "../components/NumberStepper/number-stepper.recipe.css";
50
+ @import "../components/Steps/steps.recipe.css";
51
+ @import "../components/ImageGallery/image-gallery.recipe.css";
52
+ @import "../components/DataTable/data-table.recipe.css";
53
+ @import "../components/FileDropzone/file-dropzone.recipe.css";
54
+ @import "../components/ProgressBar/progress-bar.recipe.css";
44
55
 
45
56
  /* =============================================================================
46
57
  3. TAILWIND THEME
@@ -57,6 +68,16 @@
57
68
  --color-white: #ffffff;
58
69
  --color-black: #000000;
59
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
+
60
81
  /* Background */
61
82
  --color-bg-strong: var(--bg-strong);
62
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";