@aceshooting/lyra-ui 1.2.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (384) hide show
  1. package/README.md +98 -14
  2. package/custom-elements.json +30279 -12124
  3. package/dist/components/app-rail/app-rail-item.d.ts +30 -0
  4. package/dist/components/app-rail/app-rail-item.js +68 -0
  5. package/dist/components/app-rail/app-rail-item.styles.d.ts +1 -0
  6. package/dist/components/app-rail/app-rail-item.styles.js +65 -0
  7. package/dist/components/app-rail/app-rail.d.ts +168 -0
  8. package/dist/components/app-rail/app-rail.js +419 -0
  9. package/dist/components/app-rail/app-rail.styles.d.ts +1 -0
  10. package/dist/components/app-rail/app-rail.styles.js +128 -0
  11. package/dist/components/attachment-chip/attachment-chip.d.ts +141 -0
  12. package/dist/components/attachment-chip/attachment-chip.js +356 -0
  13. package/dist/components/attachment-chip/attachment-chip.styles.d.ts +1 -0
  14. package/dist/components/attachment-chip/attachment-chip.styles.js +184 -0
  15. package/dist/components/attachment-trigger/attachment-trigger.d.ts +96 -0
  16. package/dist/components/attachment-trigger/attachment-trigger.js +270 -0
  17. package/dist/components/attachment-trigger/attachment-trigger.styles.d.ts +1 -0
  18. package/dist/components/attachment-trigger/attachment-trigger.styles.js +90 -0
  19. package/dist/components/chart/bar-chart.js +2 -18
  20. package/dist/components/chart/box-plot.d.ts +25 -1
  21. package/dist/components/chart/box-plot.js +147 -7
  22. package/dist/components/chart/box-plot.styles.js +13 -0
  23. package/dist/components/chart/bubble-chart.js +2 -18
  24. package/dist/components/chart/chart-loader.d.ts +44 -13
  25. package/dist/components/chart/chart-loader.js +65 -18
  26. package/dist/components/chart/chart.d.ts +55 -12
  27. package/dist/components/chart/chart.js +247 -49
  28. package/dist/components/chart/doughnut-chart.js +2 -18
  29. package/dist/components/chart/histogram-bin.d.ts +7 -1
  30. package/dist/components/chart/histogram-bin.js +32 -14
  31. package/dist/components/chart/histogram.js +8 -16
  32. package/dist/components/chart/line-chart.js +2 -18
  33. package/dist/components/chart/lite-chart.d.ts +134 -3
  34. package/dist/components/chart/lite-chart.js +382 -67
  35. package/dist/components/chart/lite-chart.styles.js +9 -0
  36. package/dist/components/chart/pie-chart.js +2 -18
  37. package/dist/components/chart/polar-area-chart.js +2 -18
  38. package/dist/components/chart/radar-chart.js +2 -18
  39. package/dist/components/chart/scatter-chart.js +2 -18
  40. package/dist/components/chat-composer/chat-composer.d.ts +133 -0
  41. package/dist/components/chat-composer/chat-composer.js +366 -0
  42. package/dist/components/chat-composer/chat-composer.styles.d.ts +1 -0
  43. package/dist/components/chat-composer/chat-composer.styles.js +145 -0
  44. package/dist/components/chat-message/chat-message.d.ts +141 -0
  45. package/dist/components/chat-message/chat-message.js +331 -0
  46. package/dist/components/chat-message/chat-message.styles.d.ts +1 -0
  47. package/dist/components/chat-message/chat-message.styles.js +203 -0
  48. package/dist/components/checkbox/checkbox.d.ts +117 -0
  49. package/dist/components/checkbox/checkbox.js +353 -0
  50. package/dist/components/checkbox/checkbox.styles.d.ts +1 -0
  51. package/dist/components/checkbox/checkbox.styles.js +77 -0
  52. package/dist/components/chip/chip-group.d.ts +56 -0
  53. package/dist/components/chip/chip-group.js +130 -0
  54. package/dist/components/chip/chip-group.styles.d.ts +1 -0
  55. package/dist/components/chip/chip-group.styles.js +57 -0
  56. package/dist/components/chip/chip.d.ts +64 -0
  57. package/dist/components/chip/chip.js +122 -0
  58. package/dist/components/chip/chip.styles.d.ts +1 -0
  59. package/dist/components/chip/chip.styles.js +115 -0
  60. package/dist/components/citation-badge/citation-badge.d.ts +113 -0
  61. package/dist/components/citation-badge/citation-badge.js +318 -0
  62. package/dist/components/citation-badge/citation-badge.styles.d.ts +1 -0
  63. package/dist/components/citation-badge/citation-badge.styles.js +96 -0
  64. package/dist/components/code-block/code-block.d.ts +127 -0
  65. package/dist/components/code-block/code-block.js +382 -0
  66. package/dist/components/code-block/code-block.styles.d.ts +1 -0
  67. package/dist/components/code-block/code-block.styles.js +187 -0
  68. package/dist/components/code-block/code-loader.d.ts +87 -0
  69. package/dist/components/code-block/code-loader.js +142 -0
  70. package/dist/components/combobox/combobox.d.ts +65 -6
  71. package/dist/components/combobox/combobox.js +258 -48
  72. package/dist/components/combobox/combobox.styles.js +3 -3
  73. package/dist/components/combobox/option.d.ts +5 -1
  74. package/dist/components/combobox/option.js +35 -0
  75. package/dist/components/context-meter/context-meter.d.ts +53 -0
  76. package/dist/components/context-meter/context-meter.js +159 -0
  77. package/dist/components/context-meter/context-meter.styles.d.ts +1 -0
  78. package/dist/components/context-meter/context-meter.styles.js +114 -0
  79. package/dist/components/conversation-item/conversation-item.d.ts +125 -0
  80. package/dist/components/conversation-item/conversation-item.js +331 -0
  81. package/dist/components/conversation-item/conversation-item.styles.d.ts +1 -0
  82. package/dist/components/conversation-item/conversation-item.styles.js +155 -0
  83. package/dist/components/date-picker/calendar-core.d.ts +24 -0
  84. package/dist/components/date-picker/calendar-core.js +51 -4
  85. package/dist/components/date-picker/date-input.d.ts +100 -9
  86. package/dist/components/date-picker/date-input.js +383 -66
  87. package/dist/components/date-picker/date-picker.d.ts +35 -4
  88. package/dist/components/date-picker/date-picker.js +171 -44
  89. package/dist/components/dialog/confirm.d.ts +40 -0
  90. package/dist/components/dialog/confirm.js +76 -0
  91. package/dist/components/dialog/dialog.d.ts +129 -0
  92. package/dist/components/dialog/dialog.js +288 -0
  93. package/dist/components/dialog/dialog.styles.d.ts +1 -0
  94. package/dist/components/dialog/dialog.styles.js +96 -0
  95. package/dist/components/dock-panel/dock-panel.d.ts +142 -0
  96. package/dist/components/dock-panel/dock-panel.js +359 -0
  97. package/dist/components/dock-panel/dock-panel.styles.d.ts +1 -0
  98. package/dist/components/dock-panel/dock-panel.styles.js +159 -0
  99. package/dist/components/document-preview/document-preview.d.ts +143 -0
  100. package/dist/components/document-preview/document-preview.js +388 -0
  101. package/dist/components/document-preview/document-preview.styles.d.ts +1 -0
  102. package/dist/components/document-preview/document-preview.styles.js +191 -0
  103. package/dist/components/empty/empty.d.ts +1 -2
  104. package/dist/components/empty/empty.js +18 -12
  105. package/dist/components/empty/empty.styles.js +0 -3
  106. package/dist/components/export-button/csv.js +1 -1
  107. package/dist/components/export-button/export-button.d.ts +12 -0
  108. package/dist/components/export-button/export-button.js +35 -5
  109. package/dist/components/export-button/export-button.styles.js +5 -1
  110. package/dist/components/file-input/accept.js +2 -0
  111. package/dist/components/file-input/file-input.d.ts +10 -1
  112. package/dist/components/file-input/file-input.js +36 -5
  113. package/dist/components/flag/flag.d.ts +29 -13
  114. package/dist/components/flag/flag.js +54 -14
  115. package/dist/components/flag/flag.styles.js +1 -1
  116. package/dist/components/flag/language-map.d.ts +4 -1
  117. package/dist/components/flag/language-map.js +6 -3
  118. package/dist/components/gauge/gauge.d.ts +10 -1
  119. package/dist/components/gauge/gauge.js +41 -13
  120. package/dist/components/generation-status/generation-status.d.ts +117 -0
  121. package/dist/components/generation-status/generation-status.js +327 -0
  122. package/dist/components/generation-status/generation-status.styles.d.ts +1 -0
  123. package/dist/components/generation-status/generation-status.styles.js +84 -0
  124. package/dist/components/graph/graph.d.ts +37 -3
  125. package/dist/components/graph/graph.js +132 -20
  126. package/dist/components/heatmap/calendar-grid.d.ts +19 -7
  127. package/dist/components/heatmap/calendar-grid.js +42 -18
  128. package/dist/components/heatmap/heatmap-scale.d.ts +11 -1
  129. package/dist/components/heatmap/heatmap-scale.js +14 -2
  130. package/dist/components/heatmap/heatmap.d.ts +227 -12
  131. package/dist/components/heatmap/heatmap.js +488 -93
  132. package/dist/components/json-viewer/json-viewer.d.ts +70 -0
  133. package/dist/components/json-viewer/json-viewer.js +361 -0
  134. package/dist/components/json-viewer/json-viewer.styles.d.ts +1 -0
  135. package/dist/components/json-viewer/json-viewer.styles.js +177 -0
  136. package/dist/components/kbd/kbd.d.ts +77 -0
  137. package/dist/components/kbd/kbd.js +231 -0
  138. package/dist/components/kbd/kbd.styles.d.ts +1 -0
  139. package/dist/components/kbd/kbd.styles.js +52 -0
  140. package/dist/components/live-region/live-region.d.ts +90 -0
  141. package/dist/components/live-region/live-region.js +189 -0
  142. package/dist/components/live-region/live-region.styles.d.ts +1 -0
  143. package/dist/components/live-region/live-region.styles.js +10 -0
  144. package/dist/components/map/map.d.ts +32 -7
  145. package/dist/components/map/map.js +133 -32
  146. package/dist/components/markdown/markdown-loader.d.ts +58 -0
  147. package/dist/components/markdown/markdown-loader.js +77 -0
  148. package/dist/components/markdown/markdown.d.ts +119 -0
  149. package/dist/components/markdown/markdown.js +389 -0
  150. package/dist/components/markdown/markdown.styles.d.ts +1 -0
  151. package/dist/components/markdown/markdown.styles.js +88 -0
  152. package/dist/components/media-card/media-card.d.ts +130 -0
  153. package/dist/components/media-card/media-card.js +273 -0
  154. package/dist/components/media-card/media-card.styles.d.ts +1 -0
  155. package/dist/components/media-card/media-card.styles.js +132 -0
  156. package/dist/components/mention-popover/mention-popover.d.ts +203 -0
  157. package/dist/components/mention-popover/mention-popover.js +493 -0
  158. package/dist/components/mention-popover/mention-popover.styles.d.ts +1 -0
  159. package/dist/components/mention-popover/mention-popover.styles.js +101 -0
  160. package/dist/components/menu/menu-item.d.ts +91 -0
  161. package/dist/components/menu/menu-item.js +206 -0
  162. package/dist/components/menu/menu-item.styles.d.ts +1 -0
  163. package/dist/components/menu/menu-item.styles.js +75 -0
  164. package/dist/components/menu/menu.d.ts +167 -0
  165. package/dist/components/menu/menu.js +461 -0
  166. package/dist/components/menu/menu.styles.d.ts +1 -0
  167. package/dist/components/menu/menu.styles.js +67 -0
  168. package/dist/components/model-select/model-select.d.ts +170 -0
  169. package/dist/components/model-select/model-select.js +588 -0
  170. package/dist/components/model-select/model-select.styles.d.ts +1 -0
  171. package/dist/components/model-select/model-select.styles.js +203 -0
  172. package/dist/components/model-settings-panel/model-settings-panel.d.ts +93 -0
  173. package/dist/components/model-settings-panel/model-settings-panel.js +209 -0
  174. package/dist/components/model-settings-panel/model-settings-panel.styles.d.ts +1 -0
  175. package/dist/components/model-settings-panel/model-settings-panel.styles.js +82 -0
  176. package/dist/components/playback/playback.d.ts +19 -3
  177. package/dist/components/playback/playback.js +109 -33
  178. package/dist/components/playback/playback.styles.js +6 -1
  179. package/dist/components/responsive-panel/responsive-panel.d.ts +163 -0
  180. package/dist/components/responsive-panel/responsive-panel.js +363 -0
  181. package/dist/components/responsive-panel/responsive-panel.styles.d.ts +1 -0
  182. package/dist/components/responsive-panel/responsive-panel.styles.js +103 -0
  183. package/dist/components/result-card/result-card.d.ts +50 -0
  184. package/dist/components/result-card/result-card.js +89 -0
  185. package/dist/components/result-card/result-card.styles.d.ts +1 -0
  186. package/dist/components/result-card/result-card.styles.js +49 -0
  187. package/dist/components/result-card/result-field.d.ts +36 -0
  188. package/dist/components/result-card/result-field.js +87 -0
  189. package/dist/components/result-card/result-field.styles.d.ts +1 -0
  190. package/dist/components/result-card/result-field.styles.js +32 -0
  191. package/dist/components/select/select.d.ts +84 -4
  192. package/dist/components/select/select.js +251 -36
  193. package/dist/components/skeleton/skeleton.d.ts +3 -0
  194. package/dist/components/skeleton/skeleton.js +7 -1
  195. package/dist/components/skeleton/skeleton.styles.js +5 -4
  196. package/dist/components/slider/slider.d.ts +141 -0
  197. package/dist/components/slider/slider.js +467 -0
  198. package/dist/components/slider/slider.styles.d.ts +1 -0
  199. package/dist/components/slider/slider.styles.js +87 -0
  200. package/dist/components/source-card/source-card.d.ts +104 -0
  201. package/dist/components/source-card/source-card.js +195 -0
  202. package/dist/components/source-card/source-card.styles.d.ts +1 -0
  203. package/dist/components/source-card/source-card.styles.js +69 -0
  204. package/dist/components/source-list/source-list.d.ts +63 -0
  205. package/dist/components/source-list/source-list.js +130 -0
  206. package/dist/components/source-list/source-list.styles.d.ts +1 -0
  207. package/dist/components/source-list/source-list.styles.js +59 -0
  208. package/dist/components/sparkline/sparkline.js +58 -20
  209. package/dist/components/split/split.d.ts +224 -5
  210. package/dist/components/split/split.js +617 -43
  211. package/dist/components/split/split.styles.js +47 -0
  212. package/dist/components/stat/stat.d.ts +15 -4
  213. package/dist/components/stat/stat.js +53 -12
  214. package/dist/components/stream-status/stream-status.d.ts +126 -0
  215. package/dist/components/stream-status/stream-status.js +292 -0
  216. package/dist/components/stream-status/stream-status.styles.d.ts +1 -0
  217. package/dist/components/stream-status/stream-status.styles.js +103 -0
  218. package/dist/components/streaming-text/streaming-text.d.ts +104 -0
  219. package/dist/components/streaming-text/streaming-text.js +224 -0
  220. package/dist/components/streaming-text/streaming-text.styles.d.ts +1 -0
  221. package/dist/components/streaming-text/streaming-text.styles.js +63 -0
  222. package/dist/components/switch/switch.d.ts +103 -0
  223. package/dist/components/switch/switch.js +250 -0
  224. package/dist/components/switch/switch.styles.d.ts +1 -0
  225. package/dist/components/switch/switch.styles.js +75 -0
  226. package/dist/components/table/table.d.ts +89 -5
  227. package/dist/components/table/table.js +243 -26
  228. package/dist/components/table/table.styles.js +6 -1
  229. package/dist/components/tabs/tabs.d.ts +74 -0
  230. package/dist/components/tabs/tabs.js +254 -0
  231. package/dist/components/tabs/tabs.styles.d.ts +1 -0
  232. package/dist/components/tabs/tabs.styles.js +74 -0
  233. package/dist/components/thinking-panel/thinking-panel.d.ts +123 -0
  234. package/dist/components/thinking-panel/thinking-panel.js +260 -0
  235. package/dist/components/thinking-panel/thinking-panel.styles.d.ts +1 -0
  236. package/dist/components/thinking-panel/thinking-panel.styles.js +123 -0
  237. package/dist/components/time-range/time-range.d.ts +59 -2
  238. package/dist/components/time-range/time-range.js +163 -67
  239. package/dist/components/toast/toast-item.d.ts +12 -2
  240. package/dist/components/toast/toast-item.js +106 -44
  241. package/dist/components/toast/toast-item.styles.js +59 -28
  242. package/dist/components/toast/toast.js +17 -5
  243. package/dist/components/toast/toaster.js +10 -1
  244. package/dist/components/tool-approval-dialog/tool-approval-dialog.d.ts +131 -0
  245. package/dist/components/tool-approval-dialog/tool-approval-dialog.js +329 -0
  246. package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.d.ts +1 -0
  247. package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.js +160 -0
  248. package/dist/components/tool-call-chip/tool-call-chip.d.ts +105 -0
  249. package/dist/components/tool-call-chip/tool-call-chip.js +349 -0
  250. package/dist/components/tool-call-chip/tool-call-chip.styles.d.ts +1 -0
  251. package/dist/components/tool-call-chip/tool-call-chip.styles.js +203 -0
  252. package/dist/components/tool-param-form/tool-param-form.d.ts +206 -0
  253. package/dist/components/tool-param-form/tool-param-form.js +610 -0
  254. package/dist/components/tool-param-form/tool-param-form.styles.d.ts +1 -0
  255. package/dist/components/tool-param-form/tool-param-form.styles.js +75 -0
  256. package/dist/components/tool-result-dialog/tool-result-dialog.d.ts +122 -0
  257. package/dist/components/tool-result-dialog/tool-result-dialog.js +358 -0
  258. package/dist/components/tool-result-dialog/tool-result-dialog.styles.d.ts +1 -0
  259. package/dist/components/tool-result-dialog/tool-result-dialog.styles.js +176 -0
  260. package/dist/components/tool-result-view/registry.d.ts +73 -0
  261. package/dist/components/tool-result-view/registry.js +89 -0
  262. package/dist/components/tool-result-view/tool-result-view.d.ts +58 -0
  263. package/dist/components/tool-result-view/tool-result-view.js +152 -0
  264. package/dist/components/tool-result-view/tool-result-view.styles.d.ts +1 -0
  265. package/dist/components/tool-result-view/tool-result-view.styles.js +13 -0
  266. package/dist/components/tool-select-dialog/tool-select-dialog.d.ts +151 -0
  267. package/dist/components/tool-select-dialog/tool-select-dialog.js +350 -0
  268. package/dist/components/tool-select-dialog/tool-select-dialog.styles.d.ts +1 -0
  269. package/dist/components/tool-select-dialog/tool-select-dialog.styles.js +191 -0
  270. package/dist/components/tree/tree-node.d.ts +15 -3
  271. package/dist/components/tree/tree-node.js +20 -7
  272. package/dist/components/tree/tree.d.ts +25 -10
  273. package/dist/components/tree/tree.js +39 -31
  274. package/dist/components/typing-indicator/typing-indicator.d.ts +70 -0
  275. package/dist/components/typing-indicator/typing-indicator.js +108 -0
  276. package/dist/components/typing-indicator/typing-indicator.styles.d.ts +1 -0
  277. package/dist/components/typing-indicator/typing-indicator.styles.js +132 -0
  278. package/dist/components/virtual-list/virtual-list.d.ts +210 -0
  279. package/dist/components/virtual-list/virtual-list.js +607 -0
  280. package/dist/components/virtual-list/virtual-list.styles.d.ts +1 -0
  281. package/dist/components/virtual-list/virtual-list.styles.js +56 -0
  282. package/dist/components/widget/widget.d.ts +5 -4
  283. package/dist/components/widget/widget.js +54 -120
  284. package/dist/components/widget/widget.styles.js +8 -2
  285. package/dist/components/word-cloud/word-cloud-layout.d.ts +7 -0
  286. package/dist/components/word-cloud/word-cloud-layout.js +29 -2
  287. package/dist/components/word-cloud/word-cloud.d.ts +28 -2
  288. package/dist/components/word-cloud/word-cloud.js +69 -19
  289. package/dist/components/word-cloud/word-cloud.styles.js +16 -3
  290. package/dist/internal/anchored-validity.d.ts +1 -0
  291. package/dist/internal/anchored-validity.js +86 -0
  292. package/dist/internal/announcer.d.ts +57 -0
  293. package/dist/internal/announcer.js +71 -0
  294. package/dist/internal/form-associated.d.ts +8 -0
  295. package/dist/internal/form-associated.js +98 -15
  296. package/dist/internal/group-by-recency.d.ts +50 -0
  297. package/dist/internal/group-by-recency.js +80 -0
  298. package/dist/internal/numbers.d.ts +12 -0
  299. package/dist/internal/numbers.js +26 -0
  300. package/dist/internal/overlay-manager.d.ts +51 -0
  301. package/dist/internal/overlay-manager.js +523 -0
  302. package/dist/internal/positioner.js +27 -3
  303. package/dist/internal/rtl.d.ts +23 -0
  304. package/dist/internal/rtl.js +28 -0
  305. package/dist/internal/safe-url.d.ts +12 -0
  306. package/dist/internal/safe-url.js +41 -0
  307. package/dist/internal/scroll-lock.d.ts +10 -5
  308. package/dist/internal/scroll-lock.js +30 -14
  309. package/dist/internal/tokens.styles.js +22 -10
  310. package/dist/lyra.d.ts +133 -31
  311. package/dist/lyra.js +96 -26
  312. package/llms-full.txt +4546 -183
  313. package/llms.txt +21 -5
  314. package/package.json +41 -6
  315. package/dist/components/chart/bar-chart.stories.d.ts +0 -5
  316. package/dist/components/chart/bar-chart.stories.js +0 -20
  317. package/dist/components/chart/box-plot.stories.d.ts +0 -5
  318. package/dist/components/chart/box-plot.stories.js +0 -29
  319. package/dist/components/chart/bubble-chart.stories.d.ts +0 -5
  320. package/dist/components/chart/bubble-chart.stories.js +0 -26
  321. package/dist/components/chart/chart.stories.d.ts +0 -32
  322. package/dist/components/chart/chart.stories.js +0 -141
  323. package/dist/components/chart/doughnut-chart.stories.d.ts +0 -5
  324. package/dist/components/chart/doughnut-chart.stories.js +0 -26
  325. package/dist/components/chart/histogram.stories.d.ts +0 -5
  326. package/dist/components/chart/histogram.stories.js +0 -17
  327. package/dist/components/chart/line-chart.stories.d.ts +0 -22
  328. package/dist/components/chart/line-chart.stories.js +0 -99
  329. package/dist/components/chart/lite-chart.stories.d.ts +0 -14
  330. package/dist/components/chart/lite-chart.stories.js +0 -114
  331. package/dist/components/chart/pie-chart.stories.d.ts +0 -5
  332. package/dist/components/chart/pie-chart.stories.js +0 -26
  333. package/dist/components/chart/polar-area-chart.stories.d.ts +0 -5
  334. package/dist/components/chart/polar-area-chart.stories.js +0 -20
  335. package/dist/components/chart/radar-chart.stories.d.ts +0 -5
  336. package/dist/components/chart/radar-chart.stories.js +0 -20
  337. package/dist/components/chart/scatter-chart.stories.d.ts +0 -5
  338. package/dist/components/chart/scatter-chart.stories.js +0 -31
  339. package/dist/components/combobox/combobox.stories.d.ts +0 -24
  340. package/dist/components/combobox/combobox.stories.js +0 -102
  341. package/dist/components/date-picker/date-input.stories.d.ts +0 -10
  342. package/dist/components/date-picker/date-input.stories.js +0 -48
  343. package/dist/components/date-picker/date-picker.stories.d.ts +0 -10
  344. package/dist/components/date-picker/date-picker.stories.js +0 -25
  345. package/dist/components/empty/empty.stories.d.ts +0 -7
  346. package/dist/components/empty/empty.stories.js +0 -34
  347. package/dist/components/export-button/export-button.stories.d.ts +0 -7
  348. package/dist/components/export-button/export-button.stories.js +0 -37
  349. package/dist/components/file-input/file-input.stories.d.ts +0 -7
  350. package/dist/components/file-input/file-input.stories.js +0 -19
  351. package/dist/components/flag/flag.stories.d.ts +0 -6
  352. package/dist/components/flag/flag.stories.js +0 -31
  353. package/dist/components/gauge/gauge.stories.d.ts +0 -8
  354. package/dist/components/gauge/gauge.stories.js +0 -19
  355. package/dist/components/graph/graph.stories.d.ts +0 -8
  356. package/dist/components/graph/graph.stories.js +0 -68
  357. package/dist/components/heatmap/heatmap.stories.d.ts +0 -27
  358. package/dist/components/heatmap/heatmap.stories.js +0 -179
  359. package/dist/components/map/map.stories.d.ts +0 -15
  360. package/dist/components/map/map.stories.js +0 -135
  361. package/dist/components/playback/playback.stories.d.ts +0 -7
  362. package/dist/components/playback/playback.stories.js +0 -16
  363. package/dist/components/select/select.stories.d.ts +0 -21
  364. package/dist/components/select/select.stories.js +0 -91
  365. package/dist/components/skeleton/skeleton.stories.d.ts +0 -5
  366. package/dist/components/skeleton/skeleton.stories.js +0 -16
  367. package/dist/components/sparkline/sparkline.stories.d.ts +0 -11
  368. package/dist/components/sparkline/sparkline.stories.js +0 -39
  369. package/dist/components/split/split.stories.d.ts +0 -7
  370. package/dist/components/split/split.stories.js +0 -36
  371. package/dist/components/stat/stat.stories.d.ts +0 -9
  372. package/dist/components/stat/stat.stories.js +0 -81
  373. package/dist/components/table/table.stories.d.ts +0 -12
  374. package/dist/components/table/table.stories.js +0 -67
  375. package/dist/components/time-range/time-range.stories.d.ts +0 -8
  376. package/dist/components/time-range/time-range.stories.js +0 -26
  377. package/dist/components/toast/toast.stories.d.ts +0 -8
  378. package/dist/components/toast/toast.stories.js +0 -72
  379. package/dist/components/tree/tree.stories.d.ts +0 -9
  380. package/dist/components/tree/tree.stories.js +0 -52
  381. package/dist/components/widget/widget.stories.d.ts +0 -9
  382. package/dist/components/widget/widget.stories.js +0 -74
  383. package/dist/components/word-cloud/word-cloud.stories.d.ts +0 -10
  384. package/dist/components/word-cloud/word-cloud.stories.js +0 -55
