@sovereignfs/ui 0.41.0 → 0.45.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 (174) hide show
  1. package/dist/Accordion.module.css +3 -0
  2. package/dist/Alert.module.css +62 -0
  3. package/dist/AspectRatio.module.css +15 -0
  4. package/dist/Badge.module.css +75 -9
  5. package/dist/Breadcrumb.module.css +49 -0
  6. package/dist/Button.module.css +12 -3
  7. package/dist/ButtonGroup.module.css +29 -0
  8. package/dist/Card.module.css +6 -0
  9. package/dist/Checkbox.module.css +3 -1
  10. package/dist/Collapsible.module.css +70 -0
  11. package/dist/Combobox.module.css +122 -0
  12. package/dist/Command.module.css +80 -0
  13. package/dist/ConfirmDialog.module.css +5 -1
  14. package/dist/DataTable.module.css +28 -0
  15. package/dist/DatePicker.module.css +6 -2
  16. package/dist/Dialog.module.css +3 -0
  17. package/dist/HoverCard.module.css +3 -0
  18. package/dist/Input.module.css +6 -1
  19. package/dist/Item.module.css +70 -0
  20. package/dist/Kbd.module.css +14 -0
  21. package/dist/Label.module.css +11 -0
  22. package/dist/Marker.module.css +33 -0
  23. package/dist/Menu.module.css +8 -1
  24. package/dist/Message.module.css +99 -0
  25. package/dist/MessageScroller.module.css +54 -0
  26. package/dist/NavigationMenu.module.css +53 -0
  27. package/dist/Pagination.module.css +98 -0
  28. package/dist/Progress.module.css +20 -0
  29. package/dist/RadioGroup.module.css +88 -0
  30. package/dist/Resizable.module.css +70 -0
  31. package/dist/ScrollArea.module.css +20 -0
  32. package/dist/Select.module.css +7 -3
  33. package/dist/Slider.module.css +95 -0
  34. package/dist/Table.module.css +45 -0
  35. package/dist/Tabs.module.css +6 -1
  36. package/dist/Toggle.module.css +6 -1
  37. package/dist/Typography.module.css +47 -0
  38. package/dist/index.d.ts +617 -5
  39. package/dist/index.js +1847 -499
  40. package/dist/tokens/primitives.css +22 -8
  41. package/package.json +1 -1
  42. package/src/components/Accordion/Accordion.module.css +3 -0
  43. package/src/components/Accordion/Accordion.stories.tsx +110 -0
  44. package/src/components/Accordion/Accordion.tsx +53 -0
  45. package/src/components/Accordion/__tests__/Accordion.test.tsx +61 -0
  46. package/src/components/Alert/Alert.module.css +62 -0
  47. package/src/components/Alert/Alert.stories.tsx +96 -0
  48. package/src/components/Alert/Alert.tsx +58 -0
  49. package/src/components/Alert/__tests__/Alert.test.tsx +75 -0
  50. package/src/components/AspectRatio/AspectRatio.module.css +15 -0
  51. package/src/components/AspectRatio/AspectRatio.stories.tsx +78 -0
  52. package/src/components/AspectRatio/AspectRatio.tsx +21 -0
  53. package/src/components/AspectRatio/__tests__/AspectRatio.test.tsx +27 -0
  54. package/src/components/Badge/Badge.module.css +75 -9
  55. package/src/components/Badge/Badge.stories.tsx +109 -1
  56. package/src/components/Badge/Badge.tsx +30 -2
  57. package/src/components/Badge/__tests__/Badge.test.tsx +26 -2
  58. package/src/components/Breadcrumb/Breadcrumb.module.css +49 -0
  59. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +47 -0
  60. package/src/components/Breadcrumb/Breadcrumb.tsx +57 -0
  61. package/src/components/Breadcrumb/__tests__/Breadcrumb.test.tsx +52 -0
  62. package/src/components/Button/Button.module.css +12 -3
  63. package/src/components/Button/Button.stories.tsx +3 -2
  64. package/src/components/Button/Button.tsx +1 -1
  65. package/src/components/Button/__tests__/Button.test.tsx +10 -0
  66. package/src/components/ButtonGroup/ButtonGroup.module.css +29 -0
  67. package/src/components/ButtonGroup/ButtonGroup.stories.tsx +57 -0
  68. package/src/components/ButtonGroup/ButtonGroup.tsx +27 -0
  69. package/src/components/ButtonGroup/__tests__/ButtonGroup.test.tsx +29 -0
  70. package/src/components/Card/Card.module.css +6 -0
  71. package/src/components/Checkbox/Checkbox.module.css +3 -1
  72. package/src/components/Collapsible/Collapsible.module.css +70 -0
  73. package/src/components/Collapsible/Collapsible.stories.tsx +62 -0
  74. package/src/components/Collapsible/Collapsible.tsx +66 -0
  75. package/src/components/Collapsible/__tests__/Collapsible.test.tsx +71 -0
  76. package/src/components/Combobox/Combobox.module.css +122 -0
  77. package/src/components/Combobox/Combobox.stories.tsx +79 -0
  78. package/src/components/Combobox/Combobox.tsx +186 -0
  79. package/src/components/Combobox/__tests__/Combobox.test.tsx +158 -0
  80. package/src/components/Command/Command.module.css +80 -0
  81. package/src/components/Command/Command.stories.tsx +104 -0
  82. package/src/components/Command/Command.tsx +168 -0
  83. package/src/components/Command/__tests__/Command.test.tsx +162 -0
  84. package/src/components/ConfirmDialog/ConfirmDialog.module.css +5 -1
  85. package/src/components/ContextMenu/ContextMenu.stories.tsx +81 -0
  86. package/src/components/ContextMenu/ContextMenu.tsx +100 -0
  87. package/src/components/ContextMenu/__tests__/ContextMenu.test.tsx +87 -0
  88. package/src/components/DataTable/DataTable.module.css +28 -0
  89. package/src/components/DataTable/DataTable.stories.tsx +74 -0
  90. package/src/components/DataTable/DataTable.tsx +154 -0
  91. package/src/components/DataTable/__tests__/DataTable.test.tsx +123 -0
  92. package/src/components/DatePicker/DatePicker.module.css +6 -2
  93. package/src/components/Dialog/Dialog.module.css +3 -0
  94. package/src/components/HoverCard/HoverCard.module.css +3 -0
  95. package/src/components/HoverCard/HoverCard.stories.tsx +66 -0
  96. package/src/components/HoverCard/HoverCard.tsx +111 -0
  97. package/src/components/HoverCard/__tests__/HoverCard.test.tsx +99 -0
  98. package/src/components/Icon/icons/circle-check.tsx +21 -0
  99. package/src/components/Icon/icons/circle-x.tsx +22 -0
  100. package/src/components/Icon/icons/index.ts +8 -0
  101. package/src/components/Input/Input.module.css +6 -1
  102. package/src/components/Item/Item.module.css +70 -0
  103. package/src/components/Item/Item.stories.tsx +62 -0
  104. package/src/components/Item/Item.tsx +54 -0
  105. package/src/components/Item/__tests__/Item.test.tsx +39 -0
  106. package/src/components/Kbd/Kbd.module.css +14 -0
  107. package/src/components/Kbd/Kbd.stories.tsx +32 -0
  108. package/src/components/Kbd/Kbd.tsx +12 -0
  109. package/src/components/Kbd/__tests__/Kbd.test.tsx +14 -0
  110. package/src/components/Label/Label.module.css +11 -0
  111. package/src/components/Label/Label.stories.tsx +40 -0
  112. package/src/components/Label/Label.tsx +24 -0
  113. package/src/components/Label/__tests__/Label.test.tsx +32 -0
  114. package/src/components/Marker/Marker.module.css +33 -0
  115. package/src/components/Marker/Marker.stories.tsx +39 -0
  116. package/src/components/Marker/Marker.tsx +34 -0
  117. package/src/components/Marker/__tests__/Marker.test.tsx +23 -0
  118. package/src/components/Menu/Menu.module.css +8 -1
  119. package/src/components/Menu/Menu.tsx +30 -8
  120. package/src/components/Menubar/Menubar.stories.tsx +52 -0
  121. package/src/components/Menubar/Menubar.tsx +42 -0
  122. package/src/components/Menubar/__tests__/Menubar.test.tsx +45 -0
  123. package/src/components/Message/Message.module.css +99 -0
  124. package/src/components/Message/Message.stories.tsx +79 -0
  125. package/src/components/Message/Message.tsx +41 -0
  126. package/src/components/Message/__tests__/Message.test.tsx +46 -0
  127. package/src/components/MessageScroller/MessageScroller.module.css +54 -0
  128. package/src/components/MessageScroller/MessageScroller.stories.tsx +84 -0
  129. package/src/components/MessageScroller/MessageScroller.tsx +72 -0
  130. package/src/components/MessageScroller/__tests__/MessageScroller.test.tsx +105 -0
  131. package/src/components/NavigationMenu/NavigationMenu.module.css +53 -0
  132. package/src/components/NavigationMenu/NavigationMenu.stories.tsx +58 -0
  133. package/src/components/NavigationMenu/NavigationMenu.tsx +125 -0
  134. package/src/components/NavigationMenu/__tests__/NavigationMenu.test.tsx +93 -0
  135. package/src/components/Pagination/Pagination.module.css +98 -0
  136. package/src/components/Pagination/Pagination.stories.tsx +49 -0
  137. package/src/components/Pagination/Pagination.tsx +87 -0
  138. package/src/components/Pagination/__tests__/Pagination.test.tsx +56 -0
  139. package/src/components/Progress/Progress.module.css +20 -0
  140. package/src/components/Progress/Progress.stories.tsx +40 -0
  141. package/src/components/Progress/Progress.tsx +35 -0
  142. package/src/components/Progress/__tests__/Progress.test.tsx +31 -0
  143. package/src/components/RadioGroup/RadioGroup.module.css +88 -0
  144. package/src/components/RadioGroup/RadioGroup.stories.tsx +69 -0
  145. package/src/components/RadioGroup/RadioGroup.tsx +99 -0
  146. package/src/components/RadioGroup/__tests__/RadioGroup.test.tsx +59 -0
  147. package/src/components/Resizable/Resizable.module.css +70 -0
  148. package/src/components/Resizable/Resizable.stories.tsx +82 -0
  149. package/src/components/Resizable/Resizable.tsx +313 -0
  150. package/src/components/Resizable/__tests__/Resizable.test.tsx +128 -0
  151. package/src/components/ScrollArea/ScrollArea.module.css +20 -0
  152. package/src/components/ScrollArea/ScrollArea.stories.tsx +57 -0
  153. package/src/components/ScrollArea/ScrollArea.tsx +27 -0
  154. package/src/components/ScrollArea/__tests__/ScrollArea.test.tsx +39 -0
  155. package/src/components/Select/Select.module.css +7 -3
  156. package/src/components/Slider/Slider.module.css +95 -0
  157. package/src/components/Slider/Slider.stories.tsx +64 -0
  158. package/src/components/Slider/Slider.tsx +77 -0
  159. package/src/components/Slider/__tests__/Slider.test.tsx +45 -0
  160. package/src/components/Table/Table.module.css +45 -0
  161. package/src/components/Table/Table.stories.tsx +125 -0
  162. package/src/components/Table/Table.tsx +51 -0
  163. package/src/components/Table/__tests__/Table.test.tsx +50 -0
  164. package/src/components/Tabs/Tabs.module.css +6 -1
  165. package/src/components/Toggle/Toggle.module.css +6 -1
  166. package/src/components/Typography/Typography.module.css +47 -0
  167. package/src/components/Typography/Typography.stories.tsx +62 -0
  168. package/src/components/Typography/Typography.tsx +30 -0
  169. package/src/components/Typography/__tests__/Typography.test.tsx +34 -0
  170. package/src/index.ts +78 -1
  171. package/src/stories/DesignSystemOverview.stories.tsx +614 -2
  172. package/src/stories/MobilePatterns.stories.tsx +8 -2
  173. package/src/stories/TokenGallery.stories.tsx +112 -16
  174. package/src/tokens/primitives.css +22 -8
