@signal9/era-ui 33.0.0 → 34.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.
@@ -1,67 +0,0 @@
1
- export * as Accordion from './accordion/index.js';
2
- export * as AlertDialog from './alert-dialog/index.js';
3
- export { AspectRatio } from './aspect-ratio/index.js';
4
- export * as Avatar from './avatar/index.js';
5
- export { Badge } from './badge/index.js';
6
- export * as Calendar from './calendar/index.js';
7
- export { Chip } from './chip/index.js';
8
- export { CodeBlock } from './code-block/index.js';
9
- export { CopyButton } from './copy-button/index.js';
10
- export { Cycle, type CycleOption } from './cycle/index.js';
11
- export * as Checkbox from './checkbox/index.js';
12
- export * as Combobox from './combobox/index.js';
13
- export * as Collapsible from './collapsible/index.js';
14
- export * as Command from './command/index.js';
15
- export * from './command-bar/index.js';
16
- export * as Step from './step/index.js';
17
- export * as ContextMenu from './context-menu/index.js';
18
- export * as DateField from './date-field/index.js';
19
- export * as DatePicker from './date-picker/index.js';
20
- export * as DateRangeField from './date-range-field/index.js';
21
- export * as DateRangePicker from './date-range-picker/index.js';
22
- export * as Dialog from './dialog/index.js';
23
- export * as DropdownMenu from './dropdown-menu/index.js';
24
- export { FileUpload } from './file-upload/index.js';
25
- export * as Menubar from './menubar/index.js';
26
- export * as Nav from './nav/index.js';
27
- export * as Menu from './menu/index.js';
28
- export { Meter } from './meter/index.js';
29
- export { Progress } from './progress/index.js';
30
- export * as RadioGroup from './radio-group/index.js';
31
- export * as RangeCalendar from './range-calendar/index.js';
32
- export * as RatingGroup from './rating-group/index.js';
33
- export * as ScrollArea from './scroll-area/index.js';
34
- export * as Select from './select/index.js';
35
- export * as Sheet from './sheet/index.js';
36
- export * as Slider from './slider/index.js';
37
- export * as Table from './table/index.js';
38
- export * as Tabs from './tabs/index.js';
39
- export * as TimeField from './time-field/index.js';
40
- export * as TimeRangeField from './time-range-field/index.js';
41
- export * as Tooltip from './tooltip/index.js';
42
- export * as ToggleGroup from './toggle-group/index.js';
43
- export * as Timeline from './timeline/index.js';
44
- export * as Tree from './tree/index.js';
45
- export * as Toolbar from './toolbar/index.js';
46
- export { Bar } from './bar/index.js';
47
- export { Button } from './button/index.js';
48
- export { ButtonGroup } from './button-group/index.js';
49
- export { Card } from './card/index.js';
50
- export { Input, Textarea } from './input/index.js';
51
- export { KV } from './kv/index.js';
52
- export { Label } from './label/index.js';
53
- export * as LinkPreview from './link-preview/index.js';
54
- export { Logo } from './logo/index.js';
55
- export type { LogoPalette, LogoState, LogoParams } from './logo/index.js';
56
- export { Mode } from './mode/index.js';
57
- export { Pane, Root as PaneRoot, Handle as PaneHandle, Content as PaneContent, Close as PaneClose, Tabs as PaneTabs, TabList as PaneTabList, Tab as PaneTab, TabPanel as PaneTabPanel } from './pane/index.js';
58
- export * as Pagination from './pagination/index.js';
59
- export * as NavigationMenu from './navigation-menu/index.js';
60
- export * as Popover from './popover/index.js';
61
- export * as PinInput from './pin-input/index.js';
62
- export { modes, defaultMode, type Mode as DensityMode, surfaces, defaultSurface, surfaceRegistry, type Surface, type SurfaceMeta, corners, defaultCorners, type Corners, fonts, defaultFont, type Font, motions, defaultMotion, type Motion, axisRegistry, axisKeys, type AxisKey, type AxisMeta, type AxisLevel } from './provider/index.js';
63
- export { Separator } from './separator/index.js';
64
- export { Skeleton } from './skeleton/index.js';
65
- export { Switch } from './switch/index.js';
66
- export { Toggle } from './toggle/index.js';
67
- export { VideoPlayer } from './video-player/index.js';
package/dist/ui/index.js DELETED
@@ -1,70 +0,0 @@
1
- export * as Accordion from './accordion/index.js';
2
- export * as AlertDialog from './alert-dialog/index.js';
3
- export { AspectRatio } from './aspect-ratio/index.js';
4
- export * as Avatar from './avatar/index.js';
5
- export { Badge } from './badge/index.js';
6
- export * as Calendar from './calendar/index.js';
7
- export { Chip } from './chip/index.js';
8
- export { CodeBlock } from './code-block/index.js';
9
- export { CopyButton } from './copy-button/index.js';
10
- export { Cycle } from './cycle/index.js';
11
- export * as Checkbox from './checkbox/index.js';
12
- export * as Combobox from './combobox/index.js';
13
- export * as Collapsible from './collapsible/index.js';
14
- export * as Command from './command/index.js';
15
- export * from './command-bar/index.js';
16
- export * as Step from './step/index.js';
17
- export * as ContextMenu from './context-menu/index.js';
18
- export * as DateField from './date-field/index.js';
19
- export * as DatePicker from './date-picker/index.js';
20
- export * as DateRangeField from './date-range-field/index.js';
21
- export * as DateRangePicker from './date-range-picker/index.js';
22
- export * as Dialog from './dialog/index.js';
23
- export * as DropdownMenu from './dropdown-menu/index.js';
24
- export { FileUpload } from './file-upload/index.js';
25
- export * as Menubar from './menubar/index.js';
26
- export * as Nav from './nav/index.js';
27
- export * as Menu from './menu/index.js';
28
- export { Meter } from './meter/index.js';
29
- export { Progress } from './progress/index.js';
30
- export * as RadioGroup from './radio-group/index.js';
31
- export * as RangeCalendar from './range-calendar/index.js';
32
- export * as RatingGroup from './rating-group/index.js';
33
- export * as ScrollArea from './scroll-area/index.js';
34
- export * as Select from './select/index.js';
35
- export * as Sheet from './sheet/index.js';
36
- export * as Slider from './slider/index.js';
37
- export * as Table from './table/index.js';
38
- export * as Tabs from './tabs/index.js';
39
- export * as TimeField from './time-field/index.js';
40
- export * as TimeRangeField from './time-range-field/index.js';
41
- export * as Tooltip from './tooltip/index.js';
42
- export * as ToggleGroup from './toggle-group/index.js';
43
- export * as Timeline from './timeline/index.js';
44
- export * as Tree from './tree/index.js';
45
- export * as Toolbar from './toolbar/index.js';
46
- export { Bar } from './bar/index.js';
47
- export { Button } from './button/index.js';
48
- export { ButtonGroup } from './button-group/index.js';
49
- export { Card } from './card/index.js';
50
- export { Input, Textarea } from './input/index.js';
51
- export { KV } from './kv/index.js';
52
- export { Label } from './label/index.js';
53
- export * as LinkPreview from './link-preview/index.js';
54
- export { Logo } from './logo/index.js';
55
- export { Mode } from './mode/index.js';
56
- export { Pane, Root as PaneRoot, Handle as PaneHandle, Content as PaneContent, Close as PaneClose, Tabs as PaneTabs, TabList as PaneTabList, Tab as PaneTab, TabPanel as PaneTabPanel } from './pane/index.js';
57
- export * as Pagination from './pagination/index.js';
58
- export * as NavigationMenu from './navigation-menu/index.js';
59
- export * as Popover from './popover/index.js';
60
- export * as PinInput from './pin-input/index.js';
61
- // `Mode` as a top-level identifier is reserved for the component (above), so
62
- // the density-union type can't be re-exported here under its own name — it is
63
- // available (under its original name) from the `@signal9/era-ui/provider`
64
- // subpath, or aliased as `DensityMode` below. Everything else flows through.
65
- export { modes, defaultMode, surfaces, defaultSurface, surfaceRegistry, corners, defaultCorners, fonts, defaultFont, motions, defaultMotion, axisRegistry, axisKeys } from './provider/index.js';
66
- export { Separator } from './separator/index.js';
67
- export { Skeleton } from './skeleton/index.js';
68
- export { Switch } from './switch/index.js';
69
- export { Toggle } from './toggle/index.js';
70
- export { VideoPlayer } from './video-player/index.js';
package/skill/SKILL.md DELETED
@@ -1,225 +0,0 @@
1
- ---
2
- name: era-ui
3
- description: |
4
- Design-system methodology for building UIs with @signal9/era-ui (Svelte 5 +
5
- Tailwind v4). Use when: writing or reviewing any component, layout, or page
6
- in a project that uses era-ui — sizing controls, spacing/padding, radii,
7
- surfaces, motion, or composing library components. Covers: the named class
8
- API, the sp-derived tier ladder, the even-gap and concentricity laws,
9
- geometric vs optical padding, surface/shadow rules, motion, and the
10
- mistakes agents make.
11
- version: 1.1.0
12
- ---
13
-
14
- # Building with era-ui
15
-
16
- Every size, gap, and radius derives from ONE number per density mode: `sp`
17
- (8/10/12/16 for dense/balanced/spacious/touch). Never write a hardcoded px,
18
- rem, radius, duration, or color — there is a class for everything, and the
19
- whole system re-derives per element, so any `data-*` axis override on any
20
- subtree just works.
21
-
22
- **Write named classes, not var classes.** Era's public styling API is pure
23
- Tailwind-looking utilities: `tier-control px-gutter shadow`, never
24
- `h-(--era-h-control)`-style var spellings. Where Tailwind already names the concept
25
- era overloads it (bare `shadow` is the
26
- surface chrome, `transition-colors` rides the motion axis); where it doesn't,
27
- era registers its own (`tier-control`, `gap-gutter`, `p-card`). The `--era-*` custom
28
- properties remain public as the escape hatch for the few things without a
29
- name — noted inline below — but reaching for one when a named class exists is
30
- a review finding.
31
-
32
- ## The five axes (data attributes, all orthogonal)
33
-
34
- | Axis | Attribute | Values |
35
- | ------- | -------------- | ------------------------------------- |
36
- | Density | `data-mode` | `dense` `balanced` `spacious` `touch` |
37
- | Surface | `data-surface` | `flat` `glass` `bevel` |
38
- | Corners | `data-corners` | `rounded` `square` |
39
- | Font | `data-font` | `mono` (default) `sans` `serif` |
40
- | Motion | `data-motion` | `instant` `normal` `extra` |
41
-
42
- **SET EVERY AXIS ON `<html>`.** A subtree override works for everything
43
- rendered inside that subtree — and does NOT reach anything that portals.
44
- Dialog, AlertDialog, Sheet, DropdownMenu, ContextMenu, Menubar, Tooltip and
45
- LinkPreview render at `document.body`, so they take the ROOT's axes, not the
46
- ones on the wrapper their trigger sits in.
47
-
48
- Measured: a `<Card>` inside a `data-surface="bevel"` div resolves to bevel and
49
- gets the chisel; a `<Dialog.Content>` opened from that same div resolves to
50
- `flat` and gets flat's chrome. Two surfaces in one screen, and nothing errors.
51
-
52
- So a subtree override is for a REGION you want to look different — a settings
53
- panel that is deliberately denser. If you want the whole app on bevel, set it
54
- at the root and never on a wrapper. The same applies to `data-mode`: a
55
- `data-mode="spacious"` section will open balanced menus if the root is
56
- balanced.
57
-
58
- A monospace root needs `html { font-size: 16px }` (browser quirk: monospace
59
- roots default to ~13px, silently shrinking every rem-derived token).
60
-
61
- ## The tier ladder
62
-
63
- Named for the ROLE each rung plays, never for its size — a scale whose names
64
- can invert is a scale nobody reads correctly (this library once shipped an
65
- `xxs` that was bigger than its `xs`).
66
-
67
- | Tier | Geometry | Width/min-width helpers | Use for |
68
- | --------- | -------------- | ---------------------------- | ------------------------------------ |
69
- | `icon` | `tier-icon` | `w-icon`, `min-w-icon` | a lucide glyph, switch thumbs |
70
- | `pill` | `tier-pill` | `w-pill`, `min-w-pill` | a badge/chip nested INSIDE a control |
71
- | `chip` | `tier-chip` | `w-chip`, `min-w-chip` | standalone pills, switch tracks, KV |
72
- | `control` | `tier-control` | `w-control`, `min-w-control` | buttons, inputs, selects, triggers |
73
- | `bar` | `tier-bar` | `w-bar`, `min-w-bar` | bars and bounded headers |
74
-
75
- `min-h-*`, `min-w-*` and `w-*` exist across the same rungs. There is no escape
76
- hatch here any more: `min-w-control` is a real class, because role names collide
77
- with nothing in Tailwind's container scale the way `min-w-md` did.
78
-
79
- `rounded-sm/md/lg` are TAILWIND's, not era's — era stopped shadowing them when
80
- the ladder was renamed. Reaching for one gets a fixed radius that ignores the
81
- corners axis.
82
-
83
- ## The two laws
84
-
85
- 1. **Even gaps** — the padding between a container's edge and its children
86
- must equal the gap between the children, on every side. `gap-gutter`
87
- (= sp/2) is the universal inter-element gap, and `p-gutter` (+ `px-`/`py-`)
88
- is the matching gutter a scrollable list or rail owes its rows.
89
- 2. **Concentricity** — `rd-T − rd-U = (h-T − h-U)/2` for every tier pair.
90
- `tier-T` binds height and radius so they cannot drift. A bounded container
91
- names the ACTUAL inner tier and owns the matching inset; nested corners then
92
- share a center automatically. The concentric insets are advanced enough to stay
93
- token-form, and each is named for the pair it centres:
94
- `--era-icon-inset-chip` (an icon inside a chip, = sp/2),
95
- `--era-icon-inset-pill`, `--era-pill-inset-control`, `--era-pill-inset-chip`,
96
- `--era-icon-inset-control`, `--era-icon-inset-bar`, `--era-chip-inset-control`,
97
- `--era-chip-inset-bar`.
98
-
99
- **The boundary**: an unbounded surface has no height tier. Its exposed corner is
100
- either optical or derives OUTWARD from a declared corner-bearing child. Never
101
- derive a bounded row's radius inward from an ancestor; that makes the row's
102
- relationship with its own badge or chip depend on unrelated outer chrome.
103
-
104
- ## Padding: geometric vs optical
105
-
106
- - **Bounded (tier-height) containers** — bars, triggers, pills: geometric.
107
- Side padding `px-gutter` (sp/2 — one token, not a per-tier family);
108
- text-symmetric vertical centering `p`/`px`/`py-inset-{pill,chip,control}` =
109
- (h-T − text)/2; pill side breathing `px-pill`/`px-chip` = (h-T − 0.6·text)/2
110
- (text wants ~2× more horizontal than vertical padding); text-field side
111
- padding `px-field`.
112
- - **Unbounded containers** — optical: `p-panel` (compact shells), `p-card`
113
- (cards, dialogs, popovers), `p-content` (full content panels). Super-linear
114
- across modes so whitespace keeps pace with growing controls while text
115
- stays 14px. Never pad a card with `px-*` or ad-hoc `calc`.
116
-
117
- ## Surfaces and shadows
118
-
119
- - Depth is **shadow, not border**: raised chrome takes bare `shadow`;
120
- floating panels take `shadow-lg`; recessed content containers (inputs,
121
- tracks, wells) take `shadow-well`; pressed/latched faces take
122
- `shadow-pressed`. On press, bevel sinks the CONTENT via
123
- `--era-press-sink-x`/`-y` while the box holds still.
124
- - **Transient vs latched fills**: hover/focus/highlighted feedback uses
125
- `bg-highlight` + `shadow-highlight` (surface-owned; translucent on glass).
126
- Held state (toggle on, current tab, active button) uses opaque `bg-hover`.
127
- Never swap.
128
- - Panels: use `material-popover` for transient floating chrome and
129
- `material-panel` for persistent floating chrome. These atomically bind fill,
130
- relief, and backdrop without naming flat/glass/bevel. Use `surface-backdrop`
131
- only when a custom surface must choose its own fill and relief. Modal scrims
132
- use `bg-overlay`. Menu panels pad with `p-menu` and their rows take
133
- `rounded-menu-item` so the row highlight stays concentric inside the frame.
134
-
135
- ## Motion
136
-
137
- The bare `transition-*` utilities default to the motion axis — `transition-colors`
138
- alone is on-design: 0s at `instant` (also forced by reduced-motion), longer at
139
- `extra` with a gentle overshoot. Name the axis explicitly with `ease-base` /
140
- `duration-base` when overriding; never `duration-150` or a literal bezier.
141
- Deriving compound timings (shimmer loops, cursor pulses) as multiples of
142
- `--era-duration` makes them motion-axis-aware for free.
143
-
144
- ## Text
145
-
146
- - `text-body` for control/body text (density-aware size); `text-fg` default,
147
- `text-bright` emphasis, `text-muted` secondary.
148
- - Single-glyph elements carry a min-width equal to their tier height (a lone
149
- character renders square, never a skinny pill) — `min-w-control`, see
150
- the ladder note.
151
- - Single-line control text next to icons carries `era-text-trim`
152
- (`line-height: 1` + `text-box: trim-both ex alphabetic`) — flexbox centers
153
- the line box, not the ink; the utility centers the x-height band and holds
154
- alignment to <0.5px across fonts. `era-text-trim-caps` for ALL-CAPS strings.
155
- Never a translateY nudge, never `cap alphabetic`/`cap text` for mixed case.
156
- - Fonts: the library's default mono stack (ui-monospace → SF Mono → Menlo →
157
- Consolas → Liberation Mono) is the reference for all text-metric guarantees
158
- (ink centering, pill paddings, square floors). Overriding `--font-mono` is
159
- supported, but re-check control-text alignment with your font — metrics
160
- move with the face.
161
- - `font-mono` is a display-token convention (Badge, Chip, KV, code), not a
162
- universal rule.
163
- - Headings balance and prose wraps pretty automatically — don't re-add
164
- `text-balance`/`text-pretty` except on non-semantic prose elements.
165
-
166
- ## CSS utilities (classes, not components)
167
-
168
- Not everything era exposes is a component — these ride along with the stylesheet
169
- and need no import. Reach for one before hand-rolling the same styling or bending
170
- a component into the role. Full reference (including every named scale above):
171
- `/utilities.md`; machine-readable list: `/utilities.json` (or
172
- `@signal9/era-ui/utilities.json`).
173
-
174
- | Class | Use it for |
175
- | -------------------- | ---------------------------------------------------------------------------------------------------------------------- |
176
- | `era-link` | inline text link in body copy/prose — NOT `Button variant="link"` (that's a control) and never a hand-rolled underline |
177
- | `era-interactive` | the focus/disabled recipe on a custom control (every era wrapper carries it) |
178
- | `era-text-trim` | ink-centering single-line control text beside an icon; fixed-height elements only |
179
- | `era-text-trim-caps` | the same for ALL-CAPS strings (kbd hints, acronym badges) |
180
- | `era-shimmer` | a "working…" / streaming label — motion-aware, dies at `instant` and under reduced-motion |
181
- | `scrollbar-none` | an overflowing strip that scrolls with no visible bar (ScrollArea is for when the bar IS the design) |
182
- | `material-popover` | complete transient floating material: raised fill, floating relief, and surface-owned backdrop |
183
- | `material-panel` | complete persistent floating material: resting fill, floating relief, and surface-owned backdrop |
184
- | `surface-backdrop` | backdrop treatment only, for a custom surface whose fill and relief are deliberately separate |
185
- | `pressable` | physical pressed face; moves its marked direct content plane by the surface-owned travel |
186
-
187
- ## Composing the library
188
-
189
- One entry point per component — nothing re-exports them together, so an import
190
- can never pull in a component you did not ask for. The ROOT is the system layer
191
- (`cn`, `tv`, the axis registry, `ModeProvider`) and holds no components.
192
-
193
- ```svelte
194
- <script lang="ts">
195
- import { Button } from '@signal9/era-ui/button';
196
- import { Badge } from '@signal9/era-ui/badge';
197
- import * as Select from '@signal9/era-ui/select'; // namespaced parts: Select.Root…
198
- import { Desktop } from '@signal9/era-ui/os';
199
- import { Conversation } from '@signal9/era-ui/ai/conversation';
200
-
201
- import { cn } from '@signal9/era-ui'; // the root: system only
202
- </script>
203
- ```
204
-
205
- - `ui` primitives are minimal bits-ui wrappers — all bits props/snippets pass
206
- through; style via `class` (merged with tailwind-merge, consumer wins — the
207
- named classes conflict-resolve against internals, so `class="h-bar"` on a
208
- control-tier control just works).
209
- - `@signal9/era-ui/os`: WindowManager + workspaces, Desktop, Pane, Taskbar
210
- (built-in command bar), Toaster. `@signal9/era-ui/ai/<part>`: Conversation,
211
- Message, Response, PromptInput, Tool/Reasoning/Task over the Step primitive.
212
- - List-item keyboard highlight is `data-[highlighted]:bg-hover` — never
213
- `hover:text-bright` on items.
214
-
215
- ## Review checklist (the mistakes to catch)
216
-
217
- 1. Hardcoded px/rem/radius/duration/color → replace with the named class.
218
- 2. Radius chosen by bulk instead of corner region.
219
- 3. Unequal edge padding vs inner gap at any nesting level.
220
- 4. `px-*`/geometric padding on an unbounded container (or `p-card` on a pill).
221
- 5. `bg-hover` used for hover feedback, or `bg-highlight` for latched state.
222
- 6. Icon not `size-icon`; single glyph without the `min-w-*` square floor.
223
- 7. A `-(--era-*)` var class where a named class exists (`h-(--era-h-control)` →
224
- `h-control`); if the var form is genuinely needed, always the paren shorthand —
225
- never `x-[var(--era-y)]`.