@viax.io/uxm 4.44.0 → 4.46.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 (31) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/studio/lib/registry/inputs/radio-group.cjs +33 -1
  3. package/dist/studio/lib/registry/inputs/radio-group.cjs.map +1 -1
  4. package/dist/studio/lib/registry/inputs/radio-group.d.ts.map +1 -1
  5. package/dist/studio/lib/registry/inputs/radio-group.js +33 -1
  6. package/dist/studio/lib/registry/inputs/radio-group.js.map +1 -1
  7. package/dist/ui/button/button.cjs +10 -10
  8. package/dist/ui/button/button.cjs.map +1 -1
  9. package/dist/ui/button/button.d.ts +20 -8
  10. package/dist/ui/button/button.d.ts.map +1 -1
  11. package/dist/ui/button/button.js +10 -10
  12. package/dist/ui/button/button.js.map +1 -1
  13. package/dist/ui/icon-button/icon-button.cjs +2 -0
  14. package/dist/ui/icon-button/icon-button.cjs.map +1 -1
  15. package/dist/ui/icon-button/icon-button.d.ts +3 -3
  16. package/dist/ui/icon-button/icon-button.d.ts.map +1 -1
  17. package/dist/ui/icon-button/icon-button.js +2 -0
  18. package/dist/ui/icon-button/icon-button.js.map +1 -1
  19. package/dist/ui/radio-group/radio-group-preview.cjs +86 -35
  20. package/dist/ui/radio-group/radio-group-preview.cjs.map +1 -1
  21. package/dist/ui/radio-group/radio-group-preview.d.ts.map +1 -1
  22. package/dist/ui/radio-group/radio-group-preview.js +87 -36
  23. package/dist/ui/radio-group/radio-group-preview.js.map +1 -1
  24. package/dist/ui/radio-group/radio-group.cjs +46 -18
  25. package/dist/ui/radio-group/radio-group.cjs.map +1 -1
  26. package/dist/ui/radio-group/radio-group.css +82 -0
  27. package/dist/ui/radio-group/radio-group.d.ts +24 -1
  28. package/dist/ui/radio-group/radio-group.d.ts.map +1 -1
  29. package/dist/ui/radio-group/radio-group.js +46 -18
  30. package/dist/ui/radio-group/radio-group.js.map +1 -1
  31. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # [4.46.0](https://github.com/viax-io/uxm/compare/v4.45.0...v4.46.0) (2026-09-22)
