@aceshooting/lyra-ui 16.0.0 → 17.0.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 (296) hide show
  1. package/CHANGELOG.md +504 -0
  2. package/custom-elements.json +1 -1
  3. package/dist/cli/migration-contract.json +1 -1
  4. package/dist/components/agent-tools/browser-frame/browser-frame.class.d.ts +3 -3
  5. package/dist/components/agent-tools/browser-frame/browser-frame.class.js +2 -2
  6. package/dist/components/agent-tools/compare-panel/compare-panel.class.d.ts +2 -2
  7. package/dist/components/agent-tools/compare-panel/compare-panel.class.js +3 -3
  8. package/dist/components/agent-tools/confirm-bar/confirm-bar.class.d.ts +37 -13
  9. package/dist/components/agent-tools/confirm-bar/confirm-bar.class.js +2 -2
  10. package/dist/components/agent-tools/task-list/task-list.class.js +2 -2
  11. package/dist/components/agent-tools/tool-call-chip/tool-call-chip.class.d.ts +4 -0
  12. package/dist/components/agent-tools/tool-call-chip/tool-call-chip.class.js +2 -2
  13. package/dist/components/agent-tools/tool-param-form/tool-param-form.class.d.ts +3 -3
  14. package/dist/components/agent-tools/tool-param-form/tool-param-form.class.js +1 -1
  15. package/dist/components/charts/chart/chart.class.d.ts +117 -17
  16. package/dist/components/charts/chart/chart.class.js +3 -3
  17. package/dist/components/charts/chart/histogram-bin.d.ts +5 -1
  18. package/dist/components/charts/chart/histogram-bin.js +1 -1
  19. package/dist/components/charts/chart/lite-chart.class.d.ts +9 -0
  20. package/dist/components/conversation/code-block/code-block.styles.js +1 -1
  21. package/dist/components/conversation/message-actions/message-actions.styles.js +1 -1
  22. package/dist/components/conversation/model-select/model-select.class.d.ts +13 -4
  23. package/dist/components/conversation/model-select/model-select.class.js +2 -1
  24. package/dist/components/conversation/model-select/model-select.styles.js +1 -1
  25. package/dist/components/conversation/streaming-text/streaming-text-base.class.d.ts +40 -2
  26. package/dist/components/conversation/streaming-text/streaming-text-base.class.js +2 -2
  27. package/dist/components/conversation/streaming-text/streaming-text-core.class.d.ts +5 -3
  28. package/dist/components/conversation/streaming-text/streaming-text-core.class.js +10 -0
  29. package/dist/components/conversation/streaming-text/streaming-text.class.d.ts +9 -3
  30. package/dist/components/conversation/streaming-text/streaming-text.class.js +10 -0
  31. package/dist/components/conversation/suggestion-chips/suggestion-chips.class.d.ts +30 -2
  32. package/dist/components/conversation/suggestion-chips/suggestion-chips.class.js +4 -3
  33. package/dist/components/conversation/suggestion-chips/suggestion-chips.styles.js +1 -1
  34. package/dist/components/conversation/transcript-feed/transcript-feed.class.js +1 -1
  35. package/dist/components/conversation/usage-badge/usage-badge-overlay-runtime.js +1 -1
  36. package/dist/components/conversation/usage-badge/usage-badge.class.d.ts +4 -0
  37. package/dist/components/conversation/voice-picker/voice-picker.class.d.ts +16 -4
  38. package/dist/components/conversation/voice-picker/voice-picker.class.js +2 -1
  39. package/dist/components/conversation/voice-picker/voice-picker.styles.js +1 -1
  40. package/dist/components/data/context-meter/context-meter.class.d.ts +23 -4
  41. package/dist/components/data/context-meter/context-meter.class.js +10 -7
  42. package/dist/components/data/context-meter/context-meter.styles.js +1 -1
  43. package/dist/components/data/data-grid/data-grid.class.d.ts +5 -2
  44. package/dist/components/data/data-grid/data-grid.class.js +1 -1
  45. package/dist/components/data/flow-canvas/flow-canvas.class.d.ts +32 -5
  46. package/dist/components/data/flow-canvas/flow-canvas.class.js +3 -1
  47. package/dist/components/data/flow-canvas/flow-canvas.styles.js +1 -1
  48. package/dist/components/data/flow-canvas/flow-model.js +1 -1
  49. package/dist/components/data/flow-canvas/flow-types.d.ts +10 -1
  50. package/dist/components/data/gauge/gauge.class.d.ts +15 -2
  51. package/dist/components/data/gauge/gauge.class.js +20 -20
  52. package/dist/components/data/gauge/gauge.styles.js +1 -1
  53. package/dist/components/data/graph-query-builder/graph-query-builder.class.d.ts +14 -5
  54. package/dist/components/data/graph-query-builder/graph-query-builder.class.js +2 -2
  55. package/dist/components/data/sequence-strip/sequence-strip.class.d.ts +28 -2
  56. package/dist/components/data/sequence-strip/sequence-strip.class.js +3 -2
  57. package/dist/components/data/sequence-strip/sequence-strip.styles.js +1 -1
  58. package/dist/components/data/table/table.class.d.ts +155 -30
  59. package/dist/components/data/table/table.class.js +6 -4
  60. package/dist/components/data/table/table.styles.js +1 -1
  61. package/dist/components/data/timeline/timeline-item.class.d.ts +9 -1
  62. package/dist/components/data/timeline/timeline-item.class.js +2 -2
  63. package/dist/components/data/word-cloud/word-cloud.class.js +1 -1
  64. package/dist/components/data/word-cloud/word-cloud.styles.js +1 -1
  65. package/dist/components/forms/button/button.class.d.ts +30 -1
  66. package/dist/components/forms/button/button.class.js +2 -2
  67. package/dist/components/forms/checkbox/checkbox.class.d.ts +8 -6
  68. package/dist/components/forms/checkbox/checkbox.class.js +2 -2
  69. package/dist/components/forms/checkbox-group/checkbox-group.class.d.ts +7 -5
  70. package/dist/components/forms/checkbox-group/checkbox-group.class.js +1 -1
  71. package/dist/components/forms/color-picker/color-picker.class.d.ts +16 -2
  72. package/dist/components/forms/color-picker/color-picker.class.js +2 -2
  73. package/dist/components/forms/color-picker/color-picker.styles.js +1 -1
  74. package/dist/components/forms/combobox/combobox.class.d.ts +43 -8
  75. package/dist/components/forms/combobox/combobox.class.js +2 -2
  76. package/dist/components/forms/date-picker/date-input.class.d.ts +4 -0
  77. package/dist/components/forms/date-picker/date-input.class.js +1 -1
  78. package/dist/components/forms/icon-button/icon-button.class.d.ts +20 -3
  79. package/dist/components/forms/icon-button/icon-button.class.js +1 -1
  80. package/dist/components/forms/icon-button/icon-button.styles.js +1 -1
  81. package/dist/components/forms/input/input.class.d.ts +5 -2
  82. package/dist/components/forms/input/input.class.js +1 -1
  83. package/dist/components/forms/input/time-input.class.d.ts +4 -0
  84. package/dist/components/forms/input/time-input.class.js +1 -1
  85. package/dist/components/forms/locale-picker/locale-picker.class.d.ts +11 -5
  86. package/dist/components/forms/locale-picker/locale-picker.class.js +1 -1
  87. package/dist/components/forms/otp-input/otp-input.class.d.ts +7 -2
  88. package/dist/components/forms/otp-input/otp-input.class.js +2 -2
  89. package/dist/components/forms/radio/radio-button.class.d.ts +2 -1
  90. package/dist/components/forms/radio/radio-group.class.d.ts +9 -4
  91. package/dist/components/forms/radio/radio-group.class.js +1 -1
  92. package/dist/components/forms/radio/radio.class.d.ts +13 -7
  93. package/dist/components/forms/radio/radio.class.js +1 -1
  94. package/dist/components/forms/rubric-form/rubric-form.class.d.ts +16 -6
  95. package/dist/components/forms/rubric-form/rubric-form.class.js +2 -2
  96. package/dist/components/forms/select/select.class.d.ts +19 -8
  97. package/dist/components/forms/select/select.class.js +2 -2
  98. package/dist/components/forms/slider/slider.class.d.ts +4 -2
  99. package/dist/components/forms/slider/slider.class.js +1 -1
  100. package/dist/components/forms/switch/switch.class.d.ts +8 -6
  101. package/dist/components/forms/switch/switch.class.js +1 -1
  102. package/dist/components/forms/textarea/textarea.class.d.ts +5 -3
  103. package/dist/components/forms/textarea/textarea.class.js +1 -1
  104. package/dist/components/forms/time-range/time-range.class.d.ts +12 -7
  105. package/dist/components/forms/time-range/time-range.class.js +1 -1
  106. package/dist/components/forms/time-range/time-range.styles.js +1 -1
  107. package/dist/components/forms/token-input/token-input.class.d.ts +6 -4
  108. package/dist/components/forms/token-input/token-input.class.js +1 -1
  109. package/dist/components/layout/app-rail/app-rail-item.class.d.ts +109 -4
  110. package/dist/components/layout/app-rail/app-rail-item.class.js +34 -29
  111. package/dist/components/layout/app-rail/app-rail-item.styles.js +1 -1
  112. package/dist/components/layout/app-rail/app-rail.class.d.ts +25 -3
  113. package/dist/components/layout/app-rail/app-rail.styles.js +1 -1
  114. package/dist/components/layout/app-rail-group/app-rail-group.class.d.ts +2 -2
  115. package/dist/components/layout/app-rail-group/app-rail-group.class.js +2 -2
  116. package/dist/components/layout/carousel/carousel.class.d.ts +1 -1
  117. package/dist/components/layout/carousel/carousel.class.js +1 -1
  118. package/dist/components/layout/details/accordion.class.d.ts +2 -2
  119. package/dist/components/layout/details/accordion.class.js +2 -2
  120. package/dist/components/layout/filter-bar/filter-bar-register.d.ts +1 -0
  121. package/dist/components/layout/filter-bar/filter-bar-register.js +1 -0
  122. package/dist/components/layout/filter-bar/filter-bar.class.d.ts +85 -10
  123. package/dist/components/layout/filter-bar/filter-bar.class.js +7 -4
  124. package/dist/components/layout/menu/menu-item.class.d.ts +3 -3
  125. package/dist/components/layout/menu/menu-item.class.js +3 -3
  126. package/dist/components/layout/menu/menu.class.d.ts +5 -1
  127. package/dist/components/layout/menu/menu.class.js +2 -2
  128. package/dist/components/layout/reorder-list/reorder-item.styles.js +1 -1
  129. package/dist/components/layout/virtual-list/virtual-list.class.js +1 -1
  130. package/dist/components/media/attachment-trigger/attachment-trigger.styles.js +1 -1
  131. package/dist/components/media/avatar-group/avatar-group.class.d.ts +12 -1
  132. package/dist/components/media/avatar-group/avatar-group.class.js +2 -2
  133. package/dist/components/media/drop-zone/drop-zone.class.d.ts +32 -11
  134. package/dist/components/media/drop-zone/drop-zone.class.js +2 -2
  135. package/dist/components/media/file-input/file-input.class.d.ts +40 -19
  136. package/dist/components/media/file-input/file-input.class.js +2 -2
  137. package/dist/components/overlays/callout/callout.styles.js +1 -1
  138. package/dist/components/overlays/dialog/dialog.styles.js +1 -1
  139. package/dist/components/overlays/overlay/dropdown.class.d.ts +13 -3
  140. package/dist/components/overlays/overlay/dropdown.class.js +2 -2
  141. package/dist/components/overlays/overlay/popover.class.d.ts +12 -3
  142. package/dist/components/overlays/overlay/popover.class.js +2 -2
  143. package/dist/components/overlays/rating/rating.class.d.ts +9 -7
  144. package/dist/components/overlays/rating/rating.class.js +1 -1
  145. package/dist/components/retrieval/citation-badge/citation-badge.class.d.ts +5 -1
  146. package/dist/components/retrieval/citation-badge/citation-badge.class.js +1 -1
  147. package/dist/components/retrieval/embedding-explorer/embedding-explorer.styles.js +1 -1
  148. package/dist/components/retrieval/entity-chip/entity-chip.class.d.ts +5 -1
  149. package/dist/components/retrieval/entity-chip/entity-chip.class.js +1 -1
  150. package/dist/components/retrieval/graph-legend/graph-legend.styles.js +1 -1
  151. package/dist/components/retrieval/retrieval-value-format.js +1 -1
  152. package/dist/components/retrieval/source-list/source-list.styles.js +1 -1
  153. package/dist/components/utility/copy-button/copy-button.class.d.ts +23 -11
  154. package/dist/components/utility/copy-button/copy-button.class.js +2 -2
  155. package/dist/components/utility/copy-button/copy-button.styles.js +1 -1
  156. package/dist/components/utility/diff-view/diff-view.styles.js +1 -1
  157. package/dist/components/utility/export-button/export-button.class.d.ts +4 -0
  158. package/dist/components/utility/export-button/export-button.class.js +1 -1
  159. package/dist/components/utility/json-viewer/json-viewer.styles.js +1 -1
  160. package/dist/components/utility/known-date/known-date.class.js +1 -1
  161. package/dist/components/utility/mention-popover/mention-popover.class.d.ts +38 -3
  162. package/dist/components/utility/mention-popover/mention-popover.class.js +2 -1
  163. package/dist/components/utility/mention-popover/mention-popover.styles.js +1 -1
  164. package/dist/components/utility/poll-status/poll-status.styles.js +1 -1
  165. package/dist/components/utility/tour/tour.class.d.ts +4 -0
  166. package/dist/components/utility/tour/tour.class.js +1 -1
  167. package/dist/components/utility/tour/tour.styles.js +1 -1
  168. package/dist/components/viewers/document-preview/document-preview.class.js +2 -2
  169. package/dist/components/viewers/docx-viewer/docx-viewer.class.js +2 -2
  170. package/dist/components/viewers/ebook-viewer/ebook-viewer.class.js +2 -2
  171. package/dist/components/viewers/highlight-layer/highlight-layer.class.js +2 -2
  172. package/dist/components/viewers/notebook-viewer/notebook-viewer.class.js +2 -2
  173. package/dist/components/viewers/pdf-viewer/pdf-viewer.class.js +2 -2
  174. package/dist/components/viewers/pptx-viewer/pptx-viewer.class.js +2 -2
  175. package/dist/components/viewers/xml-viewer/xml-viewer.class.js +2 -2
  176. package/dist/custom-elements-jsx.d.ts +2 -2
  177. package/dist/events.d.ts +13 -12
  178. package/dist/internal/aggregate-file-limits.d.ts +33 -0
  179. package/dist/internal/aggregate-file-limits.js +1 -0
  180. package/dist/internal/catalog-picker.d.ts +15 -2
  181. package/dist/internal/catalog-picker.js +1 -1
  182. package/dist/internal/debounce-controller.d.ts +14 -0
  183. package/dist/internal/debounce-controller.js +1 -1
  184. package/dist/internal/default-strings.generated.d.ts +1 -1
  185. package/dist/internal/default-strings.generated.js +2 -2
  186. package/dist/internal/focus-navigation.d.ts +45 -0
  187. package/dist/internal/focus-navigation.js +1 -1
  188. package/dist/internal/form-associated.js +1 -1
  189. package/dist/internal/initial-slot-collection.d.ts +30 -0
  190. package/dist/internal/initial-slot-collection.js +1 -0
  191. package/dist/internal/intl-cache.js +1 -1
  192. package/dist/internal/invalid-event-alias.d.ts +46 -0
  193. package/dist/internal/invalid-event-alias.js +1 -1
  194. package/dist/internal/localization-runtime.d.ts +24 -0
  195. package/dist/internal/localization-runtime.js +1 -1
  196. package/dist/internal/localization-types.d.ts +1 -1
  197. package/dist/internal/localization.js +1 -1
  198. package/dist/internal/package-metadata.d.ts +1 -1
  199. package/dist/internal/package-metadata.js +1 -1
  200. package/dist/internal/positioning-strategy.d.ts +3 -1
  201. package/dist/internal/state-part.d.ts +49 -0
  202. package/dist/internal/state-part.js +1 -0
  203. package/dist/internal/variants.styles.js +1 -1
  204. package/dist/lyra.d.ts +1 -1
  205. package/dist/svelte.d.ts +2 -2
  206. package/dist/testing/index.d.ts +1 -1
  207. package/dist/testing/index.js +1 -1
  208. package/dist/testing/lyra-tag-event-map.d.ts +2 -2
  209. package/dist/testing/lyra-tag-event-map.js +1 -1
  210. package/dist/testing/wait-for-mount.d.ts +46 -0
  211. package/dist/testing/wait-for-mount.js +1 -0
  212. package/dist/theme/theme-bootstrap.js +1 -1
  213. package/dist/theme/theme.d.ts +11 -2
  214. package/dist/theme/theme.js +1 -1
  215. package/dist/translations/ar/layout.js +1 -1
  216. package/dist/translations/de/layout.js +1 -1
  217. package/dist/translations/es/layout.js +1 -1
  218. package/dist/translations/fa/layout.js +1 -1
  219. package/dist/translations/fr/layout.js +1 -1
  220. package/dist/translations/he/layout.js +1 -1
  221. package/dist/translations/it/layout.js +1 -1
  222. package/dist/translations/ja/layout.js +1 -1
  223. package/dist/translations/pt-BR/layout.js +1 -1
  224. package/dist/translations/ru/layout.js +1 -1
  225. package/dist/translations/zh-CN/layout.js +1 -1
  226. package/dist/utilities/format.d.ts +17 -0
  227. package/dist/utilities/format.js +1 -1
  228. package/dist/vue.d.ts +2 -2
  229. package/llms/components/lr-app-rail-group.md +87 -10
  230. package/llms/components/lr-app-rail-item.md +88 -11
  231. package/llms/components/lr-app-rail.md +88 -11
  232. package/llms/components/lr-attachment-trigger.md +21 -0
  233. package/llms/components/lr-bar-chart.md +3 -2
  234. package/llms/components/lr-bubble-chart.md +3 -2
  235. package/llms/components/lr-callout.md +10 -0
  236. package/llms/components/lr-chart.md +43 -12
  237. package/llms/components/lr-citation-badge.md +7 -1
  238. package/llms/components/lr-code-block.md +21 -0
  239. package/llms/components/lr-color-picker.md +12 -7
  240. package/llms/components/lr-combobox.md +13 -1
  241. package/llms/components/lr-confirm-bar.md +36 -7
  242. package/llms/components/lr-context-meter.md +17 -4
  243. package/llms/components/lr-date-input.md +7 -1
  244. package/llms/components/lr-date-picker.md +6 -0
  245. package/llms/components/lr-dialog.md +21 -0
  246. package/llms/components/lr-doughnut-chart.md +3 -2
  247. package/llms/components/lr-drawer.md +10 -0
  248. package/llms/components/lr-drop-zone.md +16 -7
  249. package/llms/components/lr-dropdown-item.md +7 -0
  250. package/llms/components/lr-entity-chip.md +7 -1
  251. package/llms/components/lr-export-button.md +7 -1
  252. package/llms/components/lr-file-input.md +21 -10
  253. package/llms/components/lr-filter-bar.md +91 -15
  254. package/llms/components/lr-flow-canvas.md +16 -9
  255. package/llms/components/lr-gauge.md +22 -2
  256. package/llms/components/lr-histogram.md +7 -2
  257. package/llms/components/lr-icon-button.md +15 -7
  258. package/llms/components/lr-input.md +3 -1
  259. package/llms/components/lr-line-chart.md +3 -2
  260. package/llms/components/lr-lite-chart.md +13 -0
  261. package/llms/components/lr-locale-picker.md +7 -1
  262. package/llms/components/lr-mention-popover.md +16 -3
  263. package/llms/components/lr-menu-item.md +7 -0
  264. package/llms/components/lr-menu.md +8 -1
  265. package/llms/components/lr-message-actions.md +10 -0
  266. package/llms/components/lr-model-select.md +8 -3
  267. package/llms/components/lr-native-time-input.md +8 -1
  268. package/llms/components/lr-number-input.md +8 -1
  269. package/llms/components/lr-option.md +12 -0
  270. package/llms/components/lr-otp-input.md +6 -0
  271. package/llms/components/lr-pie-chart.md +3 -2
  272. package/llms/components/lr-polar-area-chart.md +3 -2
  273. package/llms/components/lr-prompt-input.md +2 -2
  274. package/llms/components/lr-radar-chart.md +3 -2
  275. package/llms/components/lr-reorder-item.md +12 -0
  276. package/llms/components/lr-reorder-list.md +12 -0
  277. package/llms/components/lr-scatter-chart.md +3 -2
  278. package/llms/components/lr-sequence-strip.md +10 -4
  279. package/llms/components/lr-streaming-text-core.md +21 -8
  280. package/llms/components/lr-streaming-text.md +34 -4
  281. package/llms/components/lr-suggestion-chips.md +8 -4
  282. package/llms/components/lr-table.md +47 -10
  283. package/llms/components/lr-textarea.md +1 -1
  284. package/llms/components/lr-time-input.md +7 -1
  285. package/llms/components/lr-tool-call-chip.md +7 -1
  286. package/llms/components/lr-tour.md +7 -1
  287. package/llms/components/lr-usage-badge.md +7 -1
  288. package/llms/components/lr-voice-picker.md +7 -3
  289. package/llms/shared.md +169 -16
  290. package/llms/tokens.md +17 -1
  291. package/llms-full.txt +941 -147
  292. package/package.json +16 -2
  293. package/registrations.json +1 -1
  294. package/vscode-css-data.json +1 -1
  295. package/vscode-html-data.json +1 -1
  296. package/web-types.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,500 @@
