@threadlabs/looma 0.22.9 → 0.22.11

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 (417) hide show
  1. package/components/shared/overlay.js +33 -1
  2. package/components/ui-affordance-scope/ui-affordance-scope.js +2 -2
  3. package/components/ui-avatar/ui-avatar.js +5 -5
  4. package/components/ui-avatar-group/ui-avatar-group.js +5 -5
  5. package/components/ui-button/ui-button.js +1 -1
  6. package/components/ui-checkbox/ui-checkbox.js +5 -5
  7. package/components/ui-combobox/ui-combobox.js +61 -61
  8. package/components/ui-context-menu/ui-context-menu.js +6 -6
  9. package/components/ui-dialog/ui-dialog.html +6 -0
  10. package/components/ui-dialog/ui-dialog.js +11 -11
  11. package/components/ui-disclosure/ui-disclosure.js +6 -6
  12. package/components/ui-editable/ui-editable.js +6 -6
  13. package/components/ui-editor-insert-table-grid/ui-editor-insert-table-grid.js +4 -4
  14. package/components/ui-editor-mention-menu/ui-editor-mention-menu.js +8 -8
  15. package/components/ui-editor-slash-menu/ui-editor-slash-menu.js +6 -6
  16. package/components/ui-editor-table-context-menu/ui-editor-table-context-menu.js +5 -5
  17. package/components/ui-editor-table-overlay/ui-editor-table-overlay.js +4 -4
  18. package/components/ui-editor-table-toolbar/ui-editor-table-toolbar.js +5 -5
  19. package/components/ui-form-field/ui-form-field.js +4 -4
  20. package/components/ui-icon-button/ui-icon-button.js +2 -2
  21. package/components/ui-input/ui-input.js +1 -1
  22. package/components/ui-input-group/ui-input-group.html +14 -0
  23. package/components/ui-input-group/ui-input-group.js +1 -1
  24. package/components/ui-listbox/ui-listbox.js +12 -12
  25. package/components/ui-menu/ui-menu.js +7 -7
  26. package/components/ui-menu-item/ui-menu-item.js +7 -7
  27. package/components/ui-popover/ui-popover.js +4 -4
  28. package/components/ui-radio/ui-radio.js +5 -5
  29. package/components/ui-radio-group/ui-radio-group.js +6 -6
  30. package/components/ui-scroll-area/ui-scroll-area.js +1 -1
  31. package/components/ui-search-shell/ui-search-shell.html +8 -0
  32. package/components/ui-search-shell/ui-search-shell.js +17 -7
  33. package/components/ui-select/ui-select.js +1 -1
  34. package/components/ui-sidebar/ui-sidebar.js +15 -12
  35. package/components/ui-switch/ui-switch.js +5 -5
  36. package/components/ui-switcher/ui-switcher.js +1 -1
  37. package/components/ui-tabs/ui-tabs.js +5 -5
  38. package/components/ui-textarea/ui-textarea.js +1 -1
  39. package/components/ui-toast/ui-toast.js +3 -3
  40. package/components/ui-toast-region/ui-toast-region.js +5 -1
  41. package/components/ui-tooltip/ui-tooltip.js +22 -11
  42. package/components/ui-tree/ui-tree.js +4 -4
  43. package/components/ui-tree-item/ui-tree-item.js +11 -11
  44. package/dist/index.js +1 -1
  45. package/package.json +2 -2
  46. package/styles/ui-action-bar.css +1 -1
  47. package/styles/ui-affordance-scope.css +1 -1
  48. package/styles/ui-avatar-group.css +1 -1
  49. package/styles/ui-avatar.css +1 -1
  50. package/styles/ui-badge.css +1 -1
  51. package/styles/ui-breadcrumb-item.css +1 -1
  52. package/styles/ui-breadcrumbs.css +1 -1
  53. package/styles/ui-button.css +1 -1
  54. package/styles/ui-callout.css +1 -1
  55. package/styles/ui-card.css +1 -1
  56. package/styles/ui-checkbox.css +1 -1
  57. package/styles/ui-cluster.css +1 -1
  58. package/styles/ui-combobox.css +1 -1
  59. package/styles/ui-container.css +1 -1
  60. package/styles/ui-context-menu.css +1 -1
  61. package/styles/ui-cover.css +1 -1
  62. package/styles/ui-description-item.css +1 -1
  63. package/styles/ui-description-list.css +1 -1
  64. package/styles/ui-dialog.css +7 -1
  65. package/styles/ui-disclosure.css +1 -1
  66. package/styles/ui-editable.css +1 -1
  67. package/styles/ui-editor-insert-table-grid.css +1 -1
  68. package/styles/ui-editor-mention-menu-item.css +1 -1
  69. package/styles/ui-editor-mention-menu.css +1 -1
  70. package/styles/ui-editor-slash-menu-group.css +1 -1
  71. package/styles/ui-editor-slash-menu-item.css +1 -1
  72. package/styles/ui-editor-slash-menu.css +1 -1
  73. package/styles/ui-editor-table-context-menu.css +1 -1
  74. package/styles/ui-editor-table-overlay.css +1 -1
  75. package/styles/ui-editor-table-toolbar.css +1 -1
  76. package/styles/ui-editor-toolbar.css +1 -1
  77. package/styles/ui-floating-action-button.css +1 -1
  78. package/styles/ui-form-field.css +1 -1
  79. package/styles/ui-grid.css +1 -1
  80. package/styles/ui-icon-button.css +1 -1
  81. package/styles/ui-icon.css +1 -1
  82. package/styles/ui-input-group.css +17 -1
  83. package/styles/ui-input.css +1 -1
  84. package/styles/ui-list-item.css +1 -1
  85. package/styles/ui-list.css +1 -1
  86. package/styles/ui-listbox.css +1 -1
  87. package/styles/ui-menu-group.css +1 -1
  88. package/styles/ui-menu-item.css +1 -1
  89. package/styles/ui-menu.css +1 -1
  90. package/styles/ui-meter.css +1 -1
  91. package/styles/ui-nav-item.css +1 -1
  92. package/styles/ui-page-header.css +1 -1
  93. package/styles/ui-popover.css +1 -1
  94. package/styles/ui-radio-group.css +1 -1
  95. package/styles/ui-radio.css +1 -1
  96. package/styles/ui-reel.css +1 -1
  97. package/styles/ui-scroll-area.css +1 -1
  98. package/styles/ui-search-result-row.css +1 -1
  99. package/styles/ui-search-shell.css +9 -1
  100. package/styles/ui-section.css +1 -1
  101. package/styles/ui-select.css +1 -1
  102. package/styles/ui-separator.css +1 -1
  103. package/styles/ui-sidebar.css +1 -1
  104. package/styles/ui-spinner.css +1 -1
  105. package/styles/ui-stack.css +1 -1
  106. package/styles/ui-status-message.css +1 -1
  107. package/styles/ui-switch.css +1 -1
  108. package/styles/ui-switcher.css +1 -1
  109. package/styles/ui-table.css +1 -1
  110. package/styles/ui-tabs.css +1 -1
  111. package/styles/ui-text.css +1 -1
  112. package/styles/ui-textarea.css +1 -1
  113. package/styles/ui-toast-region.css +1 -1
  114. package/styles/ui-toast.css +1 -1
  115. package/styles/ui-tooltip.css +1 -1
  116. package/styles/ui-top-bar.css +1 -1
  117. package/styles/ui-tree-item.css +1 -1
  118. package/styles/ui-tree.css +1 -1
  119. package/vanilla/UiActionBar.d.ts +1 -1
  120. package/vanilla/UiActionBar.js +1 -1
  121. package/vanilla/UiAffordanceScope.d.ts +1 -1
  122. package/vanilla/UiAffordanceScope.js +1 -1
  123. package/vanilla/UiAvatar.d.ts +1 -1
  124. package/vanilla/UiAvatar.js +1 -1
  125. package/vanilla/UiAvatarGroup.d.ts +1 -1
  126. package/vanilla/UiAvatarGroup.js +1 -1
  127. package/vanilla/UiBadge.d.ts +1 -1
  128. package/vanilla/UiBadge.js +1 -1
  129. package/vanilla/UiBreadcrumbItem.d.ts +1 -1
  130. package/vanilla/UiBreadcrumbItem.js +1 -1
  131. package/vanilla/UiBreadcrumbs.d.ts +1 -1
  132. package/vanilla/UiBreadcrumbs.js +1 -1
  133. package/vanilla/UiButton.d.ts +1 -1
  134. package/vanilla/UiButton.js +1 -1
  135. package/vanilla/UiCallout.d.ts +1 -1
  136. package/vanilla/UiCallout.js +1 -1
  137. package/vanilla/UiCard.d.ts +1 -1
  138. package/vanilla/UiCard.js +1 -1
  139. package/vanilla/UiCheckbox.d.ts +1 -1
  140. package/vanilla/UiCheckbox.js +1 -1
  141. package/vanilla/UiCluster.d.ts +1 -1
  142. package/vanilla/UiCluster.js +1 -1
  143. package/vanilla/UiCombobox.d.ts +1 -1
  144. package/vanilla/UiCombobox.js +1 -1
  145. package/vanilla/UiContainer.d.ts +1 -1
  146. package/vanilla/UiContainer.js +1 -1
  147. package/vanilla/UiContextMenu.d.ts +1 -1
  148. package/vanilla/UiContextMenu.js +1 -1
  149. package/vanilla/UiCover.d.ts +1 -1
  150. package/vanilla/UiCover.js +1 -1
  151. package/vanilla/UiDescriptionItem.d.ts +1 -1
  152. package/vanilla/UiDescriptionItem.js +1 -1
  153. package/vanilla/UiDescriptionList.d.ts +1 -1
  154. package/vanilla/UiDescriptionList.js +1 -1
  155. package/vanilla/UiDialog.d.ts +1 -1
  156. package/vanilla/UiDialog.js +1 -1
  157. package/vanilla/UiDisclosure.d.ts +1 -1
  158. package/vanilla/UiDisclosure.js +1 -1
  159. package/vanilla/UiEditable.d.ts +1 -1
  160. package/vanilla/UiEditable.js +1 -1
  161. package/vanilla/UiEditorInsertTableGrid.d.ts +1 -1
  162. package/vanilla/UiEditorInsertTableGrid.js +1 -1
  163. package/vanilla/UiEditorMentionMenu.d.ts +1 -1
  164. package/vanilla/UiEditorMentionMenu.js +1 -1
  165. package/vanilla/UiEditorMentionMenuItem.d.ts +1 -1
  166. package/vanilla/UiEditorMentionMenuItem.js +1 -1
  167. package/vanilla/UiEditorSlashMenu.d.ts +1 -1
  168. package/vanilla/UiEditorSlashMenu.js +1 -1
  169. package/vanilla/UiEditorSlashMenuGroup.d.ts +1 -1
  170. package/vanilla/UiEditorSlashMenuGroup.js +1 -1
  171. package/vanilla/UiEditorSlashMenuItem.d.ts +1 -1
  172. package/vanilla/UiEditorSlashMenuItem.js +1 -1
  173. package/vanilla/UiEditorTableContextMenu.d.ts +1 -1
  174. package/vanilla/UiEditorTableContextMenu.js +1 -1
  175. package/vanilla/UiEditorTableOverlay.d.ts +1 -1
  176. package/vanilla/UiEditorTableOverlay.js +1 -1
  177. package/vanilla/UiEditorTableToolbar.d.ts +1 -1
  178. package/vanilla/UiEditorTableToolbar.js +1 -1
  179. package/vanilla/UiEditorToolbar.d.ts +1 -1
  180. package/vanilla/UiEditorToolbar.js +1 -1
  181. package/vanilla/UiFloatingActionButton.d.ts +1 -1
  182. package/vanilla/UiFloatingActionButton.js +1 -1
  183. package/vanilla/UiFormField.d.ts +1 -1
  184. package/vanilla/UiFormField.js +1 -1
  185. package/vanilla/UiGrid.d.ts +1 -1
  186. package/vanilla/UiGrid.js +1 -1
  187. package/vanilla/UiIcon.d.ts +1 -1
  188. package/vanilla/UiIcon.js +1 -1
  189. package/vanilla/UiIconButton.d.ts +1 -1
  190. package/vanilla/UiIconButton.js +1 -1
  191. package/vanilla/UiInput.d.ts +1 -1
  192. package/vanilla/UiInput.js +1 -1
  193. package/vanilla/UiInputGroup.d.ts +1 -1
  194. package/vanilla/UiInputGroup.js +1 -1
  195. package/vanilla/UiList.d.ts +1 -1
  196. package/vanilla/UiList.js +1 -1
  197. package/vanilla/UiListItem.d.ts +1 -1
  198. package/vanilla/UiListItem.js +1 -1
  199. package/vanilla/UiListbox.d.ts +1 -1
  200. package/vanilla/UiListbox.js +1 -1
  201. package/vanilla/UiMenu.d.ts +1 -1
  202. package/vanilla/UiMenu.js +1 -1
  203. package/vanilla/UiMenuGroup.d.ts +1 -1
  204. package/vanilla/UiMenuGroup.js +1 -1
  205. package/vanilla/UiMenuItem.d.ts +1 -1
  206. package/vanilla/UiMenuItem.js +1 -1
  207. package/vanilla/UiMeter.d.ts +1 -1
  208. package/vanilla/UiMeter.js +1 -1
  209. package/vanilla/UiNavItem.d.ts +1 -1
  210. package/vanilla/UiNavItem.js +1 -1
  211. package/vanilla/UiPageHeader.d.ts +1 -1
  212. package/vanilla/UiPageHeader.js +1 -1
  213. package/vanilla/UiPopover.d.ts +1 -1
  214. package/vanilla/UiPopover.js +1 -1
  215. package/vanilla/UiRadio.d.ts +1 -1
  216. package/vanilla/UiRadio.js +1 -1
  217. package/vanilla/UiRadioGroup.d.ts +1 -1
  218. package/vanilla/UiRadioGroup.js +1 -1
  219. package/vanilla/UiReel.d.ts +1 -1
  220. package/vanilla/UiReel.js +1 -1
  221. package/vanilla/UiScrollArea.d.ts +1 -1
  222. package/vanilla/UiScrollArea.js +1 -1
  223. package/vanilla/UiSearchResultRow.d.ts +1 -1
  224. package/vanilla/UiSearchResultRow.js +1 -1
  225. package/vanilla/UiSearchShell.d.ts +1 -1
  226. package/vanilla/UiSearchShell.js +1 -1
  227. package/vanilla/UiSection.d.ts +1 -1
  228. package/vanilla/UiSection.js +1 -1
  229. package/vanilla/UiSelect.d.ts +1 -1
  230. package/vanilla/UiSelect.js +1 -1
  231. package/vanilla/UiSeparator.d.ts +1 -1
  232. package/vanilla/UiSeparator.js +1 -1
  233. package/vanilla/UiSidebar.d.ts +1 -1
  234. package/vanilla/UiSidebar.js +1 -1
  235. package/vanilla/UiSpinner.d.ts +1 -1
  236. package/vanilla/UiSpinner.js +1 -1
  237. package/vanilla/UiStack.d.ts +1 -1
  238. package/vanilla/UiStack.js +1 -1
  239. package/vanilla/UiStatusMessage.d.ts +1 -1
  240. package/vanilla/UiStatusMessage.js +1 -1
  241. package/vanilla/UiSwitch.d.ts +1 -1
  242. package/vanilla/UiSwitch.js +1 -1
  243. package/vanilla/UiSwitcher.d.ts +1 -1
  244. package/vanilla/UiSwitcher.js +1 -1
  245. package/vanilla/UiTable.d.ts +1 -1
  246. package/vanilla/UiTable.js +1 -1
  247. package/vanilla/UiTabs.d.ts +1 -1
  248. package/vanilla/UiTabs.js +1 -1
  249. package/vanilla/UiText.d.ts +1 -1
  250. package/vanilla/UiText.js +1 -1
  251. package/vanilla/UiTextarea.d.ts +1 -1
  252. package/vanilla/UiTextarea.js +1 -1
  253. package/vanilla/UiToast.d.ts +1 -1
  254. package/vanilla/UiToast.js +1 -1
  255. package/vanilla/UiToastRegion.d.ts +1 -1
  256. package/vanilla/UiToastRegion.js +1 -1
  257. package/vanilla/UiTooltip.d.ts +1 -1
  258. package/vanilla/UiTooltip.js +1 -1
  259. package/vanilla/UiTopBar.d.ts +1 -1
  260. package/vanilla/UiTopBar.js +1 -1
  261. package/vanilla/UiTree.d.ts +1 -1
  262. package/vanilla/UiTree.js +1 -1
  263. package/vanilla/UiTreeItem.d.ts +1 -1
  264. package/vanilla/UiTreeItem.js +1 -1
  265. package/vue/UiActionBar.vue +1 -1
  266. package/vue/UiAffordanceScope.vue +17 -4
  267. package/vue/UiAvatar.vue +38 -5
  268. package/vue/UiAvatarGroup.vue +32 -5
  269. package/vue/UiBadge.vue +13 -3
  270. package/vue/UiBreadcrumbItem.vue +5 -3
  271. package/vue/UiBreadcrumbs.vue +5 -3
  272. package/vue/UiButton.vue +72 -7
  273. package/vue/UiCallout.vue +5 -3
  274. package/vue/UiCard.vue +16 -6
  275. package/vue/UiCheckbox.vue +41 -4
  276. package/vue/UiCluster.vue +8 -3
  277. package/vue/UiCombobox.vue +98 -6
  278. package/vue/UiContainer.vue +6 -3
  279. package/vue/UiContextMenu.vue +17 -4
  280. package/vue/UiCover.vue +5 -3
  281. package/vue/UiDescriptionItem.vue +5 -3
  282. package/vue/UiDescriptionList.vue +11 -3
  283. package/vue/UiDialog.vue +44 -5
  284. package/vue/UiDisclosure.vue +28 -4
  285. package/vue/UiEditable.vue +50 -4
  286. package/vue/UiEditorInsertTableGrid.vue +24 -4
  287. package/vue/UiEditorMentionMenu.vue +41 -4
  288. package/vue/UiEditorMentionMenuItem.vue +7 -3
  289. package/vue/UiEditorSlashMenu.vue +28 -4
  290. package/vue/UiEditorSlashMenuGroup.vue +5 -3
  291. package/vue/UiEditorSlashMenuItem.vue +15 -3
  292. package/vue/UiEditorTableContextMenu.vue +28 -4
  293. package/vue/UiEditorTableOverlay.vue +17 -4
  294. package/vue/UiEditorTableToolbar.vue +28 -4
  295. package/vue/UiEditorToolbar.vue +16 -4
  296. package/vue/UiFloatingActionButton.vue +7 -3
  297. package/vue/UiFormField.vue +18 -4
  298. package/vue/UiGrid.vue +7 -3
  299. package/vue/UiIcon.vue +5 -3
  300. package/vue/UiIconButton.vue +47 -5
  301. package/vue/UiInput.vue +90 -37
  302. package/vue/UiInputGroup.vue +30 -4
  303. package/vue/UiList.vue +20 -7
  304. package/vue/UiListItem.vue +6 -3
  305. package/vue/UiListbox.vue +38 -5
  306. package/vue/UiMenu.vue +28 -4
  307. package/vue/UiMenuGroup.vue +5 -3
  308. package/vue/UiMenuItem.vue +27 -5
  309. package/vue/UiMeter.vue +19 -3
  310. package/vue/UiNavItem.vue +28 -6
  311. package/vue/UiPageHeader.vue +5 -3
  312. package/vue/UiPopover.vue +18 -5
  313. package/vue/UiRadio.vue +28 -4
  314. package/vue/UiRadioGroup.vue +30 -4
  315. package/vue/UiReel.vue +7 -3
  316. package/vue/UiScrollArea.vue +16 -4
  317. package/vue/UiSearchResultRow.d.ts +1 -1
  318. package/vue/UiSearchResultRow.vue +6 -3
  319. package/vue/UiSearchShell.vue +32 -4
  320. package/vue/UiSection.vue +7 -3
  321. package/vue/UiSelect.vue +33 -5
  322. package/vue/UiSeparator.vue +5 -3
  323. package/vue/UiSidebar.vue +44 -4
  324. package/vue/UiSpinner.vue +6 -3
  325. package/vue/UiStack.vue +7 -3
  326. package/vue/UiStatusMessage.vue +7 -3
  327. package/vue/UiSwitch.vue +28 -4
  328. package/vue/UiSwitcher.vue +30 -5
  329. package/vue/UiTable.vue +17 -4
  330. package/vue/UiTabs.vue +28 -4
  331. package/vue/UiText.vue +29 -15
  332. package/vue/UiTextarea.vue +39 -5
  333. package/vue/UiToast.vue +17 -4
  334. package/vue/UiToastRegion.vue +17 -5
  335. package/vue/UiTooltip.vue +30 -5
  336. package/vue/UiTopBar.vue +1 -1
  337. package/vue/UiTree.vue +28 -4
  338. package/vue/UiTreeItem.d.ts +1 -1
  339. package/vue/UiTreeItem.vue +59 -4
  340. package/vue/chunks/UiActionBar.js +1 -1
  341. package/vue/chunks/UiAffordanceScope.js +19 -5
  342. package/vue/chunks/UiAvatar.js +40 -11
  343. package/vue/chunks/UiAvatarGroup.js +31 -8
  344. package/vue/chunks/UiBadge.js +13 -7
  345. package/vue/chunks/UiBreadcrumbItem.js +5 -4
  346. package/vue/chunks/UiBreadcrumbs.js +5 -4
  347. package/vue/chunks/UiButton.js +60 -19
  348. package/vue/chunks/UiCallout.js +5 -4
  349. package/vue/chunks/UiCard.js +16 -10
  350. package/vue/chunks/UiCheckbox.js +40 -11
  351. package/vue/chunks/UiCluster.js +13 -7
  352. package/vue/chunks/UiCombobox.js +85 -26
  353. package/vue/chunks/UiContainer.js +9 -5
  354. package/vue/chunks/UiContextMenu.js +19 -5
  355. package/vue/chunks/UiCover.js +5 -4
  356. package/vue/chunks/UiDescriptionItem.js +5 -4
  357. package/vue/chunks/UiDescriptionList.js +11 -6
  358. package/vue/chunks/UiDialog.js +40 -11
  359. package/vue/chunks/UiDisclosure.js +34 -9
  360. package/vue/chunks/UiEditable.js +49 -14
  361. package/vue/chunks/UiEditorInsertTableGrid.js +28 -7
  362. package/vue/chunks/UiEditorMentionMenu.js +40 -11
  363. package/vue/chunks/UiEditorMentionMenuItem.js +11 -6
  364. package/vue/chunks/UiEditorSlashMenu.js +34 -9
  365. package/vue/chunks/UiEditorSlashMenuGroup.js +5 -4
  366. package/vue/chunks/UiEditorSlashMenuItem.js +15 -8
  367. package/vue/chunks/UiEditorTableContextMenu.js +34 -9
  368. package/vue/chunks/UiEditorTableOverlay.js +19 -5
  369. package/vue/chunks/UiEditorTableToolbar.js +34 -9
  370. package/vue/chunks/UiEditorToolbar.js +15 -4
  371. package/vue/chunks/UiFloatingActionButton.js +11 -6
  372. package/vue/chunks/UiFormField.js +26 -7
  373. package/vue/chunks/UiGrid.js +11 -6
  374. package/vue/chunks/UiIcon.js +5 -4
  375. package/vue/chunks/UiIconButton.js +41 -12
  376. package/vue/chunks/UiInput.js +53 -14
  377. package/vue/chunks/UiInputGroup.js +16 -5
  378. package/vue/chunks/UiList.js +14 -8
  379. package/vue/chunks/UiListItem.js +9 -5
  380. package/vue/chunks/UiListbox.js +40 -11
  381. package/vue/chunks/UiMenu.js +34 -9
  382. package/vue/chunks/UiMenuGroup.js +5 -4
  383. package/vue/chunks/UiMenuItem.js +32 -9
  384. package/vue/chunks/UiMeter.js +19 -10
  385. package/vue/chunks/UiNavItem.js +16 -9
  386. package/vue/chunks/UiPageHeader.js +5 -4
  387. package/vue/chunks/UiPopover.js +25 -6
  388. package/vue/chunks/UiRadio.js +34 -9
  389. package/vue/chunks/UiRadioGroup.js +37 -10
  390. package/vue/chunks/UiReel.js +11 -6
  391. package/vue/chunks/UiScrollArea.js +15 -4
  392. package/vue/chunks/UiSearchResultRow.js +9 -5
  393. package/vue/chunks/UiSearchShell.js +28 -7
  394. package/vue/chunks/UiSection.js +11 -6
  395. package/vue/chunks/UiSelect.js +33 -10
  396. package/vue/chunks/UiSeparator.js +5 -4
  397. package/vue/chunks/UiSidebar.js +43 -12
  398. package/vue/chunks/UiSpinner.js +9 -5
  399. package/vue/chunks/UiStack.js +11 -6
  400. package/vue/chunks/UiStatusMessage.js +11 -6
  401. package/vue/chunks/UiSwitch.js +34 -9
  402. package/vue/chunks/UiSwitcher.js +28 -7
  403. package/vue/chunks/UiTable.js +20 -6
  404. package/vue/chunks/UiTabs.js +34 -9
  405. package/vue/chunks/UiText.js +29 -20
  406. package/vue/chunks/UiTextarea.js +42 -13
  407. package/vue/chunks/UiToast.js +19 -5
  408. package/vue/chunks/UiToastRegion.js +19 -5
  409. package/vue/chunks/UiTooltip.js +37 -10
  410. package/vue/chunks/UiTopBar.js +1 -1
  411. package/vue/chunks/UiTree.js +35 -10
  412. package/vue/chunks/UiTreeItem.js +58 -17
  413. package/vue/chunks/host.js +22 -4
  414. package/vue/chunks/props.js +20 -7
  415. package/vue/components.css +1228 -1205
  416. package/vue/editor/index.js +9 -2
  417. package/vue/host.ts +50 -6
