@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
@@ -208,9 +208,18 @@ width), `--lr-app-rail-overlay-color` (default `var(--lr-color-overlay)` — the
208
208
  color; component-specific since no shared token exists), `--lr-app-rail-panel-inset-block-start`
209
209
  (default `0`, applied to both `[part="panel"]` and `[part="backdrop"]` — raise it to leave room for
210
210
  a fixed app bar/status area above the drawer instead of the panel/scrim starting flush with the
211
- viewport top), `--lr-app-rail-panel-radius` (default `0` — corner radius of `[part="panel"]`; pairs
212
- naturally with a nonzero `--lr-app-rail-panel-inset-block-start`, which exposes the panel's top
213
- corners), `--lr-app-rail-panel-overflow-block` (default `auto`) and
211
+ viewport top), `--lr-app-rail-panel-radius` (default `0` — uniform corner radius of `[part="panel"]`;
212
+ pairs naturally with a nonzero `--lr-app-rail-panel-inset-block-start`, which exposes the panel's top
213
+ corners). Four direction-aware per-corner tokens each default to `--lr-app-rail-panel-radius`, so
214
+ setting only the uniform token still rounds all four corners exactly as before:
215
+ `--lr-app-rail-panel-radius-start-start` and `--lr-app-rail-panel-radius-end-start` (logical
216
+ `border-start-start-radius`/`border-end-start-radius` — the two corners at the panel's own flush
217
+ inline-start edge, since the drawer always sits flush against `inset-inline-start: 0`) and
218
+ `--lr-app-rail-panel-radius-start-end`/`--lr-app-rail-panel-radius-end-end` (logical
219
+ `border-start-end-radius`/`border-end-end-radius` — the two corners away from that flush edge, the
220
+ pair a flush-against-one-edge drawer typically rounds). All four are logical, so which physical
221
+ corner each one paints swaps under `dir="rtl"` with no second consumer rule.
222
+ `--lr-app-rail-panel-overflow-block` (default `auto`) and
214
223
  `--lr-app-rail-panel-overflow-inline` (default `clip`) — `[part="panel"]`'s logical overflow axes;
215
224
  either non-`visible` value clips a `position: fixed` popup opened by a slotted/nav-item control
216
225
  (e.g. a slotted `<lr-select>`/`<lr-menu>`) whenever its rendered box extends past the panel,