@@ -4,13 +4,14 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { html } from 'lit';
7
+ import { html, nothing } from 'lit';
8
8
  import { property, state } from 'lit/decorators.js';
9
9
  import { LyraElement } from '../../internal/lyra-element.js';
10
10
  import { defineElement } from '../../internal/prefix.js';
11
11
  import { place } from '../../internal/positioner.js';
12
12
  import { nextId } from '../../internal/a11y.js';
13
13
  import { chevronIcon, closeIcon } from '../../internal/icons.js';
14
+ import { AnchoredValidityController, VALIDITY_ANCHOR } from '../../internal/anchored-validity.js';
14
15
  import { styles } from './combobox.styles.js';
15
16
  import { LyraOption } from './option.js';
16
17
  import './option.js';
@@ -26,8 +27,11 @@ import './option.js';
26
27
  * @slot label - Custom label content.
27
28
  * @slot hint - Custom hint content.
28
29
  * @slot error - Custom error content.
29
- * @event change - The selection changed.
30
- * @event input - The user typed in the filter or changed the selection.
30
+ * @event {Event} change - The selection changed through user interaction. A bubbling,
31
+ * composed, non-cancelable Event.
32
+ * @event {InputEvent | Event} input - The user typed in the filter or changed the selection. Text
33
+ * edits expose the original InputEvent; selection changes emit a bubbling,
34
+ * composed, non-cancelable Event.
31
35
  * @event lyra-show - The listbox opened.
