@aceshooting/lyra-ui 17.0.0 → 18.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/CHANGELOG.md +483 -0
  2. package/README.md +2 -2
  3. package/custom-elements.json +1 -1
  4. package/design-tokens.json +1 -1
  5. package/dist/cli/migration-contract.json +1 -1
  6. package/dist/components/conversation/message-actions/message-actions.class.d.ts +2 -1
  7. package/dist/components/conversation/streaming-text/streaming-text-core.class.d.ts +22 -0
  8. package/dist/components/conversation/streaming-text/streaming-text-core.class.js +1 -0
  9. package/dist/components/conversation/streaming-text/streaming-text.class.d.ts +22 -0
  10. package/dist/components/conversation/streaming-text/streaming-text.class.js +1 -0
  11. package/dist/components/conversation/thread-list/thread-list.class.js +1 -1
  12. package/dist/components/data/table/table.styles.js +1 -1
  13. package/dist/components/forms/combobox/combobox.class.d.ts +12 -2
  14. package/dist/components/forms/combobox/combobox.class.js +2 -2
  15. package/dist/components/forms/combobox/combobox.styles.js +1 -1
  16. package/dist/components/forms/icon-button/icon-button.class.d.ts +18 -9
  17. package/dist/components/forms/select/select.class.d.ts +63 -8
  18. package/dist/components/forms/select/select.class.js +4 -4
  19. package/dist/components/forms/select/select.styles.js +1 -1
  20. package/dist/components/layout/filter-bar/filter-bar.class.d.ts +148 -14
  21. package/dist/components/layout/filter-bar/filter-bar.class.js +12 -4
  22. package/dist/components/layout/filter-bar/filter-bar.styles.js +1 -1
  23. package/dist/components/layout/reorder-list/reorder-list.class.js +1 -1
  24. package/dist/components/layout/virtual-list/virtual-list.class.d.ts +154 -18
  25. package/dist/components/layout/virtual-list/virtual-list.class.js +12 -7
  26. package/dist/components/media/map/map.class.d.ts +269 -14
  27. package/dist/components/media/map/map.class.js +62 -30
  28. package/dist/components/media/map/map.styles.js +1 -1
  29. package/dist/components/utility/copy-button/copy-button.class.d.ts +4 -3
  30. package/dist/custom-elements-jsx.d.ts +1 -1
  31. package/dist/events.d.ts +13 -1
  32. package/dist/internal/package-metadata.d.ts +1 -1
  33. package/dist/internal/package-metadata.js +1 -1
  34. package/dist/internal/tokens.styles.js +1 -1
  35. package/dist/lyra.d.ts +1 -1
  36. package/dist/lyra.js +1 -1
  37. package/dist/styles/tokens-root.css +1 -1
  38. package/dist/svelte.d.ts +1 -1
  39. package/dist/testing/lyra-tag-event-map.js +1 -1
  40. package/dist/translations/ar/retrieval.js +1 -1
  41. package/dist/translations/ar/shared.js +1 -1
  42. package/dist/translations/de/retrieval.js +1 -1
  43. package/dist/translations/de/shared.js +1 -1
  44. package/dist/translations/es/retrieval.js +1 -1
  45. package/dist/translations/es/shared.js +1 -1
  46. package/dist/translations/fa/retrieval.js +1 -1
  47. package/dist/translations/fa/shared.js +1 -1
  48. package/dist/translations/fr/retrieval.js +1 -1
  49. package/dist/translations/fr/shared.js +1 -1
  50. package/dist/translations/he/retrieval.js +1 -1
  51. package/dist/translations/he/shared.js +1 -1
  52. package/dist/translations/it/retrieval.js +1 -1
  53. package/dist/translations/it/shared.js +1 -1
  54. package/dist/translations/ja/retrieval.js +1 -1
  55. package/dist/translations/ja/shared.js +1 -1
  56. package/dist/translations/pt-BR/retrieval.js +1 -1
  57. package/dist/translations/pt-BR/shared.js +1 -1
  58. package/dist/translations/ro/agent-tools.d.ts +1 -0
  59. package/dist/translations/ro/agent-tools.js +1 -0
  60. package/dist/translations/ro/charts.d.ts +1 -0
  61. package/dist/translations/ro/charts.js +1 -0
  62. package/dist/translations/ro/conversation.d.ts +1 -0
  63. package/dist/translations/ro/conversation.js +1 -0
  64. package/dist/translations/ro/data.d.ts +1 -0
  65. package/dist/translations/ro/data.js +1 -0
  66. package/dist/translations/ro/forms.d.ts +1 -0
  67. package/dist/translations/ro/forms.js +1 -0
  68. package/dist/translations/ro/layout.d.ts +1 -0
  69. package/dist/translations/ro/layout.js +1 -0
  70. package/dist/translations/ro/media.d.ts +1 -0
  71. package/dist/translations/ro/media.js +1 -0
  72. package/dist/translations/ro/overlays.d.ts +1 -0
  73. package/dist/translations/ro/overlays.js +1 -0
  74. package/dist/translations/ro/retrieval.d.ts +1 -0
  75. package/dist/translations/ro/retrieval.js +1 -0
  76. package/dist/translations/ro/shared.d.ts +1 -0
  77. package/dist/translations/ro/shared.js +1 -0
  78. package/dist/translations/ro/utility.d.ts +1 -0
  79. package/dist/translations/ro/utility.js +1 -0
  80. package/dist/translations/ro/viewers.d.ts +1 -0
  81. package/dist/translations/ro/viewers.js +5 -0
  82. package/dist/translations/ro.d.ts +1 -0
  83. package/dist/translations/ro.js +1 -0
  84. package/dist/translations/ru/retrieval.js +1 -1
  85. package/dist/translations/ru/shared.js +1 -1
  86. package/dist/translations/zh-CN/retrieval.js +1 -1
  87. package/dist/translations/zh-CN/shared.js +1 -1
  88. package/dist/vue.d.ts +1 -1
  89. package/llms/components/lr-button.md +5 -4
  90. package/llms/components/lr-card.md +2 -1
  91. package/llms/components/lr-combobox.md +11 -0
  92. package/llms/components/lr-filter-bar.md +123 -7
  93. package/llms/components/lr-icon-button.md +17 -8
  94. package/llms/components/lr-map.md +127 -8
  95. package/llms/components/lr-option.md +11 -0
  96. package/llms/components/lr-select.md +45 -3
  97. package/llms/components/lr-streaming-text-core.md +7 -3
  98. package/llms/components/lr-streaming-text.md +7 -2
  99. package/llms/components/lr-virtual-list.md +53 -0
  100. package/llms/shared.md +47 -3
  101. package/llms/tokens.md +7 -4
  102. package/llms-full.txt +465 -36
  103. package/package.json +28 -2
  104. package/registrations.json +1 -1
  105. package/vscode-css-data.json +1 -1
  106. package/vscode-html-data.json +1 -1
  107. package/web-types.json +1 -1