1
1
  # Changelog
2
2
 
3
+ ## 17.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - a0507c3: Release the accumulated Lyra UI API, metadata, compatibility, and accessibility corrections as
8
+ `17.0.0`. This release includes the common-issue cleanup pass across form controls, overlays, data
9
+ and retrieval components, viewers, shared tokens, localization, RTL behavior, generated contracts,
10
+ and package-size tooling.
11
+
12
+ ### Minor Changes
13
+
14
+ - e7d8187: `<lr-app-rail>`'s `[part="panel"]` gains four direction-aware per-corner radius tokens
15
+ (`--lr-app-rail-panel-radius-start-start`/`-start-end`/`-end-start`/`-end-end`), each defaulting to
16
+ the existing uniform `--lr-app-rail-panel-radius` so an unset override still rounds all four
17
+ corners exactly as before. Because the mobile drawer is always flush against its own logical
18
+ inline-start edge, the two `-end` corner tokens are the ones a flush-against-one-edge drawer
19
+ typically rounds, and both mirror to the opposite physical side under `dir="rtl"` with no second
20
+ consumer rule. `[part="nav"]` gains `--lr-app-rail-nav-padding` and `--lr-app-rail-nav-gap`,
21
+ defaulting to the values that rule previously hard-coded. `<lr-app-rail-item>`'s icon-only square
22
+ gains `--lr-app-rail-item-icon-only-size`, which — when set — sizes `[part="base"]`'s icon-only
23
+ square (and its `min-block-size` floor) directly, independent of
24
+ `--lr-app-rail-item-min-block-size`, so a taller expanded row and an icon-only square pinned to
25
+ `--lr-icon-button-size` can coexist. Unset, all three continue to reproduce their prior rendering
26
+ exactly.
27
+ - e7d8187: `<lr-app-rail-item>`'s `[part="current-indicator"]` full-height edge bar now suppresses itself by
28
+ default in the `icon-only` presentation, where it previously painted a broken-looking bar across a
29
+ square icon tile. `--lr-app-rail-item-current-indicator-display` restores it per instance. A new
30
+ `--lr-app-rail-item-current-ring` token adds an inset ring on the icon-only current tile by
31
+ default — a non-color-only signal (WCAG 1.4.1) that replaces the suppressed bar there — while
32
+ leaving the full presentation, which already conveys current state through the bar and
33
+ `--lr-app-rail-item-current-font-weight`, ring-free by default. Setting the ring token explicitly
34
+ applies the same value in both presentations. Full presentation is otherwise byte-identical to
35
+ before.
36
+ - fa5c976: `<lr-app-rail-item>` gains its own expandable child list — the treeitem-with-link pattern used by
37
+ repository trees, Notion-style page trees and IDE explorers, where the row itself navigates and a
38
+ separate disclosure expands that item's own nested rows. Nested `<lr-app-rail-item>`s slotted into
39
+ `children` grow a built-in disclosure (`[part="toggle"]`) as a SIBLING of the item's own
40
+ link/button, never nested inside it, so the link keeps navigating on its own and the disclosure
41
+ keeps toggling on its own. The new `expanded` property (reflected, `false` by default) is driven
42
+ through a cancelable `lr-toggle-request`/settled `lr-toggle` pair, mirroring
43
+ `<lr-app-rail-group>`'s collapsible contract exactly (same event names, same `{ open }` detail
44
+ shape, same request/commit veto semantics). The disclosure carries `aria-expanded` and
45
+ `aria-controls`, and a localized accessible name interpolating the item's own label. `icon-only`
46
+ forwards from an item onto every `<lr-app-rail-item>` it owns through `children`, exactly how
47
+ `<lr-app-rail-group>` forwards onto the items and groups it owns; a new
48
+ `--lr-app-rail-item-indent` token (default `var(--lr-space-l)`) indents `[part="children"]` once
49
+ per nesting level. An item with nothing slotted into `children` renders no disclosure and no
50
+ `[part="children"]` at all — byte-identical to an item authored before this feature existed.
51
+ - 351a078: Added `lr-chart` (and every chart tag built on it -- `lr-bar-chart`, `lr-line-chart`,
52
+ `lr-scatter-chart`, `lr-bubble-chart`, `lr-pie-chart`, `lr-doughnut-chart`, `lr-radar-chart`,
53
+ `lr-polar-area-chart`, `lr-histogram`) three additive surfaces so a mixed dashboard chart no longer
54
+ needs to drop to raw Chart.js: `LyraChartSeries.stack` (a per-series Chart.js dataset `stack` group
55
+ id -- two groups on the same stacked axis are summed independently and drawn side by side);
56
+ `stackedAxes` (a per-value-axis override of `stacked`, so a stacked bar series on the primary axis
57
+ can sit next to an unstacked overlay series on `y2`); and `tooltipTitleFormatter`/
58
+ `tooltipFooterFormatter` (tooltip title/footer hooks receiving every hovered item's context at
59
+ once, in the same `LyraChartFormatterContext` shape `formatter`'s `'tooltip'` surface already
60
+ produces). `computeStackTotals()` is now computed per stack group as well as per axis, and the
61
+ canvas `stack-totals` data-label draws once per (axis, group) rather than once per axis. All three
62
+ additions are opt-in and unset by default: a chart that only sets the legacy `stacked` boolean
63
+ renders byte-identically to before. `lr-lite-chart` has no counterpart for any of the three --
64
+ documented as a deliberate omission (its single-value-scale, single-stack SVG bar-geometry model
65
+ and native per-mark `<title>` tooltip have no equivalent shape for a second value axis, a
66
+ per-series stack group, or a multi-item tooltip title/footer) rather than implemented.
67
+ - 7ef4f5e: `<lr-combobox>` now takes part in the library's positioning-strategy contract. It exposes
68
+ `positioningStrategy` (attribute `positioning-strategy`), spelled the same as on `<lr-select>`,
69
+ `<lr-popover>`, `<lr-dropdown>`, `<lr-tooltip>` and `<lr-color-picker>`, and when the instance sets
70
+ nothing it honours the cascading `--lr-positioning-strategy` custom property ahead of its own
71
+ default.
72
+
73
+ Previously the listbox was always `fixed` through an undocumented internal default: an app that set
74
+ `--lr-positioning-strategy` once on `:root` to retune every floating surface silently left comboboxes
75
+ behind, and no instance could opt out. The default stays `fixed` — what the listbox has always
76
+ rendered, and the right choice for a typeahead list that usually sits inside a scrollable region — so
77
+ existing layouts do not move.
78
+
79
+ There is deliberately no `hoist` alias on this control. On `<lr-select>` it is Shoelace's established
80
+ spelling; here it would be a boolean defaulting to `true`, whose attribute could only ever express
81
+ the value the control already has. Use `positioning-strategy="absolute"` to opt out.
82
+ - 4fc2bc1: `<lr-context-meter>`'s interactive mode can now express a non-actionable band. A `segments` entry
83
+ accepts `disabled`, which renders that band and its legend row as genuinely disabled controls — no
84
+ tab stop, no hover or press affordance, and no `lr-segment-activate` on activation. Previously a
85
+ band that filtered to nothing was still a fully enabled, tabbable button, so a keyboard user tabbed
86
+ through dead controls with no indication, and nothing distinguished the row visually.
87
+
88
+ Two derived state tokens join `segment-selected`/`legend-item-selected`, and all of them compose:
89
+ `segment-empty`/`legend-item-empty` for a band whose `value` is 0, and
90
+ `segment-disabled`/`legend-item-disabled` for a declared-disabled entry. `--lr-context-meter-disabled-opacity`
91
+ (default `0.5`) themes the disabled treatment.
92
+
93
+ Inertness is deliberately never inferred from `value === 0`: a zero band is legitimately clickable
94
+ in a token-budget meter, so the empty pair is a presentational hook with no built-in treatment while
95
+ `disabled` is declared by the consumer. A meter whose entries set neither renders exactly as before.
96
+
97
+ Internally this adds a shared `statePart()` helper, so a part name carrying several states is built
98
+ one way across the library instead of being hand-rolled per component.
99
+ - 6c826ec: `<lr-file-input>` and `<lr-drop-zone>` can now enforce a cumulative `maxFiles`/`maxTotalSize` cap
100
+ across separate picker or drop sessions. Both limits previously counted only the files the control
101
+ itself held, so with `nonRetaining` (or after a reload in retaining mode) a user already holding 99
102
+ server-persisted files could add 50 more without the control ever rejecting, and the consumer had to
103
+ re-implement the aggregate check and render its own error.
104
+
105
+ Two optional numeric properties, `heldFileCount` (`held-file-count`) and `heldTotalSize`
106
+ (`held-total-size`), are the numeric counterpart of `valuePresent`: they are added to the running
107
+ totals before a batch is evaluated, in both retaining and non-retaining modes, so an over-cap batch is
108
+ rejected through the control's own rejection UI with the existing `maxFiles`/`maxTotalSize` reasons.
109
+ Both default to `0`, which reproduces today's behavior exactly, and a negative, `NaN` or infinite
110
+ value is treated as `0`. The `lr-files` detail also gains `remainingFiles` and `remainingTotalSize`
111
+ (`null` while that limit is unset), so a consumer can say how many more files may be added. The
112
+ aggregate arithmetic is now shared by both components, so the contract cannot drift between them.
113
+ - 771d6fc: Five `<lr-filter-bar>` fixes.
114
+
115
+ An unset `'select'` or single `'combobox'` filter bound `''`, which those controls treat as a
116
+ committed unmatched value, so every page load showed their "not in catalog" treatment instead of the
117
+ declared placeholder. Unset now binds absent. The date branch deliberately keeps `''`, having no
118
+ catalog to mismatch against.
119
+
120
+ `activeFiltersDisplay` (`all` | `changed` | `hidden`, default `all`) controls the active-filter chip
121
+ row. It was unconditional, and a filter resting at its `defaultValue` counted as active — so a bar
122
+ whose default narrows the view claimed the user had narrowed it. `changed` lists only what the user
123
+ actually changed. The default reproduces today exactly.
124
+
125
+ The `'checkbox-menu'` trigger gains the disclosure caret its neighbours have, which also start-aligns
126
+ its content instead of centring a bold sentence in a stretched field, and its label and caret parts
127
+ are forwarded under the `filter-control-*` scheme.
128
+
129
+ A lean registration entry lets a bar pay only for the filter types it declares. The real cost was
130
+ that `filter-bar.class.ts` bare-imported eleven composed control modules it never referenced; those
131
+ are gone, so the class module is genuinely side-effect-free and the default entry still registers
132
+ everything for existing consumers.
133
+
134
+ The composed combobox tag's remove button is now forwarded, so a consumer re-skinning filter tags as
135
+ pills can style the control inside them instead of leaving library defaults in a custom pill.
136
+ - 71e9296: `<lr-gauge>`'s value/label captions are now sized in `em` (`--lr-size-1em` for the value, and
137
+ `calc(var(--lr-size-1em) * 0.625)` for the label — the same 0.625 multiplier `--lr-font-size-2xs`
138
+ carries, kept as `em` math because the value-named token catalog's growth is frozen) instead of the
139
+ previous `rem`-anchored tokens (`--lr-font-size-m`, `--lr-font-size-2xs`, and, for the `linear`
140
+ shape specifically, a flat `--lr-size-0-5rem`). Every box in this component was already `em`-based
141
+ (`--lr-size-8em` for `radial`/`ring`, `--lr-size-12em` by `--lr-size-1-5em` for `linear`), so a
142
+ smaller `size` tier or a caller's own `font-size` on the host previously shrank the frame while the
143
+ caption stayed pinned to the document root — at the smallest tiers, or below them, the fixed
144
+ caption nearly filled or overflowed the box. The caption now scales with the same font-size that
145
+ sets the frame, so `<lr-gauge shape="linear" size="xs">` (or smaller) is usable as a compact
146
+ dashboard meter. At the default (unset `size`, unmodified ambient font) tier the resolved caption
147
+ size is unchanged.
148
+
149
+ New `showValue` property (default `true`, matching today's rendering) lets the decorative
150
+ `part="value"` caption be omitted — `<lr-gauge show-value="false">` — the same way an empty
151
+ `label` already omits the `part="label"` caption. Mirrors `<lr-progress-bar>`'s and
152
+ `<lr-progress-ring>`'s own `showValue` name and meaning; the default differs because a gauge's
153
+ purpose is showing the reading it announces, so hiding it is the opt-out. The accessible value
154
+ (`aria-valuenow`/`aria-valuetext`, the host's computed accessible name) is unaffected either way,
155
+ since the caption was always `aria-hidden`.
156
+ - 2435dad: A blocked native form submission — clicking a `type="submit"` control, calling
157
+ `form.requestSubmit()`, or implicit Enter submission — now marks every invalid participant as
158
+ user-interacted, so `:state(user-invalid)` (and `:state(user-valid)` once corrected) matches
159
+ exactly like native `:user-invalid`/`:user-valid` do. Previously only an explicit
160
+ `control.reportValidity()`/`form.reportValidity()` call counted: a submission attempt drives
161
+ `ElementInternals` directly and never calls a control's own `reportValidity()` method, so
162
+ `aria-invalid` correctly went `true` on a blocked submit while the `user-invalid` custom state
163
+ silently stayed unset.
164
+
165
+ A control's own silent `checkValidity()` query continues to never count as interaction, however
166
+ invalid the control already is — this is unchanged and is the one path interactive validation is
167
+ deliberately distinguished from.
168
+
169
+ Affects every form control that manages `ElementInternals` directly rather than through the
170
+ `FormAssociated` mixin (the mixin itself already got this fix): `<lr-radio>`, `<lr-radio-button>`,
171
+ `<lr-radio-group>`, `<lr-checkbox>`, `<lr-checkbox-group>`, `<lr-switch>`, `<lr-slider>`,
172
+ `<lr-select>`, `<lr-combobox>`, `<lr-token-input>`, `<lr-time-range>`, `<lr-file-input>`,
173
+ `<lr-rating>`, `<lr-model-select>`, `<lr-voice-picker>`, `<lr-locale-picker>`,
174
+ `<lr-graph-query-builder>`, `<lr-tool-param-form>`, and `<lr-rubric-form>`. Every affected
175
+ component's `@cssstate user-valid`/`user-invalid` JSDoc is corrected to document the rule above
176
+ instead of the looser "or a native validity check"/"or an explicit validity report" wording some
177
+ of them previously carried.
178
+ - 96c30ac: `<lr-model-select>` and `<lr-voice-picker>` catalog entries accept `disabled`. A disabled row renders
179
+ as a genuinely non-actionable control — no tab stop, no hover or press affordance — and keyboard
180
+ navigation steps over it without stranding focus. Both components share one catalog entry type, so
181
+ the contract cannot drift between them. An entry that does not set it renders exactly as before.
182
+ - a80606f: `<lr-color-picker>` palette swatches accept `disabled`, so a swatch can be shown as unavailable
183
+ rather than silently doing nothing when chosen. The swatch renders genuinely disabled, selection
184
+ emits nothing, and keyboard navigation steps past it. A swatch that does not set it renders exactly
185
+ as before.
186
+ - d6eb9b1: `<lr-flow-canvas>` nodes accept `disabled`, so a locked, read-only or in-progress node can be shown
187
+ without being activatable. The node's control renders genuinely disabled, activation emits nothing,
188
+ and roving focus steps past it. A node that does not set it renders exactly as before.
189
+ - 62db946: `<lr-mention-popover>` items accept `disabled`, so an ineligible mention or command can stay visible
190
+ without being selectable. The row carries `aria-disabled`, activation emits nothing, and
191
+ active-descendant navigation steps over it without leaving focus stranded. An item that does not set
192
+ it renders exactly as before.
193
+ - 5f4e877: `<lr-sequence-strip>` items accept `disabled`, so a step that cannot currently be opened stops being
194
+ a reachable control that does nothing. Activation emits nothing and roving focus steps past it. An
195
+ item that does not set it renders exactly as before.
196
+ - 694032e: `<lr-suggestion-chips>` suggestions accept `disabled`, so a suggestion that is visible but not
197
+ currently offerable stops being a live, focusable control that does nothing. Activation emits
198
+ nothing and keyboard navigation steps past it. A suggestion that does not set it renders exactly as
199
+ before.
200
+ - 3e5b916: Every `registrations.json` row now carries `localeKeys`: the `LyraMessageKey`s reachable by every tag
201
+ that importing it registers. It reuses the reachability walk that already derives the tree-shakeable
202
+ default-string slices — including keys a component reaches only through an indirect lookup table,
203
+ such as `lr-attachment-trigger`'s per-kind trigger and menu keys — rather than scanning for literal
204
+ `localize()` calls. Paired with `getRegisteredLyraLocaleKeys()`, a consumer can now verify that its
205
+ locale catalogue covers everything its rendered components can reach entirely from public, generated
206
+ metadata, with no parsing of `dist/`. The field is additive, so `schemaVersion` stays `1`.
207
+ - 3e5b916: `registrations.json` now covers every published registration specifier, not just per-tag aliases.
208
+ The three published integration-bridge specifiers — `components/media/flag/flag-peer.js`,
209
+ `components/viewers/archive-viewer/archive-viewer-register.js` and
210
+ `components/viewers/ebook-viewer/ebook-viewer-register.js` — had no row at all, so a consumer asking
211
+ which tags importing one of them defines still had to walk `dist/`. They now appear in a new
212
+ top-level `integrations` array, each with a `registers` list derived from the module's real
213
+ transitive import closure (including the lazy `import()` a document-format registrar uses once a
214
+ matching file appears), never inferred from the file name.
215
+
216
+ Every row, in `entries` and `integrations`, also gains `distModule`: the registration module's own
217
+ published deep specifier. `registrationModule` is a `src/` path that cannot be resolved against the
218
+ tarball; `distModule` can.
219
+
220
+ The bridges live in their own array rather than as tag-less rows inside `entries`, because every
221
+ `entries` row has always carried `tag` and a reader keying by it would otherwise receive `undefined`.
222
+ All additions are additive, so `schemaVersion` stays `1`.
223
+ - 83cde91: `<lr-streaming-text>`/`<lr-streaming-text-core>` forward the rest of the composed `<lr-markdown>`/
224
+ `<lr-markdown-core>` configuration surface verbatim: `tabSize`, `htmlMode`, `gfm`, `linkTarget`,
225
+ `internalLinkPrefix`, `headingOffset`, `highlightCode`, `headingAnchors`, `math`, and `maxHeight`,
226
+ alongside the already-forwarded `content`, `streaming`, and `languages`. Previously every one of
227
+ these was pinned at the composed element's default and unreachable through the wrapper, so a
228
+ consumer who had deliberately set, for example, `link-target=""` for same-tab links silently got
229
+ `target="_blank"` back after adopting `<lr-streaming-text>`. Each new property defaults to exactly
230
+ the composed element's own default, so leaving all of them unset renders identically to before.
231
+ The composed element still applies its own `rel="noopener noreferrer"` guard whenever a forwarded
232
+ `linkTarget` emits a `target`, and never a bare `opener`.
233
+ - 3b1e717: `<lr-table>`'s `editTrigger: 'double-click'` inline cell editor is now reachable by keyboard, closing
234
+ a WCAG 2.1.1 gap: a `'double-click'` column's resting cell is its own `tabindex="-1"` roving-focus
235
+ stop, reachable with ArrowRight/ArrowLeft once the row itself has focus, and `F2` or `Enter` on that
236
+ focused cell opens its editor exactly as a double-click would. `Enter` on the row itself still only
237
+ activates the row. Closing the editor, by commit or by cancel, returns focus to the cell that opened
238
+ it. A new public `editCell(rowKey, columnKey)` method opens the same editor programmatically, for a
239
+ consumer's own key binding or menu action. A table with no `editTrigger: 'double-click'` column
240
+ renders byte-identical markup. `TableColumn.cell` is now optional for an `editTrigger: 'always'`
241
+ column, whose persistent editor renders unconditionally and never falls back to it; every other
242
+ column still requires `cell`.
243
+ - f1612c9: `<lr-table>` columns gain `editLabel?: (row: T) => string`, mirroring the existing `editValue`/
244
+ `cellTitle` row callbacks: when defined, it becomes the inline cell editor's accessible name for
245
+ that row instead of the interpolated `tableEditCell` default (`Edit {column}`). The default is
246
+ identical for every row in a column, which is adequate for `editTrigger: 'double-click'` (only one
247
+ editor is ever open at a time) but not for `editTrigger: 'always'`, where every row's editor is a
248
+ permanent, individually focusable Tab stop -- a 50-row column with no `editLabel` exposed 50
249
+ identically named controls to keyboard and screen-reader users (WCAG 2.4.6, 1.3.1). A column that
250
+ omits `editLabel` renders byte-identical output to before.
251
+ - 0baf79e: `<lr-table>` gains `rowExpandLabel?: (row, expanded) => string`, the accessible name for one row's
252
+ expand/collapse chevron. Every chevron was named from the same localized `expand`/`collapse` string,
253
+ so a long table exposed dozens of identically named Tab stops with no way to tell the rows apart —
254
+ the same shape as the inline editor's naming gap, on a different surface.
255
+
256
+ The default is unchanged, because this component has no row-header notion to derive row context from
257
+ (`rowKey` is an opaque identity, not a label), so a table that does not set the callback renders
258
+ byte-identically.
259
+ - acb4266: Added `waitForLyraElement()` and `waitForToast()` to `@aceshooting/lyra-ui/testing`. `toast()`
260
+ registers `<lr-toast>`/`<lr-toast-item>` through a dynamic `import()` on first call, so a
261
+ fire-and-forget `toast(...)` -- the normal application pattern -- leaves the document empty for at
262
+ least one microtask, forcing a downstream test to hand-write a polling loop before it can assert on
263
+ the toast's rendered text. `waitForLyraElement(selector, options?)` is a generic, bounded,
264
+ event-driven awaitable (`MutationObserver` plus `customElements.whenDefined()`, no busy polling) for
265
+ "a matching library element is connected and upgraded," reachable from an optional `root` and
266
+ filterable by an optional `match` predicate; it rejects with a descriptive error after a bounded
267
+ timeout (2000ms default). `waitForToast(match?, options?)` is the named convenience for `<lr-toast-item>`,
268
+ matching by trimmed text or a predicate. Both run in a real browser and in the documented happy-dom
269
+ test environment. `confirm()` was swept too: it registers `<lr-dialog>` synchronously and has no
270
+ equivalent gap, so it gets no new helper.
271
+ - 857f2ef: `@aceshooting/lyra-ui/theme-bootstrap.js` -- the static, external no-flash theme script for a
272
+ strict Content-Security-Policy -- now reads `data-lr-theme-storage-key` and
273
+ `data-lr-theme-attributes` (space-separated) from its own `<script>` tag via
274
+ `document.currentScript` at parse time, so an application with its own pre-existing `localStorage`
275
+ key can use the shared static asset instead of inlining a per-app copy generated from
276
+ `createLyraThemeBootstrap({ storageKey })`. Both attributes are optional and validated, failing
277
+ closed to today's baked-in defaults (`'lyra-theme'` and `data-lr-theme`/`data-theme`) on an absent,
278
+ empty, oversized, or malformed value -- including an attribute-name list entry that is not a safe
279
+ `data-*`-shaped token (rejecting `on*` handler names, `style`/`class`/`id`, and anything containing
280
+ whitespace, a quote, `=`, or a control character), a list longer than eight entries or with a
281
+ duplicated entry, an oversized storage key, or a `null` `document.currentScript` (module/async
282
+ misuse). A `<script>` tag carrying neither attribute -- every existing deployment, and every inline
283
+ use of `lyraThemeBootstrap`/`createLyraThemeBootstrap()` -- behaves exactly as before.
284
+
285
+ ### Patch Changes
286
+
287
+ - 2787a1d: `<lr-button>` now re-evaluates its icon-only geometry when the slotted label's visibility changes
288
+ through CSS alone. Detection ran on `slotchange` and once on the first update, so the most natural
289
+ responsive idiom — a container or media query hiding the label at a narrow width — changed computed
290
+ style with no DOM mutation and nothing re-ran: the button kept full text geometry, padding and
291
+ min-width around an invisible label. It happened to look right only when the element was created
292
+ after the breakpoint was already crossed, which made it read as an intermittent bug.
293
+
294
+ A `ResizeObserver` now watches the label wrapper's own box. It deliberately does not watch the host
295
+ or the base part: once icon-only, those take a fixed size, so widening the container would not resize
296
+ them and the button could never flip back — the same one-way trap the fix exists to remove. The
297
+ recompute is deferred to an animation frame, matching `<lr-textarea>`'s auto-grow observer, because a
298
+ microtask-deferred write lands inside the same delivery pass and trips a ResizeObserver loop warning.
299
+ - 1059b56: Fixed `custom-elements.json` silently omitting `value`, `name`, `required`, and `disabled` (as both
300
+ members and attributes) for a `FormAssociated` component that inherits the mixin through a
301
+ superclass in a different module rather than declaring it directly -- `lr-number-input` and
302
+ `lr-native-time-input` (both extend `LyraInput`, which owns the mixin). The
303
+ `lr-form-associated-mixin-members` custom-elements-manifest plugin's superclass-chain walk already
304
+ found and back-filled these declarations correctly; the gap was that `scripts/manifest-compact.mjs`
305
+ runs as a separate pass after `cem analyze` and prunes any member/attribute whose `inheritedFrom`
306
+ resolves to an identical entry on the named superclass, which is exactly what the back-filled (and,
307
+ for `value`, CEM's own natively-inherited) entries looked like. Both tags now carry the same
308
+ member/attribute shapes, types, and defaults as every other `FormAssociated` consumer. Manifest
309
+ accuracy only -- runtime behavior was already correct.
310
+ - 0b207cb: Docs: every component whose icon-only action became a composed `<lr-icon-button>` in 16.0.0 now
311
+ carries the migration note that only `lr-copy-button` had. A `::part()` rule that used to paint that
312
+ button now names the composed child's host, which paints nothing — and because `color` still
313
+ inherits, such a rule looks half-alive rather than broken, which is how it escapes review. The note
314
+ says what to do instead: set the `--lr-icon-button-*` paint tokens on the component or an ancestor,
315
+ and use `--lr-theme-icon-button-size` for size, since `--lr-icon-button-size` is re-declared on every
316
+ host and never reaches a composed child.
317
+
318
+ Also pins the border half of that contract with a test: an ancestor `--lr-icon-button-border` does
319
+ reach a composed control, so border is not the one paint property that silently dies.
320
+ - ef05323: Fixed `<lr-confirm-bar>`'s `returnFocusTo` thunk resolving before a reactive host could re-create
321
+ the control it names. The documented motivating case -- a host that conditionally swaps a focused
322
+ trigger out for this bar, then swaps a brand-new trigger back in once a decision lands -- could
323
+ never work: every supported host framework re-renders asynchronously relative to the bar's own
324
+ synchronous focus handoff, so the thunk's first (and, previously, only) call always found the
325
+ replacement control missing and fell back past `[part="status"]` to `<body>` once the host's own
326
+ re-render removed the bar.
327
+
328
+ When the thunk's immediate resolution fails, the handoff now retries once more after the host has
329
+ had a real chance to react, and moves focus there only if it has since appeared, is connected and
330
+ focusable, and nothing else has claimed focus in the meantime. An immediately-resolving thunk or a
331
+ plain element value is unaffected -- resolved once, synchronously, exactly as before.
332
+
333
+ The retry is a new shared primitive, `deferComposedFocusRepair()` (plus its `nextHostUpdateOpportunity()`
334
+ timing helper), in `src/internal/focus-navigation.ts`, built on the existing
335
+ `captureComposedFocusRepair()`/`applyComposedFocusRepair()` pair so any other component with the same
336
+ shape -- a return-focus thunk naming a control its host re-creates asynchronously -- can adopt it
337
+ directly.
338
+ - 71e9296: Fixed: `<lr-context-meter shape="ring">`'s centered caption (`.ring-label`, inside `part="label"`)
339
+ now sizes itself in `em` (`calc(var(--lr-size-1em) * 0.625)`) instead of the previous
340
+ `rem`-anchored `--lr-font-size-2xs`. The ring itself is already `--lr-size-8em`, so a caller's own
341
+ `font-size` on the host shrinks the ring but previously left the caption pinned to the document
342
+ root — the same defect shape `<lr-gauge>`'s linear caption had. At the default (unmodified ambient
343
+ font) size the resolved caption size is unchanged.
344
+ - 63ee11b: `<lr-data-grid>` no longer treats an unchanged re-bind of `filters` or `sort` as a change. Both
345
+ setters rebuilt a fresh frozen array on every write, so the new reference was never `===` the old one
346
+ and Lit's dirty check always reported a change. Because a `filters`/`sort` change schedules a server
347
+ request — and a `filters` change schedules the *debounced* one — a host that re-binds these
348
+ properties on every render (the ordinary controlled pattern, often driven by the grid's own events)
349
+ could push the server request further away indefinitely, and re-rendered for nothing in the meantime.
350
+
351
+ The setters now compare the normalized content and keep the held value, including its reference, when
352
+ nothing actually changed. A genuinely different value still schedules exactly as before.
353
+ - 36f83ca: `<lr-input>`'s and `<lr-textarea>`'s `debounce` no longer silently stops working under the
354
+ controlled-input pattern. A pending `lr-input-settled` was cancelled by any programmatic `value`
355
+ write, including the one every framework binding makes on each render when it writes the just-typed
356
+ value straight back, so the event simply never fired and nothing warned. Only a write that actually
357
+ changes the value now cancels the pending settle; a write of the value already held leaves it
358
+ pending. A genuinely different value still supersedes the in-flight edit, exactly as before.
359
+
360
+ The fix lives in the shared `DebounceController` (a new `cancelIfChanged()`), so every debounced
361
+ control that routes external writes through it gets the same contract.
362
+ - 622e12c: `formatNumber`, `formatDate`, `formatRelativeTime`, `formatBytes` and the exported `binValues()` now
363
+ treat an omitted `locale` as the app's active locale instead of hardcoding English. They passed the
364
+ argument straight to the Intl cache, whose resolver starts at `'en'`, so an app that called
365
+ `setLyraLocale('fr')` saw every component render French while these standalone helpers silently stayed
366
+ English — and it looked correct in any English-locale test run.
367
+
368
+ An explicit `locale` argument still wins, and an app that never calls `setLyraLocale()` gets
369
+ byte-identical output: the resolution consults only the pinned active locale and deliberately does
370
+ not fall through to `<html lang>` or `navigator.language`, since a bare function call has no host
371
+ element to resolve against.
372
+ - 6130112: Fix: the seven built-in controls that compose `<lr-icon-button>` for an icon-only action
373
+ (`<lr-callout>`, `<lr-dialog>` — inherited by `<lr-drawer>` — `<lr-code-block>`, shared by
374
+ `<lr-code-block-core>`, `<lr-message-actions>`, `<lr-reorder-item>`, `<lr-attachment-trigger>`, and
375
+ `<lr-copy-button>`) no longer capture a public `--lr-icon-button-*` token on their own `:host` and
376
+ re-declare that same public name on the composed part. `<lr-icon-button>` now carries a private
377
+ `--_lr-icon-button-<token>-default` fallback tier for every paint token (background/color/border and
378
+ their hover/active variants), generalizing the existing `--_lr-icon-button-radius-default` shape;
379
+ each composing component sets its own default directly on that private tier instead of the public
380
+ one. An ancestor `--lr-icon-button-*` override still wins exactly as before — `<lr-icon-button>`'s
381
+ own stylesheet checks the public token first, ahead of any default a composing parent supplies — but
382
+ no descendant declares the public name from a private token derived from that same public token
383
+ anymore, so a scope-flattening custom-property resolver with no notion of which element declared
384
+ what (happy-dom, at least through 20.14.5) no longer sees a cycle: rendering any of the seven
385
+ controls under such an environment no longer throws `RangeError: Maximum call stack size exceeded`.
386
+ Revises the `llms/shared.md` testing note added in 16.0.0 to match — current versions are
387
+ unaffected. No public API changed.
388
+ - 2435dad: Verified and documented that `--lr-icon-button-border` reaches every 16.0.0 composed icon action
389
+ (`<lr-dialog>`'s close control, `<lr-reorder-item>`'s move controls, `<lr-code-block>`'s copy
390
+ control, `<lr-attachment-trigger>`'s trigger) the same way `--lr-icon-button-background`/`-color`/
391
+ `-radius` do. A report read the absence of a relayed `--_lr-icon-button-border-default` on
392
+ `<lr-dialog>`/`<lr-reorder-item>`/`<lr-code-block>` (none of which paint a resting border) as
393
+ border theming being broken for those components. Rendered `getComputedStyle` assertions now cover
394
+ all four components, including `<lr-attachment-trigger>`'s `outlined`/`filled-outlined`
395
+ appearances, which DO relay a non-zero border default and must still let an ancestor's public
396
+ token override it. No source change was needed — the public token was already the first, winning
397
+ arm of the fallback chain in every case; only test coverage and the authored `llms/` reference
398
+ pages were missing an explicit statement of the rule.
399
+ - af075a9: Docs: corrected the token-scope contract for `--lr-icon-button-size`, `--lr-otp-input-segment-size`,
400
+ and `--lr-popover-viewport-clamp`. All three read like ordinary per-component
401
+ `--lr-<component>-*` tokens, but the shared base token layer (`internal/tokens.styles.ts`) declares
402
+ each of them on its own `:host` block, which every `lr-*` component includes -- so, like
403
+ `--lr-focus-ring-width`/`-color`/`-offset`, a rule that sets one of them on an ancestor is reset at
404
+ the first intervening `lr-*` component and never reaches a nested target. This was always the
405
+ behavior (and is already asserted by `internal/tokens.test.ts`); the docs previously implied all
406
+ `--lr-icon-button-*`/`--lr-otp-input-*` tokens inherit uniformly from an ancestor, which is true for
407
+ every other one of them (e.g. `--lr-icon-button-radius`/`-background`) but not these. Updated
408
+ `lr-icon-button`'s and `lr-otp-input`'s own `@cssprop` JSDoc, the icon-button and otp-input entries
409
+ in `llms/forms.md`, and the design-token overview built by `scripts/build-llms.mjs`
410
+ (`llms/tokens.md`) to state the general rule once and name the affected tokens; added test coverage
411
+ proving the asymmetry against a nested shadow root. No runtime behavior changed and no token was
412
+ renamed.
413
+ - 616e6d6: Twenty components derived state from their slotted children only through a `slotchange` listener, so
414
+ they depended on the environment firing that event for a slot's INITIAL assignment. A DOM
415
+ implementation that does not — happy-dom, through 20.14.5 — leaves that state empty forever when the
416
+ children already exist at connect, which is what the ordinary conditional-render pattern produces.
417
+ Most visibly, an `<lr-select>`/`<lr-combobox>` whose `<lr-option>` children are rendered in the same
418
+ commit had zero options there, so the shipped `chooseOption()` testing driver threw, contradicting
419
+ the testing entry's own cross-environment promise.
420
+
421
+ Each affected component now also collects once on first update, from the slot's assigned elements,
422
+ through a shared helper. The collection is idempotent, so a real browser firing the initial event as
423
+ well changes nothing. Also fixed along the way: `lr-menu`'s collection was not idempotent (a second
424
+ pass misread the settled active item as having moved and stole focus), and `lr-chart` could have an
425
+ already-collected slotted config clobbered back to undefined by a phantom `slotchange` fired at the
426
+ slot element discarded during its loading-to-loaded render swap.
427
+
428
+ About eighty other components were checked and already seed their slot-derived state eagerly; they
429
+ are unchanged.
430
+ - 9c19aed: The cascading `--lr-positioning-strategy` custom property (`src/internal/positioning-strategy.ts`)
431
+ was documented as read by "every anchored/positioned overlay in this library", but until now only
432
+ `<lr-select>`, `<lr-popover>` (and `<lr-dropdown>` through it), `<lr-tooltip>`, `<lr-color-picker>`
433
+ and `<lr-combobox>` actually routed their placement through the shared resolver. An app that set the
434
+ property once on `:root` to retune every floating surface silently left every other anchored surface
435
+ behind.
436
+
437
+ `<lr-menu>` (the private submenu surface), `<lr-mention-popover>`, `<lr-export-button>`,
438
+ `<lr-usage-badge>`, `<lr-tool-call-chip>`, `<lr-tour>`, `<lr-locale-picker>`, `<lr-date-input>`,
439
+ `<lr-time-input>`, `<lr-citation-badge>`, `<lr-entity-chip>`, and `<lr-app-rail-item>` now honour the
440
+ same cascading property. None of them exposes a per-instance `positioning-strategy` property — that
441
+ remains a separate, deliberate decision — so an ancestor override is the only way to change them, and
442
+ their own default stays exactly what it always rendered (`fixed` in every case), so nothing moves for
443
+ anyone who sets nothing.
444
+
445
+ `<lr-popup>`, the low-level positioning primitive, is deliberately excluded: its own `strategy`
446
+ property is a plain, always-defined value (default `'absolute'`, never `undefined`), so there is no
447
+ way to distinguish "left unset" from "authored the default" without adding the same
448
+ explicit-vs-default tracking machinery the higher-level components' `positioning-strategy` property
449
+ uses — which this sweep does not add anywhere. It is also meant to be composed directly by a consumer
450
+ who already controls `strategy` explicitly.
451
+ - 2435dad: Added `pnpm run regen`, a single command that runs every source-artifact generator (manifest,
452
+ component inventory, framework types, events, the testing event registry, component metadata,
453
+ registrations/tag-aliases, the autoloader manifest, the registration graph, default-string and
454
+ translation slices, the three palette generators, design tokens, reservation styles, editor data,
455
+ and llms) in real dependency order, so a batch of source changes no longer needs a human to
456
+ remember and re-run each generator individually before `pnpm lint`. Added `scripts/check-regen-
457
+ coverage.mjs` (wired into `contract-policy` as `check:regen-coverage`/`test:regen-coverage`), a
458
+ gate that derives which generators `regen` must reach directly from the freshness gates themselves
459
+ — a same-file `--check`/write argument pair, a gate's own `pnpm run <name>` remedy text, or a gate
460
+ that imports/references a generator file directly — rather than a hand-kept list, so a newly added
461
+ or renamed generator cannot silently fall out of `regen` again. No runtime behavior changed;
462
+ `pnpm run regen` on an already-fresh tree is a no-op.
463
+ - 74a887b: `<lr-table>` no longer gets stuck with `priority`-hidden columns after the table widens back out.
464
+ Narrowing correctly hid `low`/`medium` columns once their content actually overflowed, but widening
465
+ never restored them: `recomputeHiddenPriorityColumns()` reconstructed "how wide would everything be"
466
+ by adding a hidden tier's cached natural width to `[part='base']`'s CURRENT `scrollWidth` — and once a
467
+ tier was hidden, `[part='table']`'s own `inline-size: 100%` stretched the remaining columns to fill
468
+ any leftover room, so that `scrollWidth` tracked `clientWidth` instead of the remaining content's real
469
+ width. The reconstructed total then chased whatever the container currently measured rather than the
470
+ actual content, so `overflowAtFull` never dropped enough to re-admit a hidden tier — `reload` or
471
+ `priorityColumnsVisible = true` were the only ways back, because both bypass the measurement entirely.
472
+
473
+ The fully-visible width is now reconstructed from three independently cached natural widths (the
474
+ always-visible columns, plus each hidden tier) instead of from the currently-rendered, potentially
475
+ stretched `scrollWidth`. Every cache is refreshed only on a pass where the table is genuinely too wide
476
+ for its container — the one condition under which nothing rendered has spare room to stretch into, and
477
+ necessarily true on the pass that first decides to hide anything — so a widening container now
478
+ correctly restores every tier that fits, without the restored tier immediately re-hiding on the very
479
+ next measurement pass its own restoration triggers.
480
+ - 2435dad: Fixed `<lr-input>`'s required-field description, `<lr-task-list>`'s per-item status label,
481
+ `<lr-transcript-feed>`'s interim "Transcribing…" marker, and `<lr-filter-bar>`'s touched-required
482
+ inline error and hidden filter-control label: all four rendered `class="sr-only"` without
483
+ composing the shared `srOnly` style block from `internal/a11y.ts` into their own
484
+ `static override styles`, so the class name did nothing and the assistive-only text rendered as
485
+ ordinary visible content instead of being clipped to a 1px box. Each component now composes the
486
+ shared `srOnly` export, matching the reference shape in `time-input.class.ts`.
487
+
488
+ Added `scripts/check-visually-hidden.mjs` (with its own `scripts/check-visually-hidden.test.mjs`
489
+ unit tests), a new static gate wired into `contract-policy`/`pnpm lint` as
490
+ `check:visually-hidden`/`test:visually-hidden`. It flags any `*.class.ts` file whose render
491
+ template applies the `sr-only` class without either composing the shared `srOnly` export or
492
+ declaring a matching scoped `.sr-only { ... }` rule in its own sibling `*.styles.ts`, so this
493
+ class of defect fails CI instead of shipping silently. Added browser regression tests for all four
494
+ components asserting the rendered `getComputedStyle()` result (clipped, absolute-positioned, with
495
+ the accessible text still present in the DOM), plus explicit `<lr-input>` coverage of the pristine
496
+ (no visible required text, error part hidden) and failed-submission (error becomes visible) states.
497
+
3
498
  ## 16.0.0
4
499
 
5
500
  ### Major Changes
@@ -65,6 +560,15 @@
65
560
  reading a painted value off it (`getComputedStyle(node).backgroundColor`) needs
66
561
  `node.shadowRoot.querySelector('[part~="button"]')`.
67
562
 
563
+ **Size is the one token that does NOT follow that rule.** `--lr-icon-button-background`/`-color`/
564
+ `-radius`/`-border` inherit down to a composed action, but `--lr-icon-button-size` set on the
565
+ wrapping component does not reach it, and `min-inline-size`/`min-block-size` written on the old
566
+ part cannot push the nested control past its own floor — so a pre-16 rule that sized one of these
567
+ controls, including a coarse-pointer touch-target pair, is inert with no visible symptom. Use
568
+ `--lr-theme-icon-button-size` instead; it is the hook that crosses into the composed child. This
569
+ applies to every component in the table above, not only `<lr-copy-button>`, whose reference page
570
+ was previously the only place it was written down.
571
+
68
572
  **Not affected by this change.** Other icon-sized built-in buttons deliberately stay native
69
573
  `<button>`s in 16.0.0, so every rule you already wrote against them still applies: `<lr-alert>`,
70
574
  `<lr-toast-item>`, `<lr-lightbox>` and `<lr-tool-result-dialog>` close buttons; `<lr-chip>`,