32
36
  * @event lyra-hide - The listbox closed.
33
37
  * @event lyra-clear - The value was cleared.
@@ -53,15 +57,15 @@ export class LyraCombobox extends LyraElement {
53
57
  static { this.formAssociated = true; }
54
58
  static { this.styles = [LyraElement.styles, styles]; }
55
59
  static { this.properties = {
60
+ multiple: { type: Boolean, reflect: true, noAccessor: true },
61
+ disabled: { type: Boolean, reflect: true, noAccessor: true },
62
+ required: { type: Boolean, reflect: true, noAccessor: true },
56
63
  value: { noAccessor: true },
64
+ name: { reflect: true, noAccessor: true },
57
65
  }; }
58
66
  constructor() {
59
67
  super();
60
- this.multiple = false;
61
68
  this.placeholder = '';
62
- this.disabled = false;
63
- this.required = false;
64
- this.name = '';
65
69
  this.label = '';
66
70
  this.hint = '';
67
71
  this.errorText = '';
@@ -69,6 +73,10 @@ export class LyraCombobox extends LyraElement {
69
73
  this.withClear = false;
70
74
  this.maxOptionsVisible = 3;
71
75
  this.emptyText = 'No results';
76
+ /** Status copy shown in the listbox while a `source` fetch is in flight. */
77
+ this.loadingText = 'Loading…';
78
+ /** Status copy shown when `maxRender` caps the row list; `{n}` is replaced with the hidden count. */
79
+ this.overflowText = '+{n} more — refine your search';
72
80
  this.filter = null;
73
81
  this.source = null;
74
82
  this.maxRender = 200;
@@ -91,16 +99,29 @@ export class LyraCombobox extends LyraElement {
91
99
  this.loading = false;
92
100
  this.asyncRows = [];
93
101
  this.sourceToken = 0;
102
+ // Guards the proactive `asyncRows` warm-up in `willUpdate()` below so it
103
+ // fires at most once per mount instead of re-running (and endlessly
104
+ // resetting the debounce timer) on every subsequent render while the fetch
105
+ // is still in flight.
106
+ this._sourceWarmed = false;
94
107
  this._selectedLabelCache = new Map();
95
108
  // Rebuilt once per render (in render(), before renderRows()) from the
96
109
  // currently-visible row set -- backs the delegated listbox click/mousedown
97
110
  // handlers' data-value lookup below, instead of each option row closing
98
111
  // over its own row object.
99
112
  this._rowsByValue = new Map();
113
+ // Tracked separately from the consumer's own `disabled` -- a native
114
+ // `<input>`'s own `disabled` IDL property/attribute is never mutated by
115
+ // fieldset cascading, so a consumer's explicit `disabled` must survive the
116
+ // fieldset re-enabling (see `formDisabledCallback` below).
117
+ this._fieldsetDisabled = false;
100
118
  this.listId = nextId('combobox-list');
101
119
  this.inputId = nextId('combobox-input');
102
120
  this._isFirstUpdate = true;
103
121
  this._selected = [];
122
+ this._multiple = false;
123
+ this._disabled = false;
124
+ this._required = false;
104
125
  // What `form.reset()` restores to. Captured exactly once, from whatever
105
126
  // `<lyra-option selected>` markup was present the first time slotted
106
127
  // options are collected (mirrors native `<select><option selected>`) —
@@ -111,6 +132,18 @@ export class LyraCombobox extends LyraElement {
111
132
  // property assignment never does).
112
133
  this._defaultSelected = [];
113
134
  this._defaultCaptured = false;
135
+ // A restored value must win over declarative selected markup collected by
136
+ // the first asynchronous slotchange. Cleared by the next ordinary value write.
137
+ this._restoredStateActive = false;
138
+ // Hand-written accessor (mirrors the `value` accessor below, and Task 2's
139
+ // `FormAssociated.name` in `../../internal/form-associated.ts`): a
140
+ // form-associated custom element's submitted entry name is resolved by the
141
+ // browser from the live `name` *content attribute*, read synchronously at
142
+ // FormData-construction/submit time (see `syncFormValue()` below) -- Lit's
143
+ // async (microtask-deferred) `reflect: true` alone would leave a
144
+ // property-only assignment like `el.name = 'b'` invisible to a same-tick
145
+ // `new FormData(form)`/submit, so the attribute write happens here instead.
146
+ this._name = '';
114
147
  this.collectOptions = (e) => {
115
148
  const slot = e.target;
116
149
  const previous = new Set(this.options);
@@ -128,7 +161,7 @@ export class LyraCombobox extends LyraElement {
128
161
  // after the user has picked something.
129
162
  const declared = this.options.filter((o) => o.selected).map((o) => o.value);
130
163
  this._defaultSelected = [...declared];
131
- if (declared.length) {
164
+ if (declared.length && !this._restoredStateActive) {
132
165
  this.value = this.multiple ? declared : declared[0];
133
166
  return; // `value=`'s setter already called reflectSelected()
134
167
  }
@@ -140,7 +173,7 @@ export class LyraCombobox extends LyraElement {
140
173
  // into the live selection instead of letting reflectSelected() below
141
174
  // strip their `selected` attribute back off.
142
175
  const newlySelected = this.options.filter((o) => !previous.has(o) && o.selected).map((o) => o.value);
143
- if (newlySelected.length) {
176
+ if (newlySelected.length && !this._restoredStateActive) {
144
177
  this.value = this.multiple
145
178
  ? [...new Set([...this._selected, ...newlySelected])]
146
179
  : newlySelected[newlySelected.length - 1];
@@ -149,6 +182,14 @@ export class LyraCombobox extends LyraElement {
149
182
  }
150
183
  this.reflectSelected();
151
184
  };
185
+ this.onOptionChange = () => {
186
+ // Touch the `options` array reference so Lit's change-detection sees a
187
+ // "new" value and re-renders `renderRows()`/`filtered`/`labelFor()` off
188
+ // the options' now-current data -- the *set* of options is unchanged,
189
+ // only one member's own properties are, so this skips
190
+ // collectOptions()'s selection-seeding logic entirely.
191
+ this.options = [...this.options];
192
+ };
152
193
  this.onDocPointer = (e) => {
153
194
  if (!e.composedPath().includes(this))
154
195
  this.hide();
@@ -159,7 +200,6 @@ export class LyraCombobox extends LyraElement {
159
200
  this.show();
160
201
  if (this.source)
161
202
  this.runSource(this.query);
162
- this.emit('input');
163
203
  };
164
204
  this.onInputBlur = () => {
165
205
  this.touched = true;
@@ -226,7 +266,7 @@ export class LyraCombobox extends LyraElement {
226
266
  }
227
267
  };
228
268
  this.onComboMouseDown = (e) => {
229
- if (this.disabled)
269
+ if (this.effectiveDisabled)
230
270
  return;
231
271
  if (e.target.closest('button'))
232
272
  return;
@@ -251,6 +291,26 @@ export class LyraCombobox extends LyraElement {
251
291
  this.pickRow(row);
252
292
  };
253
293
  this.internals = this.attachInternals();
294
+ this.validityController = new AnchoredValidityController(this, this.internals, () => this[VALIDITY_ANCHOR]());
295
+ }
296
+ get form() {
297
+ return this.internals.form;
298
+ }
299
+ get labels() {
300
+ return this.internals.labels;
301
+ }
302
+ get validity() {
303
+ return this.internals.validity;
304
+ }
305
+ get validationMessage() {
306
+ return this.internals.validationMessage;
307
+ }
308
+ get willValidate() {
309
+ return this.internals.willValidate;
310
+ }
311
+ /** @internal */
312
+ [VALIDITY_ANCHOR]() {
313
+ return this.renderRoot?.querySelector('[part="combobox-input"]') ?? null;
254
314
  }
255
315
  connectedCallback() {
256
316
  super.connectedCallback();
@@ -267,6 +327,62 @@ export class LyraCombobox extends LyraElement {
267
327
  this.hasErrorSlot = Array.from(this.children).some((el) => el.getAttribute('slot') === 'error');
268
328
  this.hasLabelSlot = Array.from(this.children).some((el) => el.getAttribute('slot') === 'label');
269
329
  }
330
+ // In source (async) mode, `labelFor()` can only resolve a programmatically
331
+ // -set value's label from `asyncRows` -- and nothing normally populates
332
+ // `asyncRows` until the listbox is actually opened. Fire the fetch once,
333
+ // independent of `open`, so the closed input / multi-select tag chips can
334
+ // already show the real label the very first time they render (the
335
+ // common "edit an existing record" case) instead of the raw value string.
336
+ if (!this._sourceWarmed && this.source && this._selected.length && this.asyncRows.length === 0) {
337
+ this._sourceWarmed = true;
338
+ this.runSource('');
339
+ }
340
+ }
341
+ get name() {
342
+ return this._name;
343
+ }
344
+ set name(next) {
345
+ const old = this._name;
346
+ this._name = next ?? '';
347
+ if (this._name) {
348
+ this.setAttribute('name', this._name);
349
+ }
350
+ else {
351
+ this.removeAttribute('name');
352
+ }
353
+ this.syncFormValue();
354
+ this.requestUpdate('name', old);
355
+ }
356
+ get multiple() {
357
+ return this._multiple;
358
+ }
359
+ set multiple(next) {
360
+ const old = this._multiple;
361
+ this._multiple = Boolean(next);
362
+ this.toggleAttribute('multiple', this._multiple);
363
+ this.syncFormValue();
364
+ this.requestUpdate('multiple', old);
365
+ }
366
+ get disabled() {
367
+ return this._disabled;
368
+ }
369
+ set disabled(next) {
370
+ const old = this._disabled;
371
+ this._disabled = Boolean(next);
372
+ this.toggleAttribute('disabled', this._disabled);
373
+ if (this._disabled)
374
+ this.hide();
375
+ this.requestUpdate('disabled', old);
376
+ }
377
+ get required() {
378
+ return this._required;
379
+ }
380
+ set required(next) {
381
+ const old = this._required;
382
+ this._required = Boolean(next);
383
+ this.toggleAttribute('required', this._required);
384
+ this.updateValidity();
385
+ this.requestUpdate('required', old);
270
386
  }
271
387
  /** The selected value(s): a string in single mode, a string[] in `multiple` mode. */
272
388
  get value() {
@@ -274,6 +390,7 @@ export class LyraCombobox extends LyraElement {
274
390
  }
275
391
  set value(next) {
276
392
  const old = this._selected;
393
+ this._restoredStateActive = false;
277
394
  this._selected = Array.isArray(next) ? [...next] : next ? [next] : [];
278
395
  this.syncFormValue();
279
396
  this.reflectSelected();
@@ -282,13 +399,14 @@ export class LyraCombobox extends LyraElement {
282
399
  }
283
400
  updateValidity() {
284
401
  if (this.required && this._selected.length === 0) {
285
- this.internals.setValidity({ valueMissing: true }, 'Please select an option.');
402
+ this.validityController.setValidity({ valueMissing: true }, 'Please select an option.');
286
403
  }
287
404
  else {
288
- this.internals.setValidity({});
405
+ this.validityController.setValidity({});
289
406
  }
290
407
  }
291
408
  syncFormValue() {
409
+ const state = JSON.stringify(this._selected);
292
410
  if (this.multiple) {
293
411
  // A FormData form value submits under the keys baked into the FormData
294
412
  // itself, bypassing the element's own `name` the way a plain string
@@ -297,24 +415,54 @@ export class LyraCombobox extends LyraElement {
297
415
  // inventing a shared key that would merge with any other unnamed
298
416
  // combobox in the same form.
299
417
  if (!this.name) {
300
- this.internals.setFormValue(null);
418
+ this.internals.setFormValue(null, state);
301
419
  return;
302
420
  }
303
421
  const fd = new FormData();
304
422
  for (const v of this._selected)
305
423
  fd.append(this.name, v);
306
- this.internals.setFormValue(fd);
424
+ this.internals.setFormValue(fd, state);
307
425
  }
308
426
  else {
309
- this.internals.setFormValue(this._selected[0] ?? '');
427
+ this.internals.setFormValue(this._selected[0] ?? '', state);
310
428
  }
311
429
  }
430
+ /** Effective disabled state: this element's own `disabled` OR an ancestor
431
+ * `<fieldset disabled>`'s inherited state -- mirrors native `<input>`, whose
432
+ * own `disabled` IDL property/attribute is never mutated by a fieldset. */
433
+ get effectiveDisabled() {
434
+ return this.disabled || this._fieldsetDisabled;
435
+ }
312
436
  formResetCallback() {
313
437
  this.value = [...this._defaultSelected];
314
438
  this.query = '';
315
439
  }
440
+ formStateRestoreCallback(state, _mode) {
441
+ let selected = [];
442
+ if (typeof state === 'string') {
443
+ try {
444
+ const parsed = JSON.parse(state);
445
+ if (Array.isArray(parsed) && parsed.every((value) => typeof value === 'string'))
446
+ selected = parsed;
447
+ }
448
+ catch {
449
+ // Malformed persisted state restores an empty selection.
450
+ }
451
+ }
452
+ this.value = this.multiple ? selected : (selected[0] ?? '');
453
+ this._restoredStateActive = true;
454
+ }
455
+ /**
456
+ * Called by the browser when an ancestor `<fieldset disabled>` toggles.
457
+ * Tracked separately from the consumer's own `disabled` (see
458
+ * `effectiveDisabled`) so a consumer's explicit `disabled` survives the
459
+ * fieldset re-enabling instead of being permanently overwritten.
460
+ */
316
461
  formDisabledCallback(disabled) {
317
- this.disabled = disabled;
462
+ this._fieldsetDisabled = disabled;
463
+ if (disabled)
464
+ this.hide();
465
+ this.requestUpdate();
318
466
  }
319
467
  checkValidity() {
320
468
  return this.internals.checkValidity();
@@ -325,8 +473,15 @@ export class LyraCombobox extends LyraElement {
325
473
  disconnectedCallback() {
326
474
  super.disconnectedCallback();
327
475
  this.cleanup?.();
476
+ this.cleanup = undefined;
328
477
  clearTimeout(this.sourceTimer);
329
478
  document.removeEventListener('pointerdown', this.onDocPointer);
479
+ // Reset so a reconnect (e.g. a drag-drop reparent) re-triggers
480
+ // `updated()`'s `open`-driven branch -- without this, `open` stays
481
+ // `true` across the disconnect/reconnect and `changed.has('open')` never
482
+ // fires again, leaving the listbox rendered open with no positioning and
483
+ // no outside-click listener.
484
+ this.open = false;
330
485
  }
331
486
  reflectSelected() {
332
487
  const sel = new Set(this._selected);
@@ -334,7 +489,17 @@ export class LyraCombobox extends LyraElement {
334
489
  o.selected = sel.has(o.value);
335
490
  }
336
491
  labelFor(value) {
337
- return this._selectedLabelCache.get(value) ?? this.options.find((o) => o.value === value)?.label ?? value;
492
+ // Checked in order: an explicit pick's own label (works even after the
493
+ // source rows backing it have since changed), a slotted `<lyra-option>`
494
+ // (local mode), then the last-fetched async row set (source mode) -- a
495
+ // value set programmatically (e.g. `el.value = 'b'` before the listbox
496
+ // has ever been opened) has no chance to have populated the first two,
497
+ // so without this last fallback it would render as the raw value string
498
+ // instead of its label.
499
+ return (this._selectedLabelCache.get(value) ??
500
+ this.options.find((o) => o.value === value)?.label ??
501
+ this.asyncRows.find((r) => r.value === value)?.label ??
502
+ value);
338
503
  }
339
504
  /** The current row set in a source-agnostic shape, before capping. */
340
505
  get effectiveRows() {
@@ -354,15 +519,27 @@ export class LyraCombobox extends LyraElement {
354
519
  const all = this.effectiveRows;
355
520
  if (all.length <= this.maxRender)
356
521
  return { rows: all, overflow: 0 };
522
+ const originalIndex = new Map(all.map((r, i) => [r, i]));
357
523
  const capped = all.slice(0, this.maxRender);
358
524
  const cappedValues = new Set(capped.map((r) => r.value));
525
+ let appendedOutOfCap = false;
359
526
  for (const v of this._selected) {
360
527
  if (!cappedValues.has(v)) {
361
528
  const selectedRow = all.find((r) => r.value === v);
362
- if (selectedRow)
529
+ if (selectedRow) {
363
530
  capped.push(selectedRow);
531
+ appendedOutOfCap = true;
532
+ }
364
533
  }
365
534
  }
535
+ if (appendedOutOfCap) {
536
+ // A preserved out-of-cap selection was just tacked onto the very end,
537
+ // regardless of its own `group` -- stable-sort back by each row's
538
+ // original position so it lands among its own group's other rows
539
+ // instead of forcing renderRows() to emit that group's label a second
540
+ // time after whatever group happens to trail the cap.
541
+ capped.sort((a, b) => originalIndex.get(a) - originalIndex.get(b));
542
+ }
366
543
  return { rows: capped, overflow: all.length - capped.length };
367
544
  }
368
545
  get filtered() {
@@ -381,7 +558,7 @@ export class LyraCombobox extends LyraElement {
381
558
  return this._selected[0] ? this.labelFor(this._selected[0]) : '';
382
559
  }
383
560
  show() {
384
- if (this.open || this.disabled)
561
+ if (this.open || this.effectiveDisabled)
385
562
  return;
386
563
  this.open = true;
387
564
  }
@@ -390,6 +567,15 @@ export class LyraCombobox extends LyraElement {
390
567
  return;
391
568
  this.open = false;
392
569
  this.activeIndex = -1;
570
+ // Single-select mode only shows `query` while `open` (see `displayValue`
571
+ // above) -- but dismissing without picking a row (blur, Escape, or an
572
+ // outside click) previously left an abandoned filter string sitting in
573
+ // `query` forever, so the *next* reopen would reappear with stale text
574
+ // and re-filter the list from it. Multiple mode is unaffected: its input
575
+ // always shows `query` regardless of `open`, by design (a persistent
576
+ // search box next to the tags).
577
+ if (!this.multiple)
578
+ this.query = '';
393
579
  }
394
580
  updated(changed) {
395
581
  if (changed.has('open')) {
@@ -420,15 +606,25 @@ export class LyraCombobox extends LyraElement {
420
606
  this.emit('lyra-hide');
421
607
  }
422
608
  }
423
- if (changed.has('required'))
424
- this.updateValidity();
609
+ if (changed.has('name'))
610
+ this.syncFormValue();
425
611
  if (changed.has('touched') || changed.has('required') || changed.has('value')) {
426
612
  this.toggleAttribute('data-invalid', this.touched && !this.internals.validity.valid);
427
613
  }
428
614
  }
615
+ /** Dispatches the platform-style value-event pair used by non-text user
616
+ * interactions. Text editing keeps and exposes the original InputEvent
617
+ * from the shadow input so its data/inputType metadata is not lost. */
618
+ emitValueEvents() {
619
+ const EventConstructor = this.ownerDocument.defaultView?.Event ?? Event;
620
+ const init = { bubbles: true, composed: true };
621
+ this.dispatchEvent(new EventConstructor('input', init));
622
+ this.dispatchEvent(new EventConstructor('change', init));
623
+ }
429
624
  pickRow(row) {
430
- if (row.disabled)
625
+ if (this.effectiveDisabled || row.disabled)
431
626
  return;
627
+ const selectionChanged = this.multiple || this._selected[0] !== row.value;
432
628
  this._selectedLabelCache.set(row.value, row.label);
433
629
  if (this.multiple) {
434
630
  const set = new Set(this._selected);
@@ -447,20 +643,25 @@ export class LyraCombobox extends LyraElement {
447
643
  // mode) matches the now-empty input instead of the stale prior query.
448
644
  if (this.source)
449
645
  this.runSource(this.query);
450
- this.emit('input');
451
- this.emit('change');
646
+ if (selectionChanged)
647
+ this.emitValueEvents();
452
648
  }
453
649
  removeValue(value) {
454
- this.value = this._selected.filter((v) => v !== value);
455
- this.emit('change');
650
+ const next = this._selected.filter((v) => v !== value);
651
+ if (next.length === this._selected.length)
652
+ return;
653
+ this.value = next;
654
+ this.emitValueEvents();
456
655
  }
457
656
  clear() {
657
+ if (this._selected.length === 0)
658
+ return;
458
659
  this.value = [];
459
660
  this.query = '';
460
661
  if (this.source)
461
662
  this.runSource(this.query);
663
+ this.emitValueEvents();
462
664
  this.emit('lyra-clear');
463
- this.emit('change');
464
665
  }
465
666
  runSource(query) {
466
667
  if (!this.source)
@@ -469,11 +670,22 @@ export class LyraCombobox extends LyraElement {
469
670
  this.sourceTimer = setTimeout(() => {
470
671
  const token = ++this.sourceToken;
471
672
  this.loading = true;
472
- this.source(query)
673
+ // `Promise.resolve().then(() => this.source!(query))` moves the call
674
+ // itself inside a `.then()` callback, so a *synchronous* throw from
675
+ // `this.source(query)` becomes a normal promise rejection the
676
+ // following `.catch()` handles, instead of escaping this `setTimeout`
677
+ // callback as an uncaught exception.
678
+ Promise.resolve()
679
+ .then(() => this.source(query))
473
680
  .then((rows) => {
474
681
  if (token !== this.sourceToken || !this.isConnected)
475
682
  return;
476
683
  this.asyncRows = rows;
684
+ })
685
+ .catch((err) => {
686
+ if (token !== this.sourceToken || !this.isConnected)
687
+ return;
688
+ console.warn('<lyra-combobox> source() rejected:', err);
477
689
  })
478
690
  .finally(() => {
479
691
  if (token === this.sourceToken)
@@ -523,6 +735,7 @@ export class LyraCombobox extends LyraElement {
523
735
  const hasHint = this.hasHintSlot || this.hint.length > 0;
524
736
  const hasError = this.hasErrorSlot || this.errorText.length > 0;
525
737
  const hasLabel = this.hasLabelSlot || this.label.length > 0;
738
+ const describedBy = [hasError ? 'combobox-error' : '', hasHint ? 'combobox-hint' : ''].filter(Boolean).join(' ');
526
739
  return html `
527
740
  <div part="form-control">
528
741
  <label part="form-control-label" for=${this.inputId} ?hidden=${!hasLabel}>
@@ -534,6 +747,7 @@ export class LyraCombobox extends LyraElement {
534
747
  >${this.labelFor(v)}<button
535
748
  part="tag__remove-button"
536
749
  type="button"
750
+ ?disabled=${this.effectiveDisabled}
537
751
  aria-label="Remove ${this.labelFor(v)}"
538
752
  @click=${(e) => {
539
753
  e.stopPropagation();
@@ -549,7 +763,8 @@ export class LyraCombobox extends LyraElement {
549
763
  id=${this.inputId}
550
764
  part="combobox-input"
551
765
  role="combobox"
552
- aria-label=${this.getAttribute('aria-label') || this.label || this.placeholder || 'Combobox'}
766
+ aria-label=${this.getAttribute('aria-label') || (hasLabel ? nothing : this.placeholder || 'Combobox')}
767
+ aria-describedby=${describedBy || nothing}
553
768
  aria-expanded=${this.open ? 'true' : 'false'}
554
769
  aria-controls=${this.listId}
555
770
  aria-activedescendant=${activeId}
@@ -559,7 +774,7 @@ export class LyraCombobox extends LyraElement {
559
774
  autocomplete="off"
560
775
  .value=${this.displayValue}
561
776
  placeholder=${hasValue && !this.multiple ? '' : this.placeholder}
562
- ?disabled=${this.disabled}
777
+ ?disabled=${this.effectiveDisabled}
563
778
  @input=${this.onInput}
564
779
  @keydown=${this.onKeyDown}
565
780
  @focus=${() => this.show()}
@@ -569,6 +784,7 @@ export class LyraCombobox extends LyraElement {
569
784
  ? html `<button
570
785
  part="clear-button"
571
786
  type="button"
787
+ ?disabled=${this.effectiveDisabled}
572
788
  aria-label="Clear"
573
789
  @click=${(e) => {
574
790
  e.stopPropagation();
@@ -589,40 +805,28 @@ export class LyraCombobox extends LyraElement {
589
805
  @click=${this.onListboxClick}
590
806
  >
591
807
  ${this.loading
592
- ? html `<div class="loading" role="option" aria-selected="false" aria-disabled="true">Loading…</div>`
808
+ ? html `<div class="loading" role="option" aria-selected="false" aria-disabled="true">${this.loadingText}</div>`
593
809
  : rows.length === 0
594
810
  ? html `<div class="empty" role="option" aria-selected="false" aria-disabled="true">${this.emptyText}</div>`
595
811
  : html `${this.renderRows(rows, activeId)}
596
812
  ${overflow > 0
597
- ? html `<div part="option-overflow">+${overflow} more — refine your search</div>`
813
+ ? html `<div part="option-overflow">${this.overflowText.replace('{n}', String(overflow))}</div>`
598
814
  : ''}`}
599
815
  </div>
600
- <div part="error" ?hidden=${!hasError}>
816
+ <div id="combobox-error" part="error" ?hidden=${!hasError}>
601
817
  ${this.errorText}<slot name="error" @slotchange=${this.onErrorSlotChange}></slot>
602
818
  </div>
603
- <div part="hint" ?hidden=${!hasHint}>
819
+ <div id="combobox-hint" part="hint" ?hidden=${!hasHint}>
604
820
  ${this.hint}<slot name="hint" @slotchange=${this.onHintSlotChange}></slot>
605
821
  </div>
606
822
  </div>
607
- <slot @slotchange=${this.collectOptions} hidden></slot>
823
+ <slot @slotchange=${this.collectOptions} @lyra-option-change=${this.onOptionChange} hidden></slot>
608
824
  `;
609
825
  }
610
826
  }
611
- __decorate([
612
- property({ type: Boolean, reflect: true })
613
- ], LyraCombobox.prototype, "multiple", void 0);
614
827
  __decorate([
615
828
  property()
616
829
  ], LyraCombobox.prototype, "placeholder", void 0);
617
- __decorate([
618
- property({ type: Boolean, reflect: true })
619
- ], LyraCombobox.prototype, "disabled", void 0);
620
- __decorate([
621
- property({ type: Boolean, reflect: true })
622
- ], LyraCombobox.prototype, "required", void 0);
623
- __decorate([
624
- property()
625
- ], LyraCombobox.prototype, "name", void 0);
626
830
  __decorate([
627
831
  property()
628
832
  ], LyraCombobox.prototype, "label", void 0);
@@ -644,6 +848,12 @@ __decorate([
644
848
  __decorate([
645
849
  property({ attribute: 'empty-text' })
646
850
  ], LyraCombobox.prototype, "emptyText", void 0);
851
+ __decorate([
852
+ property({ attribute: 'loading-text' })
853
+ ], LyraCombobox.prototype, "loadingText", void 0);
854
+ __decorate([
855
+ property({ attribute: 'overflow-text' })
856
+ ], LyraCombobox.prototype, "overflowText", void 0);
647
857
  __decorate([
648
858
  property({ attribute: false })
649
859
  ], LyraCombobox.prototype, "filter", void 0);
@@ -111,11 +111,11 @@ export const styles = css `
111
111
  position: fixed;
112
112
  z-index: 900;
113
113
  box-sizing: border-box;
114
- max-block-size: 18rem;
114
+ max-block-size: min(18rem, var(--lyra-positioner-available-block-size, 18rem));
115
115
  overflow-y: auto;
116
116
  inline-size: max-content;
117
- min-inline-size: 12rem;
118
- max-inline-size: min(92vw, 28rem);
117
+ min-inline-size: min(12rem, var(--lyra-positioner-available-inline-size, 12rem));
118
+ max-inline-size: min(92vw, 28rem, var(--lyra-positioner-available-inline-size, 100vw));
119
119
  padding: var(--lyra-space-xs);
120
120
  background: var(--lyra-color-surface);
121
121
  border: 1px solid var(--lyra-color-border);
@@ -1,4 +1,4 @@
1
- import { type TemplateResult } from 'lit';
1
+ import { type TemplateResult, type PropertyValues } from 'lit';
2
2
  import { LyraElement } from '../../internal/lyra-element.js';
3
3
  /**
4
4
  * `<lyra-option>` — a selectable option for `<lyra-combobox>`.
@@ -27,6 +27,10 @@ export declare class LyraOption extends LyraElement {
27
27
  dotColor: string;
28
28
  /** Resolved label: explicit non-empty `label` attribute wins, else trimmed text content. */
29
29
  get label(): string;
30
+ private labelObserver?;
31
+ connectedCallback(): void;
32
+ disconnectedCallback(): void;
33
+ protected updated(changed: PropertyValues): void;
30
34
  render(): TemplateResult;
31
35
  }
32
36
  declare global {
@@ -48,6 +48,41 @@ export class LyraOption extends LyraElement {
48
48
  const attr = this.getAttribute('label');
49
49
  return (attr ? attr : (this.textContent ?? '')).trim();
50
50
  }
51
+ connectedCallback() {
52
+ super.connectedCallback();
53
+ // `label` is derived from either the `label` attribute or `textContent` --
54
+ // neither is a Lit reactive property, so a direct mutation of either
55
+ // (e.g. `option.textContent = 'New label'`) needs its own observer to
56
+ // notify the parent combobox/select that its cached row data is stale.
57
+ this.labelObserver = new MutationObserver(() => this.emit('lyra-option-change'));
58
+ this.labelObserver.observe(this, {
59
+ attributes: true,
60
+ attributeFilter: ['label'],
61
+ childList: true,
62
+ characterData: true,
63
+ subtree: true,
64
+ });
65
+ }
66
+ disconnectedCallback() {
67
+ super.disconnectedCallback();
68
+ this.labelObserver?.disconnect();
69
+ this.labelObserver = undefined;
70
+ }
71
+ updated(changed) {
72
+ // `selected` is deliberately excluded -- the parent combobox/select
73
+ // already sets `selected` itself as *part of* rendering the current
74
+ // selection, so echoing that back as a `lyra-option-change` notification
75
+ // would trigger a redundant re-render on every selection change, rather
76
+ // than signal a genuine "this option's own data changed externally".
77
+ if (changed.has('value') ||
78
+ changed.has('disabled') ||
79
+ changed.has('group') ||
80
+ changed.has('searchText') ||
81
+ changed.has('sub') ||
82
+ changed.has('dotColor')) {
83
+ this.emit('lyra-option-change');
84
+ }
85
+ }
51
86
  render() {
52
87
  return html `<slot></slot>`;
53
88
  }