@@ -226,7 +235,10 @@ docked rail chrome). `--lr-app-rail-header-padding` and `--lr-app-rail-footer-pa
226
235
  `var(--lr-space-m)`) retune `[part="header"]`/`[part="footer"]`'s padding independently.
227
236
  `--lr-app-rail-header-min-block-size` (default `auto`, the property's own initial value, so unset
228
237
  reproduces today's exact height) reserves a minimum height for `[part="header"]`, for content that
229
- mounts or resizes asynchronously. Plus shared
238
+ mounts or resizes asynchronously. `--lr-app-rail-nav-padding` and `--lr-app-rail-nav-gap` (default
239
+ `var(--lr-space-s)`/`var(--lr-space-xs)`, the values this rule hard-coded before either token
240
+ existed) retune `[part="nav"]`'s own padding and inter-item gap — the rail's vertical rhythm,
241
+ previously reachable only through `::part(nav)`. Plus shared
230
242
  tokens (`--lr-color-border`,
231
243
  `--lr-color-surface`, `--lr-color-text`, `--lr-color-brand`, `--lr-color-brand-quiet`,
232
244
  `--lr-space-*`, `--lr-radius`, `--lr-shadow`, `--lr-icon-button-size`,
@@ -359,10 +371,22 @@ removing the label from the accessibility tree.
359
371
  `<lr-app-rail>` as the viewport narrows) hides it from view. No effect outside icon-only mode,
360
372
  since the label is already visible there. `false` (the default) reproduces the exact existing
361
373
  output.
374
+ - `expanded: boolean = false` (reflected) — whether this item's own `children` are shown. `false`
375
+ reproduces exactly what an item without this property rendered before this feature existed.
376
+ Driven through the same request/commit pair as `<lr-app-rail-group>`'s `open`, see Events below.
362
377
 
363
378
  A host `aria-label` is copied to the rendered native link or button by attribute presence,
364
379
  including an explicitly empty value; without it, the default slot supplies the native name. The
365
- same precedence supplies the tooltip text when that opt-in flyout is visible.
380
+ same precedence supplies the tooltip text when that opt-in flyout is visible, and the disclosure's
381
+ interpolated `{label}` (see Events below).
382
+
383
+ **Events:** `lr-toggle-request` — cancelable, emitted before `expanded` changes from the built-in
384
+ disclosure (`detail: { open }` — the field is named `open`, matching `<lr-app-rail-group>`'s
385
+ identical event name and detail shape exactly). Call `preventDefault()` to keep the current state,
386
+ or assign `expanded` from the listener to resolve it yourself; a write during the dispatch
387
+ suppresses the default commit even when it assigns the value the property already held. Not
388
+ emitted for a direct `expanded` write. `lr-toggle` — non-cancelable, emitted after `expanded` is
389
+ written, never for a vetoed or listener-resolved request (`detail: { open }`).
366
390
 
367
391
  **Methods:** `click(): void` activates the internal native link or button; it is a no-op while
368
392
  `disabled`.
@@ -385,6 +409,28 @@ names the native control, which remains the sole action).
385
409
  control keeps its own click, keyboard activation and focus order instead of being swallowed.
386
410
  Unlike `meta` it stays visible in `icon-only` mode, where it shares the narrow rail's width with
387
411
  the icon.
412
+ - `children` slot — nested `<lr-app-rail-item>`s disclosed beneath this item (the
413
+ treeitem-with-link pattern: the row itself navigates, a separate disclosure expands its own
414
+ child rows). Slotting anything into it grows a built-in `[part="toggle"]` disclosure button as a
415
+ SIBLING of the item's own link/button, never nested inside it, so the link keeps navigating on
416
+ its own and the disclosure keeps toggling on its own — clicking one never triggers the other.
417
+ Leaving `children` empty renders neither the disclosure nor `[part="children"]` at all: an item
418
+ authored without any `children` content renders byte-identically to one authored before this
419
+ slot existed. The disclosure carries `aria-expanded` (both states) and `aria-controls` pointing
420
+ at `[part="children"]`'s id, and a localized accessible name interpolating this item's own label
421
+ (`Expand {label}`/`Collapse {label}` in the default locale — no literal fallback, so a
422
+ `registerLyraLocale()` translation or a `.strings` override always reaches it). `<lr-app-rail-group>`
423
+ cannot express this pattern: its collapsible heading *is* the toggle, so a navigable link cannot
424
+ live inside it without nesting an interactive element inside a button.
425
+
426
+ `icon-only` forwards from this item onto every `<lr-app-rail-item>` it directly owns through
427
+ `children` — including ones appended later — exactly how `<lr-app-rail-group>` forwards onto the
428
+ items and nested groups it owns. The disclosure itself never changes shape between
429
+ presentations: it is always a fixed icon-button-sized square beside `[part="base"]`, reusing the
430
+ same hover/active/focus tokens as the link/button (`--lr-app-rail-item-hover-bg` etc.) rather than
431
+ a second disclosure-only set. There is no ancestor-current treatment — `<lr-app-rail-group>` has
432
+ no equivalent concept for a group containing the current item, so none is invented here either; a
433
+ current descendant stays perceivable only through its own `current` property.
388
434
 
389
435
  Both wrappers (`[part="meta"]`, `[part="end"]`) are hidden while empty, so an item using neither
390
436
  renders exactly as before. Note that while the mobile overlay is open, a click anywhere in the
@@ -393,10 +439,16 @@ nav-slot behaviour, not new to these slots.
393
439
 
394
440
  **CSS parts:** `base`, `icon`, `label`, `current-indicator` (a decorative inline indicator rendered
395
441
  only while the item is `current`/`aria-current="page"`, mirroring `<lr-conversation-item>`'s
396
- shipped `active-indicator` part), `tooltip` (the hover/focus label flyout, only rendered while
397
- `tooltip` is set, the item is `icon-only`, and it is hovered or focused), `meta` (the wrapper around
398
- the `meta` slot, hidden while empty) and `end` (the wrapper around the `end` slot, hidden while
399
- empty).
442
+ shipped `active-indicator` part suppressed by default while `icon-only`, see the current-ring
443
+ tokens below), `tooltip` (the hover/focus label flyout, only rendered while `tooltip` is set, the
444
+ item is `icon-only`, and it is hovered or focused), `meta` (the wrapper around the `meta` slot,
445
+ hidden while empty), `end` (the wrapper around the `end` slot, hidden while empty), `toggle` (the
446
+ `children` disclosure, rendered only while something is slotted into `children`; a sibling of
447
+ `base`, never nested inside it), `toggle-icon` (the wrapper around the disclosure chevron,
448
+ direction-aware through this wrapper's own `transform` — mirrors `<lr-app-rail-group>`'s own
449
+ `[part="toggle-icon"]`) and `children` (the wrapper around the `children` slot, rendered only
450
+ alongside `toggle`; hidden — but present, so `aria-controls` keeps resolving — while `expanded` is
451
+ `false`).
400
452
 
401
453
  **Themeable custom properties:** `--lr-app-rail-item-current-bg` (default
402
454
  `var(--lr-color-brand-quiet)`), `--lr-app-rail-item-current-color` (default
@@ -415,6 +467,16 @@ before. `--lr-app-rail-item-current-font-weight` mirrors `<lr-stepper>`'s
415
467
  `--lr-app-rail-item-current-indicator-width` (default `var(--lr-size-2px)`), and
416
468
  `--lr-app-rail-item-current-indicator-inset-inline` (default `0 auto`; set `auto 0` to place the
417
469
  indicator at the inline-end edge instead) theme `[part="current-indicator"]`.
470
+ `--lr-app-rail-item-current-indicator-display` (no default; unset resolves to `none` while
471
+ `icon-only`) restores the indicator bar in icon-only presentation — a full-height edge bar reads
472
+ as a rendering glitch on the square icon-only tile, so it is suppressed there by default; full
473
+ presentation is unaffected either way, since its own `[part="current-indicator"]` rule declares no
474
+ `display` at all. `--lr-app-rail-item-current-ring` (no default; unset resolves to `none` in full
475
+ presentation and an inset ring in icon-only presentation) sets `box-shadow` on `[part="base"]`
476
+ while current: unset, icon-only gets an inset ring automatically — the non-color-only signal
477
+ (WCAG 1.4.1) that replaces the bar suppressed there, since full presentation already conveys
478
+ current state through the indicator bar and `--lr-app-rail-item-current-font-weight`. Setting this
479
+ token explicitly applies the same value in both presentations.
418
480
  Ordinary interaction states are independently inheritable through
419
481
  `--lr-app-rail-item-hover-bg`, `--lr-app-rail-item-hover-color`,
420
482
  `--lr-app-rail-item-active-bg`, and `--lr-app-rail-item-active-color`, again retaining the former
@@ -432,7 +494,22 @@ floor-clamped since the icon is decorative, not itself a pointer target), and
432
494
  is retuned while family/weight/line-height stay inherited) retune the row's geometry.
433
495
  While `icon-only`, `[part="base"]` resolves to a square hit target matching the icon-button
434
496
  footprint used elsewhere in this library (`aspect-ratio: 1` against its already floor-clamped
435
- block size) instead of stretching across the rail's icon column.
497
+ block size) instead of stretching across the rail's icon column. `--lr-app-rail-item-icon-only-size`
498
+ (no default) sizes that square directly — both `inline-size` and `block-size`, and the row's own
499
+ `min-block-size` floor — independent of `--lr-app-rail-item-min-block-size`, so a taller expanded
500
+ row and an icon-only square pinned to `--lr-icon-button-size` can coexist. Unset, the square is
501
+ still derived via `aspect-ratio: 1` against the row's block size exactly as before.
502
+
503
+ **`--lr-positioning-strategy`** (16.0.0) — the icon-only flyout tooltip reads this same cascading
504
+ `absolute`/`fixed` override documented on `<lr-popover>` when it is (re)positioned, falling back to
505
+ its own `fixed` default when nothing is set. There is no per-instance `positioning-strategy`
506
+ property on `<lr-app-rail-item>`; set the custom property on `:root`, a theme, or one clipping
507
+ ancestor to change every unset rail item's flyout beneath it.
508
+
509
+ `--lr-app-rail-item-indent` (default `var(--lr-space-l)`) sets `[part="children"]`'s
510
+ `padding-inline-start`. Applied once per nesting level — a doubly-nested `children` list compounds
511
+ two insets automatically, since each level's own `[part="children"]` applies the token again.
512
+ Logical, so it mirrors under `dir="rtl"` with no separate rule.
436
513
 
437
514
  **Optional peer deps:** none.
438
515
 
@@ -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** 7 parts, 17 custom properties — see this component's own `@csspart`/`@cssprop` list below
12
+ - **Themeable via** 10 parts, 22 custom properties — see this component's own `@csspart`/`@cssprop` list below
13
13
  - **Documented with** `lr-app-rail`, `lr-app-rail-group` (same section below)
14
14
  - **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`
