@aceshooting/lyra-ui 21.0.0 → 21.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 (272) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/README.md +6 -3
  3. package/custom-elements.json +1 -1
  4. package/dist/ai/runtime.js +1 -1
  5. package/dist/ai/types.d.ts +13 -5
  6. package/dist/cli/lyra-rename-ledger.mjs +1 -0
  7. package/dist/cli/migrate-wa.mjs +33 -13
  8. package/dist/cli/migration-contract.json +1 -1
  9. package/dist/components/agent-tools/agent-trace/agent-trace.class.d.ts +5 -3
  10. package/dist/components/agent-tools/agent-trace/agent-trace.class.js +3 -2
  11. package/dist/components/agent-tools/tool-call-block/tool-call-block.class.d.ts +15 -3
  12. package/dist/components/agent-tools/tool-call-block/tool-call-block.class.js +3 -3
  13. package/dist/components/agent-tools/tool-call-chip/tool-call-chip.class.d.ts +24 -8
  14. package/dist/components/agent-tools/tool-call-chip/tool-call-chip.class.js +3 -3
  15. package/dist/components/agent-tools/tool-param-form/tool-param-form.class.js +4 -0
  16. package/dist/components/agent-tools/tool-result-dialog/tool-result-dialog.class.d.ts +9 -5
  17. package/dist/components/agent-tools/tool-result-dialog/tool-result-dialog.class.js +2 -2
  18. package/dist/components/agent-tools/tool-result-dialog/tool-result-dialog.styles.js +1 -1
  19. package/dist/components/agent-tools/tool-status.js +2 -2
  20. package/dist/components/agent-tools/tool-timeline/tool-timeline.class.d.ts +8 -0
  21. package/dist/components/agent-tools/tool-timeline/tool-timeline.class.js +3 -2
  22. package/dist/components/agent-tools/tool-timeline/tool-timeline.styles.js +1 -1
  23. package/dist/components/agent-tools/trace-tree/span.d.ts +2 -2
  24. package/dist/components/charts/chart/box-plot.class.d.ts +3 -1
  25. package/dist/components/charts/chart/box-plot.class.js +9 -9
  26. package/dist/components/charts/chart/chart-bidi.d.ts +109 -0
  27. package/dist/components/charts/chart/chart-bidi.js +1 -0
  28. package/dist/components/charts/chart/chart.class.d.ts +17 -2
  29. package/dist/components/charts/chart/chart.class.js +10 -8
  30. package/dist/components/charts/chart/histogram.class.js +1 -1
  31. package/dist/components/charts/chart/lite-chart.class.d.ts +24 -5
  32. package/dist/components/charts/chart/lite-chart.class.js +9 -9
  33. package/dist/components/charts/chart/lite-chart.styles.js +1 -1
  34. package/dist/components/conversation/code-block/shiki-dark-theme.d.ts +2 -2
  35. package/dist/components/conversation/code-block/shiki-dark-theme.js +1 -1
  36. package/dist/components/conversation/conversation-item/conversation-item.class.d.ts +18 -2
  37. package/dist/components/conversation/conversation-item/conversation-item.class.js +3 -3
  38. package/dist/components/conversation/conversation-item/conversation-item.styles.js +1 -1
  39. package/dist/components/conversation/markdown/markdown-base.class.js +1 -1
  40. package/dist/components/conversation/markdown/markdown-core.class.d.ts +3 -1
  41. package/dist/components/conversation/markdown/markdown.class.d.ts +3 -1
  42. package/dist/components/conversation/message-actions/message-actions.class.d.ts +7 -2
  43. package/dist/components/conversation/message-actions/message-actions.class.js +2 -2
  44. package/dist/components/conversation/message-parts/message-parts.class.d.ts +6 -2
  45. package/dist/components/conversation/message-parts/message-parts.class.js +5 -3
  46. package/dist/components/conversation/selection-toolbar/selection-toolbar.class.d.ts +3 -2
  47. package/dist/components/conversation/selection-toolbar/selection-toolbar.class.js +1 -1
  48. package/dist/components/conversation/streaming-text/streaming-text-base.class.d.ts +1 -5
  49. package/dist/components/conversation/streaming-text/streaming-text-base.class.js +2 -2
  50. package/dist/components/conversation/streaming-text/streaming-text-core.class.d.ts +7 -1
  51. package/dist/components/conversation/streaming-text/streaming-text-core.class.js +3 -4
  52. package/dist/components/conversation/streaming-text/streaming-text.class.d.ts +7 -1
  53. package/dist/components/conversation/streaming-text/streaming-text.class.js +3 -4
  54. package/dist/components/conversation/thread-list/thread-list.class.d.ts +13 -2
  55. package/dist/components/conversation/thread-list/thread-list.class.js +3 -3
  56. package/dist/components/data/data-grid/data-grid.class.js +1 -1
  57. package/dist/components/data/document-library/document-library.class.js +2 -0
  58. package/dist/components/data/flow-canvas/flow-canvas.class.js +1 -1
  59. package/dist/components/data/flow-minimap/flow-minimap.class.js +1 -1
  60. package/dist/components/data/flow-node/flow-node.class.d.ts +6 -2
  61. package/dist/components/data/flow-node/flow-node.class.js +6 -2
  62. package/dist/components/data/flow-node/flow-node.styles.js +1 -1
  63. package/dist/components/data/gauge/gauge.styles.js +1 -1
  64. package/dist/components/data/heatmap/heatmap.class.d.ts +3 -0
  65. package/dist/components/data/heatmap/heatmap.class.js +2 -2
  66. package/dist/components/data/heatmap/heatmap.styles.js +1 -1
  67. package/dist/components/data/sparkline/sparkline.class.d.ts +5 -3
  68. package/dist/components/data/stat/stat.class.d.ts +4 -3
  69. package/dist/components/data/table/table.class.d.ts +32 -5
  70. package/dist/components/data/table/table.class.js +3 -2
  71. package/dist/components/forms/button/button.class.d.ts +7 -1
  72. package/dist/components/forms/button/button.styles.js +1 -1
  73. package/dist/components/forms/date-picker/date-input.styles.js +1 -1
  74. package/dist/components/forms/input/input.styles.js +1 -1
  75. package/dist/components/forms/rubric-form/rubric-form.class.js +1 -0
  76. package/dist/components/layout/app-rail/app-rail.class.d.ts +50 -11
  77. package/dist/components/layout/app-rail/app-rail.class.js +2 -2
  78. package/dist/components/layout/command-palette/command-palette.class.js +1 -1
  79. package/dist/components/layout/menu/menu.class.d.ts +6 -5
  80. package/dist/components/layout/split-panel/split-panel.class.d.ts +2 -1
  81. package/dist/components/media/flag/language-map.d.ts +8 -0
  82. package/dist/components/media/flag/language-map.js +1 -1
  83. package/dist/components/media/map/map-loader.d.ts +7 -1
  84. package/dist/components/media/map/map.class.d.ts +111 -5
  85. package/dist/components/media/map/map.class.js +3 -3
  86. package/dist/components/media/media-card/media-card.class.d.ts +18 -5
  87. package/dist/components/media/media-card/media-card.class.js +1 -1
  88. package/dist/components/overlays/overlay/popover.class.d.ts +20 -0
  89. package/dist/components/overlays/overlay/popover.class.js +2 -2
  90. package/dist/components/retrieval/graph/graph.class.d.ts +3 -3
  91. package/dist/components/retrieval/graph/graph.class.js +1 -1
  92. package/dist/components/retrieval/knowledge-graph-explorer/knowledge-graph-explorer.class.d.ts +5 -3
  93. package/dist/components/retrieval/knowledge-graph-explorer/knowledge-graph-explorer.class.js +3 -2
  94. package/dist/components/retrieval/mind-map/mind-map.class.d.ts +3 -3
  95. package/dist/components/retrieval/mind-map/mind-map.class.js +1 -1
  96. package/dist/components/retrieval/retrieval-results/retrieval-results.class.d.ts +4 -1
  97. package/dist/components/retrieval/retrieval-results/retrieval-results.class.js +5 -1
  98. package/dist/components/retrieval/source-picker/source-picker.class.d.ts +4 -1
  99. package/dist/components/retrieval/source-picker/source-picker.class.js +5 -1
  100. package/dist/components/utility/icon/icon.class.d.ts +9 -3
  101. package/dist/components/utility/icon/icon.class.js +1 -1
  102. package/dist/components/utility/mutation-observer/mutation-observer.class.d.ts +14 -8
  103. package/dist/components/utility/mutation-observer/mutation-observer.class.js +1 -1
  104. package/dist/components/viewers/document-viewer/document-viewer.class.d.ts +6 -1
  105. package/dist/components/viewers/document-viewer/document-viewer.class.js +7 -1
  106. package/dist/components/viewers/document-viewer/registry.d.ts +12 -3
  107. package/dist/components/viewers/geojson-view/geojson-view.class.d.ts +13 -5
  108. package/dist/components/viewers/geojson-view/geojson-view.class.js +1 -1
  109. package/dist/components/viewers/geojson-view/geojson-viewer.class.d.ts +3 -2
  110. package/dist/custom-elements-jsx.d.ts +1 -1
  111. package/dist/events.d.ts +644 -1242
  112. package/dist/internal/anchored-overlay-runtime.d.ts +2 -2
  113. package/dist/internal/cell-range.d.ts +0 -6
  114. package/dist/internal/cell-range.js +1 -1
  115. package/dist/internal/css-token-length.d.ts +7 -0
  116. package/dist/internal/css-token-length.js +1 -0
  117. package/dist/internal/default-strings.generated.d.ts +1 -1
  118. package/dist/internal/default-strings.generated.js +1 -1
  119. package/dist/internal/deferred-focus-return.d.ts +7 -4
  120. package/dist/internal/deferred-focus-return.js +1 -1
  121. package/dist/internal/dev-mode-attribute-warning.d.ts +35 -0
  122. package/dist/internal/dev-mode-attribute-warning.js +1 -1
  123. package/dist/internal/localization-runtime.js +1 -1
  124. package/dist/internal/localization-types.d.ts +1 -1
  125. package/dist/internal/localization.js +2 -2
  126. package/dist/internal/package-metadata.d.ts +1 -1
  127. package/dist/internal/package-metadata.js +1 -1
  128. package/dist/internal/papaparse-loader.d.ts +1 -1
  129. package/dist/internal/papaparse-loader.js +1 -1
  130. package/dist/internal/positioner.d.ts +10 -0
  131. package/dist/internal/positioner.js +1 -1
  132. package/dist/internal/shared-unions.d.ts +2 -1
  133. package/dist/internal/slotted-overlay-controller.d.ts +20 -0
  134. package/dist/internal/slotted-overlay-controller.js +1 -0
  135. package/dist/internal/text-quote.d.ts +1 -1
  136. package/dist/internal/text-quote.js +1 -1
  137. package/dist/internal/theme-observation.d.ts +4 -0
  138. package/dist/internal/theme-observation.js +1 -0
  139. package/dist/internal/theme-watcher.js +1 -1
  140. package/dist/localization.d.ts +6 -1
  141. package/dist/localization.js +1 -1
  142. package/dist/lyra.d.ts +1 -1
  143. package/dist/lyra.js +1 -1
  144. package/dist/svelte.d.ts +1 -1
  145. package/dist/testing/lyra-tag-event-map.js +1 -1
  146. package/dist/translations/ar/agent-tools.js +1 -1
  147. package/dist/translations/cs/agent-tools.js +1 -1
  148. package/dist/translations/da/agent-tools.js +1 -1
  149. package/dist/translations/de/agent-tools.js +1 -1
  150. package/dist/translations/de-CH/agent-tools.js +1 -1
  151. package/dist/translations/es/agent-tools.js +1 -1
  152. package/dist/translations/fa/agent-tools.js +1 -1
  153. package/dist/translations/fi/agent-tools.js +1 -1
  154. package/dist/translations/fr/agent-tools.js +1 -1
  155. package/dist/translations/he/agent-tools.js +1 -1
  156. package/dist/translations/hi/agent-tools.js +1 -1
  157. package/dist/translations/hr/agent-tools.js +1 -1
  158. package/dist/translations/hu/agent-tools.js +1 -1
  159. package/dist/translations/id/agent-tools.js +1 -1
  160. package/dist/translations/it/agent-tools.js +1 -1
  161. package/dist/translations/ja/agent-tools.js +1 -1
  162. package/dist/translations/kk/agent-tools.js +1 -1
  163. package/dist/translations/ko/agent-tools.js +1 -1
  164. package/dist/translations/nb/agent-tools.js +1 -1
  165. package/dist/translations/nl/agent-tools.js +1 -1
  166. package/dist/translations/nn/agent-tools.js +1 -1
  167. package/dist/translations/pl/agent-tools.js +1 -1
  168. package/dist/translations/pt-BR/agent-tools.js +1 -1
  169. package/dist/translations/pt-PT/agent-tools.js +1 -1
  170. package/dist/translations/pt-PT/charts.js +1 -1
  171. package/dist/translations/pt-PT/conversation.js +1 -1
  172. package/dist/translations/pt-PT/data.js +1 -1
  173. package/dist/translations/pt-PT/forms.js +1 -1
  174. package/dist/translations/pt-PT/layout.js +1 -1
  175. package/dist/translations/pt-PT/media.js +1 -1
  176. package/dist/translations/pt-PT/retrieval.js +1 -1
  177. package/dist/translations/pt-PT/shared.js +1 -1
  178. package/dist/translations/pt-PT/utility.js +1 -1
  179. package/dist/translations/pt-PT/viewers.js +2 -2
  180. package/dist/translations/ro/agent-tools.js +1 -1
  181. package/dist/translations/ru/agent-tools.js +1 -1
  182. package/dist/translations/sl/agent-tools.js +1 -1
  183. package/dist/translations/sv/agent-tools.js +1 -1
  184. package/dist/translations/tr/agent-tools.js +1 -1
  185. package/dist/translations/uk/agent-tools.js +1 -1
  186. package/dist/translations/zh-CN/agent-tools.js +1 -1
  187. package/dist/translations/zh-TW/agent-tools.js +1 -1
  188. package/dist/utilities/index.d.ts +1 -1
  189. package/dist/utilities/index.js +1 -1
  190. package/dist/utilities/localization.d.ts +28 -10
  191. package/dist/vue.d.ts +1 -1
  192. package/llms/components/lr-accordion-item.md +2 -344
  193. package/llms/components/lr-accordion.md +2 -344
  194. package/llms/components/lr-app-rail-group.md +2 -721
  195. package/llms/components/lr-app-rail-item.md +2 -721
  196. package/llms/components/lr-app-rail.md +29 -4
  197. package/llms/components/lr-bar-chart.md +2 -87
  198. package/llms/components/lr-box-plot.md +1 -1
  199. package/llms/components/lr-breadcrumb-item.md +2 -67
  200. package/llms/components/lr-bubble-chart.md +2 -87
  201. package/llms/components/lr-button.md +7 -0
  202. package/llms/components/lr-chart.md +4 -5
  203. package/llms/components/lr-chip-group.md +2 -272
  204. package/llms/components/lr-conversation-item.md +20 -2
  205. package/llms/components/lr-date-input.md +2 -457
  206. package/llms/components/lr-date-picker.md +6 -2
  207. package/llms/components/lr-document-library.md +3 -3
  208. package/llms/components/lr-document-viewer.md +14 -5
  209. package/llms/components/lr-doughnut-chart.md +2 -87
  210. package/llms/components/lr-dropdown-item.md +2 -306
  211. package/llms/components/lr-dropdown.md +6 -0
  212. package/llms/components/lr-flag.md +9 -1
  213. package/llms/components/lr-flow-node.md +4 -1
  214. package/llms/components/lr-geojson-view.md +3 -90
  215. package/llms/components/lr-geojson-viewer.md +13 -5
  216. package/llms/components/lr-icon-button.md +4 -1
  217. package/llms/components/lr-icon.md +14 -6
  218. package/llms/components/lr-input.md +9 -2
  219. package/llms/components/lr-lite-chart.md +17 -9
  220. package/llms/components/lr-map.md +87 -2
  221. package/llms/components/lr-markdown-core.md +5 -4
  222. package/llms/components/lr-markdown.md +4 -2
  223. package/llms/components/lr-media-card.md +10 -5
  224. package/llms/components/lr-menu-item.md +2 -306
  225. package/llms/components/lr-menu.md +9 -6
  226. package/llms/components/lr-menubar-item.md +2 -125
  227. package/llms/components/lr-message-actions.md +4 -1
  228. package/llms/components/lr-message-parts.md +14 -5
  229. package/llms/components/lr-mutation-observer.md +12 -6
  230. package/llms/components/lr-navigation-menu-item.md +2 -237
  231. package/llms/components/lr-number-input.md +4 -0
  232. package/llms/components/lr-option.md +2 -712
  233. package/llms/components/lr-pie-chart.md +2 -87
  234. package/llms/components/lr-polar-area-chart.md +2 -87
  235. package/llms/components/lr-popover.md +10 -0
  236. package/llms/components/lr-prompt-input.md +5 -1
  237. package/llms/components/lr-radar-chart.md +2 -87
  238. package/llms/components/lr-reorder-item.md +2 -157
  239. package/llms/components/lr-result-field.md +2 -117
  240. package/llms/components/lr-retrieval-results.md +3 -1
  241. package/llms/components/lr-rubric-form.md +3 -2
  242. package/llms/components/lr-scatter-chart.md +2 -87
  243. package/llms/components/lr-selection-toolbar.md +4 -2
  244. package/llms/components/lr-source-card.md +2 -186
  245. package/llms/components/lr-source-picker.md +3 -1
  246. package/llms/components/lr-sparkline.md +9 -4
  247. package/llms/components/lr-split-panel.md +5 -3
  248. package/llms/components/lr-stat.md +4 -3
  249. package/llms/components/lr-streaming-text-core.md +7 -5
  250. package/llms/components/lr-streaming-text.md +9 -6
  251. package/llms/components/lr-swatch-picker.md +130 -0
  252. package/llms/components/lr-tag.md +2 -177
  253. package/llms/components/lr-thread-list.md +27 -4
  254. package/llms/components/lr-timeline-item.md +2 -120
  255. package/llms/components/lr-toast-item.md +2 -223
  256. package/llms/components/lr-tool-call-block.md +12 -3
  257. package/llms/components/lr-tool-call-chip.md +12 -6
  258. package/llms/components/lr-tool-param-form.md +3 -2
  259. package/llms/components/lr-tool-result-dialog.md +7 -3
  260. package/llms/components/lr-tool-result-view.md +4 -3
  261. package/llms/components/lr-tool-timeline.md +12 -5
  262. package/llms/components/lr-tree-item.md +2 -354
  263. package/llms/index.md +22 -4
  264. package/llms/migration.md +75 -1
  265. package/llms/peers.md +1 -1
  266. package/llms/shared.md +86 -39
  267. package/llms-full.txt +739 -163
  268. package/package.json +6 -6
  269. package/registrations.json +1 -1
  270. package/vscode-css-data.json +1 -1
  271. package/vscode-html-data.json +1 -1
  272. package/web-types.json +1 -1
