@signal9/era-ui 30.8.0 → 32.0.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 (116) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/ai/artifact/artifact.svelte +1 -1
  3. package/dist/ai/conversations/conversations-item.svelte +1 -1
  4. package/dist/ai/plan/plan-header.svelte +1 -1
  5. package/dist/ai/prompt-input/prompt-input-attachments.svelte +2 -6
  6. package/dist/ai/swarm/swarm-node.svelte +1 -1
  7. package/dist/ai/todo/todo-header.svelte +1 -1
  8. package/dist/ai/todo/todo-item.svelte +1 -1
  9. package/dist/ai/tool/tool-chip.svelte +1 -1
  10. package/dist/ai/web-preview/web-preview.svelte +2 -2
  11. package/dist/ai/workflow/node.svelte +1 -1
  12. package/dist/dev/audit/audits/wall-is-isotropic.js +1 -1
  13. package/dist/docs/css-utilities.js +9 -5
  14. package/dist/era-ui.css +1 -1
  15. package/dist/generated-docs/badge.md +1 -1
  16. package/dist/generated-docs/bar.md +22 -4
  17. package/dist/generated-docs/button.md +38 -4
  18. package/dist/generated-docs/card.md +35 -5
  19. package/dist/generated-docs/chip.md +16 -0
  20. package/dist/generated-docs/llms-full.txt +370 -70
  21. package/dist/generated-docs/llms.txt +8 -4
  22. package/dist/generated-docs/manifest.json +85 -28
  23. package/dist/generated-docs/meter.md +79 -1
  24. package/dist/generated-docs/nav.md +8 -1
  25. package/dist/generated-docs/separator.md +18 -0
  26. package/dist/generated-docs/utilities.json +68 -15
  27. package/dist/generated-docs/utilities.md +145 -50
  28. package/dist/os/notification-center.svelte +1 -1
  29. package/dist/os/taskbar.svelte +1 -1
  30. package/dist/os/toast.svelte +1 -1
  31. package/dist/styles/density.css +15 -25
  32. package/dist/styles/index.css +74 -48
  33. package/dist/styles/motion.css +1 -1
  34. package/dist/styles/prose.css +1 -1
  35. package/dist/styles/surfaces/bevel.css +16 -19
  36. package/dist/styles/surfaces/contract.css +50 -0
  37. package/dist/styles/surfaces/flat.css +27 -0
  38. package/dist/styles/surfaces/glass.css +11 -8
  39. package/dist/ui/accordion/accordion-trigger.svelte +1 -1
  40. package/dist/ui/alert-dialog/alert-dialog-content.svelte +1 -1
  41. package/dist/ui/badge/badge.svelte +8 -2
  42. package/dist/ui/badge/badge.svelte.d.ts +1 -1
  43. package/dist/ui/bar/bar.svelte +95 -26
  44. package/dist/ui/bar/bar.svelte.d.ts +71 -31
  45. package/dist/ui/button/button.svelte +6 -0
  46. package/dist/ui/button/button.svelte.d.ts +2 -0
  47. package/dist/ui/button/variants.d.ts +3 -3
  48. package/dist/ui/button/variants.js +6 -11
  49. package/dist/ui/calendar/calendar-day.svelte +1 -1
  50. package/dist/ui/card/card.svelte +23 -10
  51. package/dist/ui/card/card.svelte.d.ts +19 -7
  52. package/dist/ui/chip/chip.svelte +5 -2
  53. package/dist/ui/chip/chip.svelte.d.ts +6 -6
  54. package/dist/ui/collapsible/collapsible-trigger.svelte +1 -1
  55. package/dist/ui/combobox/combobox-content.svelte +1 -1
  56. package/dist/ui/combobox/combobox-trigger.svelte +1 -1
  57. package/dist/ui/command/command-item.svelte +1 -1
  58. package/dist/ui/command/command-link-item.svelte +1 -1
  59. package/dist/ui/command/command-root.svelte +5 -7
  60. package/dist/ui/command-bar/command-bar.svelte +3 -3
  61. package/dist/ui/context-menu/context-menu-content.svelte +1 -4
  62. package/dist/ui/context-menu/context-menu-sub-content.svelte +1 -4
  63. package/dist/ui/date-field/date-field-segment.svelte +1 -1
  64. package/dist/ui/date-picker/date-picker-content.svelte +1 -1
  65. package/dist/ui/date-picker/date-picker-day.svelte +1 -1
  66. package/dist/ui/date-picker/date-picker-segment.svelte +1 -1
  67. package/dist/ui/date-picker/date-picker-trigger.svelte +1 -1
  68. package/dist/ui/date-range-field/date-range-field-segment.svelte +1 -1
  69. package/dist/ui/date-range-picker/date-range-picker-content.svelte +1 -1
  70. package/dist/ui/date-range-picker/date-range-picker-day.svelte +1 -1
  71. package/dist/ui/date-range-picker/date-range-picker-segment.svelte +1 -1
  72. package/dist/ui/date-range-picker/date-range-picker-trigger.svelte +1 -1
  73. package/dist/ui/dialog/dialog-content.svelte +20 -2
  74. package/dist/ui/dropdown-menu/dropdown-menu-content.svelte +1 -1
  75. package/dist/ui/dropdown-menu/dropdown-menu-sub-content.svelte +1 -4
  76. package/dist/ui/dropdown-menu/dropdown-menu-trigger.svelte +1 -1
  77. package/dist/ui/file-upload/file-upload.svelte +1 -1
  78. package/dist/ui/input/variants.d.ts +6 -6
  79. package/dist/ui/input/variants.js +2 -2
  80. package/dist/ui/kv/kv.svelte +1 -1
  81. package/dist/ui/link-preview/link-preview-content.svelte +1 -1
  82. package/dist/ui/menubar/menubar-content.svelte +1 -1
  83. package/dist/ui/menubar/menubar-root.svelte +1 -1
  84. package/dist/ui/menubar/menubar-sub-content.svelte +1 -4
  85. package/dist/ui/menubar/menubar-trigger.svelte +1 -1
  86. package/dist/ui/meter/meter.svelte +1 -2
  87. package/dist/ui/nav/nav-bar.svelte +9 -4
  88. package/dist/ui/nav/nav-bar.svelte.d.ts +2 -1
  89. package/dist/ui/nav/nav-item.svelte +1 -0
  90. package/dist/ui/pane/pane-root.svelte +3 -12
  91. package/dist/ui/pane/pane-tab.svelte +1 -1
  92. package/dist/ui/popover/popover-content.svelte +1 -1
  93. package/dist/ui/provider/surfaces.d.ts +1 -1
  94. package/dist/ui/provider/surfaces.js +1 -1
  95. package/dist/ui/select/select-content.svelte +1 -1
  96. package/dist/ui/select/select-trigger.svelte +1 -1
  97. package/dist/ui/sheet/sheet-content.svelte +1 -1
  98. package/dist/ui/sheet/sheet-content.svelte.d.ts +1 -1
  99. package/dist/ui/slider/slider-thumb.svelte +1 -1
  100. package/dist/ui/step/step-summary.svelte +1 -1
  101. package/dist/ui/switch/switch.svelte +3 -3
  102. package/dist/ui/time-field/time-field-segment.svelte +1 -1
  103. package/dist/ui/time-range-field/time-range-field-segment.svelte +1 -1
  104. package/dist/ui/timeline/timeline-step.svelte +1 -1
  105. package/dist/ui/toggle-group/toggle-group-item.svelte +2 -2
  106. package/dist/ui/toggle-group/toggle-group-item.svelte.d.ts +6 -6
  107. package/dist/ui/toggle-group/toggle-group-root.svelte +1 -2
  108. package/dist/ui/toggle-group/toggle-group-root.svelte.d.ts +3 -3
  109. package/dist/ui/tooltip/tooltip-content.svelte +1 -1
  110. package/dist/ui/tree/tree-item.svelte +1 -1
  111. package/dist/ui/video-player/video-player.svelte +2 -2
  112. package/dist/utils/tw-merge-config.d.ts +6 -1
  113. package/dist/utils/tw-merge-config.js +6 -2
  114. package/package.json +5 -3
  115. package/skill/SKILL.md +26 -21
  116. package/dist/styles/surfaces/base.css +0 -257