15
15
 
@@ -208,9 +208,18 @@ width), `--lr-app-rail-overlay-color` (default `var(--lr-color-overlay)` — the
208
208
  color; component-specific since no shared token exists), `--lr-app-rail-panel-inset-block-start`
209
209
  (default `0`, applied to both `[part="panel"]` and `[part="backdrop"]` — raise it to leave room for
210
210
  a fixed app bar/status area above the drawer instead of the panel/scrim starting flush with the
211
- viewport top), `--lr-app-rail-panel-radius` (default `0` — corner radius of `[part="panel"]`; pairs
212
- naturally with a nonzero `--lr-app-rail-panel-inset-block-start`, which exposes the panel's top
213
- corners), `--lr-app-rail-panel-overflow-block` (default `auto`) and
211
+ viewport top), `--lr-app-rail-panel-radius` (default `0` — uniform corner radius of `[part="panel"]`;
212
+ pairs naturally with a nonzero `--lr-app-rail-panel-inset-block-start`, which exposes the panel's top
213
+ corners). Four direction-aware per-corner tokens each default to `--lr-app-rail-panel-radius`, so
214
+ setting only the uniform token still rounds all four corners exactly as before:
215
+ `--lr-app-rail-panel-radius-start-start` and `--lr-app-rail-panel-radius-end-start` (logical
216
+ `border-start-start-radius`/`border-end-start-radius` — the two corners at the panel's own flush
217
+ inline-start edge, since the drawer always sits flush against `inset-inline-start: 0`) and
218
+ `--lr-app-rail-panel-radius-start-end`/`--lr-app-rail-panel-radius-end-end` (logical
219
+ `border-start-end-radius`/`border-end-end-radius` — the two corners away from that flush edge, the
220
+ pair a flush-against-one-edge drawer typically rounds). All four are logical, so which physical
221
+ corner each one paints swaps under `dir="rtl"` with no second consumer rule.
222
+ `--lr-app-rail-panel-overflow-block` (default `auto`) and
214
223
  `--lr-app-rail-panel-overflow-inline` (default `clip`) — `[part="panel"]`'s logical overflow axes;
215
224
  either non-`visible` value clips a `position: fixed` popup opened by a slotted/nav-item control
216
225
  (e.g. a slotted `<lr-select>`/`<lr-menu>`) whenever its rendered box extends past the panel,