@@ -9,181 +9,6 @@
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** none
12
- - **Themeable via** 7 parts, 24 custom properties — see this component's own `@csspart`/`@cssprop` list below
13
- - **Documented with** `lr-badge` (same section below)
12
+ - **Themeable via** 7 parts, 24 custom properties — see `lr-badge.md`
13
+ - **Documented with** `lr-badge`: see [lr-badge.md](./lr-badge.md).
14
14
  - **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`
15
-
16
- ---
17
-
18
- ## `lr-badge` and `lr-tag`
19
-
20
- Compact status labels. `LyraTag` extends `LyraBadge`, so the two share one visual contract; `lr-tag`
21
- adds tag semantics and an optional remove affordance. Both are static text by default, matching the
22
- mirrored upstreams and avoiding repeated announcements when a category badge is re-rendered.
23
- Authors can opt a genuinely changing badge into live semantics with `role="status"`; that and every
24
- other author-supplied role remain authoritative across updates, hydration, and reconnect.
25
-
26
- **Visual break in 8.0.0 — a badge is no longer a pill by default.** Both components used to render
27
- fully-rounded ends unconditionally. `--lr-badge-radius` now defaults to `var(--lr-radius)` (a rounded
28
- rectangle) and the pill treatment moved behind the new opt-in `pill` boolean. Existing markup keeps
29
- its corner radius only if you add `pill`, or set `--lr-badge-radius: var(--lr-radius-pill)` once at
30
- the app level.
31
-
32
- **Properties** (all are declared by `lr-badge` and inherited by `lr-tag`; `lr-tag` adds the
33
- `variant="text"` spelling plus `withRemove` / `removable`):
34
-
35
- - `variant: 'neutral' | 'brand' | 'primary' | 'success' | 'warning' | 'danger' = 'neutral'`
36
- (reflected) — the semantic palette. `primary` renders through the same brand palette while
37
- remaining `primary` on property reads, selectors, serialization and reflection. `lr-tag`
38
- additionally accepts and preserves `text`, rendering the neutral plain treatment.
39
- - `size: '2xs' | 'xs' | 's' | 'm' | 'l' | 'xl' | 'small' | 'medium' | 'large' = 'm'` (reflected) — the same visual-density scale
40
- `<lr-chip>` uses, for typography/padding/minimum block size; `m` preserves the original badge
41
- dimensions. Both short and long upstream spellings round-trip verbatim while resolving to the
42
- same private effective size for rendering.
43
- - `appearance: 'accent' | 'filled' | 'outlined' | 'filled-outlined' | 'plain' = 'filled-outlined'`
44
- (reflected) — **new in 8.0.0.** The second visual axis: `variant` picks the palette, `appearance`
45
- decides how much of it lands on the fill, the border and the text. `filled-outlined` (the default)
46
- is quiet tint + loud border + loud text, i.e. exactly the pre-8.0.0 treatment; `filled` drops the
47
- border, `outlined` drops the fill, `accent` fills solidly with on-loud text, and `plain` drops both
48
- fill and border while keeping the label color. The border-less appearances use a `transparent`
49
- border rather than `none`, so switching appearance never changes the badge's layout box.
50
- - `pill: boolean = false` (reflected) — **new in 8.0.0.** Fully-rounded ends instead of the default
51
- rounded rectangle; see the visual break above. Since it defaults to `false`, `pill="false"` is not
52
- a way to switch it off — remove the attribute, or assign `.pill = false`.
53
- - `attention: 'none' | 'pulse' | 'bounce' = 'none'` (reflected) — **new in 8.0.0.** An opt-in,
54
- infinitely-looping attention animation for a badge that has to be noticed: `pulse` draws an
55
- expanding ring, `bounce` hops the surface vertically (block-direction, so it needs no RTL
56
- mirroring). Both stop outright — not merely shorten — under `prefers-reduced-motion: reduce`.
57
- The default does not materialize an attribute; an explicit `attention="none"` is authoritative
58
- and suppresses the `pulse` shorthand.
59
- - `pulse: boolean = false` (reflected) — upstream-compatible shorthand for the pulse attention
60
- treatment while the `attention` attribute is omitted. Any explicit attention value wins. Lyra's
61
- intentional `variant="neutral"` and `appearance="filled-outlined"` defaults remain unchanged
62
- because the two pinned upstreams disagree on both defaults.
63
- - `withRemove: boolean = false` (attribute `with-remove`, reflected) — **`lr-tag` only, new in
64
- 8.0.0.** Renders the remove affordance. `lr-badge` never renders one, even if the attribute is
65
- present on the markup.
66
- - `removable: boolean = false` (attribute `removable`) — **`lr-tag` only.** Shoelace-compatible
67
- alias for `withRemove`; reading either property reports the shared state. Either authored
68
- attribute keeps removal enabled until both are absent. Assigning `false` through either property
69
- clears both attributes, while assigning `true` reflects that property's own spelling.
70
-
71
- **Events:** `lr-remove` — noncancelable, no detail, bubbles and composes. Emitted by `lr-tag` only (a
72
- badge emits nothing at all) when the remove button is activated by click or by Enter/Space while
73
- focused; it is a real native `<button>`, so both come for free. Only rendered, and therefore only
74
- fired, while `withRemove` / `removable` is set, and the event's `target` is the tag itself.
75
-
76
- Like `<lr-chip>`, a removable `lr-tag` is controlled: activation only announces the request. The
77
- tag remains connected even if a listener calls `preventDefault()` (the event is not cancelable),
78
- and the consumer removes it by updating the collection that rendered it.
79
-
80
- If that controlled listener synchronously removes the focused tag, or a direct property write
81
- removes its action, focus moves to the nearest available composed action. Focus explicitly moved by
82
- the listener is preserved.
83
-
84
- For a removable tag, `focus(options?)`, `blur()`, and `click()` delegate to its native remove
85
- button. A plain tag's `click()` retains native `HTMLElement.click()` behavior and dispatches one
86
- host `click`; its `focus()` has no delegated target. Setting `withRemove` / `removable` false
87
- revokes remove-button focus and activation synchronously before the outgoing button is rerendered,
88
- so same-task `click()` uses the plain host behavior instead of firing `lr-remove`. `blur()` remains
89
- available during that same-task window so it can release the stale focused button; after render
90
- there is no owner to blur.
91
-
92
- **Slots:** default (the label), `start` (content before the label, typically an icon) and `end`
93
- (content after it) — both new in 8.0.0. Each wrapper collapses entirely (`display: none`, so no
94
- stray gap) while its slot is empty, and is seeded from the light-DOM children before the first
95
- render so declarative content never flashes hidden for a frame. Mark purely decorative slotted
96
- content `aria-hidden`.
97
-
98
- **CSS parts:** `base` and `badge` are aliases on the same badge/tag surface; `start` and `end` (the slot wrappers, hidden entirely
99
- while empty), `content` (the wrapper around the default slot — this is the part that truncates with
100
- an ellipsis, deliberately not `base`, so the tag's oversized remove hit target can overhang the
101
- compact surface without being clipped), and `remove-button` (`lr-tag` only, rendered only while
102
- `withRemove` / `removable`). The button also carries Shoelace's `remove-button__base` alias, so
103
- either part name styles the same native button.
104
-
105
- **Themeable custom properties.** Three layers, so a consumer can retune one without restating the
106
- others. Public hooks are consumed through private use-site defaults instead of being redeclared on
107
- the host, so values set directly or inherited from a theme ancestor both win. The same contract
108
- reaches `lr-tag` unchanged.
109
-
110
- _Overrides_ — undeclared by default, so they still inherit from a consumer's own ancestor rule, and
111
- win over whatever `variant`/`appearance` resolved: `--lr-badge-background` (falls back to
112
- `--lr-badge-fill`), `--lr-badge-border` (falls back to `--lr-badge-stroke`), `--lr-badge-color`
113
- (falls back to `--lr-badge-text`).
114
-
115
- _Palette — what `variant` chooses_ (new in 8.0.0): `--lr-badge-tint` (private default
116
- `var(--lr-color-surface)`, the quiet fill; each non-neutral variant changes that private default to
117
- `var(--lr-color-fill-quiet)`, which the shared variants sheet has already re-pointed at that
118
- variant's row of the semantic grid), `--lr-badge-solid` (private default
119
- `var(--lr-color-fill-loud)`, the loud fill used by `appearance="accent"`), `--lr-badge-edge`
120
- (private default `var(--lr-color-border-subtle)`, the border color), `--lr-badge-ink` (private default
121
- `var(--lr-color-text)`, the text color) and
122
- `--lr-badge-on-solid` (default `var(--lr-color-on-loud)`, the text color that stays legible on
123
- `--lr-badge-solid`). An inherited or direct public palette value remains authoritative. Neutral is
124
- the only variant whose border and text colors differ, which is why `-edge` and `-ink` are separate
125
- slots rather than one loud color.
126
-
127
- _Surface — what `appearance` routes onto the box_ (new in 8.0.0): `--lr-badge-fill` (default
128
- `var(--lr-badge-tint)`), `--lr-badge-stroke` (default `var(--lr-badge-edge)`) and `--lr-badge-text`
129
- (default `var(--lr-badge-ink)`). Set one of these to retune a single appearance without touching the
130
- palette.
131
-
132
- _Density and shape:_ `--lr-badge-font-size` (default `var(--lr-font-size-sm)`),
133
- `--lr-badge-padding-inline` (default `var(--lr-space-s)`) and `--lr-badge-min-height` (default
134
- `var(--lr-size-1-25rem)`) — the trio each private effective-size rule rewrites to that step's font size,
135
- inline padding and minimum block size; the `m` defaults above exactly reproduce the pre-`size` fixed
136
- badge treatment. `--lr-badge-gap` (default `var(--lr-space-2xs)`, new in 8.0.0) is the space between
137
- the `start` slot, the label and the `end` slot — it collapses on its own when a wrapper is empty,
138
- because the empty wrapper is `display: none` rather than zero-width. `--lr-badge-radius` (default
139
- `var(--lr-radius)`; `pill` raises it to `var(--lr-radius-pill)`) is `[part='base']`'s corner radius,
140
- retunable without a `::part(base)` rule and, unlike the density trio, does not vary by `size` — the
141
- same `--lr-button-radius` pattern.
142
-
143
- _Attention_ (all new in 8.0.0): `--lr-badge-attention-duration` (default
144
- `var(--lr-duration-ambient)` — one cycle of the animation), `--lr-badge-attention-easing` (default
145
- `var(--lr-easing-emphasized)` — kept a separate token from the duration so the `animation` shorthand
146
- expands to exactly one timing function), `--lr-badge-pulse-color` (default
147
- `color-mix(in srgb, currentColor 40%, transparent)` — the expanding ring's color; upstream alias
148
- `--pulse-color`),
149
- `--lr-badge-pulse-spread` (default `var(--lr-size-0-25rem)` — how far the ring expands) and
150
- `--lr-badge-bounce-distance` (default `var(--lr-size-0-1875rem)` — the hop's peak travel).
151
-
152
- _`lr-tag`'s own two_ (new in 8.0.0): `--lr-tag-remove-radius` (default `var(--lr-badge-radius)`, so
153
- retuning the tag's corner retunes the remove button's with it) and
154
- `--lr-tag-remove-hover-background` (default `color-mix(in srgb, currentColor 16%, transparent)` —
155
- the remove button's `:hover` fill).
156
-
157
- **Known gotchas:**
158
-
159
- - The remove button's hit target meets the shared `--lr-icon-button-size` minimum in both axes while
160
- the visible glyph stays compact. Its full allocation participates in layout with no negative
161
- margins, so adjacent compact tags retain disjoint targets.
162
- - Its accessible name is computed from the default slot's own text ("Remove {label}", localized;
163
- bare "Remove" for a label-less tag) and re-derived live when that text changes. Text inside the
164
- decorative `start`/`end` slots never leaks into it. Visible accessible text, forwarding-slot
165
- reassignment and external assigned-node mutations stay synchronized; hidden/inert/CSS-hidden/
166
- `aria-hidden` branches are excluded. A host `aria-label`, including an explicit empty value,
167
- names a single aggregate `role="group"`; it is not copied to the nested action. The remove button
168
- retains its purpose-specific visible-label/localized-fallback name.
169
- - `appearance` and `variant` are orthogonal: `appearance="plain"` on `variant="danger"` still reads
170
- as danger, because the palette is chosen before the surface routing.
171
-
172
- ```html
173
- <lr-badge variant="success" appearance="accent" pill size="s">
174
- <svg slot="start" aria-hidden="true" width="12" height="12">
175
- <!-- icon -->
176
- </svg>
177
- Live
178
- </lr-badge>
179
-
180
- <lr-tag variant="brand" appearance="outlined" with-remove>Design</lr-tag>
181
- <script type="module">
182
- import "@aceshooting/lyra-ui/components/overlays/badge/badge.js";
183
- import "@aceshooting/lyra-ui/components/overlays/badge/tag.js";
184
-
185
- document.querySelector("lr-tag").addEventListener("lr-remove", (e) => {
186
- e.target.remove(); // in an app, update the backing collection instead
187
- });
188
- </script>
189
- ```
@@ -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** none
12
- - **Themeable via** 41 parts, 20 custom properties — see this component's own `@csspart`/`@cssprop` list below
12
+ - **Themeable via** 42 parts, 20 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
  ---
@@ -127,8 +127,11 @@ ancestor `--lr-positioning-strategy` still wins), and a trapped `fixed` menu ope
127
127
  outside the list, in the browser top layer where the native Popover API exists, in left-to-right
128
128
  and right-to-left documents, with no consumer CSS. A promoted menu whose trigger scrolls out of the
129
129
  list is hidden until the trigger returns. Where the Popover API is absent, the row holding an open
130
- `lr-dropdown` stops transforming while it is open, so its menu is still not clipped. Unset renders
131
- only the built-in
130
+ `lr-dropdown` stops transforming while it is open, so its menu is still not clipped. While such a
131
+ menu is open its row carries `row-item-base-menu-open` (see the parts below) and keeps its built-in
132
+ hover tint. Arrow, Home and End keys a returned control already handled (`lr-menu` moving between
133
+ its own items, a dropdown trigger opening its menu) stay with that control rather than also moving
134
+ focus to another row. Unset renders only the built-in
132
135
  `rowActions`.
133
136
  `renderStart?: (thread: LyraChatThread) => TemplateResult` (attribute: false) — renders non-interactive
134
137
  start-side content in each virtualized row. `renderExcerpt?: (thread: LyraChatThread) => TemplateResult`
@@ -211,10 +214,30 @@ reach callback-rendered descendants through these parts). `row-excerpt` wraps `r
211
214
  output, which is slotted into the row item's own `excerpt` slot.
