@charcuterie/ui 2.4.0 → 2.5.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 (60) hide show
  1. package/dist/Checkbox/Checkbox.d.ts +59 -0
  2. package/dist/Checkbox/Checkbox.d.ts.map +1 -0
  3. package/dist/Checkbox/Checkbox.js +61 -0
  4. package/dist/Checkbox/Checkbox.js.map +1 -0
  5. package/dist/Combobox/Combobox.d.ts.map +1 -1
  6. package/dist/Combobox/Combobox.js +1 -2
  7. package/dist/Combobox/Combobox.js.map +1 -1
  8. package/dist/Field/Field.d.ts.map +1 -1
  9. package/dist/Field/Field.js +12 -1
  10. package/dist/Field/Field.js.map +1 -1
  11. package/dist/Menu/Menu.d.ts +60 -2
  12. package/dist/Menu/Menu.d.ts.map +1 -1
  13. package/dist/Menu/Menu.js +58 -11
  14. package/dist/Menu/Menu.js.map +1 -1
  15. package/dist/RadioGroup/RadioGroup.d.ts +47 -0
  16. package/dist/RadioGroup/RadioGroup.d.ts.map +1 -0
  17. package/dist/RadioGroup/RadioGroup.js +114 -0
  18. package/dist/RadioGroup/RadioGroup.js.map +1 -0
  19. package/dist/RadioGroup/RadioGroupOption.d.ts +26 -0
  20. package/dist/RadioGroup/RadioGroupOption.d.ts.map +1 -0
  21. package/dist/RadioGroup/RadioGroupOption.js +52 -0
  22. package/dist/RadioGroup/RadioGroupOption.js.map +1 -0
  23. package/dist/Switch/Switch.d.ts +54 -0
  24. package/dist/Switch/Switch.d.ts.map +1 -0
  25. package/dist/Switch/Switch.js +94 -0
  26. package/dist/Switch/Switch.js.map +1 -0
  27. package/dist/index.d.ts +6 -0
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +3 -0
  30. package/dist/index.js.map +1 -1
  31. package/dist/slotWiring.d.ts +9 -7
  32. package/dist/slotWiring.d.ts.map +1 -1
  33. package/dist/slotWiring.js +10 -70
  34. package/dist/slotWiring.js.map +1 -1
  35. package/package.json +3 -3
  36. package/src/Checkbox/Checkbox.mdx +58 -0
  37. package/src/Checkbox/Checkbox.stories.tsx +100 -0
  38. package/src/Checkbox/Checkbox.test.tsx +80 -0
  39. package/src/Checkbox/Checkbox.tsx +146 -0
  40. package/src/Combobox/Combobox.stories.tsx +64 -4
  41. package/src/Combobox/Combobox.tsx +13 -1
  42. package/src/Field/Field.stories.tsx +19 -0
  43. package/src/Field/Field.test.tsx +30 -2
  44. package/src/Field/Field.tsx +13 -1
  45. package/src/Menu/Menu.stories.tsx +80 -2
  46. package/src/Menu/Menu.test.tsx +102 -0
  47. package/src/Menu/Menu.tsx +156 -17
  48. package/src/RadioGroup/RadioGroup.mdx +58 -0
  49. package/src/RadioGroup/RadioGroup.stories.tsx +130 -0
  50. package/src/RadioGroup/RadioGroup.test.tsx +191 -0
  51. package/src/RadioGroup/RadioGroup.tsx +204 -0
  52. package/src/RadioGroup/RadioGroupOption.tsx +126 -0
  53. package/src/Switch/Switch.mdx +53 -0
  54. package/src/Switch/Switch.stories.tsx +94 -0
  55. package/src/Switch/Switch.test.tsx +86 -0
  56. package/src/Switch/Switch.tsx +162 -0
  57. package/src/index.ts +9 -0
  58. package/src/slotWiring.ts +15 -107
  59. package/src/sourceRules.test.ts +11 -1
  60. package/src/tailwindCandidates.test.ts +9 -7
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RadioGroup.js","sourceRoot":"","sources":["../../src/RadioGroup/RadioGroup.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { ControlSize } from "@charcuterie/tokens";
2
+ import type { ReactNode } from "react";
3
+ import type { RadioItem } from "./RadioGroup.tsx";
4
+ export type RadioGroupOptionProps = {
5
+ isChecked: boolean;
6
+ item: RadioItem;
7
+ onChoose: (value: string) => void;
8
+ /** `RovingFocus.register` — membership of the arrow-key group. */
9
+ registerFocus: (value: string) => () => void;
10
+ /** `SinglePicker.register` — membership of the choice. */
11
+ registerSelection: (value: string) => () => void;
12
+ size: ControlSize;
13
+ tabIndex: number;
14
+ trackElement: (value: string, element: HTMLButtonElement | null) => void;
15
+ };
16
+ /**
17
+ * Its own file for the same reason `SegmentedOption` is: **both
18
+ * registrations are effects**, and an effect cannot run in a loop.
19
+ *
20
+ * The ring and the dot are two elements rather than a bordered box
21
+ * with a background, so the checked dot can be centred by the grid
22
+ * and sized independently of the ring — a filled `bg-intent-accent`
23
+ * ring with no inner dot reads as a checkbox, not a radio.
24
+ */
25
+ export declare const RadioGroupOption: ({ isChecked, item, onChoose, registerFocus, registerSelection, size, tabIndex, trackElement, }: RadioGroupOptionProps) => ReactNode;
26
+ //# sourceMappingURL=RadioGroupOption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RadioGroupOption.d.ts","sourceRoot":"","sources":["../../src/RadioGroup/RadioGroupOption.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAEjD,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,EAAE,OAAO,CAAA;IAClB,IAAI,EAAE,SAAS,CAAA;IACf,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,kEAAkE;IAClE,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,IAAI,CAAA;IAC5C,0DAA0D;IAC1D,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,IAAI,CAAA;IAChD,IAAI,EAAE,WAAW,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,CACZ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,iBAAiB,GAAG,IAAI,KAC9B,IAAI,CAAA;CACV,CAAA;AAoBD;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,GAAI,gGAS9B,qBAAqB,KAAG,SAiE1B,CAAA"}
@@ -0,0 +1,52 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect } from "react";
3
+ import { FOCUS_RING_CLASS } from "../intentStyles.js";
4
+ import { toClassName } from "../toClassName.js";
5
+ const RING_SIZE_CLASS = {
6
+ sm: "size-3.5",
7
+ md: "size-4",
8
+ lg: "size-5",
9
+ };
10
+ const DOT_SIZE_CLASS = {
11
+ sm: "size-1.5",
12
+ md: "size-2",
13
+ lg: "size-2.5",
14
+ };
15
+ const TEXT_SIZE_CLASS = {
16
+ sm: "text-sm",
17
+ md: "text-md",
18
+ lg: "text-lg",
19
+ };
20
+ /**
21
+ * Its own file for the same reason `SegmentedOption` is: **both
22
+ * registrations are effects**, and an effect cannot run in a loop.
23
+ *
24
+ * The ring and the dot are two elements rather than a bordered box
25
+ * with a background, so the checked dot can be centred by the grid
26
+ * and sized independently of the ring — a filled `bg-intent-accent`
27
+ * ring with no inner dot reads as a checkbox, not a radio.
28
+ */
29
+ export const RadioGroupOption = ({ isChecked, item, onChoose, registerFocus, registerSelection, size, tabIndex, trackElement, }) => {
30
+ const { isDisabled = false, label, value } = item;
31
+ useEffect(() => registerSelection(value), [registerSelection, value]);
32
+ useEffect(() => {
33
+ if (isDisabled) {
34
+ return;
35
+ }
36
+ return registerFocus(value);
37
+ }, [isDisabled, registerFocus, value]);
38
+ return (_jsxs("button", { "aria-checked": isChecked, className: toClassName("inline-flex cursor-pointer items-center gap-2 rounded-sm text-start transition-colors duration-(--duration-fast) ease-standard", TEXT_SIZE_CLASS[size], isDisabled
39
+ ? "cursor-not-allowed text-content-disabled"
40
+ : "text-content-secondary hover:text-content-primary", FOCUS_RING_CLASS), disabled: isDisabled, onClick: () => {
41
+ onChoose(value);
42
+ }, ref: (element) => {
43
+ trackElement(value, element);
44
+ }, role: "radio", tabIndex: tabIndex, type: "button", children: [_jsx("span", { className: toClassName("grid shrink-0 place-items-center rounded-full border transition-colors duration-(--duration-fast) ease-standard", isDisabled
45
+ ? "border-border-subtle"
46
+ : isChecked
47
+ ? "border-intent-accent-solid"
48
+ : "border-border-strong", RING_SIZE_CLASS[size]), children: _jsx("span", { className: toClassName("rounded-full transition-transform duration-(--duration-fast) ease-standard", isChecked ? "scale-100" : "scale-0", isDisabled
49
+ ? "bg-content-disabled"
50
+ : "bg-intent-accent-solid", DOT_SIZE_CLASS[size]) }) }), _jsx("span", { children: label })] }));
51
+ };
52
+ //# sourceMappingURL=RadioGroupOption.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RadioGroupOption.js","sourceRoot":"","sources":["../../src/RadioGroup/RadioGroupOption.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAmB/C,MAAM,eAAe,GAAgC;IACnD,EAAE,EAAE,UAAU;IACd,EAAE,EAAE,QAAQ;IACZ,EAAE,EAAE,QAAQ;CACb,CAAA;AAED,MAAM,cAAc,GAAgC;IAClD,EAAE,EAAE,UAAU;IACd,EAAE,EAAE,QAAQ;IACZ,EAAE,EAAE,UAAU;CACf,CAAA;AAED,MAAM,eAAe,GAAgC;IACnD,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;CACd,CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAC/B,SAAS,EACT,IAAI,EACJ,QAAQ,EACR,aAAa,EACb,iBAAiB,EACjB,IAAI,EACJ,QAAQ,EACR,YAAY,GACU,EAAa,EAAE;IACrC,MAAM,EAAE,UAAU,GAAG,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,IAAI,CAAA;IAEjD,SAAS,CACP,GAAG,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAC9B,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAC3B,CAAA;IAED,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,UAAU,EAAE,CAAC;YACf,OAAM;QACR,CAAC;QAED,OAAO,aAAa,CAAC,KAAK,CAAC,CAAA;IAC7B,CAAC,EAAE,CAAC,UAAU,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC,CAAA;IAEtC,OAAO,CAEL,kCACgB,SAAS,EACvB,SAAS,EAAE,WAAW,CACpB,gIAAgI,EAChI,eAAe,CAAC,IAAI,CAAC,EACrB,UAAU;YACR,CAAC,CAAC,0CAA0C;YAC5C,CAAC,CAAC,mDAAmD,EACvD,gBAAgB,CACjB,EACD,QAAQ,EAAE,UAAU,EACpB,OAAO,EAAE,GAAG,EAAE;YACZ,QAAQ,CAAC,KAAK,CAAC,CAAA;QACjB,CAAC,EACD,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE;YACf,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;QAC9B,CAAC,EACD,IAAI,EAAC,OAAO,EACZ,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAC,QAAQ,aAEb,eACE,SAAS,EAAE,WAAW,CACpB,iHAAiH,EACjH,UAAU;oBACR,CAAC,CAAC,sBAAsB;oBACxB,CAAC,CAAC,SAAS;wBACT,CAAC,CAAC,4BAA4B;wBAC9B,CAAC,CAAC,sBAAsB,EAC5B,eAAe,CAAC,IAAI,CAAC,CACtB,YAED,eACE,SAAS,EAAE,WAAW,CACpB,4EAA4E,EAC5E,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,EACnC,UAAU;wBACR,CAAC,CAAC,qBAAqB;wBACvB,CAAC,CAAC,wBAAwB,EAC5B,cAAc,CAAC,IAAI,CAAC,CACrB,GACD,GACG,EAEP,yBAAO,KAAK,GAAQ,IACb,CACV,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,54 @@
1
+ import type { ControlSize } from "@charcuterie/tokens";
2
+ import type { ReactNode } from "react";
3
+ export type SwitchProps = {
4
+ className?: string;
5
+ /**
6
+ * **Initial** only. The `Switch` owns it from then on — the same
7
+ * uncontrolled contract as `Checkbox` and `SegmentedControl`, so
8
+ * `onChange` reports the new state and there is no controlled
9
+ * `checked` prop to keep in step.
10
+ */
11
+ isChecked?: boolean;
12
+ isDisabled?: boolean;
13
+ /** The visible text, and the switch's accessible name. */
14
+ label: ReactNode;
15
+ onChange?: (isChecked: boolean) => void;
16
+ size?: ControlSize;
17
+ };
18
+ /**
19
+ * A boolean that takes effect the moment it is flipped — a setting,
20
+ * not a form value.
21
+ *
22
+ * A `Checkbox` and a `Switch` are the same state kind and a
23
+ * different affordance, and the split is meaning rather than looks:
24
+ * a checkbox is a value you submit ("I agree"), a switch is a state
25
+ * you toggle and live with immediately ("dark mode on"). ARIA gives
26
+ * the second its own role, and a screen reader announces "on/off"
27
+ * for a `switch` where it announces "checked/unchecked" for a
28
+ * checkbox.
29
+ *
30
+ * ### A `button role="switch"`, not an `input`
31
+ *
32
+ * The sliding track and thumb are the whole point of the affordance,
33
+ * and a `<button>` styles them without fighting a native control's
34
+ * own rendering. It carries `aria-checked`, `aria-labelledby`, and
35
+ * nothing else the browser would try to own. The value lives in
36
+ * React state seeded once from `isChecked` — the switch is the
37
+ * store, the same as the DOM is for `Checkbox`.
38
+ *
39
+ * ### The thumb is one colour, the track carries the state
40
+ *
41
+ * `bg-surface-raised` in both positions — the knob is the same object
42
+ * sliding, not two differently-painted dots, which is what the first
43
+ * cut looked like when off was `content-secondary` and on was
44
+ * `on-solid`. A themed system has no single colour that is "light" in
45
+ * both schemes, so consistency lives *within* a scheme: `surface-raised`
46
+ * is a white knob in a light one and a raised charcoal knob in a dark
47
+ * one, off and on identical either way. The **track** shows the state —
48
+ * `bg-intent-accent-solid` on, `bg-surface-sunken` with a `ring-2`
49
+ * outline off — which is where a switch's state belongs, and the ring
50
+ * gives the off track the defined edge a bare well would miss on a pale
51
+ * theme.
52
+ */
53
+ export declare const Switch: ({ className, isChecked, isDisabled, label, onChange, size, }: SwitchProps) => ReactNode;
54
+ //# sourceMappingURL=Switch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Switch.d.ts","sourceRoot":"","sources":["../../src/Switch/Switch.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMtC,MAAM,MAAM,WAAW,GAAG;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,0DAA0D;IAC1D,KAAK,EAAE,SAAS,CAAA;IAChB,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAA;IACvC,IAAI,CAAC,EAAE,WAAW,CAAA;CACnB,CAAA;AAkCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,eAAO,MAAM,MAAM,GAAI,8DAOpB,WAAW,KAAG,SA+DhB,CAAA"}
@@ -0,0 +1,94 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useUniqueId } from "@charcuterie/logic";
3
+ import { useState } from "react";
4
+ import { FOCUS_RING_CLASS } from "../intentStyles.js";
5
+ import { toClassName } from "../toClassName.js";
6
+ // Track and thumb are sized so `p-1` (4px) breathes evenly on every
7
+ // side and the thumb is centred by arithmetic, not by eye: inner
8
+ // height (track − 2·padding) equals the thumb, and the on-translate is
9
+ // (track width − 2·padding − thumb). Break one of those and the thumb
10
+ // clips an edge, which is what the first cut did.
11
+ const TRACK_SIZE_CLASS = {
12
+ sm: "h-5 w-9",
13
+ md: "h-6 w-11",
14
+ lg: "h-7 w-14",
15
+ };
16
+ const THUMB_SIZE_CLASS = {
17
+ sm: "size-3",
18
+ md: "size-4",
19
+ lg: "size-5",
20
+ };
21
+ const THUMB_ON_TRANSLATE_CLASS = {
22
+ sm: "translate-x-4",
23
+ md: "translate-x-5",
24
+ lg: "translate-x-7",
25
+ };
26
+ const TEXT_SIZE_CLASS = {
27
+ sm: "text-sm",
28
+ md: "text-md",
29
+ lg: "text-lg",
30
+ };
31
+ /**
32
+ * A boolean that takes effect the moment it is flipped — a setting,
33
+ * not a form value.
34
+ *
35
+ * A `Checkbox` and a `Switch` are the same state kind and a
36
+ * different affordance, and the split is meaning rather than looks:
37
+ * a checkbox is a value you submit ("I agree"), a switch is a state
38
+ * you toggle and live with immediately ("dark mode on"). ARIA gives
39
+ * the second its own role, and a screen reader announces "on/off"
40
+ * for a `switch` where it announces "checked/unchecked" for a
41
+ * checkbox.
42
+ *
43
+ * ### A `button role="switch"`, not an `input`
44
+ *
45
+ * The sliding track and thumb are the whole point of the affordance,
46
+ * and a `<button>` styles them without fighting a native control's
47
+ * own rendering. It carries `aria-checked`, `aria-labelledby`, and
48
+ * nothing else the browser would try to own. The value lives in
49
+ * React state seeded once from `isChecked` — the switch is the
50
+ * store, the same as the DOM is for `Checkbox`.
51
+ *
52
+ * ### The thumb is one colour, the track carries the state
53
+ *
54
+ * `bg-surface-raised` in both positions — the knob is the same object
55
+ * sliding, not two differently-painted dots, which is what the first
56
+ * cut looked like when off was `content-secondary` and on was
57
+ * `on-solid`. A themed system has no single colour that is "light" in
58
+ * both schemes, so consistency lives *within* a scheme: `surface-raised`
59
+ * is a white knob in a light one and a raised charcoal knob in a dark
60
+ * one, off and on identical either way. The **track** shows the state —
61
+ * `bg-intent-accent-solid` on, `bg-surface-sunken` with a `ring-2`
62
+ * outline off — which is where a switch's state belongs, and the ring
63
+ * gives the off track the defined edge a bare well would miss on a pale
64
+ * theme.
65
+ */
66
+ export const Switch = ({ className, isChecked = false, isDisabled = false, label, onChange, size = "md", }) => {
67
+ const [isOn, setIsOn] = useState(isChecked);
68
+ const labelId = useUniqueId();
69
+ return (_jsxs("span", { className: toClassName("inline-flex items-center gap-2 text-content-secondary select-none", TEXT_SIZE_CLASS[size], isDisabled && "text-content-disabled", className), children: [_jsx("button", { "aria-checked": isOn, "aria-labelledby": labelId, className: toClassName(
70
+ // `p-1` is the breathing room; `ring-inset` draws the off
71
+ // outline without changing the box size, so the centring
72
+ // arithmetic above stays exact.
73
+ "inline-flex shrink-0 cursor-pointer items-center rounded-full p-1 transition-colors duration-(--duration-fast) ease-standard",
74
+ // One state class, chosen by ternary — two `bg-`/`ring-`
75
+ // utilities of the same specificity do not resolve by
76
+ // class-list order, so disabled has to win as the only one
77
+ // written.
78
+ isDisabled
79
+ ? "cursor-not-allowed bg-surface-sunken ring-2 ring-border-subtle ring-inset"
80
+ : isOn
81
+ ? "bg-intent-accent-solid"
82
+ : "bg-surface-sunken ring-2 ring-border-strong ring-inset", TRACK_SIZE_CLASS[size], FOCUS_RING_CLASS), disabled: isDisabled, onClick: () => {
83
+ const isNextOn = !isOn;
84
+ setIsOn(isNextOn);
85
+ onChange?.(isNextOn);
86
+ }, role: "switch", type: "button", children: _jsx("span", { className: toClassName("rounded-full transition-transform duration-(--duration-fast) ease-standard",
87
+ // One knob, same colour off and on; disabled mutes it.
88
+ isDisabled
89
+ ? "bg-content-disabled"
90
+ : "bg-surface-raised", isOn
91
+ ? THUMB_ON_TRANSLATE_CLASS[size]
92
+ : "translate-x-0", THUMB_SIZE_CLASS[size]) }) }), _jsx("span", { id: labelId, children: label })] }));
93
+ };
94
+ //# sourceMappingURL=Switch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Switch.js","sourceRoot":"","sources":["../../src/Switch/Switch.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGhD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEhC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAkB/C,oEAAoE;AACpE,iEAAiE;AACjE,uEAAuE;AACvE,sEAAsE;AACtE,kDAAkD;AAClD,MAAM,gBAAgB,GAAgC;IACpD,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,UAAU;IACd,EAAE,EAAE,UAAU;CACf,CAAA;AAED,MAAM,gBAAgB,GAAgC;IACpD,EAAE,EAAE,QAAQ;IACZ,EAAE,EAAE,QAAQ;IACZ,EAAE,EAAE,QAAQ;CACb,CAAA;AAED,MAAM,wBAAwB,GAG1B;IACF,EAAE,EAAE,eAAe;IACnB,EAAE,EAAE,eAAe;IACnB,EAAE,EAAE,eAAe;CACpB,CAAA;AAED,MAAM,eAAe,GAAgC;IACnD,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;CACd,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,EACrB,SAAS,EACT,SAAS,GAAG,KAAK,EACjB,UAAU,GAAG,KAAK,EAClB,KAAK,EACL,QAAQ,EACR,IAAI,GAAG,IAAI,GACC,EAAa,EAAE;IAC3B,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAA;IAE3C,MAAM,OAAO,GAAG,WAAW,EAAE,CAAA;IAE7B,OAAO,CACL,gBACE,SAAS,EAAE,WAAW,CACpB,mEAAmE,EACnE,eAAe,CAAC,IAAI,CAAC,EACrB,UAAU,IAAI,uBAAuB,EACrC,SAAS,CACV,aAED,iCACgB,IAAI,qBACD,OAAO,EACxB,SAAS,EAAE,WAAW;gBACpB,0DAA0D;gBAC1D,yDAAyD;gBACzD,gCAAgC;gBAChC,8HAA8H;gBAC9H,yDAAyD;gBACzD,sDAAsD;gBACtD,2DAA2D;gBAC3D,WAAW;gBACX,UAAU;oBACR,CAAC,CAAC,2EAA2E;oBAC7E,CAAC,CAAC,IAAI;wBACJ,CAAC,CAAC,wBAAwB;wBAC1B,CAAC,CAAC,wDAAwD,EAC9D,gBAAgB,CAAC,IAAI,CAAC,EACtB,gBAAgB,CACjB,EACD,QAAQ,EAAE,UAAU,EACpB,OAAO,EAAE,GAAG,EAAE;oBACZ,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAA;oBAEtB,OAAO,CAAC,QAAQ,CAAC,CAAA;oBAEjB,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAA;gBACtB,CAAC,EACD,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,QAAQ,YAEb,eACE,SAAS,EAAE,WAAW,CACpB,4EAA4E;oBAC5E,uDAAuD;oBACvD,UAAU;wBACR,CAAC,CAAC,qBAAqB;wBACvB,CAAC,CAAC,mBAAmB,EACvB,IAAI;wBACF,CAAC,CAAC,wBAAwB,CAAC,IAAI,CAAC;wBAChC,CAAC,CAAC,eAAe,EACnB,gBAAgB,CAAC,IAAI,CAAC,CACvB,GACD,GACK,EAET,eAAM,EAAE,EAAE,OAAO,YAAG,KAAK,GAAQ,IAC5B,CACR,CAAA;AACH,CAAC,CAAA"}
package/dist/index.d.ts CHANGED
@@ -40,6 +40,8 @@ export type { ButtonProps } from "./Button/Button.tsx";
40
40
  export { Button } from "./Button/Button.tsx";
