@signal9/era-ui 2.25.0 → 2.27.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/dist/docs/button.md +1 -0
- package/dist/docs/css-utilities.d.ts +21 -0
- package/dist/docs/css-utilities.js +124 -0
- package/dist/docs/generated-docs.d.ts +2 -0
- package/dist/docs/generated-docs.js +7 -0
- package/dist/docs/index.js +4 -0
- package/dist/docs/llms-txt.js +17 -1
- package/dist/docs/scroll-area.md +7 -0
- package/dist/docs/utilities.d.ts +4 -0
- package/dist/docs/utilities.js +15 -0
- package/dist/era-ui.css +1 -1
- package/dist/generated-docs/button.md +1 -0
- package/dist/generated-docs/llms-full.txt +224 -1
- package/dist/generated-docs/llms.txt +15 -1
- package/dist/generated-docs/manifest.json +72 -3
- package/dist/generated-docs/scroll-area.md +8 -0
- package/dist/generated-docs/utilities.json +53 -0
- package/dist/generated-docs/utilities.md +195 -0
- package/dist/styles/index.css +25 -5
- package/dist/styles/surfaces/bevel.css +55 -0
- package/dist/styles/surfaces/glass.css +5 -1
- package/dist/ui/button/button.svelte +6 -0
- package/package.json +3 -2
- package/skill/SKILL.md +17 -0
package/dist/styles/index.css
CHANGED
|
@@ -36,7 +36,10 @@
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/* Shared interactive-state recipe: quiet focus, disabled affordance.
|
|
39
|
-
* Equivalent to `focus:outline-none disabled:cursor-not-allowed disabled:opacity-50`.
|
|
39
|
+
* Equivalent to `focus:outline-none disabled:cursor-not-allowed disabled:opacity-50`.
|
|
40
|
+
*
|
|
41
|
+
* @use the focus/disabled recipe every era control carries — put it on a custom
|
|
42
|
+
* interactive element instead of hand-writing focus/disabled variants. */
|
|
40
43
|
@utility era-interactive {
|
|
41
44
|
&:focus {
|
|
42
45
|
outline: none;
|
|
@@ -54,7 +57,11 @@
|
|
|
54
57
|
* "extra" — matching every other era transition. Font-agnostic: it styles
|
|
55
58
|
* decoration + colour only, so it reads correctly in mono, sans, or serif, and
|
|
56
59
|
* the 0.2em offset scales with the type size. Keyboard focus mirrors hover so
|
|
57
|
-
* the affordance is reachable without a pointer.
|
|
60
|
+
* the affordance is reachable without a pointer.
|
|
61
|
+
*
|
|
62
|
+
* @use understated, motion-aware inline text link — the canonical style for a
|
|
63
|
+
* link in body copy or prose; prefer it over a hand-rolled underline or
|
|
64
|
+
* `Button variant="link"` (which is a control, not running text). */
|
|
58
65
|
@utility era-link {
|
|
59
66
|
/* The text is bright at rest and never changes — the link reads as a link
|
|
60
67
|
* before you touch it. Only the UNDERLINE reacts: a faint half-strength-muted
|
|
@@ -71,7 +78,10 @@
|
|
|
71
78
|
}
|
|
72
79
|
|
|
73
80
|
/* Scrollable but chromeless — hides the scrollbar while keeping wheel / touch /
|
|
74
|
-
* drag scrolling (e.g. an overflowing tab strip in a small pane handle).
|
|
81
|
+
* drag scrolling (e.g. an overflowing tab strip in a small pane handle).
|
|
82
|
+
*
|
|
83
|
+
* @use hide the scrollbar on an overflowing strip or rail while keeping it
|
|
84
|
+
* scrollable — for a scroll region that should show its bar, use ScrollArea. */
|
|
75
85
|
@utility scrollbar-none {
|
|
76
86
|
scrollbar-width: none;
|
|
77
87
|
&::-webkit-scrollbar {
|
|
@@ -101,6 +111,10 @@
|
|
|
101
111
|
* command-input) and clipping display tokens (KV) correctly carry it. For
|
|
102
112
|
* truncating text, put the trim on the fixed-height ROW and let the child
|
|
103
113
|
* center via the row's items-center.
|
|
114
|
+
*
|
|
115
|
+
* @use vertically center single-line control text (a label beside an icon, an
|
|
116
|
+
* input's own text) without a translateY nudge — fixed-height elements only;
|
|
117
|
+
* see era-text-trim-caps for ALL-CAPS strings.
|
|
104
118
|
*/
|
|
105
119
|
@utility era-text-trim {
|
|
106
120
|
line-height: 1;
|
|
@@ -108,7 +122,10 @@
|
|
|
108
122
|
}
|
|
109
123
|
|
|
110
124
|
/* ALL-CAPS single-line text (kbd hints, acronym badges): the x-height band
|
|
111
|
-
* misjudges caps-only strings — cap/alphabetic edges are the right box.
|
|
125
|
+
* misjudges caps-only strings — cap/alphabetic edges are the right box.
|
|
126
|
+
*
|
|
127
|
+
* @use the era-text-trim variant for ALL-CAPS single-line strings (kbd hints,
|
|
128
|
+
* acronym badges) — never use it for mixed-case text. */
|
|
112
129
|
@utility era-text-trim-caps {
|
|
113
130
|
line-height: 1;
|
|
114
131
|
text-box: trim-both cap alphabetic;
|
|
@@ -118,7 +135,10 @@
|
|
|
118
135
|
* "working…" label treatment in streaming UIs). Timing derives from the motion
|
|
119
136
|
* axis (10× --era-duration ≈ 1.5s at normal, 2.6s at extra); at instant the
|
|
120
137
|
* duration is 0s and the sweep freezes on its base frame — plain muted text —
|
|
121
|
-
* so reduced-motion and data-motion="instant" both kill it for free.
|
|
138
|
+
* so reduced-motion and data-motion="instant" both kill it for free.
|
|
139
|
+
*
|
|
140
|
+
* @use the in-progress text treatment — put it on a "working…" / "thinking…"
|
|
141
|
+
* label while a task streams, instead of a spinner beside the text. */
|
|
122
142
|
@utility era-shimmer {
|
|
123
143
|
background: linear-gradient(
|
|
124
144
|
110deg,
|
|
@@ -91,9 +91,64 @@
|
|
|
91
91
|
* the icon/label depresses like a Win95 keycap pushed in from the top-left. */
|
|
92
92
|
--era-press-sink-x: 1px;
|
|
93
93
|
--era-press-sink-y: 1px;
|
|
94
|
+
/* Angle of the shade a pressed face sits under, DERIVED from the one light
|
|
95
|
+
* knob rather than picked by eye: the shadow runs along the light's own
|
|
96
|
+
* direction vector (side, 1), so relighting the surface relights it too.
|
|
97
|
+
* side=1 → 135deg (the classic corner-lit diagonal); side=0.6 → ~149deg, the
|
|
98
|
+
* light rotated toward straight-above. Falls from the TOP-LEFT because that is
|
|
99
|
+
* the corner a well leaves in shade (see --era-shadow-well: dark chisel on
|
|
100
|
+
* top/left, lit chisel on bottom/right — the exact inverse of a raised face). */
|
|
101
|
+
--era-bevel-press-angle: calc(180deg - atan2(var(--era-bevel-side), 1));
|
|
102
|
+
--era-bevel-press-shade: light-dark(oklch(0 0 0 / 0.2), oklch(0 0 0 / 0.28));
|
|
94
103
|
/* Floating panels wear a 2-layer chisel frame; row highlights inset past
|
|
95
104
|
* it with a concentric radius (square under data-corners="square", as
|
|
96
105
|
* the era had it — Win95 drew its selection bar inside the border). */
|
|
97
106
|
--era-panel-inset: 2px;
|
|
98
107
|
--era-item-rd-scale: 1;
|
|
99
108
|
}
|
|
109
|
+
|
|
110
|
+
/*
|
|
111
|
+
* PRESS SHADE — the shadow a sunken face sits under (icon buttons).
|
|
112
|
+
*
|
|
113
|
+
* Pressing a bevel button turns its face into a well, and the frame's lit edge
|
|
114
|
+
* then casts a shade down into it. The chisel alone can't express that: it draws
|
|
115
|
+
* the WALLS of the well but leaves the floor evenly lit, so a pressed icon looked
|
|
116
|
+
* exactly as bright as a raised one — the glyph read as floating above the recess
|
|
117
|
+
* instead of sitting in it.
|
|
118
|
+
*
|
|
119
|
+
* The film lies ABOVE the content, not under it, and that is the whole point: a
|
|
120
|
+
* shadow cast into a well falls across whatever is in the well, glyph included.
|
|
121
|
+
* The icon darkens WITH the face it sits on rather than hovering over it,
|
|
122
|
+
* untouched. It rides the frame, not the content — `[&:active>*]` sinks the
|
|
123
|
+
* icon 1px, but the shade holds still, because the frame is what casts it.
|
|
124
|
+
*
|
|
125
|
+
* The overlay is always mounted at opacity 0 so the fade can ride the motion
|
|
126
|
+
* axis (0s at instant → it snaps; longer at extra). A pseudo-element that only
|
|
127
|
+
* came into being on :active would have nothing to transition FROM.
|
|
128
|
+
*
|
|
129
|
+
* `link` buttons are excluded: they are chromeless tinted text with no face, and
|
|
130
|
+
* a film laid over prose is just dirt. Bevel is the only surface that does this —
|
|
131
|
+
* flat and glass express press as tone, and cartoon flattens the sticker.
|
|
132
|
+
*/
|
|
133
|
+
[data-surface='bevel'] button:not([data-variant='link']):has(svg) {
|
|
134
|
+
position: relative;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
[data-surface='bevel'] button:not([data-variant='link']):has(svg)::after {
|
|
138
|
+
content: '';
|
|
139
|
+
position: absolute;
|
|
140
|
+
inset: 0;
|
|
141
|
+
border-radius: inherit;
|
|
142
|
+
pointer-events: none;
|
|
143
|
+
opacity: 0;
|
|
144
|
+
background-image: linear-gradient(
|
|
145
|
+
var(--era-bevel-press-angle),
|
|
146
|
+
var(--era-bevel-press-shade),
|
|
147
|
+
transparent 70%
|
|
148
|
+
);
|
|
149
|
+
transition: opacity var(--era-duration) var(--era-ease);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
[data-surface='bevel'] button:not([data-variant='link']):has(svg):active::after {
|
|
153
|
+
opacity: 1;
|
|
154
|
+
}
|
|
@@ -118,7 +118,11 @@
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
/* Tailwind v4 cannot resolve var() inside backdrop-blur-[], so the filter
|
|
121
|
-
* is a registered utility, gated to glass subtrees.
|
|
121
|
+
* is a registered utility, gated to glass subtrees.
|
|
122
|
+
*
|
|
123
|
+
* @use the backdrop blur for a floating panel (popover, dialog, taskbar) — it
|
|
124
|
+
* applies only inside a data-surface="glass" subtree and is inert elsewhere,
|
|
125
|
+
* so it is safe to leave on a panel that renders under every surface. */
|
|
122
126
|
@utility glass-blur {
|
|
123
127
|
[data-surface='glass'] & {
|
|
124
128
|
backdrop-filter: blur(var(--era-blur)) saturate(var(--era-saturate));
|
|
@@ -46,12 +46,18 @@
|
|
|
46
46
|
hover sweep is what surfaced this — a latched button correctly shows no hover
|
|
47
47
|
delta (it must keep its pressed face), but with no attribute to read, that is
|
|
48
48
|
indistinguishable from a control with no hover state at all.
|
|
49
|
+
|
|
50
|
+
`variant` is exposed for the same reason: a surface has to be able to tell a
|
|
51
|
+
chromed button from a chromeless `link` one. bevel's press shade is a film laid
|
|
52
|
+
over the button's face, which a link button does not have — and a class is not
|
|
53
|
+
something CSS can ask about.
|
|
49
54
|
-->
|
|
50
55
|
<Button.Root
|
|
51
56
|
bind:ref
|
|
52
57
|
disabled={effectiveDisabled}
|
|
53
58
|
aria-busy={loading || undefined}
|
|
54
59
|
data-state={active ? 'on' : undefined}
|
|
60
|
+
data-variant={variant}
|
|
55
61
|
class={cn(buttonVariants({ variant, tone, size, icon, active }), className)}
|
|
56
62
|
{...restProps}
|
|
57
63
|
>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signal9/era-ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.27.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "vite dev --host",
|
|
6
6
|
"build": "vite build && npm run prepack",
|
|
@@ -65,7 +65,8 @@
|
|
|
65
65
|
},
|
|
66
66
|
"./css": "./dist/era-ui.css",
|
|
67
67
|
"./styles/raw": "./dist/styles/index.css",
|
|
68
|
-
"./styles/themes": "./dist/styles/themes.css"
|
|
68
|
+
"./styles/themes": "./dist/styles/themes.css",
|
|
69
|
+
"./utilities.json": "./dist/generated-docs/utilities.json"
|
|
69
70
|
},
|
|
70
71
|
"peerDependencies": {
|
|
71
72
|
"svelte": "^5.0.0",
|
package/skill/SKILL.md
CHANGED
|
@@ -115,6 +115,23 @@ motion-axis-aware for free.
|
|
|
115
115
|
- Headings balance and prose wraps pretty automatically — don't re-add
|
|
116
116
|
`text-balance`/`text-pretty` except on non-semantic prose elements.
|
|
117
117
|
|
|
118
|
+
## CSS utilities (classes, not components)
|
|
119
|
+
|
|
120
|
+
Not everything era exposes is a component — these ride along with the stylesheet
|
|
121
|
+
and need no import. Reach for one before hand-rolling the same styling or bending
|
|
122
|
+
a component into the role. Full reference: `/utilities.md`; machine-readable list:
|
|
123
|
+
`/utilities.json` (or `@sig-nine/era-ui/utilities.json`).
|
|
124
|
+
|
|
125
|
+
| Class | Use it for |
|
|
126
|
+
| -------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
|
127
|
+
| `era-link` | inline text link in body copy/prose — NOT `Button variant="link"` (that's a control) and never a hand-rolled underline |
|
|
128
|
+
| `era-interactive` | the focus/disabled recipe on a custom control (every era wrapper carries it) |
|
|
129
|
+
| `era-text-trim` | ink-centering single-line control text beside an icon; fixed-height elements only |
|
|
130
|
+
| `era-text-trim-caps` | the same for ALL-CAPS strings (kbd hints, acronym badges) |
|
|
131
|
+
| `era-shimmer` | a "working…" / streaming label — motion-aware, dies at `instant` and under reduced-motion |
|
|
132
|
+
| `scrollbar-none` | an overflowing strip that scrolls with no visible bar (ScrollArea is for when the bar IS the design) |
|
|
133
|
+
| `glass-blur` | backdrop blur on a floating panel; inert outside a `data-surface="glass"` subtree |
|
|
134
|
+
|
|
118
135
|
## Composing the library
|
|
119
136
|
|
|
120
137
|
```svelte
|