@signal9/era-ui 4.7.2 → 4.9.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/swarm/index.d.ts +2 -1
- package/dist/ai/swarm/index.js +2 -1
- package/dist/ai/swarm/swarm-actions.svelte +86 -0
- package/dist/ai/swarm/swarm-actions.svelte.d.ts +31 -0
- package/dist/ai/swarm/swarm-agent.svelte +9 -43
- package/dist/ai/swarm/swarm-artifact.svelte +2 -6
- package/dist/ai/swarm/swarm-artifacts.svelte +1 -10
- package/dist/ai/swarm/swarm-artifacts.svelte.d.ts +0 -2
- package/dist/ai/swarm/swarm-barriers.svelte +39 -0
- package/dist/ai/swarm/swarm-barriers.svelte.d.ts +13 -0
- package/dist/ai/swarm/swarm-counts.svelte +1 -4
- package/dist/ai/swarm/swarm-counts.svelte.d.ts +0 -2
- package/dist/ai/swarm/swarm-footer.svelte +20 -13
- package/dist/ai/swarm/swarm-header.svelte +3 -5
- package/dist/ai/swarm/swarm-node.svelte +8 -64
- package/dist/ai/swarm/swarm-role.svelte +2 -9
- package/dist/ai/swarm/swarm-sandbox.svelte +45 -0
- package/dist/ai/swarm/swarm-sandbox.svelte.d.ts +10 -0
- package/dist/ai/swarm/swarm-tree.svelte +22 -8
- package/dist/ai/swarm/swarm.d.ts +8 -0
- package/dist/ai/swarm/swarm.js +11 -2
- package/dist/ai/swarm/swarm.svelte.d.ts +0 -1
- package/dist/ai/swarm/swarm.svelte.js +10 -12
- package/dist/apps/llm-shell/llm-shell.svelte +2 -36
- package/dist/apps/llm-shell/llm-swarm.svelte +64 -0
- package/dist/apps/llm-shell/llm-swarm.svelte.d.ts +23 -0
- package/dist/apps/llm-shell/types.d.ts +2 -0
- package/dist/apps/notes/editor/bubble-toolbar.svelte +2 -1
- package/dist/apps/notes/notes.svelte +13 -10
- package/dist/dev/audit/audits/clipped-glyphs.js +33 -11
- package/dist/docs/llms-txt.js +1 -1
- package/dist/era-ui.css +1 -1
- package/dist/generated-docs/bar.md +3 -0
- package/dist/generated-docs/input.md +3 -1
- package/dist/generated-docs/llms-full.txt +15 -6
- package/dist/generated-docs/llms.txt +1 -1
- package/dist/generated-docs/manifest.json +5 -5
- package/dist/generated-docs/utilities.json +2 -2
- package/dist/generated-docs/utilities.md +8 -4
- package/dist/styles/density.css +42 -9
- package/dist/styles/index.css +8 -4
- package/dist/ui/bar/bar.svelte +37 -3
- package/dist/ui/bar/bar.svelte.d.ts +61 -1
- package/dist/ui/input/input.svelte +24 -4
- package/dist/ui/input/input.svelte.d.ts +6 -1
- package/dist/ui/input/variants.d.ts +99 -30
- package/dist/ui/input/variants.js +45 -19
- package/package.json +1 -1
|
@@ -10,12 +10,14 @@ import { Input } from "$lib/ui/input";
|
|
|
10
10
|
|
|
11
11
|
## Props
|
|
12
12
|
|
|
13
|
-
Inherits all props from `HTMLInputAttributes
|
|
13
|
+
Inherits all props from `Omit<HTMLInputAttributes, 'size'>`.
|
|
14
14
|
|
|
15
15
|
| Prop | Type | Default | Notes |
|
|
16
16
|
|------|------|---------|-------|
|
|
17
17
|
| `ref?` | `HTMLInputElement \| null` | `null` | bindable |
|
|
18
18
|
| `icon?` | `Component<IconProps> \| null` | `null` | Lucide glyph rendered inside the field, left of the text. |
|
|
19
|
+
| `size?` | `'md' \| 'xxs'` | `'md'` | Field tier. `xxs` is badge height — for compact chrome where the field
|
|
20
|
+
sits level with xxs buttons. See inputVariants. |
|
|
19
21
|
| `bare?` | `boolean` | `false` | Drop the field chrome — for an input inside a container that is already the field. |
|
|
20
22
|
| `reveal?` | `boolean` | `false` | Hold the field chrome back until hover — for a title or label that IS the content. |
|
|
21
23
|
| `value?` | `(forwarded)` | `''` | bindable |
|
|
@@ -15,7 +15,7 @@ Named exports wrap a single primitive (`Button`, `Badge`, `Chip`, `Input`, …).
|
|
|
15
15
|
|
|
16
16
|
Five orthogonal axes are exposed as HTML attributes on any ancestor. The entire subtree re-tiers through CSS inheritance — no JS, no context provider.
|
|
17
17
|
|
|
18
|
-
- `data-mode`: **dense** (default) · balanced · spacious · touch — adjusts the spacing atom (`--era-sp`).
|
|
18
|
+
- `data-mode`: **dense** (default) · balanced · spacious · touch — adjusts the spacing atom (`--era-sp`) and the type size (`--era-text`: 12px at dense, 14px above).
|
|
19
19
|
- `data-surface`: **flat** (default) · glass · bevel — swaps the background treatment.
|
|
20
20
|
- `data-corners`: **rounded** (default) · square — scales all radii toward 0.
|
|
21
21
|
- `data-font`: **mono** (default) · sans · serif — switches the font stack.
|
|
@@ -249,7 +249,9 @@ centering the x-height band — the visual mass of MIXED-CASE text (caps and
|
|
|
249
249
|
descenders cancel above/below). cap alphabetic is the spec-example recipe
|
|
250
250
|
but is descender-blind (reads high; CSSWG #9148) — measured 4x worse here.
|
|
251
251
|
Where text-box is supported it fully determines the box, so the two
|
|
252
|
-
declarations never fight. Worst-case residual: 0.44px
|
|
252
|
+
declarations never fight. Worst-case residual: 0.44px (measured at 14px; the
|
|
253
|
+
mechanism is font-relative, so dense's 12px inherits the same guarantee with
|
|
254
|
+
a proportionally smaller residual).
|
|
253
255
|
|
|
254
256
|
The hard rules concern overflow clipping, and there are TWO of them.
|
|
255
257
|
|
|
@@ -371,9 +373,11 @@ The class also owns `overflow: hidden` — animating height without it just
|
|
|
371
373
|
spills the content out of the shrinking box.
|
|
372
374
|
|
|
373
375
|
Timing rides the motion axis, so `instant` collapses it to a cut (0s) and
|
|
374
|
-
`extra` stretches it, for free.
|
|
375
|
-
these keyframes under
|
|
376
|
-
|
|
376
|
+
`extra` stretches it, for free. Two components carried a byte-identical copy of
|
|
377
|
+
these keyframes under two different names before this existed (a Step's body
|
|
378
|
+
and the error panel's detail), and the swarm tree would have made a third; the
|
|
379
|
+
panel that needs different motion should override `animation`, not re-declare
|
|
380
|
+
it.
|
|
377
381
|
|
|
378
382
|
Declared in `index.css`.
|
|
379
383
|
|
|
@@ -908,6 +912,9 @@ Inherits all props from `HTMLAttributes<HTMLDivElement>`.
|
|
|
908
912
|
|------|------|---------|-------|
|
|
909
913
|
| `ref?` | `HTMLDivElement \| null` | `null` | bindable |
|
|
910
914
|
| `size?` | `'sm' \| 'md' \| 'lg'` | `'lg'` | Height tier (scales with density). Default `lg` — a full toolbar. |
|
|
915
|
+
| `content?` | `'tier' \| 'xxs'` | `'tier'` | Tier of the controls inside — drives the bar's padding and gap so they
|
|
916
|
+
stay concentric to them. `tier` (default) is one tier smaller; `xxs` is
|
|
917
|
+
the compact pairing (xxs pills/fields in an sm or md bar). |
|
|
911
918
|
| `children?` | `Snippet` | — | — |
|
|
912
919
|
|
|
913
920
|
<!-- end: bar -->
|
|
@@ -2848,12 +2855,14 @@ import { Input } from "$lib/ui/input";
|
|
|
2848
2855
|
|
|
2849
2856
|
## Props
|
|
2850
2857
|
|
|
2851
|
-
Inherits all props from `HTMLInputAttributes
|
|
2858
|
+
Inherits all props from `Omit<HTMLInputAttributes, 'size'>`.
|
|
2852
2859
|
|
|
2853
2860
|
| Prop | Type | Default | Notes |
|
|
2854
2861
|
|------|------|---------|-------|
|
|
2855
2862
|
| `ref?` | `HTMLInputElement \| null` | `null` | bindable |
|
|
2856
2863
|
| `icon?` | `Component<IconProps> \| null` | `null` | Lucide glyph rendered inside the field, left of the text. |
|
|
2864
|
+
| `size?` | `'md' \| 'xxs'` | `'md'` | Field tier. `xxs` is badge height — for compact chrome where the field
|
|
2865
|
+
sits level with xxs buttons. See inputVariants. |
|
|
2857
2866
|
| `bare?` | `boolean` | `false` | Drop the field chrome — for an input inside a container that is already the field. |
|
|
2858
2867
|
| `reveal?` | `boolean` | `false` | Hold the field chrome back until hover — for a title or label that IS the content. |
|
|
2859
2868
|
| `value?` | `(forwarded)` | `''` | bindable |
|
|
@@ -15,7 +15,7 @@ Named exports wrap a single primitive (`Button`, `Badge`, `Chip`, `Input`, …).
|
|
|
15
15
|
|
|
16
16
|
Five orthogonal axes are exposed as HTML attributes on any ancestor. The entire subtree re-tiers through CSS inheritance — no JS, no context provider.
|
|
17
17
|
|
|
18
|
-
- `data-mode`: **dense** (default) · balanced · spacious · touch — adjusts the spacing atom (`--era-sp`).
|
|
18
|
+
- `data-mode`: **dense** (default) · balanced · spacious · touch — adjusts the spacing atom (`--era-sp`) and the type size (`--era-text`: 12px at dense, 14px above).
|
|
19
19
|
- `data-surface`: **flat** (default) · glass · bevel — swaps the background treatment.
|
|
20
20
|
- `data-corners`: **rounded** (default) · square — scales all radii toward 0.
|
|
21
21
|
- `data-font`: **mono** (default) · sans · serif — switches the font stack.
|
|
@@ -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": 5333,
|
|
48
48
|
"sections": [
|
|
49
49
|
"Overview",
|
|
50
50
|
"era-interactive",
|
|
@@ -159,7 +159,7 @@
|
|
|
159
159
|
"slug": "bar",
|
|
160
160
|
"title": "Bar",
|
|
161
161
|
"summary": "A flex container for toolbars and headers, in three heights.",
|
|
162
|
-
"tokenEstimate":
|
|
162
|
+
"tokenEstimate": 181,
|
|
163
163
|
"sections": [
|
|
164
164
|
"Import",
|
|
165
165
|
"Props"
|
|
@@ -634,7 +634,7 @@
|
|
|
634
634
|
"slug": "input",
|
|
635
635
|
"title": "Input",
|
|
636
636
|
"summary": "A text input field, with textarea variant.",
|
|
637
|
-
"tokenEstimate":
|
|
637
|
+
"tokenEstimate": 219,
|
|
638
638
|
"sections": [
|
|
639
639
|
"Import",
|
|
640
640
|
"Props"
|
|
@@ -997,7 +997,7 @@
|
|
|
997
997
|
],
|
|
998
998
|
"file": "index.css",
|
|
999
999
|
"useCase": "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; see era-text-trim-caps for ALL-CAPS strings.",
|
|
1000
|
-
"description": "Font-agnostic vertical ink-centering for single-line control text.\nMeasured verdict (4 fonts x 2 dpr, ink from device-pixel screenshots):\nthe offset has TWO causes — a fractional line box (14px x 1.5lh = 21px in\na 24px row places ink on a half pixel, ~1px error) and font ascent/descent\nasymmetry (+-1px, sign flips per font). line-height: 1 fixes the first and\nis the Firefox fallback; text-box ex/alphabetic fixes the second by\ncentering the x-height band — the visual mass of MIXED-CASE text (caps and\ndescenders cancel above/below). cap alphabetic is the spec-example recipe\nbut is descender-blind (reads high; CSSWG #9148) — measured 4x worse here.\nWhere text-box is supported it fully determines the box, so the two\ndeclarations never fight. Worst-case residual: 0.44px.\n\nThe hard rules concern overflow clipping, and there are TWO of them.\n\n1. NEVER on a NATIVE EDITABLE — <input>, <textarea>, <select>. These clip to\n a UA-owned inner editor box that IS the trimmed line box, so a fixed\n height does NOT hold it open: whatever you type gets its ascenders and\n descenders sliced off (a \"d\" renders as an \"o\"). This rule used to read\n the other way round — it claimed a fixed-height <input> was the trim's\n intended home — and the Input component shipped chopped text as a result.\n A tier-height input centres its own text; it needs no trim.\n\n2. NEVER on an AUTO-height element that clips — a `truncate` child, an\n auto-height box with overflow-hidden. With no height to hold it open the\n box collapses to the x-height band (~7.5px at 14px) and the clip chops the\n glyphs into a middle stripe. Put the trim on the fixed-height ROW instead\n and let the child centre via the row's items-center.\n\nA fixed-height NON-editable element is the safe home: the ink overflows the\ntrimmed LINE box but stays inside the padding box, which is what actually\nclips. Both rules are enforced at runtime by typography/collapsed-text-trim.",
|
|
1000
|
+
"description": "Font-agnostic vertical ink-centering for single-line control text.\nMeasured verdict (4 fonts x 2 dpr, ink from device-pixel screenshots):\nthe offset has TWO causes — a fractional line box (14px x 1.5lh = 21px in\na 24px row places ink on a half pixel, ~1px error) and font ascent/descent\nasymmetry (+-1px, sign flips per font). line-height: 1 fixes the first and\nis the Firefox fallback; text-box ex/alphabetic fixes the second by\ncentering the x-height band — the visual mass of MIXED-CASE text (caps and\ndescenders cancel above/below). cap alphabetic is the spec-example recipe\nbut is descender-blind (reads high; CSSWG #9148) — measured 4x worse here.\nWhere text-box is supported it fully determines the box, so the two\ndeclarations never fight. Worst-case residual: 0.44px (measured at 14px; the\nmechanism is font-relative, so dense's 12px inherits the same guarantee with\na proportionally smaller residual).\n\nThe hard rules concern overflow clipping, and there are TWO of them.\n\n1. NEVER on a NATIVE EDITABLE — <input>, <textarea>, <select>. These clip to\n a UA-owned inner editor box that IS the trimmed line box, so a fixed\n height does NOT hold it open: whatever you type gets its ascenders and\n descenders sliced off (a \"d\" renders as an \"o\"). This rule used to read\n the other way round — it claimed a fixed-height <input> was the trim's\n intended home — and the Input component shipped chopped text as a result.\n A tier-height input centres its own text; it needs no trim.\n\n2. NEVER on an AUTO-height element that clips — a `truncate` child, an\n auto-height box with overflow-hidden. With no height to hold it open the\n box collapses to the x-height band (~7.5px at 14px) and the clip chops the\n glyphs into a middle stripe. Put the trim on the fixed-height ROW instead\n and let the child centre via the row's items-center.\n\nA fixed-height NON-editable element is the safe home: the ink overflows the\ntrimmed LINE box but stays inside the padding box, which is what actually\nclips. Both rules are enforced at runtime by typography/collapsed-text-trim.",
|
|
1001
1001
|
"css": "@utility era-text-trim {\n\tline-height: 1;\n\ttext-box: trim-both ex alphabetic;\n}"
|
|
1002
1002
|
},
|
|
1003
1003
|
{
|
|
@@ -1037,7 +1037,7 @@
|
|
|
1037
1037
|
],
|
|
1038
1038
|
"file": "index.css",
|
|
1039
1039
|
"useCase": "the height sweep for a bits-ui Collapsible.Content — put it on the Content element itself (it carries its own overflow: hidden).",
|
|
1040
|
-
"description": "The open/close animation for a bits-ui Collapsible.Content — the height\nsweep every disclosure in the library uses (a Step's body, an error panel's\ndetail, a swarm node's children).\n\nIt has to be a keyframe animation rather than a transition because the\nnatural height is only knowable at open time: bits measures the content and\npublishes `--bits-collapsible-content-height`, which the `to` frame reads.\nThe class also owns `overflow: hidden` — animating height without it just\nspills the content out of the shrinking box.\n\nTiming rides the motion axis, so `instant` collapses it to a cut (0s) and\n`extra` stretches it, for free.
|
|
1040
|
+
"description": "The open/close animation for a bits-ui Collapsible.Content — the height\nsweep every disclosure in the library uses (a Step's body, an error panel's\ndetail, a swarm node's children).\n\nIt has to be a keyframe animation rather than a transition because the\nnatural height is only knowable at open time: bits measures the content and\npublishes `--bits-collapsible-content-height`, which the `to` frame reads.\nThe class also owns `overflow: hidden` — animating height without it just\nspills the content out of the shrinking box.\n\nTiming rides the motion axis, so `instant` collapses it to a cut (0s) and\n`extra` stretches it, for free. Two components carried a byte-identical copy of\nthese keyframes under two different names before this existed (a Step's body\nand the error panel's detail), and the swarm tree would have made a third; the\npanel that needs different motion should override `animation`, not re-declare\nit.",
|
|
1041
1041
|
"css": "@utility era-collapse {\n\toverflow: hidden;\n\t&[data-state='open'] {\n\t\tanimation: era-collapse-open var(--era-duration) var(--era-ease);\n\t}\n\t&[data-state='closed'] {\n\t\tanimation: era-collapse-close var(--era-duration) var(--era-ease);\n\t}\n}"
|
|
1042
1042
|
},
|
|
1043
1043
|
{
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
],
|
|
38
38
|
"file": "index.css",
|
|
39
39
|
"useCase": "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; see era-text-trim-caps for ALL-CAPS strings.",
|
|
40
|
-
"description": "Font-agnostic vertical ink-centering for single-line control text.\nMeasured verdict (4 fonts x 2 dpr, ink from device-pixel screenshots):\nthe offset has TWO causes — a fractional line box (14px x 1.5lh = 21px in\na 24px row places ink on a half pixel, ~1px error) and font ascent/descent\nasymmetry (+-1px, sign flips per font). line-height: 1 fixes the first and\nis the Firefox fallback; text-box ex/alphabetic fixes the second by\ncentering the x-height band — the visual mass of MIXED-CASE text (caps and\ndescenders cancel above/below). cap alphabetic is the spec-example recipe\nbut is descender-blind (reads high; CSSWG #9148) — measured 4x worse here.\nWhere text-box is supported it fully determines the box, so the two\ndeclarations never fight. Worst-case residual: 0.44px.\n\nThe hard rules concern overflow clipping, and there are TWO of them.\n\n1. NEVER on a NATIVE EDITABLE — <input>, <textarea>, <select>. These clip to\n a UA-owned inner editor box that IS the trimmed line box, so a fixed\n height does NOT hold it open: whatever you type gets its ascenders and\n descenders sliced off (a \"d\" renders as an \"o\"). This rule used to read\n the other way round — it claimed a fixed-height <input> was the trim's\n intended home — and the Input component shipped chopped text as a result.\n A tier-height input centres its own text; it needs no trim.\n\n2. NEVER on an AUTO-height element that clips — a `truncate` child, an\n auto-height box with overflow-hidden. With no height to hold it open the\n box collapses to the x-height band (~7.5px at 14px) and the clip chops the\n glyphs into a middle stripe. Put the trim on the fixed-height ROW instead\n and let the child centre via the row's items-center.\n\nA fixed-height NON-editable element is the safe home: the ink overflows the\ntrimmed LINE box but stays inside the padding box, which is what actually\nclips. Both rules are enforced at runtime by typography/collapsed-text-trim.",
|
|
40
|
+
"description": "Font-agnostic vertical ink-centering for single-line control text.\nMeasured verdict (4 fonts x 2 dpr, ink from device-pixel screenshots):\nthe offset has TWO causes — a fractional line box (14px x 1.5lh = 21px in\na 24px row places ink on a half pixel, ~1px error) and font ascent/descent\nasymmetry (+-1px, sign flips per font). line-height: 1 fixes the first and\nis the Firefox fallback; text-box ex/alphabetic fixes the second by\ncentering the x-height band — the visual mass of MIXED-CASE text (caps and\ndescenders cancel above/below). cap alphabetic is the spec-example recipe\nbut is descender-blind (reads high; CSSWG #9148) — measured 4x worse here.\nWhere text-box is supported it fully determines the box, so the two\ndeclarations never fight. Worst-case residual: 0.44px (measured at 14px; the\nmechanism is font-relative, so dense's 12px inherits the same guarantee with\na proportionally smaller residual).\n\nThe hard rules concern overflow clipping, and there are TWO of them.\n\n1. NEVER on a NATIVE EDITABLE — <input>, <textarea>, <select>. These clip to\n a UA-owned inner editor box that IS the trimmed line box, so a fixed\n height does NOT hold it open: whatever you type gets its ascenders and\n descenders sliced off (a \"d\" renders as an \"o\"). This rule used to read\n the other way round — it claimed a fixed-height <input> was the trim's\n intended home — and the Input component shipped chopped text as a result.\n A tier-height input centres its own text; it needs no trim.\n\n2. NEVER on an AUTO-height element that clips — a `truncate` child, an\n auto-height box with overflow-hidden. With no height to hold it open the\n box collapses to the x-height band (~7.5px at 14px) and the clip chops the\n glyphs into a middle stripe. Put the trim on the fixed-height ROW instead\n and let the child centre via the row's items-center.\n\nA fixed-height NON-editable element is the safe home: the ink overflows the\ntrimmed LINE box but stays inside the padding box, which is what actually\nclips. Both rules are enforced at runtime by typography/collapsed-text-trim.",
|
|
41
41
|
"css": "@utility era-text-trim {\n\tline-height: 1;\n\ttext-box: trim-both ex alphabetic;\n}"
|
|
42
42
|
},
|
|
43
43
|
{
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
],
|
|
78
78
|
"file": "index.css",
|
|
79
79
|
"useCase": "the height sweep for a bits-ui Collapsible.Content — put it on the Content element itself (it carries its own overflow: hidden).",
|
|
80
|
-
"description": "The open/close animation for a bits-ui Collapsible.Content — the height\nsweep every disclosure in the library uses (a Step's body, an error panel's\ndetail, a swarm node's children).\n\nIt has to be a keyframe animation rather than a transition because the\nnatural height is only knowable at open time: bits measures the content and\npublishes `--bits-collapsible-content-height`, which the `to` frame reads.\nThe class also owns `overflow: hidden` — animating height without it just\nspills the content out of the shrinking box.\n\nTiming rides the motion axis, so `instant` collapses it to a cut (0s) and\n`extra` stretches it, for free.
|
|
80
|
+
"description": "The open/close animation for a bits-ui Collapsible.Content — the height\nsweep every disclosure in the library uses (a Step's body, an error panel's\ndetail, a swarm node's children).\n\nIt has to be a keyframe animation rather than a transition because the\nnatural height is only knowable at open time: bits measures the content and\npublishes `--bits-collapsible-content-height`, which the `to` frame reads.\nThe class also owns `overflow: hidden` — animating height without it just\nspills the content out of the shrinking box.\n\nTiming rides the motion axis, so `instant` collapses it to a cut (0s) and\n`extra` stretches it, for free. Two components carried a byte-identical copy of\nthese keyframes under two different names before this existed (a Step's body\nand the error panel's detail), and the swarm tree would have made a third; the\npanel that needs different motion should override `animation`, not re-declare\nit.",
|
|
81
81
|
"css": "@utility era-collapse {\n\toverflow: hidden;\n\t&[data-state='open'] {\n\t\tanimation: era-collapse-open var(--era-duration) var(--era-ease);\n\t}\n\t&[data-state='closed'] {\n\t\tanimation: era-collapse-close var(--era-duration) var(--era-ease);\n\t}\n}"
|
|
82
82
|
},
|
|
83
83
|
{
|
|
@@ -146,7 +146,9 @@ centering the x-height band — the visual mass of MIXED-CASE text (caps and
|
|
|
146
146
|
descenders cancel above/below). cap alphabetic is the spec-example recipe
|
|
147
147
|
but is descender-blind (reads high; CSSWG #9148) — measured 4x worse here.
|
|
148
148
|
Where text-box is supported it fully determines the box, so the two
|
|
149
|
-
declarations never fight. Worst-case residual: 0.44px
|
|
149
|
+
declarations never fight. Worst-case residual: 0.44px (measured at 14px; the
|
|
150
|
+
mechanism is font-relative, so dense's 12px inherits the same guarantee with
|
|
151
|
+
a proportionally smaller residual).
|
|
150
152
|
|
|
151
153
|
The hard rules concern overflow clipping, and there are TWO of them.
|
|
152
154
|
|
|
@@ -268,9 +270,11 @@ The class also owns `overflow: hidden` — animating height without it just
|
|
|
268
270
|
spills the content out of the shrinking box.
|
|
269
271
|
|
|
270
272
|
Timing rides the motion axis, so `instant` collapses it to a cut (0s) and
|
|
271
|
-
`extra` stretches it, for free.
|
|
272
|
-
these keyframes under
|
|
273
|
-
|
|
273
|
+
`extra` stretches it, for free. Two components carried a byte-identical copy of
|
|
274
|
+
these keyframes under two different names before this existed (a Step's body
|
|
275
|
+
and the error panel's detail), and the swarm tree would have made a third; the
|
|
276
|
+
panel that needs different motion should override `animation`, not re-declare
|
|
277
|
+
it.
|
|
274
278
|
|
|
275
279
|
Declared in `index.css`.
|
|
276
280
|
|
package/dist/styles/density.css
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* lg = 4·sp (bars, containers)
|
|
14
14
|
*
|
|
15
15
|
* xs carries a +6 floor so icons stay legible (≥14px) at every sp. xxs sits
|
|
16
|
-
* 4px above xs so
|
|
16
|
+
* 4px above xs so body text has just enough pill around it while fitting
|
|
17
17
|
* inside an md container with a visible concentric gap (≥3px at dense). sm
|
|
18
18
|
* keeps the generous 2·sp + 6 that gives switch thumbs their sp/2 slot and
|
|
19
19
|
* KV rows their padded feel. md and lg are pure sp multiples so button and
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
* --era-px-{sm,md,lg} sp/2 — tier-to-tier nesting padding
|
|
44
44
|
* --era-gap sp/2 — inter-element gap
|
|
45
45
|
* --era-inset-{xxs,sm,md} (T − text)/2 — text-symmetric content padding
|
|
46
|
+
* (text is 12px at dense, 14 above)
|
|
46
47
|
* --era-xs-inset-sm (sm − xs)/2 = sp/2 — centering an xs element inside sm
|
|
47
48
|
*
|
|
48
49
|
* OPTICAL PADDING (unbounded content containers)
|
|
@@ -52,7 +53,8 @@
|
|
|
52
53
|
* height C inside a container of height T is (T − C)/2, linear in sp. But
|
|
53
54
|
* cards, dialogs, and content panels have no bounding tier — their padding
|
|
54
55
|
* is optical, and linear-in-sp padding falls behind as modes loosen: controls
|
|
55
|
-
* grow linearly while text
|
|
56
|
+
* grow linearly while text barely moves (12px at dense, 14 above), so
|
|
57
|
+
* whitespace must grow SUPER-linearly
|
|
56
58
|
* to hold the same perceived balance. (The tokens that already feel right
|
|
57
59
|
* across modes — inset-md 5→17, content-p 16→48 — are exactly the convex
|
|
58
60
|
* ones; the cramped ones — card's old sp/2 = 4→8 — are the linear ones.)
|
|
@@ -154,9 +156,9 @@
|
|
|
154
156
|
|
|
155
157
|
/* Content insets — text-symmetric padding (vertical centering, reused as
|
|
156
158
|
horizontal only where the content is a single square glyph). */
|
|
157
|
-
--era-inset-xxs: max(0px, calc((var(--era-h-xxs) - var(--era-text)) / 2)); /*
|
|
158
|
-
--era-inset-sm: max(0px, calc((var(--era-h-sm) - var(--era-text)) / 2)); /*
|
|
159
|
-
--era-inset-md: max(0px, calc((var(--era-h-md) - var(--era-text)) / 2)); /*
|
|
159
|
+
--era-inset-xxs: max(0px, calc((var(--era-h-xxs) - var(--era-text)) / 2)); /* 3/3/4/6 */
|
|
160
|
+
--era-inset-sm: max(0px, calc((var(--era-h-sm) - var(--era-text)) / 2)); /* 5/6/8/12 */
|
|
161
|
+
--era-inset-md: max(0px, calc((var(--era-h-md) - var(--era-text)) / 2)); /* 6/8/11/17 */
|
|
160
162
|
|
|
161
163
|
/* Pill side padding — horizontal breathing room for badge/chip text.
|
|
162
164
|
Text wants MORE horizontal than vertical padding: line-height adds
|
|
@@ -167,8 +169,8 @@
|
|
|
167
169
|
is narrower than the line, this comes out ~2× the vertical inset on its
|
|
168
170
|
own — and a lone glyph still measures exactly the tier width, so the
|
|
169
171
|
"single glyph = square" floor (min-w = h) is preserved, not broken. */
|
|
170
|
-
--era-pill-xxs: max(0px, calc((var(--era-h-xxs) - 0.6 * var(--era-text)) / 2)); /* 4
|
|
171
|
-
--era-pill-sm: max(0px, calc((var(--era-h-sm) - 0.6 * var(--era-text)) / 2)); /*
|
|
172
|
+
--era-pill-xxs: max(0px, calc((var(--era-h-xxs) - 0.6 * var(--era-text)) / 2)); /* 5.4/5.8/6.8 */
|
|
173
|
+
--era-pill-sm: max(0px, calc((var(--era-h-sm) - 0.6 * var(--era-text)) / 2)); /* 7.4/8.8/10.8 */
|
|
172
174
|
|
|
173
175
|
/* Text-field side padding — the horizontal room where typed text starts in an
|
|
174
176
|
md-tier input (Input, Textarea, combobox/command inputs, date/time fields).
|
|
@@ -261,7 +263,8 @@
|
|
|
261
263
|
}
|
|
262
264
|
|
|
263
265
|
/* -------------------------------------------------- */
|
|
264
|
-
/* Mode inputs —
|
|
266
|
+
/* Mode inputs — --era-sp, and --era-text (12 at dense, */
|
|
267
|
+
/* 14 above; see the dense block). */
|
|
265
268
|
/* The derivation above re-runs per element wherever */
|
|
266
269
|
/* --era-sp is overridden. Animation timing is NOT here */
|
|
267
270
|
/* — it's the motion axis (motion.css), orthogonal to */
|
|
@@ -286,7 +289,37 @@
|
|
|
286
289
|
[data-mode='dense'] {
|
|
287
290
|
--era-sp: 0.5rem; /* 8px */
|
|
288
291
|
--era-density: 1; /* d = sp / 8px */
|
|
289
|
-
|
|
292
|
+
/* 12px at dense, 14px from balanced up (set in the block below).
|
|
293
|
+
*
|
|
294
|
+
* Type is the SECOND density input, and for a long time it was not one: the
|
|
295
|
+
* token read "14px — static across modes", so dense and balanced differed in
|
|
296
|
+
* their boxes and not in their type. That is what made dense feel like
|
|
297
|
+
* balanced-with-tighter-gaps rather than a genuinely dense mode — the chrome
|
|
298
|
+
* shrank while the thing inside it did not.
|
|
299
|
+
*
|
|
300
|
+
* 12px is the size the reference terminal app is built at, and it makes the
|
|
301
|
+
* whole ladder line up with it: --era-inset-xxs becomes (18−12)/2 = 3px,
|
|
302
|
+
* which is exactly the 3px that app hardcodes for the wall and gap of an
|
|
303
|
+
* 18px control in a 24px bar. Same numbers, derived instead of typed.
|
|
304
|
+
*
|
|
305
|
+
* Everything text-derived follows: inset-xxs 2→3, inset-sm 4→5, inset-md
|
|
306
|
+
* 5→6, pill-xxs 4.8→5.4. Heights do NOT — they are sp-derived, so the tier
|
|
307
|
+
* ladder (14/18/22/24/32) is unchanged and dense stays dimensionally the
|
|
308
|
+
* same mode it was.
|
|
309
|
+
*
|
|
310
|
+
* Only dense moves. Balanced/spacious/touch keep 14px: they exist for
|
|
311
|
+
* reading comfort and pointer size, and shrinking their type would undo the
|
|
312
|
+
* thing they are for. */
|
|
313
|
+
--era-text: 0.75rem; /* 12px */
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/* Balanced and up: 14px, the comfortable reading size. Declared once here and
|
|
317
|
+
* inherited by spacious/touch so there is a single place the non-dense size
|
|
318
|
+
* lives. */
|
|
319
|
+
[data-mode='balanced'],
|
|
320
|
+
[data-mode='spacious'],
|
|
321
|
+
[data-mode='touch'] {
|
|
322
|
+
--era-text: 0.875rem; /* 14px */
|
|
290
323
|
}
|
|
291
324
|
|
|
292
325
|
[data-mode='balanced'] {
|
package/dist/styles/index.css
CHANGED
|
@@ -126,7 +126,9 @@
|
|
|
126
126
|
* descenders cancel above/below). cap alphabetic is the spec-example recipe
|
|
127
127
|
* but is descender-blind (reads high; CSSWG #9148) — measured 4x worse here.
|
|
128
128
|
* Where text-box is supported it fully determines the box, so the two
|
|
129
|
-
* declarations never fight. Worst-case residual: 0.44px
|
|
129
|
+
* declarations never fight. Worst-case residual: 0.44px (measured at 14px; the
|
|
130
|
+
* mechanism is font-relative, so dense's 12px inherits the same guarantee with
|
|
131
|
+
* a proportionally smaller residual).
|
|
130
132
|
*
|
|
131
133
|
* The hard rules concern overflow clipping, and there are TWO of them.
|
|
132
134
|
*
|
|
@@ -234,9 +236,11 @@
|
|
|
234
236
|
* spills the content out of the shrinking box.
|
|
235
237
|
*
|
|
236
238
|
* Timing rides the motion axis, so `instant` collapses it to a cut (0s) and
|
|
237
|
-
* `extra` stretches it, for free.
|
|
238
|
-
* these keyframes under
|
|
239
|
-
*
|
|
239
|
+
* `extra` stretches it, for free. Two components carried a byte-identical copy of
|
|
240
|
+
* these keyframes under two different names before this existed (a Step's body
|
|
241
|
+
* and the error panel's detail), and the swarm tree would have made a third; the
|
|
242
|
+
* panel that needs different motion should override `animation`, not re-declare
|
|
243
|
+
* it.
|
|
240
244
|
*
|
|
241
245
|
* @use the height sweep for a bits-ui Collapsible.Content — put it on the
|
|
242
246
|
* Content element itself (it carries its own overflow: hidden). */
|
package/dist/ui/bar/bar.svelte
CHANGED
|
@@ -10,15 +10,42 @@
|
|
|
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 era-text-trim',
|
|
14
14
|
variants: {
|
|
15
15
|
size: {
|
|
16
16
|
sm: 'h-(--era-h-sm) rounded-(--era-rd-sm)',
|
|
17
17
|
md: 'h-(--era-h-md) rounded-(--era-rd-md)',
|
|
18
18
|
lg: 'h-(--era-h-lg) rounded-(--era-rd-lg)'
|
|
19
|
+
},
|
|
20
|
+
/**
|
|
21
|
+
* The tier of the CONTROLS inside, because that is what the bar's own
|
|
22
|
+
* padding and gap have to be concentric to — (bar − content)/2 on every
|
|
23
|
+
* side. It is a variant rather than a caller's class because the ladder
|
|
24
|
+
* math belongs next to the heights it is derived from: three call sites
|
|
25
|
+
* had each restated the two-tier value by hand, and the geometry spec had
|
|
26
|
+
* been rewritten twice chasing which token they were restating.
|
|
27
|
+
*
|
|
28
|
+
* - `tier` (default) — one tier smaller, the pairing above. sm⊃xs, md⊃sm
|
|
29
|
+
* and lg⊃md all equal sp/2, which is why one token covers every size.
|
|
30
|
+
* - `xxs` — the compact pairing: xxs pills and fields (a filter beside an
|
|
31
|
+
* xxs icon button, a title bar). Two tiers down, so the inset differs
|
|
32
|
+
* per size and comes from the compounds below.
|
|
33
|
+
*/
|
|
34
|
+
content: {
|
|
35
|
+
tier: 'gap-(--era-xs-inset-sm) px-(--era-xs-inset-sm)',
|
|
36
|
+
xxs: ''
|
|
19
37
|
}
|
|
20
38
|
},
|
|
21
|
-
|
|
39
|
+
compoundVariants: [
|
|
40
|
+
// md ⊃ xxs = (3sp − sp − 10)/2 — the named token.
|
|
41
|
+
{ size: 'md', content: 'xxs', class: 'gap-(--era-xxs-inset-md) px-(--era-xxs-inset-md)' },
|
|
42
|
+
// sm ⊃ xxs = (2sp + 6 − sp − 10)/2 = (sp − 4)/2, which is ALSO (h-xxs − text)/2
|
|
43
|
+
// at 14px text — the same number --era-inset-xxs already carries, so the
|
|
44
|
+
// identity is reused rather than a fifth token invented. (lg ⊃ xxs has no
|
|
45
|
+
// token because nothing pairs a page header with pill-tier controls.)
|
|
46
|
+
{ size: 'sm', content: 'xxs', class: 'gap-(--era-inset-xxs) px-(--era-inset-xxs)' }
|
|
47
|
+
],
|
|
48
|
+
defaultVariants: { size: 'lg', content: 'tier' }
|
|
22
49
|
});
|
|
23
50
|
</script>
|
|
24
51
|
|
|
@@ -29,6 +56,7 @@
|
|
|
29
56
|
let {
|
|
30
57
|
ref = $bindable(null),
|
|
31
58
|
size = 'lg',
|
|
59
|
+
content = 'tier',
|
|
32
60
|
children,
|
|
33
61
|
class: className,
|
|
34
62
|
...restProps
|
|
@@ -36,10 +64,16 @@
|
|
|
36
64
|
ref?: HTMLDivElement | null;
|
|
37
65
|
/** Height tier (scales with density). Default `lg` — a full toolbar. */
|
|
38
66
|
size?: 'sm' | 'md' | 'lg';
|
|
67
|
+
/**
|
|
68
|
+
* Tier of the controls inside — drives the bar's padding and gap so they
|
|
69
|
+
* stay concentric to them. `tier` (default) is one tier smaller; `xxs` is
|
|
70
|
+
* the compact pairing (xxs pills/fields in an sm or md bar).
|
|
71
|
+
*/
|
|
72
|
+
content?: 'tier' | 'xxs';
|
|
39
73
|
children?: Snippet;
|
|
40
74
|
} = $props();
|
|
41
75
|
</script>
|
|
42
76
|
|
|
43
|
-
<div bind:this={ref} class={cn(barVariants({ size }), className)} {...restProps}>
|
|
77
|
+
<div bind:this={ref} class={cn(barVariants({ size, content }), className)} {...restProps}>
|
|
44
78
|
{@render children?.()}
|
|
45
79
|
</div>
|
|
@@ -4,18 +4,72 @@ export declare const barVariants: import("tailwind-variants").TVReturnType<{
|
|
|
4
4
|
md: "h-(--era-h-md) rounded-(--era-rd-md)";
|
|
5
5
|
lg: "h-(--era-h-lg) rounded-(--era-rd-lg)";
|
|
6
6
|
};
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* The tier of the CONTROLS inside, because that is what the bar's own
|
|
9
|
+
* padding and gap have to be concentric to — (bar − content)/2 on every
|
|
10
|
+
* side. It is a variant rather than a caller's class because the ladder
|
|
11
|
+
* math belongs next to the heights it is derived from: three call sites
|
|
12
|
+
* had each restated the two-tier value by hand, and the geometry spec had
|
|
13
|
+
* been rewritten twice chasing which token they were restating.
|
|
14
|
+
*
|
|
15
|
+
* - `tier` (default) — one tier smaller, the pairing above. sm⊃xs, md⊃sm
|
|
16
|
+
* and lg⊃md all equal sp/2, which is why one token covers every size.
|
|
17
|
+
* - `xxs` — the compact pairing: xxs pills and fields (a filter beside an
|
|
18
|
+
* xxs icon button, a title bar). Two tiers down, so the inset differs
|
|
19
|
+
* per size and comes from the compounds below.
|
|
20
|
+
*/
|
|
21
|
+
content: {
|
|
22
|
+
tier: "gap-(--era-xs-inset-sm) px-(--era-xs-inset-sm)";
|
|
23
|
+
xxs: "";
|
|
24
|
+
};
|
|
25
|
+
}, undefined, "flex items-center era-text-trim", {
|
|
8
26
|
size: {
|
|
9
27
|
sm: "h-(--era-h-sm) rounded-(--era-rd-sm)";
|
|
10
28
|
md: "h-(--era-h-md) rounded-(--era-rd-md)";
|
|
11
29
|
lg: "h-(--era-h-lg) rounded-(--era-rd-lg)";
|
|
12
30
|
};
|
|
31
|
+
/**
|
|
32
|
+
* The tier of the CONTROLS inside, because that is what the bar's own
|
|
33
|
+
* padding and gap have to be concentric to — (bar − content)/2 on every
|
|
34
|
+
* side. It is a variant rather than a caller's class because the ladder
|
|
35
|
+
* math belongs next to the heights it is derived from: three call sites
|
|
36
|
+
* had each restated the two-tier value by hand, and the geometry spec had
|
|
37
|
+
* been rewritten twice chasing which token they were restating.
|
|
38
|
+
*
|
|
39
|
+
* - `tier` (default) — one tier smaller, the pairing above. sm⊃xs, md⊃sm
|
|
40
|
+
* and lg⊃md all equal sp/2, which is why one token covers every size.
|
|
41
|
+
* - `xxs` — the compact pairing: xxs pills and fields (a filter beside an
|
|
42
|
+
* xxs icon button, a title bar). Two tiers down, so the inset differs
|
|
43
|
+
* per size and comes from the compounds below.
|
|
44
|
+
*/
|
|
45
|
+
content: {
|
|
46
|
+
tier: "gap-(--era-xs-inset-sm) px-(--era-xs-inset-sm)";
|
|
47
|
+
xxs: "";
|
|
48
|
+
};
|
|
13
49
|
}, undefined, import("tailwind-variants").TVReturnTypeLike<{
|
|
14
50
|
size: {
|
|
15
51
|
sm: "h-(--era-h-sm) rounded-(--era-rd-sm)";
|
|
16
52
|
md: "h-(--era-h-md) rounded-(--era-rd-md)";
|
|
17
53
|
lg: "h-(--era-h-lg) rounded-(--era-rd-lg)";
|
|
18
54
|
};
|
|
55
|
+
/**
|
|
56
|
+
* The tier of the CONTROLS inside, because that is what the bar's own
|
|
57
|
+
* padding and gap have to be concentric to — (bar − content)/2 on every
|
|
58
|
+
* side. It is a variant rather than a caller's class because the ladder
|
|
59
|
+
* math belongs next to the heights it is derived from: three call sites
|
|
60
|
+
* had each restated the two-tier value by hand, and the geometry spec had
|
|
61
|
+
* been rewritten twice chasing which token they were restating.
|
|
62
|
+
*
|
|
63
|
+
* - `tier` (default) — one tier smaller, the pairing above. sm⊃xs, md⊃sm
|
|
64
|
+
* and lg⊃md all equal sp/2, which is why one token covers every size.
|
|
65
|
+
* - `xxs` — the compact pairing: xxs pills and fields (a filter beside an
|
|
66
|
+
* xxs icon button, a title bar). Two tiers down, so the inset differs
|
|
67
|
+
* per size and comes from the compounds below.
|
|
68
|
+
*/
|
|
69
|
+
content: {
|
|
70
|
+
tier: "gap-(--era-xs-inset-sm) px-(--era-xs-inset-sm)";
|
|
71
|
+
xxs: "";
|
|
72
|
+
};
|
|
19
73
|
}, undefined>>;
|
|
20
74
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
21
75
|
import type { Snippet } from 'svelte';
|
|
@@ -23,6 +77,12 @@ type $$ComponentProps = HTMLAttributes<HTMLDivElement> & {
|
|
|
23
77
|
ref?: HTMLDivElement | null;
|
|
24
78
|
/** Height tier (scales with density). Default `lg` — a full toolbar. */
|
|
25
79
|
size?: 'sm' | 'md' | 'lg';
|
|
80
|
+
/**
|
|
81
|
+
* Tier of the controls inside — drives the bar's padding and gap so they
|
|
82
|
+
* stay concentric to them. `tier` (default) is one tier smaller; `xxs` is
|
|
83
|
+
* the compact pairing (xxs pills/fields in an sm or md bar).
|
|
84
|
+
*/
|
|
85
|
+
content?: 'tier' | 'xxs';
|
|
26
86
|
children?: Snippet;
|
|
27
87
|
};
|
|
28
88
|
declare const Bar: import("svelte").Component<$$ComponentProps, {}, "ref">;
|
|
@@ -9,14 +9,25 @@
|
|
|
9
9
|
ref = $bindable(null),
|
|
10
10
|
value = $bindable(''),
|
|
11
11
|
icon = null,
|
|
12
|
+
size = 'md',
|
|
12
13
|
bare = false,
|
|
13
14
|
reveal = false,
|
|
14
15
|
class: className,
|
|
15
16
|
...restProps
|
|
16
|
-
|
|
17
|
+
// The native `size` attribute (visible width in characters) is shadowed on
|
|
18
|
+
// purpose: era fields size by tier and by flex, never by character count,
|
|
19
|
+
// and `size` is the name every other component in the library uses for its
|
|
20
|
+
// tier. Consumers who genuinely want the HTML attribute can set it via
|
|
21
|
+
// {...restProps} spread from an object.
|
|
22
|
+
}: Omit<HTMLInputAttributes, 'size'> & {
|
|
17
23
|
ref?: HTMLInputElement | null;
|
|
18
24
|
/** Lucide glyph rendered inside the field, left of the text. */
|
|
19
25
|
icon?: Component<IconProps> | null;
|
|
26
|
+
/**
|
|
27
|
+
* Field tier. `xxs` is badge height — for compact chrome where the field
|
|
28
|
+
* sits level with xxs buttons. See inputVariants.
|
|
29
|
+
*/
|
|
30
|
+
size?: 'md' | 'xxs';
|
|
20
31
|
/** Drop the field chrome — for an input inside a container that is already the field. */
|
|
21
32
|
bare?: boolean;
|
|
22
33
|
/** Hold the field chrome back until hover — for a title or label that IS the content. */
|
|
@@ -34,6 +45,13 @@
|
|
|
34
45
|
// chrome" cannot tell a sanctioned exception from a regression — which is the
|
|
35
46
|
// hole the Notes fields sat in. Naming the kind closes it.
|
|
36
47
|
const kind = $derived(reveal ? 'reveal' : bare ? 'bare' : '');
|
|
48
|
+
|
|
49
|
+
// The field's glyph is the icon tier OF ITS OWN TIER, which is what puts it on
|
|
50
|
+
// the same optical footing as the icon button beside it: an md field pairs
|
|
51
|
+
// with a default button (h-xs glyph), an xxs field with an xxs button
|
|
52
|
+
// (icon-xxs). One size for both would leave the two glyphs in one bar drawn at
|
|
53
|
+
// different weights.
|
|
54
|
+
const glyphClass = $derived(size === 'xxs' ? 'size-(--era-icon-xxs)' : 'size-(--era-h-xs)');
|
|
37
55
|
</script>
|
|
38
56
|
|
|
39
57
|
{#if icon}
|
|
@@ -48,9 +66,10 @@
|
|
|
48
66
|
arbitrary container that may carry its own fill. -->
|
|
49
67
|
<div
|
|
50
68
|
data-input-field={kind}
|
|
51
|
-
|
|
69
|
+
data-input-size={size}
|
|
70
|
+
class={cn(inputVariants({ bare, reveal, size }), 'items-center gap-(--era-gap)', className)}
|
|
52
71
|
>
|
|
53
|
-
<Icon class=
|
|
72
|
+
<Icon class={cn('shrink-0 text-muted', glyphClass)} />
|
|
54
73
|
<input
|
|
55
74
|
bind:this={ref}
|
|
56
75
|
bind:value
|
|
@@ -63,7 +82,8 @@
|
|
|
63
82
|
bind:this={ref}
|
|
64
83
|
bind:value
|
|
65
84
|
data-input-field={kind}
|
|
66
|
-
|
|
85
|
+
data-input-size={size}
|
|
86
|
+
class={cn(inputVariants({ bare, reveal, size }), textClass, className)}
|
|
67
87
|
{...restProps}
|
|
68
88
|
/>
|
|
69
89
|
{/if}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import type { Component } from 'svelte';
|
|
2
2
|
import type { IconProps } from '@lucide/svelte';
|
|
3
3
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
4
|
-
type $$ComponentProps = HTMLInputAttributes & {
|
|
4
|
+
type $$ComponentProps = Omit<HTMLInputAttributes, 'size'> & {
|
|
5
5
|
ref?: HTMLInputElement | null;
|
|
6
6
|
/** Lucide glyph rendered inside the field, left of the text. */
|
|
7
7
|
icon?: Component<IconProps> | null;
|
|
8
|
+
/**
|
|
9
|
+
* Field tier. `xxs` is badge height — for compact chrome where the field
|
|
10
|
+
* sits level with xxs buttons. See inputVariants.
|
|
11
|
+
*/
|
|
12
|
+
size?: 'md' | 'xxs';
|
|
8
13
|
/** Drop the field chrome — for an input inside a container that is already the field. */
|
|
9
14
|
bare?: boolean;
|
|
10
15
|
/** Hold the field chrome back until hover — for a title or label that IS the content. */
|