41
41
  export type { CardPadding, CardProps, CardSurface, } from "./Card/Card.tsx";
42
42
  export { Card } from "./Card/Card.tsx";
43
+ export type { CheckboxProps } from "./Checkbox/Checkbox.tsx";
44
+ export { Checkbox } from "./Checkbox/Checkbox.tsx";
43
45
  export type { ColorSchemeSwitcherProps } from "./ColorSchemeSwitcher/ColorSchemeSwitcher.tsx";
44
46
  export { ColorSchemeSwitcher } from "./ColorSchemeSwitcher/ColorSchemeSwitcher.tsx";
45
47
  export type { ColorSchemeIcons, ColorSchemeToggleProps, } from "./ColorSchemeToggle/ColorSchemeToggle.tsx";
@@ -84,6 +86,8 @@ export type { ProgressBarProps, ProgressBarSize, } from "./ProgressBar/ProgressB
84
86
  export { ProgressBar } from "./ProgressBar/ProgressBar.tsx";
85
87
  export type { ProgressThreshold } from "./ProgressBar/progressValue.ts";
86
88
  export { getProgressIntent, toProgressPercent, toProgressValue, } from "./ProgressBar/progressValue.ts";
89
+ export type { RadioGroupProps, RadioItem, } from "./RadioGroup/RadioGroup.tsx";
90
+ export { RadioGroup } from "./RadioGroup/RadioGroup.tsx";
87
91
  export type { SegmentedControlProps, SegmentedItem, } from "./SegmentedControl/SegmentedControl.tsx";