@@ -9,7 +9,7 @@
9
9
  - **Release history** [CHANGELOG.md](../../CHANGELOG.md); family-wide breaking-change summaries: [llms-full.txt](../../llms-full.txt)
10
10
  - **Deprecations** none
11
11
  - **Optional peers** `dompurify`, `katex`, `marked`, `shiki` — see `llms/peers.md`
12
- - **Themeable via** 2 parts, 2 custom properties — see this component's own `@csspart`/`@cssprop` list below
12
+ - **Themeable via** 13 parts, 2 custom properties — see this component's own `@csspart`/`@cssprop` list below
13
13
  - **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`
14
14
 
15
15
  ---
@@ -83,7 +83,12 @@ never see that update happen. See `<lr-thinking-panel>`'s own reference at `llms
83
83
 
84
84
  **Slots:** none — content renders from `content`, not a slot.
85
85
 
86
- **CSS parts:** `base`, `cursor` (only rendered while `streaming` is `true`)
86
+ **CSS parts:** `base`, `cursor` (only rendered while `streaming` is `true`), plus every part
87
+ `<lr-markdown>` documents forwarded verbatim (no aliasing — none collides with `base`/`cursor`)
88
+ from the composed `<lr-markdown>` in Markdown mode via `exportparts`: `content`, `heading`,
89
+ `paragraph`, `list`, `code-block`, `inline-code`, `link`, `table`, `blockquote`, `img`, `math`. A
90
+ host-level `lr-streaming-text::part(link)`/`::part(img)` rule reaches the rendered `<a>`/`<img>`
91
+ exactly as the same rule does applied directly to `<lr-markdown>`.
87
92
 