212
215
 
213
216
  Data mode additionally forwards each row `<lr-conversation-item>`'s own parts under a `row-item-`
214
- prefix: `row-item-base`, `row-item-active-indicator`, `row-item-select-button`, `row-item-start`, `row-item-content`,
217
+ prefix: `row-item-base`, `row-item-base-menu-open`, `row-item-active-indicator`, `row-item-select-button`, `row-item-start`, `row-item-content`,
215
218
  `row-item-label`, `row-item-label-input`, `row-item-rename-button`, `row-item-excerpt`,
216
219
  `row-item-meta`, `row-item-timestamp`, `row-item-actions`.
217
220
 
221
+ **Row menu-open state:** `row-item-base-menu-open` is carried by `row-item-base` while a menu that
222
+ `renderActions` opened from that row (`lr-dropdown`, `lr-popover` or `lr-context-menu`) is open,
223
+ however it was opened. That menu sits in the browser top layer, where Chromium and WebKit stop
224
+ matching `:hover` and `:focus-within` on the row while the pointer or keyboard focus is inside it.
225
+ A menu trigger revealed on row hover or focus must key on this state too, or it hides while its own
226
+ menu is open — and a `display`-based reveal hides the menu with it, because an open menu is
227
+ concealed once its trigger stops being measurable. `::part()` cannot be followed by a descendant,
228
+ so carry the reveal to `row-actions` through an inherited custom property:
229
+
230
+ ```css
231
+ lr-thread-list::part(row-item-base):hover,
232
+ lr-thread-list::part(row-item-base):focus-within,
233
+ lr-thread-list::part(row-item-base-menu-open) {
234
+ --app-row-actions-opacity: 1;
235
+ }
236
+ lr-thread-list::part(row-actions) {
237
+ opacity: var(--app-row-actions-opacity, 0);
238
+ }
239
+ ```
240
+
218
241
  **Themeable excerpt highlights:** `<mark>` descendants returned by `renderExcerpt` use