88
92
  export { SegmentedControl } from "./SegmentedControl/SegmentedControl.tsx";
89
93
  export type { SelectItem, SelectOption, SelectOptionGroup, SelectProps, } from "./Select/Select.tsx";
@@ -96,6 +100,8 @@ export type { SpinnerProps } from "./Spinner/Spinner.tsx";
96
100
  export { Spinner } from "./Spinner/Spinner.tsx";
97
101
  export type { SwatchAppearance, SwatchProps, SwatchSize, } from "./Swatch/Swatch.tsx";
98
102
  export { Swatch } from "./Swatch/Swatch.tsx";
103
+ export type { SwitchProps } from "./Switch/Switch.tsx";
104
+ export { Switch } from "./Switch/Switch.tsx";
99
105
  export type { SlotProps } from "./slotProps.ts";
100
106
  export { mergeSlotProps } from "./slotProps.ts";
101
107
  export { getAsyncIntent, getAsyncLabel, getConnectionIntent, getConnectionLabel, getIsConnectionBusy, } from "./statusIntent.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -35,6 +35,7 @@ export { Alert } from "./Alert/Alert.js";
35
35
  export { Badge } from "./Badge/Badge.js";
36
36
  export { Button } from "./Button/Button.js";
37
37
  export { Card } from "./Card/Card.js";