88
93
  **Themeable custom properties:** `--lr-inline-cursor-width` (default
89
94
  `var(--lr-size-0-125rem)`, the shared inline cursor width), `--lr-inline-cursor-height` (default
@@ -101,6 +101,17 @@ list's `base` scroll container exposes horizontal scrolling for that explicit op
101
101
  number `56` and fixes every row to that many pixels. Property callers assign a number, not a
102
102
  numeric string. Anything else (non-numeric, zero, negative, non-finite) safely canonicalizes to
103
103
  `'auto'` rather than throwing.
104
+ - `rowProjection: 'shadow' | 'light' = 'shadow'` (attribute `row-projection`) — where
105
+ `renderItem`'s output is instantiated. `'shadow'` (default) stamps it inside this component's own
106
+ shadow root, so only inherited custom properties and the public row parts reach it. `'light'`
107
+ renders the windowed rows into the host's own light DOM instead, assigned into the shadow viewport
108
+ through internal named slots, so ordinary document CSS styles a virtualized row exactly as it
109
+ styles the same row unvirtualized. The component keeps owning windowing, measurement, spacer
110
+ sizing, `scrollToIndex()`, the external-scroller mode and the ARIA contract either way, and
111
+ positioning stays on the shadow-side `[part="row"]` wrapper that document CSS cannot select — so
112
+ consumer styles can never break windowing. Any other value canonicalizes to `'shadow'`. Left
113
+ unset, the rendered output is byte-identical to before and the host's light DOM stays empty.
114
+ See **Light-DOM row projection** below for the trade-offs it carries.
104
115
  - `itemRole: 'listitem' | 'row' = 'listitem'` (attribute `item-role`) — `'listitem'` (default)
105
116
  preserves the plain `role="list"`/`role="listitem"` mapping with `aria-setsize`/`aria-posinset`.
106
117
  `'row'` additionally maps `[part="base"]` to `role="rowgroup"`, `[part="spacer"]` to
@@ -355,4 +366,46 @@ default estimate with sparse `ResizeObserver` measurements for rows that have ac
355
366
  decides: groups render before the rows, so an active row wins while (and only while) it needs to,
356
367
  which is right — a group header is a non-interactive `pointer-events: none` label.
357
368
 
369
+ ### Light-DOM row projection
370
+
371
+ `rowProjection="light"` exists for one shape: an application whose list rows are already styled by
372
+ its own global stylesheet, and which therefore could not adopt virtualization without rehoming a
373
+ dozen descendant rules per row into a new custom element or a growing set of custom properties. In
374
+ projection mode the windowed rows render into the host's own light DOM, so ordinary document CSS
375
+ reaches row content directly.
376
+
377
+ Positioning, measurement and semantics stay where they were. The `[part="row"]` wrapper remains in
378
+ the shadow root and keeps `position: absolute`, the per-frame `transform`, `role`, `aria-setsize`/
379
+ `aria-posinset` (or `aria-rowindex`) and the `ResizeObserver` box — document CSS cannot select it,
380
+ so consumer styles can never break windowing. The whole part vocabulary (`base`, `spacer`, `row`,
381
+ `group`, `sticky-group`) keeps matching in both modes, and `row-height="auto"` still measures
382
+ projected content because the light row is an ordinary in-flow child of that wrapper.
383
+
384
+ `projectedRows: HTMLElement[]` returns the projected light-DOM row wrappers in item order, and is
385
+ empty outside projection mode. The exported type is `LyraVirtualListRowProjection`; the reserved
386
+ attributes marking library-owned light-DOM nodes are exported as `VIRTUAL_LIST_ROW_ATTRIBUTE`
387
+ (`data-lr-virtual-list-row`) and `VIRTUAL_LIST_STICKY_ATTRIBUTE` (`data-lr-virtual-list-sticky`).
388
+
389
+ **Known gotchas, all inherent to handing the cascade back to the consumer:**
390
+
391
+ - **One component-owned wrapper sits between the host and your markup.** A slot cannot assign a text
392
+ node or a multi-root fragment by attribute, so each row's content lives inside a wrapper carrying
393
+ `data-lr-virtual-list-row`. Descendant selectors (`lr-virtual-list .row-title`) port unchanged;
394
+ child combinators (`lr-virtual-list > .row`), `:nth-child`, `:first-child` and sibling combinators
395
+ written against the unvirtualized markup do not. `:nth-child` on the wrappers reflects the current
396
+ *window*, not the item index.
397
+ - **`closest('[part="row"]')` stops resolving.** A delegated listener on the host now sees an
398
+ un-retargeted `event.target` inside the light DOM. Use `closest('[data-lr-virtual-list-row]')`.
399
+ - **The document cascade now reaches row content**, including resets and element-level rules that
400
+ previously could not, so a projected row can look different from the same row in shadow mode.
401
+ - **Per-row light-DOM state does not survive a disconnect/reconnect.** Disconnect removes the
402
+ projected rows completely (no rows, no markers, no anchor left behind), so a reparenting move
403
+ rebuilds them. Scroll position, measurements and the window are unaffected — they live in
404
+ component state, not in the rows.
405
+ - **Projection activates one task after hydration.** A server render has no DOM to project into, so
406
+ the first window is shadow-rendered, hydration matches the server markup, and the rows then swap
407
+ into the light DOM on the next task.
408
+ - **A row taken out of flow collapses its wrapper.** `position: fixed`/`absolute` or
409
+ `display: none` on your own row leaves nothing for the wrapper to measure.
410
+
358
411
  ---
package/llms/shared.md CHANGED
@@ -1166,6 +1166,47 @@ code. See each control's own reference page for its exact pair.
1166
1166
  `lr-select`. It is a _floor_, not a fixed size. Keep the resolved value **at or above 24px**
1167
1167
  (WCAG 2.2 SC 2.5.8 target size); the default leaves headroom. Lowering it below that shrinks
1168
1168
  every affordance in the library at once.
1169
+ - **`--lr-icon-button-size-scope`** resizes icon buttons for **one subtree** instead of the whole
1170
+ application. Set it on any wrapper; it inherits past intervening components and reaches every
1171
+ icon-only control below it. Three names, three scopes — pick by how far you want the change to
1172
+ reach:
1173
+
1174
+ | Property | Scope | Set it on |
1175
+ | --- | --- | --- |
1176
+ | `--lr-theme-icon-button-size` | application-wide | `:root`, or any ancestor |
1177
+ | `--lr-icon-button-size-scope` | one subtree | the wrapper you want affected |
1178
+ | `--lr-icon-button-size` | one element | the icon-only control itself |
1179
+
1180
+ `--lr-theme-icon-button-size` wins wherever both ancestor inputs are set. `--lr-icon-button-size`
1181
+ is **element-scoped on purpose** and is not a wrapper knob: every component re-declares it on its
1182
+ own host so the touch-target floor can apply per element, so a value set on a wrapper is replaced
1183
+ at the first component in between and never reaches anything nested inside one. That behaviour is
1184
+ unchanged — use `--lr-icon-button-size-scope` for the wrapper case.
1185
+
1186
+ ```css
1187
+ /* A dense toolbar, without touching the rest of the app. */
1188
+ .message-toolbar {
1189
+ --lr-icon-button-size-scope: 1.75rem;
1190
+ }
1191
+ ```
1192
+
1193
+ The coarse-pointer floor still applies to both ancestor inputs: on a touch device (`hover: none`
1194
+ or `pointer: coarse`) a resolved value below `2.75rem` is raised back to it, so the new subtree
1195
+ knob is not a way around WCAG 2.2 SC 2.5.8 — a deliberately dense desktop toolbar still becomes
1196
+ tappable on a phone.
1197
+ - **`--lr-color-surface-overlay` follows `--lr-theme-color-surface-default` in both modes.** It is
1198
+ the panel colour behind every floating surface — dropdowns, listboxes, menus, toasts, popovers,
1199
+ dialogs, and the `lr-app-rail` mobile drawer. In light mode it resolves straight to
1200
+ `--lr-color-surface`, so a re-skinned page surface carries them all with it. Dark mode cannot
1201
+ resolve to the page surface — panel and page would be the same near-black, and an open dialog
1202
+ would read as a scrim with text floating on it and no panel at all — so it is **derived** from
1203
+ the page surface instead: `color-mix(in srgb, var(--lr-color-surface) 85%, #8bade2)`, which lifts
1204
+ the panel a fixed amount above whatever the base happens to be. One
1205
+ `--lr-theme-color-surface-default` override therefore re-skins every floating surface in dark
1206
+ mode too, and the elevation delta survives the re-skin. At the built-in dark base the pair still
1207
+ resolves to the same panel colour it always has, so no existing dark theme moves.
1208
+ `--lr-theme-color-surface-overlay` still wins outright when you set it — reach for it only when
1209
+ you want a panel colour unrelated to the page surface.
1169
1210
  - **Aligning your own content next to a checkbox or radio.** `--lr-checkbox-label-indent` /
1170
1211
  `--lr-radio-label-indent` publish the label offset, but custom properties inherit _down_, not
1171
1212
  sideways, so a sibling node in your tree cannot read them off the control. Compute the same
@@ -1769,8 +1810,8 @@ silently defeats a registered catalog — omit it, or pass `undefined`.
1769
1810
 
1770
1811
  ### Ready-made catalogs: `@aceshooting/lyra-ui/translations/<locale>.js`
1771
1812
 
1772
- Eleven full catalogs ship with the package — **`ar`, `de`, `es`, `fa`, `fr`, `he`, `it`, `ja`,
1773
- `pt-BR`, `ru`, `zh-CN`** — each covering every key in `LYRA_DEFAULT_STRINGS`. They are
1813
+ Twelve full catalogs ship with the package — **`ar`, `de`, `es`, `fa`, `fr`, `he`, `it`, `ja`,
1814
+ `pt-BR`, `ro`, `ru`, `zh-CN`** — each covering every key in `LYRA_DEFAULT_STRINGS`. They are
1774
1815
  **side-effect-only modules**: import one bare, read nothing from it, and it calls
1775
1816
  `registerLyraLocale()` for you.
1776
1817
 
@@ -1781,11 +1822,14 @@ import "@aceshooting/lyra-ui/translations/fa.js"; // fa-IR falls back to this ba
1781
1822
  import "@aceshooting/lyra-ui/translations/he.js"; // he-IL falls back to this base catalog
1782
1823
  import "@aceshooting/lyra-ui/translations/it.js"; // Italian
1783
1824
  import "@aceshooting/lyra-ui/translations/pt-BR.js"; // also serves pt and pt-PT
1825
+ import "@aceshooting/lyra-ui/translations/ro.js"; // Romanian
1784
1826
  import "@aceshooting/lyra-ui/translations/zh-CN.js"; // also serves zh, zh-Hans and zh-Hans-CN
1785
1827
  ```
1786
1828
 
1787
1829
  Persian and Hebrew use CLDR plural categories (`fa`: `one`/`other`; `he`:
1788
- `one`/`two`/`other`); Italian uses a non-default set too (`it`: `one`/`many`/`other`). `ar`, `fa`
1830
+ `one`/`two`/`other`); Italian uses a non-default set too (`it`: `one`/`many`/`other`), and so does
1831
+ Romanian (`ro`: `one`/`few`/`other`, where `few` covers `0` and `2`-`19` and `other` is the
1832
+ `de`-requiring form from `20` upward). `ar`, `fa`
1789
1833
  and `he` declare `dir: 'rtl'`, so `getLyraLocaleDirection()`
1790
1834
  answers for them (and for `ar-EG`, `fa-IR`, `he-IL`) — but locale selection still does not _force_
1791
1835
  writing direction: set `dir="rtl"` on the page or an ancestor yourself.
package/llms/tokens.md CHANGED
@@ -52,8 +52,11 @@ ordinary per-component property: a rule that sets one of them directly on an anc
52
52
  at the first intervening `lr-*` component and never reaches a nested target — even though
53
53
  setting it directly on the target element itself still works, which is what makes the failure
54
54
  look arbitrary rather than systematic. Reach through a subtree with `--lr-theme-focus-ring-*`,
55
- `--lr-theme-icon-button-size`, `--lr-theme-otp-input-segment-size`, or
56
- `--lr-theme-popover-viewport-clamp` instead. Every other `--lr-<component>-*` token — including
55
+ `--lr-theme-otp-input-segment-size`, or `--lr-theme-popover-viewport-clamp` instead.
56
+ `--lr-icon-button-size` additionally has a dedicated subtree-scoped input,
57
+ `--lr-icon-button-size-scope`, which an ancestor rule can set without reaching for the
58
+ application-wide `--lr-theme-icon-button-size`; the theme input still wins over it when both
59
+ are set. Every other `--lr-<component>-*` token — including
57
60
  the rest of `lr-icon-button`'s own (`-radius`, `-background`, `-color`, `-border`, and their
58
61
  `-hover`/`-active` variants) — is not re-declared anywhere in the shared layer and inherits
59
62
  normally from an ancestor.
@@ -120,7 +123,7 @@ normally from an ancestor.
120
123
  | `--lr-color-success-on-normal` | `--lr-theme-color-success-on-normal` | `var(--lr-ramp-neutral-05)` | dark: `var(--lr-theme-color-success-on-normal, var(--lr-ramp-neutral-95))` |
121
124
  | `--lr-color-success-on-quiet` | `--lr-theme-color-success-on-quiet` | `var(--lr-ramp-neutral-05)` | dark: `var(--lr-theme-color-success-on-quiet, var(--lr-ramp-neutral-95))` |
122
125
  | `--lr-color-surface` | `--lr-theme-color-surface-default` | `#fff` | dark: `var(--lr-theme-color-surface-default, #1a1a1a)`<br>forcedColors: `Canvas` |
123
- | `--lr-color-surface-overlay` | `--lr-theme-color-surface-overlay` | `var(--lr-color-surface)` | dark: `var(--lr-theme-color-surface-overlay, #2b3038)` |
126
+ | `--lr-color-surface-overlay` | `--lr-theme-color-surface-overlay` | `var(--lr-color-surface)` | dark: `var(--lr-theme-color-surface-overlay, color-mix(in srgb, var(--lr-color-surface) 85%, #8bade2))` |
124
127
  | `--lr-color-surface-raised` | `--lr-theme-color-surface-raised` | `#f6f8fa` | dark: `var(--lr-theme-color-surface-raised, #22272e)`<br>forcedColors: `Canvas` |
125
128
  | `--lr-color-text` | `--lr-theme-color-text-normal` | `#1a1a1a` | dark: `var(--lr-theme-color-text-normal, #f2f2f2)`<br>forcedColors: `CanvasText` |
126
129
  | `--lr-color-text-quiet` | `--lr-theme-color-text-quiet` | `#6b7280` | dark: `var(--lr-theme-color-text-quiet, #9aa1ac)`<br>forcedColors: `CanvasText` |
@@ -175,7 +178,7 @@ normally from an ancestor.
175
178
  | `--lr-graph-cat-7` | `--lr-theme-graph-cat-7` | `#52d6e8` | dark: `var(--lr-theme-graph-cat-7, #79e2ef)`<br>forcedColors: `Highlight` |
176
179
  | `--lr-graph-cat-8` | `--lr-theme-graph-cat-8` | `#c9d1d9` | dark: `var(--lr-theme-graph-cat-8, #e4e7eb)`<br>forcedColors: `LinkText` |
177
180
  | `--lr-hover-brightness` | `--lr-theme-hover-brightness` | `1.08` | — |
178
- | `--lr-icon-button-size` | `--lr-theme-icon-button-size` | `2.5rem` | — |
181
+ | `--lr-icon-button-size` | `--lr-theme-icon-button-size` | `var(--lr-icon-button-size-scope, 2.5rem)` | — |
179
182
  | `--lr-layer-base` | `--lr-theme-z-index-base` | `0` | — |
180
183
  | `--lr-layer-content` | `--lr-theme-z-index-content` | `1` | — |
181
184
  | `--lr-layer-dropdown` | `--lr-theme-z-index-dropdown` | `900` | — |