219
242
  `--lr-thread-list-excerpt-highlight-background` (default `var(--lr-color-warning-quiet)`),
220
243
  `--lr-thread-list-excerpt-highlight-foreground` (default `inherit`),
@@ -9,124 +9,6 @@
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** none
12
- - **Themeable via** 11 parts, 8 custom properties — see this component's own `@csspart`/`@cssprop` list below
13
- - **Documented with** `lr-timeline` (same section below)
12
+ - **Themeable via** 11 parts, 8 custom properties — see `lr-timeline.md`
13
+ - **Documented with** `lr-timeline`: see [lr-timeline.md](./lr-timeline.md).
14
14
  - **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`
15
-
16
- ---
17
-
18
- ## `lr-timeline` and `lr-timeline-item`
19
-
20
- Read-only chronological sequence by default. `lr-timeline` is a `role="list"` flex container; each
21
- `lr-timeline-item` is a light-DOM child that sets `role="listitem"` on itself and renders its own
22
- marker plus the trailing rail segment reaching toward the next item's marker. The last item's rail is
23
- suppressed purely in CSS (`::slotted([role='listitem']:last-child)`) — no JS coordination anywhere.
24
- Items have no keyboard navigation or selection model: a passive record display, by design (an
25
- item's `title`/`description` routinely hold focusable content, so wrapping the row in `role="button"`
26
- would trip `nested-interactive`). The opt-in clustered time scale adds only native count-marker
27
- buttons; it does not make the individual rows interactive.
28
-
29
- Horizontal time layouts using `collision="overlap"` or `collision="stack"` allocate their block size
30
- from the actual item content and lane offsets. The height follows content growth, shrinkage, and
31
- changes in lane count. `--lr-timeline-time-extent` still controls only the main-axis distance, and
32
- horizontal scrolling retains clipping on the cross axis. Cluster mode keeps its existing sizing
33
- behavior.
34
-
35
- **`lr-timeline` properties:** `orientation: 'vertical' | 'horizontal' = 'vertical'` — note the
36
- opposite default from `lr-stepper`; `horizontal` makes `[part='base']` a horizontally scrollable row.
37
- `accessibleLabel?: string` (attribute `aria-label`) overrides the localized `"Timeline"` name —
38
- omitting it reads back `undefined` and falls back to that default, while an explicitly empty
39
- `aria-label` stays empty
40
- (the `role="list"` element is in the shadow root and never inherits a host attribute). Read-only
41
- `itemCount: number` is the live count of default-slot `<lr-timeline-item>` assignments (including
42
- flattened forwarding slots); unrelated slotted elements and text nodes are ignored.
43
- `scale: 'flow' | 'time' = 'flow'` (attribute `scale`, type `LyraTimelineScale`) chooses how items
44
- are distributed along the main axis. `'flow'` is the default even sequence, where `timestamp` is
45
- rendered as text but carries no positional meaning. `'time'` positions each item at its true
46
- proportion of the range, so a gap of weeks and a gap of decades stop looking identical. `'time'`
47
- needs a definite extent to distribute along — `--lr-timeline-time-extent` (default
48
- `var(--lr-size-20rem)`), applied as `block-size` when vertical and `inline-size` when horizontal —
49
- because items are absolutely positioned and a percentage against an auto-sized track resolves to
50
- zero. `collision: 'overlap' | 'stack' | 'cluster' = 'overlap'` (attribute `collision`, type
51
- `LyraTimelineCollision`) chooses what `scale="time"` does with items landing on nearly the same
52
- position: `'overlap'` leaves them stacked on one another, `'stack'` steps each colliding item one
53
- lane along the **cross** axis (indent per lane: `--lr-timeline-collision-offset`, default
54
- `var(--lr-space-l)`), and `'cluster'` replaces every group of at least two colliding items with one
55
- count marker. The group's first member in author order becomes its representative and renders the
56
- button in that item's existing list/Tab position; the remaining members are hidden, so visual,
57
- semantic, and keyboard order do not diverge merely because clustering is enabled. Stack mode and
58
- the cluster floor treat items within 1.5% of the axis as colliding.
59
- Cluster mode widens that floor to the rendered count action's footprint on the currently allocated
60
- axis, then reclusters when the allocation or rendered action size changes, so interactive marker
61
- hit areas do not overlap.
62
- Cluster windows are bounded from their first sorted position rather than transitively chaining every
63
- dense neighbour, so a large history becomes a useful sequence of markers rather than one axis-wide
64
- cluster. An isolated item remains an ordinary timeline item. Activating a count marker is a
65
- notification only; it never expands or selects items internally.
66
- `rangeStart` / `rangeEnd` (`Date | string | number`, attribute: false) pin the axis instead of
67
- deriving it from the earliest/latest item; a reversed or non-finite pair falls back to the derived
68
- range. An item with no parseable `timestamp` (including one supplied only through the `timestamp`
69
- slot, which carries no machine-readable instant) keeps document order and is spread evenly, so a
70
- partially-timestamped list degrades rather than stacking at the origin. Reassigning an item's
71
- `timestamp` reclusters without requiring a slot mutation. Positions are written to
72
- each child as a private `--_lr-timeline-item-offset` custom property and removed again on a switch
73
- back to `'flow'`. Cluster mode adds and removes a private visibility marker on non-representative
74
- members and temporarily changes only the representative item's shadow presentation; switching
75
- mode, shrinking the data, or disconnecting restores every ordinary row. If regrouping would remove
76
- the focused row content or count action, focus moves to the replacement cluster action, the first
77
- surviving item action, or the timeline list as a programmatic fallback.
78
-
79
- **`lr-timeline-item` properties:** `timestamp?: Date | string | number` (attribute: false — `Date`
80
- isn't attribute-serializable; invalid input normalizes to unset and renders no timestamp UI),
81
- `sync: boolean = false` (forwarded to the internal `<lr-relative-time>`; no effect when the
82
- `timestamp` slot is filled), `variant: 'neutral' | 'brand' | 'success' | 'warning' | 'danger' =
83
- 'neutral'` (marker tone), `active: boolean = false` (reflected — a static marker ring plus an
84
- optional pulse disabled under `prefers-reduced-motion: reduce`, with explicit `aria-current="true"`
85
- or `"false"` on the host).
86
-
87
- **Events:** `lr-timeline` emits `lr-cluster-activate` when a `collision="cluster"` marker is
88
- activated by pointer, Enter, or Space. Its non-cancelable, bubbling, composed
89
- `detail: LyraTimelineClusterActivateDetail` is `{ items: readonly LyraTimelineItem[] }`: a fresh
90
- frozen snapshot of the cluster members in document order, preserving each element's identity.
91
- `LyraTimelineClusterActivateDetail {
92
- items: readonly LyraTimelineItem[];
93
- }`
94
- Use it to open a consumer-owned popover, dialog, or detail view. `lr-timeline-item` emits no events.
95
- Read the reactive `itemCount` property after changing assigned items; the internal slot's
96
- non-composed `slotchange` event is not a host-level public signal.
97
-
98
- **Slots:** `lr-timeline`'s default slot holds the items, in display order. On an item the **default
99
- slot is the title** (there is no `title` slot), plus `marker-icon` (marker glyph override; an empty
100
- slot falls back to a color-coded dot), `timestamp` (wins outright over the
101
- `timestamp` property whenever it has assigned content), and `description` (its part is hidden
102
- entirely when empty).
103
-
104
- **CSS parts:** timeline `base` — the `role="list"` flex container (no separate `list` part). Item:
105
- `cluster` — the native count button rendered while that item represents a cluster, with a 40px
106
- minimum action surface; `cluster-count` — its painted count pill; `base`, `track`
107
- (marker + rail spine, always the opposite axis from `base`), `marker`
108
- (`aria-hidden="true"`, decorative), `rail` (the connecting segment; `visibility: hidden` rather than
109
- removed on the last item, so marker alignment stays consistent), `content`, `header` (flex row
110
- wrapping `title` and `timestamp`; wraps at narrow widths rather than truncating), `title`,
111
- `timestamp` (hidden when there's nothing to show), `description`.
112
-
113
- **Themeable custom properties:** `--lr-timeline-gap` (default `var(--lr-space-l)`) — declared on
114
- `lr-timeline` but consumed inside each item via inheritance across the slot boundary; it is both the
115
- inter-item spacing and the length each rail bridges. `--lr-timeline-cluster-size` (default
116
- `var(--lr-size-2rem)`) sizes the painted count pill, `--lr-timeline-cluster-bg` (default
117
- `var(--lr-color-brand)`) sets its background, and `--lr-timeline-cluster-color` (default
118
- `var(--lr-color-on-brand)`) sets its foreground. `--lr-scroll-fade-size` (default `2rem`) controls
119
- each horizontal-overflow edge fade; forced-colors mode removes the masks while retaining native
120
- scrolling. On the item: `--lr-timeline-marker-size`
121
- (default `var(--lr-size-1-25rem)`, both dimensions so the dot stays circular),
122
- `--lr-timeline-rail-width` (default `var(--lr-border-width-medium)`), `--lr-timeline-rail-color`
123
- (default `var(--lr-color-border-subtle)`), `--lr-timeline-marker-color` (default
124
- `var(--lr-color-text-quiet)`, with a private default that changes per `variant`), and
125
- `--lr-timeline-active-ring-color`
126
- (defaults to the effective marker color). All five item hooks inherit from theme
127
- ancestors; setting one directly on an item wins over both the inherited value and variant default.
128
-
129
- Version 9 removes the legacy item `icon` slot; migrate marker glyphs to `slot="marker-icon"`.
130
- Timeline orientation/rail coordination now uses private implementation-prefixed cross-shadow
131
- properties. The only supported spacing input remains `--lr-timeline-gap`; stop overriding the five
132
- former `--lr-timeline-item-*` plumbing names.
@@ -9,227 +9,6 @@
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** none
12
- - **Themeable via** 12 parts, 16 custom properties — see this component's own `@csspart`/`@cssprop` list below
13
- - **Documented with** `lr-toast` (same section below)
12
+ - **Themeable via** 12 parts, 16 custom properties — see `lr-toast.md`
13
+ - **Documented with** `lr-toast`: see [lr-toast.md](./lr-toast.md).
14
14
  - **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`