@@ -14,14 +14,47 @@ Inherits all props from `Button.RootProps`.
14
14
 
15
15
  | Prop | Type | Default | Notes |
16
16
  |------|------|---------|-------|
17
- | `tone?` | `'default' \| 'accent' \| 'destructive' \| 'success' \| 'warning'` | `'default'` | — |
17
+ | `tone?` | `'default' \| 'accent' \| 'destructive' \| 'success' \| 'warning' \| 'info'` | `'default'` | — |
18
18
  | `size?` | `'control' \| 'chip' \| 'pill' \| 'icon'` | `'control'` | — |
19
19
  | `variant?` | `'filled' \| 'link'` | `'filled'` | — |
20
20
  | `active?` | `boolean` | `false` | — |
21
21
  | `icon?` | `boolean` | `false` | — |
22
- | `loading?` | `boolean` | `false` | When true, disables the button, sets `aria-busy`, and prepends a
23
- spinner. The existing label stays rendered so focus, click targets,
24
- and screen-reader accessible names don't change shape mid-flight. |
22
+ | `loading?` | `boolean` | `false` | In flight: disables the button, sets `aria-busy`, and puts a spinner
23
+ over the label.
24
+ THE GEOMETRY DOES NOT MOVE. That is the requirement, not a detail. A
25
+ button is loading because it was just CLICKED, so anything `loading`
26
+ changes about the box moves the page under the pointer that is still
27
+ on it — and a spinner PREPENDED to the label (what this used to do)
28
+ costs an icon's width plus a gap, measured on a wrapping header row
29
+ that reflowed everything beside it. A consumer hit exactly that and
30
+ stopped using the prop, hand-rolling `disabled` + `aria-busy`
31
+ instead, which is the report that produced this note.
32
+ So the spinner is absolutely positioned and takes no part in the
33
+ flex layout, and the label goes to `opacity-0` rather than being
34
+ unmounted: the box that holds the width stays, and the text stays in
35
+ the accessibility tree as the button's accessible name.
36
+ The visible label is therefore HIDDEN in flight — the one thing this
37
+ trades away, and the reason `loadingLabel` exists.
38
+ IF YOU DO NOT WANT A SPINNER, use `busy`. Not showing one is a
39
+ supported posture, not a legacy one — see that prop. |
40
+ | `busy?` | `boolean` | `false` | In flight, WITHOUT a spinner: disables the button and sets `aria-busy`,
41
+ and changes nothing else. The label stays visible and legible.
42
+ This exists because "show a spinner" is a taste, not a requirement,
43
+ and era had only one answer. A consumer whose house style is that
44
+ spinners should not appear had to spell the posture out themselves —
45
+ `disabled` plus a restated `aria-busy` — and rely on knowing that
46
+ `restProps` spreads last, which is a real fact about this component
47
+ that no reader should have to depend on. Two words for two postures
48
+ is clearer than one word plus a workaround.
49
+ `loading` implies this: it is `busy` plus the spinner and the hidden
50
+ label. What you get from `busy` alone is a control that is visibly
51
+ disabled (the era-interactive opacity) and announced as busy, with
52
+ its geometry and its ink untouched — which is also why it needs no
53
+ `loadingLabel`: nothing about the button changed except that you
54
+ cannot press it.
55
+ Reported by a consumer whose user asked for no spinners anywhere.
56
+ They were right that a fix for the width shift did not answer it: a
57
+ spinner that no longer moves its neighbours is still a spinner. |
25
58
  | `loadingLabel?` | `string` | — | Screen-reader-only label announced while `loading` is true. |