@@ -226,7 +235,10 @@ docked rail chrome). `--lr-app-rail-header-padding` and `--lr-app-rail-footer-pa
226
235
  `var(--lr-space-m)`) retune `[part="header"]`/`[part="footer"]`'s padding independently.
227
236
  `--lr-app-rail-header-min-block-size` (default `auto`, the property's own initial value, so unset
228
237
  reproduces today's exact height) reserves a minimum height for `[part="header"]`, for content that
229
- mounts or resizes asynchronously. Plus shared
238
+ mounts or resizes asynchronously. `--lr-app-rail-nav-padding` and `--lr-app-rail-nav-gap` (default
239
+ `var(--lr-space-s)`/`var(--lr-space-xs)`, the values this rule hard-coded before either token
240
+ existed) retune `[part="nav"]`'s own padding and inter-item gap — the rail's vertical rhythm,
241
+ previously reachable only through `::part(nav)`. Plus shared
230
242
  tokens (`--lr-color-border`,
231
243
  `--lr-color-surface`, `--lr-color-text`, `--lr-color-brand`, `--lr-color-brand-quiet`,
232
244
  `--lr-space-*`, `--lr-radius`, `--lr-shadow`, `--lr-icon-button-size`,
@@ -359,10 +371,22 @@ removing the label from the accessibility tree.
359
371
  `<lr-app-rail>` as the viewport narrows) hides it from view. No effect outside icon-only mode,
360
372
  since the label is already visible there. `false` (the default) reproduces the exact existing
361
373
  output.
374
+ - `expanded: boolean = false` (reflected) — whether this item's own `children` are shown. `false`
375
+ reproduces exactly what an item without this property rendered before this feature existed.
376
+ Driven through the same request/commit pair as `<lr-app-rail-group>`'s `open`, see Events below.
362
377
 
363
378
  A host `aria-label` is copied to the rendered native link or button by attribute presence,
364
379
  including an explicitly empty value; without it, the default slot supplies the native name. The
365
- same precedence supplies the tooltip text when that opt-in flyout is visible.
380
+ same precedence supplies the tooltip text when that opt-in flyout is visible, and the disclosure's
381
+ interpolated `{label}` (see Events below).
382
+
383
+ **Events:** `lr-toggle-request` — cancelable, emitted before `expanded` changes from the built-in
384
+ disclosure (`detail: { open }` — the field is named `open`, matching `<lr-app-rail-group>`'s
385
+ identical event name and detail shape exactly). Call `preventDefault()` to keep the current state,
386
+ or assign `expanded` from the listener to resolve it yourself; a write during the dispatch
387
+ suppresses the default commit even when it assigns the value the property already held. Not
388
+ emitted for a direct `expanded` write. `lr-toggle` — non-cancelable, emitted after `expanded` is
389
+ written, never for a vetoed or listener-resolved request (`detail: { open }`).
366
390
 
367
391
  **Methods:** `click(): void` activates the internal native link or button; it is a no-op while
368
392
  `disabled`.
@@ -385,6 +409,28 @@ names the native control, which remains the sole action).
385
409
  control keeps its own click, keyboard activation and focus order instead of being swallowed.
386
410
  Unlike `meta` it stays visible in `icon-only` mode, where it shares the narrow rail's width with
387
411
  the icon.
412
+ - `children` slot — nested `<lr-app-rail-item>`s disclosed beneath this item (the
413
+ treeitem-with-link pattern: the row itself navigates, a separate disclosure expands its own
414
+ child rows). Slotting anything into it grows a built-in `[part="toggle"]` disclosure button as a
415
+ SIBLING of the item's own link/button, never nested inside it, so the link keeps navigating on
416
+ its own and the disclosure keeps toggling on its own — clicking one never triggers the other.
417
+ Leaving `children` empty renders neither the disclosure nor `[part="children"]` at all: an item
418
+ authored without any `children` content renders byte-identically to one authored before this
419
+ slot existed. The disclosure carries `aria-expanded` (both states) and `aria-controls` pointing
420
+ at `[part="children"]`'s id, and a localized accessible name interpolating this item's own label
421
+ (`Expand {label}`/`Collapse {label}` in the default locale — no literal fallback, so a
422
+ `registerLyraLocale()` translation or a `.strings` override always reaches it). `<lr-app-rail-group>`
423
+ cannot express this pattern: its collapsible heading *is* the toggle, so a navigable link cannot
424
+ live inside it without nesting an interactive element inside a button.
425
+
426
+ `icon-only` forwards from this item onto every `<lr-app-rail-item>` it directly owns through
427
+ `children` — including ones appended later — exactly how `<lr-app-rail-group>` forwards onto the
428
+ items and nested groups it owns. The disclosure itself never changes shape between
429
+ presentations: it is always a fixed icon-button-sized square beside `[part="base"]`, reusing the
430
+ same hover/active/focus tokens as the link/button (`--lr-app-rail-item-hover-bg` etc.) rather than
431
+ a second disclosure-only set. There is no ancestor-current treatment — `<lr-app-rail-group>` has
432
+ no equivalent concept for a group containing the current item, so none is invented here either; a
433
+ current descendant stays perceivable only through its own `current` property.
388
434
 
389
435
  Both wrappers (`[part="meta"]`, `[part="end"]`) are hidden while empty, so an item using neither
390
436
  renders exactly as before. Note that while the mobile overlay is open, a click anywhere in the
@@ -393,10 +439,16 @@ nav-slot behaviour, not new to these slots.
393
439
 
394
440
  **CSS parts:** `base`, `icon`, `label`, `current-indicator` (a decorative inline indicator rendered
395
441
  only while the item is `current`/`aria-current="page"`, mirroring `<lr-conversation-item>`'s
396
- shipped `active-indicator` part), `tooltip` (the hover/focus label flyout, only rendered while
397
- `tooltip` is set, the item is `icon-only`, and it is hovered or focused), `meta` (the wrapper around
398
- the `meta` slot, hidden while empty) and `end` (the wrapper around the `end` slot, hidden while
399
- empty).
442
+ shipped `active-indicator` part suppressed by default while `icon-only`, see the current-ring
443
+ tokens below), `tooltip` (the hover/focus label flyout, only rendered while `tooltip` is set, the
444
+ item is `icon-only`, and it is hovered or focused), `meta` (the wrapper around the `meta` slot,
445
+ hidden while empty), `end` (the wrapper around the `end` slot, hidden while empty), `toggle` (the
446
+ `children` disclosure, rendered only while something is slotted into `children`; a sibling of
447
+ `base`, never nested inside it), `toggle-icon` (the wrapper around the disclosure chevron,
448
+ direction-aware through this wrapper's own `transform` — mirrors `<lr-app-rail-group>`'s own
449
+ `[part="toggle-icon"]`) and `children` (the wrapper around the `children` slot, rendered only
450
+ alongside `toggle`; hidden — but present, so `aria-controls` keeps resolving — while `expanded` is
451
+ `false`).
400
452
 
401
453
  **Themeable custom properties:** `--lr-app-rail-item-current-bg` (default
402
454
  `var(--lr-color-brand-quiet)`), `--lr-app-rail-item-current-color` (default
@@ -415,6 +467,16 @@ before. `--lr-app-rail-item-current-font-weight` mirrors `<lr-stepper>`'s
415
467
  `--lr-app-rail-item-current-indicator-width` (default `var(--lr-size-2px)`), and
416
468
  `--lr-app-rail-item-current-indicator-inset-inline` (default `0 auto`; set `auto 0` to place the
417
469
  indicator at the inline-end edge instead) theme `[part="current-indicator"]`.
470
+ `--lr-app-rail-item-current-indicator-display` (no default; unset resolves to `none` while
471
+ `icon-only`) restores the indicator bar in icon-only presentation — a full-height edge bar reads
472
+ as a rendering glitch on the square icon-only tile, so it is suppressed there by default; full
473
+ presentation is unaffected either way, since its own `[part="current-indicator"]` rule declares no
474
+ `display` at all. `--lr-app-rail-item-current-ring` (no default; unset resolves to `none` in full
475
+ presentation and an inset ring in icon-only presentation) sets `box-shadow` on `[part="base"]`
476
+ while current: unset, icon-only gets an inset ring automatically — the non-color-only signal
477
+ (WCAG 1.4.1) that replaces the bar suppressed there, since full presentation already conveys
478
+ current state through the indicator bar and `--lr-app-rail-item-current-font-weight`. Setting this
479
+ token explicitly applies the same value in both presentations.
418
480
  Ordinary interaction states are independently inheritable through
419
481
  `--lr-app-rail-item-hover-bg`, `--lr-app-rail-item-hover-color`,
420
482
  `--lr-app-rail-item-active-bg`, and `--lr-app-rail-item-active-color`, again retaining the former
@@ -432,7 +494,22 @@ floor-clamped since the icon is decorative, not itself a pointer target), and
432
494
  is retuned while family/weight/line-height stay inherited) retune the row's geometry.
433
495
  While `icon-only`, `[part="base"]` resolves to a square hit target matching the icon-button
434
496
  footprint used elsewhere in this library (`aspect-ratio: 1` against its already floor-clamped
435
- block size) instead of stretching across the rail's icon column.
497
+ block size) instead of stretching across the rail's icon column. `--lr-app-rail-item-icon-only-size`
498
+ (no default) sizes that square directly — both `inline-size` and `block-size`, and the row's own
499
+ `min-block-size` floor — independent of `--lr-app-rail-item-min-block-size`, so a taller expanded
500
+ row and an icon-only square pinned to `--lr-icon-button-size` can coexist. Unset, the square is
501
+ still derived via `aspect-ratio: 1` against the row's block size exactly as before.
502
+
503
+ **`--lr-positioning-strategy`** (16.0.0) — the icon-only flyout tooltip reads this same cascading
504
+ `absolute`/`fixed` override documented on `<lr-popover>` when it is (re)positioned, falling back to
505
+ its own `fixed` default when nothing is set. There is no per-instance `positioning-strategy`
506
+ property on `<lr-app-rail-item>`; set the custom property on `:root`, a theme, or one clipping
507
+ ancestor to change every unset rail item's flyout beneath it.
508
+
509
+ `--lr-app-rail-item-indent` (default `var(--lr-space-l)`) sets `[part="children"]`'s
510
+ `padding-inline-start`. Applied once per nesting level — a doubly-nested `children` list compounds
511
+ two insets automatically, since each level's own `[part="children"]` applies the token again.
512
+ Logical, so it mirrors under `dir="rtl"` with no separate rule.
436
513
 
437
514
  **Optional peer deps:** none.
438
515
 
@@ -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** 11 parts, 23 custom properties — see this component's own `@csspart`/`@cssprop` list below
12
+ - **Themeable via** 11 parts, 29 custom properties — see this component's own `@csspart`/`@cssprop` list below
13
13
  - **Documented with** `lr-app-rail-item`, `lr-app-rail-group` (same section below)
14
14
  - **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`
