@threadlabs/looma 0.3.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (494) hide show
  1. package/README.md +43 -12
  2. package/components/shared/editor.js +69 -0
  3. package/components/shared/input-modality.js +20 -0
  4. package/components/shared/overlay.js +281 -0
  5. package/components/shared/trigger.js +17 -0
  6. package/components/ui-affordance-scope/ui-affordance-scope.html +22 -0
  7. package/components/ui-affordance-scope/ui-affordance-scope.js +76 -0
  8. package/components/ui-avatar/ui-avatar.html +59 -0
  9. package/components/ui-avatar/ui-avatar.js +47 -0
  10. package/components/ui-avatar-group/ui-avatar-group.html +62 -0
  11. package/components/ui-avatar-group/ui-avatar-group.js +27 -0
  12. package/components/ui-badge/ui-badge.html +94 -0
  13. package/components/ui-button/ui-button.html +198 -0
  14. package/components/ui-callout/ui-callout.html +104 -0
  15. package/components/ui-checkbox/ui-checkbox.html +107 -0
  16. package/components/ui-checkbox/ui-checkbox.js +24 -0
  17. package/components/ui-cluster/ui-cluster.html +49 -0
  18. package/components/ui-combobox/ui-combobox.html +377 -0
  19. package/components/ui-combobox/ui-combobox.js +432 -0
  20. package/components/ui-container/ui-container.html +39 -0
  21. package/components/ui-context-menu/ui-context-menu.html +75 -0
  22. package/components/ui-context-menu/ui-context-menu.js +143 -0
  23. package/components/ui-dialog/ui-dialog.html +178 -0
  24. package/components/ui-dialog/ui-dialog.js +105 -0
  25. package/components/ui-disclosure/ui-disclosure.html +109 -0
  26. package/components/ui-disclosure/ui-disclosure.js +28 -0
  27. package/components/ui-editable/ui-editable.html +163 -0
  28. package/components/ui-editable/ui-editable.js +113 -0
  29. package/components/ui-editor-insert-table-grid/ui-editor-insert-table-grid.html +97 -0
  30. package/components/ui-editor-insert-table-grid/ui-editor-insert-table-grid.js +71 -0
  31. package/components/ui-editor-mention-menu/ui-editor-mention-menu.html +157 -0
  32. package/components/ui-editor-mention-menu/ui-editor-mention-menu.js +50 -0
  33. package/components/ui-editor-slash-menu/ui-editor-slash-menu.html +197 -0
  34. package/components/ui-editor-slash-menu/ui-editor-slash-menu.js +44 -0
  35. package/components/ui-editor-table-context-menu/ui-editor-table-context-menu.html +164 -0
  36. package/components/ui-editor-table-context-menu/ui-editor-table-context-menu.js +75 -0
  37. package/components/ui-editor-table-overlay/ui-editor-table-overlay.html +422 -0
  38. package/components/ui-editor-table-overlay/ui-editor-table-overlay.js +119 -0
  39. package/components/ui-editor-table-toolbar/ui-editor-table-toolbar.html +271 -0
  40. package/components/ui-editor-table-toolbar/ui-editor-table-toolbar.js +54 -0
  41. package/components/ui-editor-toolbar/ui-editor-toolbar.html +110 -0
  42. package/components/ui-floating-action-button/ui-floating-action-button.html +83 -0
  43. package/components/ui-form-field/ui-form-field.html +45 -0
  44. package/components/ui-form-field/ui-form-field.js +71 -0
  45. package/components/ui-grid/ui-grid.html +46 -0
  46. package/components/ui-icon/ui-icon.html +34 -0
  47. package/components/ui-icon/ui-icon.js +8 -0
  48. package/components/ui-icon-button/ui-icon-button.html +167 -0
  49. package/components/ui-icon-button/ui-icon-button.js +7 -0
  50. package/components/ui-input/ui-input.html +81 -0
  51. package/components/ui-input/ui-input.js +7 -0
  52. package/components/ui-menu/ui-menu.html +87 -0
  53. package/components/ui-menu/ui-menu.js +114 -0
  54. package/components/ui-menu-item/ui-menu-item.html +37 -0
  55. package/components/ui-popover/ui-popover.html +85 -0
  56. package/components/ui-popover/ui-popover.js +70 -0
  57. package/components/ui-radio/ui-radio.html +57 -0
  58. package/components/ui-radio/ui-radio.js +25 -0
  59. package/components/ui-radio-group/ui-radio-group.html +51 -0
  60. package/components/ui-radio-group/ui-radio-group.js +42 -0
  61. package/components/ui-reel/ui-reel.html +67 -0
  62. package/components/ui-search-result-row/ui-search-result-row.html +101 -0
  63. package/components/ui-search-shell/ui-search-shell.html +142 -0
  64. package/components/ui-search-shell/ui-search-shell.js +60 -0
  65. package/components/ui-select/ui-select.html +87 -0
  66. package/components/ui-select/ui-select.js +16 -0
  67. package/components/ui-separator/ui-separator.html +22 -0
  68. package/components/ui-sidebar/ui-sidebar.html +183 -0
  69. package/components/ui-sidebar/ui-sidebar.js +178 -0
  70. package/components/ui-stack/ui-stack.html +59 -0
  71. package/components/ui-switch/ui-switch.html +95 -0
  72. package/components/ui-switch/ui-switch.js +24 -0
  73. package/components/ui-switcher/ui-switcher.html +65 -0
  74. package/components/ui-tabs/ui-tabs.html +134 -0
  75. package/components/ui-tabs/ui-tabs.js +81 -0
  76. package/components/ui-textarea/ui-textarea.html +80 -0
  77. package/components/ui-textarea/ui-textarea.js +7 -0
  78. package/components/ui-toast-region/ui-toast-region.html +127 -0
  79. package/components/ui-toast-region/ui-toast-region.js +119 -0
  80. package/components/ui-tooltip/ui-tooltip.html +122 -0
  81. package/components/ui-tooltip/ui-tooltip.js +134 -0
  82. package/components/ui-top-bar/ui-top-bar.html +53 -0
  83. package/components/ui-tree/ui-tree.html +29 -0
  84. package/components/ui-tree/ui-tree.js +250 -0
  85. package/components/ui-tree-item/ui-tree-item.html +326 -0
  86. package/components/ui-tree-item/ui-tree-item.js +94 -0
  87. package/dist/index.d.ts +4 -414
  88. package/dist/index.js +55 -657
  89. package/editor/chunks/extensions.js +7267 -0
  90. package/editor/chunks/table-backgrounds.js +51 -0
  91. package/editor/chunks/ui.js +92 -0
  92. package/editor/extensions/callout.d.ts +20 -0
  93. package/editor/extensions/index.d.ts +12 -441
  94. package/editor/extensions/index.js +3 -64
  95. package/editor/extensions/list-behavior.d.ts +7 -0
  96. package/editor/extensions/mention.d.ts +35 -0
  97. package/editor/extensions/preset.d.ts +42 -0
  98. package/editor/extensions/slash-command.d.ts +80 -0
  99. package/editor/extensions/smart-paste.d.ts +13 -0
  100. package/editor/extensions/table-commands.d.ts +114 -0
  101. package/editor/extensions/table-formatting.d.ts +60 -0
  102. package/editor/icons.d.ts +55 -0
  103. package/editor/index.d.ts +8 -6
  104. package/editor/index.js +96 -71
  105. package/editor/insert-table-grid.d.ts +7 -0
  106. package/editor/mention-contract.d.ts +78 -0
  107. package/editor/mention-menu.d.ts +9 -0
  108. package/editor/slash-menu.d.ts +29 -0
  109. package/editor/table-backgrounds.d.ts +43 -0
  110. package/editor/table-context-menu.d.ts +12 -0
  111. package/editor/table-overlay.d.ts +79 -0
  112. package/editor/ui.d.ts +10 -50
  113. package/editor/ui.js +3 -14
  114. package/editor/viewport.d.ts +15 -0
  115. package/package.json +84 -80
  116. package/styles/ui-affordance-scope.css +19 -0
  117. package/styles/ui-avatar-group.css +56 -0
  118. package/styles/ui-avatar.css +47 -0
  119. package/styles/ui-badge.css +91 -0
  120. package/styles/ui-button.css +206 -0
  121. package/styles/ui-callout.css +76 -0
  122. package/styles/ui-checkbox.css +98 -0
  123. package/styles/ui-cluster.css +46 -0
  124. package/styles/ui-combobox.css +213 -0
  125. package/styles/ui-container.css +36 -0
  126. package/styles/ui-context-menu.css +68 -0
  127. package/styles/ui-dialog.css +160 -0
  128. package/styles/ui-disclosure.css +95 -0
  129. package/styles/ui-editable.css +139 -0
  130. package/styles/ui-editor-insert-table-grid.css +65 -0
  131. package/styles/ui-editor-mention-menu.css +121 -0
  132. package/styles/ui-editor-slash-menu.css +179 -0
  133. package/styles/ui-editor-table-context-menu.css +118 -0
  134. package/styles/ui-editor-table-overlay.css +318 -0
  135. package/styles/ui-editor-table-toolbar.css +191 -0
  136. package/styles/ui-editor-toolbar.css +115 -0
  137. package/styles/ui-floating-action-button.css +82 -0
  138. package/styles/ui-form-field.css +36 -0
  139. package/styles/ui-grid.css +43 -0
  140. package/styles/ui-icon-button.css +169 -0
  141. package/styles/ui-icon.css +23 -0
  142. package/styles/ui-input.css +82 -0
  143. package/styles/ui-menu-item.css +34 -0
  144. package/styles/ui-menu.css +80 -0
  145. package/styles/ui-popover.css +76 -0
  146. package/styles/ui-radio-group.css +38 -0
  147. package/styles/ui-radio.css +46 -0
  148. package/styles/ui-reel.css +63 -0
  149. package/styles/ui-search-result-row.css +92 -0
  150. package/styles/ui-search-shell.css +128 -0
  151. package/styles/ui-select.css +86 -0
  152. package/styles/ui-separator.css +16 -0
  153. package/styles/ui-sidebar.css +166 -0
  154. package/styles/ui-stack.css +55 -0
  155. package/styles/ui-switch.css +88 -0
  156. package/styles/ui-switcher.css +61 -0
  157. package/styles/ui-tabs.css +114 -0
  158. package/styles/ui-textarea.css +77 -0
  159. package/styles/ui-toast-region.css +103 -0
  160. package/styles/ui-tooltip.css +113 -0
  161. package/styles/ui-top-bar.css +51 -0
  162. package/styles/ui-tree-item.css +267 -0
  163. package/styles/ui-tree.css +16 -0
  164. package/vanilla/UiAffordanceScope.d.ts +14 -0
  165. package/vanilla/UiAffordanceScope.js +30 -0
  166. package/vanilla/UiAvatar.d.ts +17 -0
  167. package/vanilla/UiAvatar.js +41 -0
  168. package/vanilla/UiAvatarGroup.d.ts +15 -0
  169. package/vanilla/UiAvatarGroup.js +40 -0
  170. package/vanilla/UiBadge.d.ts +15 -0
  171. package/vanilla/UiBadge.js +30 -0
  172. package/vanilla/UiButton.d.ts +16 -0
  173. package/vanilla/UiButton.js +32 -0
  174. package/vanilla/UiCallout.d.ts +14 -0
  175. package/vanilla/UiCallout.js +124 -0
  176. package/vanilla/UiCheckbox.d.ts +19 -0
  177. package/vanilla/UiCheckbox.js +47 -0
  178. package/vanilla/UiCluster.d.ts +15 -0
  179. package/vanilla/UiCluster.js +30 -0
  180. package/vanilla/UiCombobox.d.ts +42 -0
  181. package/vanilla/UiCombobox.js +194 -0
  182. package/vanilla/UiContainer.d.ts +15 -0
  183. package/vanilla/UiContainer.js +30 -0
  184. package/vanilla/UiContextMenu.d.ts +18 -0
  185. package/vanilla/UiContextMenu.js +35 -0
  186. package/vanilla/UiDialog.d.ts +19 -0
  187. package/vanilla/UiDialog.js +53 -0
  188. package/vanilla/UiDisclosure.d.ts +18 -0
  189. package/vanilla/UiDisclosure.js +49 -0
  190. package/vanilla/UiEditable.d.ts +22 -0
  191. package/vanilla/UiEditable.js +59 -0
  192. package/vanilla/UiEditorInsertTableGrid.d.ts +18 -0
  193. package/vanilla/UiEditorInsertTableGrid.js +46 -0
  194. package/vanilla/UiEditorMentionMenu.d.ts +21 -0
  195. package/vanilla/UiEditorMentionMenu.js +63 -0
  196. package/vanilla/UiEditorSlashMenu.d.ts +20 -0
  197. package/vanilla/UiEditorSlashMenu.js +74 -0
  198. package/vanilla/UiEditorTableContextMenu.d.ts +17 -0
  199. package/vanilla/UiEditorTableContextMenu.js +69 -0
  200. package/vanilla/UiEditorTableOverlay.d.ts +16 -0
  201. package/vanilla/UiEditorTableOverlay.js +113 -0
  202. package/vanilla/UiEditorTableToolbar.d.ts +18 -0
  203. package/vanilla/UiEditorTableToolbar.js +121 -0
  204. package/vanilla/UiEditorToolbar.d.ts +14 -0
  205. package/vanilla/UiEditorToolbar.js +30 -0
  206. package/vanilla/UiFloatingActionButton.d.ts +16 -0
  207. package/vanilla/UiFloatingActionButton.js +35 -0
  208. package/vanilla/UiFormField.d.ts +16 -0
  209. package/vanilla/UiFormField.js +54 -0
  210. package/vanilla/UiGrid.d.ts +15 -0
  211. package/vanilla/UiGrid.js +30 -0
  212. package/vanilla/UiIcon.d.ts +14 -0
  213. package/vanilla/UiIcon.js +40 -0
  214. package/vanilla/UiIconButton.d.ts +19 -0
  215. package/vanilla/UiIconButton.js +37 -0
  216. package/vanilla/UiInput.d.ts +18 -0
  217. package/vanilla/UiInput.js +37 -0
  218. package/vanilla/UiMenu.d.ts +19 -0
  219. package/vanilla/UiMenu.js +35 -0
  220. package/vanilla/UiMenuItem.d.ts +15 -0
  221. package/vanilla/UiMenuItem.js +43 -0
  222. package/vanilla/UiPopover.d.ts +18 -0
  223. package/vanilla/UiPopover.js +33 -0
  224. package/vanilla/UiRadio.d.ts +19 -0
  225. package/vanilla/UiRadio.js +48 -0
  226. package/vanilla/UiRadioGroup.d.ts +21 -0
  227. package/vanilla/UiRadioGroup.js +35 -0
  228. package/vanilla/UiReel.d.ts +16 -0
  229. package/vanilla/UiReel.js +34 -0
  230. package/vanilla/UiSearchResultRow.d.ts +15 -0
  231. package/vanilla/UiSearchResultRow.js +82 -0
  232. package/vanilla/UiSearchShell.d.ts +18 -0
  233. package/vanilla/UiSearchShell.js +74 -0
  234. package/vanilla/UiSelect.d.ts +18 -0
  235. package/vanilla/UiSelect.js +42 -0
  236. package/vanilla/UiSeparator.d.ts +14 -0
  237. package/vanilla/UiSeparator.js +28 -0
  238. package/vanilla/UiSidebar.d.ts +24 -0
  239. package/vanilla/UiSidebar.js +47 -0
  240. package/vanilla/UiStack.d.ts +16 -0
  241. package/vanilla/UiStack.js +32 -0
  242. package/vanilla/UiSwitch.d.ts +18 -0
  243. package/vanilla/UiSwitch.js +46 -0
  244. package/vanilla/UiSwitcher.d.ts +16 -0
  245. package/vanilla/UiSwitcher.js +32 -0
  246. package/vanilla/UiTabs.d.ts +18 -0
  247. package/vanilla/UiTabs.js +47 -0
  248. package/vanilla/UiTextarea.d.ts +19 -0
  249. package/vanilla/UiTextarea.js +40 -0
  250. package/vanilla/UiToastRegion.d.ts +20 -0
  251. package/vanilla/UiToastRegion.js +58 -0
  252. package/vanilla/UiTooltip.d.ts +21 -0
  253. package/vanilla/UiTooltip.js +34 -0
  254. package/vanilla/UiTopBar.d.ts +13 -0
  255. package/vanilla/UiTopBar.js +59 -0
  256. package/vanilla/UiTree.d.ts +18 -0
  257. package/vanilla/UiTree.js +31 -0
  258. package/vanilla/UiTreeItem.d.ts +26 -0
  259. package/vanilla/UiTreeItem.js +164 -0
  260. package/vanilla/index.js +48 -0
  261. package/vue/UiAffordanceScope.d.ts +18 -0
  262. package/vue/UiAffordanceScope.js +2 -0
  263. package/vue/UiAffordanceScope.vue +118 -0
  264. package/vue/UiAvatar.d.ts +23 -0
  265. package/vue/UiAvatar.js +2 -0
  266. package/vue/UiAvatar.vue +152 -0
  267. package/vue/UiAvatarGroup.d.ts +20 -0
  268. package/vue/UiAvatarGroup.js +2 -0
  269. package/vue/UiAvatarGroup.vue +167 -0
  270. package/vue/UiBadge.d.ts +20 -0
  271. package/vue/UiBadge.js +2 -0
  272. package/vue/UiBadge.vue +123 -0
  273. package/vue/UiButton.d.ts +22 -0
  274. package/vue/UiButton.js +2 -0
  275. package/vue/UiButton.vue +229 -0
  276. package/vue/UiCallout.d.ts +18 -0
  277. package/vue/UiCallout.js +2 -0
  278. package/vue/UiCallout.vue +104 -0
  279. package/vue/UiCheckbox.d.ts +38 -0
  280. package/vue/UiCheckbox.js +2 -0
  281. package/vue/UiCheckbox.vue +216 -0
  282. package/vue/UiCluster.d.ts +17 -0
  283. package/vue/UiCluster.js +2 -0
  284. package/vue/UiCluster.vue +75 -0
  285. package/vue/UiCombobox.d.ts +255 -0
  286. package/vue/UiCombobox.js +2 -0
  287. package/vue/UiCombobox.vue +466 -0
  288. package/vue/UiContainer.d.ts +17 -0
  289. package/vue/UiContainer.js +2 -0
  290. package/vue/UiContainer.vue +65 -0
  291. package/vue/UiContextMenu.d.ts +50 -0
  292. package/vue/UiContextMenu.js +2 -0
  293. package/vue/UiContextMenu.vue +166 -0
  294. package/vue/UiDialog.d.ts +39 -0
  295. package/vue/UiDialog.js +2 -0
  296. package/vue/UiDialog.vue +273 -0
  297. package/vue/UiDisclosure.d.ts +44 -0
  298. package/vue/UiDisclosure.js +2 -0
  299. package/vue/UiDisclosure.vue +211 -0
  300. package/vue/UiEditable.d.ts +48 -0
  301. package/vue/UiEditable.js +2 -0
  302. package/vue/UiEditable.vue +267 -0
  303. package/vue/UiEditorInsertTableGrid.d.ts +26 -0
  304. package/vue/UiEditorInsertTableGrid.js +2 -0
  305. package/vue/UiEditorInsertTableGrid.vue +210 -0
  306. package/vue/UiEditorMentionMenu.d.ts +44 -0
  307. package/vue/UiEditorMentionMenu.js +2 -0
  308. package/vue/UiEditorMentionMenu.vue +284 -0
  309. package/vue/UiEditorSlashMenu.d.ts +41 -0
  310. package/vue/UiEditorSlashMenu.js +2 -0
  311. package/vue/UiEditorSlashMenu.vue +306 -0
  312. package/vue/UiEditorTableContextMenu.d.ts +19 -0
  313. package/vue/UiEditorTableContextMenu.js +2 -0
  314. package/vue/UiEditorTableContextMenu.vue +252 -0
  315. package/vue/UiEditorTableOverlay.d.ts +66 -0
  316. package/vue/UiEditorTableOverlay.js +2 -0
  317. package/vue/UiEditorTableOverlay.vue +455 -0
  318. package/vue/UiEditorTableToolbar.d.ts +21 -0
  319. package/vue/UiEditorTableToolbar.js +2 -0
  320. package/vue/UiEditorTableToolbar.vue +339 -0
  321. package/vue/UiEditorToolbar.d.ts +18 -0
  322. package/vue/UiEditorToolbar.js +2 -0
  323. package/vue/UiEditorToolbar.vue +138 -0
  324. package/vue/UiFloatingActionButton.d.ts +22 -0
  325. package/vue/UiFloatingActionButton.js +2 -0
  326. package/vue/UiFloatingActionButton.vue +116 -0
  327. package/vue/UiFormField.d.ts +28 -0
  328. package/vue/UiFormField.js +2 -0
  329. package/vue/UiFormField.vue +124 -0
  330. package/vue/UiGrid.d.ts +17 -0
  331. package/vue/UiGrid.js +2 -0
  332. package/vue/UiGrid.vue +72 -0
  333. package/vue/UiIcon.d.ts +8 -0
  334. package/vue/UiIcon.js +2 -0
  335. package/vue/UiIcon.vue +135 -0
  336. package/vue/UiIconButton.d.ts +27 -0
  337. package/vue/UiIconButton.js +2 -0
  338. package/vue/UiIconButton.vue +268 -0
  339. package/vue/UiInput.d.ts +20 -0
  340. package/vue/UiInput.js +2 -0
  341. package/vue/UiInput.vue +177 -0
  342. package/vue/UiMenu.d.ts +52 -0
  343. package/vue/UiMenu.js +2 -0
  344. package/vue/UiMenu.vue +194 -0
  345. package/vue/UiMenuItem.d.ts +20 -0
  346. package/vue/UiMenuItem.js +2 -0
  347. package/vue/UiMenuItem.vue +55 -0
  348. package/vue/UiPopover.d.ts +44 -0
  349. package/vue/UiPopover.js +2 -0
  350. package/vue/UiPopover.vue +188 -0
  351. package/vue/UiRadio.d.ts +38 -0
  352. package/vue/UiRadio.js +2 -0
  353. package/vue/UiRadio.vue +166 -0
  354. package/vue/UiRadioGroup.d.ts +50 -0
  355. package/vue/UiRadioGroup.js +2 -0
  356. package/vue/UiRadioGroup.vue +161 -0
  357. package/vue/UiReel.d.ts +18 -0
  358. package/vue/UiReel.js +2 -0
  359. package/vue/UiReel.vue +93 -0
  360. package/vue/UiSearchResultRow.d.ts +28 -0
  361. package/vue/UiSearchResultRow.js +2 -0
  362. package/vue/UiSearchResultRow.vue +124 -0
  363. package/vue/UiSearchShell.d.ts +42 -0
  364. package/vue/UiSearchShell.js +2 -0
  365. package/vue/UiSearchShell.vue +233 -0
  366. package/vue/UiSelect.d.ts +30 -0
  367. package/vue/UiSelect.js +2 -0
  368. package/vue/UiSelect.vue +183 -0
  369. package/vue/UiSeparator.d.ts +8 -0
  370. package/vue/UiSeparator.js +2 -0
  371. package/vue/UiSeparator.vue +38 -0
  372. package/vue/UiSidebar.d.ts +54 -0
  373. package/vue/UiSidebar.js +2 -0
  374. package/vue/UiSidebar.vue +288 -0
  375. package/vue/UiStack.d.ts +18 -0
  376. package/vue/UiStack.js +2 -0
  377. package/vue/UiStack.vue +85 -0
  378. package/vue/UiSwitch.d.ts +36 -0
  379. package/vue/UiSwitch.js +2 -0
  380. package/vue/UiSwitch.vue +203 -0
  381. package/vue/UiSwitcher.d.ts +18 -0
  382. package/vue/UiSwitcher.js +2 -0
  383. package/vue/UiSwitcher.vue +91 -0
  384. package/vue/UiTabs.d.ts +36 -0
  385. package/vue/UiTabs.js +2 -0
  386. package/vue/UiTabs.vue +269 -0
  387. package/vue/UiTextarea.d.ts +22 -0
  388. package/vue/UiTextarea.js +2 -0
  389. package/vue/UiTextarea.vue +177 -0
  390. package/vue/UiToastRegion.d.ts +48 -0
  391. package/vue/UiToastRegion.js +2 -0
  392. package/vue/UiToastRegion.vue +256 -0
  393. package/vue/UiTooltip.d.ts +50 -0
  394. package/vue/UiTooltip.js +2 -0
  395. package/vue/UiTooltip.vue +230 -0
  396. package/vue/UiTopBar.d.ts +19 -0
  397. package/vue/UiTopBar.js +2 -0
  398. package/vue/UiTopBar.vue +56 -0
  399. package/vue/UiTree.d.ts +62 -0
  400. package/vue/UiTree.js +2 -0
  401. package/vue/UiTree.vue +117 -0
  402. package/vue/UiTreeItem.d.ts +56 -0
  403. package/vue/UiTreeItem.js +2 -0
  404. package/vue/UiTreeItem.vue +418 -0
  405. package/vue/chunks/UiAffordanceScope.js +112 -0
  406. package/vue/chunks/UiAvatar.js +144 -0
  407. package/vue/chunks/UiAvatarGroup.js +142 -0
  408. package/vue/chunks/UiBadge.js +33 -0
  409. package/vue/chunks/UiButton.js +47 -0
  410. package/vue/chunks/UiCallout.js +117 -0
  411. package/vue/chunks/UiCheckbox.js +167 -0
  412. package/vue/chunks/UiCluster.js +33 -0
  413. package/vue/chunks/UiCombobox.js +684 -0
  414. package/vue/chunks/UiContainer.js +33 -0
  415. package/vue/chunks/UiContextMenu.js +153 -0
  416. package/vue/chunks/UiDialog.js +162 -0
  417. package/vue/chunks/UiDisclosure.js +185 -0
  418. package/vue/chunks/UiEditable.js +223 -0
  419. package/vue/chunks/UiEditorInsertTableGrid.js +221 -0
  420. package/vue/chunks/UiEditorMentionMenu.js +245 -0
  421. package/vue/chunks/UiEditorSlashMenu.js +210 -0
  422. package/vue/chunks/UiEditorTableContextMenu.js +201 -0
  423. package/vue/chunks/UiEditorTableOverlay.js +301 -0
  424. package/vue/chunks/UiEditorTableToolbar.js +299 -0
  425. package/vue/chunks/UiEditorToolbar.js +37 -0
  426. package/vue/chunks/UiFloatingActionButton.js +56 -0
  427. package/vue/chunks/UiFormField.js +113 -0
  428. package/vue/chunks/UiGrid.js +33 -0
  429. package/vue/chunks/UiIcon.js +170 -0
  430. package/vue/chunks/UiIconButton.js +141 -0
  431. package/vue/chunks/UiInput.js +136 -0
  432. package/vue/chunks/UiMenu.js +163 -0
  433. package/vue/chunks/UiMenuItem.js +37 -0
  434. package/vue/chunks/UiPopover.js +149 -0
  435. package/vue/chunks/UiRadio.js +164 -0
  436. package/vue/chunks/UiRadioGroup.js +160 -0
  437. package/vue/chunks/UiReel.js +42 -0
  438. package/vue/chunks/UiSearchResultRow.js +63 -0
  439. package/vue/chunks/UiSearchShell.js +152 -0
  440. package/vue/chunks/UiSelect.js +134 -0
  441. package/vue/chunks/UiSeparator.js +24 -0
  442. package/vue/chunks/UiSidebar.js +180 -0
  443. package/vue/chunks/UiStack.js +38 -0
  444. package/vue/chunks/UiSwitch.js +162 -0
  445. package/vue/chunks/UiSwitcher.js +38 -0
  446. package/vue/chunks/UiTabs.js +210 -0
  447. package/vue/chunks/UiTextarea.js +139 -0
  448. package/vue/chunks/UiToastRegion.js +227 -0
  449. package/vue/chunks/UiTooltip.js +163 -0
  450. package/vue/chunks/UiTopBar.js +25 -0
  451. package/vue/chunks/UiTree.js +140 -0
  452. package/vue/chunks/UiTreeItem.js +315 -0
  453. package/vue/chunks/_plugin-vue_export-helper.js +8 -0
  454. package/vue/components.css +4405 -0
  455. package/vue/editor/LoomaEditor.d.ts +171 -0
  456. package/vue/editor/image-delivery.d.ts +61 -0
  457. package/vue/editor/index.d.ts +4 -386
  458. package/vue/editor/index.js +995 -1134
  459. package/vue/editor/primitives.d.ts +23 -0
  460. package/vue/index.d.ts +48 -604
  461. package/vue/index.js +49 -86
  462. package/dist/chunk-MLKGABMK.js +0 -9
  463. package/dist/chunk-RWLYVQY6.js +0 -5719
  464. package/dist/chunk-XDNZIKNI.js +0 -2721
  465. package/dist/declarative-generated.cjs +0 -149
  466. package/dist/declarative-generated.d.cts +0 -16
  467. package/dist/declarative-generated.d.ts +0 -16
  468. package/dist/declarative-generated.js +0 -124
  469. package/dist/declarative.cjs +0 -2750
  470. package/dist/declarative.d.cts +0 -101
  471. package/dist/declarative.d.ts +0 -101
  472. package/dist/declarative.js +0 -15
  473. package/dist/index.cjs +0 -9077
  474. package/dist/index.d.cts +0 -414
  475. package/dist/loader.cjs +0 -8442
  476. package/dist/loader.d.cts +0 -4
  477. package/dist/loader.d.ts +0 -4
  478. package/dist/loader.js +0 -16
  479. package/editor/chunk-EUIH3TBV.js +0 -6826
  480. package/editor/chunk-JK53ENSG.js +0 -29
  481. package/editor/chunk-U36XNFJN.js +0 -2592
  482. package/editor/table-overlay-DZFGHQDt.d.ts +0 -138
  483. package/editor.css +0 -1592
  484. package/layout/index.cjs +0 -356
  485. package/layout/index.d.cts +0 -18
  486. package/layout/index.d.ts +0 -18
  487. package/layout/index.js +0 -341
  488. package/layout.css +0 -191
  489. package/react/index.d.ts +0 -1276
  490. package/react/index.js +0 -1526
  491. package/styles.css +0 -940
  492. package/svelte/index.d.ts +0 -204
  493. package/svelte/index.js +0 -1892
  494. package/vue/chunk-OX3EACZ7.js +0 -4369
