@signal9/era-ui 10.0.0 → 10.1.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/ai/index.js +1 -1
- package/dist/ai/message/message-usage.svelte +1 -1
- package/dist/ai/prompt-input/prompt-input-attachments.svelte +1 -1
- package/dist/ai/run-status/run-status.svelte +3 -2
- package/dist/ai/swarm/swarm-agent.svelte +2 -2
- package/dist/ai/swarm/swarm-artifact.svelte +1 -1
- package/dist/ai/swarm/swarm-barrier.svelte +1 -1
- package/dist/ai/swarm/swarm-footer.svelte +3 -2
- package/dist/ai/swarm/swarm-header.svelte +1 -1
- package/dist/ai/swarm/swarm-node.svelte +1 -1
- package/dist/ai/swarm/swarm-role.svelte +5 -2
- package/dist/ai/tool/tool-chip.svelte +1 -1
- package/dist/apps/index.d.ts +3 -3
- package/dist/apps/index.js +3 -3
- package/dist/apps/notes/editor/slash-menu.svelte +2 -4
- package/dist/apps/notes/notes.svelte +1 -1
- package/dist/dev/audit/audits/anonymous-text.d.ts +2 -0
- package/dist/dev/audit/audits/anonymous-text.js +73 -0
- package/dist/dev/audit/audits/index.d.ts +2 -1
- package/dist/dev/audit/audits/index.js +3 -1
- package/dist/dev/audit/types.d.ts +1 -1
- package/dist/docs/css-utilities.js +1 -1
- package/dist/docs/llms-txt.js +2 -2
- package/dist/docs/notes.md +3 -3
- package/dist/era-ui.css +1 -1
- package/dist/generated-docs/llms-full.txt +96 -16
- package/dist/generated-docs/llms.txt +11 -7
- package/dist/generated-docs/manifest.json +28 -7
- package/dist/generated-docs/notes.md +3 -3
- package/dist/generated-docs/utilities.json +23 -4
- package/dist/generated-docs/utilities.md +82 -6
- package/dist/styles/index.css +43 -5
- package/dist/ui/bar/bar.svelte +1 -1
- package/dist/ui/bar/bar.svelte.d.ts +1 -1
- package/dist/ui/button/button.svelte +12 -1
- package/dist/ui/button/variants.d.ts +1 -1
- package/dist/ui/button/variants.js +1 -1
- package/dist/ui/chip/chip.svelte +13 -3
- package/dist/ui/chip/chip.svelte.d.ts +1 -1
- package/dist/ui/command/command-item.svelte +1 -1
- package/dist/ui/command/command-link-item.svelte +1 -1
- package/dist/ui/command-bar/command-bar.svelte +1 -1
- package/dist/ui/index.js +1 -1
- package/dist/ui/kv/kv.svelte +1 -1
- package/dist/ui/select/select-trigger.svelte +1 -1
- package/dist/ui/step/step-summary.svelte +1 -1
- package/package.json +1 -1
|
@@ -4,18 +4,20 @@
|
|
|
4
4
|
|
|
5
5
|
## Using the library
|
|
6
6
|
|
|
7
|
+
This package is published to two registries under two names: `@signal9/era-ui` on npm (used throughout these docs) and `@sig-nine/era-ui` on GitHub Packages, where the scope must match the repo owner. Same code, same versions — pick the one your registry serves and keep the scope consistent.
|
|
8
|
+
|
|
7
9
|
**One entry point per component.** There is no barrel that re-exports everything — importing a component can never drag in another one, or another one's dependencies.
|
|
8
10
|
|
|
9
11
|
```ts
|
|
10
|
-
import { Button } from "@
|
|
11
|
-
import * as Select from "@
|
|
12
|
-
import * as Table from "@
|
|
12
|
+
import { Button } from "@signal9/era-ui/button";
|
|
13
|
+
import * as Select from "@signal9/era-ui/select";
|
|
14
|
+
import * as Table from "@signal9/era-ui/table";
|
|
13
15
|
|
|
14
16
|
// The root is the SYSTEM layer only: cn/tv, keybindings, the axis
|
|
15
17
|
// registry, and Mode. It imports no component.
|
|
16
|
-
import { cn, ModeProvider } from "@
|
|
18
|
+
import { cn, ModeProvider } from "@signal9/era-ui";
|
|
17
19
|
|
|
18
|
-
import "@
|
|
20
|
+
import "@signal9/era-ui/styles"; // source CSS, scanned by your Tailwind
|
|
19
21
|
```
|
|
20
22
|
|
|
21
23
|
The path is always the component's own kebab-case name — `/button`, `/dropdown-menu`, `/date-range-picker` — and the other layers are namespaced: `/ai` and `/ai/<part>`, `/apps/<app>`, `/os`, `/audit`.
|
|
@@ -24,7 +26,7 @@ Named exports wrap a single primitive (`Button`, `Badge`, `Chip`, `Input`, …).
|
|
|
24
26
|
|
|
25
27
|
### Stylesheets
|
|
26
28
|
|
|
27
|
-
`@
|
|
29
|
+
`@signal9/era-ui/styles` is the source CSS — import it once and your own Tailwind build scans era's components and emits only the utilities they use. `@signal9/era-ui/css` is the prebuilt alternative for a project without Tailwind. Three more are opt-in, each single-purpose: `/styles/video-player` (vidstack's vendor CSS, needed only with `VideoPlayer`), `/styles/prose` (document typography for a TipTap editor — put `era-notes-prose` on your editor element; `NoteEditor` imports it already), and `/styles/themes` (the raw theme tokens).
|
|
28
30
|
|
|
29
31
|
### Optional peers
|
|
30
32
|
|
|
@@ -58,7 +60,9 @@ Classes, not components — they need no import beyond the stylesheet. Reach for
|
|
|
58
60
|
- `era-text-trim` — vertically center single-line control text (a label beside an icon, a button's own text) without a translateY nudge. Fixed-height, non-editable elements ONLY: never on an <input>/<textarea>, and never on the same element as `truncate` or any overflow clip — put it on the fixed-height ROW and let the truncating child centre inside it. See era-text-trim-caps for ALL-CAPS.
|
|
59
61
|
- `truncate` — single-line horizontal truncation with an ellipsis — put it on the truncating CHILD inside a trimmed or leading-none row, never on the same element as era-text-trim; it will not clip ascenders or descenders.
|
|
60
62
|
- `era-text-trim-caps` — the era-text-trim variant for ALL-CAPS single-line strings (kbd hints, acronym badges) — never for mixed-case text (a label like "System" reads high; use era-text-trim), and never on the same element as `truncate`.
|
|
61
|
-
- `era-
|
|
63
|
+
- `era-ink-center` — on a native single-line <input> (or the text layer that must mirror one) inside a fixed-height field — never alongside era-text-trim.
|
|
64
|
+
- `era-token-ink` — the ink centring for a token pill — a badge, a KV value, any short caps-or-digits label in a fixed-height box, CENTRED horizontally and with no icon sibling. For a left-aligned sentence-case label use era-label-ink; when an icon really must sit beside the text, see the note there.
|
|
65
|
+
- `era-label-ink` — the ink centring for a fixed-height control holding ONE line of sentence-case text and no icon — a menu item, a nav trigger, a button label. Never alongside `truncate` (the trimmed box becomes the clip).
|
|
62
66
|
- `era-shimmer` — the in-progress text treatment — put it on a "working…" / "thinking…" label while a task streams, instead of a spinner beside the text.
|
|
63
67
|
- `era-collapse` — the height sweep for a bits-ui Collapsible.Content — put it on the Content element itself (it carries its own overflow: hidden).
|
|
64
68
|
- `h-icon · h-pill · h-chip · h-control · h-bar` — the tier-height ladder — h-icon (icon) · h-pill (nested pill) · h-chip (standalone pill) · h-control (control) · h-bar (bar); the named form of h-(--era-h-*).
|
|
@@ -131,7 +135,7 @@ never the `h-(--era-h-control)` var-class spelling. Everything below rides along
|
|
|
131
135
|
with the stylesheet and needs no import:
|
|
132
136
|
|
|
133
137
|
```ts
|
|
134
|
-
import "@
|
|
138
|
+
import "@signal9/era-ui/css";
|
|
135
139
|
```
|
|
136
140
|
|
|
137
141
|
```svelte
|
|
@@ -166,7 +170,9 @@ enough to stay var-form — `min-w-(--era-h-control)` etc. remain the escape hat
|
|
|
166
170
|
| `era-text-trim` | vertically center single-line control text (a label beside an icon, a button's own text) without a translateY nudge. Fixed-height, non-editable elements ONLY: never on an <input>/<textarea>, and never on the same element as `truncate` or any overflow clip — put it on the fixed-height ROW and let the truncating child centre inside it. See era-text-trim-caps for ALL-CAPS. |
|
|
167
171
|
| `truncate` | single-line horizontal truncation with an ellipsis — put it on the truncating CHILD inside a trimmed or leading-none row, never on the same element as era-text-trim; it will not clip ascenders or descenders. |
|
|
168
172
|
| `era-text-trim-caps` | the era-text-trim variant for ALL-CAPS single-line strings (kbd hints, acronym badges) — never for mixed-case text (a label like "System" reads high; use era-text-trim), and never on the same element as `truncate`. |
|
|
169
|
-
| `era-
|
|
173
|
+
| `era-ink-center` | on a native single-line <input> (or the text layer that must mirror one) inside a fixed-height field — never alongside era-text-trim. |
|
|
174
|
+
| `era-token-ink` | the ink centring for a token pill — a badge, a KV value, any short caps-or-digits label in a fixed-height box, CENTRED horizontally and with no icon sibling. For a left-aligned sentence-case label use era-label-ink; when an icon really must sit beside the text, see the note there. |
|
|
175
|
+
| `era-label-ink` | the ink centring for a fixed-height control holding ONE line of sentence-case text and no icon — a menu item, a nav trigger, a button label. Never alongside `truncate` (the trimmed box becomes the clip). |
|
|
170
176
|
| `era-shimmer` | the in-progress text treatment — put it on a "working…" / "thinking…" label while a task streams, instead of a spinner beside the text. |
|
|
171
177
|
| `era-collapse` | the height sweep for a bits-ui Collapsible.Content — put it on the Content element itself (it carries its own overflow: hidden). |
|
|
172
178
|
| `h-icon` `h-pill` `h-chip` `h-control` `h-bar` | the tier-height ladder — h-icon (icon) · h-pill (nested pill) · h-chip (standalone pill) · h-control (control) · h-bar (bar); the named form of h-(--era-h-*). |
|
|
@@ -357,9 +363,47 @@ Declared in `index.css`.
|
|
|
357
363
|
}
|
|
358
364
|
```
|
|
359
365
|
|
|
360
|
-
## era-
|
|
366
|
+
## era-ink-center
|
|
367
|
+
|
|
368
|
+
**Use it for:** on a native single-line <input> (or the text layer that must mirror one) inside a fixed-height field — never alongside era-text-trim.
|
|
369
|
+
|
|
370
|
+
The EDITABLE counterpart of era-text-trim — for native <input>s, which the
|
|
371
|
+
trim is forbidden on (it collapses the UA's inner editor box and slices the
|
|
372
|
+
glyphs; see typography/collapsed-text-trim).
|
|
373
|
+
|
|
374
|
+
Without help, a tier-height input centres its text by FONT BOX, and the ui
|
|
375
|
+
stacks' font box is deeply asymmetric: ascent ≈1.07em against descent
|
|
376
|
+
≈0.29em. Centring that box parks the visible band (caps, x-height) ~0.115em
|
|
377
|
+
LOW — so a field's text sat visibly below the trimmed label beside it.
|
|
378
|
+
|
|
379
|
+
The value is OPTICAL, not the derivation's: pure x-band centring computes
|
|
380
|
+
to ~0.23em of padding, but pixel-measured against real Title-Case text it
|
|
381
|
+
over-lifts — the eye weighs the cap-to-baseline mass, which x-band
|
|
382
|
+
centring parks ~2px high (caps 2.75px off the top against 5.7px of air
|
|
383
|
+
under the baseline, measured at dense). 0.08em splits the difference
|
|
384
|
+
between the x-band ideal and the cap-band ideal, landing caps ~3.7px in an
|
|
385
|
+
18px field with ~4.7px under the baseline — the reading where neither
|
|
386
|
+
band's partisans win and neither complains.
|
|
387
|
+
|
|
388
|
+
The lift is padding, not a translateY: an icon-less Input paints the field
|
|
389
|
+
chrome itself, and a transform would drag the field along with the ink.
|
|
390
|
+
padding-bottom shrinks the content box from below, and a single-line input
|
|
391
|
+
re-centres its line box in what remains — the ink rises by exactly half the
|
|
392
|
+
padding, the chrome doesn't move, and the caret and selection follow the
|
|
393
|
+
text. In em on purpose: the correction is a fraction of the type, so it
|
|
394
|
+
holds across every density and text size with one value.
|
|
395
|
+
|
|
396
|
+
Declared in `index.css`.
|
|
397
|
+
|
|
398
|
+
```css
|
|
399
|
+
@utility era-ink-center {
|
|
400
|
+
padding-bottom: 0.08em;
|
|
401
|
+
}
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
## era-token-ink
|
|
361
405
|
|
|
362
|
-
**Use it for:** the ink centring for a token pill — a badge, a KV value, any short caps-or-digits label in a fixed-height box
|
|
406
|
+
**Use it for:** the ink centring for a token pill — a badge, a KV value, any short caps-or-digits label in a fixed-height box, CENTRED horizontally and with no icon sibling. For a left-aligned sentence-case label use era-label-ink; when an icon really must sit beside the text, see the note there.
|
|
363
407
|
|
|
364
408
|
TOKEN INK — the ink centring for a pill whose content is a TOKEN: an id, a
|
|
365
409
|
count, a status, a tag. Font-independent, unlike everything it replaces.
|
|
@@ -398,9 +442,45 @@ Declared in `index.css`.
|
|
|
398
442
|
line-height: 1;
|
|
399
443
|
text-box: trim-both cap alphabetic;
|
|
400
444
|
}
|
|
445
|
+
```
|
|
401
446
|
|
|
402
|
-
|
|
403
|
-
|
|
447
|
+
## era-label-ink
|
|
448
|
+
|
|
449
|
+
**Use it for:** the ink centring for a fixed-height control holding ONE line of sentence-case text and no icon — a menu item, a nav trigger, a button label. Never alongside `truncate` (the trimmed box becomes the clip).
|
|
450
|
+
|
|
451
|
+
LABEL INK — era-token-ink's mixed-case sibling, and the general answer to
|
|
452
|
+
"this fixed-height control holds one line of text".
|
|
453
|
+
|
|
454
|
+
Same mechanism, same reason: `text-box-trim` needs a BLOCK box, so the row
|
|
455
|
+
becomes one and `align-content` (block-container alignment) does the
|
|
456
|
+
centring. What differs is the band and the alignment, because the content
|
|
457
|
+
class differs — a label is sentence case, so the x-height band is the visual
|
|
458
|
+
mass to centre (cap-band reads low on "System"), and it is laid out against
|
|
459
|
+
the row's padding rather than centred in it.
|
|
460
|
+
|
|
461
|
+
WHY IT EXISTS AT ALL: era's controls are flex, and a flex container's bare
|
|
462
|
+
text is an ANONYMOUS flex item — a box no selector reaches and no
|
|
463
|
+
non-inherited property touches. So `era-text-trim` on a flex row is inert,
|
|
464
|
+
contributing only its `line-height: 1`, and the ink falls back to line-box
|
|
465
|
+
centring by font metrics. era-token-ink already fixed that for centred
|
|
466
|
+
tokens; this fixes it for everything else.
|
|
467
|
+
|
|
468
|
+
THE ICON CASE IS NOT SOLVED, and cannot be from CSS: an icon beside the text
|
|
469
|
+
needs the box to stay flex, which re-creates the anonymous item. A component
|
|
470
|
+
whose children are an opaque slot therefore guards it —
|
|
471
|
+
`not-has-[svg]:era-label-ink` — and ink-centres the text-only case while
|
|
472
|
+
leaving the icon case on line-box centring. Splitting icon and label into
|
|
473
|
+
separate slots is what would close it; typography/inert-trim reports every
|
|
474
|
+
site still on the fallback.
|
|
475
|
+
|
|
476
|
+
Declared in `index.css`.
|
|
477
|
+
|
|
478
|
+
```css
|
|
479
|
+
@utility era-label-ink {
|
|
480
|
+
display: block;
|
|
481
|
+
align-content: center;
|
|
482
|
+
line-height: 1;
|
|
483
|
+
text-box: trim-both ex alphabetic;
|
|
404
484
|
}
|
|
405
485
|
```
|
|
406
486
|
|
|
@@ -755,13 +835,13 @@ A complete notes app — rich-text editor, slash commands, local persistence.
|
|
|
755
835
|
|
|
756
836
|
## Usage
|
|
757
837
|
|
|
758
|
-
Apps ship on their own subpath and are **not** re-exported from `@
|
|
838
|
+
Apps ship on their own subpath and are **not** re-exported from `@signal9/era-ui`.
|
|
759
839
|
Notes carries TipTap, and a consumer who never imports an app should never pay
|
|
760
840
|
for it.
|
|
761
841
|
|
|
762
842
|
```svelte
|
|
763
843
|
<script>
|
|
764
|
-
import { Notes } from '@
|
|
844
|
+
import { Notes } from '@signal9/era-ui/apps';
|
|
765
845
|
</script>
|
|
766
846
|
|
|
767
847
|
<Notes />
|
|
@@ -801,7 +881,7 @@ Persistence is one small interface, so server-backed hosting is a drop-in swap
|
|
|
801
881
|
`load`/`save` may be sync or async:
|
|
802
882
|
|
|
803
883
|
```ts
|
|
804
|
-
import { Notes, NotesStore } from '@
|
|
884
|
+
import { Notes, NotesStore } from '@signal9/era-ui/apps';
|
|
805
885
|
|
|
806
886
|
const store = new NotesStore({
|
|
807
887
|
adapter: {
|
|
@@ -38,18 +38,20 @@ Full derivations: `{{ORIGIN}}/spacing.md` (the ladder and every token), `{{ORIGI
|
|
|
38
38
|
|
|
39
39
|
## Using the library
|
|
40
40
|
|
|
41
|
+
This package is published to two registries under two names: `@signal9/era-ui` on npm (used throughout these docs) and `@sig-nine/era-ui` on GitHub Packages, where the scope must match the repo owner. Same code, same versions — pick the one your registry serves and keep the scope consistent.
|
|
42
|
+
|
|
41
43
|
**One entry point per component.** There is no barrel that re-exports everything — importing a component can never drag in another one, or another one's dependencies.
|
|
42
44
|
|
|
43
45
|
```ts
|
|
44
|
-
import { Button } from "@
|
|
45
|
-
import * as Select from "@
|
|
46
|
-
import * as Table from "@
|
|
46
|
+
import { Button } from "@signal9/era-ui/button";
|
|
47
|
+
import * as Select from "@signal9/era-ui/select";
|
|
48
|
+
import * as Table from "@signal9/era-ui/table";
|
|
47
49
|
|
|
48
50
|
// The root is the SYSTEM layer only: cn/tv, keybindings, the axis
|
|
49
51
|
// registry, and Mode. It imports no component.
|
|
50
|
-
import { cn, ModeProvider } from "@
|
|
52
|
+
import { cn, ModeProvider } from "@signal9/era-ui";
|
|
51
53
|
|
|
52
|
-
import "@
|
|
54
|
+
import "@signal9/era-ui/styles"; // source CSS, scanned by your Tailwind
|
|
53
55
|
```
|
|
54
56
|
|
|
55
57
|
The path is always the component's own kebab-case name — `/button`, `/dropdown-menu`, `/date-range-picker` — and the other layers are namespaced: `/ai` and `/ai/<part>`, `/apps/<app>`, `/os`, `/audit`.
|
|
@@ -58,7 +60,7 @@ Named exports wrap a single primitive (`Button`, `Badge`, `Chip`, `Input`, …).
|
|
|
58
60
|
|
|
59
61
|
### Stylesheets
|
|
60
62
|
|
|
61
|
-
`@
|
|
63
|
+
`@signal9/era-ui/styles` is the source CSS — import it once and your own Tailwind build scans era's components and emits only the utilities they use. `@signal9/era-ui/css` is the prebuilt alternative for a project without Tailwind. Three more are opt-in, each single-purpose: `/styles/video-player` (vidstack's vendor CSS, needed only with `VideoPlayer`), `/styles/prose` (document typography for a TipTap editor — put `era-notes-prose` on your editor element; `NoteEditor` imports it already), and `/styles/themes` (the raw theme tokens).
|
|
62
64
|
|
|
63
65
|
### Optional peers
|
|
64
66
|
|
|
@@ -96,7 +98,9 @@ Classes, not components — they need no import beyond the stylesheet. Reach for
|
|
|
96
98
|
- `era-text-trim` — vertically center single-line control text (a label beside an icon, a button's own text) without a translateY nudge. Fixed-height, non-editable elements ONLY: never on an <input>/<textarea>, and never on the same element as `truncate` or any overflow clip — put it on the fixed-height ROW and let the truncating child centre inside it. See era-text-trim-caps for ALL-CAPS.
|
|
97
99
|
- `truncate` — single-line horizontal truncation with an ellipsis — put it on the truncating CHILD inside a trimmed or leading-none row, never on the same element as era-text-trim; it will not clip ascenders or descenders.
|
|
98
100
|
- `era-text-trim-caps` — the era-text-trim variant for ALL-CAPS single-line strings (kbd hints, acronym badges) — never for mixed-case text (a label like "System" reads high; use era-text-trim), and never on the same element as `truncate`.
|
|
99
|
-
- `era-
|
|
101
|
+
- `era-ink-center` — on a native single-line <input> (or the text layer that must mirror one) inside a fixed-height field — never alongside era-text-trim.
|
|
102
|
+
- `era-token-ink` — the ink centring for a token pill — a badge, a KV value, any short caps-or-digits label in a fixed-height box, CENTRED horizontally and with no icon sibling. For a left-aligned sentence-case label use era-label-ink; when an icon really must sit beside the text, see the note there.
|
|
103
|
+
- `era-label-ink` — the ink centring for a fixed-height control holding ONE line of sentence-case text and no icon — a menu item, a nav trigger, a button label. Never alongside `truncate` (the trimmed box becomes the clip).
|
|
100
104
|
- `era-shimmer` — the in-progress text treatment — put it on a "working…" / "thinking…" label while a task streams, instead of a spinner beside the text.
|
|
101
105
|
- `era-collapse` — the height sweep for a bits-ui Collapsible.Content — put it on the Content element itself (it carries its own overflow: hidden).
|
|
102
106
|
- `h-icon · h-pill · h-chip · h-control · h-bar` — the tier-height ladder — h-icon (icon) · h-pill (nested pill) · h-chip (standalone pill) · h-control (control) · h-bar (bar); the named form of h-(--era-h-*).
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"slug": "utilities",
|
|
45
45
|
"title": "Utilities",
|
|
46
46
|
"summary": "The CSS classes era ships alongside the components — links, ink-centred text, shimmer, hidden scrollbars.",
|
|
47
|
-
"tokenEstimate":
|
|
47
|
+
"tokenEstimate": 7162,
|
|
48
48
|
"sections": [
|
|
49
49
|
"Overview",
|
|
50
50
|
"era-interactive",
|
|
@@ -53,7 +53,9 @@
|
|
|
53
53
|
"era-text-trim",
|
|
54
54
|
"truncate",
|
|
55
55
|
"era-text-trim-caps",
|
|
56
|
-
"era-
|
|
56
|
+
"era-ink-center",
|
|
57
|
+
"era-token-ink",
|
|
58
|
+
"era-label-ink",
|
|
57
59
|
"era-shimmer",
|
|
58
60
|
"era-collapse",
|
|
59
61
|
"h-icon · h-pill · h-chip · h-control · h-bar",
|
|
@@ -107,7 +109,7 @@
|
|
|
107
109
|
"slug": "notes",
|
|
108
110
|
"title": "Notes",
|
|
109
111
|
"summary": "A complete notes app — rich-text editor, slash commands, local persistence.",
|
|
110
|
-
"tokenEstimate":
|
|
112
|
+
"tokenEstimate": 884,
|
|
111
113
|
"sections": [
|
|
112
114
|
"Usage",
|
|
113
115
|
"Peer dependencies",
|
|
@@ -1022,15 +1024,34 @@
|
|
|
1022
1024
|
"css": "@utility era-text-trim-caps {\n\tline-height: 1;\n\ttext-box: trim-both cap alphabetic;\n}"
|
|
1023
1025
|
},
|
|
1024
1026
|
{
|
|
1025
|
-
"name": "era-
|
|
1027
|
+
"name": "era-ink-center",
|
|
1026
1028
|
"names": [
|
|
1027
|
-
"era-token-ink",
|
|
1028
1029
|
"era-ink-center"
|
|
1029
1030
|
],
|
|
1030
1031
|
"file": "index.css",
|
|
1031
|
-
"useCase": "
|
|
1032
|
+
"useCase": "on a native single-line <input> (or the text layer that must mirror one) inside a fixed-height field — never alongside era-text-trim.",
|
|
1033
|
+
"description": "The EDITABLE counterpart of era-text-trim — for native <input>s, which the\ntrim is forbidden on (it collapses the UA's inner editor box and slices the\nglyphs; see typography/collapsed-text-trim).\n\nWithout help, a tier-height input centres its text by FONT BOX, and the ui\nstacks' font box is deeply asymmetric: ascent ≈1.07em against descent\n≈0.29em. Centring that box parks the visible band (caps, x-height) ~0.115em\nLOW — so a field's text sat visibly below the trimmed label beside it.\n\nThe value is OPTICAL, not the derivation's: pure x-band centring computes\nto ~0.23em of padding, but pixel-measured against real Title-Case text it\nover-lifts — the eye weighs the cap-to-baseline mass, which x-band\ncentring parks ~2px high (caps 2.75px off the top against 5.7px of air\nunder the baseline, measured at dense). 0.08em splits the difference\nbetween the x-band ideal and the cap-band ideal, landing caps ~3.7px in an\n18px field with ~4.7px under the baseline — the reading where neither\nband's partisans win and neither complains.\n\nThe lift is padding, not a translateY: an icon-less Input paints the field\nchrome itself, and a transform would drag the field along with the ink.\npadding-bottom shrinks the content box from below, and a single-line input\nre-centres its line box in what remains — the ink rises by exactly half the\npadding, the chrome doesn't move, and the caret and selection follow the\ntext. In em on purpose: the correction is a fraction of the type, so it\nholds across every density and text size with one value.",
|
|
1034
|
+
"css": "@utility era-ink-center {\n\tpadding-bottom: 0.08em;\n}"
|
|
1035
|
+
},
|
|
1036
|
+
{
|
|
1037
|
+
"name": "era-token-ink",
|
|
1038
|
+
"names": [
|
|
1039
|
+
"era-token-ink"
|
|
1040
|
+
],
|
|
1041
|
+
"file": "index.css",
|
|
1042
|
+
"useCase": "the ink centring for a token pill — a badge, a KV value, any short caps-or-digits label in a fixed-height box, CENTRED horizontally and with no icon sibling. For a left-aligned sentence-case label use era-label-ink; when an icon really must sit beside the text, see the note there.",
|
|
1032
1043
|
"description": "TOKEN INK — the ink centring for a pill whose content is a TOKEN: an id, a\ncount, a status, a tag. Font-independent, unlike everything it replaces.\n\nTHE BUG IT FIXES, which had been shipping library-wide and invisibly:\n`text-box-trim` DOES NOTHING ON A FLEX CONTAINER. Era's controls are all\nflex, and a flex container's bare text becomes an ANONYMOUS flex item — a box\nno selector can reach and no non-inherited property can touch. So\n`era-text-trim` on a Badge, a Chip, a Button or a Bar contributed exactly one\nthing: `line-height: 1`. The ink was then centred by `align-items: center`\non the LINE BOX, which is precisely the font-metric-dependent centring the\ntrim exists to eliminate. Measured on the shipped mono stack: a badge reading\n\"AC-2.1\" sat 2px high in an 18px pill, and no amount of tuning the trim's\nBAND changed it, because the trim was never running.\n\nThe mechanism here restores it: a BLOCK box (where text-box-trim does apply)\nwhose trimmed line box is then centred by `align-content` — block-container\nalignment, so no flex formatting context and no anonymous item. The browser\ncomputes the band from the font's own metrics, which is what makes it hold\nacross ui-monospace, system-ui and ui-serif instead of needing a constant\nper stack.\n\nCAP band, not the x-height band the general trim uses, because the content\nclass is different: a token is caps and digits (both cap-height), and\ncentring the x-band parks them high by (cap − x)/2. Measured on the shipped\nstacks, cap-band centring takes an id/count/status from −2.0px to 0.0.\nProse and sentence-case labels keep era-text-trim; this is for tokens.",
|
|
1033
|
-
"css": "@utility era-token-ink {\n\tdisplay: block;\n\talign-content: center;\n\ttext-align: center;\n\tline-height: 1;\n\ttext-box: trim-both cap alphabetic;\n}
|
|
1044
|
+
"css": "@utility era-token-ink {\n\tdisplay: block;\n\talign-content: center;\n\ttext-align: center;\n\tline-height: 1;\n\ttext-box: trim-both cap alphabetic;\n}"
|
|
1045
|
+
},
|
|
1046
|
+
{
|
|
1047
|
+
"name": "era-label-ink",
|
|
1048
|
+
"names": [
|
|
1049
|
+
"era-label-ink"
|
|
1050
|
+
],
|
|
1051
|
+
"file": "index.css",
|
|
1052
|
+
"useCase": "the ink centring for a fixed-height control holding ONE line of sentence-case text and no icon — a menu item, a nav trigger, a button label. Never alongside `truncate` (the trimmed box becomes the clip).",
|
|
1053
|
+
"description": "LABEL INK — era-token-ink's mixed-case sibling, and the general answer to\n\"this fixed-height control holds one line of text\".\n\nSame mechanism, same reason: `text-box-trim` needs a BLOCK box, so the row\nbecomes one and `align-content` (block-container alignment) does the\ncentring. What differs is the band and the alignment, because the content\nclass differs — a label is sentence case, so the x-height band is the visual\nmass to centre (cap-band reads low on \"System\"), and it is laid out against\nthe row's padding rather than centred in it.\n\nWHY IT EXISTS AT ALL: era's controls are flex, and a flex container's bare\ntext is an ANONYMOUS flex item — a box no selector reaches and no\nnon-inherited property touches. So `era-text-trim` on a flex row is inert,\ncontributing only its `line-height: 1`, and the ink falls back to line-box\ncentring by font metrics. era-token-ink already fixed that for centred\ntokens; this fixes it for everything else.\n\nTHE ICON CASE IS NOT SOLVED, and cannot be from CSS: an icon beside the text\nneeds the box to stay flex, which re-creates the anonymous item. A component\nwhose children are an opaque slot therefore guards it —\n`not-has-[svg]:era-label-ink` — and ink-centres the text-only case while\nleaving the icon case on line-box centring. Splitting icon and label into\nseparate slots is what would close it; typography/inert-trim reports every\nsite still on the fallback.",
|
|
1054
|
+
"css": "@utility era-label-ink {\n\tdisplay: block;\n\talign-content: center;\n\tline-height: 1;\n\ttext-box: trim-both ex alphabetic;\n}"
|
|
1034
1055
|
},
|
|
1035
1056
|
{
|
|
1036
1057
|
"name": "era-shimmer",
|
|
@@ -4,13 +4,13 @@ A complete notes app — rich-text editor, slash commands, local persistence.
|
|
|
4
4
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
7
|
-
Apps ship on their own subpath and are **not** re-exported from `@
|
|
7
|
+
Apps ship on their own subpath and are **not** re-exported from `@signal9/era-ui`.
|
|
8
8
|
Notes carries TipTap, and a consumer who never imports an app should never pay
|
|
9
9
|
for it.
|
|
10
10
|
|
|
11
11
|
```svelte
|
|
12
12
|
<script>
|
|
13
|
-
import { Notes } from '@
|
|
13
|
+
import { Notes } from '@signal9/era-ui/apps';
|
|
14
14
|
</script>
|
|
15
15
|
|
|
16
16
|
<Notes />
|
|
@@ -50,7 +50,7 @@ Persistence is one small interface, so server-backed hosting is a drop-in swap
|
|
|
50
50
|
`load`/`save` may be sync or async:
|
|
51
51
|
|
|
52
52
|
```ts
|
|
53
|
-
import { Notes, NotesStore } from '@
|
|
53
|
+
import { Notes, NotesStore } from '@signal9/era-ui/apps';
|
|
54
54
|
|
|
55
55
|
const store = new NotesStore({
|
|
56
56
|
adapter: {
|
|
@@ -61,15 +61,34 @@
|
|
|
61
61
|
"css": "@utility era-text-trim-caps {\n\tline-height: 1;\n\ttext-box: trim-both cap alphabetic;\n}"
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
|
-
"name": "era-
|
|
64
|
+
"name": "era-ink-center",
|
|
65
65
|
"names": [
|
|
66
|
-
"era-token-ink",
|
|
67
66
|
"era-ink-center"
|
|
68
67
|
],
|
|
69
68
|
"file": "index.css",
|
|
70
|
-
"useCase": "
|
|
69
|
+
"useCase": "on a native single-line <input> (or the text layer that must mirror one) inside a fixed-height field — never alongside era-text-trim.",
|
|
70
|
+
"description": "The EDITABLE counterpart of era-text-trim — for native <input>s, which the\ntrim is forbidden on (it collapses the UA's inner editor box and slices the\nglyphs; see typography/collapsed-text-trim).\n\nWithout help, a tier-height input centres its text by FONT BOX, and the ui\nstacks' font box is deeply asymmetric: ascent ≈1.07em against descent\n≈0.29em. Centring that box parks the visible band (caps, x-height) ~0.115em\nLOW — so a field's text sat visibly below the trimmed label beside it.\n\nThe value is OPTICAL, not the derivation's: pure x-band centring computes\nto ~0.23em of padding, but pixel-measured against real Title-Case text it\nover-lifts — the eye weighs the cap-to-baseline mass, which x-band\ncentring parks ~2px high (caps 2.75px off the top against 5.7px of air\nunder the baseline, measured at dense). 0.08em splits the difference\nbetween the x-band ideal and the cap-band ideal, landing caps ~3.7px in an\n18px field with ~4.7px under the baseline — the reading where neither\nband's partisans win and neither complains.\n\nThe lift is padding, not a translateY: an icon-less Input paints the field\nchrome itself, and a transform would drag the field along with the ink.\npadding-bottom shrinks the content box from below, and a single-line input\nre-centres its line box in what remains — the ink rises by exactly half the\npadding, the chrome doesn't move, and the caret and selection follow the\ntext. In em on purpose: the correction is a fraction of the type, so it\nholds across every density and text size with one value.",
|
|
71
|
+
"css": "@utility era-ink-center {\n\tpadding-bottom: 0.08em;\n}"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"name": "era-token-ink",
|
|
75
|
+
"names": [
|
|
76
|
+
"era-token-ink"
|
|
77
|
+
],
|
|
78
|
+
"file": "index.css",
|
|
79
|
+
"useCase": "the ink centring for a token pill — a badge, a KV value, any short caps-or-digits label in a fixed-height box, CENTRED horizontally and with no icon sibling. For a left-aligned sentence-case label use era-label-ink; when an icon really must sit beside the text, see the note there.",
|
|
71
80
|
"description": "TOKEN INK — the ink centring for a pill whose content is a TOKEN: an id, a\ncount, a status, a tag. Font-independent, unlike everything it replaces.\n\nTHE BUG IT FIXES, which had been shipping library-wide and invisibly:\n`text-box-trim` DOES NOTHING ON A FLEX CONTAINER. Era's controls are all\nflex, and a flex container's bare text becomes an ANONYMOUS flex item — a box\nno selector can reach and no non-inherited property can touch. So\n`era-text-trim` on a Badge, a Chip, a Button or a Bar contributed exactly one\nthing: `line-height: 1`. The ink was then centred by `align-items: center`\non the LINE BOX, which is precisely the font-metric-dependent centring the\ntrim exists to eliminate. Measured on the shipped mono stack: a badge reading\n\"AC-2.1\" sat 2px high in an 18px pill, and no amount of tuning the trim's\nBAND changed it, because the trim was never running.\n\nThe mechanism here restores it: a BLOCK box (where text-box-trim does apply)\nwhose trimmed line box is then centred by `align-content` — block-container\nalignment, so no flex formatting context and no anonymous item. The browser\ncomputes the band from the font's own metrics, which is what makes it hold\nacross ui-monospace, system-ui and ui-serif instead of needing a constant\nper stack.\n\nCAP band, not the x-height band the general trim uses, because the content\nclass is different: a token is caps and digits (both cap-height), and\ncentring the x-band parks them high by (cap − x)/2. Measured on the shipped\nstacks, cap-band centring takes an id/count/status from −2.0px to 0.0.\nProse and sentence-case labels keep era-text-trim; this is for tokens.",
|
|
72
|
-
"css": "@utility era-token-ink {\n\tdisplay: block;\n\talign-content: center;\n\ttext-align: center;\n\tline-height: 1;\n\ttext-box: trim-both cap alphabetic;\n}
|
|
81
|
+
"css": "@utility era-token-ink {\n\tdisplay: block;\n\talign-content: center;\n\ttext-align: center;\n\tline-height: 1;\n\ttext-box: trim-both cap alphabetic;\n}"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"name": "era-label-ink",
|
|
85
|
+
"names": [
|
|
86
|
+
"era-label-ink"
|
|
87
|
+
],
|
|
88
|
+
"file": "index.css",
|
|
89
|
+
"useCase": "the ink centring for a fixed-height control holding ONE line of sentence-case text and no icon — a menu item, a nav trigger, a button label. Never alongside `truncate` (the trimmed box becomes the clip).",
|
|
90
|
+
"description": "LABEL INK — era-token-ink's mixed-case sibling, and the general answer to\n\"this fixed-height control holds one line of text\".\n\nSame mechanism, same reason: `text-box-trim` needs a BLOCK box, so the row\nbecomes one and `align-content` (block-container alignment) does the\ncentring. What differs is the band and the alignment, because the content\nclass differs — a label is sentence case, so the x-height band is the visual\nmass to centre (cap-band reads low on \"System\"), and it is laid out against\nthe row's padding rather than centred in it.\n\nWHY IT EXISTS AT ALL: era's controls are flex, and a flex container's bare\ntext is an ANONYMOUS flex item — a box no selector reaches and no\nnon-inherited property touches. So `era-text-trim` on a flex row is inert,\ncontributing only its `line-height: 1`, and the ink falls back to line-box\ncentring by font metrics. era-token-ink already fixed that for centred\ntokens; this fixes it for everything else.\n\nTHE ICON CASE IS NOT SOLVED, and cannot be from CSS: an icon beside the text\nneeds the box to stay flex, which re-creates the anonymous item. A component\nwhose children are an opaque slot therefore guards it —\n`not-has-[svg]:era-label-ink` — and ink-centres the text-only case while\nleaving the icon case on line-box centring. Splitting icon and label into\nseparate slots is what would close it; typography/inert-trim reports every\nsite still on the fallback.",
|
|
91
|
+
"css": "@utility era-label-ink {\n\tdisplay: block;\n\talign-content: center;\n\tline-height: 1;\n\ttext-box: trim-both ex alphabetic;\n}"
|
|
73
92
|
},
|
|
74
93
|
{
|
|
75
94
|
"name": "era-shimmer",
|
|
@@ -9,7 +9,7 @@ never the `h-(--era-h-control)` var-class spelling. Everything below rides along
|
|
|
9
9
|
with the stylesheet and needs no import:
|
|
10
10
|
|
|
11
11
|
```ts
|
|
12
|
-
import "@
|
|
12
|
+
import "@signal9/era-ui/css";
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
```svelte
|
|
@@ -44,7 +44,9 @@ enough to stay var-form — `min-w-(--era-h-control)` etc. remain the escape hat
|
|
|
44
44
|
| `era-text-trim` | vertically center single-line control text (a label beside an icon, a button's own text) without a translateY nudge. Fixed-height, non-editable elements ONLY: never on an <input>/<textarea>, and never on the same element as `truncate` or any overflow clip — put it on the fixed-height ROW and let the truncating child centre inside it. See era-text-trim-caps for ALL-CAPS. |
|
|
45
45
|
| `truncate` | single-line horizontal truncation with an ellipsis — put it on the truncating CHILD inside a trimmed or leading-none row, never on the same element as era-text-trim; it will not clip ascenders or descenders. |
|
|
46
46
|
| `era-text-trim-caps` | the era-text-trim variant for ALL-CAPS single-line strings (kbd hints, acronym badges) — never for mixed-case text (a label like "System" reads high; use era-text-trim), and never on the same element as `truncate`. |
|
|
47
|
-
| `era-
|
|
47
|
+
| `era-ink-center` | on a native single-line <input> (or the text layer that must mirror one) inside a fixed-height field — never alongside era-text-trim. |
|
|
48
|
+
| `era-token-ink` | the ink centring for a token pill — a badge, a KV value, any short caps-or-digits label in a fixed-height box, CENTRED horizontally and with no icon sibling. For a left-aligned sentence-case label use era-label-ink; when an icon really must sit beside the text, see the note there. |
|
|
49
|
+
| `era-label-ink` | the ink centring for a fixed-height control holding ONE line of sentence-case text and no icon — a menu item, a nav trigger, a button label. Never alongside `truncate` (the trimmed box becomes the clip). |
|
|
48
50
|
| `era-shimmer` | the in-progress text treatment — put it on a "working…" / "thinking…" label while a task streams, instead of a spinner beside the text. |
|
|
49
51
|
| `era-collapse` | the height sweep for a bits-ui Collapsible.Content — put it on the Content element itself (it carries its own overflow: hidden). |
|
|
50
52
|
| `h-icon` `h-pill` `h-chip` `h-control` `h-bar` | the tier-height ladder — h-icon (icon) · h-pill (nested pill) · h-chip (standalone pill) · h-control (control) · h-bar (bar); the named form of h-(--era-h-*). |
|
|
@@ -235,9 +237,47 @@ Declared in `index.css`.
|
|
|
235
237
|
}
|
|
236
238
|
```
|
|
237
239
|
|
|
238
|
-
## era-
|
|
240
|
+
## era-ink-center
|
|
239
241
|
|
|
240
|
-
**Use it for:**
|
|
242
|
+
**Use it for:** on a native single-line <input> (or the text layer that must mirror one) inside a fixed-height field — never alongside era-text-trim.
|
|
243
|
+
|
|
244
|
+
The EDITABLE counterpart of era-text-trim — for native <input>s, which the
|
|
245
|
+
trim is forbidden on (it collapses the UA's inner editor box and slices the
|
|
246
|
+
glyphs; see typography/collapsed-text-trim).
|
|
247
|
+
|
|
248
|
+
Without help, a tier-height input centres its text by FONT BOX, and the ui
|
|
249
|
+
stacks' font box is deeply asymmetric: ascent ≈1.07em against descent
|
|
250
|
+
≈0.29em. Centring that box parks the visible band (caps, x-height) ~0.115em
|
|
251
|
+
LOW — so a field's text sat visibly below the trimmed label beside it.
|
|
252
|
+
|
|
253
|
+
The value is OPTICAL, not the derivation's: pure x-band centring computes
|
|
254
|
+
to ~0.23em of padding, but pixel-measured against real Title-Case text it
|
|
255
|
+
over-lifts — the eye weighs the cap-to-baseline mass, which x-band
|
|
256
|
+
centring parks ~2px high (caps 2.75px off the top against 5.7px of air
|
|
257
|
+
under the baseline, measured at dense). 0.08em splits the difference
|
|
258
|
+
between the x-band ideal and the cap-band ideal, landing caps ~3.7px in an
|
|
259
|
+
18px field with ~4.7px under the baseline — the reading where neither
|
|
260
|
+
band's partisans win and neither complains.
|
|
261
|
+
|
|
262
|
+
The lift is padding, not a translateY: an icon-less Input paints the field
|
|
263
|
+
chrome itself, and a transform would drag the field along with the ink.
|
|
264
|
+
padding-bottom shrinks the content box from below, and a single-line input
|
|
265
|
+
re-centres its line box in what remains — the ink rises by exactly half the
|
|
266
|
+
padding, the chrome doesn't move, and the caret and selection follow the
|
|
267
|
+
text. In em on purpose: the correction is a fraction of the type, so it
|
|
268
|
+
holds across every density and text size with one value.
|
|
269
|
+
|
|
270
|
+
Declared in `index.css`.
|
|
271
|
+
|
|
272
|
+
```css
|
|
273
|
+
@utility era-ink-center {
|
|
274
|
+
padding-bottom: 0.08em;
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## era-token-ink
|
|
279
|
+
|
|
280
|
+
**Use it for:** the ink centring for a token pill — a badge, a KV value, any short caps-or-digits label in a fixed-height box, CENTRED horizontally and with no icon sibling. For a left-aligned sentence-case label use era-label-ink; when an icon really must sit beside the text, see the note there.
|
|
241
281
|
|
|
242
282
|
TOKEN INK — the ink centring for a pill whose content is a TOKEN: an id, a
|
|
243
283
|
count, a status, a tag. Font-independent, unlike everything it replaces.
|
|
@@ -276,9 +316,45 @@ Declared in `index.css`.
|
|
|
276
316
|
line-height: 1;
|
|
277
317
|
text-box: trim-both cap alphabetic;
|
|
278
318
|
}
|
|
319
|
+
```
|
|
279
320
|
|
|
280
|
-
|
|
281
|
-
|
|
321
|
+
## era-label-ink
|
|
322
|
+
|
|
323
|
+
**Use it for:** the ink centring for a fixed-height control holding ONE line of sentence-case text and no icon — a menu item, a nav trigger, a button label. Never alongside `truncate` (the trimmed box becomes the clip).
|
|
324
|
+
|
|
325
|
+
LABEL INK — era-token-ink's mixed-case sibling, and the general answer to
|
|
326
|
+
"this fixed-height control holds one line of text".
|
|
327
|
+
|
|
328
|
+
Same mechanism, same reason: `text-box-trim` needs a BLOCK box, so the row
|
|
329
|
+
becomes one and `align-content` (block-container alignment) does the
|
|
330
|
+
centring. What differs is the band and the alignment, because the content
|
|
331
|
+
class differs — a label is sentence case, so the x-height band is the visual
|
|
332
|
+
mass to centre (cap-band reads low on "System"), and it is laid out against
|
|
333
|
+
the row's padding rather than centred in it.
|
|
334
|
+
|
|
335
|
+
WHY IT EXISTS AT ALL: era's controls are flex, and a flex container's bare
|
|
336
|
+
text is an ANONYMOUS flex item — a box no selector reaches and no
|
|
337
|
+
non-inherited property touches. So `era-text-trim` on a flex row is inert,
|
|
338
|
+
contributing only its `line-height: 1`, and the ink falls back to line-box
|
|
339
|
+
centring by font metrics. era-token-ink already fixed that for centred
|
|
340
|
+
tokens; this fixes it for everything else.
|
|
341
|
+
|
|
342
|
+
THE ICON CASE IS NOT SOLVED, and cannot be from CSS: an icon beside the text
|
|
343
|
+
needs the box to stay flex, which re-creates the anonymous item. A component
|
|
344
|
+
whose children are an opaque slot therefore guards it —
|
|
345
|
+
`not-has-[svg]:era-label-ink` — and ink-centres the text-only case while
|
|
346
|
+
leaving the icon case on line-box centring. Splitting icon and label into
|
|
347
|
+
separate slots is what would close it; typography/inert-trim reports every
|
|
348
|
+
site still on the fallback.
|
|
349
|
+
|
|
350
|
+
Declared in `index.css`.
|
|
351
|
+
|
|
352
|
+
```css
|
|
353
|
+
@utility era-label-ink {
|
|
354
|
+
display: block;
|
|
355
|
+
align-content: center;
|
|
356
|
+
line-height: 1;
|
|
357
|
+
text-box: trim-both ex alphabetic;
|
|
282
358
|
}
|
|
283
359
|
```
|
|
284
360
|
|
package/dist/styles/index.css
CHANGED
|
@@ -227,7 +227,9 @@
|
|
|
227
227
|
* the pair so the runtime audit can point at it). It exists so the failure mode
|
|
228
228
|
* is a no-op instead of unreadable text. */
|
|
229
229
|
.era-text-trim.truncate,
|
|
230
|
-
.era-text-trim-caps.truncate
|
|
230
|
+
.era-text-trim-caps.truncate,
|
|
231
|
+
.era-label-ink.truncate,
|
|
232
|
+
.era-token-ink.truncate {
|
|
231
233
|
line-height: normal;
|
|
232
234
|
text-box: normal;
|
|
233
235
|
}
|
|
@@ -271,6 +273,10 @@
|
|
|
271
273
|
*
|
|
272
274
|
* @use on a native single-line <input> (or the text layer that must mirror
|
|
273
275
|
* one) inside a fixed-height field — never alongside era-text-trim. */
|
|
276
|
+
@utility era-ink-center {
|
|
277
|
+
padding-bottom: 0.08em;
|
|
278
|
+
}
|
|
279
|
+
|
|
274
280
|
/* TOKEN INK — the ink centring for a pill whose content is a TOKEN: an id, a
|
|
275
281
|
* count, a status, a tag. Font-independent, unlike everything it replaces.
|
|
276
282
|
*
|
|
@@ -299,8 +305,9 @@
|
|
|
299
305
|
* Prose and sentence-case labels keep era-text-trim; this is for tokens.
|
|
300
306
|
*
|
|
301
307
|
* @use the ink centring for a token pill — a badge, a KV value, any short
|
|
302
|
-
* caps-or-digits label in a fixed-height box
|
|
303
|
-
*
|
|
308
|
+
* caps-or-digits label in a fixed-height box, CENTRED horizontally and with no
|
|
309
|
+
* icon sibling. For a left-aligned sentence-case label use era-label-ink; when
|
|
310
|
+
* an icon really must sit beside the text, see the note there. */
|
|
304
311
|
@utility era-token-ink {
|
|
305
312
|
display: block;
|
|
306
313
|
align-content: center;
|
|
@@ -309,8 +316,39 @@
|
|
|
309
316
|
text-box: trim-both cap alphabetic;
|
|
310
317
|
}
|
|
311
318
|
|
|
312
|
-
|
|
313
|
-
|
|
319
|
+
/* LABEL INK — era-token-ink's mixed-case sibling, and the general answer to
|
|
320
|
+
* "this fixed-height control holds one line of text".
|
|
321
|
+
*
|
|
322
|
+
* Same mechanism, same reason: `text-box-trim` needs a BLOCK box, so the row
|
|
323
|
+
* becomes one and `align-content` (block-container alignment) does the
|
|
324
|
+
* centring. What differs is the band and the alignment, because the content
|
|
325
|
+
* class differs — a label is sentence case, so the x-height band is the visual
|
|
326
|
+
* mass to centre (cap-band reads low on "System"), and it is laid out against
|
|
327
|
+
* the row's padding rather than centred in it.
|
|
328
|
+
*
|
|
329
|
+
* WHY IT EXISTS AT ALL: era's controls are flex, and a flex container's bare
|
|
330
|
+
* text is an ANONYMOUS flex item — a box no selector reaches and no
|
|
331
|
+
* non-inherited property touches. So `era-text-trim` on a flex row is inert,
|
|
332
|
+
* contributing only its `line-height: 1`, and the ink falls back to line-box
|
|
333
|
+
* centring by font metrics. era-token-ink already fixed that for centred
|
|
334
|
+
* tokens; this fixes it for everything else.
|
|
335
|
+
*
|
|
336
|
+
* THE ICON CASE IS NOT SOLVED, and cannot be from CSS: an icon beside the text
|
|
337
|
+
* needs the box to stay flex, which re-creates the anonymous item. A component
|
|
338
|
+
* whose children are an opaque slot therefore guards it —
|
|
339
|
+
* `not-has-[svg]:era-label-ink` — and ink-centres the text-only case while
|
|
340
|
+
* leaving the icon case on line-box centring. Splitting icon and label into
|
|
341
|
+
* separate slots is what would close it; typography/inert-trim reports every
|
|
342
|
+
* site still on the fallback.
|
|
343
|
+
*
|
|
344
|
+
* @use the ink centring for a fixed-height control holding ONE line of
|
|
345
|
+
* sentence-case text and no icon — a menu item, a nav trigger, a button label.
|
|
346
|
+
* Never alongside `truncate` (the trimmed box becomes the clip). */
|
|
347
|
+
@utility era-label-ink {
|
|
348
|
+
display: block;
|
|
349
|
+
align-content: center;
|
|
350
|
+
line-height: 1;
|
|
351
|
+
text-box: trim-both ex alphabetic;
|
|
314
352
|
}
|
|
315
353
|
|
|
316
354
|
/* In-progress text shimmer — a bright sweep through muted text (the standard
|
package/dist/ui/bar/bar.svelte
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// Radius stays concentric to the height; gap/px are sp/2 (xs-inset-sm),
|
|
11
11
|
// the even gap for one-tier-smaller content at every size.
|
|
12
12
|
export const barVariants = tv({
|
|
13
|
-
base: 'flex items-center
|
|
13
|
+
base: 'flex items-center leading-none',
|
|
14
14
|
variants: {
|
|
15
15
|
size: {
|
|
16
16
|
chip: 'h-(--era-h-chip) rounded-(--era-rd-chip)',
|
|
@@ -44,7 +44,7 @@ export declare const barVariants: import("tailwind-variants").TVReturnType<{
|
|
|
44
44
|
true: "shrink-0 rounded-t-none rounded-b-(--era-rd-control) [box-shadow:0_1px_0_var(--color-divider-faded)]";
|
|
45
45
|
false: "";
|
|
46
46
|
};
|
|
47
|
-
}, undefined, "flex items-center
|
|
47
|
+
}, undefined, "flex items-center leading-none", {
|
|
48
48
|
size: {
|
|
49
49
|
chip: "h-(--era-h-chip) rounded-(--era-rd-chip)";
|
|
50
50
|
control: "h-(--era-h-control) rounded-(--era-rd-control)";
|
|
@@ -70,7 +70,18 @@
|
|
|
70
70
|
and they separated on press. Wrapping unifies them, and `gap: inherit`
|
|
71
71
|
forwards the button's own gap so the icon/label spacing is unchanged.
|
|
72
72
|
-->
|
|
73
|
-
|
|
73
|
+
<!--
|
|
74
|
+
not-has-[svg]:era-label-ink — a text-only button ink-centres its label.
|
|
75
|
+
The span is otherwise a flex box, and a flex box's bare text is an
|
|
76
|
+
ANONYMOUS item that `text-box-trim` can never reach, so the label fell back
|
|
77
|
+
to line-box centring by font metrics (the bug era-label-ink documents).
|
|
78
|
+
With an icon present the box must stay flex for the gap, and that case is
|
|
79
|
+
still on the fallback — typography/inert-trim reports it.
|
|
80
|
+
-->
|
|
81
|
+
<span
|
|
82
|
+
data-button-content
|
|
83
|
+
class="inline-flex items-center justify-center [gap:inherit] not-has-[svg]:era-label-ink"
|
|
84
|
+
>
|
|
74
85
|
{#if loading}
|
|
75
86
|
<LoaderCircle class="size-(--era-h-icon) shrink-0 animate-spin" aria-hidden="true" />
|
|
76
87
|
{#if loadingLabel}<span class="sr-only">{loadingLabel}</span>{/if}
|