26
59
  | `lead?` | `Snippet` | — | Icon rendered BEFORE the label, outside it. Use this rather than putting
27
60
  an icon in `children`: the label then gets its own box, which is the only
@@ -59,6 +92,7 @@ snippet's text cannot be read before it renders.
59
92
  Only reaches the label when `lead`/`trail` give it its own box. Without
60
93
  one the label is an anonymous flex item that no selector can address,
61
94
  which is the whole reason those snippets exist. |
95
+ | `topology?` | `'bounded' \| 'docked'` | `'bounded'` | `docked` joins this control to a neighbour and removes one or more curves. |
62
96
  | `children?` | `Snippet` | — | — |
63
97
  | `ref?` | `(forwarded)` | `null` | bindable |
64
98
 
@@ -18,11 +18,41 @@ Inherits all props from `ButtonBits`.
18
18
  |------|------|---------|-------|
19
19
  | `ref?` | `CardElement \| null` | `null` | bindable |
20
20
  | `tone?` | `'elevated' \| 'surface' \| 'well' \| 'flat'` | `'elevated'` | Surface tier the card paints on.
21
- - `elevated` (default): the lifted surface. Use on the page background.
22
- - `surface`: the base surface tier. Use when nesting cards inside another elevated container.
23
- - `well`: recessed. For content the surrounding UI puts INTO the card a tool's
24
- output pane, a transcript body — the container twin of a text field's fill.
25
- - `flat`: no background; only the rounded/padded shell. For grouping content visually without adding contrast. |
21
+ - `elevated` (default): the lifted surface, with a resting shadow. Use
22
+ on the page background.
23
+ - `surface`: the base surface tier, no shadow. Use when nesting cards
24
+ inside another elevated container.
25
+ - `well`: recessed. For content the surrounding UI puts INTO the card
26
+ a tool's output pane, a transcript body — the container twin of a
27
+ text field's fill.
28
+ - `flat`: no background; only the rounded/padded shell. For grouping
29
+ content visually without adding contrast.
30
+ READ THE CLASSES AND THEY LOOK SWAPPED. They are not, and this is
31
+ worth a sentence because a consumer read them, believed it, and
32
+ shipped flat cards for months. `surface` paints `bg-well` and `well`
33
+ paints `bg-field`, because era's utility names describe FILLS rather
34
+ than tiers: `bg-well` is the surface's own resting fill (it is what a
35
+ panel is painted with, and it pairs with `shadow-well` when you want
36
+ recessed chrome), and `bg-field` is the recessed fill a text input
37
+ sits in. The tone names are the tiers; the class names are the paints.
38
+ A CARD THAT IS PRESSABLE SHOULD USUALLY BE `elevated`. Passing `href`
39
+ or `onclick` turns on the interactive face — hover, focus, press — but
40
+ it deliberately does NOT override the tier you asked for, so a
41
+ `surface` link card does not get the raised tier's separation and can
42
+ read flatter than the static cards around it. That combination was
43
+ reported as a bug and it is a choice: a tone that silently changed
44
+ under an event handler would be a worse one.
45
+ HOW THE TIERS DIFFER IS SURFACE-DEPENDENT, so do not go looking for a
46
+ fill difference on every surface. `base` mixes the elevated fill 6%
47
+ toward `--color-bright` and adds a resting shadow, so there the tiers
48
+ differ in COLOUR. `bevel` sets `--era-surface-bg-elevated` to
49
+ `--era-surface-bg` outright — elevation is a chisel, not a tone, which
50
+ is bevel's whole premise — so `surface` and `elevated` paint the
51
+ IDENTICAL fill there and differ only in relief. A consumer measured
52
+ exactly that on 30.8.0 bevel: both tones `oklch(0.195 0 none)` in dark,
53
+ `0.863` in light, one variable, side by side. `glass` splits the tiers
54
+ its own way again. So the tier is real on every surface; the thing
55
+ carrying it is not always the fill. |
26
56
  | `header?` | `Snippet` | — | Rendered above the body with a subtle divider. |
