@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.
- package/CHANGELOG.md +3 -11
- package/dist/era-ui.css +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/ui/provider/index.d.ts +3 -3
- package/dist/ui/provider/index.js +3 -3
- package/package.json +474 -10
- package/skills/era-ui/SKILL.md +37 -0
- package/skills/era-ui/references/composition.md +19 -0
- package/skills/era-ui/references/geometry.md +24 -0
- package/skills/era-ui/references/materials.md +15 -0
- package/dist/ui/index.d.ts +0 -67
- package/dist/ui/index.js +0 -70
- package/skill/SKILL.md +0 -225
package/dist/ui/index.d.ts
DELETED
|
@@ -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)]`.
|