38
+ export { Checkbox } from "./Checkbox/Checkbox.js";
38
39
  export { ColorSchemeSwitcher } from "./ColorSchemeSwitcher/ColorSchemeSwitcher.js";
39
40
  export { ColorSchemeToggle } from "./ColorSchemeToggle/ColorSchemeToggle.js";
40
41
  export { Combobox } from "./Combobox/Combobox.js";
@@ -57,12 +58,14 @@ export { Modal } from "./Modal/Modal.js";
57
58
  export { Popover } from "./Popover/Popover.js";
58
59
  export { ProgressBar } from "./ProgressBar/ProgressBar.js";
59
60
  export { getProgressIntent, toProgressPercent, toProgressValue, } from "./ProgressBar/progressValue.js";
61
+ export { RadioGroup } from "./RadioGroup/RadioGroup.js";
60
62
  export { SegmentedControl } from "./SegmentedControl/SegmentedControl.js";
61
63
  export { Select } from "./Select/Select.js";
62
64
  export { Skeleton } from "./Skeleton/Skeleton.js";
63
65
  export { SortableTableHeader } from "./SortableTableHeader/SortableTableHeader.js";
64
66
  export { Spinner } from "./Spinner/Spinner.js";
65
67
  export { Swatch } from "./Swatch/Swatch.js";
