@aceshooting/lyra-ui 2.5.0 → 2.7.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/README.md +13 -7
- package/custom-elements.json +4560 -1025
- package/dist/components/app-rail/app-rail.class.d.ts +8 -1
- package/dist/components/app-rail/app-rail.class.d.ts.map +1 -1
- package/dist/components/app-rail/app-rail.class.js +12 -2
- package/dist/components/app-rail/app-rail.class.js.map +1 -1
- package/dist/components/chat-composer/chat-composer.class.d.ts +27 -0
- package/dist/components/chat-composer/chat-composer.class.d.ts.map +1 -1
- package/dist/components/chat-composer/chat-composer.class.js +64 -1
- package/dist/components/chat-composer/chat-composer.class.js.map +1 -1
- package/dist/components/chat-message/chat-message.class.d.ts +7 -1
- package/dist/components/chat-message/chat-message.class.d.ts.map +1 -1
- package/dist/components/chat-message/chat-message.class.js +15 -4
- package/dist/components/chat-message/chat-message.class.js.map +1 -1
- package/dist/components/checkbox/checkbox.class.d.ts +7 -0
- package/dist/components/checkbox/checkbox.class.d.ts.map +1 -1
- package/dist/components/checkbox/checkbox.class.js +7 -0
- package/dist/components/checkbox/checkbox.class.js.map +1 -1
- package/dist/components/chip/chip.class.d.ts +2 -0
- package/dist/components/chip/chip.class.d.ts.map +1 -1
- package/dist/components/chip/chip.class.js +3 -1
- package/dist/components/chip/chip.class.js.map +1 -1
- package/dist/components/chip/chip.styles.d.ts.map +1 -1
- package/dist/components/chip/chip.styles.js +10 -2
- package/dist/components/chip/chip.styles.js.map +1 -1
- package/dist/components/combobox/combobox.class.d.ts +16 -0
- package/dist/components/combobox/combobox.class.d.ts.map +1 -1
- package/dist/components/combobox/combobox.class.js +47 -2
- package/dist/components/combobox/combobox.class.js.map +1 -1
- package/dist/components/combobox/combobox.styles.d.ts.map +1 -1
- package/dist/components/combobox/combobox.styles.js +56 -6
- package/dist/components/combobox/combobox.styles.js.map +1 -1
- package/dist/components/conversation-item/conversation-item.class.d.ts +14 -0
- package/dist/components/conversation-item/conversation-item.class.d.ts.map +1 -1
- package/dist/components/conversation-item/conversation-item.class.js +38 -0
- package/dist/components/conversation-item/conversation-item.class.js.map +1 -1
- package/dist/components/date-picker/date-input.class.d.ts +25 -0
- package/dist/components/date-picker/date-input.class.d.ts.map +1 -1
- package/dist/components/date-picker/date-input.class.js +61 -0
- package/dist/components/date-picker/date-input.class.js.map +1 -1
- package/dist/components/dialog/dialog.class.d.ts +13 -1
- package/dist/components/dialog/dialog.class.d.ts.map +1 -1
- package/dist/components/dialog/dialog.class.js +24 -8
- package/dist/components/dialog/dialog.class.js.map +1 -1
- package/dist/components/empty/empty.class.d.ts +2 -0
- package/dist/components/empty/empty.class.d.ts.map +1 -1
- package/dist/components/empty/empty.class.js +2 -0
- package/dist/components/empty/empty.class.js.map +1 -1
- package/dist/components/empty/empty.styles.d.ts.map +1 -1
- package/dist/components/empty/empty.styles.js +6 -3
- package/dist/components/empty/empty.styles.js.map +1 -1
- package/dist/components/export-button/export-button.class.d.ts +19 -2
- package/dist/components/export-button/export-button.class.d.ts.map +1 -1
- package/dist/components/export-button/export-button.class.js +32 -8
- package/dist/components/export-button/export-button.class.js.map +1 -1
- package/dist/components/export-button/export-button.styles.d.ts.map +1 -1
- package/dist/components/export-button/export-button.styles.js +8 -1
- package/dist/components/export-button/export-button.styles.js.map +1 -1
- package/dist/components/gauge/gauge.class.d.ts +6 -2
- package/dist/components/gauge/gauge.class.d.ts.map +1 -1
- package/dist/components/gauge/gauge.class.js +40 -4
- package/dist/components/gauge/gauge.class.js.map +1 -1
- package/dist/components/gauge/gauge.styles.js +1 -1
- package/dist/components/graph/graph.class.d.ts +28 -1
- package/dist/components/graph/graph.class.d.ts.map +1 -1
- package/dist/components/graph/graph.class.js +94 -42
- package/dist/components/graph/graph.class.js.map +1 -1
- package/dist/components/graph/graph.styles.d.ts.map +1 -1
- package/dist/components/graph/graph.styles.js +4 -1
- package/dist/components/graph/graph.styles.js.map +1 -1
- package/dist/components/heatmap/heatmap.class.d.ts +22 -1
- package/dist/components/heatmap/heatmap.class.d.ts.map +1 -1
- package/dist/components/heatmap/heatmap.class.js +38 -3
- package/dist/components/heatmap/heatmap.class.js.map +1 -1
- package/dist/components/map/map.class.d.ts +4 -2
- package/dist/components/map/map.class.d.ts.map +1 -1
- package/dist/components/map/map.class.js +5 -3
- package/dist/components/map/map.class.js.map +1 -1
- package/dist/components/mention-popover/mention-popover.class.d.ts +9 -4
- package/dist/components/mention-popover/mention-popover.class.d.ts.map +1 -1
- package/dist/components/mention-popover/mention-popover.class.js +11 -5
- package/dist/components/mention-popover/mention-popover.class.js.map +1 -1
- package/dist/components/menu/menu.class.d.ts +10 -4
- package/dist/components/menu/menu.class.d.ts.map +1 -1
- package/dist/components/menu/menu.class.js +11 -5
- package/dist/components/menu/menu.class.js.map +1 -1
- package/dist/components/model-select/model-select.class.d.ts +44 -0
- package/dist/components/model-select/model-select.class.d.ts.map +1 -1
- package/dist/components/model-select/model-select.class.js +125 -0
- package/dist/components/model-select/model-select.class.js.map +1 -1
- package/dist/components/model-select/model-select.styles.d.ts.map +1 -1
- package/dist/components/model-select/model-select.styles.js +21 -0
- package/dist/components/model-select/model-select.styles.js.map +1 -1
- package/dist/components/pagination/pagination.class.d.ts +81 -0
- package/dist/components/pagination/pagination.class.d.ts.map +1 -0
- package/dist/components/pagination/pagination.class.js +278 -0
- package/dist/components/pagination/pagination.class.js.map +1 -0
- package/dist/components/pagination/pagination.d.ts +2 -0
- package/dist/components/pagination/pagination.d.ts.map +1 -0
- package/dist/components/pagination/pagination.js +5 -0
- package/dist/components/pagination/pagination.js.map +1 -0
- package/dist/components/pagination/pagination.styles.d.ts +2 -0
- package/dist/components/pagination/pagination.styles.d.ts.map +1 -0
- package/dist/components/pagination/pagination.styles.js +142 -0
- package/dist/components/pagination/pagination.styles.js.map +1 -0
- package/dist/components/phone-input/phone-input.class.d.ts +191 -0
- package/dist/components/phone-input/phone-input.class.d.ts.map +1 -0
- package/dist/components/phone-input/phone-input.class.js +493 -0
- package/dist/components/phone-input/phone-input.class.js.map +1 -0
- package/dist/components/phone-input/phone-input.d.ts +2 -0
- package/dist/components/phone-input/phone-input.d.ts.map +1 -0
- package/dist/components/phone-input/phone-input.js +5 -0
- package/dist/components/phone-input/phone-input.js.map +1 -0
- package/dist/components/phone-input/phone-input.styles.d.ts +2 -0
- package/dist/components/phone-input/phone-input.styles.d.ts.map +1 -0
- package/dist/components/phone-input/phone-input.styles.js +123 -0
- package/dist/components/phone-input/phone-input.styles.js.map +1 -0
- package/dist/components/poll-status/poll-status.styles.d.ts.map +1 -1
- package/dist/components/poll-status/poll-status.styles.js +5 -6
- package/dist/components/poll-status/poll-status.styles.js.map +1 -1
- package/dist/components/segmented/segmented.class.d.ts +4 -0
- package/dist/components/segmented/segmented.class.d.ts.map +1 -1
- package/dist/components/segmented/segmented.class.js +2 -1
- package/dist/components/segmented/segmented.class.js.map +1 -1
- package/dist/components/segmented/segmented.styles.d.ts.map +1 -1
- package/dist/components/segmented/segmented.styles.js +7 -0
- package/dist/components/segmented/segmented.styles.js.map +1 -1
- package/dist/components/skeleton/skeleton.styles.d.ts.map +1 -1
- package/dist/components/skeleton/skeleton.styles.js +1 -0
- package/dist/components/skeleton/skeleton.styles.js.map +1 -1
- package/dist/components/slider/slider.class.d.ts +3 -0
- package/dist/components/slider/slider.class.d.ts.map +1 -1
- package/dist/components/slider/slider.class.js +3 -0
- package/dist/components/slider/slider.class.js.map +1 -1
- package/dist/components/stream-status/stream-status.styles.d.ts.map +1 -1
- package/dist/components/stream-status/stream-status.styles.js +4 -5
- package/dist/components/stream-status/stream-status.styles.js.map +1 -1
- package/dist/components/switch/switch.class.d.ts +20 -0
- package/dist/components/switch/switch.class.d.ts.map +1 -1
- package/dist/components/switch/switch.class.js +83 -23
- package/dist/components/switch/switch.class.js.map +1 -1
- package/dist/components/switch/switch.styles.d.ts.map +1 -1
- package/dist/components/switch/switch.styles.js +18 -0
- package/dist/components/switch/switch.styles.js.map +1 -1
- package/dist/components/table/table.class.d.ts +12 -0
- package/dist/components/table/table.class.d.ts.map +1 -1
- package/dist/components/table/table.class.js +6 -1
- package/dist/components/table/table.class.js.map +1 -1
- package/dist/components/table/table.styles.d.ts.map +1 -1
- package/dist/components/table/table.styles.js +3 -0
- package/dist/components/table/table.styles.js.map +1 -1
- package/dist/components/textarea/textarea.class.d.ts +127 -0
- package/dist/components/textarea/textarea.class.d.ts.map +1 -0
- package/dist/components/textarea/textarea.class.js +364 -0
- package/dist/components/textarea/textarea.class.js.map +1 -0
- package/dist/components/textarea/textarea.d.ts +2 -0
- package/dist/components/textarea/textarea.d.ts.map +1 -0
- package/dist/components/textarea/textarea.js +5 -0
- package/dist/components/textarea/textarea.js.map +1 -0
- package/dist/components/textarea/textarea.styles.d.ts +2 -0
- package/dist/components/textarea/textarea.styles.d.ts.map +1 -0
- package/dist/components/textarea/textarea.styles.js +67 -0
- package/dist/components/textarea/textarea.styles.js.map +1 -0
- package/dist/components/time-range/time-range.class.d.ts +4 -0
- package/dist/components/time-range/time-range.class.d.ts.map +1 -1
- package/dist/components/time-range/time-range.class.js +4 -0
- package/dist/components/time-range/time-range.class.js.map +1 -1
- package/dist/components/tool-approval-dialog/tool-approval-dialog.class.d.ts +6 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.class.d.ts.map +1 -1
- package/dist/components/tool-approval-dialog/tool-approval-dialog.class.js +8 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.class.js.map +1 -1
- package/dist/components/tree/tree-node.class.d.ts +3 -0
- package/dist/components/tree/tree-node.class.d.ts.map +1 -1
- package/dist/components/tree/tree-node.class.js +16 -1
- package/dist/components/tree/tree-node.class.js.map +1 -1
- package/dist/components/tree/tree-node.styles.d.ts.map +1 -1
- package/dist/components/tree/tree-node.styles.js +27 -1
- package/dist/components/tree/tree-node.styles.js.map +1 -1
- package/dist/components/tree/tree.class.d.ts +11 -1
- package/dist/components/tree/tree.class.d.ts.map +1 -1
- package/dist/components/tree/tree.class.js +6 -2
- package/dist/components/tree/tree.class.js.map +1 -1
- package/dist/components/typing-indicator/typing-indicator.class.d.ts +4 -0
- package/dist/components/typing-indicator/typing-indicator.class.d.ts.map +1 -1
- package/dist/components/typing-indicator/typing-indicator.class.js +4 -0
- package/dist/components/typing-indicator/typing-indicator.class.js.map +1 -1
- package/dist/components/typing-indicator/typing-indicator.styles.d.ts.map +1 -1
- package/dist/components/typing-indicator/typing-indicator.styles.js +24 -22
- package/dist/components/typing-indicator/typing-indicator.styles.js.map +1 -1
- package/dist/components/widget/widget.class.d.ts +5 -0
- package/dist/components/widget/widget.class.d.ts.map +1 -1
- package/dist/components/widget/widget.class.js +22 -1
- package/dist/components/widget/widget.class.js.map +1 -1
- package/dist/components/widget/widget.styles.d.ts.map +1 -1
- package/dist/components/widget/widget.styles.js +3 -2
- package/dist/components/widget/widget.styles.js.map +1 -1
- package/dist/internal/localization.d.ts +1 -1
- package/dist/internal/localization.d.ts.map +1 -1
- package/dist/internal/localization.js +6 -0
- package/dist/internal/localization.js.map +1 -1
- package/dist/internal/root-registration-allowlist.d.ts +1 -1
- package/dist/internal/root-registration-allowlist.d.ts.map +1 -1
- package/dist/internal/root-registration-allowlist.js +3 -0
- package/dist/internal/root-registration-allowlist.js.map +1 -1
- package/dist/internal/tokens.styles.d.ts.map +1 -1
- package/dist/internal/tokens.styles.js +6 -2
- package/dist/internal/tokens.styles.js.map +1 -1
- package/dist/lyra.d.ts +14 -2
- package/dist/lyra.d.ts.map +1 -1
- package/dist/lyra.js +6 -0
- package/dist/lyra.js.map +1 -1
- package/llms-full.txt +615 -92
- package/llms.txt +5 -3
- package/package.json +12 -2
package/llms-full.txt
CHANGED
|
@@ -22,8 +22,8 @@ composition without registration; for example, `components/empty/empty.class.js`
|
|
|
22
22
|
## Contents
|
|
23
23
|
|
|
24
24
|
- **Shared foundation** — `internal/` (base class, form-association mixin, positioning helper, design tokens)
|
|
25
|
-
- **Form controls, toasts, sparkline, and flags** — `lyra-combobox`/`lyra-option`, `lyra-select`, `lyra-date-picker`/`lyra-date-input`, `lyra-toast` family, `lyra-sparkline`, `lyra-flag`
|
|
26
|
-
- **Dashboard atoms** — `lyra-empty`, `lyra-skeleton`, `lyra-stat`, `lyra-table`, `lyra-gauge`, `lyra-export-button`, `lyra-copy-button`, `lyra-split`, `lyra-widget`, `lyra-word-cloud`
|
|
25
|
+
- **Form controls, toasts, sparkline, and flags** — `lyra-combobox`/`lyra-option`, `lyra-select`, `lyra-date-picker`/`lyra-date-input`, `lyra-phone-input`, `lyra-toast` family, `lyra-sparkline`, `lyra-flag`
|
|
26
|
+
- **Dashboard atoms** — `lyra-empty`, `lyra-skeleton`, `lyra-stat`, `lyra-table`, `lyra-pagination`, `lyra-gauge`, `lyra-export-button`, `lyra-copy-button`, `lyra-split`, `lyra-widget`, `lyra-word-cloud`
|
|
27
27
|
- **Temporal & graph** — `lyra-time-range`, `lyra-playback`, `lyra-heatmap`, `lyra-graph`, `lyra-tree`/`lyra-tree-node`
|
|
28
28
|
- **Chart family** — `lyra-chart` (core), typed subclasses, `lyra-histogram`, `lyra-box-plot`,
|
|
29
29
|
`lyra-lite-chart` (dependency-free bar/line alternative, no peer deps)
|
|
@@ -193,6 +193,8 @@ shared `FormAssociated` mixin — see gotchas).
|
|
|
193
193
|
|
|
194
194
|
**Properties:**
|
|
195
195
|
- `multiple: boolean = false` (reflected)
|
|
196
|
+
- `size: 'xs' | 's' | 'm' | 'l' | 'xl' = 'm'` (reflected — same scale as `lyra-select`'s `size`;
|
|
197
|
+
also scales the "+N" overflow tag's padding/font-size to match)
|
|
196
198
|
- `placeholder: string = ''`
|
|
197
199
|
- `disabled: boolean = false` (reflected)
|
|
198
200
|
- `required: boolean = false` (reflected — enforced via `internals.setValidity()`; also reflected as
|
|
@@ -224,10 +226,17 @@ shared `FormAssociated` mixin — see gotchas).
|
|
|
224
226
|
`overflowText` row instead of being dropped silently)
|
|
225
227
|
- `value: string | string[]` — a getter/setter: plain `string` in single mode, `string[]` in
|
|
226
228
|
`multiple` mode
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
229
|
+
- `selectedRows: ComboboxSourceRow[]` (read-only getter) — structured rows for the current
|
|
230
|
+
selection, including any opaque `data` payload supplied by an async source. Selected async rows
|
|
231
|
+
remain available after the query changes or a later source result no longer contains them
|
|
232
|
+
|
|
233
|
+
`ComboboxSourceRow = { value: string; label: string; sub?: string; icon?: unknown; badge?: string |
|
|
234
|
+
number; accessibleLabel?: string; data?: unknown; dotColor?: string; group?: string; disabled?:
|
|
235
|
+
boolean }` — the row shape used by the async `source` path. `icon` renders as a decorative leading
|
|
236
|
+
visual, `badge` as trailing metadata, `accessibleLabel` can provide richer spoken text than the
|
|
237
|
+
visible label, and `data` is retained without being rendered for retrieval through `selectedRows`.
|
|
238
|
+
The light-DOM `<lyra-option>` path normalizes its supported label/sub/dot/group fields to the same
|
|
239
|
+
internal row model.
|
|
231
240
|
|
|
232
241
|
**Events:** typing in the filter exposes the original bubbling/composed, non-cancelable `InputEvent`
|
|
233
242
|
as exactly one host `input` event and does not fire `change`. An actual user selection mutation —
|
|
@@ -242,9 +251,10 @@ attribute when provided)
|
|
|
242
251
|
|
|
243
252
|
**CSS parts:** `form-control`, `form-control-label`, `combobox`, `tags`, `tag`,
|
|
244
253
|
`tag__remove-button`, `combobox-input`, `clear-button`, `expand-icon`, `listbox`, `option`,
|
|
245
|
-
`option-dot` (the leading status dot, when a row's `dotColor` is set), `option-
|
|
246
|
-
|
|
247
|
-
`
|
|
254
|
+
`option-dot` (the leading status dot, when a row's `dotColor` is set), `option-icon` (the decorative
|
|
255
|
+
leading visual for an async row), `option-label`, `option-sub` (a row's secondary line, when `sub`
|
|
256
|
+
is set), `option-badge` (an async row's trailing metadata), `option-overflow` (the "+N more"
|
|
257
|
+
indicator from `maxRender`), `error`, `hint`
|
|
248
258
|
|
|
249
259
|
**Themeable custom properties:** shared tokens only.
|
|
250
260
|
|
|
@@ -281,7 +291,14 @@ attribute when provided)
|
|
|
281
291
|
<script type="module">
|
|
282
292
|
document.getElementById('cb2').source = async (query) => {
|
|
283
293
|
const rows = await fetchFruit(query); // your own lookup
|
|
284
|
-
return rows.map((r) => ({
|
|
294
|
+
return rows.map((r) => ({
|
|
295
|
+
value: r.id,
|
|
296
|
+
label: r.name,
|
|
297
|
+
icon: renderFruitIcon(r), // decorative; hidden from assistive technology
|
|
298
|
+
badge: r.category,
|
|
299
|
+
accessibleLabel: `${r.name}, ${r.category}`,
|
|
300
|
+
data: r, // retained in cb2.selectedRows after selection
|
|
301
|
+
}));
|
|
285
302
|
};
|
|
286
303
|
</script>
|
|
287
304
|
```
|
|
@@ -304,7 +321,6 @@ synchronous and fires no `input`/`change` event.
|
|
|
304
321
|
- a host-level `aria-label` attribute on `<lyra-combobox>` now takes priority over `label`/
|
|
305
322
|
`placeholder`/`"Combobox"` when resolving the accessible name on `[part="combobox-input"]` —
|
|
306
323
|
previously it was silently ignored. Matches the same fallback on `<lyra-select>`.
|
|
307
|
-
- no `size` variant (small/medium/large) unlike sibling `lyra-toast-item`.
|
|
308
324
|
- `aria-required` reflects `required` immediately; `aria-invalid`, by contrast, only reflects
|
|
309
325
|
**after the field has been touched** (first `blur`) — a `required` field with a validity error
|
|
310
326
|
doesn't look invalid to assistive tech before that, by design (avoids flashing invalid styling on
|
|
@@ -313,6 +329,10 @@ synchronous and fires no `input`/`change` event.
|
|
|
313
329
|
- `dotColor`/`sub`/`group` are read from light-DOM `<lyra-option>` children as before, but are also
|
|
314
330
|
first-class fields on `ComboboxSourceRow` for the async `source` path — an async lookup can drive
|
|
315
331
|
the same grouped/dot/sub-text rendering a static option list can.
|
|
332
|
+
- `icon`, `badge`, `accessibleLabel`, and `data` are async-source row features rather than
|
|
333
|
+
`<lyra-option>` properties. Icons are decorative (`aria-hidden`); use `accessibleLabel` when the
|
|
334
|
+
visible label/sub/badge combination needs a fuller spoken name. `data` is deliberately opaque and
|
|
335
|
+
is available only through the read-only `selectedRows` getter.
|
|
316
336
|
- Full ARIA 1.2 combobox pattern (`role=combobox`, roving `aria-activedescendant`, real DOM focus
|
|
317
337
|
kept on the input) is implemented correctly — a genuine strength, safe to build on. Declaratively-
|
|
318
338
|
selected options (`<lyra-option value="b" selected>`) are seeded into the selection (mirroring
|
|
@@ -507,10 +527,18 @@ Text field + calendar popover, **form-associated** via the shared `FormAssociate
|
|
|
507
527
|
calendar-toggle button)
|
|
508
528
|
- `dialogLabel: string = 'Choose date'` (attribute `dialog-label` — accessible name for the
|
|
509
529
|
`role="dialog"` calendar popover)
|
|
530
|
+
- `spellcheck: boolean = true` — forwarded to the internal `<input>`
|
|
531
|
+
- `autocapitalize: string = ''` — forwarded to the internal `<input>`; empty omits the attribute
|
|
532
|
+
- `autoCorrect: string = ''` (attribute `autocorrect`, Safari/WebKit-specific) — forwarded to the
|
|
533
|
+
internal `<input>`; empty omits the attribute. Named `autoCorrect` in JS/TS (not `autocorrect`)
|
|
534
|
+
to dodge a `lib.dom.d.ts` collision with `HTMLElement`'s own boolean `autocorrect` IDL member;
|
|
535
|
+
the wire attribute is still the plain `autocorrect` name
|
|
510
536
|
|
|
511
537
|
**Methods:** `show()`, `hide()`, `clear()`
|
|
512
538
|
|
|
513
|
-
**Events:** `input`, `change`, `lyra-show`, `lyra-hide`, `lyra-clear`
|
|
539
|
+
**Events:** `input`, `change`, `lyra-show`, `lyra-hide`, `lyra-clear`, `blur` (re-dispatched from
|
|
540
|
+
the internal `<input>`'s own `blur`, bubbling and composed unlike the native event), `focus`
|
|
541
|
+
(re-dispatched from the internal `<input>`'s own `focus`, for the same reason as `blur`)
|
|
514
542
|
|
|
515
543
|
**Slots:** `label`, `error` (overrides `errorText`), `hint`
|
|
516
544
|
|
|
@@ -579,6 +607,247 @@ and `dateTimeFormat(locale, options)`.
|
|
|
579
607
|
|
|
580
608
|
---
|
|
581
609
|
|
|
610
|
+
## lyra-textarea
|
|
611
|
+
|
|
612
|
+
A multiline plain-text input primitive, form-associated (participates in native `<form>`
|
|
613
|
+
submission/validation/reset via `name`/`value`/`disabled`/`required`/`checkValidity()`/
|
|
614
|
+
`reportValidity()`). Ships an opt-in `label`/`hint`/`errorText` form-control chrome mirroring
|
|
615
|
+
`lyra-select` -- left unset, none of it renders.
|
|
616
|
+
|
|
617
|
+
```html
|
|
618
|
+
<lyra-textarea placeholder="Notes" rows="4"></lyra-textarea>
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
### Properties
|
|
622
|
+
|
|
623
|
+
| Property | Attribute | Type | Default | Description |
|
|
624
|
+
| --- | --- | --- | --- | --- |
|
|
625
|
+
| `value` | `value` | `string` | `''` | The current text value. |
|
|
626
|
+
| `rows` | `rows` | `number` | `3` | Visible text rows. |
|
|
627
|
+
| `resize` | `resize` | `'none' \| 'vertical' \| 'both' \| 'auto'` | `'vertical'` | Native CSS `resize` behavior, plus `'auto'` (`ResizeObserver`-driven grow-to-content, no manual handle). |
|
|
628
|
+
| `placeholder` | `placeholder` | `string` | `''` | Placeholder text. |
|
|
629
|
+
| `label` | `label` | `string` | `''` | Visible label text. Unset: no label chrome renders. |
|
|
630
|
+
| `hint` | `hint` | `string` | `''` | Hint text below the field. |
|
|
631
|
+
| `errorText` | `error-text` | `string` | `''` | Error text below the field (overridden by slotted `error` content). |
|
|
632
|
+
| `accessibleLabel` | `aria-label` | `string \| null` | `null` | Accessible-name override forwarded to the internal `<textarea>`; wins over `label`, `placeholder`, and the localized default. |
|
|
633
|
+
| `spellcheck` | `spellcheck` | `boolean` | `true` | Forwarded to the native `<textarea>`. |
|
|
634
|
+
| `autocapitalize` | `autocapitalize` | `string` | `''` | Forwarded to the native `<textarea>`; empty omits the attribute. |
|
|
635
|
+
| `autoCorrect` | `autocorrect` | `string` | `''` | Forwarded to the native `<textarea>` (Safari/WebKit-specific); empty omits the attribute. |
|
|
636
|
+
| `wrap` | `wrap` | `'hard' \| 'soft' \| 'off'` | `'soft'` | Native line-wrapping/submission behavior. |
|
|
637
|
+
| `autocomplete` | `autocomplete` | `string` | `''` | Forwarded to the native `<textarea>`; empty omits the attribute. |
|
|
638
|
+
| `inputMode` | `inputmode` | `string` | `''` | Virtual-keyboard input hint forwarded to the native `<textarea>`. |
|
|
639
|
+
| `enterKeyHint` | `enterkeyhint` | `string` | `''` | Virtual-keyboard Enter-key hint forwarded to the native `<textarea>`. |
|
|
640
|
+
| `name` | `name` | `string` | `''` | Form field name. |
|
|
641
|
+
| `disabled` | `disabled` | `boolean` | `false` | Disables the control. |
|
|
642
|
+
| `required` | `required` | `boolean` | `false` | Participates in native constraint validation. |
|
|
643
|
+
|
|
644
|
+
The visible label, hint, and error live in the same shadow tree as the native control, so their
|
|
645
|
+
generated ids safely drive the native `<label>`/`aria-describedby` relationships. Name precedence
|
|
646
|
+
is `accessibleLabel`/host `aria-label`, visible `label`, `placeholder`, then the localized
|
|
647
|
+
`textareaLabel` message. External `aria-labelledby`/`aria-describedby` idrefs are not copied across
|
|
648
|
+
the shadow boundary.
|
|
649
|
+
|
|
650
|
+
### Getters and selection properties
|
|
651
|
+
|
|
652
|
+
- `input: HTMLTextAreaElement | null` — the internal native control.
|
|
653
|
+
- `selectionStart: number | null`, `selectionEnd: number | null`, and
|
|
654
|
+
`selectionDirection: 'forward'|'backward'|'none'|null` — readable and writable passthroughs to
|
|
655
|
+
the native selection state.
|
|
656
|
+
- The shared form-associated getters `form`, `labels`, `validity`, `validationMessage`,
|
|
657
|
+
`willValidate`, and `effectiveDisabled` are also available.
|
|
658
|
+
|
|
659
|
+
### Methods
|
|
660
|
+
|
|
661
|
+
| Method | Description |
|
|
662
|
+
| --- | --- |
|
|
663
|
+
| `focus(options?)` / `blur()` | Focus or blur the internal native control. |
|
|
664
|
+
| `select()` | Select all text. |
|
|
665
|
+
| `setSelectionRange(start, end, direction?)` | Set the native selection range and optional direction. |
|
|
666
|
+
| `setRangeText(replacement, start?, end?, selectMode?)` | Apply a native range edit, then synchronize the component `value`, form value, validity, and auto-grown size without emitting a user event. |
|
|
667
|
+
| `setFormValue(value)` | Set the reactive and submitted value synchronously. |
|
|
668
|
+
| `checkValidity()` / `reportValidity()` | Run native constraint validation through `ElementInternals`. |
|
|
669
|
+
|
|
670
|
+
### Events
|
|
671
|
+
|
|
672
|
+
| Event | Detail | Description |
|
|
673
|
+
| --- | --- | --- |
|
|
674
|
+
| `lyra-input` | `{ value: string }` | Fired on every user-driven edit. |
|
|
675
|
+
| `lyra-change` | `{ value: string }` | Fired on native `change` timing (blur after a committed edit). |
|
|
676
|
+
| `blur` | none | Re-dispatched from the internal native `<textarea>`'s own `blur` -- bubbling and composed, unlike the native event. |
|
|
677
|
+
| `focus` | none | Re-dispatched from the internal native `<textarea>`'s own `focus`, for the same reason as `blur`. |
|
|
678
|
+
|
|
679
|
+
Programmatic property assignments, selection changes, `setRangeText()`, form reset, and form-state
|
|
680
|
+
restoration are silent. User edits update `value`, submitted form data, and required validity before
|
|
681
|
+
the corresponding `lyra-input`/`lyra-change` event is dispatched. `form.reset()` restores the
|
|
682
|
+
original declarative `value`, matching native `defaultValue` behavior.
|
|
683
|
+
|
|
684
|
+
### Slots
|
|
685
|
+
|
|
686
|
+
| Slot | Description |
|
|
687
|
+
| --- | --- |
|
|
688
|
+
| `label` | Custom label content. |
|
|
689
|
+
| `hint` | Custom hint content. |
|
|
690
|
+
| `error` | Custom error content. |
|
|
691
|
+
|
|
692
|
+
### CSS Parts
|
|
693
|
+
|
|
694
|
+
| Part | Description |
|
|
695
|
+
| --- | --- |
|
|
696
|
+
| `form-control` | The outer wrapper around label, textarea, error and hint. |
|
|
697
|
+
| `form-control-label` | The `<label>` element. |
|
|
698
|
+
| `textarea` | The native `<textarea>` element. |
|
|
699
|
+
| `hint` | The hint message. |
|
|
700
|
+
| `error` | The error message. |
|
|
701
|
+
|
|
702
|
+
### Themeable custom properties
|
|
703
|
+
|
|
704
|
+
- `--lyra-textarea-max-block-size` (default `none`) — bounds `resize="auto"`; content beyond the
|
|
705
|
+
bound scrolls inside the native textarea. Auto-resize remeasures after user edits, programmatic
|
|
706
|
+
`value`/`rows` changes, range edits, and container-width changes.
|
|
707
|
+
|
|
708
|
+
---
|
|
709
|
+
|
|
710
|
+
## `lyra-phone-input`
|
|
711
|
+
|
|
712
|
+
A form-associated, country-aware telephone field. The submitted `value` is either canonical E.164
|
|
713
|
+
(for example `+352621123456`) or `''` while the editable input is empty, incomplete, or invalid.
|
|
714
|
+
Numbering-plan metadata and national formatting stay outside Lyra's base bundle: supply a
|
|
715
|
+
synchronous `PhoneNumberAdapter`, or lazily create one from a `libphonenumber-js`-compatible module
|
|
716
|
+
with `loadLibphonenumberAdapter()`. Without an adapter, already-international E.164 input still
|
|
717
|
+
normalizes and validates; national input remains editable with `incomplete` validity.
|
|
718
|
+
|
|
719
|
+
**Types:**
|
|
720
|
+
|
|
721
|
+
```ts
|
|
722
|
+
type PhoneNumberStatus = 'empty' | 'incomplete' | 'invalid' | 'valid';
|
|
723
|
+
|
|
724
|
+
interface PhoneCountry {
|
|
725
|
+
code: string; // ISO 3166-1 alpha-2
|
|
726
|
+
callingCode: string; // no leading "+"
|
|
727
|
+
label?: string; // overrides Intl.DisplayNames
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
interface PhoneNumberParseResult {
|
|
731
|
+
status: PhoneNumberStatus;
|
|
732
|
+
e164?: string; // required for status: 'valid'
|
|
733
|
+
formatted?: string; // best-effort editable display text
|
|
734
|
+
country?: string; // detected ISO alpha-2 code
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
interface PhoneNumberAdapter {
|
|
738
|
+
readonly countries?: readonly PhoneCountry[];
|
|
739
|
+
parse(input: string, country?: string): PhoneNumberParseResult;
|
|
740
|
+
}
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
**Properties:**
|
|
744
|
+
|
|
745
|
+
- `value: string = ''` — canonical E.164 form/submission value. A programmatic assignment is parsed
|
|
746
|
+
and normalized synchronously but emits no user event.
|
|
747
|
+
- `name: string = ''`, `disabled: boolean = false`, `required: boolean = false` — native-like
|
|
748
|
+
form-control properties supplied by `FormAssociated`; inherited disabled fieldsets are included
|
|
749
|
+
through `effectiveDisabled`.
|
|
750
|
+
- `adapter?: PhoneNumberAdapter` (attribute: false) — synchronous numbering-plan parser/formatter.
|
|
751
|
+
No metadata implementation is imported by the component itself.
|
|
752
|
+
- `countries: readonly PhoneCountry[] = []` (attribute: false) — explicit selector rows; takes
|
|
753
|
+
precedence over `adapter.countries`.
|
|
754
|
+
- `defaultCountry: string = ''` (attribute `default-country`) — selected when `country` has not been
|
|
755
|
+
set explicitly.
|
|
756
|
+
- `country: string` — current uppercase ISO alpha-2 selection; falls back to `defaultCountry`, then
|
|
757
|
+
the first explicit/adapter country. Changing the country reparses the editable number.
|
|
758
|
+
- `label: string = ''`, `hint: string = ''`, `errorText: string = ''` (attribute `error-text`) —
|
|
759
|
+
visible form-field chrome; each has a matching named slot.
|
|
760
|
+
- `placeholder: string = ''` — forwarded to the native telephone input.
|
|
761
|
+
- host `aria-label` — forwarded to the internal telephone input. Name precedence is `phoneLabel`,
|
|
762
|
+
host `aria-label`, visible `label`, then `placeholder`.
|
|
763
|
+
- `phoneLabel: string = ''` (attribute `phone-label`) — explicit accessible-name override for the
|
|
764
|
+
native telephone input.
|
|
765
|
+
- `countryLabel: string = 'Select'` (attribute `country-label`) — country-selector accessible name;
|
|
766
|
+
the untouched default routes through the shared localized `select` message.
|
|
767
|
+
- `incompleteText: string = 'The value is invalid.'` (attribute `incomplete-text`) — validation
|
|
768
|
+
message for dial-like input that can still become valid with more digits. The untouched default
|
|
769
|
+
routes through the shared localized `valueInvalid` message.
|
|
770
|
+
- `invalidText: string = 'The value is invalid.'` (attribute `invalid-text`) — completed-invalid
|
|
771
|
+
message, localized through the same shared key while left at its default.
|
|
772
|
+
- `autocomplete: string = 'tel'`, `inputmode: 'tel'|'numeric'|'text' = 'tel'`,
|
|
773
|
+
`enterkeyhint: string = ''` — forwarded to the internal `<input type="tel">`.
|
|
774
|
+
- readonly `input: HTMLInputElement | undefined` — the internal native telephone input.
|
|
775
|
+
- readonly `inputValue: string` — editable formatted/partial text, which remains available even when
|
|
776
|
+
canonical `value` is `''`.
|
|
777
|
+
- readonly `phoneStatus: PhoneNumberStatus` — current parse state. The host also reflects it through
|
|
778
|
+
`data-phone-status`.
|
|
779
|
+
- readonly `form`, `labels`, `validity`, `validationMessage`, `willValidate`, and
|
|
780
|
+
`effectiveDisabled` — the shared form-associated native-like getters.
|
|
781
|
+
|
|
782
|
+
**Validity:** empty + `required` sets `valueMissing`; incomplete dial-like input sets `badInput`;
|
|
783
|
+
completed-invalid input sets `typeMismatch`; valid E.164 input clears all three. Partial or invalid
|
|
784
|
+
text remains in `inputValue`/the native input so validation never makes a number impossible to edit,
|
|
785
|
+
but its canonical submitted `value` is blank. Native validation feedback is anchored to the
|
|
786
|
+
telephone input, not the adjacent country selector.
|
|
787
|
+
|
|
788
|
+
**Methods:** `focus(options?)`, `blur()`, and `select()` forward to the native telephone input.
|
|
789
|
+
`setFormValue(value)`, `checkValidity()`, and `reportValidity()` come from `FormAssociated`.
|
|
790
|
+
`form.reset()` restores the original declarative `value` and the default country.
|
|
791
|
+
|
|
792
|
+
**Events:**
|
|
793
|
+
|
|
794
|
+
- `input` — every user edit and country change.
|
|
795
|
+
- `change` — native telephone-input commit timing and every country change.
|
|
796
|
+
- `focus` / `blur` — bubbling, composed bridges for the internal native input's non-crossing focus
|
|
797
|
+
events.
|
|
798
|
+
|
|
799
|
+
`input`/`change` detail is
|
|
800
|
+
`{ value: string; inputValue: string; country: string; valid: boolean; status: PhoneNumberStatus }`.
|
|
801
|
+
Programmatic property assignments and form reset/state restoration are silent.
|
|
802
|
+
|
|
803
|
+
**Slots:** `label`, `hint`, `error`, `country-prefix` (optional visual before the country selector,
|
|
804
|
+
such as a consumer-owned `<lyra-flag>`; no flag package is imported automatically).
|
|
805
|
+
|
|
806
|
+
**CSS parts:** `form-control`, `form-control-label`, `input-wrapper`, `country-prefix`,
|
|
807
|
+
`country-select`, `calling-code`, `input`, `hint`, `error`.
|
|
808
|
+
|
|
809
|
+
**Themeable custom properties:** shared tokens only. The phone-number input and calling code are
|
|
810
|
+
deliberately `dir="ltr"`/isolated because telephone numbers are algorithmic content; surrounding
|
|
811
|
+
form chrome and the country selector inherit LTR/RTL and use logical spacing/borders.
|
|
812
|
+
|
|
813
|
+
**Optional peer deps:** `libphonenumber-js` is declared optional but never imported by Lyra itself.
|
|
814
|
+
For full national parsing/formatting, install it in the consuming app and pass it through the
|
|
815
|
+
consumer-supplied lazy loader below. Because the import expression lives in consumer code, no
|
|
816
|
+
numbering metadata enters a bundle that does not opt in.
|
|
817
|
+
|
|
818
|
+
```ts
|
|
819
|
+
import '@aceshooting/lyra-ui/components/phone-input/phone-input.js';
|
|
820
|
+
import { loadLibphonenumberAdapter } from
|
|
821
|
+
'@aceshooting/lyra-ui/components/phone-input/phone-input.class.js';
|
|
822
|
+
|
|
823
|
+
const phone = document.querySelector('lyra-phone-input');
|
|
824
|
+
phone.adapter = await loadLibphonenumberAdapter(() => import('libphonenumber-js/min'));
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
```html
|
|
828
|
+
<lyra-phone-input
|
|
829
|
+
name="mobile"
|
|
830
|
+
label="Mobile number"
|
|
831
|
+
hint="Used only for account security"
|
|
832
|
+
default-country="LU"
|
|
833
|
+
required
|
|
834
|
+
></lyra-phone-input>
|
|
835
|
+
```
|
|
836
|
+
|
|
837
|
+
**Known gotchas:**
|
|
838
|
+
|
|
839
|
+
- An adapter's `parse()` method is synchronous because it runs on every keystroke. Load any optional
|
|
840
|
+
module first, then assign the resolved adapter. Adapter exceptions degrade to the E.164-only
|
|
841
|
+
fallback rather than breaking editing.
|
|
842
|
+
- A valid adapter result must include an E.164-shaped `e164`; a malformed "valid" result is treated
|
|
843
|
+
as invalid instead of entering form submission.
|
|
844
|
+
- Country names use `Intl.DisplayNames` and fall back to the ISO code; set `PhoneCountry.label` for
|
|
845
|
+
a product-specific name. Calling codes are data, not derived by the component.
|
|
846
|
+
- The component does not import `@aceshooting/lyra-flags`. Compose an optional flag through
|
|
847
|
+
`country-prefix` and keep it decorative when the adjacent select already announces the country.
|
|
848
|
+
|
|
849
|
+
---
|
|
850
|
+
|
|
582
851
|
## `lyra-toast` / `lyra-toast-item` / `toast()`
|
|
583
852
|
|
|
584
853
|
Stacking toast/notification region. Mirrors `<wa-toast>`/`<wa-toast-item>` under `lyra-`.
|
|
@@ -866,8 +1135,9 @@ attribute), `description` (rich description content, overrides the `description`
|
|
|
866
1135
|
|
|
867
1136
|
**CSS parts:** `base`, `icon`, `heading`, `description`, `actions`
|
|
868
1137
|
|
|
869
|
-
**Themeable custom properties:**
|
|
870
|
-
|
|
1138
|
+
**Themeable custom properties:** `--lyra-empty-compact-align` (compact mode only; defaults preserve
|
|
1139
|
+
the existing `flex-start` cross-axis and `start` text alignment, and `center` centers both), plus
|
|
1140
|
+
shared tokens (`--lyra-space-xs/-s/-l`, `--lyra-color-text-quiet/-border/-text`).
|
|
871
1141
|
|
|
872
1142
|
**Optional peer deps:** none.
|
|
873
1143
|
|
|
@@ -876,6 +1146,8 @@ attribute), `description` (rich description content, overrides the `description`
|
|
|
876
1146
|
<svg slot="" ...></svg> <!-- default slot: any icon/illustration -->
|
|
877
1147
|
<div slot="actions"><button>Clear filters</button></div>
|
|
878
1148
|
</lyra-empty>
|
|
1149
|
+
<lyra-empty compact heading="No results" description="Try a different search."
|
|
1150
|
+
style="--lyra-empty-compact-align: center"></lyra-empty>
|
|
879
1151
|
```
|
|
880
1152
|
|
|
881
1153
|
**Known gotchas:**
|
|
@@ -1108,18 +1380,94 @@ body's `max-block-size`).
|
|
|
1108
1380
|
|
|
1109
1381
|
---
|
|
1110
1382
|
|
|
1383
|
+
## `lyra-pagination`
|
|
1384
|
+
|
|
1385
|
+
Controlled page navigation for server-side or client-side data sets: previous/next buttons, a
|
|
1386
|
+
validated numeric page jump, a localized item-range summary, and a polite announcement after the
|
|
1387
|
+
host applies a requested page. The component owns no data fetching and never mutates `page`.
|
|
1388
|
+
|
|
1389
|
+
**Properties and getters:**
|
|
1390
|
+
- `page: number = 1` (reflected) — the currently applied page. Runtime values are presented within
|
|
1391
|
+
the valid `1..pageCount` range, but the public property itself remains controlled and is not
|
|
1392
|
+
rewritten by the component
|
|
1393
|
+
- `pageSize: number = 20` (attribute `page-size`) — items per page; finite values are truncated to
|
|
1394
|
+
a non-negative integer for the derived calculations, and zero produces no pages
|
|
1395
|
+
- `totalItems: number = 0` (attribute `total-items`) — total item count; finite values are truncated
|
|
1396
|
+
to a non-negative integer for display and page-count calculations
|
|
1397
|
+
- `pageCount: number` (readonly getter) — `ceil(totalItems / pageSize)` after the normalization
|
|
1398
|
+
above, or `0` when either normalized input is zero
|
|
1399
|
+
- `disabled: boolean = false` (reflected)
|
|
1400
|
+
- `loading: boolean = false` (reflected) — disables all controls and sets `aria-busy="true"` on the
|
|
1401
|
+
internal navigation landmark
|
|
1402
|
+
- `hideSummary: boolean = false` (attribute `hide-summary`, reflected) — omits the built-in range
|
|
1403
|
+
summary while retaining the controls
|
|
1404
|
+
- `size: 'xs'|'s'|'m'|'l'|'xl' = 'm'` (reflected) — changes control height and type size
|
|
1405
|
+
- `itemLabel: string = ''` (attribute `item-label`) — custom item noun used in the summary; empty
|
|
1406
|
+
selects the localized singular `item` or plural `items` key
|
|
1407
|
+
- `accessibleLabel: string | null = null` (attribute `aria-label`) — host accessible-name override
|
|
1408
|
+
forwarded to the internal `<nav>` landmark; takes precedence over `label`
|
|
1409
|
+
- `label: string = 'Pagination'` — fallback accessible name for the internal `<nav>` landmark
|
|
1410
|
+
- `pageLabel: string = 'Page'` (attribute `page-label`) — accessible name for the page-jump input
|
|
1411
|
+
- `previousLabel: string = 'Previous'` (attribute `previous-label`), `nextLabel: string = 'Next'`
|
|
1412
|
+
(attribute `next-label`) — accessible names for the icon-only directional buttons
|
|
1413
|
+
|
|
1414
|
+
Built-in property defaults resolve through the locale registry. A property value customized away
|
|
1415
|
+
from its built-in default is treated as an explicit per-instance wording override.
|
|
1416
|
+
|
|
1417
|
+
**Events:** `lyra-page-change` (`detail: { page: number }`, bubbles and composes, non-cancelable) —
|
|
1418
|
+
emitted for a valid, different requested page. The host applies `event.detail.page` back to `page`
|
|
1419
|
+
after routing, fetching, or any other policy decision.
|
|
1420
|
+
|
|
1421
|
+
**Slots:** none.
|
|
1422
|
+
|
|
1423
|
+
**CSS parts:** `base`, `summary`, `controls`, `previous-button`, `previous-icon`, `page-field`,
|
|
1424
|
+
`page-input`, `page-count`, `next-button`, `next-icon`, `live-region`.
|
|
1425
|
+
|
|
1426
|
+
**Themeable custom properties:** `--lyra-pagination-control-size` and
|
|
1427
|
+
`--lyra-pagination-font-size` (both default from `size`), plus shared color, spacing, border, radius,
|
|
1428
|
+
disabled-opacity, and focus-ring tokens.
|
|
1429
|
+
|
|
1430
|
+
**Optional peer deps:** none.
|
|
1431
|
+
|
|
1432
|
+
```html
|
|
1433
|
+
<lyra-pagination total-items="237" page-size="20"></lyra-pagination>
|
|
1434
|
+
<script>
|
|
1435
|
+
const pagination = document.querySelector('lyra-pagination');
|
|
1436
|
+
pagination.addEventListener('lyra-page-change', async (event) => {
|
|
1437
|
+
await loadPage(event.detail.page);
|
|
1438
|
+
pagination.page = event.detail.page;
|
|
1439
|
+
});
|
|
1440
|
+
</script>
|
|
1441
|
+
```
|
|
1442
|
+
|
|
1443
|
+
**Known gotchas:**
|
|
1444
|
+
- user activation only emits an intent. Until the host applies a new `page`, the numeric input
|
|
1445
|
+
returns to the currently controlled value; assigning the page triggers the localized
|
|
1446
|
+
`role="status"` announcement
|
|
1447
|
+
- the jump input accepts only whole pages in `1..pageCount`; empty, fractional, and out-of-range
|
|
1448
|
+
drafts expose `aria-invalid="true"` and emit nothing
|
|
1449
|
+
- zero items, zero page size, `disabled`, and `loading` all disable the navigation controls. The
|
|
1450
|
+
empty summary is still rendered via the localized `paginationEmptySummary` message
|
|
1451
|
+
(`'{total} {itemLabel}'`, producing `0 items` in the default locale) unless `hide-summary` is set
|
|
1452
|
+
- below a 20rem container allocation the summary and controls stack; the breakpoint responds to
|
|
1453
|
+
the component's own inline size, not the viewport. Previous/next icons also mirror under RTL
|
|
1454
|
+
|
|
1455
|
+
---
|
|
1456
|
+
|
|
1111
1457
|
## `lyra-gauge`
|
|
1112
1458
|
|
|
1113
|
-
Dependency-free SVG radial or linear meter (
|
|
1459
|
+
Dependency-free SVG radial, full-circle ring, or linear meter (no charting library).
|
|
1114
1460
|
|
|
1115
1461
|
**Properties:**
|
|
1116
1462
|
- `value: number = 0`
|
|
1117
1463
|
- `min: number = 0`
|
|
1118
1464
|
- `max: number = 100`
|
|
1119
|
-
- `type: 'radial'|'linear' = 'radial'` (reflected
|
|
1465
|
+
- `type: 'radial'|'ring'|'linear' = 'radial'` (reflected — `radial` is a 270° sweep; `ring` is a
|
|
1466
|
+
full circle that begins at 12 o'clock)
|
|
1120
1467
|
- `label: string = ''`
|
|
1121
|
-
- `valueLabel?: string` (attribute: false — overrides
|
|
1122
|
-
string is treated the same as unset and falls back to the numeric
|
|
1468
|
+
- `valueLabel?: string` (attribute: false — overrides both the visible text and the host's
|
|
1469
|
+
`aria-valuetext`; an empty string is treated the same as unset and falls back to the numeric
|
|
1470
|
+
`value` while removing `aria-valuetext`)
|
|
1123
1471
|
|
|
1124
1472
|
**Events:** none.
|
|
1125
1473
|
|
|
@@ -1127,16 +1475,18 @@ Dependency-free SVG radial or linear meter (270°-sweep arc math, no charting li
|
|
|
1127
1475
|
|
|
1128
1476
|
**CSS parts:** `base` (the `<svg>`), `track`, `fill`, `value`, `label`
|
|
1129
1477
|
|
|
1130
|
-
**Themeable custom properties:** `--lyra-
|
|
1131
|
-
|
|
1478
|
+
**Themeable custom properties:** `--lyra-gauge-fill` (fill stroke, falling back to the shared
|
|
1479
|
+
`--lyra-color-brand` token).
|
|
1132
1480
|
|
|
1133
1481
|
**Optional peer deps:** none.
|
|
1134
1482
|
|
|
1135
1483
|
```html
|
|
1136
1484
|
<lyra-gauge value="72" min="0" max="100" label="CPU"></lyra-gauge>
|
|
1485
|
+
<lyra-gauge type="ring" value="84" label="Coverage"
|
|
1486
|
+
style="--lyra-gauge-fill: var(--lyra-color-success)"></lyra-gauge>
|
|
1137
1487
|
<lyra-gauge type="linear" value="0.4" max="1"></lyra-gauge>
|
|
1138
1488
|
<script type="module">
|
|
1139
|
-
document.querySelector('lyra-gauge').valueLabel = '72°F'; //
|
|
1489
|
+
document.querySelector('lyra-gauge').valueLabel = '72°F'; // visible text and announced value
|
|
1140
1490
|
</script>
|
|
1141
1491
|
```
|
|
1142
1492
|
|
|
@@ -1145,8 +1495,8 @@ gauge-specific custom property exists).
|
|
|
1145
1495
|
changing the visible SVG text), so a screen reader announces your formatted string instead of the
|
|
1146
1496
|
raw `aria-valuenow` number; the SVG `<text part="value">`/`<text part="label">` elements are
|
|
1147
1497
|
`aria-hidden="true"` so they're no longer separately exposed inside the same `role="meter"` host.
|
|
1148
|
-
- no color-threshold/variant
|
|
1149
|
-
|
|
1498
|
+
- no automatic color-threshold/variant logic is built in. Set `--lyra-gauge-fill` per instance (or
|
|
1499
|
+
reactively from application state) when the value should select a success/warning/danger color.
|
|
1150
1500
|
- no documented component-specific sizing custom property; host size is fixed em values
|
|
1151
1501
|
(`8em`/`12em` radial, `12em`/`1.5em` linear) — resize via plain CSS `width`/`height` on the
|
|
1152
1502
|
element instead.
|
|
@@ -1160,8 +1510,8 @@ gauge-specific custom property exists).
|
|
|
1160
1510
|
|
|
1161
1511
|
## `lyra-export-button`
|
|
1162
1512
|
|
|
1163
|
-
CSV/JSON download button — either single-format (click exports
|
|
1164
|
-
opens a small menu).
|
|
1513
|
+
CSV/JSON download button with extensible event-driven formats — either single-format (click exports
|
|
1514
|
+
immediately) or multi-format (click opens a small menu).
|
|
1165
1515
|
|
|
1166
1516
|
**Properties:**
|
|
1167
1517
|
- `rows: Record<string, unknown>[] = []` (attribute: false)
|
|
@@ -1171,21 +1521,27 @@ opens a small menu).
|
|
|
1171
1521
|
of CSV degrading to a header-less/blank file while only JSON had a fallback — so an unconfigured
|
|
1172
1522
|
export still produces a proper header + data file in either format
|
|
1173
1523
|
- `filename: string = 'export'`
|
|
1174
|
-
- `formats:
|
|
1175
|
-
|
|
1524
|
+
- `formats: ExportFormatOption[] = ['csv']` (attribute: false), where `ExportFormatOption` is the
|
|
1525
|
+
built-in `ExportFormat = 'csv' | 'json'` or an `ExportFormatDescriptor = { id: string; label:
|
|
1526
|
+
string; description?: string; extension?: string }`. Descriptor labels/descriptions are
|
|
1527
|
+
consumer-supplied, already-localized copy. Custom ids are event-only; no custom encoder is bundled
|
|
1176
1528
|
- `disabled: boolean = false` (reflected) — also disables every `[part="menu-item"]` button, not just
|
|
1177
1529
|
the trigger
|
|
1530
|
+
- `loading: boolean = false` (reflected) — controlled busy state for an async or server-generated
|
|
1531
|
+
export; sets host/trigger `aria-busy` and disables the trigger and menu items. The component does
|
|
1532
|
+
not toggle it automatically
|
|
1178
1533
|
- `label: string = 'Export'` — trigger button text; also feeds the format-choice menu's `aria-label`
|
|
1179
1534
|
as `` `${label} format` `` so assistive tech gets an accessible name for the menu
|
|
1180
1535
|
- `open: boolean = false` (reflected)
|
|
1181
1536
|
|
|
1182
|
-
**Events:** `lyra-export` (`detail: { format }`, **cancelable** — call `preventDefault()` to
|
|
1537
|
+
**Events:** `lyra-export` (`detail: { format: string }`, **cancelable** — call `preventDefault()` to
|
|
1183
1538
|
substitute your own server-generated download instead of the built-in client-side one),
|
|
1184
|
-
`lyra-export-complete` (`detail: { format }`, fires after a non-cancelled
|
|
1539
|
+
`lyra-export-complete` (`detail: { format: 'csv' | 'json' }`, fires only after a non-cancelled
|
|
1540
|
+
built-in download completes), `lyra-show`, `lyra-hide` (format-menu visibility transitions)
|
|
1185
1541
|
|
|
1186
1542
|
**Slots:** none.
|
|
1187
1543
|
|
|
1188
|
-
**CSS parts:** `trigger`, `menu`, `menu-item`
|
|
1544
|
+
**CSS parts:** `trigger`, `menu`, `menu-item`, `format-label`, `format-description`
|
|
1189
1545
|
|
|
1190
1546
|
**Themeable custom properties:** shared tokens only.
|
|
1191
1547
|
|
|
@@ -1199,6 +1555,19 @@ substitute your own server-generated download instead of the built-in client-sid
|
|
|
1199
1555
|
exp.columns = [{ key: 'name', label: 'Name' }, { key: 'value', label: 'Value' }];
|
|
1200
1556
|
exp.formats = ['csv', 'json']; // shows a format-choice menu instead of exporting immediately
|
|
1201
1557
|
exp.addEventListener('lyra-export', (e) => console.log('exporting', e.detail.format));
|
|
1558
|
+
|
|
1559
|
+
// Custom formats supply menu copy but remain application-handled.
|
|
1560
|
+
exp.formats = [
|
|
1561
|
+
'csv',
|
|
1562
|
+
{ id: 'xlsx', label: 'Excel workbook', description: 'Preserves spreadsheet data types', extension: 'xlsx' },
|
|
1563
|
+
];
|
|
1564
|
+
exp.addEventListener('lyra-export', async (e) => {
|
|
1565
|
+
if (e.detail.format !== 'xlsx') return;
|
|
1566
|
+
e.preventDefault();
|
|
1567
|
+
exp.loading = true;
|
|
1568
|
+
try { await exportWorkbook(exp.rows); }
|
|
1569
|
+
finally { exp.loading = false; }
|
|
1570
|
+
});
|
|
1202
1571
|
</script>
|
|
1203
1572
|
```
|
|
1204
1573
|
|
|
@@ -1211,8 +1580,10 @@ downloadBlob(content: string, filename: string, mime: string): void // trig
|
|
|
1211
1580
|
```
|
|
1212
1581
|
|
|
1213
1582
|
**Known gotchas:**
|
|
1214
|
-
-
|
|
1215
|
-
`
|
|
1583
|
+
- CSV and JSON are the only built-in encoders. To offer XLSX/PDF/etc., pass an
|
|
1584
|
+
`ExportFormatDescriptor` and handle its id from `lyra-export`; custom formats never trigger a
|
|
1585
|
+
download or `lyra-export-complete` on their own. A descriptor's optional `extension` is metadata
|
|
1586
|
+
for that handler, not automatic filename handling.
|
|
1216
1587
|
- CSV formula-injection guarding and the deferred (5s) `URL.revokeObjectURL` (works around Safari
|
|
1217
1588
|
cancelling in-flight downloads on immediate revoke) are genuine, safe-to-rely-on strengths.
|
|
1218
1589
|
- the multi-format menu (`role="menu"`) supports full arrow-key navigation — ArrowUp/ArrowDown move
|
|
@@ -1846,36 +2217,48 @@ same color as `--lyra-heatmap-focus-ring-color`).
|
|
|
1846
2217
|
A force-directed node-link diagram with pan/zoom/drag, built on `d3-force`.
|
|
1847
2218
|
|
|
1848
2219
|
**Properties:**
|
|
1849
|
-
- `nodes: GraphNode[] = []` (attribute: false) — `GraphNode { id: string; label?: string;
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
2220
|
+
- `nodes: GraphNode[] = []` (attribute: false) — `GraphNode { id: string; label?: string;
|
|
2221
|
+
accessibleLabel?: string; description?: string; radius?: number; color?: string }`;
|
|
2222
|
+
`accessibleLabel` supplies richer spoken text than the visible label, while `description` renders
|
|
2223
|
+
as native SVG `<title>` tooltip text. `radius` is clamped to `[6, 24]` (an unset/non-finite value
|
|
2224
|
+
falls back to the midpoint, `15`) so a node can never render invisibly small or absurdly large
|
|
2225
|
+
- `links: GraphLink[] = []` (attribute: false) — `GraphLink { id?: string; source: string; target:
|
|
2226
|
+
string; width?: number; label?: string; accessibleLabel?: string; description?: string; directed?:
|
|
2227
|
+
boolean; color?: string; dash?: number[] }` (source/target are node ids). `directed` adds an
|
|
2228
|
+
arrowhead; `color` and `dash` style the individual stroke; `label` provides a spoken-name and SVG
|
|
2229
|
+
tooltip fallback but is not rendered as visible edge text; `accessibleLabel` and `description`
|
|
2230
|
+
can override the spoken name and tooltip independently. A link whose `source` id doesn't resolve
|
|
2231
|
+
to a real node is still dropped entirely
|
|
2232
|
+
(there's no position to draw a stub from). A link whose `target` id doesn't resolve instead renders
|
|
2233
|
+
as a short, dashed, non-interactive stub off `source`'s own position
|
|
2234
|
+
(`[part='link'][data-dangling]`, `aria-hidden="true"`) rather than being silently dropped — e.g. for
|
|
2235
|
+
a wiki-style `[[link]]` reference to a not-yet-created node. A dangling stub is excluded from
|
|
2236
|
+
`d3-force`'s own simulation input and from click/keyboard interaction.
|
|
1859
2237
|
- `width: number = 800`
|
|
1860
2238
|
- `height: number = 600`
|
|
1861
2239
|
- `chargeStrength: number = -300` (attribute `charge-strength` — live-reactive, see gotchas)
|
|
1862
2240
|
- `linkDistance: number = 100` (attribute `link-distance` — live-reactive, see gotchas)
|
|
1863
2241
|
- `minZoom: number = 0.1` (attribute `min-zoom`)
|
|
1864
2242
|
- `maxZoom: number = 8` (attribute `max-zoom`)
|
|
2243
|
+
- `accessibleLabel: string | null = null` (attribute `aria-label`) — host accessible name forwarded
|
|
2244
|
+
to the internal semantic SVG; when unset, the SVG uses the localized node/link-count summary
|
|
1865
2245
|
- `seed?: number` — when set, seeds each node's initial x/y deterministically
|
|
1866
2246
|
(keyed by node **id**, not array index/order) instead of `forceSimulation()`'s own random start,
|
|
1867
2247
|
and settles the simulation synchronously instead of animating the settle (same effect
|
|
1868
2248
|
`prefers-reduced-motion` has, see gotchas)
|
|
1869
2249
|
|
|
1870
|
-
**Events:** `lyra-node-click` (`detail: { id }`), `lyra-link-click` (`detail: { source, target
|
|
2250
|
+
**Events:** `lyra-node-click` (`detail: { id }`), `lyra-link-click` (`detail: { source, target,
|
|
2251
|
+
id? }`; the optional `id` is the stable `GraphLink.id` supplied by the caller)
|
|
1871
2252
|
|
|
1872
2253
|
**Slots:** none.
|
|
1873
2254
|
|
|
1874
|
-
**CSS parts:** `base`, `svg`, `node`, `link`, `
|
|
2255
|
+
**CSS parts:** `base`, `svg`, `node`, `link`, `arrowhead` (the marker path shared by directed links),
|
|
2256
|
+
`label`, `live-region`, `data-list`, `empty`
|
|
1875
2257
|
|
|
1876
2258
|
**Themeable custom properties:** `--lyra-node-fill` (set inline per-node from `GraphNode.color`,
|
|
1877
|
-
falls back to `--lyra-color-brand`)
|
|
1878
|
-
|
|
2259
|
+
falls back to `--lyra-color-brand`) and `--lyra-link-color` (set inline per-link from
|
|
2260
|
+
`GraphLink.color`, falling back to `--lyra-color-border`); also uses `--lyra-color-text` +
|
|
2261
|
+
`--lyra-font` (label text), `--lyra-focus-ring-*` (node/link `:focus-visible` outline).
|
|
1879
2262
|
|
|
1880
2263
|
**Optional peer deps:** `d3-force`, `d3-drag`, `d3-zoom`, `d3-selection` (all four required
|
|
1881
2264
|
together; lazy-`import()`ed once per page, `console.warn` once and renders empty if missing —
|
|
@@ -1885,9 +2268,17 @@ install with `pnpm add d3-force d3-drag d3-zoom d3-selection`).
|
|
|
1885
2268
|
<lyra-graph style="display:block;height:500px"></lyra-graph>
|
|
1886
2269
|
<script>
|
|
1887
2270
|
const g = document.querySelector('lyra-graph');
|
|
1888
|
-
g.nodes = [
|
|
1889
|
-
|
|
2271
|
+
g.nodes = [
|
|
2272
|
+
{ id: 'a', label: 'A', accessibleLabel: 'Source document A', description: 'The source document' },
|
|
2273
|
+
{ id: 'b', label: 'B', description: 'The cited document' },
|
|
2274
|
+
];
|
|
2275
|
+
g.links = [{
|
|
2276
|
+
id: 'citation-a-b', source: 'a', target: 'b', label: 'cites',
|
|
2277
|
+
accessibleLabel: 'Document A cites document B', description: 'Citation relationship',
|
|
2278
|
+
directed: true, color: 'var(--lyra-color-brand)', dash: [6, 3],
|
|
2279
|
+
}];
|
|
1890
2280
|
g.addEventListener('lyra-node-click', (e) => console.log(e.detail.id));
|
|
2281
|
+
g.addEventListener('lyra-link-click', (e) => console.log(e.detail.id, e.detail.source, e.detail.target));
|
|
1891
2282
|
</script>
|
|
1892
2283
|
```
|
|
1893
2284
|
|
|
@@ -1916,6 +2307,9 @@ install with `pnpm add d3-force d3-drag d3-zoom d3-selection`).
|
|
|
1916
2307
|
- `GraphNode.color` is sanitized (rejects `;`/`{`/`}`) before being written into the
|
|
1917
2308
|
`--lyra-node-fill` inline custom property, so an untrusted color string can't break out of that
|
|
1918
2309
|
CSS declaration.
|
|
2310
|
+
- `GraphLink.color` applies the same declaration-delimiter sanitization. `GraphLink.dash` is used
|
|
2311
|
+
only when every entry is finite and non-negative; an empty or invalid array falls back to a solid
|
|
2312
|
+
line rather than partially applying malformed SVG stroke data.
|
|
1919
2313
|
- a structural `nodes`/`links` change now carries over each already-settled node's position (and any
|
|
1920
2314
|
in-progress drag) by id when rebuilding the simulation, instead of discarding every node's (x, y)
|
|
1921
2315
|
and re-running the whole ~300-tick random-start settle from scratch — only genuinely new ids get a
|
|
@@ -1946,10 +2340,13 @@ deeply-nested node's own shadow root still reaches it).
|
|
|
1946
2340
|
|
|
1947
2341
|
**Properties:**
|
|
1948
2342
|
- `data: TreeItem[] = []` (attribute: false) — `TreeItem { id: string; label: string; children?:
|
|
1949
|
-
TreeItem[]; badge?: string | number
|
|
2343
|
+
TreeItem[]; badge?: string | number; icon?: unknown; description?: string; accessibleLabel?:
|
|
2344
|
+
string }`; `icon` renders as a decorative leading visual, `description` as secondary visible row
|
|
2345
|
+
text, and `accessibleLabel` names the `role="treeitem"` host without changing its visible label
|
|
1950
2346
|
- `label: string = ''` — accessible name for the tree; `role="tree"` lives on an internal
|
|
1951
|
-
`[part="base"]` element
|
|
1952
|
-
`
|
|
2347
|
+
`[part="base"]` element. The component forwards a host `aria-label` to that semantic element when
|
|
2348
|
+
`label` is empty; `label` takes precedence when both are set. External `aria-labelledby` idrefs
|
|
2349
|
+
are not forwarded across the shadow boundary.
|
|
1953
2350
|
|
|
1954
2351
|
**Keyboard:** ArrowDown/ArrowUp move the roving focus to the next/previous *visible* node.
|
|
1955
2352
|
ArrowRight expands a collapsed node (focus stays put; a second ArrowRight then steps into the first
|
|
@@ -1965,7 +2362,7 @@ observed internally to keep the roving `activeId` in sync with clicks).
|
|
|
1965
2362
|
|
|
1966
2363
|
**Slots:** default (holds the `<lyra-tree-node>` elements it manages).
|
|
1967
2364
|
|
|
1968
|
-
**CSS parts:** `base`
|
|
2365
|
+
**CSS parts:** `base`, `empty` (the empty-state message shown when `data` is empty)
|
|
1969
2366
|
|
|
1970
2367
|
**Themeable custom properties:** shared tokens `--lyra-space-xs`/`-s`, `--lyra-color-brand-quiet`,
|
|
1971
2368
|
`--lyra-color-text-quiet`, `--lyra-color-border`, `--lyra-color-text`, `--lyra-radius`,
|
|
@@ -1997,12 +2394,15 @@ descendants of the treeitem, matching the WAI-ARIA treeitem pattern's containmen
|
|
|
1997
2394
|
|
|
1998
2395
|
**Events:** `lyra-node-toggle` (`detail: { id, expanded }`, fired by `expand()`/`collapse()` — via
|
|
1999
2396
|
the toggle button or ArrowRight/ArrowLeft), `lyra-node-select` (`detail: { id }`, fired by `select()`
|
|
2000
|
-
— via clicking the
|
|
2397
|
+
— via clicking anywhere in the row or Enter/Space) — dispatched from `lyra-tree-node`,
|
|
2398
|
+
bubble/compose up
|
|
2001
2399
|
through `lyra-tree`'s light DOM.
|
|
2002
2400
|
|
|
2003
2401
|
**Slots:** none.
|
|
2004
2402
|
|
|
2005
|
-
**CSS parts:** `row`, `toggle`, `label`, `badge`
|
|
2403
|
+
**CSS parts:** `row`, `toggle`, `icon`, `content`, `label`, `description`, `badge`, `group`. `icon` is
|
|
2404
|
+
`aria-hidden="true"`; `content` groups the primary label and optional wrapping secondary
|
|
2405
|
+
description while preserving one interactive treeitem per row.
|
|
2006
2406
|
|
|
2007
2407
|
**Themeable custom properties:** `--lyra-tree-depth` (internal, set inline per row for
|
|
2008
2408
|
indentation), plus the shared tokens listed above.
|
|
@@ -2013,7 +2413,14 @@ indentation), plus the shared tokens listed above.
|
|
|
2013
2413
|
<lyra-tree></lyra-tree>
|
|
2014
2414
|
<script>
|
|
2015
2415
|
document.querySelector('lyra-tree').data = [
|
|
2016
|
-
{
|
|
2416
|
+
{
|
|
2417
|
+
id: '1',
|
|
2418
|
+
label: 'Root',
|
|
2419
|
+
description: 'Two child documents',
|
|
2420
|
+
accessibleLabel: 'Root, two child documents',
|
|
2421
|
+
icon: document.createTextNode('◇'),
|
|
2422
|
+
children: [{ id: '1a', label: 'Child A' }, { id: '1b', label: 'Child B', badge: 3 }],
|
|
2423
|
+
},
|
|
2017
2424
|
];
|
|
2018
2425
|
</script>
|
|
2019
2426
|
```
|
|
@@ -2030,6 +2437,9 @@ indentation), plus the shared tokens listed above.
|
|
|
2030
2437
|
tree's `updateComplete` (e.g. after `focusNode()`) doesn't run before an arbitrarily-nested node has
|
|
2031
2438
|
actually finished rendering its pushed-down `activeId`/`tabIndex` — one more pending update per
|
|
2032
2439
|
depth level, otherwise.
|
|
2440
|
+
- row enrichment is intentionally structured rather than an unrestricted renderer: use `icon`,
|
|
2441
|
+
`label`, `description`, `badge`, and `accessibleLabel`. This keeps the host as the single
|
|
2442
|
+
`role="treeitem"` interaction target and preserves the APG keyboard model.
|
|
2033
2443
|
|
|
2034
2444
|
---
|
|
2035
2445
|
|
|
@@ -2409,6 +2819,10 @@ raw `map` escape hatch for anything unexposed.
|
|
|
2409
2819
|
escaped) when the content is plain text. A marker whose `color` changes for a persisting `id`
|
|
2410
2820
|
can't be recolored in place (no `Marker.setColor()`) and is torn down/reconstructed instead — see
|
|
2411
2821
|
gotchas.
|
|
2822
|
+
- `label: string = ''` — accessible name for the map region, applied as `[part="base"]`'s
|
|
2823
|
+
`aria-label`. A plain `aria-label` attribute on the host itself is honored as a fallback when
|
|
2824
|
+
`label` is left unset, matching `lyra-slider`/`lyra-checkbox`/`lyra-switch`; with neither set, it
|
|
2825
|
+
falls back to the localized `'map'` message.
|
|
2412
2826
|
|
|
2413
2827
|
**Getters:** `map` → the raw `maplibregl.Map` instance.
|
|
2414
2828
|
|
|
@@ -2576,6 +2990,11 @@ hand-building that chrome isn't worth it.
|
|
|
2576
2990
|
header row (creating one, with no heading text, if `heading` is unset), wired to the same
|
|
2577
2991
|
`close()` path Escape/backdrop-dismiss already use, with reason `'close-button'`
|
|
2578
2992
|
|
|
2993
|
+
Also settable as a plain `aria-label` attribute (not a public JS property): overrides the panel's
|
|
2994
|
+
computed accessible name outright, winning over every other source below (a slotted heading,
|
|
2995
|
+
`heading`, `label`) — matching `<lyra-date-input>`'s `accessibleLabel` pattern. Left unset, the
|
|
2996
|
+
existing three-tier fallback below is unchanged.
|
|
2997
|
+
|
|
2579
2998
|
**Methods:** `close(reason: DialogCloseReason = 'api'): void` — closes the dialog, emits
|
|
2580
2999
|
`lyra-dialog-close` with `reason`, and returns focus to whatever had it right before the dialog
|
|
2581
3000
|
opened. `DialogCloseReason = 'escape' | 'backdrop' | 'close-button' | 'api' | 'unmount' | string` —
|
|
@@ -2635,7 +3054,12 @@ clipped; the viewport is still a hard limit either way), plus shared tokens `--l
|
|
|
2635
3054
|
</script>
|
|
2636
3055
|
```
|
|
2637
3056
|
|
|
2638
|
-
Accessible name / visible header, in priority order: (
|
|
3057
|
+
Accessible name / visible header, in priority order: (0) if the host element itself has an
|
|
3058
|
+
`aria-label` attribute set, its value becomes `aria-label` on the panel outright, overriding every
|
|
3059
|
+
source below (including a slotted heading) and suppressing the visible header/`heading` row and the
|
|
3060
|
+
sr-only `label` element from rendering at all — the standard ARIA convention for a consumer that
|
|
3061
|
+
wants full control over the announced name regardless of whatever `heading`/`label` props are also
|
|
3062
|
+
set; (1) otherwise, if a heading element (`h1`–`h6` or
|
|
2639
3063
|
`[role="heading"]`) is a *direct child* (not inside `slot="footer"`), its text content becomes
|
|
2640
3064
|
`aria-label` on the panel — takes priority over `heading` below so an existing consumer that already
|
|
2641
3065
|
slots its own heading keeps rendering it exactly as before; (2) otherwise, when `heading` is set, a
|
|
@@ -2850,8 +3274,11 @@ labeled options, rendered as a button row" is ubiquitous settings/filter-panel U
|
|
|
2850
3274
|
|
|
2851
3275
|
**Properties:**
|
|
2852
3276
|
- `items: SegmentedItem[] = []` (attribute: false) — `SegmentedItem { value: string; label: string;
|
|
2853
|
-
disabled?: boolean }
|
|
3277
|
+
icon?: unknown; disabled?: boolean }`; `icon` renders as a decorative leading visual inside
|
|
3278
|
+
`segment-icon` and does not replace the required text label.
|
|
2854
3279
|
- `value: string = ''` — the currently selected item's `value`.
|
|
3280
|
+
- `label: string = ''` — accessible name copied to the internal `role="radiogroup"`; when empty, a
|
|
3281
|
+
host-level `aria-label` is used as a fallback.
|
|
2855
3282
|
|
|
2856
3283
|
**Events:** `lyra-change` (`detail: { value }`) — fired when the selected value changes via click or
|
|
2857
3284
|
keyboard.
|
|
@@ -2859,7 +3286,7 @@ keyboard.
|
|
|
2859
3286
|
**Slots:** none.
|
|
2860
3287
|
|
|
2861
3288
|
**CSS parts:** `base` (the `role="radiogroup"` root), `segment` (a single `role="radio"` button),
|
|
2862
|
-
`segment-label` (the segment's label text).
|
|
3289
|
+
`segment-icon` (an optional decorative leading icon), `segment-label` (the segment's label text).
|
|
2863
3290
|
|
|
2864
3291
|
**Themeable custom properties:** shared tokens only — `--lyra-color-border`/`-surface`/`-text`/
|
|
2865
3292
|
`-text-quiet`, `--lyra-radius`, `--lyra-font-size-sm`, `--lyra-font-weight-semibold`,
|
|
@@ -2872,8 +3299,8 @@ keyboard.
|
|
|
2872
3299
|
<script type="module">
|
|
2873
3300
|
const seg = document.querySelector('lyra-segmented');
|
|
2874
3301
|
seg.items = [
|
|
2875
|
-
{ value: 'day', label: 'Day' },
|
|
2876
|
-
{ value: 'week', label: 'Week' },
|
|
3302
|
+
{ value: 'day', label: 'Day', icon: '☀' },
|
|
3303
|
+
{ value: 'week', label: 'Week', icon: '▦' },
|
|
2877
3304
|
{ value: 'month', label: 'Month' },
|
|
2878
3305
|
];
|
|
2879
3306
|
seg.value = 'week';
|
|
@@ -2887,6 +3314,8 @@ keyboard.
|
|
|
2887
3314
|
- this component self-selects on navigation: clicking or arrow-navigating to an item immediately
|
|
2888
3315
|
updates `value` and fires `lyra-change` — there's no separate "commit" step the way, e.g.,
|
|
2889
3316
|
`lyra-select`'s popup has.
|
|
3317
|
+
- the semantic `radiogroup` lives inside shadow DOM. Set `label` (preferred for reactive code) or a
|
|
3318
|
+
host `aria-label`; the component deliberately forwards the resulting name to that internal role.
|
|
2890
3319
|
|
|
2891
3320
|
---
|
|
2892
3321
|
|
|
@@ -2960,6 +3389,10 @@ empty string. Restoration updates state, form data, and validity synchronously w
|
|
|
2960
3389
|
A boolean toggle-switch form control. `role="switch"` with `aria-checked` read as an on/off state
|
|
2961
3390
|
rather than checked/unchecked, and no indeterminate state. Structurally the same idea as
|
|
2962
3391
|
`<lyra-checkbox>` (form-associated via `ElementInternals`, click and Space/Enter both toggle).
|
|
3392
|
+
Ships an opt-in `hint`/`errorText` form-control chrome (props + matching named slots + `hint`/`error`
|
|
3393
|
+
CSS parts), mirroring `<lyra-select>`'s pattern for those two pieces — left unset, neither renders.
|
|
3394
|
+
Deliberately no separate top-of-field `label` prop/slot/part: the default slot already is this
|
|
3395
|
+
control's visible, clickable label (same as `<lyra-checkbox>`).
|
|
2963
3396
|
|
|
2964
3397
|
**Properties:**
|
|
2965
3398
|
- `checked: boolean = false` (reflected)
|
|
@@ -2967,17 +3400,24 @@ rather than checked/unchecked, and no indeterminate state. Structurally the same
|
|
|
2967
3400
|
- `required: boolean = false` (reflected — enforced via `internals.setValidity()`)
|
|
2968
3401
|
- `name: string = ''`
|
|
2969
3402
|
- `value: string = 'on'` — only contributed to form submission while `checked`
|
|
3403
|
+
- `hint: string = ''` — hint text below the switch. Unset: no hint chrome renders.
|
|
3404
|
+
- `errorText: string = ''` (attribute `error-text`) — error text below the switch (overridden by
|
|
3405
|
+
slotted `error` content). Unset: no error chrome renders.
|
|
2970
3406
|
|
|
2971
3407
|
**Events:** `lyra-change` (`detail: { checked: boolean }`) — fired on a user toggle (click or
|
|
2972
3408
|
Space/Enter); not fired for a programmatic `.checked` assignment.
|
|
2973
3409
|
|
|
2974
|
-
**Slots:**
|
|
2975
|
-
|
|
2976
|
-
|
|
3410
|
+
**Slots:**
|
|
3411
|
+
- default — label text, rendered next to the track. Clicking it toggles the switch, the same as
|
|
3412
|
+
clicking a checkbox's associated `<label>`. If left empty, set `aria-label` on the host so the
|
|
3413
|
+
control still has an accessible name.
|
|
3414
|
+
- `hint` — custom hint content.
|
|
3415
|
+
- `error` — custom error content.
|
|
2977
3416
|
|
|
2978
|
-
**CSS parts:** `
|
|
2979
|
-
|
|
2980
|
-
default slot)
|
|
3417
|
+
**CSS parts:** `form-control` (the outer wrapper around the switch, error and hint), `base` (the
|
|
3418
|
+
whole interactive control, `role="switch"`), `track` (the pill-shaped background), `thumb` (the
|
|
3419
|
+
circular knob that slides across the track), `label` (wrapper around the default slot), `hint` (the
|
|
3420
|
+
hint message), `error` (the error message)
|
|
2981
3421
|
|
|
2982
3422
|
**Themeable custom properties:** `--lyra-switch-track-inline-size` (default `2.25rem`),
|
|
2983
3423
|
`--lyra-switch-track-block-size` (default `1.25rem`), `--lyra-switch-thumb-offset` (default
|
|
@@ -3346,6 +3786,10 @@ inline size; component-specific, no shared width token exists), plus shared toke
|
|
|
3346
3786
|
`--lyra-color-brand`, `--lyra-color-text-quiet`, `--lyra-color-danger`, `--lyra-color-danger-quiet`,
|
|
3347
3787
|
`--lyra-radius`, `--lyra-icon-button-size`, `--lyra-focus-ring-*`, `--lyra-transition-fast`.
|
|
3348
3788
|
|
|
3789
|
+
`[part=bubble]`'s background resolves through `--lyra-color-surface`. If your own panel/container
|
|
3790
|
+
background already maps to that same token, override `[part=bubble]`'s background explicitly (e.g.
|
|
3791
|
+
via `::part(bubble)`) so message bubbles stay visually distinct from the surrounding panel.
|
|
3792
|
+
|
|
3349
3793
|
**Optional peer deps:** none. Internally renders a `<lyra-live-region>` (a first-party sibling
|
|
3350
3794
|
component, auto-imported alongside this one, not an npm peer) for the status-transition
|
|
3351
3795
|
announcements described below.
|
|
@@ -3418,10 +3862,11 @@ variant), `cursor` (the blinking bar in the `cursor` variant)
|
|
|
3418
3862
|
**Themeable custom properties:** `--lyra-typing-dot-size` (default `0.5rem`, `0.375rem` at
|
|
3419
3863
|
`size="sm"`), `--lyra-typing-gap` (default `0.25rem`, `0.1875rem` at `size="sm"`),
|
|
3420
3864
|
`--lyra-typing-cursor-width` (default `0.125rem`, `0.09375rem` at `size="sm"`),
|
|
3421
|
-
`--lyra-typing-cursor-height` (default `1em`, unaffected by `size`)
|
|
3422
|
-
|
|
3423
|
-
(
|
|
3424
|
-
|
|
3865
|
+
`--lyra-typing-cursor-height` (default `1em`, unaffected by `size`),
|
|
3866
|
+
`--lyra-typing-dot-stagger-1` (default `600ms`, second dot), and
|
|
3867
|
+
`--lyra-typing-dot-stagger-2` (default `1200ms`, third dot). Every variant uses the shared
|
|
3868
|
+
`--lyra-transition-ambient` compound duration/timing token (default `1.8s ease-in-out`) as its
|
|
3869
|
+
animation cycle.
|
|
3425
3870
|
|
|
3426
3871
|
**Optional peer deps:** none.
|
|
3427
3872
|
|
|
@@ -3429,6 +3874,9 @@ discrete state flip (which would instead use `--lyra-transition-fast`).
|
|
|
3429
3874
|
<lyra-typing-indicator label="Assistant is responding…"></lyra-typing-indicator>
|
|
3430
3875
|
<lyra-typing-indicator variant="pulse" size="sm"></lyra-typing-indicator>
|
|
3431
3876
|
<lyra-typing-indicator variant="cursor"></lyra-typing-indicator>
|
|
3877
|
+
<lyra-typing-indicator
|
|
3878
|
+
style="--lyra-transition-ambient: 900ms ease-in-out; --lyra-typing-dot-stagger-1: 300ms; --lyra-typing-dot-stagger-2: 600ms"
|
|
3879
|
+
></lyra-typing-indicator>
|
|
3432
3880
|
```
|
|
3433
3881
|
|
|
3434
3882
|
Accessibility: since this indicator typically mounts and unmounts around a real generation lifecycle
|
|
@@ -3446,11 +3894,9 @@ decorative; `label` is the entire accessible content, nothing narrates individua
|
|
|
3446
3894
|
state (`opacity: 1`, no transform, `animation: none !important`) rather than freezing on whatever
|
|
3447
3895
|
frame the animation happened to be on — notably relevant for `cursor`, which would otherwise risk
|
|
3448
3896
|
freezing on its invisible ("off") blink half.
|
|
3449
|
-
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
arithmetically; the two delays just approximate a third and two-thirds of the token's own default
|
|
3453
|
-
duration.
|
|
3897
|
+
- `--lyra-transition-ambient` is a compound `duration timing-function` value and cannot be divided
|
|
3898
|
+
with `calc()`. When retiming it, override both stagger properties alongside it to preserve the
|
|
3899
|
+
default one-third/two-thirds dot phasing, as shown above.
|
|
3454
3900
|
- `size="sm"` shrinks the dot size, gap, and cursor width, but **not** `--lyra-typing-cursor-height`
|
|
3455
3901
|
(still `1em` at any size) — the cursor bar's height is meant to track surrounding text size via
|
|
3456
3902
|
`1em`, not the component's own `size` property.
|
|
@@ -3775,7 +4221,9 @@ state, so no additional scroll-lock/focus-trap bookkeeping is needed for that tr
|
|
|
3775
4221
|
## `lyra-chat-composer`
|
|
3776
4222
|
|
|
3777
4223
|
The message input for a chat/agent conversation surface: an auto-resizing `<textarea>` plus a
|
|
3778
|
-
built-in send/stop button.
|
|
4224
|
+
built-in send/stop button. Deliberately no label/hint/error chrome — a composite chat-input
|
|
4225
|
+
control, not a labeled form field; wrap it in your own layout for that context. **Form-associated**
|
|
4226
|
+
via the shared `FormAssociated` mixin (same shape as
|
|
3779
4227
|
`<lyra-date-input>`) — `name: string = ''`, `value: string = ''`, `disabled: boolean = false`
|
|
3780
4228
|
(reflected), `required: boolean = false` (reflected) are all inherited, along with
|
|
3781
4229
|
`checkValidity()`/`reportValidity()`, so it participates in native `<form>` submission/validation/
|
|
@@ -3794,6 +4242,12 @@ reveals the invalid state, and `form.reset()` clears the touched presentation.
|
|
|
3794
4242
|
built-in button's icon/label (send vs. stop) and whether Enter still submits
|
|
3795
4243
|
- `submitOnEnter: boolean = true` (reflected, attribute `submit-on-enter`) — when `false`, Enter
|
|
3796
4244
|
always inserts a newline instead of submitting
|
|
4245
|
+
- `spellcheck: boolean = true` — forwarded to the internal `<textarea>`
|
|
4246
|
+
- `autocapitalize: string = ''` — forwarded to the internal `<textarea>`; empty omits the attribute
|
|
4247
|
+
- `autoCorrect: string = ''` (attribute `autocorrect`) — forwarded to the internal `<textarea>`
|
|
4248
|
+
(Safari/WebKit-specific); empty omits the attribute. Named `autoCorrect`, not `autocorrect`, only
|
|
4249
|
+
to dodge a `lib.dom.d.ts` collision with `HTMLElement`'s own `boolean`-typed `autocorrect` IDL
|
|
4250
|
+
member; the host attribute is explicitly mapped to plain `autocorrect`.
|
|
3797
4251
|
|
|
3798
4252
|
**Methods (own):** none beyond the inherited `checkValidity()`/`reportValidity()`.
|
|
3799
4253
|
|
|
@@ -3805,6 +4259,10 @@ reveals the invalid state, and `form.reset()` clears the touched presentation.
|
|
|
3805
4259
|
trimming is left to the consumer. Submitting does **not** clear `value`
|
|
3806
4260
|
- `lyra-stop` (no detail) — fired by the built-in button while `status` is `"sending"` or
|
|
3807
4261
|
`"streaming"`
|
|
4262
|
+
- `blur` (no detail) — re-dispatched from the internal `<textarea>`'s own `blur`, bubbling and
|
|
4263
|
+
composed unlike the native event
|
|
4264
|
+
- `focus` (no detail) — re-dispatched from the internal `<textarea>`'s own `focus`, for the same
|
|
4265
|
+
reason as `blur`
|
|
3808
4266
|
|
|
3809
4267
|
**Slots:** `leading` (content before the textarea, e.g. an attach-file trigger button), `chips` (an
|
|
3810
4268
|
attachment tray rendered above the input row), `trailing` (overrides the built-in send/stop button
|
|
@@ -4295,6 +4753,12 @@ First-party invention (no Web Awesome equivalent).
|
|
|
4295
4753
|
rename button never renders and the row can never enter its editing state; flipping it to `false`
|
|
4296
4754
|
while a rename is already in progress cancels that edit (discards the draft, like Escape) rather
|
|
4297
4755
|
than leaving it stranded and still committable.
|
|
4756
|
+
- `spellcheck: boolean = true` — forwarded to the in-place rename `<input>`; `spellcheck="false"` is
|
|
4757
|
+
parsed as false (not Lit's default boolean-attribute behavior)
|
|
4758
|
+
- `autocapitalize: string = ''` — forwarded to the in-place rename `<input>`; empty omits the attribute
|
|
4759
|
+
- `autoCorrect: string = ''` (attribute `autocorrect`) — forwarded to the in-place rename `<input>`
|
|
4760
|
+
(Safari/WebKit-specific); empty omits the attribute. Named `autoCorrect` to avoid
|
|
4761
|
+
`HTMLElement.autocorrect`'s incompatible DOM typing.
|
|
4298
4762
|
|
|
4299
4763
|
**Events:** `lyra-select` (no detail payload — identify the row via the platform `id` attribute on the
|
|
4300
4764
|
event's `target`/`currentTarget`, the same convention `<lyra-attachment-chip>` uses; fires on a click on
|
|
@@ -4302,7 +4766,9 @@ event's `target`/`currentTarget`, the same convention `<lyra-attachment-chip>` u
|
|
|
4302
4766
|
while not currently renaming), `lyra-rename` (`detail: { title: string }` — an in-place rename was
|
|
4303
4767
|
committed via Enter or blur-while-editing; does not mutate `title` itself, this is a controlled
|
|
4304
4768
|
component — not fired when the trimmed draft is empty or unchanged from the original `title`, treated
|
|
4305
|
-
as an implicit cancel)
|
|
4769
|
+
as an implicit cancel), `blur` (no detail — re-dispatched from the in-place rename `<input>`'s own
|
|
4770
|
+
`blur`, bubbling and composed unlike the native event), `focus` (no detail — re-dispatched from the
|
|
4771
|
+
in-place rename `<input>`'s own `focus`, for the same reason as `blur`)
|
|
4306
4772
|
|
|
4307
4773
|
**Slots:** `actions` — overflow/icon-button controls rendered at the trailing edge of the row (e.g. a
|
|
4308
4774
|
pin/delete control); only visually shown once it actually has assigned elements.
|
|
@@ -4385,7 +4851,20 @@ emitting `lyra-change`.
|
|
|
4385
4851
|
id, and once non-empty it takes over as the accessible-name source (an `aria-label` override is
|
|
4386
4852
|
then only consulted as the fallback). Empty (the default) keeps the original
|
|
4387
4853
|
`aria-label || placeholder || 'Model'` accessible-name chain untouched.
|
|
4854
|
+
- `hint: string = ''` — hint text below the field. Unset (the default): no hint chrome renders.
|
|
4855
|
+
- `errorText: string = ''` (attribute `error-text`) — error text below the field (overridden by
|
|
4856
|
+
slotted `error` content). Unset (the default): no error chrome renders.
|
|
4388
4857
|
- `placeholder: string = ''`
|
|
4858
|
+
- `spellcheck: boolean = true` — forwarded to the free-text mode's native `<input>`; no effect in
|
|
4859
|
+
closed-dropdown mode (no native text input there). `spellcheck="false"` is parsed as `false` (a
|
|
4860
|
+
custom converter, not Lit's presence-based `type: Boolean`, so the literal attribute string is
|
|
4861
|
+
honored — matches `<lyra-textarea>`/`<lyra-date-input>`).
|
|
4862
|
+
- `autocapitalize: string = ''` — forwarded to the free-text mode's native `<input>`; empty omits
|
|
4863
|
+
the attribute.
|
|
4864
|
+
- `autoCorrect: string = ''` (attribute `autocorrect`) — forwarded to the free-text mode's native
|
|
4865
|
+
`<input>`'s own `autocorrect` (Safari/WebKit-specific); empty omits the attribute. Named
|
|
4866
|
+
`autoCorrect` in JS purely to dodge a `lib.dom.d.ts` typing collision — the wire attribute is
|
|
4867
|
+
still plain `autocorrect`.
|
|
4389
4868
|
- `name: string = ''` (reflected)
|
|
4390
4869
|
- `disabled: boolean = false` (reflected)
|
|
4391
4870
|
- `required: boolean = false` (reflected — enforced via `internals.setValidity()`)
|
|
@@ -4408,12 +4887,18 @@ since changed) is never silently dropped: it's appended to the rendered option l
|
|
|
4408
4887
|
visually-distinct row (dashed border, italic label, "not in catalog" badge) computed fresh from
|
|
4409
4888
|
`catalog` + `value` on every access, without ever mutating the `catalog` property itself.
|
|
4410
4889
|
|
|
4411
|
-
**Events:**
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4890
|
+
**Events:**
|
|
4891
|
+
- `lyra-change` (`detail: { value: string; inCatalog: boolean }` — fired when a value is selected
|
|
4892
|
+
from the listbox or committed in free-text mode; `inCatalog` reflects whether that value was
|
|
4893
|
+
actually present in `normalizedCatalog`, so a consumer can flag a freshly-typed custom value
|
|
4894
|
+
distinctly from a real catalog pick)
|
|
4895
|
+
- `blur` (no detail) — re-dispatched from the free-text mode's internal `<input>`'s own `blur`,
|
|
4896
|
+
bubbling and composed unlike the native event. Closed-dropdown mode's trigger `<button>` has no
|
|
4897
|
+
equivalent re-dispatch, matching `<lyra-select>`'s own trigger.
|
|
4898
|
+
- `focus` (no detail) — re-dispatched from the free-text mode's internal `<input>`'s own `focus`,
|
|
4899
|
+
for the same reason as `blur`.
|
|
4900
|
+
|
|
4901
|
+
**Slots:** `hint` (custom hint content), `error` (custom error content).
|
|
4417
4902
|
|
|
4418
4903
|
**CSS parts:** `form-control-label` (the `<label>` element — only rendered, and only contributes to
|
|
4419
4904
|
the accessible name, once `label` is non-empty), `trigger` (closed-dropdown mode's
|
|
@@ -4421,7 +4906,8 @@ the accessible name, once `label` is non-empty), `trigger` (closed-dropdown mode
|
|
|
4421
4906
|
container, also its positioning anchor), `combobox-input` (the free-text `<input>`),
|
|
4422
4907
|
`provider-badge` (the optional leading `provider` label), `listbox` (the options popover, shared by
|
|
4423
4908
|
both modes), `option`, `option-label`, `option-badge` (the "not in catalog" badge on a synthetic
|
|
4424
|
-
stale-value row), `expand-icon` (the dropdown chevron, present in both modes)
|
|
4909
|
+
stale-value row), `expand-icon` (the dropdown chevron, present in both modes), `hint` (the hint
|
|
4910
|
+
message), `error` (the error message)
|
|
4425
4911
|
|
|
4426
4912
|
**Themeable custom properties:** shared tokens only — `--lyra-space-xs/-s`,
|
|
4427
4913
|
`--lyra-color-border/-surface/-brand/-brand-quiet/-text-quiet`, `--lyra-radius`, `--lyra-shadow`,
|
|
@@ -4458,6 +4944,9 @@ stale-value row), `expand-icon` (the dropdown chevron, present in both modes)
|
|
|
4458
4944
|
- In free-text mode, the input's displayed text is `query` only while `open`; while closed it shows the
|
|
4459
4945
|
committed value's label — so setting `.value` programmatically doesn't require also touching the live
|
|
4460
4946
|
typed text.
|
|
4947
|
+
- `hint`/`errorText` mirror `<lyra-select>`'s identical chrome, including the `aria-describedby` wiring
|
|
4948
|
+
to the rendered `hint`/`error` ids — set on whichever element (`trigger` or `combobox-input`) owns
|
|
4949
|
+
`role="combobox"` for the active mode.
|
|
4461
4950
|
|
|
4462
4951
|
---
|
|
4463
4952
|
|
|
@@ -4897,7 +5386,8 @@ accessor itself, which still takes full priority.
|
|
|
4897
5386
|
no overlay chrome renders until `mode` is `'mobile'` again. Set this directly, or use the built-in
|
|
4898
5387
|
toggle button — there is no separate `show()`/`hide()` pair.
|
|
4899
5388
|
- `label: string = 'Navigation'` — accessible name for the rail's navigation landmark, and for its
|
|
4900
|
-
dialog role while the mobile overlay is open.
|
|
5389
|
+
dialog role while the mobile overlay is open. A host-level `aria-label` attribute (see below)
|
|
5390
|
+
takes precedence over this when both are set.
|
|
4901
5391
|
- `preferredMode?: 'full' | 'icon-only' | null` (attribute `preferred-mode`) — manually prefers
|
|
4902
5392
|
`'full'` or `'icon-only'` for the non-mobile breakpoint axis, while `mobile-breakpoint` continues to
|
|
4903
5393
|
be tracked automatically regardless — e.g. a user's manual collapse toggle that should still yield
|
|
@@ -4926,6 +5416,10 @@ accessor itself, which still takes full priority.
|
|
|
4926
5416
|
"chases" the pointer instead of tracking it 1:1. Effectively read-only (this component owns the
|
|
4927
5417
|
transitions), but a plain reflected property like every other boolean here.
|
|
4928
5418
|
|
|
5419
|
+
Also settable as a plain `aria-label` attribute (not a reactive property): overrides the computed
|
|
5420
|
+
`label`/localized-default accessible name on both the navigation landmark and the mobile dialog
|
|
5421
|
+
role, matching `<lyra-date-input>`'s `accessibleLabel`.
|
|
5422
|
+
|
|
4929
5423
|
**Events:** `lyra-mode-change` (`detail: AppRailModeChangeDetail` = `{ mode: AppRailMode }`; the
|
|
4930
5424
|
effective mode changed, whether from a breakpoint crossing or an explicit `mode` assignment — not
|
|
4931
5425
|
fired for a redundant reassignment to the mode already in effect), `lyra-toggle`
|
|
@@ -5177,7 +5671,10 @@ own listbox.
|
|
|
5177
5671
|
- `filter: MentionFilter | null = null` (attribute: false) — overrides the built-in
|
|
5178
5672
|
case-insensitive `label`/`description` substring match entirely.
|
|
5179
5673
|
- `emptyText: string = 'No matches'` (attribute `empty-text`)
|
|
5180
|
-
- `label: string = 'Suggestions'` — accessible name for the `role="listbox"` popup.
|
|
5674
|
+
- `label: string = 'Suggestions'` — accessible name for the `role="listbox"` popup. A host-level
|
|
5675
|
+
plain `aria-label` attribute on `<lyra-mention-popover>` itself takes priority over this property
|
|
5676
|
+
when present (checked via a plain `getAttribute()` read, not a reactive property) — matches the
|
|
5677
|
+
same fallback on `<lyra-combobox>`/`<lyra-table>`.
|
|
5181
5678
|
- `filteredItems: MentionItem[]` — read-only getter; `items` filtered by `query` via `filter` (or
|
|
5182
5679
|
the built-in default). Empty `query` returns `items` unfiltered.
|
|
5183
5680
|
- `activeDescendantId: string | null` — read-only getter; the `id` of the currently-highlighted
|
|
@@ -5260,6 +5757,9 @@ automatically only on an `anchor` or `query` change while open (a keystroke move
|
|
|
5260
5757
|
fresh `query` is the proxy for "the caret may have moved").
|
|
5261
5758
|
|
|
5262
5759
|
**Known gotchas:**
|
|
5760
|
+
- a host-level `aria-label` attribute on `<lyra-mention-popover>` now takes priority over `label`
|
|
5761
|
+
(and its localized default) when resolving `[part="listbox"]`'s accessible name — previously it
|
|
5762
|
+
was silently ignored. Matches the same fallback on `<lyra-combobox>`/`<lyra-table>`.
|
|
5263
5763
|
- The popover opens pre-highlighted on the top match (index 0), unlike `<lyra-combobox>`'s own
|
|
5264
5764
|
listbox which opens with nothing highlighted (`-1`) — a bare Enter right after opening commits
|
|
5265
5765
|
immediately.
|
|
@@ -5880,6 +6380,12 @@ shared composed-tree focus traversal used by the other modal families.
|
|
|
5880
6380
|
disconnect/reconnect fire back-to-back with no update in between.
|
|
5881
6381
|
- the Approve button's native `disabled` attribute (while the draft is invalid JSON) automatically
|
|
5882
6382
|
excludes it from the shared Tab trap, whose focusable-set computation skips disabled controls.
|
|
6383
|
+
- the raw-JSON `args-editor` textarea always hardcodes `spellcheck="false"`, `autocapitalize="off"`,
|
|
6384
|
+
and `autocorrect="off"` — not exposed as configurable properties, unlike `<lyra-textarea>`'s/
|
|
6385
|
+
`<lyra-chat-composer>`'s passthrough props — since its content is always JSON, never prose; without
|
|
6386
|
+
this a mobile browser (notably iOS Safari, which defaults textarea `autocapitalize` to
|
|
6387
|
+
`'sentences'`) could auto-capitalize or auto-correct key/value text as the user edits, silently
|
|
6388
|
+
corrupting the JSON.
|
|
5883
6389
|
|
|
5884
6390
|
---
|
|
5885
6391
|
|
|
@@ -6039,7 +6545,10 @@ menu, an avatar menu, or a history row's overflow menu. Uses the WAI-ARIA "menu
|
|
|
6039
6545
|
side is mirrored under `dir="rtl"`, so e.g. `placement="left-start"` still anchors to the menu's
|
|
6040
6546
|
trailing edge instead of pinning to the physical left)
|
|
6041
6547
|
- `label: string = 'Menu'` — accessible name for the `role="menu"` popup; override with something
|
|
6042
|
-
specific (e.g. "Row actions") when a page has more than one menu
|
|
6548
|
+
specific (e.g. "Row actions") when a page has more than one menu. A host-level `aria-label`
|
|
6549
|
+
attribute takes precedence over both this prop and the localized default (unset by default, so
|
|
6550
|
+
a no-op for existing consumers), matching `lyra-select`/`lyra-model-select`'s
|
|
6551
|
+
`this.getAttribute('aria-label') || <computed default>` precedence
|
|
6043
6552
|
|
|
6044
6553
|
**Events:** `lyra-show` (no detail — fires only when `open` transitions to `true`, not for markup
|
|
6045
6554
|
that renders `open` true from the start), `lyra-hide` (same first-render guard, opposite
|
|
@@ -6175,7 +6684,8 @@ already follow.
|
|
|
6175
6684
|
- `removable: boolean = false` (reflected — shows the remove (×) button)
|
|
6176
6685
|
- `selected: boolean = false` (reflected) — opt-in toggle/pressed mode: when set, `[part='base']`
|
|
6177
6686
|
itself becomes focusable and keyboard-activatable (Enter/Space, mirroring native `<button>`
|
|
6178
|
-
behavior), reflects `aria-pressed
|
|
6687
|
+
behavior), reflects `aria-pressed` (explicitly `"false"`, not omitted, whenever toggle mode is
|
|
6688
|
+
active but unpressed), and toggles on click/activation, emitting `lyra-chip-select`.
|
|
6179
6689
|
Has no effect (no interactive semantics added to `[part='base']`) when combined with `removable`,
|
|
6180
6690
|
since the remove button already nests inside `[part='base']` — a focusable descendant of a
|
|
6181
6691
|
`role="button"` ancestor isn't allowed there, and this component's two real use cases (a
|
|
@@ -6202,13 +6712,26 @@ affordance, only rendered while `removable`)
|
|
|
6202
6712
|
(component-local trio swapped per `tone` rather than repeating background/color/border per part per
|
|
6203
6713
|
tone; default `var(--lyra-color-text)` / `var(--lyra-color-surface)` / `var(--lyra-color-border)` —
|
|
6204
6714
|
mirrors the same accent/bg/border vocabulary `<lyra-tool-call-chip>`/`<lyra-attachment-chip>` use),
|
|
6205
|
-
|
|
6206
|
-
`--lyra-
|
|
6207
|
-
`--lyra-
|
|
6208
|
-
`--lyra-
|
|
6715
|
+
`--lyra-chip-pressed-border` (border color while pressed/selected — falls back to
|
|
6716
|
+
`--lyra-chip-accent`), `--lyra-chip-pressed-bg` (background color while pressed/selected — falls
|
|
6717
|
+
back to `--lyra-chip-bg`), plus shared tokens (`--lyra-space-xs`, `--lyra-space-s`,
|
|
6718
|
+
`--lyra-color-brand`/`-brand-quiet`, `--lyra-color-success`/`-success-quiet`,
|
|
6719
|
+
`--lyra-color-warning`/`-warning-quiet`, `--lyra-color-danger`/`-danger-quiet`,
|
|
6720
|
+
`--lyra-icon-button-size`, `--lyra-focus-ring-width`, `--lyra-focus-ring-color`,
|
|
6721
|
+
`--lyra-focus-ring-offset`, `--lyra-transition-fast`).
|
|
6209
6722
|
|
|
6210
6723
|
**Optional peer deps:** none.
|
|
6211
6724
|
|
|
6725
|
+
```html
|
|
6726
|
+
<lyra-chip
|
|
6727
|
+
toggleable
|
|
6728
|
+
selected
|
|
6729
|
+
style="--lyra-chip-bg: var(--lyra-color-surface); --lyra-chip-pressed-bg: var(--lyra-color-warning-quiet)"
|
|
6730
|
+
>
|
|
6731
|
+
Priority filter
|
|
6732
|
+
</lyra-chip>
|
|
6733
|
+
```
|
|
6734
|
+
|
|
6212
6735
|
### `lyra-chip-group`
|
|
6213
6736
|
|
|
6214
6737
|
A flex-wrap container for a set of `<lyra-chip>` children — plain light-DOM composition, direct
|