@@ -1,4 +1,4 @@
1
- import { useEffect, useState } from 'react';
1
+ import { useEffect, useRef, useState } from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react-vite';
3
3
 
4
4
  // ---------------------------------------------------------------------------
@@ -63,6 +63,34 @@ const RADIUS_TOKENS = [
63
63
  '--sv-radius-3xl',
64
64
  '--sv-radius-full',
65
65
  ];
66
+ // RFC 0077 — instance corner-radius presets. Base px values mirror
67
+ // primitives.css's own comments (sm 6px, md 8px, xl 12px at scale 1).
68
+ //
69
+ // Each swatch's radius is computed here in JS rather than by overriding
70
+ // --sv-radius-scale on a local wrapper and letting --sv-radius-md etc.
71
+ // recompute from it. That would be the more elegant approach, but CSS custom
72
+ // properties don't support it: a custom property that references another
73
+ // custom property inside calc() (--sv-radius-md: calc(var(--sv-radius-scale)
74
+ // * 0.5rem)) has that inner reference resolved once, at the element where
75
+ // --sv-radius-md itself is *declared* (:root in primitives.css) — not at
76
+ // wherever it's later consumed via var(). A descendant overriding
77
+ // --sv-radius-scale doesn't reach back and change --sv-radius-md's
78
+ // already-fixed value (confirmed empirically — this isn't a guess). The
79
+ // production mechanism (instance-provider.tsx) still works fine: its
80
+ // override is injected as another :root { } rule, the *same* cascade node
81
+ // primitives.css declares --sv-radius-md at, not a descendant — but a
82
+ // side-by-side, multi-preset comparison on one page has no such single
83
+ // :root to share, so the swatches below compute the resulting px directly.
84
+ const RADIUS_PRESETS = [
85
+ { preset: 'none', scale: 0 },
86
+ { preset: 'xs', scale: 0.35 },
87
+ { preset: 's', scale: 0.65 },
88
+ { preset: 'm', scale: 1 },
89
+ { preset: 'l', scale: 2.75 },
90
+ ] as const;
91
+
92
+ const RADIUS_BASE_PX = { sm: 6, md: 8, xl: 12 };
93
+
66
94
  const ICON_SIZE_TOKENS = [
67
95
  '--sv-icon-size-xs',
68
96
  '--sv-icon-size-sm',
@@ -189,6 +217,75 @@ function ScaleRow({
189
217
  );
190
218
  }
191
219
 
220
+ // Radius tokens are calc() expressions since RFC 0077 (proportional to
221
+ // --sv-radius-scale) — reading the raw custom property text now shows the
222
+ // unresolved formula (e.g. "calc(1 * 0.375rem)"), not a pixel value. Render
223
+ // the swatch, then read the browser's own computed border-radius off it
224
+ // (a real CSS property, so calc() is fully resolved) instead of ScaleRow's
225
+ // getPropertyValue text read.
226
+ function RadiusScaleRow({ token }: { token: string }) {
227
+ const ref = useRef<HTMLDivElement>(null);
228
+ const [resolved, setResolved] = useState('');
229
+ useEffect(() => {
230
+ if (ref.current) setResolved(getComputedStyle(ref.current).borderRadius);
231
+ }, []);
232
+ return (
233
+ <div style={row}>
234
+ <div
235
+ ref={ref}
236
+ style={{
237
+ width: 40,
238
+ height: 24,
239
+ background: 'var(--sv-color-accent)',
240
+ borderRadius: `var(${token})`,
241
+ flexShrink: 0,
242
+ }}
243
+ />
244
+ <span style={label}>{token}</span>
245
+ <span style={value}>{resolved}</span>
246
+ </div>
247
+ );
248
+ }
249
+
250
+ function RadiusPresetRow({ preset, scale }: { preset: string; scale: number }) {
251
+ return (
252
+ <div style={row}>
253
+ <div style={{ display: 'flex', gap: 12, alignItems: 'center', flexShrink: 0 }}>
254
+ <div
255
+ style={{
256
+ width: 56,
257
+ height: 40,
258
+ background: 'var(--sv-color-surface-sunken)',
259
+ border: '1px solid var(--sv-color-border)',
260
+ borderRadius: `${scale * RADIUS_BASE_PX.xl}px`,
261
+ }}
262
+ title="card (--sv-radius-xl)"
263
+ />
264
+ <div
265
+ style={{
266
+ width: 64,
267
+ height: 36,
268
+ background: 'var(--sv-color-accent)',
269
+ borderRadius: `${scale * RADIUS_BASE_PX.md}px`,
270
+ }}
271
+ title="button, 36px tall (--sv-radius-md)"
272
+ />
273
+ <div
274
+ style={{
275
+ width: 48,
276
+ height: 18,
277
+ background: 'var(--sv-color-accent-subtle)',
278
+ borderRadius: `${scale * RADIUS_BASE_PX.sm}px`,
279
+ }}
280
+ title="badge, 18px tall (--sv-radius-sm)"
281
+ />
282
+ </div>
283
+ <span style={label}>{preset}</span>
284
+ <span style={value}>scale {scale}</span>
285
+ </div>
286
+ );
287
+ }
288
+
192
289
  // Auto-loops so the duration/easing is visible without needing to interact —
193
290
  // same technique Dialog/Drawer use for their own open/close transition
194
291
  // (see motion.ts), just driven by a timer instead of an `open` prop.
@@ -351,21 +448,20 @@ function TokenGalleryComponent() {
351
448
 
352
449
  <Section title="Radius scale">
353
450
  {RADIUS_TOKENS.map((t) => (
354
- <ScaleRow
355
- key={t}
356
- token={t}
357
- renderPreview={(_v) => (
358
- <div
359
- style={{
360
- width: 40,
361
- height: 24,
362
- background: 'var(--sv-color-accent)',
363
- borderRadius: `var(${t})`,
364
- flexShrink: 0,
365
- }}
366
- />
367
- )}
368
- />
451
+ <RadiusScaleRow key={t} token={t} />
452
+ ))}
453
+ </Section>
454
+
455
+ <Section title="Radius presets (RFC 0077)">
456
+ <p style={{ color: 'var(--sv-color-text-muted)', fontSize: 13, marginBottom: 12 }}>
457
+ Instance-level corner-radius intensity — Console → Instance identity, or{' '}
458
+ <code>INSTANCE_RADIUS</code>. Overrides <code>--sv-radius-scale</code>; every{' '}
459
+ <code>--sv-radius-*</code> token above stays proportional to it. Note how the button
460
+ swatch clips to a full pill by L — <code>border-radius</code>&apos;s own half-height
461
+ clamp, not a separate mechanism.
462
+ </p>
463
+ {RADIUS_PRESETS.map((p) => (
464
+ <RadiusPresetRow key={p.preset} preset={p.preset} scale={p.scale} />
369
465
  ))}
370
466
  </Section>
371
467
 
@@ -83,14 +83,28 @@
83
83
  --sv-icon-size-md: 1.25rem; /* 20px — standard affordance */
84
84
  --sv-icon-size-lg: 1.5rem; /* 24px — prominent / standalone */
85
85
 
86
- /* Border radii (v3.1 spec values) */
87
- --sv-radius-sm: 0.375rem; /* 6px — badge, tag */
88
- --sv-radius-md: 0.5rem; /* 8px — button, input */
89
- --sv-radius-lg: 0.6875rem; /* 11px — sidebar icon, card */
90
- --sv-radius-xl: 0.75rem; /* 12px — card, panel */
91
- --sv-radius-2xl: 0.875rem; /* 14px — popover */
92
- --sv-radius-3xl: 1.25rem; /* 20px — bottom sheet (Drawer top corners) */
93
- --sv-radius-full: 9999px; /* pill / avatar */
86
+ /* Border radii (v3.1 spec values). --sv-radius-scale is the one
87
+ instance-controllable exception to "scale tokens are theme-stable"
88
+ (RFC 0077) — an operator's corner-radius preset (None/XS/S/M/L)
89
+ overrides it at :root via the InstanceProvider style injection
90
+ (runtime/src/instance-provider.tsx), same pipeline as --sv-color-accent.
91
+ Every corner token below is proportional to it, so a plugin author never
92
+ references --sv-radius-scale directly — they keep using --sv-radius-sm
93
+ etc. exactly as before. --sv-radius-full is deliberately NOT derived
94
+ from the scale: it's a shape token (circle/pill), not a corner-rounding
95
+ one, and stays fixed regardless of the instance preset. */
96
+ --sv-radius-scale: 1;
97
+ --sv-radius-sm: calc(var(--sv-radius-scale) * 0.375rem); /* 6px @ scale 1 — badge, tag */
98
+ --sv-radius-md: calc(var(--sv-radius-scale) * 0.5rem); /* 8px @ scale 1 — button, input */
99
+ --sv-radius-lg: calc(
100
+ var(--sv-radius-scale) * 0.6875rem
101
+ ); /* 11px @ scale 1 — sidebar icon, card */
102
+ --sv-radius-xl: calc(var(--sv-radius-scale) * 0.75rem); /* 12px @ scale 1 — card, panel */
103
+ --sv-radius-2xl: calc(var(--sv-radius-scale) * 0.875rem); /* 14px @ scale 1 — popover */
104
+ --sv-radius-3xl: calc(
105
+ var(--sv-radius-scale) * 1.25rem
106
+ ); /* 20px @ scale 1 — bottom sheet (Drawer top corners) */
107
+ --sv-radius-full: 9999px; /* pill / avatar — unaffected by --sv-radius-scale */
94
108
 
95
109
  /* Touch targets — minimum hit-area dimension for interactive controls.
96
110
  44px follows the WCAG 2.5.5 / Apple HIG / Material guideline for reliable