68
+ export { Switch } from "./Switch/Switch.js";
66
69
  export { mergeSlotProps } from "./slotProps.js";
67
70
  export { getAsyncIntent, getAsyncLabel, getConnectionIntent, getConnectionLabel, getIsConnectionBusy, } from "./statusIntent.js";
68
71
  export { Tabs } from "./Tabs/Tabs.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -15,14 +15,16 @@
15
15
  * a CSS bug and is not one.
16
16
  * - **`on*`** is a listener, and listeners are plural.
17
17
  *
18
- * ### Why this is not imported from `@charcuterie/logic`
18
+ * ### Shared with `@charcuterie/logic`
19
19
  *
20
- * `useClonedChild`'s `mergeClonedProps` applies the same rule one
21
- * level down — between a slot and the element a caller wrote — and
22
- * the two are near-identical. Sharing them means a new public export
23
- * on `@charcuterie/logic`, which is a `minor`; this is a patch, and
24
- * the duplication is thirty lines against a wrong version number.
25
- * Queued in `docs/2026-08-02-reported-by-consumers-queued-for-1-1.md`.
20
+ * `useClonedChild`'s `mergeClonedProps` applies the identical rule
21
+ * one level down — between a slot and the element a caller wrote —
22
+ * so the `ref`/`on*` primitives (`mergeRefs`, `chainHandlers`, and
23
+ * the two guards) are imported from `@charcuterie/logic` rather than
24
+ * copied here, where they used to be a byte-for-byte duplicate. Only
25
+ * `mergeSlotWiring` stays local: it merges the *other* direction
26
+ * (own over received) and returns just the wiring keys, which is a
27
+ * different function from `mergeClonedProps`.
26
28
  */