15
-
16
- ---
17
-
18
- ## `lr-toast` / `lr-toast-item` / `toast()`
19
-
20
- Stacking toast/notification region. Mirrors `<wa-toast>`/`<wa-toast-item>` under `lr-`.
21
-
22
- ### `lr-toast`
23
-
24
- A placement-specific region. The imperative helper maintains one region for each
25
- `ownerDocument` + `placement` pair; manually authored regions remain independent.
26
-
27
- **Properties:**
28
-
29
- - `placement: LyraToastPlacement = 'top-end'` (reflected) — one of `'top-start'|'top-center'|'top-end'|
30
- 'bottom-start'|'bottom-center'|'bottom-end'`. Every placement resolves inside one logical usable
31
- rectangle whose four edges are the greater of `--lr-space-l` and the matching safe-area token.
32
- Start/end follow direction, center placements use that rectangle's midpoint even when the inline
33
- safe-area insets are asymmetric, and an oversized stack is capped to its usable inline size.
34
-
35
- **Methods:** `create(options: LyraToastOptions): Promise<LyraToastItem>` is the canonical form;
36
- `create(message: string, options?: LyraToastCreateOptions)` remains as a compatibility overload.
37
- `LyraToastOptions` contains `message`, optional `placement`, `ownerDocument`, `variant`, `duration`,
38
- `size`, `withIcon`, `icon`, and `action`; `LyraToastCreateOptions` omits `message` and `placement`.
39
- `icon` accepts text, a DOM node, a Lit template, or a target-document factory returning one of
40
- those. Strings are always text, never HTML; cross-document nodes are imported into the region's
41
- document. `action` creates a native button from `{ label, onClick }`. The options' `ownerDocument`,
42
- and `placement`, when supplied directly to a region, must match that region. Calling `create()`
43
- while the region is detached rejects immediately instead of leaving a render-dependent promise pending. `size` accepts
44
- the canonical `2xs`/`xs`/`s`/`m`/`l`/`xl` values plus `small`/`medium`/`large`; either spelling is
45
- preserved by the created item's getter and reflected attribute.
46
-
47
- **Live members:** `stack: HTMLElement | null` returns the rendered `[part="stack"]` element, or
48
- `null` before the render root is populated. Its identity remains stable across ordinary updates and
49
- reconnection.
50
-
51
- The region keeps exactly three items active. Later items enter a hidden, inert FIFO queue capped at
52
- twenty; their show lifecycle and auto-dismiss timer do not start until promotion. Removing an active
53
- item promotes the oldest queued item. A visible standalone item moved into a full region is
54
- deactivated and timer-paused without replaying `lr-show`, then resumes from its remaining duration
55
- when promoted; its progress ring resumes at the same elapsed fraction as that JavaScript countdown.
56
- The visible stack is safe-area bounded and vertically scrollable, so all three active items and their
57
- controls remain keyboard-reachable even with long localized content.
58
-
59
- **Events:** `lr-toast-overflow` (noncancelable, `detail: { count: number }`) reports how many oldest
60
- queued items were discarded when admission exceeded the twenty-item queue. Losses in one synchronous
61
- burst coalesce into one event and one localized polite announcement; `create()` retains its existing
62
- promise/result contract.
63
-
64
- **Slots:** default (`<lr-toast-item>` children)
65
-
66
- **CSS parts:** `stack`
67
-
68
- **CSS custom states:** `visible` while at least one `lr-toast-item` is present in the region.
69
-
70
- **Themeable custom properties:** `--lr-toast-gap` (default `var(--lr-space-s)`),
71
- `--lr-toast-width` (default `var(--lr-size-28rem)`) — set directly on the `<lr-toast>` element.
72
- The mapped `--gap` and `--width` names are compatibility aliases for those two Lyra-prefixed
73
- properties; an explicitly set Lyra-prefixed property continues to take precedence.
74
- Every `<lr-toast-item>` property below is also documented on the region, because custom properties
75
- inherit into the items slotted inside it: one declaration on `<lr-toast>` retunes the whole stack.
76
-
77
- **Optional peer deps:** none.
78
-
79
- ### `lr-toast-item`
80
-
81
- A single notification.
82
-
83
- **Properties:**
84
-
85
- - `duration: number = 5000` (ms; `Infinity` or `<= 0` disables auto-dismiss)
86
- - `size: '2xs'|'xs'|'s'|'m'|'l'|'xl'|'small'|'medium'|'large' = 'm'` (reflected — drives both `--lr-toast-padding` and the
87
- toast's own font-size through a private effective-size mapping, from a compact `2xs` up to a roomier `xl`;
88
- valid property and attribute writes round-trip without changing spelling)
89
- - `variant: 'brand'|'success'|'warning'|'danger'|'neutral' = 'neutral'` (reflected)
90
- - `withIcon: boolean = false` (attribute `with-icon`)
91
-
92
- **Methods:** `async hide(): Promise<void>` — plays the hide animation, then removes itself from the
93
- DOM. `toastItemElement: HTMLElement | null` exposes the live `[part="toast-item"]` surface (or
94
- `null` before rendering) and remains the same node across ordinary updates/reconnection.
95
-
96
- **Events:** `lr-show`, `lr-after-show`, `lr-hide`, `lr-after-hide`. `lr-show` and `lr-hide` are the
97
- cancelable before-transition veto points. The item stays hidden and inert throughout `lr-show`;
98
- vetoing its initial request releases it from the region without an after-event or timer. Re-entering
99
- the same show/hide request from its own before-event coalesces onto that request, so the outer veto
100
- remains authoritative and the lifecycle event fires once. Vetoing an auto-dismiss expiry leaves the
101
- item visible and restarts the full current normalized `duration`; repeated vetoes retry at that same
102
- interval. Vetoing a manual `hide()` leaves any active countdown at its current elapsed position. An
103
- accepted show or hide interrupted by disconnection resumes after reconnection and emits its matching
104
- `lr-after-*` event exactly once; no terminal event fires while the item is detached.
105
-
106
- **Slots:** default (message), `icon`
107
-
108
- **CSS parts:** `toast-item`, `accent`, `icon`, `content`, `close-button`, `close-icon`,
109
- `close-icon__svg`, `progress-ring`, `progress-ring__base`, `progress-ring__indicator`,
110
- `progress-ring__label`, `progress-ring__track`. The progress-ring tree is rendered for a finite,
111
- positive auto-dismiss duration and surrounds the close glyph; its indicator pauses alongside the
112
- auto-dismiss timer on hover or focus.
113
-
114
- **Themeable custom properties:** `--lr-toast-accent-width` (default `var(--lr-size-4px)`),
115
- `--lr-toast-show-duration`/`--lr-toast-hide-duration`
116
- (`var(--lr-transition-base, 180ms ease-out)` — the show/hide lifecycle reads the resolved computed
117
- transition duration and uses it for its completion fallback), `--lr-toast-padding`
118
- (`var(--lr-space-m)`) and `--lr-toast-font-size` (`var(--lr-font-size-m)`) — their private defaults
119
- follow `size`, from a compact `2xs` up to a roomier `xl` — and `--lr-toast-accent-color` (default
120
- `var(--lr-color-border)`, with a private default that follows `variant` to that variant's loud
121
- fill). Inherited or direct public values remain authoritative across every size and variant.
122
-
123
- `--lr-toast-item-gap` (default `var(--lr-space-s)`) controls the gap between the item's icon,
124
- message, and close action; `--lr-toast-item-radius` (default `var(--lr-radius)`) controls the item
125
- surface and accent-bar start corners. They are deliberately separate from `--lr-toast-gap`, which
126
- continues to control only the region's stack spacing.
127
-
128
- The close button's four inherited state hooks are `--lr-toast-close-button-hover-bg` (default
129
- `transparent`), `--lr-toast-close-button-hover-color` (default `var(--lr-color-text)`),
130
- `--lr-toast-close-button-active-bg` (default `color-mix(in oklab, transparent,
131
- var(--lr-color-mix-partner) var(--lr-color-mix-active))`), and
132
- `--lr-toast-close-button-active-color` (default `var(--lr-color-text)`). Each is an inline fallback
133
- at the relevant state, so setting one on the item or an ancestor rethemes only that close-button
134
- state rather than the item surface, other close states, or the region stack.
135
-
136
- The mapped names `--accent-width`, `--show-duration`, `--hide-duration`, and `--padding` alias their
137
- respective Lyra-prefixed properties. Setting the Lyra-prefixed form explicitly wins over its alias.
138
-
139
- **Optional peer deps:** none.
140
-
141
- Once a non-vetoed toast starts showing, its normalized message is appended to Lyra's pre-mounted,
142
- shared light-DOM announcement sink: assertive for `danger`/`warning`, polite otherwise. Changing a
143
- visible toast between those urgency levels announces that message at the new urgency. The visible
144
- item and stack themselves remain ordinary content, so an icon, action, and close button never become
145
- part of an atomic live announcement. Auto-dismiss timer **pauses** on `pointerenter`/`focusin`, **resumes**
146
- on `pointerleave`/`focusout`, with real elapsed-time bookkeeping (WCAG 2.2.1 timing-adjustable) —
147
- hover and focus are tracked as independent pause reasons, so releasing only one (e.g. the pointer
148
- leaves while focus remains, or vice versa) keeps the timer paused until _neither_ holds it anymore.
149
- A `duration` change while the timer is actively counting down reschedules it immediately against
150
- the new value instead of waiting for the next pause/resume cycle. A vetoed timer expiry restarts
151
- that full normalized value; if hover/focus or a disconnect begins during the veto event, the retry
152
- stays paused and starts from the full value only after the item resumes/reconnects.
153
- Accessible message extraction follows same-root `aria-labelledby` references and observes their
154
- targets, lookup roots, and every open shadow root actually traversed for text, including targets
155
- outside the toast subtree. Traversal is bounded; when a ceiling is reached, the announcement carries
156
- an explicit ellipsis and the close action uses the localized truncated-context template instead of
157
- silently treating the bounded prefix as whole. If no prefix fits before a ceiling, both surfaces use
158
- the localized `toastContentIncomplete` fallback so the missing content remains explicit.
159
-
160
- ### `toast()`
161
-
162
- From the `toaster` controller — the ergonomic entry point, no manual `<lr-toast>` mounting
163
- needed:
164
-
165
- ```ts
166
- import { toast } from "@aceshooting/lyra-ui/components/overlays/toast/toaster.js";
167
-
168
- toast("Saved");
169
- toast({
170
- message: "Deleted",
171
- variant: "danger",
172
- icon: (ownerDocument) => ownerDocument.createTextNode("!"),
173
- action: {
174
- label: "Undo",
175
- onClick: (item) => {
176
- /*...*/
177
- },
178
- },
179
- });
180
- ```
181
-
182
- `toast(input: LyraToastOptions | string): ToastHandle`, where
183
- `ToastHandle = { item: Promise<LyraToastItem>; dismiss: () => void }`. The canonical options are
184
- shared byte-for-byte with the region's object-form `create()`, including `ownerDocument`, safe icon
185
- payloads/factories, actions, and the long `small`/`medium`/`large` size aliases. It lazily mounts
186
- (and re-mounts if removed) **one singleton `<lr-toast>` region per distinct `ownerDocument` and
187
- `placement`** on that document's body — a call targeting one placement/document never relocates
188
- toasts already showing in another. A foreign document must have the toast elements registered in
189
- its own custom-element registry; otherwise the returned `item` promise rejects explicitly.
190
-
191
- ```html
192
- <script type="module">
193
- import { toast } from "@aceshooting/lyra-ui/components/overlays/toast/toaster.js";
194
- document
195
- .getElementById("save-btn")
196
- .addEventListener("click", () => toast("Saved!"));
197
- </script>
198
- ```
199
-
200
- **Known gotchas:**
201
-
202
- - the stack and each visible item have no live-region role. Their normalized message is appended as
203
- one child of a shared non-atomic light-DOM sink at the variant's urgency; icon, action, and close
204
- controls remain outside that sink. Later meaningful message changes add only the changed normalized
205
- message, and appending an action does not re-announce it.
206
- - the close button's accessible name is derived from the toast's own message text (the first 40
207
- grapheme clusters when it must be shortened, falling back to bare `"Close"` only when the toast
208
- has no text content and extraction completed) rather than a bare `"Close"` on every instance — useful when several toasts
209
- are stacked and a screen-reader or switch-access user needs to tell their close buttons apart
210
- without activating one first. On a legacy engine without `Intl.Segmenter`, it retains the whole
211
- label rather than splitting a grapheme. The localized `closeWithTruncatedContext` template owns
212
- truncation punctuation and word order. Rich non-interactive message markup contributes its text,
213
- named-slot/icon and actionable content do not, and live message text mutations or reassignment
214
- update the name through nested forwarding slots. Hidden, inert, CSS-hidden and `aria-hidden`
215
- message branches are excluded. Same-root external `aria-labelledby` targets and the open shadow
216
- roots traversed for their text remain synchronized across reconnect, replacement, and adoption.
217
- A bounded traversal prefix is explicitly marked as incomplete; if no prefix is available, the
218
- localized `toastContentIncomplete` fallback keeps both the announcement and close name truthful.
219
- Observation, animation frames, elapsed-time clocks and completion/auto-dismiss timers follow the
220
- item's owner window after iframe adoption and cancel through the same window that scheduled them.
221
- - pause/resume-on-hover/focus (the component's main accessibility differentiator), including the
222
- independent-hover-vs-focus pause reasons above, now has regression test coverage.
223
- - `hide()` is idempotent (a second call while already hiding is a no-op) and `[part="close-button"]`
224
- gets `aria-disabled="true"` once hiding starts, so a stray extra click/Enter during the hide
225
- animation can't re-enter it. A disconnect during that animation pauses completion; reconnecting
226
- the same item resumes it and emits/removes exactly once.
227
- - When the focused close/action control's toast finishes hiding, focus moves to an adjacent toast's
228
- close control, or back to the connected element that held focus before the toast when no adjacent
229
- item remains.
230
- - Prefer the `toast()` helper over manually creating `<lr-toast>`/`<lr-toast-item>` — it already
231
- handles the singleton-region and remount-if-removed logic. The helper and `lr-alert.toast()` never
232
- fall back to an unbounded unknown region in an owner document where the controller is unregistered;
233
- unavailable alert requests are removed and their existing `Promise<void>` settles.
234
-
235
- ---
@@ -31,11 +31,19 @@ progress, and `No data` only for a terminal status.
31
31
  **Properties:**
32
32
 
33
33
  - `name: string = ''` — tool name; an empty name renders the localized generic `Tool call` label
34
+ - `displayName?: string` (attribute `display-name`, 21.1.0) — the application's own,
35
+ already-translated label for the tool. It replaces `name` inside the localized header verb only
36
+ (`Used Lecture d’un fichier`), so the status wording stays localized; `name` still selects the
37
+ result renderer and is still reported in `lr-render-error`. Unset or empty shows `name`; a
38
+ `label` override replaces the whole header, this included
34
39
  - `callId: string = ''` (attribute `call-id`) — invocation id echoed in `lr-toggle` and
35
40
  `lr-render-error` details
36
41
  - `status: ToolCallStatus = 'pending'` (reflected, including the default) —
37
- `'pending'|'running'|'success'|'error'|'denied'`; selects the header verb, glyph and accent.
38
- Values outside the set normalize and reflect as `pending`
42
+ `'pending'|'running'|'success'|'error'|'denied'|'incomplete'`; selects the header verb, glyph
43
+ and accent. `incomplete` (21.1.0) is a call that ended without a result (an interrupted stream, a
44
+ cancelled run): it reads `Did not finish using {name}` (`toolCallBlockHeaderIncomplete`), or
45
+ `Incomplete` (`statusIncomplete`) in `status-text` beside a `label`, with a static glyph and the
46
+ neutral accent. Values outside the set normalize and reflect as `pending`
39
47
  - `expanded: boolean = false` (reflected) — whether the details are shown
40
48
  - `label?: string` — header override, used verbatim (including `''`); when set, the localized
41
49
  status text renders beside it in `status-text`. Unset renders the localized status verb
@@ -86,7 +94,8 @@ set), `duration` (only while finite), `body` (the disclosed region), `args`, `ar
86
94
  header/body divider
87
95
  - `--lr-tool-call-block-radius` (default `var(--lr-radius)`) — card radius
88
96
  - `--lr-tool-call-block-accent` — status glyph colour; its private default follows `status`
89
- (`--lr-color-text-quiet`, then brand while running, success, danger on error, warning when denied)
97
+ (`--lr-color-text-quiet` while pending or incomplete, then brand while running, success, danger
98
+ on error, warning when denied)
90
99
  - `--lr-tool-call-block-error-color` (default `var(--lr-color-danger)`) — error section text
91
100
 
92
101
  The running glyph spins and the pending glyph pulses at `--lr-transition-ambient`; both stop under