@@ -0,0 +1,65 @@
1
+ <template component="ui-switcher">
2
+ <defs>
3
+ <prop name="gap" type="xs | s | m | l | xl">gap token.</prop>
4
+ <prop name="threshold" type="xs | sm | md | lg">threshold token.</prop>
5
+ <prop name="align" type="start | center | end | stretch">align token.</prop>
6
+ </defs>
7
+ <div><slot></slot></div>
8
+ <style>
9
+ :host {
10
+ --_switcher-gap: var(--ui-space-4, 1rem);
11
+ display: flex;
12
+ flex-wrap: wrap;
13
+ gap: var(--ui-switcher-gap, var(--_switcher-gap));
14
+ min-inline-size: 0;
15
+ max-inline-size: 100%;
16
+ margin: 0;
17
+ }
18
+
19
+ :host > :slotted(*) {
20
+ min-inline-size: 0;
21
+ flex-grow: 1;
22
+ /* The large multiplier makes the basis flip as a group at the intrinsic threshold. */
23
+ flex-basis: calc((var(--ui-switcher-threshold, 30rem) - 100%) * 999);
24
+ }
25
+
26
+ :host-state([gap="xs"]) {
27
+ --_switcher-gap: var(--ui-space-2, 0.5rem);
28
+ }
29
+ :host-state([gap="s"]) {
30
+ --_switcher-gap: var(--ui-space-3, 0.75rem);
31
+ }
32
+ :host-state([gap="m"]) {
33
+ --_switcher-gap: var(--ui-space-4, 1rem);
34
+ }
35
+ :host-state([gap="l"]) {
36
+ --_switcher-gap: var(--ui-space-5, 1.5rem);
37
+ }
38
+ :host-state([gap="xl"]) {
39
+ --_switcher-gap: var(--ui-space-6, 2rem);
40
+ }
41
+ :host-state([threshold="xs"]) > :slotted(*) {
42
+ flex-basis: calc((var(--ui-switcher-threshold, 20rem) - 100%) * 999);
43
+ }
44
+ :host-state([threshold="md"]) > :slotted(*) {
45
+ flex-basis: calc((var(--ui-switcher-threshold, 45rem) - 100%) * 999);
46
+ }
47
+ :host-state([threshold="lg"]) > :slotted(*) {
48
+ flex-basis: calc((var(--ui-switcher-threshold, 60rem) - 100%) * 999);
49
+ }
50
+ :host-state([align="start"]) {
51
+ align-items: flex-start;
52
+ }
53
+ :host-state([align="center"]) {
54
+ align-items: center;
55
+ }
56
+ :host-state([align="end"]) {
57
+ align-items: flex-end;
58
+ }
59
+
60
+ /* A component that sets its display still honours the hidden attribute on its root. */
61
+ :host[hidden] {
62
+ display: none;
63
+ }
64
+ </style>
65
+ </template>
@@ -0,0 +1,134 @@
1
+ <template component="ui-tabs" controller="./ui-tabs.js">
2
+ <defs>
3
+ <prop name="label" type="string" default="Tabs">label token.</prop>
4
+ <prop name="value" type="string" default="">value token.</prop>
5
+ <prop name="orientation" type="horizontal | vertical" default="horizontal">orientation token.</prop>
6
+ <prop name="stretch" type="boolean" default="false">Share the full width of the tab list equally between tabs instead of sizing each to its label.</prop>
7
+ <state name="internalValue" :value="''"></state>
8
+ <state name="tabs" :value="[]"></state>
9
+ <event name="select" type="object({ value: string, previousValue: string, trigger: keyboard | pointer | programmatic })"></event>
10
+ </defs>
11
+ <div>
12
+ <div class="list" $ref="list" role="tablist" :aria-label="label" :aria-orientation="orientation">
13
+ <button
14
+ $each="tab of tabs"
15
+ $key="tab.id"
16
+ type="button"
17
+ role="tab"
18
+ :id="format('%s-tab', tab.id)"
19
+ :value="tab.id"
20
+ :aria-controls="tab.id"
21
+ :aria-selected="tab.id = internalValue"
22
+ $value="tab.label"
23
+ >
24
+ </button>
25
+ </div>
26
+ <div class="panels" $ref="panels"><slot></slot></div>
27
+ </div>
28
+ <style>
29
+ :host {
30
+ display: grid;
31
+ inline-size: 100%;
32
+ min-inline-size: 0;
33
+ }
34
+
35
+ .list {
36
+ display: grid;
37
+ grid-auto-flow: column;
38
+ grid-auto-columns: max-content;
39
+ justify-content: start;
40
+ inline-size: 100%;
41
+ max-inline-size: 100%;
42
+ /* Tabs that do not fit scroll sideways rather than wrapping or squeezing. */
43
+ overflow-x: auto;
44
+ /* overflow-x: auto would make the block axis scrollable too; a sideways swipe must not scroll the
45
+ strip or the page vertically. */
46
+ overflow-y: hidden;
47
+ overscroll-behavior: contain;
48
+ scrollbar-width: thin;
49
+ border-block-end: 1px solid var(--ui-border-default);
50
+ }
51
+
52
+ .list button {
53
+ min-block-size: 2.5rem;
54
+ margin: 0 0 -1px;
55
+ padding: var(--ui-space-2) var(--ui-space-3);
56
+ border: 0;
57
+ border-block-end: 2px solid transparent;
58
+ background: transparent;
59
+ color: var(--ui-text-secondary);
60
+ font: inherit;
61
+ font-size: var(--ui-font-size-sm);
62
+ font-weight: var(--ui-font-medium, 500);
63
+ cursor: pointer;
64
+ transition:
65
+ color var(--ui-motion-fast) var(--ui-motion-ease),
66
+ background-color var(--ui-motion-fast) var(--ui-motion-ease),
67
+ border-color var(--ui-motion-fast) var(--ui-motion-ease);
68
+ }
69
+
70
+ :host-state([stretch]) .list {
71
+ grid-auto-columns: minmax(max-content, 1fr);
72
+ }
73
+
74
+ .list button {
75
+ white-space: nowrap;
76
+ }
77
+
78
+ .list button:hover {
79
+ color: var(--ui-text-primary);
80
+ background: var(--ui-surface-muted);
81
+ }
82
+ .list button[aria-selected="true"] {
83
+ color: var(--ui-accent-solid);
84
+ border-block-end-color: var(--ui-accent-solid);
85
+ }
86
+ .list button:focus-visible {
87
+ position: relative;
88
+ outline: none;
89
+ box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--ui-focus-ring) 45%, transparent);
90
+ border-radius: var(--ui-radius-1);
91
+ }
92
+
93
+ .panels {
94
+ min-inline-size: 0;
95
+ }
96
+ :slotted(*) {
97
+ padding: var(--ui-space-4);
98
+ }
99
+
100
+ :host-state([orientation="vertical"]) {
101
+ grid-template-columns: max-content minmax(0, 1fr);
102
+ align-items: start;
103
+ }
104
+
105
+ :host-state([orientation="vertical"]) .list {
106
+ grid-auto-flow: row;
107
+ grid-auto-columns: auto;
108
+ border-block-end: 0;
109
+ border-inline-end: 1px solid var(--ui-border-default);
110
+ }
111
+
112
+ :host-state([orientation="vertical"]) .list button {
113
+ margin: 0 -1px 0 0;
114
+ border-block-end: 0;
115
+ border-inline-end: 2px solid transparent;
116
+ text-align: start;
117
+ }
118
+
119
+ :host-state([orientation="vertical"]) .list button[aria-selected="true"] {
120
+ border-inline-end-color: var(--ui-accent-solid);
121
+ }
122
+
123
+ @media (prefers-reduced-motion: reduce) {
124
+ .list button {
125
+ transition: none;
126
+ }
127
+ }
128
+
129
+ /* A component that sets its display still honours the hidden attribute on its root. */
130
+ :host[hidden] {
131
+ display: none;
132
+ }
133
+ </style>
134
+ </template>
@@ -0,0 +1,81 @@
1
+ import { trackTrigger } from "../shared/trigger.js";
2
+
3
+ let panelIds = 0;
4
+
5
+ /** Lists the authored panels (each labelled by its aria-label) as tabs and shows the selected one. */
6
+ export default function controller(host) {
7
+ const { list, panels: container } = host.refs;
8
+ const [trigger, stopTracking] = trackTrigger(host);
9
+ const panels = () => Array.from(container.children).filter((child) => child instanceof HTMLElement);
10
+ let external = String(host.state.value || "");
11
+ host.state.internalValue = external;
12
+
13
+ const readPanels = () => {
14
+ const items = panels();
15
+ host.state.tabs = items.map((panel, index) => {
16
+ if (!panel.id) panel.id = `ui-tab-panel-${++panelIds}`;
17
+ panel.setAttribute("role", "tabpanel");
18
+ panel.setAttribute("aria-labelledby", `${panel.id}-tab`);
19
+ return { id: panel.id, label: panel.getAttribute("aria-label") || `Tab ${index + 1}` };
20
+ });
21
+ if (!items.some((panel) => panel.id === host.state.internalValue)) {
22
+ host.state.internalValue = external || items[0]?.id || "";
23
+ }
24
+ };
25
+ const stop = host.effect(() => {
26
+ const value = String(host.state.value || "");
27
+ if (value !== external) {
28
+ external = value;
29
+ host.state.internalValue = value;
30
+ }
31
+ const selected = host.state.internalValue;
32
+ for (const panel of panels()) panel.hidden = panel.id !== selected;
33
+ // Roving focus: only the selected tab is in the tab order.
34
+ for (const button of list.querySelectorAll('[role="tab"]')) button.tabIndex = button.value === selected ? 0 : -1;
35
+ });
36
+
37
+ const select = (button, how) => {
38
+ const previousValue = host.state.internalValue || undefined;
39
+ host.state.internalValue = button.value;
40
+ host.dispatch("select", { value: button.value, previousValue, trigger: how });
41
+ };
42
+ const onClick = (event) => {
43
+ const button = event.target.closest?.('[role="tab"]');
44
+ if (button && list.contains(button)) select(button, trigger());
45
+ };
46
+ const onKeydown = (event) => {
47
+ const button = event.target.closest?.('[role="tab"]');
48
+ if (!button || !list.contains(button)) return;
49
+ const buttons = Array.from(list.querySelectorAll('[role="tab"]'));
50
+ const vertical = host.state.orientation === "vertical";
51
+ const previousKey = vertical ? "ArrowUp" : "ArrowLeft";
52
+ const nextKey = vertical ? "ArrowDown" : "ArrowRight";
53
+ if (event.key !== previousKey && event.key !== nextKey) return;
54
+ event.preventDefault();
55
+ const index = buttons.indexOf(button);
56
+ const next = buttons[(index + (event.key === nextKey ? 1 : buttons.length - 1)) % buttons.length];
57
+ select(next, "keyboard");
58
+ next.focus();
59
+ };
60
+ // A vertical mouse wheel over an overflowing strip scrolls it sideways instead of the page.
61
+ // Trackpad gestures already carry a horizontal delta and are left to the browser.
62
+ const onWheel = (event) => {
63
+ if (list.scrollWidth <= list.clientWidth || event.deltaX !== 0 || event.ctrlKey) return;
64
+ event.preventDefault();
65
+ list.scrollLeft += event.deltaY;
66
+ };
67
+ list.addEventListener("click", onClick);
68
+ list.addEventListener("keydown", onKeydown);
69
+ list.addEventListener("wheel", onWheel, { passive: false });
70
+ const observer = new MutationObserver(readPanels);
71
+ observer.observe(container, { childList: true });
72
+ readPanels();
73
+ return () => {
74
+ stop();
75
+ stopTracking();
76
+ observer.disconnect();
77
+ list.removeEventListener("click", onClick);
78
+ list.removeEventListener("keydown", onKeydown);
79
+ list.removeEventListener("wheel", onWheel);
80
+ };
81
+ }
@@ -0,0 +1,80 @@
1
+ <template component="ui-textarea" controller="./ui-textarea.js">
2
+ <defs>
3
+ <prop name="value" type="string">Current text value.</prop>
4
+ <prop name="disabled" type="boolean" default="false">Prevents editing and form submission.</prop>
5
+ <prop name="invalid" type="boolean" default="false">Exposes invalid state to assistive technology and styling.</prop>
6
+ <prop name="readonly" type="boolean" default="false">Allows selection without allowing edits.</prop>
7
+ <prop name="required" type="boolean" default="false">Marks the control as required for form validation.</prop>
8
+ <prop name="rows" type="integer" default="4">Initial number of visible text rows.</prop>
9
+ </defs>
10
+ <textarea :value="value" :disabled="disabled" :readonly="readonly" :required="required" :aria-invalid="invalid" :rows="rows"></textarea>
11
+ <style>
12
+ :host {
13
+ box-sizing: border-box;
14
+ display: inline-block;
15
+ inline-size: 100%;
16
+ min-inline-size: 0;
17
+ min-block-size: calc(var(--ui-space-12, 3rem) * 2);
18
+ margin: 0;
19
+ padding: var(--ui-space-2) var(--ui-space-3);
20
+ appearance: none;
21
+ resize: vertical;
22
+ border: 1px solid var(--ui-control-border, var(--ui-border-strong));
23
+ border-radius: var(--ui-textarea-radius, var(--ui-radius-2));
24
+ background: var(--ui-control-surface, var(--ui-surface-elevated));
25
+ color: var(--ui-text-primary);
26
+ font: inherit;
27
+ line-height: var(--ui-line-height-md);
28
+ box-shadow: var(--ui-textarea-shadow, var(--ui-control-inset));
29
+ transition:
30
+ border-color var(--ui-motion-fast) var(--ui-motion-ease),
31
+ box-shadow var(--ui-motion-fast) var(--ui-motion-ease),
32
+ background-color var(--ui-motion-fast) var(--ui-motion-ease);
33
+ }
34
+
35
+ /* Tabbing into a field selects its text; tint that selection softly instead of the page highlight. */
36
+ :host::selection {
37
+ background: color-mix(in srgb, var(--ui-accent-solid) 20%, transparent);
38
+ color: inherit;
39
+ }
40
+
41
+ :host::placeholder {
42
+ color: var(--ui-control-placeholder, var(--ui-text-secondary));
43
+ opacity: 1;
44
+ }
45
+
46
+ :host:hover:not(:focus):not(:disabled) {
47
+ border-color: var(--ui-control-border-hover, var(--ui-text-secondary));
48
+ }
49
+
50
+ :host:focus-visible {
51
+ border-color: var(--ui-control-focus, var(--ui-accent-solid));
52
+ outline: none;
53
+ box-shadow: var(--ui-textarea-focus-shadow, var(--ui-control-inset), var(--ui-control-focus-halo-shadow));
54
+ }
55
+
56
+ /* The app's invalid flag, or the browser's own verdict once the user has left an invalid field. */
57
+ :host[aria-invalid="true"],
58
+ :host:user-invalid {
59
+ border-color: var(--ui-danger-solid);
60
+ }
61
+
62
+ :host:is([aria-invalid="true"], :user-invalid):focus-visible {
63
+ box-shadow:
64
+ var(--ui-control-inset),
65
+ 0 0 0 3px color-mix(in srgb, var(--ui-danger-solid) 22%, transparent);
66
+ }
67
+
68
+ :host:disabled {
69
+ background: var(--ui-control-surface-disabled, var(--ui-surface-muted));
70
+ color: var(--ui-text-muted);
71
+ box-shadow: none;
72
+ cursor: not-allowed;
73
+ }
74
+
75
+ /* A component that sets its display still honours the hidden attribute on its root. */
76
+ :host[hidden] {
77
+ display: none;
78
+ }
79
+ </style>
80
+ </template>
@@ -0,0 +1,7 @@
1
+ // The value attribute only sets the default; a controlled value is applied to the live textarea.
2
+ export default function controller(host) {
3
+ return host.effect(() => {
4
+ const value = host.state.value;
5
+ if (value !== undefined && value !== null && host.element.value !== String(value)) host.element.value = String(value);
6
+ });
7
+ }
@@ -0,0 +1,127 @@
1
+ <link rel="component" href="../ui-icon-button/ui-icon-button.html">
2
+ <template component="ui-toast-region" controller="./ui-toast-region.js">
3
+ <defs>
4
+ <prop name="open" type="boolean" default="false">Whether the messages authored inside the region are visible.</prop>
5
+ <prop name="message" type="string" default="Notification">Fallback message used by the declarative show command.</prop>
6
+ <prop name="auto" type="boolean" default="false"
7
+ >Dismiss each message automatically after its duration. Timers pause while the pointer or focus is on a message.</prop>
8
+ <prop name="duration" type="number" default="5000">Milliseconds an automatically dismissed message stays visible.</prop>
9
+ <state name="internalOpen" :value="false"></state>
10
+ <state name="toasts" :value="[]"></state>
11
+ <event
12
+ name="close"
13
+ type="object({ open: boolean, reason: action | timeout | programmatic | light-dismiss | escape, trigger: keyboard | pointer | programmatic })"
14
+ ></event>
15
+ <event name="dismiss" type="object({ id: string, reason: action | timeout, trigger: keyboard | pointer | programmatic })"></event>
16
+ <method name="show" export="show" returns="promise(string)"></method>
17
+ </defs>
18
+ <div role="region" aria-label="Notifications" aria-live="polite" popover="manual">
19
+ <slot></slot>
20
+ <div $each="toast of toasts" $key="toast.id" class="toast" class:closing="toast.closing" :id="toast.id" :role="toast.role">
21
+ <span class="message" $value="toast.message"></span>
22
+ <span class="dismiss" :data-toast="toast.id">
23
+ <ui-icon-button size="sm" variant="ghost" :round="true" :label="format('Dismiss %s', toast.message)">
24
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true">
25
+ <path d="M18 6 6 18M6 6l12 12"></path>
26
+ </svg>
27
+ </ui-icon-button>
28
+ </span>
29
+ </div>
30
+ </div>
31
+ <style>
32
+ :host {
33
+ position: fixed;
34
+ top: calc(var(--ui-space-4) + env(safe-area-inset-top));
35
+ right: auto;
36
+ bottom: auto;
37
+ left: 50%;
38
+ transform: translateX(-50%);
39
+ z-index: 9999;
40
+ display: grid;
41
+ gap: var(--ui-space-2);
42
+ inline-size: min(24rem, calc(100vw - var(--ui-space-4) * 2));
43
+ max-inline-size: 100%;
44
+ box-sizing: border-box;
45
+ margin: 0;
46
+ padding: 0;
47
+ overflow: visible;
48
+ border: 0;
49
+ outline: 0;
50
+ background: transparent;
51
+ box-shadow: none;
52
+ pointer-events: none;
53
+ }
54
+
55
+ :host:not(:popover-open) {
56
+ display: none;
57
+ }
58
+
59
+ :host > .toast,
60
+ :host > :slotted(*) {
61
+ pointer-events: auto;
62
+ }
63
+
64
+ .toast {
65
+ display: grid;
66
+ grid-template-columns: 1fr auto;
67
+ gap: var(--ui-space-2);
68
+ align-items: start;
69
+ border: 1px solid var(--ui-border-default);
70
+ border-radius: var(--ui-radius-3);
71
+ padding: var(--ui-space-3) var(--ui-space-4);
72
+ background: var(--ui-surface-elevated);
73
+ color: var(--ui-text-primary);
74
+ box-shadow: var(--ui-elevation-overlay, var(--ui-shadow-lg));
75
+ animation: ui-toast-enter var(--ui-toast-enter-duration, 0.32s) var(--ui-motion-ease-out, cubic-bezier(0.16, 1, 0.3, 1)) both;
76
+ }
77
+
78
+ /* Leaving slides on down and fades; the controller removes the toast when this ends. */
79
+ .toast.closing {
80
+ animation: ui-toast-exit var(--ui-toast-exit-duration, 0.22s) var(--ui-motion-ease, ease) both;
81
+ pointer-events: none;
82
+ }
83
+
84
+ @keyframes ui-toast-enter {
85
+ from {
86
+ opacity: 0;
87
+ transform: translateY(-1rem);
88
+ }
89
+ to {
90
+ opacity: 1;
91
+ transform: translateY(0);
92
+ }
93
+ }
94
+
95
+ @keyframes ui-toast-exit {
96
+ from {
97
+ opacity: 1;
98
+ transform: translateY(0);
99
+ }
100
+ to {
101
+ opacity: 0;
102
+ transform: translateY(0.75rem);
103
+ }
104
+ }
105
+
106
+ @media (prefers-reduced-motion: reduce) {
107
+ .toast, .toast.closing {
108
+ animation: none;
109
+ }
110
+ }
111
+
112
+ .message {
113
+ min-inline-size: 0;
114
+ align-self: center;
115
+ }
116
+
117
+ .dismiss {
118
+ align-self: center;
119
+ margin-inline-end: calc(var(--ui-space-2) * -1);
120
+ }
121
+
122
+ /* A component that sets its display still honours the hidden attribute on its root. */
123
+ :host[hidden] {
124
+ display: none;
125
+ }
126
+ </style>
127
+ </template>
@@ -0,0 +1,119 @@
1
+ import { trackTrigger } from "../shared/trigger.js";
2
+
3
+ const instances = new WeakMap();
4
+ let toastIds = 0;
5
+
6
+ export async function show(host, message, options = {}) {
7
+ return instances.get(host.element)?.show(message, options);
8
+ }
9
+
10
+ /**
11
+ * Shows the region while `open` is set and it has authored messages, or while any message added
12
+ * with show() or the --show-toast command remains. Added messages dismiss by action or timeout.
13
+ */
14
+ export default function controller(host) {
15
+ const element = host.element;
16
+ const [trigger, stopTracking] = trackTrigger(host);
17
+ let external = host.state.open;
18
+ host.state.internalOpen = Boolean(external);
19
+
20
+ const toasts = () => host.state.toasts ?? [];
21
+ const authored = () => Array.from(element.children).some((child) => !child.classList.contains("toast"));
22
+ const sync = () => {
23
+ const visible = (host.state.internalOpen && authored()) || toasts().length > 0;
24
+ if (visible && !element.matches(":popover-open")) element.showPopover();
25
+ else if (!visible && element.matches(":popover-open")) element.hidePopover();
26
+ };
27
+
28
+ // Auto-dismiss timers: each message keeps its remaining time so hover and focus pause and resume it.
29
+ const timers = new Map();
30
+ let paused = false;
31
+ const startTimer = (id) => {
32
+ const timer = timers.get(id);
33
+ if (!timer || paused) return;
34
+ timer.started = Date.now();
35
+ timer.handle = setTimeout(() => dismiss(id, "timeout", "programmatic"), timer.remaining);
36
+ };
37
+ const pauseTimers = () => {
38
+ if (paused) return;
39
+ paused = true;
40
+ for (const timer of timers.values()) {
41
+ clearTimeout(timer.handle);
42
+ timer.remaining = Math.max(0, timer.remaining - (Date.now() - timer.started));
43
+ }
44
+ };
45
+ // Deferred: during focusout the region still matches :focus-within.
46
+ const resumeTimers = () => setTimeout(() => {
47
+ if (!paused || element.matches(":hover, :focus-within")) return;
48
+ paused = false;
49
+ for (const id of timers.keys()) startTimer(id);
50
+ }, 0);
51
+
52
+ const remove = (id) => {
53
+ host.state.toasts = toasts().filter((toast) => toast.id !== id);
54
+ };
55
+ const dismiss = (id, reason, how) => {
56
+ clearTimeout(timers.get(id)?.handle);
57
+ timers.delete(id);
58
+ const toast = toasts().find((candidate) => candidate.id === id);
59
+ if (!toast || toast.closing) return;
60
+ host.state.toasts = toasts().map((candidate) => candidate.id === id ? { ...candidate, closing: true } : candidate);
61
+ host.dispatch("dismiss", { id, reason, trigger: how });
62
+ if (toasts().every((candidate) => candidate.closing)) host.dispatch("close", { open: false, reason, trigger: how });
63
+ // Removed once the exit animation ends; reduced motion has none, and the timeout guards a missed end.
64
+ const node = element.ownerDocument.getElementById(id);
65
+ if (!node || getComputedStyle(node).animationName === "none") remove(id);
66
+ else {
67
+ node.addEventListener("animationend", () => remove(id), { once: true });
68
+ setTimeout(() => remove(id), 500);
69
+ }
70
+ };
71
+ const add = (message, options = {}) => {
72
+ const id = String(options.id || `ui-toast-${++toastIds}`);
73
+ host.state.toasts = [...toasts(), { id, message: String(message), role: options.tone === "danger" ? "alert" : "status", closing: false }];
74
+ if (options.auto ?? host.state.auto) {
75
+ timers.set(id, { remaining: Math.max(0, Number(options.duration ?? host.state.duration ?? 5000)), started: 0, handle: 0 });
76
+ startTimer(id);
77
+ }
78
+ return id;
79
+ };
80
+
81
+ const onClick = (event) => {
82
+ const id = event.target.closest?.("[data-toast]")?.dataset.toast;
83
+ if (id) dismiss(id, "action", trigger());
84
+ };
85
+ const onCommand = (event) => {
86
+ if (event.command === "--show-toast") add(event.source?.value || host.state.message || "Notification");
87
+ };
88
+ const stop = host.effect(() => {
89
+ if (host.state.open !== external) {
90
+ external = host.state.open;
91
+ host.state.internalOpen = Boolean(external);
92
+ }
93
+ sync();
94
+ });
95
+ const observer = new MutationObserver(sync);
96
+ observer.observe(element, { childList: true });
97
+ element.addEventListener("click", onClick);
98
+ element.addEventListener("command", onCommand);
99
+ element.addEventListener("pointerenter", pauseTimers);
100
+ element.addEventListener("pointerleave", resumeTimers);
101
+ element.addEventListener("focusin", pauseTimers);
102
+ element.addEventListener("focusout", resumeTimers);
103
+ instances.set(element, { show: add });
104
+ return () => {
105
+ stop();
106
+ stopTracking();
107
+ observer.disconnect();
108
+ element.removeEventListener("click", onClick);
109
+ element.removeEventListener("command", onCommand);
110
+ element.removeEventListener("pointerenter", pauseTimers);
111
+ element.removeEventListener("pointerleave", resumeTimers);
112
+ element.removeEventListener("focusin", pauseTimers);
113
+ element.removeEventListener("focusout", resumeTimers);
114
+ for (const timer of timers.values()) clearTimeout(timer.handle);
115
+ timers.clear();
116
+ if (element.matches(":popover-open")) element.hidePopover();
117
+ instances.delete(element);
118
+ };
119
+ }