15
15
 
@@ -208,9 +208,18 @@ width), `--lr-app-rail-overlay-color` (default `var(--lr-color-overlay)` — the
208
208
  color; component-specific since no shared token exists), `--lr-app-rail-panel-inset-block-start`
209
209
  (default `0`, applied to both `[part="panel"]` and `[part="backdrop"]` — raise it to leave room for
210
210
  a fixed app bar/status area above the drawer instead of the panel/scrim starting flush with the
211
- viewport top), `--lr-app-rail-panel-radius` (default `0` — corner radius of `[part="panel"]`; pairs
212
- naturally with a nonzero `--lr-app-rail-panel-inset-block-start`, which exposes the panel's top
213
- corners), `--lr-app-rail-panel-overflow-block` (default `auto`) and
211
+ viewport top), `--lr-app-rail-panel-radius` (default `0` — uniform corner radius of `[part="panel"]`;
212
+ pairs naturally with a nonzero `--lr-app-rail-panel-inset-block-start`, which exposes the panel's top
213
+ corners). Four direction-aware per-corner tokens each default to `--lr-app-rail-panel-radius`, so
214
+ setting only the uniform token still rounds all four corners exactly as before:
215
+ `--lr-app-rail-panel-radius-start-start` and `--lr-app-rail-panel-radius-end-start` (logical
216
+ `border-start-start-radius`/`border-end-start-radius` — the two corners at the panel's own flush
217
+ inline-start edge, since the drawer always sits flush against `inset-inline-start: 0`) and
218
+ `--lr-app-rail-panel-radius-start-end`/`--lr-app-rail-panel-radius-end-end` (logical
219
+ `border-start-end-radius`/`border-end-end-radius` — the two corners away from that flush edge, the
220
+ pair a flush-against-one-edge drawer typically rounds). All four are logical, so which physical
221
+ corner each one paints swaps under `dir="rtl"` with no second consumer rule.
222
+ `--lr-app-rail-panel-overflow-block` (default `auto`) and
214
223
  `--lr-app-rail-panel-overflow-inline` (default `clip`) — `[part="panel"]`'s logical overflow axes;
215
224
  either non-`visible` value clips a `position: fixed` popup opened by a slotted/nav-item control
216
225
  (e.g. a slotted `<lr-select>`/`<lr-menu>`) whenever its rendered box extends past the panel,