27
57
  | `footer?` | `Snippet` | — | Rendered below the body with a subtle divider. |
28
58
  | `children?` | `Snippet` | — | — |
@@ -18,6 +18,22 @@ Inherits all props from `HTMLAttributes<HTMLDivElement>`.
18
18
  | `size?` | `'chip' \| 'pill'` | `'chip'` | `sm` (default) is the standalone free chip; `pill` is the smaller pill
19
19
  that nests inside an md container (a select trigger, a button). |
20
20
  | `ondismiss?` | `() => void` | — | — |
21
+ | `dismissAs?` | `'button' \| 'span'` | `'button'` | What the dismiss control RENDERS AS. `button` (the default) is right
22
+ for a free-standing chip. Use `span` when the chip lives inside
23
+ another control.
24
+ A <button> inside a <button> is not merely bad manners: it is invalid,
25
+ and the HTML parser repairs it by CLOSING the outer control before the
26
+ inner one. So the server's markup and the client's DOM disagree, Svelte
27
+ discards the page's hydration and re-renders from scratch, and the
28
+ chips briefly sit outside the trigger they belong to. era's own
29
+ multi-select shipped exactly that (a Chip with `ondismiss` inside
30
+ Select.Trigger) and logged node_invalid_placement_ssr on every load.
31
+ `span` also drops the control from the accessibility tree rather than
32
+ announcing a button inside a button — which is the honest description
33
+ of what it is there: a pointer shortcut. The accessible way to remove
34
+ a selection is the listbox itself, which is unaffected. Keyboard focus
35
+ order is unchanged, because a nested button was never reachable in a
36
+ sensible order anyway. |
21
37
  | `lead?` | `Snippet` | — | Icon rendered BEFORE the label, outside it. Use this rather than putting
22
38
  an icon in `children`: the label then gets its own box, which is the only
23
39
  place era's ink centring can reach. |