27
29
  /**
28
30
  * The keys of `ownProps` that must not simply replace the ones
@@ -1 +1 @@
1
- {"version":3,"file":"slotWiring.d.ts","sourceRoot":"","sources":["../src/slotWiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAuGH;;;GAGG;AACH,eAAO,MAAM,eAAe,GAC1B,eAAe,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtC,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAChC,MAAM,CAAC,MAAM,EAAE,OAAO,CAqCtB,CAAA"}
1
+ {"version":3,"file":"slotWiring.d.ts","sourceRoot":"","sources":["../src/slotWiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AASH;;;GAGG;AACH,eAAO,MAAM,eAAe,GAC1B,eAAe,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtC,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAChC,MAAM,CAAC,MAAM,EAAE,OAAO,CAqCtB,CAAA"}
@@ -15,78 +15,18 @@
15
15
  * a CSS bug and is not one.
16
16
  * - **`on*`** is a listener, and listeners are plural.
17
17
  *
18
- * ### Why this is not imported from `@charcuterie/logic`
18
+ * ### Shared with `@charcuterie/logic`
19
19
  *
20
- * `useClonedChild`'s `mergeClonedProps` applies the same rule one
21
- * level down — between a slot and the element a caller wrote — and
22
- * the two are near-identical. Sharing them means a new public export
23
- * on `@charcuterie/logic`, which is a `minor`; this is a patch, and
24
- * the duplication is thirty lines against a wrong version number.
25
- * Queued in `docs/2026-08-02-reported-by-consumers-queued-for-1-1.md`.
20
+ * `useClonedChild`'s `mergeClonedProps` applies the identical rule
21
+ * one level down — between a slot and the element a caller wrote —
22
+ * so the `ref`/`on*` primitives (`mergeRefs`, `chainHandlers`, and
23
+ * the two guards) are imported from `@charcuterie/logic` rather than
24
+ * copied here, where they used to be a byte-for-byte duplicate. Only
25
+ * `mergeSlotWiring` stays local: it merges the *other* direction
26
+ * (own over received) and returns just the wiring keys, which is a
27
+ * different function from `mergeClonedProps`.
26
28
  */