2
+
3
+
4
+ ### Features
5
+
6
+ * **radio-group:** add a card variant for visual single-select ([5c9aa80](https://github.com/viax-io/uxm/commit/5c9aa801bf30630b628d7c3f312ade6dffc09036)), closes [#EBEBEA](https://github.com/viax-io/uxm/issues/EBEBEA)
7
+
8
+ # [4.45.0](https://github.com/viax-io/uxm/compare/v4.44.0...v4.45.0) (2026-09-22)
9
+
10
+
11
+ ### Features
12
+
13
+ * **button,icon-button:** declare ref on the button family ([ee76076](https://github.com/viax-io/uxm/commit/ee760764465faf8054f550d816d2c188adf0bc82))
14
+
1
15
  # [4.44.0](https://github.com/viax-io/uxm/compare/v4.43.2...v4.44.0) (2026-09-22)
2
16
 
3
17
 
@@ -50,7 +50,15 @@ const radioGroupDef = {
50
50
  // Error — the circles + option labels stay neutral; the group message
51
51
  // below is the sole signal (errorColor colors it, errorMessageSize sizes it).
52
52
  { key: "errorColor", label: "Message", control: "color", defaultValue: "var(--color-danger-text)", section: "errorState", showWhen: { state: "error" } },
53
- { key: "errorMessageSize", label: "Message Size", control: "number", defaultValue: 12, min: 10, max: 16, step: 1, unit: "px", section: "errorState", showWhen: { state: "error" } }
53
+ { key: "errorMessageSize", label: "Message Size", control: "number", defaultValue: 12, min: 10, max: 16, step: 1, unit: "px", section: "errorState", showWhen: { state: "error" } },
54
+ // Card presentation — geometry only. The frame, hover and focus colours
55
+ // come from the shared `--uxm-radio-group-*` vars the row already uses, so
56
+ // a theme cannot drift between the two presentations.
57
+ { key: "cardPadding", label: "Padding", control: "number", defaultValue: 12, min: 4, max: 32, step: 2, unit: "px", section: "card", showWhen: { variant: "card" } },
58
+ { key: "cardRadius", label: "Radius", control: "slider", defaultValue: 8, min: 0, max: 20, step: 1, unit: "px", section: "card", showWhen: { variant: "card" } },
59
+ { key: "cardGap", label: "Content Gap", control: "number", defaultValue: 4, min: 0, max: 16, step: 1, unit: "px", section: "card", showWhen: { variant: "card" } },
60
+ { key: "cardBorderWidth", label: "Border Width", control: "number", defaultValue: 1, min: 1, max: 4, step: 1, unit: "px", section: "card", showWhen: { variant: "card" } },
61
+ { key: "cardBg", label: "Background", control: "color", defaultValue: "var(--color-card)", section: "card", showWhen: { variant: "card" } }
54
62
  ],
55
63
  layoutVariants: [
56
64
  {
@@ -65,6 +73,30 @@ const radioGroupDef = {
65
73
  ],
66
74
  defaultValue: "default"
67
75
  },
76
+ {
77
+ // Presentation, not state: `card` swaps the option from a
78
+ // `[circle] label` row to a selectable tile. Every colour it paints
79
+ // resolves through the same `--uxm-radio-group-*` vars the row uses, so
80
+ // the States picker above keeps meaning what it means in both.
81
+ key: "variant",
82
+ label: "Presentation",
83
+ options: [
84
+ { value: "default", label: "Row" },
85
+ { value: "card", label: "Card" }
86
+ ],
87
+ defaultValue: "default"
88
+ },
89
+ {
90
+ key: "indicator",
91
+ label: "Indicator",
92
+ options: [
93
+ { value: "hidden", label: "Frame only" },
94
+ { value: "corner", label: "Corner dot" }
95
+ ],
96
+ defaultValue: "hidden",
97
+ // Meaningless on a row, where the circle IS the control.
98
+ showWhen: { variant: "card" }
99
+ },
68
100
  {
69
101
  key: "direction",
70
102
  label: "Direction",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/studio/lib/registry/inputs/radio-group.ts"],"sourcesContent":["import type { ComponentDef } from '../../types';\n\nexport const radioGroupDef: ComponentDef = {\n id: 'radio-group',\n name: 'Radio Group',\n category: 'Inputs',\n description: 'Radio button group with multiple options. State knobs cover unselected × selected across default / hover, plus shared focus ring and disabled opacity.',\n styleProperties: [\n // Default — unselected\n { key: 'unselectedBg', label: 'Background', control: 'color', defaultValue: 'transparent', section: 'unselectedColors', showWhen: { state: 'default' } },\n { key: 'unselectedBorder', label: 'Border', control: 'color', defaultValue: 'var(--color-border)', section: 'unselectedColors', showWhen: { state: 'default' } },\n // Default — selected\n { key: 'selectedBorder', label: 'Border', control: 'color', defaultValue: 'var(--color-accent)', section: 'selectedColors', showWhen: { state: 'default' } },\n { key: 'dotColor', label: 'Dot', control: 'color', defaultValue: 'var(--color-accent)', section: 'selectedColors', showWhen: { state: 'default' } },\n // Hover — unselected\n { key: 'hoverUnselectedBg', label: 'Background', control: 'color', defaultValue: 'transparent', section: 'unselectedColors', showWhen: { state: 'hover' } },\n // text-strong, not text-muted: muted is 2.54:1 on card in light — under the 3:1 UI floor (Principle IV)\n { key: 'hoverUnselectedBorder', label: 'Border', control: 'color', defaultValue: 'var(--color-text-strong)', section: 'unselectedColors', showWhen: { state: 'hover' } },\n // Hover — selected\n { key: 'hoverSelectedBorder', label: 'Border', control: 'color', defaultValue: 'var(--color-accent-bold)', section: 'selectedColors', showWhen: { state: 'hover' } },\n { key: 'hoverDotColor', label: 'Dot', control: 'color', defaultValue: 'var(--color-accent-bold)', section: 'selectedColors', showWhen: { state: 'hover' } },\n // Focus — single shared ring color\n { key: 'focusRing', label: 'Ring Color', control: 'color', defaultValue: 'var(--color-accent)', section: 'focusState', showWhen: { state: 'focus' } },\n // Disabled — shared opacity\n { key: 'disabledOpacity', label: 'Opacity', control: 'slider', defaultValue: 0.4, min: 0.1, max: 1, step: 0.05, section: 'disabledState', showWhen: { state: 'disabled' } },\n // Shared — always visible\n { key: 'size', label: 'Size', control: 'number', defaultValue: 20, min: 14, max: 32, step: 2, unit: 'px' },\n { key: 'gap', label: 'Item Gap', control: 'number', defaultValue: 16, min: 4, max: 32, step: 4, unit: 'px' },\n // Error — the circles + option labels stay neutral; the group message\n // below is the sole signal (errorColor colors it, errorMessageSize sizes it).\n { key: 'errorColor', label: 'Message', control: 'color', defaultValue: 'var(--color-danger-text)', section: 'errorState', showWhen: { state: 'error' } },\n { key: 'errorMessageSize', label: 'Message Size', control: 'number', defaultValue: 12, min: 10, max: 16, step: 1, unit: 'px', section: 'errorState', showWhen: { state: 'error' } },\n ],\n layoutVariants: [\n {\n key: 'state',\n label: 'State',\n options: [\n { value: 'default', label: 'Default' },\n { value: 'hover', label: 'Hover' },\n { value: 'focus', label: 'Focus' },\n { value: 'disabled', label: 'Disabled' },\n { value: 'error', label: 'Error' },\n ],\n defaultValue: 'default',\n },\n {\n key: 'direction',\n label: 'Direction',\n options: [\n { value: 'vertical', label: 'Vertical' },\n { value: 'horizontal', label: 'Horizontal' },\n ],\n defaultValue: 'vertical',\n },\n ],\n events: [\n { name: 'onChange', description: 'Fires when the user picks a different radio option.', payload: '{ value: string }' },\n ],\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../src/studio/lib/registry/inputs/radio-group.ts"],"sourcesContent":["import type { ComponentDef } from '../../types';\n\nexport const radioGroupDef: ComponentDef = {\n id: 'radio-group',\n name: 'Radio Group',\n category: 'Inputs',\n description: 'Radio button group with multiple options. State knobs cover unselected × selected across default / hover, plus shared focus ring and disabled opacity.',\n styleProperties: [\n // Default — unselected\n { key: 'unselectedBg', label: 'Background', control: 'color', defaultValue: 'transparent', section: 'unselectedColors', showWhen: { state: 'default' } },\n { key: 'unselectedBorder', label: 'Border', control: 'color', defaultValue: 'var(--color-border)', section: 'unselectedColors', showWhen: { state: 'default' } },\n // Default — selected\n { key: 'selectedBorder', label: 'Border', control: 'color', defaultValue: 'var(--color-accent)', section: 'selectedColors', showWhen: { state: 'default' } },\n { key: 'dotColor', label: 'Dot', control: 'color', defaultValue: 'var(--color-accent)', section: 'selectedColors', showWhen: { state: 'default' } },\n // Hover — unselected\n { key: 'hoverUnselectedBg', label: 'Background', control: 'color', defaultValue: 'transparent', section: 'unselectedColors', showWhen: { state: 'hover' } },\n // text-strong, not text-muted: muted is 2.54:1 on card in light — under the 3:1 UI floor (Principle IV)\n { key: 'hoverUnselectedBorder', label: 'Border', control: 'color', defaultValue: 'var(--color-text-strong)', section: 'unselectedColors', showWhen: { state: 'hover' } },\n // Hover — selected\n { key: 'hoverSelectedBorder', label: 'Border', control: 'color', defaultValue: 'var(--color-accent-bold)', section: 'selectedColors', showWhen: { state: 'hover' } },\n { key: 'hoverDotColor', label: 'Dot', control: 'color', defaultValue: 'var(--color-accent-bold)', section: 'selectedColors', showWhen: { state: 'hover' } },\n // Focus — single shared ring color\n { key: 'focusRing', label: 'Ring Color', control: 'color', defaultValue: 'var(--color-accent)', section: 'focusState', showWhen: { state: 'focus' } },\n // Disabled — shared opacity\n { key: 'disabledOpacity', label: 'Opacity', control: 'slider', defaultValue: 0.4, min: 0.1, max: 1, step: 0.05, section: 'disabledState', showWhen: { state: 'disabled' } },\n // Shared — always visible\n { key: 'size', label: 'Size', control: 'number', defaultValue: 20, min: 14, max: 32, step: 2, unit: 'px' },\n { key: 'gap', label: 'Item Gap', control: 'number', defaultValue: 16, min: 4, max: 32, step: 4, unit: 'px' },\n // Error — the circles + option labels stay neutral; the group message\n // below is the sole signal (errorColor colors it, errorMessageSize sizes it).\n { key: 'errorColor', label: 'Message', control: 'color', defaultValue: 'var(--color-danger-text)', section: 'errorState', showWhen: { state: 'error' } },\n { key: 'errorMessageSize', label: 'Message Size', control: 'number', defaultValue: 12, min: 10, max: 16, step: 1, unit: 'px', section: 'errorState', showWhen: { state: 'error' } },\n // Card presentation — geometry only. The frame, hover and focus colours\n // come from the shared `--uxm-radio-group-*` vars the row already uses, so\n // a theme cannot drift between the two presentations.\n { key: 'cardPadding', label: 'Padding', control: 'number', defaultValue: 12, min: 4, max: 32, step: 2, unit: 'px', section: 'card', showWhen: { variant: 'card' } },\n { key: 'cardRadius', label: 'Radius', control: 'slider', defaultValue: 8, min: 0, max: 20, step: 1, unit: 'px', section: 'card', showWhen: { variant: 'card' } },\n { key: 'cardGap', label: 'Content Gap', control: 'number', defaultValue: 4, min: 0, max: 16, step: 1, unit: 'px', section: 'card', showWhen: { variant: 'card' } },\n { key: 'cardBorderWidth', label: 'Border Width', control: 'number', defaultValue: 1, min: 1, max: 4, step: 1, unit: 'px', section: 'card', showWhen: { variant: 'card' } },\n { key: 'cardBg', label: 'Background', control: 'color', defaultValue: 'var(--color-card)', section: 'card', showWhen: { variant: 'card' } },\n ],\n layoutVariants: [\n {\n key: 'state',\n label: 'State',\n options: [\n { value: 'default', label: 'Default' },\n { value: 'hover', label: 'Hover' },\n { value: 'focus', label: 'Focus' },\n { value: 'disabled', label: 'Disabled' },\n { value: 'error', label: 'Error' },\n ],\n defaultValue: 'default',\n },\n {\n // Presentation, not state: `card` swaps the option from a\n // `[circle] label` row to a selectable tile. Every colour it paints\n // resolves through the same `--uxm-radio-group-*` vars the row uses, so\n // the States picker above keeps meaning what it means in both.\n key: 'variant',\n label: 'Presentation',\n options: [\n { value: 'default', label: 'Row' },\n { value: 'card', label: 'Card' },\n ],\n defaultValue: 'default',\n },\n {\n key: 'indicator',\n label: 'Indicator',\n options: [\n { value: 'hidden', label: 'Frame only' },\n { value: 'corner', label: 'Corner dot' },\n ],\n defaultValue: 'hidden',\n // Meaningless on a row, where the circle IS the control.\n showWhen: { variant: 'card' },\n },\n {\n key: 'direction',\n label: 'Direction',\n options: [\n { value: 'vertical', label: 'Vertical' },\n { value: 'horizontal', label: 'Horizontal' },\n ],\n defaultValue: 'vertical',\n },\n ],\n events: [\n { name: 'onChange', description: 'Fires when the user picks a different radio option.', payload: '{ value: string }' },\n ],\n};\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"radio-group.d.ts","sourceRoot":"","sources":["../../../../../src/studio/lib/registry/inputs/radio-group.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,eAAO,MAAM,aAAa,EAAE,YAyD3B,CAAC"}
1
+ {"version":3,"file":"radio-group.d.ts","sourceRoot":"","sources":["../../../../../src/studio/lib/registry/inputs/radio-group.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,eAAO,MAAM,aAAa,EAAE,YAyF3B,CAAC"}
@@ -27,7 +27,15 @@ const radioGroupDef = {
27
27
  // Error — the circles + option labels stay neutral; the group message
28
28
  // below is the sole signal (errorColor colors it, errorMessageSize sizes it).
29
29
  { key: "errorColor", label: "Message", control: "color", defaultValue: "var(--color-danger-text)", section: "errorState", showWhen: { state: "error" } },
30
- { key: "errorMessageSize", label: "Message Size", control: "number", defaultValue: 12, min: 10, max: 16, step: 1, unit: "px", section: "errorState", showWhen: { state: "error" } }
30
+ { key: "errorMessageSize", label: "Message Size", control: "number", defaultValue: 12, min: 10, max: 16, step: 1, unit: "px", section: "errorState", showWhen: { state: "error" } },
31
+ // Card presentation — geometry only. The frame, hover and focus colours
32
+ // come from the shared `--uxm-radio-group-*` vars the row already uses, so
33
+ // a theme cannot drift between the two presentations.
34
+ { key: "cardPadding", label: "Padding", control: "number", defaultValue: 12, min: 4, max: 32, step: 2, unit: "px", section: "card", showWhen: { variant: "card" } },
35
+ { key: "cardRadius", label: "Radius", control: "slider", defaultValue: 8, min: 0, max: 20, step: 1, unit: "px", section: "card", showWhen: { variant: "card" } },
36
+ { key: "cardGap", label: "Content Gap", control: "number", defaultValue: 4, min: 0, max: 16, step: 1, unit: "px", section: "card", showWhen: { variant: "card" } },
37
+ { key: "cardBorderWidth", label: "Border Width", control: "number", defaultValue: 1, min: 1, max: 4, step: 1, unit: "px", section: "card", showWhen: { variant: "card" } },
38
+ { key: "cardBg", label: "Background", control: "color", defaultValue: "var(--color-card)", section: "card", showWhen: { variant: "card" } }
31
39
  ],
32
40
  layoutVariants: [
33
41
  {
@@ -42,6 +50,30 @@ const radioGroupDef = {
42
50
  ],
43
51
  defaultValue: "default"
44
52
  },
53
+ {
54
+ // Presentation, not state: `card` swaps the option from a
55
+ // `[circle] label` row to a selectable tile. Every colour it paints
56
+ // resolves through the same `--uxm-radio-group-*` vars the row uses, so
57
+ // the States picker above keeps meaning what it means in both.
58
+ key: "variant",
59
+ label: "Presentation",
60
+ options: [
61
+ { value: "default", label: "Row" },
62
+ { value: "card", label: "Card" }
63
+ ],
64
+ defaultValue: "default"
65
+ },
66
+ {
67
+ key: "indicator",
68
+ label: "Indicator",
69
+ options: [
70
+ { value: "hidden", label: "Frame only" },
71
+ { value: "corner", label: "Corner dot" }
72
+ ],
73
+ defaultValue: "hidden",
74
+ // Meaningless on a row, where the circle IS the control.
75
+ showWhen: { variant: "card" }
76
+ },
45
77
  {
46
78
  key: "direction",
47
79
  label: "Direction",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/studio/lib/registry/inputs/radio-group.ts"],"sourcesContent":["import type { ComponentDef } from '../../types';\n\nexport const radioGroupDef: ComponentDef = {\n id: 'radio-group',\n name: 'Radio Group',\n category: 'Inputs',\n description: 'Radio button group with multiple options. State knobs cover unselected × selected across default / hover, plus shared focus ring and disabled opacity.',\n styleProperties: [\n // Default — unselected\n { key: 'unselectedBg', label: 'Background', control: 'color', defaultValue: 'transparent', section: 'unselectedColors', showWhen: { state: 'default' } },\n { key: 'unselectedBorder', label: 'Border', control: 'color', defaultValue: 'var(--color-border)', section: 'unselectedColors', showWhen: { state: 'default' } },\n // Default — selected\n { key: 'selectedBorder', label: 'Border', control: 'color', defaultValue: 'var(--color-accent)', section: 'selectedColors', showWhen: { state: 'default' } },\n { key: 'dotColor', label: 'Dot', control: 'color', defaultValue: 'var(--color-accent)', section: 'selectedColors', showWhen: { state: 'default' } },\n // Hover — unselected\n { key: 'hoverUnselectedBg', label: 'Background', control: 'color', defaultValue: 'transparent', section: 'unselectedColors', showWhen: { state: 'hover' } },\n // text-strong, not text-muted: muted is 2.54:1 on card in light — under the 3:1 UI floor (Principle IV)\n { key: 'hoverUnselectedBorder', label: 'Border', control: 'color', defaultValue: 'var(--color-text-strong)', section: 'unselectedColors', showWhen: { state: 'hover' } },\n // Hover — selected\n { key: 'hoverSelectedBorder', label: 'Border', control: 'color', defaultValue: 'var(--color-accent-bold)', section: 'selectedColors', showWhen: { state: 'hover' } },\n { key: 'hoverDotColor', label: 'Dot', control: 'color', defaultValue: 'var(--color-accent-bold)', section: 'selectedColors', showWhen: { state: 'hover' } },\n // Focus — single shared ring color\n { key: 'focusRing', label: 'Ring Color', control: 'color', defaultValue: 'var(--color-accent)', section: 'focusState', showWhen: { state: 'focus' } },\n // Disabled — shared opacity\n { key: 'disabledOpacity', label: 'Opacity', control: 'slider', defaultValue: 0.4, min: 0.1, max: 1, step: 0.05, section: 'disabledState', showWhen: { state: 'disabled' } },\n // Shared — always visible\n { key: 'size', label: 'Size', control: 'number', defaultValue: 20, min: 14, max: 32, step: 2, unit: 'px' },\n { key: 'gap', label: 'Item Gap', control: 'number', defaultValue: 16, min: 4, max: 32, step: 4, unit: 'px' },\n // Error — the circles + option labels stay neutral; the group message\n // below is the sole signal (errorColor colors it, errorMessageSize sizes it).\n { key: 'errorColor', label: 'Message', control: 'color', defaultValue: 'var(--color-danger-text)', section: 'errorState', showWhen: { state: 'error' } },\n { key: 'errorMessageSize', label: 'Message Size', control: 'number', defaultValue: 12, min: 10, max: 16, step: 1, unit: 'px', section: 'errorState', showWhen: { state: 'error' } },\n ],\n layoutVariants: [\n {\n key: 'state',\n label: 'State',\n options: [\n { value: 'default', label: 'Default' },\n { value: 'hover', label: 'Hover' },\n { value: 'focus', label: 'Focus' },\n { value: 'disabled', label: 'Disabled' },\n { value: 'error', label: 'Error' },\n ],\n defaultValue: 'default',\n },\n {\n key: 'direction',\n label: 'Direction',\n options: [\n { value: 'vertical', label: 'Vertical' },\n { value: 'horizontal', label: 'Horizontal' },\n ],\n defaultValue: 'vertical',\n },\n ],\n events: [\n { name: 'onChange', description: 'Fires when the user picks a different radio option.', payload: '{ value: string }' },\n ],\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../src/studio/lib/registry/inputs/radio-group.ts"],"sourcesContent":["import type { ComponentDef } from '../../types';\n\nexport const radioGroupDef: ComponentDef = {\n id: 'radio-group',\n name: 'Radio Group',\n category: 'Inputs',\n description: 'Radio button group with multiple options. State knobs cover unselected × selected across default / hover, plus shared focus ring and disabled opacity.',\n styleProperties: [\n // Default — unselected\n { key: 'unselectedBg', label: 'Background', control: 'color', defaultValue: 'transparent', section: 'unselectedColors', showWhen: { state: 'default' } },\n { key: 'unselectedBorder', label: 'Border', control: 'color', defaultValue: 'var(--color-border)', section: 'unselectedColors', showWhen: { state: 'default' } },\n // Default — selected\n { key: 'selectedBorder', label: 'Border', control: 'color', defaultValue: 'var(--color-accent)', section: 'selectedColors', showWhen: { state: 'default' } },\n { key: 'dotColor', label: 'Dot', control: 'color', defaultValue: 'var(--color-accent)', section: 'selectedColors', showWhen: { state: 'default' } },\n // Hover — unselected\n { key: 'hoverUnselectedBg', label: 'Background', control: 'color', defaultValue: 'transparent', section: 'unselectedColors', showWhen: { state: 'hover' } },\n // text-strong, not text-muted: muted is 2.54:1 on card in light — under the 3:1 UI floor (Principle IV)\n { key: 'hoverUnselectedBorder', label: 'Border', control: 'color', defaultValue: 'var(--color-text-strong)', section: 'unselectedColors', showWhen: { state: 'hover' } },\n // Hover — selected\n { key: 'hoverSelectedBorder', label: 'Border', control: 'color', defaultValue: 'var(--color-accent-bold)', section: 'selectedColors', showWhen: { state: 'hover' } },\n { key: 'hoverDotColor', label: 'Dot', control: 'color', defaultValue: 'var(--color-accent-bold)', section: 'selectedColors', showWhen: { state: 'hover' } },\n // Focus — single shared ring color\n { key: 'focusRing', label: 'Ring Color', control: 'color', defaultValue: 'var(--color-accent)', section: 'focusState', showWhen: { state: 'focus' } },\n // Disabled — shared opacity\n { key: 'disabledOpacity', label: 'Opacity', control: 'slider', defaultValue: 0.4, min: 0.1, max: 1, step: 0.05, section: 'disabledState', showWhen: { state: 'disabled' } },\n // Shared — always visible\n { key: 'size', label: 'Size', control: 'number', defaultValue: 20, min: 14, max: 32, step: 2, unit: 'px' },\n { key: 'gap', label: 'Item Gap', control: 'number', defaultValue: 16, min: 4, max: 32, step: 4, unit: 'px' },\n // Error — the circles + option labels stay neutral; the group message\n // below is the sole signal (errorColor colors it, errorMessageSize sizes it).\n { key: 'errorColor', label: 'Message', control: 'color', defaultValue: 'var(--color-danger-text)', section: 'errorState', showWhen: { state: 'error' } },\n { key: 'errorMessageSize', label: 'Message Size', control: 'number', defaultValue: 12, min: 10, max: 16, step: 1, unit: 'px', section: 'errorState', showWhen: { state: 'error' } },\n // Card presentation — geometry only. The frame, hover and focus colours\n // come from the shared `--uxm-radio-group-*` vars the row already uses, so\n // a theme cannot drift between the two presentations.\n { key: 'cardPadding', label: 'Padding', control: 'number', defaultValue: 12, min: 4, max: 32, step: 2, unit: 'px', section: 'card', showWhen: { variant: 'card' } },\n { key: 'cardRadius', label: 'Radius', control: 'slider', defaultValue: 8, min: 0, max: 20, step: 1, unit: 'px', section: 'card', showWhen: { variant: 'card' } },\n { key: 'cardGap', label: 'Content Gap', control: 'number', defaultValue: 4, min: 0, max: 16, step: 1, unit: 'px', section: 'card', showWhen: { variant: 'card' } },\n { key: 'cardBorderWidth', label: 'Border Width', control: 'number', defaultValue: 1, min: 1, max: 4, step: 1, unit: 'px', section: 'card', showWhen: { variant: 'card' } },\n { key: 'cardBg', label: 'Background', control: 'color', defaultValue: 'var(--color-card)', section: 'card', showWhen: { variant: 'card' } },\n ],\n layoutVariants: [\n {\n key: 'state',\n label: 'State',\n options: [\n { value: 'default', label: 'Default' },\n { value: 'hover', label: 'Hover' },\n { value: 'focus', label: 'Focus' },\n { value: 'disabled', label: 'Disabled' },\n { value: 'error', label: 'Error' },\n ],\n defaultValue: 'default',\n },\n {\n // Presentation, not state: `card` swaps the option from a\n // `[circle] label` row to a selectable tile. Every colour it paints\n // resolves through the same `--uxm-radio-group-*` vars the row uses, so\n // the States picker above keeps meaning what it means in both.\n key: 'variant',\n label: 'Presentation',\n options: [\n { value: 'default', label: 'Row' },\n { value: 'card', label: 'Card' },\n ],\n defaultValue: 'default',\n },\n {\n key: 'indicator',\n label: 'Indicator',\n options: [\n { value: 'hidden', label: 'Frame only' },\n { value: 'corner', label: 'Corner dot' },\n ],\n defaultValue: 'hidden',\n // Meaningless on a row, where the circle IS the control.\n showWhen: { variant: 'card' },\n },\n {\n key: 'direction',\n label: 'Direction',\n options: [\n { value: 'vertical', label: 'Vertical' },\n { value: 'horizontal', label: 'Horizontal' },\n ],\n defaultValue: 'vertical',\n },\n ],\n events: [\n { name: 'onChange', description: 'Fires when the user picks a different radio option.', payload: '{ value: string }' },\n ],\n};\n"],"mappings":"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","names":[]}
@@ -27,20 +27,20 @@ __export(button_exports, {
27
27
  module.exports = __toCommonJS(button_exports);
28
28
  var import_jsx_runtime = require("react/jsx-runtime");
29
29
  var import_helpers = require("../../helpers/index.cjs");
30
- function ButtonPrimary({ className, type = "button", ...rest }) {
31
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type, className: (0, import_helpers.cn)("uxm-button-primary", className), ...rest });
30
+ function ButtonPrimary({ className, type = "button", ref, ...rest }) {
31
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { ref, type, className: (0, import_helpers.cn)("uxm-button-primary", className), ...rest });
32
32
  }
33
- function ButtonSecondary({ className, type = "button", ...rest }) {
34
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type, className: (0, import_helpers.cn)("uxm-button-secondary", className), ...rest });
33
+ function ButtonSecondary({ className, type = "button", ref, ...rest }) {
34
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { ref, type, className: (0, import_helpers.cn)("uxm-button-secondary", className), ...rest });
35
35
  }
36
- function ButtonTertiary({ className, type = "button", ...rest }) {
37
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type, className: (0, import_helpers.cn)("uxm-button-tertiary", className), ...rest });
36
+ function ButtonTertiary({ className, type = "button", ref, ...rest }) {
37
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { ref, type, className: (0, import_helpers.cn)("uxm-button-tertiary", className), ...rest });
38
38
  }
39
- function ButtonGhost({ className, type = "button", ...rest }) {
40
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type, className: (0, import_helpers.cn)("uxm-button-ghost", className), ...rest });
39
+ function ButtonGhost({ className, type = "button", ref, ...rest }) {
40
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { ref, type, className: (0, import_helpers.cn)("uxm-button-ghost", className), ...rest });
41
41
  }
42
- function ButtonDanger({ className, type = "button", ...rest }) {
43
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type, className: (0, import_helpers.cn)("uxm-button-danger", className), ...rest });
42
+ function ButtonDanger({ className, type = "button", ref, ...rest }) {
43
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { ref, type, className: (0, import_helpers.cn)("uxm-button-danger", className), ...rest });
44
44
  }
45
45
  // Annotate the CommonJS export names for ESM import in node:
46
46
  0 && (module.exports = {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/ui/button/button.tsx"],"sourcesContent":["import { cn } from '@/helpers';\n\nimport type { ButtonHTMLAttributes } from 'react';\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type -- ButtonProps is a named alias for native button attrs (no extra members needed yet); shared by all button variants.\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {}\n\nexport function ButtonPrimary({ className, type = 'button', ...rest }: ButtonProps) {\n return <button type={type} className={cn('uxm-button-primary', className)} {...rest} />;\n}\n\nexport function ButtonSecondary({ className, type = 'button', ...rest }: ButtonProps) {\n return <button type={type} className={cn('uxm-button-secondary', className)} {...rest} />;\n}\n\nexport function ButtonTertiary({ className, type = 'button', ...rest }: ButtonProps) {\n return <button type={type} className={cn('uxm-button-tertiary', className)} {...rest} />;\n}\n\nexport function ButtonGhost({ className, type = 'button', ...rest }: ButtonProps) {\n return <button type={type} className={cn('uxm-button-ghost', className)} {...rest} />;\n}\n\nexport function ButtonDanger({ className, type = 'button', ...rest }: ButtonProps) {\n return <button type={type} className={cn('uxm-button-danger', className)} {...rest} />;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQS;AART,qBAAmB;AAOZ,SAAS,cAAc,EAAE,WAAW,OAAO,UAAU,GAAG,KAAK,GAAgB;AAClF,SAAO,4CAAC,YAAO,MAAY,eAAW,mBAAG,sBAAsB,SAAS,GAAI,GAAG,MAAM;AACvF;AAEO,SAAS,gBAAgB,EAAE,WAAW,OAAO,UAAU,GAAG,KAAK,GAAgB;AACpF,SAAO,4CAAC,YAAO,MAAY,eAAW,mBAAG,wBAAwB,SAAS,GAAI,GAAG,MAAM;AACzF;AAEO,SAAS,eAAe,EAAE,WAAW,OAAO,UAAU,GAAG,KAAK,GAAgB;AACnF,SAAO,4CAAC,YAAO,MAAY,eAAW,mBAAG,uBAAuB,SAAS,GAAI,GAAG,MAAM;AACxF;AAEO,SAAS,YAAY,EAAE,WAAW,OAAO,UAAU,GAAG,KAAK,GAAgB;AAChF,SAAO,4CAAC,YAAO,MAAY,eAAW,mBAAG,oBAAoB,SAAS,GAAI,GAAG,MAAM;AACrF;AAEO,SAAS,aAAa,EAAE,WAAW,OAAO,UAAU,GAAG,KAAK,GAAgB;AACjF,SAAO,4CAAC,YAAO,MAAY,eAAW,mBAAG,qBAAqB,SAAS,GAAI,GAAG,MAAM;AACtF;","names":[]}
1
+ {"version":3,"sources":["../../../src/ui/button/button.tsx"],"sourcesContent":["import { cn } from '@/helpers';\n\nimport type { ComponentPropsWithRef } from 'react';\n\n/**\n * Native `<button>` attributes **including `ref`**, shared by every variant.\n *\n * `ComponentPropsWithRef<'button'>` rather than `ButtonHTMLAttributes`: React 19\n * passes `ref` as an ordinary prop, so it already reached the element through\n * the rest spread — but `ButtonHTMLAttributes` does not declare it, so\n * `<ButtonPrimary ref={…}>` was a type error for every TypeScript consumer even\n * though it worked at runtime. That is what blocked the buttons from being\n * `HoverTooltip` / `Popover` anchors without a wrapper element around them.\n *\n * Not `forwardRef`: 4.39 deliberately moved `Modal`'s sub-components the other\n * way, off `forwardRef` and onto React 19 ref props.\n */\nexport type ButtonProps = ComponentPropsWithRef<'button'>;\n\nexport function ButtonPrimary({ className, type = 'button', ref, ...rest }: ButtonProps) {\n return <button ref={ref} type={type} className={cn('uxm-button-primary', className)} {...rest} />;\n}\n\nexport function ButtonSecondary({ className, type = 'button', ref, ...rest }: ButtonProps) {\n return <button ref={ref} type={type} className={cn('uxm-button-secondary', className)} {...rest} />;\n}\n\nexport function ButtonTertiary({ className, type = 'button', ref, ...rest }: ButtonProps) {\n return <button ref={ref} type={type} className={cn('uxm-button-tertiary', className)} {...rest} />;\n}\n\nexport function ButtonGhost({ className, type = 'button', ref, ...rest }: ButtonProps) {\n return <button ref={ref} type={type} className={cn('uxm-button-ghost', className)} {...rest} />;\n}\n\nexport function ButtonDanger({ className, type = 'button', ref, ...rest }: ButtonProps) {\n return <button ref={ref} type={type} className={cn('uxm-button-danger', className)} {...rest} />;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBS;AApBT,qBAAmB;AAmBZ,SAAS,cAAc,EAAE,WAAW,OAAO,UAAU,KAAK,GAAG,KAAK,GAAgB;AACvF,SAAO,4CAAC,YAAO,KAAU,MAAY,eAAW,mBAAG,sBAAsB,SAAS,GAAI,GAAG,MAAM;AACjG;AAEO,SAAS,gBAAgB,EAAE,WAAW,OAAO,UAAU,KAAK,GAAG,KAAK,GAAgB;AACzF,SAAO,4CAAC,YAAO,KAAU,MAAY,eAAW,mBAAG,wBAAwB,SAAS,GAAI,GAAG,MAAM;AACnG;AAEO,SAAS,eAAe,EAAE,WAAW,OAAO,UAAU,KAAK,GAAG,KAAK,GAAgB;AACxF,SAAO,4CAAC,YAAO,KAAU,MAAY,eAAW,mBAAG,uBAAuB,SAAS,GAAI,GAAG,MAAM;AAClG;AAEO,SAAS,YAAY,EAAE,WAAW,OAAO,UAAU,KAAK,GAAG,KAAK,GAAgB;AACrF,SAAO,4CAAC,YAAO,KAAU,MAAY,eAAW,mBAAG,oBAAoB,SAAS,GAAI,GAAG,MAAM;AAC/F;AAEO,SAAS,aAAa,EAAE,WAAW,OAAO,UAAU,KAAK,GAAG,KAAK,GAAgB;AACtF,SAAO,4CAAC,YAAO,KAAU,MAAY,eAAW,mBAAG,qBAAqB,SAAS,GAAI,GAAG,MAAM;AAChG;","names":[]}
@@ -1,9 +1,21 @@
1
- import type { ButtonHTMLAttributes } from 'react';
2
- export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
3
- }
4
- export declare function ButtonPrimary({ className, type, ...rest }: ButtonProps): import("react").JSX.Element;
5
- export declare function ButtonSecondary({ className, type, ...rest }: ButtonProps): import("react").JSX.Element;
6
- export declare function ButtonTertiary({ className, type, ...rest }: ButtonProps): import("react").JSX.Element;
7
- export declare function ButtonGhost({ className, type, ...rest }: ButtonProps): import("react").JSX.Element;
8
- export declare function ButtonDanger({ className, type, ...rest }: ButtonProps): import("react").JSX.Element;
1
+ import type { ComponentPropsWithRef } from 'react';
2
+ /**
3
+ * Native `<button>` attributes **including `ref`**, shared by every variant.
4
+ *
5
+ * `ComponentPropsWithRef<'button'>` rather than `ButtonHTMLAttributes`: React 19
6
+ * passes `ref` as an ordinary prop, so it already reached the element through
7
+ * the rest spread but `ButtonHTMLAttributes` does not declare it, so
8
+ * `<ButtonPrimary ref={…}>` was a type error for every TypeScript consumer even
9
+ * though it worked at runtime. That is what blocked the buttons from being
10
+ * `HoverTooltip` / `Popover` anchors without a wrapper element around them.
11
+ *
12
+ * Not `forwardRef`: 4.39 deliberately moved `Modal`'s sub-components the other
13
+ * way, off `forwardRef` and onto React 19 ref props.
14
+ */
15
+ export type ButtonProps = ComponentPropsWithRef<'button'>;
16
+ export declare function ButtonPrimary({ className, type, ref, ...rest }: ButtonProps): import("react").JSX.Element;
17
+ export declare function ButtonSecondary({ className, type, ref, ...rest }: ButtonProps): import("react").JSX.Element;
18
+ export declare function ButtonTertiary({ className, type, ref, ...rest }: ButtonProps): import("react").JSX.Element;
19
+ export declare function ButtonGhost({ className, type, ref, ...rest }: ButtonProps): import("react").JSX.Element;
20
+ export declare function ButtonDanger({ className, type, ref, ...rest }: ButtonProps): import("react").JSX.Element;
9
21
  //# sourceMappingURL=button.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/ui/button/button.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAGlD,MAAM,WAAW,WAAY,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;CAAG;AAE/E,wBAAgB,aAAa,CAAC,EAAE,SAAS,EAAE,IAAe,EAAE,GAAG,IAAI,EAAE,EAAE,WAAW,+BAEjF;AAED,wBAAgB,eAAe,CAAC,EAAE,SAAS,EAAE,IAAe,EAAE,GAAG,IAAI,EAAE,EAAE,WAAW,+BAEnF;AAED,wBAAgB,cAAc,CAAC,EAAE,SAAS,EAAE,IAAe,EAAE,GAAG,IAAI,EAAE,EAAE,WAAW,+BAElF;AAED,wBAAgB,WAAW,CAAC,EAAE,SAAS,EAAE,IAAe,EAAE,GAAG,IAAI,EAAE,EAAE,WAAW,+BAE/E;AAED,wBAAgB,YAAY,CAAC,EAAE,SAAS,EAAE,IAAe,EAAE,GAAG,IAAI,EAAE,EAAE,WAAW,+BAEhF"}
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/ui/button/button.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAEnD;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,WAAW,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;AAE1D,wBAAgB,aAAa,CAAC,EAAE,SAAS,EAAE,IAAe,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,WAAW,+BAEtF;AAED,wBAAgB,eAAe,CAAC,EAAE,SAAS,EAAE,IAAe,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,WAAW,+BAExF;AAED,wBAAgB,cAAc,CAAC,EAAE,SAAS,EAAE,IAAe,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,WAAW,+BAEvF;AAED,wBAAgB,WAAW,CAAC,EAAE,SAAS,EAAE,IAAe,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,WAAW,+BAEpF;AAED,wBAAgB,YAAY,CAAC,EAAE,SAAS,EAAE,IAAe,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,WAAW,+BAErF"}
@@ -1,19 +1,19 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { cn } from "../../helpers/index.js";
3
- function ButtonPrimary({ className, type = "button", ...rest }) {
4
- return /* @__PURE__ */ jsx("button", { type, className: cn("uxm-button-primary", className), ...rest });
3
+ function ButtonPrimary({ className, type = "button", ref, ...rest }) {
4
+ return /* @__PURE__ */ jsx("button", { ref, type, className: cn("uxm-button-primary", className), ...rest });
5
5
  }
6
- function ButtonSecondary({ className, type = "button", ...rest }) {
7
- return /* @__PURE__ */ jsx("button", { type, className: cn("uxm-button-secondary", className), ...rest });
6
+ function ButtonSecondary({ className, type = "button", ref, ...rest }) {
7
+ return /* @__PURE__ */ jsx("button", { ref, type, className: cn("uxm-button-secondary", className), ...rest });
8
8
  }
9
- function ButtonTertiary({ className, type = "button", ...rest }) {
10
- return /* @__PURE__ */ jsx("button", { type, className: cn("uxm-button-tertiary", className), ...rest });
9
+ function ButtonTertiary({ className, type = "button", ref, ...rest }) {
10
+ return /* @__PURE__ */ jsx("button", { ref, type, className: cn("uxm-button-tertiary", className), ...rest });
11
11
  }
12
- function ButtonGhost({ className, type = "button", ...rest }) {
13
- return /* @__PURE__ */ jsx("button", { type, className: cn("uxm-button-ghost", className), ...rest });
12
+ function ButtonGhost({ className, type = "button", ref, ...rest }) {
13
+ return /* @__PURE__ */ jsx("button", { ref, type, className: cn("uxm-button-ghost", className), ...rest });
14
14
  }
15
- function ButtonDanger({ className, type = "button", ...rest }) {
16
- return /* @__PURE__ */ jsx("button", { type, className: cn("uxm-button-danger", className), ...rest });
15
+ function ButtonDanger({ className, type = "button", ref, ...rest }) {
16
+ return /* @__PURE__ */ jsx("button", { ref, type, className: cn("uxm-button-danger", className), ...rest });
17
17
  }
18
18
  export {
19
19
  ButtonDanger,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/ui/button/button.tsx"],"sourcesContent":["import { cn } from '@/helpers';\n\nimport type { ButtonHTMLAttributes } from 'react';\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type -- ButtonProps is a named alias for native button attrs (no extra members needed yet); shared by all button variants.\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {}\n\nexport function ButtonPrimary({ className, type = 'button', ...rest }: ButtonProps) {\n return <button type={type} className={cn('uxm-button-primary', className)} {...rest} />;\n}\n\nexport function ButtonSecondary({ className, type = 'button', ...rest }: ButtonProps) {\n return <button type={type} className={cn('uxm-button-secondary', className)} {...rest} />;\n}\n\nexport function ButtonTertiary({ className, type = 'button', ...rest }: ButtonProps) {\n return <button type={type} className={cn('uxm-button-tertiary', className)} {...rest} />;\n}\n\nexport function ButtonGhost({ className, type = 'button', ...rest }: ButtonProps) {\n return <button type={type} className={cn('uxm-button-ghost', className)} {...rest} />;\n}\n\nexport function ButtonDanger({ className, type = 'button', ...rest }: ButtonProps) {\n return <button type={type} className={cn('uxm-button-danger', className)} {...rest} />;\n}\n"],"mappings":"AAQS;AART,SAAS,UAAU;AAOZ,SAAS,cAAc,EAAE,WAAW,OAAO,UAAU,GAAG,KAAK,GAAgB;AAClF,SAAO,oBAAC,YAAO,MAAY,WAAW,GAAG,sBAAsB,SAAS,GAAI,GAAG,MAAM;AACvF;AAEO,SAAS,gBAAgB,EAAE,WAAW,OAAO,UAAU,GAAG,KAAK,GAAgB;AACpF,SAAO,oBAAC,YAAO,MAAY,WAAW,GAAG,wBAAwB,SAAS,GAAI,GAAG,MAAM;AACzF;AAEO,SAAS,eAAe,EAAE,WAAW,OAAO,UAAU,GAAG,KAAK,GAAgB;AACnF,SAAO,oBAAC,YAAO,MAAY,WAAW,GAAG,uBAAuB,SAAS,GAAI,GAAG,MAAM;AACxF;AAEO,SAAS,YAAY,EAAE,WAAW,OAAO,UAAU,GAAG,KAAK,GAAgB;AAChF,SAAO,oBAAC,YAAO,MAAY,WAAW,GAAG,oBAAoB,SAAS,GAAI,GAAG,MAAM;AACrF;AAEO,SAAS,aAAa,EAAE,WAAW,OAAO,UAAU,GAAG,KAAK,GAAgB;AACjF,SAAO,oBAAC,YAAO,MAAY,WAAW,GAAG,qBAAqB,SAAS,GAAI,GAAG,MAAM;AACtF;","names":[]}
1
+ {"version":3,"sources":["../../../src/ui/button/button.tsx"],"sourcesContent":["import { cn } from '@/helpers';\n\nimport type { ComponentPropsWithRef } from 'react';\n\n/**\n * Native `<button>` attributes **including `ref`**, shared by every variant.\n *\n * `ComponentPropsWithRef<'button'>` rather than `ButtonHTMLAttributes`: React 19\n * passes `ref` as an ordinary prop, so it already reached the element through\n * the rest spread — but `ButtonHTMLAttributes` does not declare it, so\n * `<ButtonPrimary ref={…}>` was a type error for every TypeScript consumer even\n * though it worked at runtime. That is what blocked the buttons from being\n * `HoverTooltip` / `Popover` anchors without a wrapper element around them.\n *\n * Not `forwardRef`: 4.39 deliberately moved `Modal`'s sub-components the other\n * way, off `forwardRef` and onto React 19 ref props.\n */\nexport type ButtonProps = ComponentPropsWithRef<'button'>;\n\nexport function ButtonPrimary({ className, type = 'button', ref, ...rest }: ButtonProps) {\n return <button ref={ref} type={type} className={cn('uxm-button-primary', className)} {...rest} />;\n}\n\nexport function ButtonSecondary({ className, type = 'button', ref, ...rest }: ButtonProps) {\n return <button ref={ref} type={type} className={cn('uxm-button-secondary', className)} {...rest} />;\n}\n\nexport function ButtonTertiary({ className, type = 'button', ref, ...rest }: ButtonProps) {\n return <button ref={ref} type={type} className={cn('uxm-button-tertiary', className)} {...rest} />;\n}\n\nexport function ButtonGhost({ className, type = 'button', ref, ...rest }: ButtonProps) {\n return <button ref={ref} type={type} className={cn('uxm-button-ghost', className)} {...rest} />;\n}\n\nexport function ButtonDanger({ className, type = 'button', ref, ...rest }: ButtonProps) {\n return <button ref={ref} type={type} className={cn('uxm-button-danger', className)} {...rest} />;\n}\n"],"mappings":"AAoBS;AApBT,SAAS,UAAU;AAmBZ,SAAS,cAAc,EAAE,WAAW,OAAO,UAAU,KAAK,GAAG,KAAK,GAAgB;AACvF,SAAO,oBAAC,YAAO,KAAU,MAAY,WAAW,GAAG,sBAAsB,SAAS,GAAI,GAAG,MAAM;AACjG;AAEO,SAAS,gBAAgB,EAAE,WAAW,OAAO,UAAU,KAAK,GAAG,KAAK,GAAgB;AACzF,SAAO,oBAAC,YAAO,KAAU,MAAY,WAAW,GAAG,wBAAwB,SAAS,GAAI,GAAG,MAAM;AACnG;AAEO,SAAS,eAAe,EAAE,WAAW,OAAO,UAAU,KAAK,GAAG,KAAK,GAAgB;AACxF,SAAO,oBAAC,YAAO,KAAU,MAAY,WAAW,GAAG,uBAAuB,SAAS,GAAI,GAAG,MAAM;AAClG;AAEO,SAAS,YAAY,EAAE,WAAW,OAAO,UAAU,KAAK,GAAG,KAAK,GAAgB;AACrF,SAAO,oBAAC,YAAO,KAAU,MAAY,WAAW,GAAG,oBAAoB,SAAS,GAAI,GAAG,MAAM;AAC/F;AAEO,SAAS,aAAa,EAAE,WAAW,OAAO,UAAU,KAAK,GAAG,KAAK,GAAgB;AACtF,SAAO,oBAAC,YAAO,KAAU,MAAY,WAAW,GAAG,qBAAqB,SAAS,GAAI,GAAG,MAAM;AAChG;","names":[]}
@@ -28,11 +28,13 @@ function IconButton({
28
28
  className,
29
29
  type = "button",
30
30
  variant = "ghost",
31
+ ref,
31
32
  ...rest
32
33
  }) {
33
34
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
34
35
  "button",
35
36
  {
37
+ ref,
36
38
  type,
37
39
  className: (0, import_helpers.cn)("uxm-icon-button", variant === "filled" && "uxm-icon-button--filled", className),
38
40
  ...rest,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/ui/icon-button/icon-button.tsx"],"sourcesContent":["import { cn } from '@/helpers';\n\nimport type { ButtonHTMLAttributes, ReactNode } from 'react';\n\nexport type IconButtonVariant = 'ghost' | 'filled';\n\nexport interface IconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n /** SVG content (use the Icon component or a raw <svg>). */\n children: ReactNode;\n /** Required for accessibility on icon-only buttons. */\n 'aria-label': string;\n /**\n * `ghost` (default) — 32px, transparent, for toolbars, row ⋮ and inline\n * chrome. `filled` — 40px, `--color-surface-alt` fill, radius 8, for a\n * standalone action (\"add\", \"create\"). `filled` is the successor of the\n * deprecated `ButtonIcon` atom and paints exactly what it painted.\n */\n variant?: IconButtonVariant;\n}\n\nexport function IconButton({\n children,\n className,\n type = 'button',\n variant = 'ghost',\n ...rest\n}: IconButtonProps) {\n return (\n <button\n type={type}\n className={cn('uxm-icon-button', variant === 'filled' && 'uxm-icon-button--filled', className)}\n {...rest}\n >\n {children}\n </button>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BI;AA5BJ,qBAAmB;AAoBZ,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,GAAG;AACL,GAAoB;AAClB,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,eAAW,mBAAG,mBAAmB,YAAY,YAAY,2BAA2B,SAAS;AAAA,MAC5F,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/ui/icon-button/icon-button.tsx"],"sourcesContent":["import { cn } from '@/helpers';\n\nimport type { ComponentPropsWithRef, ReactNode } from 'react';\n\nexport type IconButtonVariant = 'ghost' | 'filled';\n\nexport interface IconButtonProps extends ComponentPropsWithRef<'button'> {\n /** SVG content (use the Icon component or a raw <svg>). */\n children: ReactNode;\n /** Required for accessibility on icon-only buttons. */\n 'aria-label': string;\n /**\n * `ghost` (default) — 32px, transparent, for toolbars, row ⋮ and inline\n * chrome. `filled` — 40px, `--color-surface-alt` fill, radius 8, for a\n * standalone action (\"add\", \"create\"). `filled` is the successor of the\n * deprecated `ButtonIcon` atom and paints exactly what it painted.\n */\n variant?: IconButtonVariant;\n}\n\nexport function IconButton({\n children,\n className,\n type = 'button',\n variant = 'ghost',\n ref,\n ...rest\n}: IconButtonProps) {\n return (\n <button\n ref={ref}\n type={type}\n className={cn('uxm-icon-button', variant === 'filled' && 'uxm-icon-button--filled', className)}\n {...rest}\n >\n {children}\n </button>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA6BI;AA7BJ,qBAAmB;AAoBZ,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV;AAAA,EACA,GAAG;AACL,GAAoB;AAClB,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,eAAW,mBAAG,mBAAmB,YAAY,YAAY,2BAA2B,SAAS;AAAA,MAC5F,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;","names":[]}
@@ -1,6 +1,6 @@
1
- import type { ButtonHTMLAttributes, ReactNode } from 'react';
1
+ import type { ComponentPropsWithRef, ReactNode } from 'react';
2
2
  export type IconButtonVariant = 'ghost' | 'filled';
3
- export interface IconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
3
+ export interface IconButtonProps extends ComponentPropsWithRef<'button'> {
4
4
  /** SVG content (use the Icon component or a raw <svg>). */
5
5
  children: ReactNode;
6
6
  /** Required for accessibility on icon-only buttons. */
@@ -13,5 +13,5 @@ export interface IconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>
13
13
  */
14
14
  variant?: IconButtonVariant;
15
15
  }
16
- export declare function IconButton({ children, className, type, variant, ...rest }: IconButtonProps): import("react").JSX.Element;
16
+ export declare function IconButton({ children, className, type, variant, ref, ...rest }: IconButtonProps): import("react").JSX.Element;
17
17
  //# sourceMappingURL=icon-button.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"icon-button.d.ts","sourceRoot":"","sources":["../../../src/ui/icon-button/icon-button.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE7D,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEnD,MAAM,WAAW,eAAgB,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;IAC9E,2DAA2D;IAC3D,QAAQ,EAAE,SAAS,CAAC;IACpB,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B;AAED,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,EACT,IAAe,EACf,OAAiB,EACjB,GAAG,IAAI,EACR,EAAE,eAAe,+BAUjB"}
1
+ {"version":3,"file":"icon-button.d.ts","sourceRoot":"","sources":["../../../src/ui/icon-button/icon-button.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEnD,MAAM,WAAW,eAAgB,SAAQ,qBAAqB,CAAC,QAAQ,CAAC;IACtE,2DAA2D;IAC3D,QAAQ,EAAE,SAAS,CAAC;IACpB,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B;AAED,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,EACT,IAAe,EACf,OAAiB,EACjB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,eAAe,+BAWjB"}
@@ -5,11 +5,13 @@ function IconButton({
5
5
  className,
6
6
  type = "button",
7
7
  variant = "ghost",
8
+ ref,
8
9
  ...rest
9
10
  }) {
10
11
  return /* @__PURE__ */ jsx(
11
12
  "button",
12
13
  {
14
+ ref,
13
15
  type,
14
16
  className: cn("uxm-icon-button", variant === "filled" && "uxm-icon-button--filled", className),
15
17
  ...rest,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/ui/icon-button/icon-button.tsx"],"sourcesContent":["import { cn } from '@/helpers';\n\nimport type { ButtonHTMLAttributes, ReactNode } from 'react';\n\nexport type IconButtonVariant = 'ghost' | 'filled';\n\nexport interface IconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n /** SVG content (use the Icon component or a raw <svg>). */\n children: ReactNode;\n /** Required for accessibility on icon-only buttons. */\n 'aria-label': string;\n /**\n * `ghost` (default) — 32px, transparent, for toolbars, row ⋮ and inline\n * chrome. `filled` — 40px, `--color-surface-alt` fill, radius 8, for a\n * standalone action (\"add\", \"create\"). `filled` is the successor of the\n * deprecated `ButtonIcon` atom and paints exactly what it painted.\n */\n variant?: IconButtonVariant;\n}\n\nexport function IconButton({\n children,\n className,\n type = 'button',\n variant = 'ghost',\n ...rest\n}: IconButtonProps) {\n return (\n <button\n type={type}\n className={cn('uxm-icon-button', variant === 'filled' && 'uxm-icon-button--filled', className)}\n {...rest}\n >\n {children}\n </button>\n );\n}\n"],"mappings":"AA4BI;AA5BJ,SAAS,UAAU;AAoBZ,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,GAAG;AACL,GAAoB;AAClB,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW,GAAG,mBAAmB,YAAY,YAAY,2BAA2B,SAAS;AAAA,MAC5F,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/ui/icon-button/icon-button.tsx"],"sourcesContent":["import { cn } from '@/helpers';\n\nimport type { ComponentPropsWithRef, ReactNode } from 'react';\n\nexport type IconButtonVariant = 'ghost' | 'filled';\n\nexport interface IconButtonProps extends ComponentPropsWithRef<'button'> {\n /** SVG content (use the Icon component or a raw <svg>). */\n children: ReactNode;\n /** Required for accessibility on icon-only buttons. */\n 'aria-label': string;\n /**\n * `ghost` (default) — 32px, transparent, for toolbars, row ⋮ and inline\n * chrome. `filled` — 40px, `--color-surface-alt` fill, radius 8, for a\n * standalone action (\"add\", \"create\"). `filled` is the successor of the\n * deprecated `ButtonIcon` atom and paints exactly what it painted.\n */\n variant?: IconButtonVariant;\n}\n\nexport function IconButton({\n children,\n className,\n type = 'button',\n variant = 'ghost',\n ref,\n ...rest\n}: IconButtonProps) {\n return (\n <button\n ref={ref}\n type={type}\n className={cn('uxm-icon-button', variant === 'filled' && 'uxm-icon-button--filled', className)}\n {...rest}\n >\n {children}\n </button>\n );\n}\n"],"mappings":"AA6BI;AA7BJ,SAAS,UAAU;AAoBZ,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV;AAAA,EACA,GAAG;AACL,GAAoB;AAClB,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,WAAW,GAAG,mBAAmB,YAAY,YAAY,2BAA2B,SAAS;AAAA,MAC5F,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;","names":[]}
@@ -27,16 +27,80 @@ function ShowcaseRow({
27
27
  selected,
28
28
  state,
29
29
  styles,
30
- label
30
+ label,
31
+ variant,
32
+ indicator
31
33
  }) {
32
34
  const isHover = state === "hover";
33
35
  const isFocus = state === "focus";
34
36
  const isDisabled = state === "disabled";
37
+ const isCard = variant === "card";
35
38
  const bg = isHover ? styles.hoverUnselectedBg : styles.unselectedBg;
36
39
  const border = isHover ? selected ? styles.hoverSelectedBorder : styles.hoverUnselectedBorder : selected ? styles.selectedBorder : styles.unselectedBorder;
37
40
  const dot = isHover ? styles.hoverDotColor : styles.dotColor;
38
41
  const ring = styles.focusRing;
39
42
  const size = styles.size ?? 20;
43
+ const circle = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
44
+ "span",
45
+ {
46
+ "aria-hidden": "true",
47
+ style: {
48
+ width: size,
49
+ height: size,
50
+ flexShrink: 0,
51
+ borderRadius: "50%",
52
+ border: `2px solid ${border}`,
53
+ backgroundColor: bg,
54
+ display: "inline-flex",
55
+ alignItems: "center",
56
+ justifyContent: "center",
57
+ transition: "border-color 0.15s, background-color 0.15s",
58
+ ...isFocus && !isCard ? { outline: `2px solid ${ring}`, outlineOffset: 2 } : {},
59
+ ...isCard ? { position: "absolute", top: styles.cardPadding, right: styles.cardPadding } : {}
60
+ },
61
+ children: selected && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
62
+ "span",
63
+ {
64
+ style: {
65
+ width: size * 0.5,
66
+ height: size * 0.5,
67
+ borderRadius: "50%",
68
+ backgroundColor: dot
69
+ }
70
+ }
71
+ )
72
+ }
73
+ );
74
+ if (isCard) {
75
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
76
+ "div",
77
+ {
78
+ style: {
79
+ position: "relative",
80
+ display: "flex",
81
+ flexDirection: "column",
82
+ gap: styles.cardGap,
83
+ minWidth: 150,
84
+ boxSizing: "border-box",
85
+ padding: styles.cardPadding,
86
+ borderRadius: styles.cardRadius,
87
+ border: `${styles.cardBorderWidth}px solid ${border}`,
88
+ backgroundColor: styles.cardBg,
89
+ fontSize: 14,
90
+ color: "var(--color-text)",
91
+ opacity: isDisabled ? styles.disabledOpacity ?? 0.4 : 1,
92
+ cursor: isDisabled ? "not-allowed" : "pointer",
93
+ transition: "border-color 0.15s, background-color 0.15s",
94
+ ...isFocus ? { outline: `2px solid ${ring}`, outlineOffset: 2 } : {}
95
+ },
96
+ children: [
97
+ indicator === "corner" && circle,
98
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: label }),
99
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "var(--color-text-muted)", fontSize: 12 }, children: "What this option does" })
100
+ ]
101
+ }
102
+ );
103
+ }
40
104
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
41
105
  "div",
42
106
  {
@@ -50,36 +114,7 @@ function ShowcaseRow({
50
114
  cursor: isDisabled ? "not-allowed" : "pointer"
51
115
  },
52
116
  children: [
53
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
54
- "span",
55
- {
56
- "aria-hidden": "true",
57
- style: {
58
- width: size,
59
- height: size,
60
- flexShrink: 0,
61
- borderRadius: "50%",
62
- border: `2px solid ${border}`,
63
- backgroundColor: bg,
64
- display: "inline-flex",
65
- alignItems: "center",
66
- justifyContent: "center",
67
- transition: "border-color 0.15s, background-color 0.15s",
68
- ...isFocus ? { outline: `2px solid ${ring}`, outlineOffset: 2 } : {}
69
- },
70
- children: selected && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
71
- "span",
72
- {
73
- style: {
74
- width: size * 0.5,
75
- height: size * 0.5,
76
- borderRadius: "50%",
77
- backgroundColor: dot
78
- }
79
- }
80
- )
81
- }
82
- ),
117
+ circle,
83
118
  label
84
119
  ]
85
120
  }
@@ -89,6 +124,8 @@ const INTERACTIVE_OPTIONS = ["Small", "Medium", "Large"];
89
124
  function RadioGroupPreview({ styles, variants }) {
90
125
  const state = variants.state ?? "default";
91
126
  const direction = variants.direction ?? "vertical";
127
+ const variant = variants.variant ?? "default";
128
+ const indicator = variants.indicator ?? "hidden";
92
129
  const cssVars = {
93
130
  "--uxm-radio-group-size": styles.size != null ? `${styles.size}px` : void 0,
94
131
  "--uxm-radio-group-gap": styles.gap != null ? `${styles.gap}px` : void 0,
@@ -103,7 +140,12 @@ function RadioGroupPreview({ styles, variants }) {
103
140
  "--uxm-radio-group-focus-ring": styles.focusRing,
104
141
  "--uxm-radio-group-disabled-opacity": styles.disabledOpacity != null ? String(styles.disabledOpacity) : void 0,
105
142
  "--uxm-radio-group-error-color": styles.errorColor,
106
- "--uxm-radio-group-error-message-size": styles.errorMessageSize != null ? `${styles.errorMessageSize}px` : void 0
143
+ "--uxm-radio-group-error-message-size": styles.errorMessageSize != null ? `${styles.errorMessageSize}px` : void 0,
144
+ "--uxm-radio-card-padding": `${styles.cardPadding}px`,
145
+ "--uxm-radio-card-radius": `${styles.cardRadius}px`,
146
+ "--uxm-radio-card-gap": `${styles.cardGap}px`,
147
+ "--uxm-radio-card-border-width": `${styles.cardBorderWidth}px`,
148
+ "--uxm-radio-card-bg": styles.cardBg
107
149
  };
108
150
  const sectionLabel = {
109
151
  fontSize: 11,
@@ -121,8 +163,8 @@ function RadioGroupPreview({ styles, variants }) {
121
163
  " state"
122
164
  ] }),
123
165
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 16 }, children: [
124
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShowcaseRow, { selected: false, state, styles, label: "Unselected" }),
125
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShowcaseRow, { selected: true, state, styles, label: "Selected" })
166
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShowcaseRow, { selected: false, state, styles, label: "Unselected", variant, indicator }),
167
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShowcaseRow, { selected: true, state, styles, label: "Selected", variant, indicator })
126
168
  ] })
127
169
  ] }),
128
170
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { borderTop: "1px solid var(--color-border)", paddingTop: 16 }, children: [
@@ -132,6 +174,8 @@ function RadioGroupPreview({ styles, variants }) {
132
174
  {
133
175
  name: `uxm-radio-preview-${interactiveKey}`,
134
176
  direction,
177
+ variant,
178
+ indicator,
135
179
  error: state === "error" ? "Pick an option to continue" : void 0,
136
180
  children: INTERACTIVE_OPTIONS.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
137
181
  import_ui.RadioOption,
@@ -139,7 +183,14 @@ function RadioGroupPreview({ styles, variants }) {
139
183
  name: `uxm-radio-preview-${interactiveKey}`,
140
184
  value: opt,
141
185
  disabled: interactiveDisabled,
142
- children: opt
186
+ children: variant === "card" ? (
187
+ // Card mode is for rich content — a one-word label in a tile
188
+ // would demo a box, not the shape the variant exists for.
189
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
190
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: opt }),
191
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "var(--color-text-muted)", fontSize: 12 }, children: "What this option does" })
192
+ ] })
193
+ ) : opt
143
194
  },
144
195
  opt
145
196
  ))