@@ -14,6 +14,13 @@ function syncScrollLock(document, state) {
14
14
  else document.documentElement.style.removeProperty("overflow");
15
15
  }
16
16
 
17
+ function syncModalBackdrops(state) {
18
+ const topModal = state.records.findLast((record) => record.modal);
19
+ for (const record of state.records) {
20
+ (record.modalElement ?? record.element).toggleAttribute("data-ui-backdrop-hidden", Boolean(record.modal && record !== topModal));
21
+ }
22
+ }
23
+
17
24
  function requestClose(document, reason, trigger) {
18
25
  const record = stateFor(document).records.at(-1);
19
26
  if (!record || (record.dismissible === false && (reason === "escape" || reason === "light-dismiss")) || record.canClose?.(reason) === false) return false;
@@ -55,13 +62,36 @@ function removeListeners(document, state) {
55
62
  export function openOverlay(record) {
56
63
  const document = record.element.ownerDocument;
57
64
  const state = stateFor(document);
58
- closeOverlay(document, record.id);
65
+ const index = state.records.findIndex((entry) => entry.id === record.id);
66
+ if (index >= 0) {
67
+ const previous = state.records[index];
68
+ state.records[index] = record;
69
+ if (previous.modal !== record.modal) {
70
+ state.modalCount += record.modal ? 1 : -1;
71
+ syncScrollLock(document, state);
72
+ }
73
+ if (previous.modalElement && previous.modalElement !== record.modalElement) previous.modalElement.removeAttribute("data-ui-backdrop-hidden");
74
+ syncModalBackdrops(state);
75
+ return;
76
+ }
59
77
  state.records.push(record);
60
78
  if (record.modal) {
61
79
  state.modalCount += 1;
62
80
  syncScrollLock(document, state);
63
81
  }
82
+ syncModalBackdrops(state);
64
83
  ensureListeners(document, state);
84
+ announceOverlayOpen(document, record.id);
85
+ }
86
+
87
+ export function onOverlayOpen(document, listener) {
88
+ const onOpen = (event) => listener(event.detail.id);
89
+ document.addEventListener("ui-overlay-open", onOpen);
90
+ return () => document.removeEventListener("ui-overlay-open", onOpen);
91
+ }
92
+
93
+ export function announceOverlayOpen(document, id) {
94
+ document.dispatchEvent(new CustomEvent("ui-overlay-open", { detail: { id } }));
65
95
  }
66
96
 
67
97
  export function closeOverlay(document, id) {
@@ -69,10 +99,12 @@ export function closeOverlay(document, id) {
69
99
  const index = state.records.findIndex((record) => record.id === id);
70
100
  if (index >= 0) {
71
101
  const [record] = state.records.splice(index, 1);
102
+ (record.modalElement ?? record.element).removeAttribute("data-ui-backdrop-hidden");
72
103
  if (record?.modal) {
73
104
  state.modalCount = Math.max(0, state.modalCount - 1);
74
105
  syncScrollLock(document, state);
75
106
  }
107
+ syncModalBackdrops(state);
76
108
  }
77
109
  removeListeners(document, state);
78
110
  }
@@ -11,7 +11,7 @@ export default function controller(host) {
11
11
  let frame = null;
12
12
  let point = null;
13
13
  let dirty = false;
14
- let nearRadius = Number(host.state.nearRadius ?? 16);
14
+ let nearRadius = Number(host.props.nearRadius.value ?? 16);
15
15
  const clear = () => {
16
16
  for (const anchor of anchors) anchor.element.removeAttribute("data-ui-proximity");
17
17
  host.state.engaged = false;
@@ -57,7 +57,7 @@ export default function controller(host) {
57
57
  owner.visualViewport?.addEventListener("resize", invalidate, { passive: true });
58
58
  owner.visualViewport?.addEventListener("scroll", invalidate, { passive: true });
59
59
  const stop = host.effect(() => {
60
- const configured = Number(host.state.nearRadius ?? 16);
60
+ const configured = Number(host.props.nearRadius.value ?? 16);
61
61
  nearRadius = Number.isFinite(configured) ? Math.max(0, configured) : 16;
62
62
  invalidate();
63
63
  });
@@ -29,17 +29,17 @@ export default function controller(host) {
29
29
  authored.hidden = !host.state.hasImage;
30
30
  element.removeAttribute("role");
31
31
  element.removeAttribute("aria-label");
32
- } else if (!host.state.decorative) {
32
+ } else if (!host.props.decorative.value) {
33
33
  element.setAttribute("role", "img");
34
- element.setAttribute("aria-label", host.state.alt || host.state.name || "Avatar");
34
+ element.setAttribute("aria-label", host.props.alt.value || host.props.name.value || "Avatar");
35
35
  }
36
- if (host.state.decorative) {
36
+ if (host.props.decorative.value) {
37
37
  element.setAttribute("aria-hidden", "true");
38
38
  element.removeAttribute("role");
39
39
  element.removeAttribute("aria-label");
40
40
  } else element.removeAttribute("aria-hidden");
41
- host.state.initials = host.state.fallback || toInitials(host.state.name || host.state.alt);
42
- host.state.showGlyph = !String(host.state.name || "").trim() && !String(host.state.alt || "").trim() && !String(host.state.fallback || "").trim();
41
+ host.state.initials = host.props.fallback.value || toInitials(host.props.name.value || host.props.alt.value);
42
+ host.state.showGlyph = !String(host.props.name.value || "").trim() && !String(host.props.alt.value || "").trim() && !String(host.props.fallback.value || "").trim();
43
43
  };
44
44
  const observer = new MutationObserver(apply);
45
45
  observer.observe(element, { childList: true });
@@ -3,11 +3,11 @@
3
3
  export default function controller(host) {
4
4
  const element = host.element;
5
5
  const update = () => {
6
- const max = Number(host.state.max);
6
+ const max = Number(host.props.max.value);
7
7
  const visible = Number.isFinite(max) ? Math.max(0, Math.floor(max)) : 0;
8
8
  const avatars = Array.from(element.children).filter((child) => child !== host.refs.overflow);
9
9
  // Small avatars overlap less, so their initials stay clear of the next one.
10
- const overlap = { xs: "-0.1875rem", sm: "-0.25rem" }[host.state.size] ?? "-0.5rem";
10
+ const overlap = { xs: "-0.1875rem", sm: "-0.25rem" }[host.props.size.value] ?? "-0.5rem";
11
11
  avatars.forEach((avatar, index) => {
12
12
  avatar.style.display = index >= visible ? "none" : "";
13
13
  avatar.style.marginInlineStart = index === 0 ? "0px" : overlap;
@@ -17,11 +17,11 @@ export default function controller(host) {
17
17
  : "var(--ui-avatar-group-overlap-shadow, var(--_overlap-shadow)), var(--ui-avatar-group-edge-ring, 0 0 0 0 transparent)";
18
18
  });
19
19
  const authoredVisible = Math.min(avatars.length, visible);
20
- const suppliedTotal = Number(host.state.total);
21
- const total = host.state.total == null || !Number.isFinite(suppliedTotal) ? avatars.length : Math.max(avatars.length, suppliedTotal);
20
+ const suppliedTotal = Number(host.props.total.value);
21
+ const total = host.props.total.value == null || !Number.isFinite(suppliedTotal) ? avatars.length : Math.max(avatars.length, suppliedTotal);
22
22
  const count = Math.max(0, total - authoredVisible);
23
23
  host.state.overflowCount = count;
24
- host.state.overflowAnnouncement = String(host.state.overflowLabel || "{count} more").replaceAll("{count}", String(count));
24
+ host.state.overflowAnnouncement = String(host.props.overflowLabel.value || "{count} more").replaceAll("{count}", String(count));
25
25
  };
26
26
  const observer = new MutationObserver(update);
27
27
  observer.observe(element, { childList: true });
@@ -1,7 +1,7 @@
1
1
  // Loading actions retain focus but cannot activate, navigate, submit, or notify click consumers.
2
2
  export default function controller(host) {
3
3
  const onClick = (event) => {
4
- if (!host.state.loading && !host.state.pending) return;
4
+ if (!host.props.loading.value && !host.props.pending.value) return;
5
5
  event.preventDefault();
6
6
  event.stopImmediatePropagation();
7
7
  };
@@ -9,17 +9,17 @@ export default function controller(host) {
9
9
  const input = host.refs.input;
10
10
  describeInput(input, host.refs.description);
11
11
  const [trigger, stopTracking] = trackTrigger(host);
12
- let external = host.state.checked;
12
+ let external = host.props.checked.value;
13
13
  host.state.internalChecked = Boolean(external);
14
14
  const stop = host.effect(() => {
15
- input.defaultChecked = Boolean(host.state.checked);
16
- if (host.state.checked === external) return;
17
- external = host.state.checked;
15
+ input.defaultChecked = Boolean(host.props.checked.value);
16
+ if (host.props.checked.value === external) return;
17
+ external = host.props.checked.value;
18
18
  host.state.internalChecked = Boolean(external);
19
19
  });
20
20
  const onChange = () => {
21
21
  host.state.internalChecked = input.checked;
22
- host.dispatch("change", { checked: input.checked, value: String(host.state.value ?? "on"), trigger: trigger() });
22
+ host.dispatch("change", { checked: input.checked, value: String(host.props.value.value ?? "on"), trigger: trigger() });
23
23
  };
24
24
  input.addEventListener("change", onChange);
25
25
  const stopReset = afterFormReset(input, () => {
@@ -47,17 +47,17 @@ export default function controller(host) {
47
47
  let initialRaw = "";
48
48
  let awaitingLabel = null;
49
49
  let proposedChange;
50
- let lastValue = host.state.value;
51
- let lastQuery = host.state.query;
50
+ let lastValue = host.props.value.value;
51
+ let lastQuery = host.props.query.value;
52
52
  const knownOptions = new Map();
53
53
 
54
54
  // Options come from authored <option>/<optgroup> children; everything else is an attribute.
55
55
  const config = () => ({
56
56
  options: authoredOptions(authored),
57
- allowFreeText: Boolean(host.state.allowFreeText),
58
- allowCreate: Boolean(host.state.allowCreate),
57
+ allowFreeText: Boolean(host.props.allowFreeText.value),
58
+ allowCreate: Boolean(host.props.allowCreate.value),
59
59
  // "none": the consumer already narrowed the options (a server search), so every one is listed.
60
- filterByLabel: host.state.filter !== "none",
60
+ filterByLabel: host.props.filter.value !== "none",
61
61
  });
62
62
  const authoredDefaults = () => {
63
63
  const values = new Set(Array.from(authored.querySelectorAll("option[selected]"), (option) => option.value));
@@ -66,19 +66,19 @@ export default function controller(host) {
66
66
  // Selected items work uncontrolled: the component keeps them and reports every change. A consumer
67
67
  // that owns `items` stays in charge, because the prop resyncs whatever it sets. A consumer that sets
68
68
  // `selectedValues` controls the selection: the chips follow it, and a user's change is only reported.
69
- const items = () => host.state.multiple && Array.isArray(host.state.internalItems) ? host.state.internalItems : [];
69
+ const items = () => host.props.multiple.value && Array.isArray(host.state.internalItems) ? host.state.internalItems : [];
70
70
  const selectedSet = () => new Set(items().map((item) => item.value));
71
- const controlledValues = () => Array.isArray(host.state.selectedValues);
71
+ const controlledValues = () => Array.isArray(host.props.selectedValues.value);
72
72
  // Each controlled value shows its authored option; a value no option describes yet keeps the chip it
73
73
  // had, or shows the value itself until its option arrives. A repeated value shows once: the chips and
74
74
  // hidden inputs are keyed by value. Array.from, not a spread: a loose transpile turns [...set] into [set].
75
75
  const itemsForValues = () => {
76
76
  const options = config().options;
77
- return Array.from(new Set(host.state.selectedValues)).map((value) => asItem(options.find((option) => option.value === value)
77
+ return Array.from(new Set(host.props.selectedValues.value)).map((value) => asItem(options.find((option) => option.value === value)
78
78
  ?? items().find((item) => item.value === value) ?? { id: value, value, label: value }));
79
79
  };
80
80
  const markSelectedRows = () => {
81
- if (!host.state.multiple || !host.state.rows?.length) return;
81
+ if (!host.props.multiple.value || !host.state.rows?.length) return;
82
82
  const selected = selectedSet();
83
83
  host.state.rows = host.state.rows.map((row) => ({ ...row, selected: selected.has(row.value) }));
84
84
  };
@@ -126,7 +126,7 @@ export default function controller(host) {
126
126
  const canCreate = () => {
127
127
  const current = config();
128
128
  const candidates = current.options ? [...current.options, ...(host.state.rows ?? [])] : (host.state.rows ?? []);
129
- return Boolean(current.allowCreate && String(host.state.raw).trim() && !host.state.loading && !host.state.lookupError
129
+ return Boolean(current.allowCreate && String(host.state.raw).trim() && !host.props.loading.value && !host.state.lookupError
130
130
  && !candidates.some((row) => row.label.toLocaleLowerCase() === String(host.state.raw).toLocaleLowerCase()));
131
131
  };
132
132
  const search = (reason) => {
@@ -142,14 +142,14 @@ export default function controller(host) {
142
142
  if (controller.signal.aborted || !alive) return;
143
143
  for (const option of options) knownOptions.set(option.value, option);
144
144
  const selectedOption = host.state.selected == null ? undefined : knownOptions.get(host.state.selected);
145
- if (host.state.query == null && awaitingLabel === host.state.selected && selectedOption) {
145
+ if (host.props.query.value == null && awaitingLabel === host.state.selected && selectedOption) {
146
146
  host.state.raw = selectedOption.label;
147
147
  host.state.display = selectedOption.label;
148
148
  awaitingLabel = null;
149
149
  resetValidation();
150
150
  }
151
151
  const ids = new Set();
152
- const selected = host.state.multiple ? selectedSet() : undefined;
152
+ const selected = host.props.multiple.value ? selectedSet() : undefined;
153
153
  // Multiple keeps its chosen options in the list, checked. Dropping them hid what was picked
154
154
  // from the list and from assistive technology, which only ever heard aria-selected="false".
155
155
  const filtered = options.filter((option) => {
@@ -180,7 +180,7 @@ export default function controller(host) {
180
180
  applyOptions(current.options);
181
181
  };
182
182
  const open = (reason = "input") => {
183
- if (host.state.disabled || host.state.readonly) return;
183
+ if (host.props.disabled.value || host.props.readonly.value) return;
184
184
  host.state.expanded = true;
185
185
  popup.style.minWidth = `${field.getBoundingClientRect().width}px`;
186
186
  surface.show();
@@ -194,8 +194,8 @@ export default function controller(host) {
194
194
  awaitingLabel = null;
195
195
  if (kind === "selection") lastSelection = option;
196
196
  const queryChanged = query !== host.state.raw;
197
- if (host.state.value == null) host.state.selected = value;
198
- if (host.state.query == null && queryChanged) {
197
+ if (host.props.value.value == null) host.state.selected = value;
198
+ if (host.props.query.value == null && queryChanged) {
199
199
  host.state.raw = query;
200
200
  host.state.display = query;
201
201
  }
@@ -209,8 +209,8 @@ export default function controller(host) {
209
209
  if (kind === "free-entry") host.dispatch("free-entry", detail);
210
210
  queueMicrotask(() => {
211
211
  if (proposedChange !== proposal) return;
212
- if (host.state.value != null && host.state.value !== proposal.value) syncValue();
213
- if (host.state.query != null && host.state.query !== proposal.query) syncQuery();
212
+ if (host.props.value.value != null && host.props.value.value !== proposal.value) syncValue();
213
+ if (host.props.query.value != null && host.props.query.value !== proposal.query) syncQuery();
214
214
  proposedChange = undefined;
215
215
  });
216
216
  };
@@ -222,7 +222,7 @@ export default function controller(host) {
222
222
  host.dispatch("selected-values-change", { selectedValues: next.map((item) => item.value), trigger });
223
223
  };
224
224
  const setMultiQuery = (query, trigger) => {
225
- if (host.state.query == null) {
225
+ if (host.props.query.value == null) {
226
226
  host.state.raw = query;
227
227
  host.state.display = query;
228
228
  }
@@ -249,7 +249,7 @@ export default function controller(host) {
249
249
  const choose = (index, trigger) => {
250
250
  const option = (host.state.rows ?? [])[index];
251
251
  if (option?.disabled) return;
252
- if (host.state.multiple) {
252
+ if (host.props.multiple.value) {
253
253
  if (option) {
254
254
  // A checked row toggles off: the list is the selection, so it has to work both ways.
255
255
  const position = items().findIndex((item) => item.value === option.value);
@@ -268,7 +268,7 @@ export default function controller(host) {
268
268
  else return;
269
269
  close();
270
270
  input.focus();
271
- if (!host.state.multiple) queueMicrotask(() => void validateCurrent());
271
+ if (!host.props.multiple.value) queueMicrotask(() => void validateCurrent());
272
272
  };
273
273
  // A strict combobox (single, no free text, no create) behaves like a select: leaving it resolves the
274
274
  // typed text to a valid option (the highlighted one, an exact label, the first label it begins, or the
@@ -276,13 +276,13 @@ export default function controller(host) {
276
276
  // "none" the remaining options are all of them, whatever their labels, so the only one listed counts.
277
277
  const resolveTyped = (trigger) => {
278
278
  const current = config();
279
- if (host.state.multiple || current.allowFreeText || current.allowCreate) return;
279
+ if (host.props.multiple.value || current.allowFreeText || current.allowCreate) return;
280
280
  const typed = String(host.state.raw ?? "");
281
281
  const selectedOption = (current.options ?? []).find((option) => option.value === host.state.selected)
282
282
  ?? knownOptions.get(host.state.selected) ?? lastSelection;
283
283
  if (selectedOption && selectedOption.label === typed) return;
284
284
  const restoreDraft = (label) => {
285
- if (host.state.query != null || label === host.state.raw) return;
285
+ if (host.props.query.value != null || label === host.state.raw) return;
286
286
  host.state.raw = label;
287
287
  host.state.display = label;
288
288
  resetValidation();
@@ -319,7 +319,7 @@ export default function controller(host) {
319
319
  const removeItemAt = (index, trigger) => {
320
320
  const current = items();
321
321
  const item = current[index];
322
- if (!item || item.disabled || host.state.disabled || host.state.readonly) return;
322
+ if (!item || item.disabled || host.props.disabled.value || host.props.readonly.value) return;
323
323
  host.dispatch("remove-item", { item, index, trigger });
324
324
  emitItems(current.filter((_, position) => position !== index), trigger);
325
325
  requestAnimationFrame(() => itemButtons()[Math.min(index, itemButtons().length - 1)]?.focus?.() ?? input.focus());
@@ -344,8 +344,8 @@ export default function controller(host) {
344
344
  // Native constraints and the free-text policy; application validation stays in the form.
345
345
  const current = config();
346
346
  const result = { output: host.state.raw, issues: [] };
347
- const empty = host.state.multiple ? !items().length : !String(host.state.raw).trim();
348
- if (host.state.required && empty) result.issues = [...result.issues, { message: "A value is required." }];
347
+ const empty = host.props.multiple.value ? !items().length : !String(host.state.raw).trim();
348
+ if (host.props.required.value && empty) result.issues = [...result.issues, { message: "A value is required." }];
349
349
  else if (host.state.raw && host.state.selected === null && !current.allowFreeText && !current.allowCreate) result.issues = [...result.issues, { message: "Choose a suggestion." }];
350
350
  if (result.issues.some((issue) => issue.severity !== "warning")) result.output = undefined;
351
351
  if (!run.signal.aborted && alive) setValidation(result);
@@ -353,9 +353,9 @@ export default function controller(host) {
353
353
  return host.state.validation;
354
354
  };
355
355
  const syncValue = () => {
356
- if (host.state.multiple || host.state.value == null) return;
357
- host.state.selected = host.state.value;
358
- if (host.state.query == null) {
356
+ if (host.props.multiple.value || host.props.value.value == null) return;
357
+ host.state.selected = host.props.value.value;
358
+ if (host.props.query.value == null) {
359
359
  const proposal = proposedChange;
360
360
  const option = config().options?.find((row) => row.value === host.state.selected) ?? (host.state.selected == null ? undefined : knownOptions.get(host.state.selected));
361
361
  const nextRaw = proposal?.value === host.state.selected ? proposal.query : option?.label ?? host.state.selected ?? "";
@@ -368,11 +368,11 @@ export default function controller(host) {
368
368
  resetValidation();
369
369
  };
370
370
  const syncQuery = () => {
371
- if (host.state.query == null || host.state.query === host.state.raw) return;
372
- if (host.state.value == null && proposedChange?.query !== host.state.query) host.state.selected = null;
371
+ if (host.props.query.value == null || host.props.query.value === host.state.raw) return;
372
+ if (host.props.value.value == null && proposedChange?.query !== host.props.query.value) host.state.selected = null;
373
373
  awaitingLabel = null;
374
- host.state.raw = host.state.query;
375
- host.state.display = host.state.query;
374
+ host.state.raw = host.props.query.value;
375
+ host.state.display = host.props.query.value;
376
376
  resetValidation();
377
377
  if (host.state.expanded) search("input");
378
378
  };
@@ -396,11 +396,11 @@ export default function controller(host) {
396
396
  host.state.creatable = canCreate();
397
397
  host.state.createIndex = rows.length;
398
398
  // What a named combobox submits in single mode: the value, never the label the field shows.
399
- host.state.submitted = String(host.state.selected ?? (host.state.allowFreeText ? host.state.raw ?? "" : ""));
400
- host.state.message = host.state.loading ? "Loading suggestions…" : host.state.lookupError || "";
399
+ host.state.submitted = String(host.state.selected ?? (host.props.allowFreeText.value ? host.state.raw ?? "" : ""));
400
+ host.state.message = host.props.loading.value ? "Loading suggestions…" : host.state.lookupError || "";
401
401
  const validation = host.state.validation ?? { status: "pristine", issues: [] };
402
402
  host.state.validationStatus = validation.status;
403
- const status = host.state.loading ? "Loading suggestions…" : host.state.lookupError || (host.state.expanded ? `${rows.length} suggestions available.` : "");
403
+ const status = host.props.loading.value ? "Loading suggestions…" : host.state.lookupError || (host.state.expanded ? `${rows.length} suggestions available.` : "");
404
404
  host.state.statusText = `${status} ${validation.status === "pending" ? "Checking value…" : (validation.issues ?? []).map((issue) => issue.message).join(" ")}`.trim();
405
405
  if (host.state.expanded && host.state.active >= 0) input.setAttribute("aria-activedescendant", `${uid}-option-${host.state.active}`);
406
406
  else input.removeAttribute("aria-activedescendant");
@@ -418,11 +418,11 @@ export default function controller(host) {
418
418
  host.dispatch("query-change", { query: host.state.raw, display: host.state.display, trigger: "keyboard" });
419
419
  // A strict combobox keeps its committed selection while the input holds a search draft.
420
420
  // Clearing a controlled value here makes the consumer restore its label on every keystroke.
421
- if (host.state.selected !== null && (host.state.allowFreeText || host.state.allowCreate)) {
421
+ if (host.state.selected !== null && (host.props.allowFreeText.value || host.props.allowCreate.value)) {
422
422
  commit(null, host.state.raw, null, "clear", "keyboard");
423
423
  }
424
424
  open();
425
- queueMicrotask(() => { if (host.state.query != null && host.state.query !== host.state.raw) syncQuery(); });
425
+ queueMicrotask(() => { if (host.props.query.value != null && host.props.query.value !== host.state.raw) syncQuery(); });
426
426
  };
427
427
  const onKeydown = (event) => {
428
428
  const item = event.target.closest?.(".item");
@@ -434,9 +434,9 @@ export default function controller(host) {
434
434
  else if (["Backspace", "Delete"].includes(event.key)) { event.preventDefault(); removeItemAt(index, "keyboard"); }
435
435
  return;
436
436
  }
437
- if (event.target !== input || composing || event.isComposing || host.state.disabled || host.state.readonly) return;
438
- if (host.state.multiple && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) {
439
- if ((host.state.tokenSeparators ?? []).includes(event.key)) { event.preventDefault(); commitQuery("keyboard"); return; }
437
+ if (event.target !== input || composing || event.isComposing || host.props.disabled.value || host.props.readonly.value) return;
438
+ if (host.props.multiple.value && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) {
439
+ if ((host.props.tokenSeparators.value ?? []).includes(event.key)) { event.preventDefault(); commitQuery("keyboard"); return; }
440
440
  if (!host.state.raw && (input.selectionStart ?? 0) === 0 && event.key === "ArrowLeft" && items().length) { event.preventDefault(); itemButtons().at(-1)?.focus(); return; }
441
441
  if (!host.state.raw && (input.selectionStart ?? 0) === 0 && event.key === "Backspace" && items().length) { event.preventDefault(); removeItemAt(items().length - 1, "keyboard"); return; }
442
442
  }
@@ -447,7 +447,7 @@ export default function controller(host) {
447
447
  else if (event.key === "Enter" && host.state.expanded) {
448
448
  if (host.state.active >= 0) { event.preventDefault(); choose(host.state.active, "keyboard"); }
449
449
  // With nothing highlighted, Enter commits what was typed, as a token separator does.
450
- else if (host.state.multiple && String(host.state.raw).trim()) { event.preventDefault(); commitQuery("keyboard"); }
450
+ else if (host.props.multiple.value && String(host.state.raw).trim()) { event.preventDefault(); commitQuery("keyboard"); }
451
451
  else if (canCreate()) { event.preventDefault(); choose((host.state.rows ?? []).length, "keyboard"); }
452
452
  else if (config().allowFreeText) { event.preventDefault(); commit(null, host.state.raw, null, "free-entry", "keyboard"); close(); }
453
453
  }
@@ -456,7 +456,7 @@ export default function controller(host) {
456
456
  const option = event.target.closest?.('[role="option"][data-index]');
457
457
  if (option) { choose(Number(option.dataset.index), "pointer"); return; }
458
458
  const action = event.target.closest?.("[data-combobox-action]")?.dataset.comboboxAction;
459
- if (action && (host.state.disabled || host.state.readonly)) return;
459
+ if (action && (host.props.disabled.value || host.props.readonly.value)) return;
460
460
  if (action === "clear") { lastSelection = null; commit(null, "", null, "clear", "pointer"); close(); input.focus(); }
461
461
  else if (action === "disclosure") { host.state.expanded ? close() : open("disclosure"); input.focus(); }
462
462
  else if (field.contains(event.target) && !event.target.closest?.("button")) input.focus();
@@ -467,11 +467,11 @@ export default function controller(host) {
467
467
  close();
468
468
  host.state.validation = { ...host.state.validation, touched: true };
469
469
  resolveTyped("pointer");
470
- if (!host.state.multiple && config().allowFreeText && host.state.selected === null) commit(null, host.state.raw, null, "free-entry", "keyboard");
470
+ if (!host.props.multiple.value && config().allowFreeText && host.state.selected === null) commit(null, host.state.raw, null, "free-entry", "keyboard");
471
471
  void validateCurrent();
472
472
  };
473
473
  const onFocusin = (event) => {
474
- if (event.target === input && host.state.openOnFocus && !host.state.expanded) open();
474
+ if (event.target === input && host.props.openOnFocus.value && !host.state.expanded) open();
475
475
  };
476
476
  const onCompositionstart = (event) => { if (event.target === input) composing = true; };
477
477
  const onCompositionend = (event) => { if (event.target === input) { composing = false; onInput(new InputEvent("input")); } };
@@ -480,16 +480,16 @@ export default function controller(host) {
480
480
 
481
481
  // The selection the props describe: where the combobox starts, and where a form reset returns it.
482
482
  const applyDefaults = () => {
483
- if (host.state.multiple) {
483
+ if (host.props.multiple.value) {
484
484
  host.state.selected = null;
485
- host.state.raw = host.state.query ?? "";
485
+ host.state.raw = host.props.query.value ?? "";
486
486
  } else {
487
- host.state.selected = host.state.value != null ? host.state.value : authoredDefaults()[0]?.value ?? null;
488
- host.state.raw = host.state.query ?? "";
489
- if (host.state.query == null && !host.state.raw && host.state.selected !== null) {
487
+ host.state.selected = host.props.value.value != null ? host.props.value.value : authoredDefaults()[0]?.value ?? null;
488
+ host.state.raw = host.props.query.value ?? "";
489
+ if (host.props.query.value == null && !host.state.raw && host.state.selected !== null) {
490
490
  host.state.raw = config().options?.find((row) => row.value === host.state.selected)?.label ?? host.state.selected;
491
491
  }
492
- if (host.state.query == null && host.state.selected !== null && host.state.raw === host.state.selected) awaitingLabel = host.state.selected;
492
+ if (host.props.query.value == null && host.state.selected !== null && host.state.raw === host.state.selected) awaitingLabel = host.state.selected;
493
493
  }
494
494
  host.state.display = host.state.raw;
495
495
  };
@@ -505,7 +505,7 @@ export default function controller(host) {
505
505
  // Authored options can change after mount (renamed, replaced, or arriving late). A selected value
506
506
  // then shows its current label, unless the user is editing the text.
507
507
  const relabel = () => {
508
- if (host.state.multiple || host.state.query != null || host.state.selected == null) return;
508
+ if (host.props.multiple.value || host.props.query.value != null || host.state.selected == null) return;
509
509
  if (element.ownerDocument.activeElement === input) return;
510
510
  const label = config().options?.find((row) => row.value === host.state.selected)?.label;
511
511
  if (label === undefined || label === host.state.raw) return;
@@ -517,7 +517,7 @@ export default function controller(host) {
517
517
  const stopReset = afterFormReset(input, () => {
518
518
  close();
519
519
  lastSelection = null;
520
- host.state.internalItems = controlledValues() ? itemsForValues() : Array.isArray(host.state.items) ? host.state.items : authoredDefaults();
520
+ host.state.internalItems = controlledValues() ? itemsForValues() : Array.isArray(host.props.items.value) ? host.props.items.value : authoredDefaults();
521
521
  applyDefaults();
522
522
  input.value = host.state.display;
523
523
  resetValidation();
@@ -529,31 +529,31 @@ export default function controller(host) {
529
529
  const observer = new MutationObserver(() => {
530
530
  relabel();
531
531
  // Controlled chips show their options' current labels, including options that arrive late.
532
- if (host.state.multiple) syncValues();
532
+ if (host.props.multiple.value) syncValues();
533
533
  const key = optionsKey();
534
534
  if (key === lastOptionsKey) return;
535
535
  lastOptionsKey = key;
536
536
  if (host.state.expanded) search(fullSet ? "disclosure" : "options");
537
537
  });
538
538
  observer.observe(authored, { childList: true, subtree: true, characterData: true, attributes: true });
539
- let lastItems = host.state.items;
540
- let lastSelectedValues = host.state.selectedValues;
539
+ let lastItems = host.props.items.value;
540
+ let lastSelectedValues = host.props.selectedValues.value;
541
541
  if (controlledValues()) host.state.internalItems = itemsForValues();
542
542
  else if (Array.isArray(lastItems)) host.state.internalItems = lastItems;
543
543
  else host.state.internalItems = authoredDefaults();
544
544
  const stop = host.effect(() => {
545
545
  // A consumer that sets `items` owns them; otherwise the component keeps its own. selectedValues wins.
546
- if (host.state.items !== lastItems) {
547
- lastItems = host.state.items;
546
+ if (host.props.items.value !== lastItems) {
547
+ lastItems = host.props.items.value;
548
548
  if (Array.isArray(lastItems) && !controlledValues()) host.state.internalItems = lastItems;
549
549
  // The list shows the selection; a consumer that adds or removes an item later (after creating
550
550
  // it, say) is reflected at once rather than at the next search.
551
551
  markSelectedRows();
552
552
  }
553
- if (host.state.selectedValues !== lastSelectedValues) { lastSelectedValues = host.state.selectedValues; syncValues(); }
554
- if (host.state.value !== lastValue) { lastValue = host.state.value; syncValue(); }
555
- if (host.state.query !== lastQuery) { lastQuery = host.state.query; syncQuery(); }
556
- if (host.state.disabled || host.state.readonly) close();
553
+ if (host.props.selectedValues.value !== lastSelectedValues) { lastSelectedValues = host.props.selectedValues.value; syncValues(); }
554
+ if (host.props.value.value !== lastValue) { lastValue = host.props.value.value; syncValue(); }
555
+ if (host.props.query.value !== lastQuery) { lastQuery = host.props.query.value; syncQuery(); }
556
+ if (host.props.disabled.value || host.props.readonly.value) close();
557
557
  updateView();
558
558
  });
559
559
 
@@ -14,8 +14,8 @@ export default function controller(host) {
14
14
  let surface = null;
15
15
  let point = null;
16
16
  let press = null;
17
- let lastFor = host.state.for;
18
- let lastOpenProp = Boolean(host.state.open);
17
+ let lastFor = host.props.for.value;
18
+ let lastOpenProp = Boolean(host.props.open.value);
19
19
  host.state.internalOpen = lastOpenProp;
20
20
 
21
21
  const items = () => menuItems(element);
@@ -27,7 +27,7 @@ export default function controller(host) {
27
27
  };
28
28
  const ids = createIdResolver(document, () => resolveTargets());
29
29
  const resolveTargets = () => {
30
- const next = ids.get(String(host.state.for ?? ""));
30
+ const next = ids.get(String(host.props.for.value ?? ""));
31
31
  if (next === target) return;
32
32
  detach();
33
33
  target = next;
@@ -43,11 +43,11 @@ export default function controller(host) {
43
43
  if (returnFocus) target?.focus();
44
44
  };
45
45
  const apply = () => {
46
- if (host.state.for !== lastFor) {
47
- lastFor = host.state.for;
46
+ if (host.props.for.value !== lastFor) {
47
+ lastFor = host.props.for.value;
48
48
  resolveTargets();
49
49
  }
50
- const externalOpen = Boolean(host.state.open);
50
+ const externalOpen = Boolean(host.props.open.value);
51
51
  if (externalOpen !== lastOpenProp) {
52
52
  lastOpenProp = externalOpen;
53
53
  host.state.internalOpen = externalOpen;
@@ -254,6 +254,12 @@
254
254
  animation: ui-dialog-backdrop-enter var(--_ui-dialog-duration, var(--ui-motion-base)) var(--ui-motion-ease);
255
255
  }
256
256
 
257
+ :host[open][data-ui-backdrop-hidden]::backdrop {
258
+ background-color: transparent;
259
+ animation: none;
260
+ transition: none;
261
+ }
262
+
257
263
  @keyframes ui-dialog-backdrop-enter {
258
264
  from {
259
265
  background-color: transparent;