@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
@@ -9,18 +9,18 @@ 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
22
  if (!input.checked) return;
23
- host.dispatch("change", { checked: input.checked, value: String(host.state.value ?? "on"), trigger: trigger() });
23
+ host.dispatch("change", { checked: input.checked, value: String(host.props.value.value ?? "on"), trigger: trigger() });
24
24
  };
25
25
  input.addEventListener("change", onChange);
26
26
  const stopReset = afterFormReset(input, () => {
@@ -8,22 +8,22 @@ let groups = 0;
8
8
  // them, so a radio's own disabled is never overwritten.
9
9
  export default function controller(host) {
10
10
  const element = host.element;
11
- const name = String(host.state.name || `ui-radio-group-${++groups}`);
11
+ const name = String(host.props.name.value || `ui-radio-group-${++groups}`);
12
12
  const [trigger, stopTracking] = trackTrigger(host);
13
13
  const inputs = () => Array.from(element.querySelectorAll('input[type="radio"]'));
14
- let external = host.state.value;
14
+ let external = host.props.value.value;
15
15
  // A radio's own required survives until the group's required changes, since either one makes the
16
16
  // whole name group required.
17
17
  let required = false;
18
18
  host.state.internalValue = String(external ?? "");
19
19
  const stop = host.effect(() => {
20
- if (host.state.value !== external) {
21
- external = host.state.value;
20
+ if (host.props.value.value !== external) {
21
+ external = host.props.value.value;
22
22
  host.state.internalValue = String(external ?? "");
23
23
  }
24
24
  const value = host.state.internalValue;
25
- const applyRequired = Boolean(host.state.required) !== required;
26
- required = Boolean(host.state.required);
25
+ const applyRequired = Boolean(host.props.required.value) !== required;
26
+ required = Boolean(host.props.required.value);
27
27
  for (const input of inputs()) {
28
28
  if (applyRequired) input.required = required;
29
29
  input.name = name;
@@ -4,7 +4,7 @@ export default function controller(host) {
4
4
 
5
5
  const update = () => {
6
6
  frame = 0;
7
- const horizontal = host.state.orientation === "horizontal";
7
+ const horizontal = host.props.orientation.value === "horizontal";
8
8
  const extent = horizontal ? area.scrollWidth - area.clientWidth : area.scrollHeight - area.clientHeight;
9
9
  const rtl = horizontal && getComputedStyle(area).direction === "rtl";
10
10
  const position = horizontal ? (rtl ? -area.scrollLeft : area.scrollLeft) : area.scrollTop;
@@ -105,6 +105,14 @@
105
105
  background: var(--ui-overlay-backdrop);
106
106
  }
107
107
 
108
+ dialog:modal {
109
+ background: transparent;
110
+ }
111
+
112
+ dialog[data-ui-backdrop-hidden]::backdrop {
113
+ background: transparent;
114
+ }
115
+
108
116
  .panel {
109
117
  position: relative;
110
118
  display: flex;
@@ -1,11 +1,14 @@
1
+ import { closeOverlay, openOverlay } from "../shared/overlay.js";
1
2
  import { trackTrigger } from "../shared/trigger.js";
2
3
 
3
4
  /** Owns native dialog state while leaving query and result state to the application. */
4
5
  export default function controller(host) {
5
6
  const dialog = host.refs.dialog;
7
+ const document = dialog.ownerDocument;
8
+ const overlayId = `ui-search-shell-${Math.random().toString(36).slice(2, 11)}`;
6
9
  const [trigger, stopTracking] = trackTrigger(host);
7
- let external = host.state.open;
8
- let activeModal = Boolean(host.state.modal);
10
+ let external = host.props.open.value;
11
+ let activeModal = Boolean(host.props.modal.value);
9
12
  let suppressNativeClose = false;
10
13
  host.state.internalOpen = Boolean(external);
11
14
 
@@ -21,18 +24,22 @@ export default function controller(host) {
21
24
  suppressNativeClose = false;
22
25
  };
23
26
  const stop = host.effect(() => {
24
- if (host.state.open !== external) {
25
- external = host.state.open;
27
+ if (host.props.open.value !== external) {
28
+ external = host.props.open.value;
26
29
  host.state.internalOpen = Boolean(external);
27
30
  }
28
- const modal = Boolean(host.state.modal);
31
+ const modal = Boolean(host.props.modal.value);
29
32
  if (dialog.open && modal !== activeModal) closeNative();
30
33
  activeModal = modal;
31
34
  if (host.state.internalOpen && !dialog.open) {
32
35
  if (modal) dialog.showModal();
33
36
  else dialog.show();
34
- } else if (!host.state.internalOpen) {
37
+ }
38
+ if (host.state.internalOpen) {
39
+ openOverlay({ id: overlayId, modal, element: dialog, modalElement: dialog, dismissible: false, requestClose: () => {} });
40
+ } else {
35
41
  closeNative();
42
+ closeOverlay(document, overlayId);
36
43
  }
37
44
  });
38
45
 
@@ -64,11 +71,13 @@ export default function controller(host) {
64
71
  else rows[fromSearch ? rows.length - 1 : (index - 1 + rows.length) % rows.length].focus();
65
72
  };
66
73
  const onClick = (event) => {
67
- if (host.state.dismissible && event.target === dialog) dispatchClose("light-dismiss", trigger());
74
+ if (host.props.dismissible.value && event.target === dialog) dispatchClose("light-dismiss", trigger());
68
75
  };
69
76
  // Only the dialog's own close: a tooltip, menu, or popover inside it reports "close" too, and it bubbles.
70
77
  const onClose = (event) => {
71
78
  if (event.target !== dialog) return;
79
+ if (dialog.open) return;
80
+ closeOverlay(document, overlayId);
72
81
  if (!suppressNativeClose && host.state.internalOpen) dispatchClose("action", trigger());
73
82
  };
74
83
  dialog.addEventListener("cancel", onCancel);
@@ -83,5 +92,6 @@ export default function controller(host) {
83
92
  dialog.removeEventListener("click", onClick);
84
93
  dialog.removeEventListener("close", onClose);
85
94
  closeNative();
95
+ closeOverlay(document, overlayId);
86
96
  };
87
97
  }
@@ -4,7 +4,7 @@
4
4
  export default function controller(host) {
5
5
  const select = host.element;
6
6
  const apply = () => {
7
- const value = host.state.value;
7
+ const value = host.props.value.value;
8
8
  if (value === undefined || value === null) return;
9
9
  for (const option of select.options) option.defaultSelected = option.value === String(value);
10
10
  if (select.value !== String(value)) select.value = String(value);
@@ -1,3 +1,5 @@
1
+ import { announceOverlayOpen } from "../shared/overlay.js";
2
+
1
3
  const BREAKPOINTS = { sm: "40rem", md: "48rem", lg: "64rem" };
2
4
 
3
5
  function positive(value, fallback) {
@@ -16,14 +18,14 @@ export default function controller(host) {
16
18
  const view = document.defaultView;
17
19
  let pointerAbort;
18
20
  let media;
19
- let lastCollapsed = Boolean(host.state.collapsed);
20
- let lastWidth = Number(host.state.width) || 0;
21
+ let lastCollapsed = Boolean(host.props.collapsed.value);
22
+ let lastWidth = Number(host.props.width.value) || 0;
21
23
  host.state.internalCollapsed = lastCollapsed;
22
24
  host.state.drawer = false;
23
25
 
24
26
  const bounds = () => {
25
- const min = positive(host.state.minWidth, 200);
26
- return { min, max: Math.max(min, positive(host.state.maxWidth, 480)), step: positive(host.state.resizeStep, 16) };
27
+ const min = positive(host.props.minWidth.value, 200);
28
+ return { min, max: Math.max(min, positive(host.props.maxWidth.value, 480)), step: positive(host.props.resizeStep.value, 16) };
27
29
  };
28
30
  const currentWidth = () => element.getBoundingClientRect().width || 280;
29
31
  const setWidth = (value, trigger = "programmatic") => {
@@ -44,7 +46,7 @@ export default function controller(host) {
44
46
  if (event.key === "End") next = max;
45
47
  if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
46
48
  const delta = event.key === "ArrowRight" ? step : -step;
47
- next = currentWidth() + (host.state.side === "end" ? -delta : delta);
49
+ next = currentWidth() + (host.props.side.value === "end" ? -delta : delta);
48
50
  }
49
51
  if (next === null) return;
50
52
  event.preventDefault();
@@ -55,7 +57,7 @@ export default function controller(host) {
55
57
  event.preventDefault();
56
58
  const startX = event.clientX;
57
59
  const startWidth = currentWidth();
58
- const multiplier = host.state.side === "end" ? -1 : 1;
60
+ const multiplier = host.props.side.value === "end" ? -1 : 1;
59
61
  pointerAbort = new AbortController();
60
62
  const signal = pointerAbort.signal;
61
63
  const finish = () => {
@@ -75,7 +77,7 @@ export default function controller(host) {
75
77
  pointerAbort = undefined;
76
78
  };
77
79
  const syncHandle = () => {
78
- if (!host.state.resizable || host.state.drawer || host.state.internalCollapsed) { endPointer(); return; }
80
+ if (!host.props.resizable.value || host.state.drawer || host.state.internalCollapsed) { endPointer(); return; }
79
81
  const { min, max } = bounds();
80
82
  handle.setAttribute("aria-valuemin", String(min));
81
83
  handle.setAttribute("aria-valuemax", String(max));
@@ -103,7 +105,7 @@ export default function controller(host) {
103
105
  media?.removeEventListener("change", applyMode);
104
106
  // Without media queries (a non-browser DOM) the sidebar simply stays docked.
105
107
  if (typeof view.matchMedia !== "function") return;
106
- const width = BREAKPOINTS[host.state.breakpoint] ?? BREAKPOINTS.md;
108
+ const width = BREAKPOINTS[host.props.breakpoint.value] ?? BREAKPOINTS.md;
107
109
  media = view.matchMedia(`(width < ${width})`);
108
110
  media.addEventListener("change", applyMode);
109
111
  applyMode();
@@ -134,16 +136,17 @@ export default function controller(host) {
134
136
  // report it again, forever. Only the drawer's own popover ToggleEvent, which has a newState, counts.
135
137
  const onPopoverToggle = (event) => {
136
138
  if (!host.state.drawer || event.target !== element || typeof event.newState !== "string") return;
139
+ if (event.newState === "open") announceOverlayOpen(document, element);
137
140
  host.dispatch("toggle", { open: event.newState === "open", mode: "drawer", trigger: "programmatic" });
138
141
  };
139
142
 
140
143
  const apply = () => {
141
- const collapsed = Boolean(host.state.collapsed);
144
+ const collapsed = Boolean(host.props.collapsed.value);
142
145
  if (collapsed !== lastCollapsed) {
143
146
  lastCollapsed = collapsed;
144
147
  host.state.internalCollapsed = collapsed;
145
148
  }
146
- const width = Number(host.state.width) || 0;
149
+ const width = Number(host.props.width.value) || 0;
147
150
  if (width !== lastWidth) {
148
151
  lastWidth = width;
149
152
  if (width > 0) setWidth(width);
@@ -160,9 +163,9 @@ export default function controller(host) {
160
163
  if (!invokerCommands) document.addEventListener("click", onDocumentClick);
161
164
  if (lastWidth > 0) setWidth(lastWidth);
162
165
  watchBreakpoint();
163
- let lastBreakpoint = host.state.breakpoint;
166
+ let lastBreakpoint = host.props.breakpoint.value;
164
167
  const stop = host.effect(() => {
165
- if (host.state.breakpoint !== lastBreakpoint) { lastBreakpoint = host.state.breakpoint; watchBreakpoint(); }
168
+ if (host.props.breakpoint.value !== lastBreakpoint) { lastBreakpoint = host.props.breakpoint.value; watchBreakpoint(); }
166
169
  apply();
167
170
  });
168
171
  apply();
@@ -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, () => {
@@ -2,7 +2,7 @@
2
2
  export default function controller(host) {
3
3
  const element = host.element;
4
4
  const update = () => {
5
- const limit = Number(host.state.limit);
5
+ const limit = Number(host.props.limit.value);
6
6
  host.state.overLimit = Number.isFinite(limit) && limit >= 1 && element.children.length > Math.floor(limit);
7
7
  };
8
8
  const stop = host.effect(update);
@@ -12,7 +12,7 @@ export default function controller(host) {
12
12
  for (const tab of tabButtons()) tab.tabIndex = tab === button ? 0 : -1;
13
13
  button.focus();
14
14
  };
15
- let external = String(host.state.value || "");
15
+ let external = String(host.props.value.value || "");
16
16
  host.state.internalValue = external;
17
17
 
18
18
  const readPanels = () => {
@@ -45,7 +45,7 @@ export default function controller(host) {
45
45
  }
46
46
  };
47
47
  const stop = host.effect(() => {
48
- const value = String(host.state.value || "");
48
+ const value = String(host.props.value.value || "");
49
49
  if (value !== external) {
50
50
  external = value;
51
51
  host.state.internalValue = value;
@@ -69,10 +69,10 @@ export default function controller(host) {
69
69
  const button = event.target.closest?.('[role="tab"]');
70
70
  if (!button || !list.contains(button)) return;
71
71
  const buttons = tabButtons().filter((candidate) => !candidate.disabled);
72
- const vertical = host.state.orientation === "vertical";
72
+ const vertical = host.props.orientation.value === "vertical";
73
73
  const previousKey = vertical ? "ArrowUp" : "ArrowLeft";
74
74
  const nextKey = vertical ? "ArrowDown" : "ArrowRight";
75
- if (host.state.activation === "manual" && (event.key === "Enter" || event.key === " ")) {
75
+ if (host.props.activation.value === "manual" && (event.key === "Enter" || event.key === " ")) {
76
76
  event.preventDefault();
77
77
  select(button, "keyboard");
78
78
  return;
@@ -81,7 +81,7 @@ export default function controller(host) {
81
81
  event.preventDefault();
82
82
  const index = buttons.indexOf(button);
83
83
  const next = event.key === "Home" ? buttons[0] : event.key === "End" ? buttons.at(-1) : buttons[(index + (event.key === nextKey ? 1 : buttons.length - 1)) % buttons.length];
84
- if (host.state.activation !== "manual") select(next, "keyboard");
84
+ if (host.props.activation.value !== "manual") select(next, "keyboard");
85
85
  focusTab(next);
86
86
  };
87
87
  const onFocusout = (event) => {
@@ -2,7 +2,7 @@
2
2
  // value is also made the native default, so a form reset returns to it.
3
3
  export default function controller(host) {
4
4
  return host.effect(() => {
5
- const value = host.state.value;
5
+ const value = host.props.value.value;
6
6
  if (value === undefined || value === null) return;
7
7
  host.element.defaultValue = String(value);
8
8
  if (host.element.value !== String(value)) host.element.value = String(value);
@@ -9,7 +9,7 @@ export default function controller(host) {
9
9
  const element = host.element;
10
10
  const { action } = host.refs;
11
11
  if (!element.id) element.id = `ui-toast-authored-${++toastSequence}`;
12
- let remaining = Math.max(0, Number(host.state.duration) || 0);
12
+ let remaining = Math.max(0, Number(host.props.duration.value) || 0);
13
13
  let started = 0;
14
14
  let timer = null;
15
15
  let paused = false;
@@ -37,7 +37,7 @@ export default function controller(host) {
37
37
  const resume = () => {
38
38
  if (!paused || element.matches(":hover, :focus-within")) return;
39
39
  paused = false;
40
- if (host.state.duration > 0 && remaining <= 0) { dismiss("timeout", "programmatic"); return; }
40
+ if (host.props.duration.value > 0 && remaining <= 0) { dismiss("timeout", "programmatic"); return; }
41
41
  start();
42
42
  };
43
43
  const onFocusOut = () => queueMicrotask(resume);
@@ -45,7 +45,7 @@ export default function controller(host) {
45
45
  if (event.target.closest?.(".dismiss") || action?.contains(event.target)) dismiss("action", inputFor(event));
46
46
  };
47
47
  const stop = host.effect(() => {
48
- const duration = Math.max(0, Number(host.state.duration) || 0);
48
+ const duration = Math.max(0, Number(host.props.duration.value) || 0);
49
49
  if (duration === remaining || dismissed) return;
50
50
  remaining = duration;
51
51
  start();
@@ -1,3 +1,4 @@
1
+ import { announceOverlayOpen } from "../shared/overlay.js";
1
2
  import { trackTrigger } from "../shared/trigger.js";
2
3
 
3
4
  const instances = new WeakMap();
@@ -16,8 +17,11 @@ export default function controller(host) {
16
17
  const [trigger, stopTracking] = trackTrigger(host);
17
18
  const toasts = () => host.state.toasts ?? [];
18
19
  const authored = () => Array.from(element.children).some((child) => !child.classList.contains("toast"));
20
+ let announcedVisible = false;
19
21
  const sync = () => {
20
22
  const visible = authored() || toasts().length > 0;
23
+ if (visible && !announcedVisible) announceOverlayOpen(element.ownerDocument, element);
24
+ announcedVisible = visible;
21
25
  if (visible && !element.matches(":popover-open")) element.showPopover();
22
26
  else if (!visible && element.matches(":popover-open")) element.hidePopover();
23
27
  };
@@ -68,7 +72,7 @@ export default function controller(host) {
68
72
  const id = String(options.id || `ui-toast-${++toastIds}`);
69
73
  const tone = ["neutral", "info", "success", "warning", "danger"].includes(options.tone) ? options.tone : "neutral";
70
74
  host.state.toasts = [...toasts(), { id, message: String(message), tone, role: tone === "danger" ? "alert" : "status", closing: false }];
71
- const duration = Math.max(0, Number(options.duration ?? host.state.duration ?? 0));
75
+ const duration = Math.max(0, Number(options.duration ?? host.props.duration.value ?? 0));
72
76
  if (duration > 0) {
73
77
  timers.set(id, { remaining: duration, started: 0, handle: 0 });
74
78
  startTimer(id);
@@ -1,4 +1,4 @@
1
- import { closeOverlay, createAnchoredSurface, createIdResolver, openOverlay } from "../shared/overlay.js";
1
+ import { closeOverlay, createAnchoredSurface, createIdResolver, onOverlayOpen, openOverlay } from "../shared/overlay.js";
2
2
 
3
3
  const warmTooltips = new WeakMap();
4
4
 
@@ -34,7 +34,7 @@ export default function controller(host) {
34
34
  let hideTimer = null;
35
35
  let lastFor;
36
36
  let lastPlacement;
37
- let lastExternalOpen = Boolean(host.state.open);
37
+ let lastExternalOpen = Boolean(host.props.open.value);
38
38
  host.state.internalOpen = lastExternalOpen;
39
39
 
40
40
  const clearShow = () => { if (showTimer !== null) clearTimeout(showTimer); showTimer = null; };
@@ -44,14 +44,14 @@ export default function controller(host) {
44
44
  if (Boolean(host.state.internalOpen) === open) return;
45
45
  host.state.internalOpen = open;
46
46
  trackVisible(open);
47
- if (trigger && host.state.trigger === "click") trigger.setAttribute("aria-expanded", String(open));
47
+ if (trigger && host.props.trigger.value === "click") trigger.setAttribute("aria-expanded", String(open));
48
48
  host.dispatch(open ? "open" : "close", { open, reason: "action", trigger: input });
49
49
  };
50
50
  const onKeydown = (event) => {
51
51
  if (event.key !== "Escape") return;
52
52
  clearTimers();
53
53
  // A tooltip the reader opened is theirs to close.
54
- if (host.state.trigger === "click" && host.state.internalOpen) setOpen(false, "keyboard");
54
+ if (host.props.trigger.value === "click" && host.state.internalOpen) setOpen(false, "keyboard");
55
55
  };
56
56
  const onEnter = (event) => {
57
57
  if (event.pointerType === "touch") return;
@@ -60,7 +60,7 @@ export default function controller(host) {
60
60
  showTimer = setTimeout(() => {
61
61
  showTimer = null;
62
62
  setOpen(true, "pointer");
63
- }, warm.active > 0 || warm.until > Date.now() ? 0 : Math.max(0, Number(host.state.showDelay ?? 500)));
63
+ }, warm.active > 0 || warm.until > Date.now() ? 0 : Math.max(0, Number(host.props.showDelay.value ?? 500)));
64
64
  };
65
65
  const onLeave = () => {
66
66
  clearShow();
@@ -68,7 +68,7 @@ export default function controller(host) {
68
68
  hideTimer = setTimeout(() => {
69
69
  hideTimer = null;
70
70
  setOpen(false, "pointer");
71
- }, Math.max(0, Number(host.state.hideDelay ?? 100)));
71
+ }, Math.max(0, Number(host.props.hideDelay.value ?? 100)));
72
72
  };
73
73
  const onFocusin = () => {
74
74
  focused = true;
@@ -104,7 +104,7 @@ export default function controller(host) {
104
104
  ids.add(element.id);
105
105
  trigger.setAttribute("aria-describedby", [...ids].join(" "));
106
106
  trigger.addEventListener("keydown", onKeydown);
107
- const how = host.state.trigger ?? "hover";
107
+ const how = host.props.trigger.value ?? "hover";
108
108
  if (how === "click") {
109
109
  // A question-mark button says nothing on hover: it opens when pressed, and closes the same way.
110
110
  trigger.addEventListener("click", onClick);
@@ -123,8 +123,8 @@ export default function controller(host) {
123
123
  apply();
124
124
  });
125
125
  const setup = () => {
126
- const nextFor = String(host.state.for ?? "");
127
- const nextPlacement = String(host.state.placement ?? "top");
126
+ const nextFor = String(host.props.for.value ?? "");
127
+ const nextPlacement = String(host.props.placement.value ?? "top");
128
128
  if (surface && nextFor === lastFor && nextPlacement === lastPlacement) return;
129
129
  lastFor = nextFor;
130
130
  lastPlacement = nextPlacement;
@@ -138,14 +138,24 @@ export default function controller(host) {
138
138
  surface = createAnchoredSurface(element, { anchor: trigger, placement: nextPlacement, gap: offset });
139
139
  };
140
140
  const close = (reason, input) => {
141
- if (reason !== "escape" && reason !== "light-dismiss") return;
141
+ if (reason !== "escape" && reason !== "light-dismiss" && reason !== "programmatic") return;
142
142
  clearTimers();
143
+ if (!host.state.internalOpen) return;
143
144
  host.state.internalOpen = false;
144
145
  trackVisible(false);
146
+ surface?.hide();
147
+ closeOverlay(document, overlayId);
148
+ if (trigger && host.props.trigger.value === "click") trigger.setAttribute("aria-expanded", "false");
145
149
  host.dispatch("close", { open: false, reason, trigger: input });
146
150
  };
151
+ const stopOverlayOpen = onOverlayOpen(document, (id) => {
152
+ if (id === overlayId) return;
153
+ clearTimers();
154
+ focused = false;
155
+ close("programmatic", "programmatic");
156
+ });
147
157
  const apply = () => {
148
- const externalOpen = Boolean(host.state.open);
158
+ const externalOpen = Boolean(host.props.open.value);
149
159
  if (externalOpen !== lastExternalOpen) {
150
160
  lastExternalOpen = externalOpen;
151
161
  host.state.internalOpen = externalOpen;
@@ -169,6 +179,7 @@ export default function controller(host) {
169
179
  apply();
170
180
  return () => {
171
181
  stop();
182
+ stopOverlayOpen();
172
183
  ids.stop();
173
184
  clearTimers();
174
185
  trackVisible(false);
@@ -41,7 +41,7 @@ export default function controller(host) {
41
41
  const allItems = () => Array.from(element.querySelectorAll(itemSelector));
42
42
  const visibleItems = () => allItems().filter((item) => item.getClientRects().length > 0 && item.getAttribute("aria-disabled") !== "true");
43
43
  const rowFor = (item) => item.querySelector(":scope > .row");
44
- const selectionMode = () => String(host.state.selection || "none");
44
+ const selectionMode = () => String(host.props.selection.value || "none");
45
45
  // Only a branch has aria-expanded.
46
46
  const acceptsChildren = (item) => item.hasAttribute("aria-expanded") && item.getAttribute("aria-disabled") !== "true";
47
47
  const metadata = (item) => ({
@@ -70,7 +70,7 @@ export default function controller(host) {
70
70
  if (nextPosition === "inside") {
71
71
  if (!acceptsChildren(to) || (toMeta.accepts.length && !toMeta.accepts.includes(fromMeta.type))) return { reason: "incompatible" };
72
72
  } else if (fromMeta.type !== toMeta.type) return { reason: "incompatible" };
73
- const maxDepth = Math.max(0, Math.floor(Number(host.state.maxDepth ?? 0)));
73
+ const maxDepth = Math.max(0, Math.floor(Number(host.props.maxDepth.value ?? 0)));
74
74
  if (maxDepth > 0) {
75
75
  const resultingDepth = Math.max(0, Math.floor(depth(to))) + (nextPosition === "inside" ? 1 : 0) + subtreeDepth(from);
76
76
  if (resultingDepth > maxDepth) return { reason: "max-depth", maxDepth, resultingDepth };
@@ -91,7 +91,7 @@ export default function controller(host) {
91
91
  hoverTimer = null;
92
92
  hoverKey = null;
93
93
  if (key) expandTarget(key);
94
- }, Math.max(0, Number(host.state.hoverExpandDelay ?? 700)));
94
+ }, Math.max(0, Number(host.props.hoverExpandDelay.value ?? 700)));
95
95
  };
96
96
  const clearTarget = () => {
97
97
  target?.removeAttribute("data-drop-position");
@@ -417,7 +417,7 @@ export default function controller(host) {
417
417
  });
418
418
  observer.observe(element, { childList: true, subtree: true, attributes: true, attributeFilter: ["aria-selected"] });
419
419
  const stop = host.effect(() => {
420
- element.setAttribute("aria-label", String(host.state.label || "Tree"));
420
+ element.setAttribute("aria-label", String(host.props.label.value || "Tree"));
421
421
  syncSelection();
422
422
  });
423
423
  syncStructure();
@@ -24,10 +24,10 @@ export default function controller(host) {
24
24
  trackInputModality(element.ownerDocument);
25
25
  const childItems = () => Array.from(children?.children ?? [])
26
26
  .filter((child) => child.matches?.('[role="treeitem"]'));
27
- let lastExternalExpanded = Boolean(host.state.expanded);
27
+ let lastExternalExpanded = Boolean(host.props.expanded.value);
28
28
  host.state.internalExpanded = lastExternalExpanded;
29
29
 
30
- const isContainer = () => Boolean(host.state.container) || Boolean(host.state.lazy) || childItems().length > 0;
30
+ const isContainer = () => Boolean(host.props.container.value) || Boolean(host.props.lazy.value) || childItems().length > 0;
31
31
  const updateLevel = () => {
32
32
  const tree = element.closest('[role="tree"]');
33
33
  let ancestor = parentItem(element);
@@ -40,21 +40,21 @@ export default function controller(host) {
40
40
  };
41
41
 
42
42
  const apply = () => {
43
- const externalExpanded = Boolean(host.state.expanded);
43
+ const externalExpanded = Boolean(host.props.expanded.value);
44
44
  if (externalExpanded !== lastExternalExpanded) {
45
45
  lastExternalExpanded = externalExpanded;
46
46
  host.state.internalExpanded = externalExpanded;
47
47
  }
48
48
  const container = isContainer();
49
49
  const expanded = container && Boolean(host.state.internalExpanded);
50
- const name = String(host.state.label || "Unnamed item");
50
+ const name = String(host.props.label.value || "Unnamed item");
51
51
  host.state.isContainer = container;
52
52
  // A leaf has no aria-expanded at all; "false" would announce it as a collapsed branch.
53
53
  if (container) element.setAttribute("aria-expanded", String(expanded));
54
54
  else element.removeAttribute("aria-expanded");
55
- if (host.state.lazy && expanded && childItems().length === 0) element.setAttribute("aria-busy", "true");
55
+ if (host.props.lazy.value && expanded && childItems().length === 0) element.setAttribute("aria-busy", "true");
56
56
  else element.removeAttribute("aria-busy");
57
- element.tabIndex = host.state.disabled || !host.state.tabStop ? -1 : 0;
57
+ element.tabIndex = host.props.disabled.value || !host.state.tabStop ? -1 : 0;
58
58
  const depth = Number(host.state.structuralLevel ?? 1) - 1;
59
59
  element.style.setProperty("--ui-tree-item-depth", String(depth));
60
60
  // Nested items already sit inside their parent's indented box. Add just one local step.
@@ -64,15 +64,15 @@ export default function controller(host) {
64
64
  };
65
65
 
66
66
  const setExpanded = (next, trigger) => {
67
- if (!isContainer() || host.state.disabled || Boolean(host.state.internalExpanded) === next) return;
67
+ if (!isContainer() || host.props.disabled.value || Boolean(host.state.internalExpanded) === next) return;
68
68
  host.state.internalExpanded = next;
69
69
  apply();
70
- host.dispatch("expand", { id: String(host.state.itemId || ""), expanded: next, trigger });
70
+ host.dispatch("expand", { id: String(host.props.itemId.value || ""), expanded: next, trigger });
71
71
  element.dispatchEvent(new CustomEvent("ui-tree-expansion-change", { bubbles: true }));
72
72
  };
73
73
  const onDisclosureClick = (event) => { event.stopPropagation(); setExpanded(!Boolean(host.state.internalExpanded), triggerFor(event)); };
74
74
  const onRowClick = (event) => {
75
- if (host.state.disabled) return;
75
+ if (host.props.disabled.value) return;
76
76
  const interactive = event.composedPath().some((node) => node instanceof HTMLElement && node.matches?.(CONTROLS));
77
77
  if (interactive) return;
78
78
  if (isContainer()) {
@@ -84,7 +84,7 @@ export default function controller(host) {
84
84
  const link = labelText?.querySelector("a[href]");
85
85
  if (link) link.dispatchEvent(new MouseEvent("click", event));
86
86
  };
87
- const onRoving = (event) => { host.state.tabStop = Boolean(event.detail?.active) && !host.state.disabled; apply(); };
87
+ const onRoving = (event) => { host.state.tabStop = Boolean(event.detail?.active) && !host.props.disabled.value; apply(); };
88
88
  const onExpansionRequest = (event) => {
89
89
  if (typeof event.detail?.expanded === "boolean") setExpanded(event.detail.expanded, event.detail.trigger ?? "keyboard");
90
90
  };
@@ -113,7 +113,7 @@ export default function controller(host) {
113
113
  let pointerHover = false;
114
114
  let keyboardFocus = false;
115
115
  // The tree sets this for its items; an item's own prop overrides it either way.
116
- const marqueeWanted = () => host.state.marquee
116
+ const marqueeWanted = () => host.props.marquee.value
117
117
  || getComputedStyle(element).getPropertyValue("--_ui-default-tree-item-marquee").trim() === "1";
118
118
  // A slotted link may fill the row and have padding past its name. Measure the rendered letters,
119
119
  // since moving that link's box to the actions would send a short name too far (or move it at all).