27
- const isEventHandlerName = (name) => /^on[A-Z]/.test(name);
28
- const isMergeableRef = (value) => typeof value === "function" ||
29
- (typeof value === "object" &&
30
- value !== null &&
31
- "current" in value);
32
- const setRef = (ref, node) => {
33
- if (typeof ref === "function") {
34
- return ref(node);
35
- }
36
- ref.current = node;
37
- return undefined;
38
- };
39
- /**
40
- * Every pair of refs ever merged, so the same two always come back
41
- * as the **same function** — which is load-bearing rather than
42
- * frugal.
43
- *
44
- * React re-runs a callback ref whenever its identity changes between
45
- * renders, detaching with the old one and attaching with the new.
46
- * Both refs here are floating-ui `setReference`s, and calling one
47
- * sets state; a merged ref rebuilt every render would call both
48
- * twice per render, each call scheduling the render that rebuilds
49
- * it. `mergeSlotProps` is a plain function called during render, so
50
- * it cannot reach for `useMemo` — the memo has to be in the identity
51
- * of the inputs, which is what a `WeakMap` of `WeakMap`s is.
52
- */
53
- const mergedRefs = new WeakMap();
54
- const mergeRefs = (first, second) => {
55
- const bySecond = mergedRefs.get(first) ??
56
- new WeakMap();
57
- mergedRefs.set(first, bySecond);
58
- const cached = bySecond.get(second);
59
- if (cached) {
60
- return cached;
61
- }
62
- const merged = (node) => {
63
- const cleanups = [
64
- setRef(first, node),
65
- setRef(second, node),
66
- ];
67
- // Per ref: one that returned a cleanup has opted out of being
68
- // called with `null`, and one that did not still expects it.
69
- return () => {
70
- for (const [index, cleanup] of cleanups.entries()) {
71
- if (typeof cleanup === "function") {
72
- cleanup();
73
- }
74
- else {
75
- setRef(index === 0 ? first : second, null);
76
- }
77
- }
78
- };
79
- };
80
- bySecond.set(second, merged);
81
- return merged;
82
- };
83
- const chainHandlers = (first, second) => (...args) => {
84
- // Outer first, the same order `aria-describedby` is joined in:
85
- // the merge order is structural — whoever wrapped whom — and the
86
- // author of the nesting is the one who chose it.
87
- first(...args);
88
- second(...args);
89
- };
29
+ import { chainHandlers, isEventHandlerName, isMergeableRef, mergeRefs, } from "@charcuterie/logic";
90
30
  /**
91
31
  * The keys of `ownProps` that must not simply replace the ones
92
32
  * `receivedProps` arrived with. Spread **last**, over both.
@@ -1 +1 @@
1
- {"version":3,"file":"slotWiring.js","sourceRoot":"","sources":["../src/slotWiring.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"slotWiring.js","sourceRoot":"","sources":["../src/slotWiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,SAAS,GACV,MAAM,oBAAoB,CAAA;AAE3B;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,aAAsC,EACtC,QAAiC,EACR,EAAE,CAC3B,MAAM,CAAC,WAAW,CAChB,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAC9B,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAuB,EAAE;IACxC,MAAM,aAAa,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;IAEzC,IACE,IAAI,KAAK,KAAK;QACd,cAAc,CAAC,aAAa,CAAC;QAC7B,cAAc,CAAC,QAAQ,CAAC,EACxB,CAAC;QACD,OAAO;YACL,CAAC,IAAI,EAAE,SAAS,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;SAC3C,CAAA;IACH,CAAC;IAED,IACE,kBAAkB,CAAC,IAAI,CAAC;QACxB,OAAO,aAAa,KAAK,UAAU;QACnC,OAAO,QAAQ,KAAK,UAAU,EAC9B,CAAC;QACD,OAAO;YACL;gBACE,IAAI;gBACJ,aAAa,CACX,aAEY,EACZ,QAA2C,CAC5C;aACF;SACF,CAAA;IACH,CAAC;IAED,OAAO,EAAE,CAAA;AACX,CAAC,CACF,CACF,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@charcuterie/ui",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "The Charcuterie components. Tokens for look, @charcuterie/logic for state, ARIA that agents can actually drive.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -43,8 +43,8 @@
43
43
  "typecheck": "tsc --noEmit"
44
44
  },
45
45
  "dependencies": {
46
- "@charcuterie/logic": "1.1.0",
47
- "@charcuterie/tokens": "1.1.2",
46
+ "@charcuterie/logic": "1.2.0",
47
+ "@charcuterie/tokens": "1.1.3",
48
48
  "@floating-ui/react": "^0.27.20",
49
49
  "@tanstack/react-virtual": "^3.13.12"
50
50
  },
@@ -0,0 +1,58 @@
1
+ import { Canvas, Controls, Meta } from "@storybook/addon-docs/blocks";
2
+
3
+ import * as CheckboxStories from "./Checkbox.stories";
4
+
5
+ <Meta of={CheckboxStories} />
6
+
7
+ # Checkbox
8
+
9
+ A single boolean, on or off, that owns nothing but itself.
10
+
11
+ This is the primitive mux-magic's `BooleanField` hand-rolled because the library had no
12
+ checkbox to reach for. Its box was `bg-slate-700 border-slate-500 accent-blue-500` — three
13
+ palette colours with no light mode, the exact M6 defect the token layer exists to delete.
14
+ Here the box is `bg-surface-sunken`, its border `border-border-strong`, and the fill
15
+ `bg-intent-accent-solid`, so one control reads correctly in `daylight`, `midnight`, and on
16
+ the kiosk with no per-app override. `BooleanField` becomes a thin wrapper that binds this
17
+ to a `CommandField`.
18
+
19
+ <Canvas of={CheckboxStories.Default} />
20
+
21
+ ## Props
22
+
23
+ <Controls />
24
+
25
+ ## The `<label>` wraps the control
26
+
27
+ A checkbox reads to the **left** of its text, which is why it is not a `Field`. `Field`
28
+ stacks label above control in a `flex-col` — right for a text input, wrong for a boolean —
29
+ and stacking every checkbox in a step card (`isRecursive`, `isDryRun`, …) would double the
30
+ card's height for no gain.
31
+
32
+ Wrapping is also the one label association that needs no `for` at all: the control is a
33
+ descendant of its `<label>`, so there is no id to mint, clone, and get wrong. That is the
34
+ whole defect [`Field`](/docs/components-field--docs) exists to prevent, avoided here by
35
+ construction rather than by wiring.
36
+
37
+ <Canvas of={CheckboxStories.AllVariants} />
38
+
39
+ ## The `<input>` is the store
40
+
41
+ `defaultChecked`, not `checked`. The DOM owns a checkbox's state natively, so there is no
42
+ second copy to keep in step and no controlled round-trip — reading the value back is the
43
+ `<input>`'s job, and `onChange` reports each change to a consumer that wants to persist it.
44
+ `isChecked` seeds the first paint and nothing after.
45
+
46
+ This is the same refusal `SegmentedControl` makes about `selectedValue`: a controlled prop
47
+ is the thing this library does not have, because a control that cannot hold its own state
48
+ is a control every consumer has to hold it for.
49
+
50
+ <Canvas of={CheckboxStories.AllStates} />
51
+
52
+ ## Checkbox or `Switch`
53
+
54
+ Same state kind, different meaning. A checkbox is a value you **submit** — "delete
55
+ originals", "I agree" — and a [`Switch`](/docs/components-switch--docs) is a setting that
56
+ **takes effect the moment it is flipped**. A screen reader announces
57
+ "checked/unchecked" for one and "on/off" for the other, which is the line to hold when
58
+ choosing between them.