@@ -226,7 +235,10 @@ docked rail chrome). `--lr-app-rail-header-padding` and `--lr-app-rail-footer-pa
226
235
  `var(--lr-space-m)`) retune `[part="header"]`/`[part="footer"]`'s padding independently.
227
236
  `--lr-app-rail-header-min-block-size` (default `auto`, the property's own initial value, so unset
228
237
  reproduces today's exact height) reserves a minimum height for `[part="header"]`, for content that
229
- mounts or resizes asynchronously. Plus shared
238
+ mounts or resizes asynchronously. `--lr-app-rail-nav-padding` and `--lr-app-rail-nav-gap` (default
239
+ `var(--lr-space-s)`/`var(--lr-space-xs)`, the values this rule hard-coded before either token
240
+ existed) retune `[part="nav"]`'s own padding and inter-item gap — the rail's vertical rhythm,
241
+ previously reachable only through `::part(nav)`. Plus shared
230
242
  tokens (`--lr-color-border`,
231
243
  `--lr-color-surface`, `--lr-color-text`, `--lr-color-brand`, `--lr-color-brand-quiet`,
232
244
  `--lr-space-*`, `--lr-radius`, `--lr-shadow`, `--lr-icon-button-size`,
@@ -359,10 +371,22 @@ removing the label from the accessibility tree.
359
371
  `<lr-app-rail>` as the viewport narrows) hides it from view. No effect outside icon-only mode,
360
372
  since the label is already visible there. `false` (the default) reproduces the exact existing
361
373
  output.
374
+ - `expanded: boolean = false` (reflected) — whether this item's own `children` are shown. `false`
375
+ reproduces exactly what an item without this property rendered before this feature existed.
376
+ Driven through the same request/commit pair as `<lr-app-rail-group>`'s `open`, see Events below.
362
377
 
363
378
  A host `aria-label` is copied to the rendered native link or button by attribute presence,
364
379
  including an explicitly empty value; without it, the default slot supplies the native name. The
365
- same precedence supplies the tooltip text when that opt-in flyout is visible.
380
+ same precedence supplies the tooltip text when that opt-in flyout is visible, and the disclosure's
381
+ interpolated `{label}` (see Events below).
382
+
383
+ **Events:** `lr-toggle-request` — cancelable, emitted before `expanded` changes from the built-in
384
+ disclosure (`detail: { open }` — the field is named `open`, matching `<lr-app-rail-group>`'s
385
+ identical event name and detail shape exactly). Call `preventDefault()` to keep the current state,
386
+ or assign `expanded` from the listener to resolve it yourself; a write during the dispatch
387
+ suppresses the default commit even when it assigns the value the property already held. Not
388
+ emitted for a direct `expanded` write. `lr-toggle` — non-cancelable, emitted after `expanded` is
389
+ written, never for a vetoed or listener-resolved request (`detail: { open }`).
366
390
 
367
391
  **Methods:** `click(): void` activates the internal native link or button; it is a no-op while
368
392
  `disabled`.
@@ -385,6 +409,28 @@ names the native control, which remains the sole action).
385
409
  control keeps its own click, keyboard activation and focus order instead of being swallowed.
386
410
  Unlike `meta` it stays visible in `icon-only` mode, where it shares the narrow rail's width with
387
411
  the icon.
412
+ - `children` slot — nested `<lr-app-rail-item>`s disclosed beneath this item (the
413
+ treeitem-with-link pattern: the row itself navigates, a separate disclosure expands its own
414
+ child rows). Slotting anything into it grows a built-in `[part="toggle"]` disclosure button as a
415
+ SIBLING of the item's own link/button, never nested inside it, so the link keeps navigating on
416
+ its own and the disclosure keeps toggling on its own — clicking one never triggers the other.
417
+ Leaving `children` empty renders neither the disclosure nor `[part="children"]` at all: an item
418
+ authored without any `children` content renders byte-identically to one authored before this
419
+ slot existed. The disclosure carries `aria-expanded` (both states) and `aria-controls` pointing
420
+ at `[part="children"]`'s id, and a localized accessible name interpolating this item's own label
421
+ (`Expand {label}`/`Collapse {label}` in the default locale — no literal fallback, so a
422
+ `registerLyraLocale()` translation or a `.strings` override always reaches it). `<lr-app-rail-group>`
423
+ cannot express this pattern: its collapsible heading *is* the toggle, so a navigable link cannot
424
+ live inside it without nesting an interactive element inside a button.
425
+
426
+ `icon-only` forwards from this item onto every `<lr-app-rail-item>` it directly owns through
427
+ `children` — including ones appended later — exactly how `<lr-app-rail-group>` forwards onto the
428
+ items and nested groups it owns. The disclosure itself never changes shape between
429
+ presentations: it is always a fixed icon-button-sized square beside `[part="base"]`, reusing the
430
+ same hover/active/focus tokens as the link/button (`--lr-app-rail-item-hover-bg` etc.) rather than
431
+ a second disclosure-only set. There is no ancestor-current treatment — `<lr-app-rail-group>` has
432
+ no equivalent concept for a group containing the current item, so none is invented here either; a
433
+ current descendant stays perceivable only through its own `current` property.
388
434
 
389
435
  Both wrappers (`[part="meta"]`, `[part="end"]`) are hidden while empty, so an item using neither
390
436
  renders exactly as before. Note that while the mobile overlay is open, a click anywhere in the
@@ -393,10 +439,16 @@ nav-slot behaviour, not new to these slots.
393
439
 
394
440
  **CSS parts:** `base`, `icon`, `label`, `current-indicator` (a decorative inline indicator rendered
395
441
  only while the item is `current`/`aria-current="page"`, mirroring `<lr-conversation-item>`'s
396
- shipped `active-indicator` part), `tooltip` (the hover/focus label flyout, only rendered while
397
- `tooltip` is set, the item is `icon-only`, and it is hovered or focused), `meta` (the wrapper around
398
- the `meta` slot, hidden while empty) and `end` (the wrapper around the `end` slot, hidden while
399
- empty).
442
+ shipped `active-indicator` part suppressed by default while `icon-only`, see the current-ring
443
+ tokens below), `tooltip` (the hover/focus label flyout, only rendered while `tooltip` is set, the
444
+ item is `icon-only`, and it is hovered or focused), `meta` (the wrapper around the `meta` slot,
445
+ hidden while empty), `end` (the wrapper around the `end` slot, hidden while empty), `toggle` (the
446
+ `children` disclosure, rendered only while something is slotted into `children`; a sibling of
447
+ `base`, never nested inside it), `toggle-icon` (the wrapper around the disclosure chevron,
448
+ direction-aware through this wrapper's own `transform` — mirrors `<lr-app-rail-group>`'s own
449
+ `[part="toggle-icon"]`) and `children` (the wrapper around the `children` slot, rendered only
450
+ alongside `toggle`; hidden — but present, so `aria-controls` keeps resolving — while `expanded` is
451
+ `false`).
400
452
 
401
453
  **Themeable custom properties:** `--lr-app-rail-item-current-bg` (default
402
454
  `var(--lr-color-brand-quiet)`), `--lr-app-rail-item-current-color` (default
@@ -415,6 +467,16 @@ before. `--lr-app-rail-item-current-font-weight` mirrors `<lr-stepper>`'s
415
467
  `--lr-app-rail-item-current-indicator-width` (default `var(--lr-size-2px)`), and
416
468
  `--lr-app-rail-item-current-indicator-inset-inline` (default `0 auto`; set `auto 0` to place the
417
469
  indicator at the inline-end edge instead) theme `[part="current-indicator"]`.
470
+ `--lr-app-rail-item-current-indicator-display` (no default; unset resolves to `none` while
471
+ `icon-only`) restores the indicator bar in icon-only presentation — a full-height edge bar reads
472
+ as a rendering glitch on the square icon-only tile, so it is suppressed there by default; full
473
+ presentation is unaffected either way, since its own `[part="current-indicator"]` rule declares no
474
+ `display` at all. `--lr-app-rail-item-current-ring` (no default; unset resolves to `none` in full
475
+ presentation and an inset ring in icon-only presentation) sets `box-shadow` on `[part="base"]`
476
+ while current: unset, icon-only gets an inset ring automatically — the non-color-only signal
477
+ (WCAG 1.4.1) that replaces the bar suppressed there, since full presentation already conveys
478
+ current state through the indicator bar and `--lr-app-rail-item-current-font-weight`. Setting this
479
+ token explicitly applies the same value in both presentations.
418
480
  Ordinary interaction states are independently inheritable through
419
481
  `--lr-app-rail-item-hover-bg`, `--lr-app-rail-item-hover-color`,
420
482
  `--lr-app-rail-item-active-bg`, and `--lr-app-rail-item-active-color`, again retaining the former
@@ -432,7 +494,22 @@ floor-clamped since the icon is decorative, not itself a pointer target), and
432
494
  is retuned while family/weight/line-height stay inherited) retune the row's geometry.
433
495
  While `icon-only`, `[part="base"]` resolves to a square hit target matching the icon-button
434
496
  footprint used elsewhere in this library (`aspect-ratio: 1` against its already floor-clamped
435
- block size) instead of stretching across the rail's icon column.
497
+ block size) instead of stretching across the rail's icon column. `--lr-app-rail-item-icon-only-size`
498
+ (no default) sizes that square directly — both `inline-size` and `block-size`, and the row's own
499
+ `min-block-size` floor — independent of `--lr-app-rail-item-min-block-size`, so a taller expanded
500
+ row and an icon-only square pinned to `--lr-icon-button-size` can coexist. Unset, the square is
501
+ still derived via `aspect-ratio: 1` against the row's block size exactly as before.
502
+
503
+ **`--lr-positioning-strategy`** (16.0.0) — the icon-only flyout tooltip reads this same cascading
504
+ `absolute`/`fixed` override documented on `<lr-popover>` when it is (re)positioned, falling back to
505
+ its own `fixed` default when nothing is set. There is no per-instance `positioning-strategy`
506
+ property on `<lr-app-rail-item>`; set the custom property on `:root`, a theme, or one clipping
507
+ ancestor to change every unset rail item's flyout beneath it.
508
+
509
+ `--lr-app-rail-item-indent` (default `var(--lr-space-l)`) sets `[part="children"]`'s
510
+ `padding-inline-start`. Applied once per nesting level — a doubly-nested `children` list compounds
511
+ two insets automatically, since each level's own `[part="children"]` applies the token again.
512
+ Logical, so it mirrors under `dir="rtl"` with no separate rule.
436
513
 
437
514
  **Optional peer deps:** none.
438
515
 
@@ -79,6 +79,27 @@ painted surface sits one boundary deeper),
79
79
  hidden via CSS by default, exposed as a part only so a consumer can override that with
80
80
  `::part(hidden-input)` in the unlikely case their integration needs to).
81
81
 
82
+ **Migrating a pre-16.0.0 `::part()` rule.** This component's icon-only action is a composed
83
+ `<lr-icon-button>`, so the part naming that action now names the composed child's HOST, which
84
+ paints nothing. A `border`, `background` or `border-radius` set on it is silently dead — only
85
+ `color` still appears to work, because it inherits, which makes such a rule look half-alive rather
86
+ than broken. Set `--lr-icon-button-background`/`-color`/`-border`/`-radius` (and their
87
+ `-hover`/`-active` variants) on this element or an ancestor instead: the composed control reads
88
+ those public tokens ahead of any default this component supplies. For SIZE use
89
+ `--lr-theme-icon-button-size`, not `--lr-icon-button-size` — every `LyraElement` re-declares the
90
+ latter on its own `:host`, so it never reaches a composed child (see `llms/tokens.md`).
91
+
92
+ **An ancestor's public border wins over this component's own relayed default, not just its
93
+ absence.** Unlike most composing components, the `outlined`/`filled-outlined` appearances here DO
94
+ relay a non-zero `--_lr-icon-button-border-default` (a themed edge) into the trigger's private
95
+ fallback tier. That does not change the resolution order: `--lr-icon-button-border` (and its
96
+ `-hover`/`-active` variants) is still the FIRST arm of the token chain, read by the composed
97
+ trigger ahead of whatever this component relays, so setting it on this element or an ancestor
98
+ overrides the outlined edge exactly as it overrides the `plain`/`filled`/`accent` appearances'
99
+ zero default. The private relay is only this component's own default opinion, never a gate the
100
+ public token must pass through. Size remains the one exception that does not cross this way: use
101
+ `--lr-theme-icon-button-size`, never `--lr-icon-button-size`, as noted above.
102
+
82
103
  **Themeable custom properties:** shared tokens only — `--lr-space-xs`, `--lr-color-text`/
83
104
  `-text-quiet`, `--lr-icon-button-size`, `--lr-focus-ring-*`, `--lr-opacity-disabled`,
84
105
  `--lr-radius`, `--lr-transition-fast`.
@@ -28,9 +28,10 @@ of every entry in these lists.**
28
28
  **Properties:** `description`, `grid`, `axes`, `compact`, `indexAxis` (`index-axis`), `label`, `hiddenDatasets`, `legendPosition`
29
29
  (`legend-position`), `hiddenDatums`, `legendMode` (`legend-mode`), `legendDisplay` (`legend-display`),
30
30
  `max`, `min`, `plugins`, `scaleType` (`scale-type`), `annotations`,
31
- `stacked`, `withoutAnimation` (`without-animation`),
31
+ `stacked`, `stackedAxes`, `withoutAnimation` (`without-animation`),
32
32
  `withoutLegend` (`without-legend`), `withoutTooltip` (`without-tooltip`), `xLabel` (`x-label`),
33
- `yLabel` (`y-label`), plus additive `labels`, `datasets`, `valueFormatter`, `formatter`, `area`, `zoom`,
33
+ `yLabel` (`y-label`), plus additive `labels`, `datasets`, `valueFormatter`, `formatter`,
34
+ `tooltipTitleFormatter`, `tooltipFooterFormatter`, `area`, `zoom`,
34
35
  `height`, `y2Label` (`y2-label`), `beginAtZero` (`begin-at-zero`), `dataLabels`
35
36
  (`data-labels`), `stackTotals` (`stack-totals`), `config`, `showDataTable`
36
37
  (`show-data-table`), `dataTableToggle` (`data-table-toggle`), `chartArea` (readonly), and `chart`.
@@ -28,9 +28,10 @@ of every entry in these lists.**
28
28
  **Properties:** `description`, `grid`, `axes`, `compact`, `indexAxis` (`index-axis`), `label`, `hiddenDatasets`, `legendPosition`
29
29
  (`legend-position`), `hiddenDatums`, `legendMode` (`legend-mode`), `legendDisplay` (`legend-display`),
30
30
  `max`, `min`, `plugins`, `scaleType` (`scale-type`), `annotations`,
31
- `stacked`, `withoutAnimation` (`without-animation`),
31
+ `stacked`, `stackedAxes`, `withoutAnimation` (`without-animation`),
32
32
  `withoutLegend` (`without-legend`), `withoutTooltip` (`without-tooltip`), `xLabel` (`x-label`),
33
- `yLabel` (`y-label`), plus additive `labels`, `datasets`, `valueFormatter`, `formatter`, `area`, `zoom`,
33
+ `yLabel` (`y-label`), plus additive `labels`, `datasets`, `valueFormatter`, `formatter`,
34
+ `tooltipTitleFormatter`, `tooltipFooterFormatter`, `area`, `zoom`,
34
35
  `height`, `y2Label` (`y2-label`), `beginAtZero` (`begin-at-zero`), `dataLabels`
35
36
  (`data-labels`), `stackTotals` (`stack-totals`), `config`, `showDataTable`
36
37
  (`show-data-table`), `dataTableToggle` (`data-table-toggle`), `chartArea` (readonly), and `chart`.
@@ -77,6 +77,16 @@ The surface chrome lives on the custom-element host, not inside `base`. Ordinary
77
77
  work directly and take normal author precedence. `inline` removes the host's border, background,
78
78
  and padding.
79
79
 
80
+ **Migrating a pre-16.0.0 `::part()` rule.** This component's icon-only action is a composed
81
+ `<lr-icon-button>`, so the part naming that action now names the composed child's HOST, which
82
+ paints nothing. A `border`, `background` or `border-radius` set on it is silently dead — only
83
+ `color` still appears to work, because it inherits, which makes such a rule look half-alive rather
84
+ than broken. Set `--lr-icon-button-background`/`-color`/`-border`/`-radius` (and their
85
+ `-hover`/`-active` variants) on this element or an ancestor instead: the composed control reads
86
+ those public tokens ahead of any default this component supplies. For SIZE use
87
+ `--lr-theme-icon-button-size`, not `--lr-icon-button-size` — every `LyraElement` re-declares the
88
+ latter on its own `:host`, so it never reaches a composed child (see `llms/tokens.md`).
89
+
80
90
  **Themeable custom properties:** `--lr-callout-background`, `--lr-callout-color`, and
81
91
  `--lr-callout-border` read the inherited generic semantic quiet/loud slots, with brand quiet/loud
82
92
  as their standalone fallback. An explicit `variant` maps all generic slots locally; leaving it