@threadlabs/looma 0.14.8 → 0.15.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 (336) hide show
  1. package/components/shared/icons.js +5 -0
  2. package/components/shared/menu-navigation.js +49 -0
  3. package/components/shared/overlay.js +33 -60
  4. package/components/ui-avatar/ui-avatar.html +19 -2
  5. package/components/ui-avatar/ui-avatar.js +7 -1
  6. package/components/ui-avatar-group/ui-avatar-group.html +8 -3
  7. package/components/ui-avatar-group/ui-avatar-group.js +6 -2
  8. package/components/ui-badge/ui-badge.html +70 -4
  9. package/components/ui-button/ui-button.html +21 -5
  10. package/components/ui-button/ui-button.js +10 -0
  11. package/components/ui-callout/ui-callout.html +13 -5
  12. package/components/ui-checkbox/ui-checkbox.html +11 -0
  13. package/components/ui-combobox/ui-combobox.html +46 -10
  14. package/components/ui-combobox/ui-combobox.js +5 -5
  15. package/components/ui-context-menu/ui-context-menu.html +33 -5
  16. package/components/ui-context-menu/ui-context-menu.js +26 -17
  17. package/components/ui-dialog/ui-dialog.html +51 -8
  18. package/components/ui-dialog/ui-dialog.js +28 -7
  19. package/components/ui-disclosure/ui-disclosure.html +14 -5
  20. package/components/ui-disclosure/ui-disclosure.js +51 -4
  21. package/components/ui-editable/ui-editable.html +17 -3
  22. package/components/ui-editable/ui-editable.js +7 -0
  23. package/components/ui-editor-insert-table-grid/ui-editor-insert-table-grid.html +48 -14
  24. package/components/ui-editor-insert-table-grid/ui-editor-insert-table-grid.js +40 -6
  25. package/components/ui-editor-mention-menu/ui-editor-mention-menu.html +22 -9
  26. package/components/ui-editor-mention-menu/ui-editor-mention-menu.js +33 -11
  27. package/components/ui-editor-mention-menu-item/ui-editor-mention-menu-item.html +67 -0
  28. package/components/ui-editor-slash-menu/ui-editor-slash-menu.html +33 -30
  29. package/components/ui-editor-slash-menu/ui-editor-slash-menu.js +42 -8
  30. package/components/ui-editor-slash-menu-group/ui-editor-slash-menu-group.html +31 -0
  31. package/components/ui-editor-slash-menu-item/ui-editor-slash-menu-item.html +75 -0
  32. package/components/ui-editor-table-context-menu/ui-editor-table-context-menu.html +16 -5
  33. package/components/ui-editor-table-context-menu/ui-editor-table-context-menu.js +10 -2
  34. package/components/ui-editor-table-overlay/ui-editor-table-overlay.html +5 -5
  35. package/components/ui-editor-table-overlay/ui-editor-table-overlay.js +5 -2
  36. package/components/ui-editor-table-toolbar/ui-editor-table-toolbar.html +14 -4
  37. package/components/ui-editor-table-toolbar/ui-editor-table-toolbar.js +2 -2
  38. package/components/ui-editor-toolbar/ui-editor-toolbar.html +1 -1
  39. package/components/ui-editor-toolbar/ui-editor-toolbar.js +46 -0
  40. package/components/ui-floating-action-button/ui-floating-action-button.html +1 -1
  41. package/components/ui-form-field/ui-form-field.html +16 -3
  42. package/components/ui-form-field/ui-form-field.js +1 -1
  43. package/components/ui-grid/ui-grid.html +17 -2
  44. package/components/ui-icon/ui-icon.html +5 -0
  45. package/components/ui-icon-button/ui-icon-button.html +25 -6
  46. package/components/ui-icon-button/ui-icon-button.js +11 -1
  47. package/components/ui-input/ui-input.html +3 -3
  48. package/components/ui-input-group/ui-input-group.html +18 -4
  49. package/components/ui-listbox/ui-listbox.html +81 -0
  50. package/components/ui-listbox/ui-listbox.js +27 -0
  51. package/components/ui-menu/ui-menu.html +33 -5
  52. package/components/ui-menu/ui-menu.js +18 -12
  53. package/components/ui-menu-group/ui-menu-group.html +27 -0
  54. package/components/ui-menu-item/ui-menu-item.html +80 -8
  55. package/components/ui-menu-item/ui-menu-item.js +47 -0
  56. package/components/ui-popover/ui-popover.html +33 -5
  57. package/components/ui-popover/ui-popover.js +9 -1
  58. package/components/ui-radio-group/ui-radio-group.html +13 -1
  59. package/components/ui-search-shell/ui-search-shell.html +6 -6
  60. package/components/ui-search-shell/ui-search-shell.js +21 -5
  61. package/components/ui-select/ui-select.html +14 -4
  62. package/components/ui-switch/ui-switch.html +2 -2
  63. package/components/ui-switcher/ui-switcher.html +8 -1
  64. package/components/ui-switcher/ui-switcher.js +15 -0
  65. package/components/ui-tabs/ui-tabs.html +17 -12
  66. package/components/ui-tabs/ui-tabs.js +43 -7
  67. package/components/ui-textarea/ui-textarea.html +28 -5
  68. package/components/ui-toast/ui-toast.html +88 -0
  69. package/components/ui-toast/ui-toast.js +68 -0
  70. package/components/ui-toast-region/ui-toast-region.html +102 -19
  71. package/components/ui-toast-region/ui-toast-region.js +10 -18
  72. package/components/ui-tooltip/ui-tooltip.html +51 -7
  73. package/components/ui-tooltip/ui-tooltip.js +29 -3
  74. package/components/ui-tree/ui-tree.html +12 -0
  75. package/components/ui-tree/ui-tree.js +191 -12
  76. package/components/ui-tree-item/ui-tree-item.html +87 -8
  77. package/components/ui-tree-item/ui-tree-item.js +3 -1
  78. package/dist/index.js +38 -32
  79. package/editor/chunks/extensions.js +82 -2
  80. package/editor/extensions/table-commands.d.ts +8 -0
  81. package/editor/icons.d.ts +5 -0
  82. package/editor/index.js +7 -2
  83. package/editor/insert-table-grid.d.ts +1 -1
  84. package/editor/mention-menu.d.ts +2 -0
  85. package/editor/slash-menu.d.ts +3 -0
  86. package/editor/table-context-menu.d.ts +1 -1
  87. package/editor/table-overlay.d.ts +2 -2
  88. package/package.json +1 -1
  89. package/styles/ui-avatar-group.css +1 -2
  90. package/styles/ui-avatar.css +11 -1
  91. package/styles/ui-badge.css +73 -1
  92. package/styles/ui-button.css +9 -1
  93. package/styles/ui-callout.css +1 -1
  94. package/styles/ui-checkbox.css +9 -0
  95. package/styles/ui-combobox.css +38 -7
  96. package/styles/ui-context-menu.css +32 -4
  97. package/styles/ui-dialog.css +42 -5
  98. package/styles/ui-editor-insert-table-grid.css +48 -11
  99. package/styles/ui-editor-mention-menu-item.css +57 -0
  100. package/styles/ui-editor-mention-menu.css +11 -1
  101. package/styles/ui-editor-slash-menu-group.css +21 -0
  102. package/styles/ui-editor-slash-menu-item.css +62 -0
  103. package/styles/ui-editor-slash-menu.css +10 -21
  104. package/styles/ui-editor-table-context-menu.css +1 -1
  105. package/styles/ui-floating-action-button.css +1 -1
  106. package/styles/ui-form-field.css +14 -1
  107. package/styles/ui-grid.css +14 -1
  108. package/styles/ui-icon-button.css +17 -5
  109. package/styles/ui-input-group.css +18 -4
  110. package/styles/ui-input.css +3 -3
  111. package/styles/ui-listbox.css +69 -0
  112. package/styles/ui-menu-group.css +19 -0
  113. package/styles/ui-menu-item.css +48 -9
  114. package/styles/ui-menu.css +32 -4
  115. package/styles/ui-popover.css +28 -4
  116. package/styles/ui-radio-group.css +9 -0
  117. package/styles/ui-search-shell.css +5 -5
  118. package/styles/ui-select.css +14 -4
  119. package/styles/ui-switch.css +2 -2
  120. package/styles/ui-switcher.css +4 -0
  121. package/styles/ui-textarea.css +27 -4
  122. package/styles/ui-toast-region.css +88 -4
  123. package/styles/ui-toast.css +74 -0
  124. package/styles/ui-tooltip.css +46 -6
  125. package/styles/ui-tree-item.css +72 -4
  126. package/styles/ui-tree.css +8 -0
  127. package/tokens.css +3 -0
  128. package/vanilla/UiAvatar.d.ts +2 -0
  129. package/vanilla/UiAvatar.js +8 -1
  130. package/vanilla/UiAvatarGroup.d.ts +2 -0
  131. package/vanilla/UiAvatarGroup.js +1 -1
  132. package/vanilla/UiBadge.d.ts +1 -1
  133. package/vanilla/UiBadge.js +1 -1
  134. package/vanilla/UiButton.d.ts +1 -0
  135. package/vanilla/UiButton.js +22 -6
  136. package/vanilla/UiCallout.d.ts +1 -1
  137. package/vanilla/UiCallout.js +1 -1
  138. package/vanilla/UiCheckbox.d.ts +1 -0
  139. package/vanilla/UiCheckbox.js +12 -9
  140. package/vanilla/UiCombobox.d.ts +3 -0
  141. package/vanilla/UiCombobox.js +30 -15
  142. package/vanilla/UiContextMenu.d.ts +1 -1
  143. package/vanilla/UiContextMenu.js +1 -1
  144. package/vanilla/UiDialog.d.ts +5 -2
  145. package/vanilla/UiDialog.js +1 -1
  146. package/vanilla/UiDisclosure.d.ts +2 -0
  147. package/vanilla/UiDisclosure.js +32 -18
  148. package/vanilla/UiEditable.d.ts +5 -0
  149. package/vanilla/UiEditable.js +7 -3
  150. package/vanilla/UiEditorInsertTableGrid.js +1 -6
  151. package/vanilla/UiEditorMentionMenu.d.ts +4 -2
  152. package/vanilla/UiEditorMentionMenu.js +49 -31
  153. package/vanilla/UiEditorMentionMenuItem.d.ts +16 -0
  154. package/vanilla/UiEditorMentionMenuItem.js +56 -0
  155. package/vanilla/UiEditorSlashMenu.d.ts +4 -3
  156. package/vanilla/UiEditorSlashMenu.js +59 -46
  157. package/vanilla/UiEditorSlashMenuGroup.d.ts +14 -0
  158. package/vanilla/UiEditorSlashMenuGroup.js +48 -0
  159. package/vanilla/UiEditorSlashMenuItem.d.ts +18 -0
  160. package/vanilla/UiEditorSlashMenuItem.js +57 -0
  161. package/vanilla/UiEditorTableContextMenu.d.ts +5 -2
  162. package/vanilla/UiEditorTableContextMenu.js +1 -2
  163. package/vanilla/UiEditorTableOverlay.d.ts +1 -1
  164. package/vanilla/UiEditorTableOverlay.js +5 -5
  165. package/vanilla/UiEditorTableToolbar.d.ts +4 -2
  166. package/vanilla/UiEditorTableToolbar.js +1 -2
  167. package/vanilla/UiEditorToolbar.js +2 -0
  168. package/vanilla/UiGrid.d.ts +1 -0
  169. package/vanilla/UiGrid.js +8 -7
  170. package/vanilla/UiIcon.js +1 -1
  171. package/vanilla/UiIconButton.d.ts +1 -0
  172. package/vanilla/UiIconButton.js +11 -2
  173. package/vanilla/UiListbox.d.ts +20 -0
  174. package/vanilla/UiListbox.js +45 -0
  175. package/vanilla/UiMenu.d.ts +1 -1
  176. package/vanilla/UiMenu.js +1 -1
  177. package/vanilla/UiMenuGroup.d.ts +14 -0
  178. package/vanilla/UiMenuGroup.js +35 -0
  179. package/vanilla/UiMenuItem.d.ts +5 -1
  180. package/vanilla/UiMenuItem.js +91 -30
  181. package/vanilla/UiPopover.d.ts +1 -1
  182. package/vanilla/UiPopover.js +1 -1
  183. package/vanilla/UiRadioGroup.d.ts +1 -0
  184. package/vanilla/UiRadioGroup.js +6 -3
  185. package/vanilla/UiSwitcher.d.ts +1 -0
  186. package/vanilla/UiSwitcher.js +7 -9
  187. package/vanilla/UiTabs.d.ts +1 -0
  188. package/vanilla/UiTabs.js +9 -1
  189. package/vanilla/UiTextarea.d.ts +1 -0
  190. package/vanilla/UiTextarea.js +4 -1
  191. package/vanilla/UiToast.d.ts +16 -0
  192. package/vanilla/UiToast.js +53 -0
  193. package/vanilla/UiToastRegion.d.ts +1 -4
  194. package/vanilla/UiToastRegion.js +3 -11
  195. package/vanilla/UiTooltip.d.ts +1 -1
  196. package/vanilla/UiTooltip.js +1 -1
  197. package/vanilla/UiTree.d.ts +2 -0
  198. package/vanilla/UiTree.js +1 -1
  199. package/vanilla/UiTreeItem.d.ts +1 -0
  200. package/vanilla/UiTreeItem.js +45 -31
  201. package/vanilla/index.js +6 -0
  202. package/vue/UiAvatar.d.ts +4 -0
  203. package/vue/UiAvatar.vue +23 -3
  204. package/vue/UiAvatarGroup.d.ts +3 -0
  205. package/vue/UiAvatarGroup.vue +7 -4
  206. package/vue/UiBadge.d.ts +2 -2
  207. package/vue/UiBadge.vue +74 -2
  208. package/vue/UiButton.d.ts +5 -3
  209. package/vue/UiButton.vue +41 -7
  210. package/vue/UiCallout.d.ts +2 -2
  211. package/vue/UiCallout.vue +3 -2
  212. package/vue/UiCheckbox.d.ts +2 -0
  213. package/vue/UiCheckbox.vue +16 -0
  214. package/vue/UiCombobox.d.ts +11 -3
  215. package/vue/UiCombobox.vue +60 -11
  216. package/vue/UiContextMenu.d.ts +2 -0
  217. package/vue/UiContextMenu.vue +47 -6
  218. package/vue/UiDialog.d.ts +18 -4
  219. package/vue/UiDialog.vue +86 -11
  220. package/vue/UiDisclosure.d.ts +8 -2
  221. package/vue/UiDisclosure.vue +38 -14
  222. package/vue/UiEditable.d.ts +10 -0
  223. package/vue/UiEditable.vue +14 -2
  224. package/vue/UiEditorInsertTableGrid.vue +52 -15
  225. package/vue/UiEditorMentionMenu.d.ts +24 -2
  226. package/vue/UiEditorMentionMenu.vue +27 -11
  227. package/vue/UiEditorMentionMenuItem.d.ts +24 -0
  228. package/vue/UiEditorMentionMenuItem.js +2 -0
  229. package/vue/UiEditorMentionMenuItem.vue +88 -0
  230. package/vue/UiEditorSlashMenu.d.ts +24 -1
  231. package/vue/UiEditorSlashMenu.vue +33 -33
  232. package/vue/UiEditorSlashMenuGroup.d.ts +18 -0
  233. package/vue/UiEditorSlashMenuGroup.js +2 -0
  234. package/vue/UiEditorSlashMenuGroup.vue +43 -0
  235. package/vue/UiEditorSlashMenuItem.d.ts +26 -0
  236. package/vue/UiEditorSlashMenuItem.js +2 -0
  237. package/vue/UiEditorSlashMenuItem.vue +101 -0
  238. package/vue/UiEditorTableContextMenu.d.ts +9 -3
  239. package/vue/UiEditorTableContextMenu.vue +53 -3
  240. package/vue/UiEditorTableOverlay.d.ts +2 -2
  241. package/vue/UiEditorTableOverlay.vue +8 -6
  242. package/vue/UiEditorTableToolbar.d.ts +7 -3
  243. package/vue/UiEditorTableToolbar.vue +50 -2
  244. package/vue/UiEditorToolbar.vue +14 -1
  245. package/vue/UiFloatingActionButton.vue +1 -1
  246. package/vue/UiFormField.vue +28 -3
  247. package/vue/UiGrid.d.ts +1 -0
  248. package/vue/UiGrid.vue +26 -2
  249. package/vue/UiIcon.vue +16 -0
  250. package/vue/UiIconButton.d.ts +5 -3
  251. package/vue/UiIconButton.vue +40 -6
  252. package/vue/UiInput.vue +10 -3
  253. package/vue/UiInputGroup.vue +32 -11
  254. package/vue/UiListbox.d.ts +33 -0
  255. package/vue/UiListbox.js +2 -0
  256. package/vue/UiListbox.vue +131 -0
  257. package/vue/UiMenu.d.ts +2 -0
  258. package/vue/UiMenu.vue +43 -6
  259. package/vue/UiMenuGroup.d.ts +18 -0
  260. package/vue/UiMenuGroup.js +2 -0
  261. package/vue/UiMenuGroup.vue +39 -0
  262. package/vue/UiMenuItem.d.ts +34 -2
  263. package/vue/UiMenuItem.vue +145 -9
  264. package/vue/UiPopover.d.ts +2 -2
  265. package/vue/UiPopover.vue +44 -5
  266. package/vue/UiRadioGroup.d.ts +2 -0
  267. package/vue/UiRadioGroup.vue +17 -0
  268. package/vue/UiSearchShell.vue +12 -5
  269. package/vue/UiSelect.vue +18 -4
  270. package/vue/UiSwitch.vue +2 -2
  271. package/vue/UiSwitcher.d.ts +1 -0
  272. package/vue/UiSwitcher.vue +22 -1
  273. package/vue/UiTabs.d.ts +6 -2
  274. package/vue/UiTabs.vue +14 -12
  275. package/vue/UiTextarea.d.ts +2 -0
  276. package/vue/UiTextarea.vue +32 -4
  277. package/vue/UiToast.d.ts +34 -0
  278. package/vue/UiToast.js +2 -0
  279. package/vue/UiToast.vue +173 -0
  280. package/vue/UiToastRegion.d.ts +2 -18
  281. package/vue/UiToastRegion.vue +123 -48
  282. package/vue/UiTooltip.d.ts +2 -2
  283. package/vue/UiTooltip.vue +67 -12
  284. package/vue/UiTree.d.ts +10 -0
  285. package/vue/UiTree.vue +27 -0
  286. package/vue/UiTreeItem.d.ts +2 -0
  287. package/vue/UiTreeItem.vue +96 -4
  288. package/vue/chunks/UiAvatar.js +19 -5
  289. package/vue/chunks/UiAvatarGroup.js +10 -4
  290. package/vue/chunks/UiBadge.js +1 -1
  291. package/vue/chunks/UiButton.js +58 -11
  292. package/vue/chunks/UiCallout.js +2 -2
  293. package/vue/chunks/UiCheckbox.js +12 -2
  294. package/vue/chunks/UiCombobox.js +29 -13
  295. package/vue/chunks/UiContextMenu.js +6 -2
  296. package/vue/chunks/UiDialog.js +25 -8
  297. package/vue/chunks/UiDisclosure.js +36 -12
  298. package/vue/chunks/UiEditable.js +22 -8
  299. package/vue/chunks/UiEditorInsertTableGrid.js +11 -14
  300. package/vue/chunks/UiEditorMentionMenu.js +30 -19
  301. package/vue/chunks/UiEditorMentionMenuItem.js +36 -0
  302. package/vue/chunks/UiEditorSlashMenu.js +33 -35
  303. package/vue/chunks/UiEditorSlashMenuGroup.js +26 -0
  304. package/vue/chunks/UiEditorSlashMenuItem.js +51 -0
  305. package/vue/chunks/UiEditorTableContextMenu.js +39 -5
  306. package/vue/chunks/UiEditorTableOverlay.js +6 -6
  307. package/vue/chunks/UiEditorTableToolbar.js +37 -4
  308. package/vue/chunks/UiEditorToolbar.js +18 -4
  309. package/vue/chunks/UiFloatingActionButton.js +1 -1
  310. package/vue/chunks/UiFormField.js +13 -9
  311. package/vue/chunks/UiGrid.js +6 -2
  312. package/vue/chunks/UiIcon.js +40 -2
  313. package/vue/chunks/UiIconButton.js +35 -4
  314. package/vue/chunks/UiInput.js +1 -1
  315. package/vue/chunks/UiInputGroup.js +1 -1
  316. package/vue/chunks/UiListbox.js +70 -0
  317. package/vue/chunks/UiMenu.js +6 -2
  318. package/vue/chunks/UiMenuGroup.js +25 -0
  319. package/vue/chunks/UiMenuItem.js +128 -7
  320. package/vue/chunks/UiPopover.js +1 -1
  321. package/vue/chunks/UiRadioGroup.js +8 -2
  322. package/vue/chunks/UiSearchShell.js +1 -1
  323. package/vue/chunks/UiSelect.js +1 -1
  324. package/vue/chunks/UiSwitch.js +1 -1
  325. package/vue/chunks/UiSwitcher.js +20 -3
  326. package/vue/chunks/UiTabs.js +4 -3
  327. package/vue/chunks/UiTextarea.js +7 -2
  328. package/vue/chunks/UiToast.js +81 -0
  329. package/vue/chunks/UiToastRegion.js +25 -49
  330. package/vue/chunks/UiTooltip.js +3 -7
  331. package/vue/chunks/UiTree.js +8 -4
  332. package/vue/chunks/UiTreeItem.js +28 -10
  333. package/vue/components.css +1840 -851
  334. package/vue/editor/index.js +263 -2
  335. package/vue/index.d.ts +6 -0
  336. package/vue/index.js +9 -3
@@ -8,7 +8,7 @@ import { gapCursor } from "@tiptap/pm/gapcursor";
8
8
  import { common, createLowlight } from "lowlight";
9
9
  import { DOMParser, Node as Node$2 } from "@tiptap/pm/model";
10
10
  import MarkdownIt from "markdown-it";
11
- import { CellSelection, TableMap, addColumn, addColumnAfter, addColumnBefore, addRow, addRowAfter, addRowBefore, cellAround, columnResizing, deleteCellSelection, deleteColumn, deleteRow, deleteTable, fixTables, goToNextCell, mergeCells, setCellAttr, splitCell, tableEditing, toggleHeader, toggleHeaderCell } from "@tiptap/pm/tables";
11
+ import { CellSelection, TableMap, addColumn, addColumnAfter, addColumnBefore, addRow, addRowAfter, addRowBefore, cellAround, columnResizing, deleteCellSelection, deleteColumn, deleteRow, deleteTable, fixTables, goToNextCell, mergeCells, moveTableColumn, moveTableRow, setCellAttr, splitCell, tableEditing, toggleHeader, toggleHeaderCell } from "@tiptap/pm/tables";
12
12
  //#region src/editor/extensions/active-block.ts
13
13
  /**
14
14
  * Marks the top-level block holding the caret so a stylesheet can show where
@@ -6754,6 +6754,12 @@ function getDefaultEditorExtensions(options = {}) {
6754
6754
  //#endregion
6755
6755
  //#region src/editor/extensions/table-commands.ts
6756
6756
  var NO_TABLE_CAPABILITIES = {
6757
+ canToggleHeaderRow: false,
6758
+ canToggleHeaderColumn: false,
6759
+ canMoveRowUp: false,
6760
+ canMoveRowDown: false,
6761
+ canMoveColumnLeft: false,
6762
+ canMoveColumnRight: false,
6757
6763
  canAddRowBefore: false,
6758
6764
  canAddRowAfter: false,
6759
6765
  canAddColumnBefore: false,
@@ -6787,14 +6793,45 @@ function getActiveTableUiState(editor) {
6787
6793
  showToolbar: false,
6788
6794
  cellAlignment: "left",
6789
6795
  cellBackground: null,
6796
+ headerRow: false,
6797
+ headerColumn: false,
6790
6798
  capabilities: { ...NO_TABLE_CAPABILITIES }
6791
6799
  };
6800
+ const table = findTable(editor)?.node;
6801
+ const map = table ? TableMap.get(table) : null;
6802
+ const headerRow = Boolean(table && map && Array.from({ length: map.width }, (_, column) => table.nodeAt(map.map[column])?.type.name === "tableHeader").every(Boolean));
6803
+ const headerColumn = Boolean(table && map && Array.from({ length: map.height }, (_, row) => table.nodeAt(map.map[row * map.width])?.type.name === "tableHeader").every(Boolean));
6804
+ const position = selectedTableCell(editor);
6805
+ const canMove = (axis, delta) => {
6806
+ if (!position || !map) return false;
6807
+ const { row, column, cellPos } = position;
6808
+ const from = axis === "row" ? row : column;
6809
+ if (from + delta < 0 || from + delta >= (axis === "row" ? map.height : map.width)) return false;
6810
+ const command = axis === "row" ? moveTableRow : moveTableColumn;
6811
+ try {
6812
+ return command({
6813
+ from,
6814
+ to: from + delta,
6815
+ pos: cellPos
6816
+ })(editor.state);
6817
+ } catch {
6818
+ return false;
6819
+ }
6820
+ };
6792
6821
  return {
6793
6822
  active: true,
6794
6823
  showToolbar: true,
6795
6824
  cellAlignment: getActiveTableCellAlignment(editor),
6796
6825
  cellBackground: getActiveTableCellBackground(editor),
6826
+ headerRow,
6827
+ headerColumn,
6797
6828
  capabilities: {
6829
+ canToggleHeaderRow: editor.can().toggleHeaderRow(),
6830
+ canToggleHeaderColumn: editor.can().toggleHeaderColumn(),
6831
+ canMoveRowUp: canMove("row", -1),
6832
+ canMoveRowDown: canMove("row", 1),
6833
+ canMoveColumnLeft: canMove("column", -1),
6834
+ canMoveColumnRight: canMove("column", 1),
6798
6835
  canAddRowBefore: editor.can().addRowBefore(),
6799
6836
  canAddRowAfter: editor.can().addRowAfter(),
6800
6837
  canAddColumnBefore: editor.can().addColumnBefore(),
@@ -6831,6 +6868,36 @@ function handleTableAction(editor, detail) {
6831
6868
  case "add-row-after": return editor.chain().focus().addRowAfter().run();
6832
6869
  case "add-column-before": return editor.chain().focus().addColumnBefore().run();
6833
6870
  case "add-column-after": return editor.chain().focus().addColumnAfter().run();
6871
+ case "toggle-header-row": return editor.chain().focus().toggleHeaderRow().run();
6872
+ case "toggle-header-column": return editor.chain().focus().toggleHeaderColumn().run();
6873
+ case "move-row-up":
6874
+ case "move-row-down":
6875
+ case "move-column-left":
6876
+ case "move-column-right": {
6877
+ const position = selectedTableCell(editor);
6878
+ if (!position) return false;
6879
+ const { row, column, cellPos } = position;
6880
+ const axis = detail.action.startsWith("move-row") ? "row" : "column";
6881
+ const from = axis === "row" ? row : column;
6882
+ const delta = detail.action.endsWith("up") || detail.action.endsWith("left") ? -1 : 1;
6883
+ const table = findTable(editor)?.node;
6884
+ if (!table) return false;
6885
+ const map = TableMap.get(table);
6886
+ if (from + delta < 0 || from + delta >= (axis === "row" ? map.height : map.width)) return false;
6887
+ const command = axis === "row" ? moveTableRow : moveTableColumn;
6888
+ let moved = false;
6889
+ try {
6890
+ moved = command({
6891
+ from,
6892
+ to: from + delta,
6893
+ pos: cellPos
6894
+ })(editor.state, editor.view.dispatch);
6895
+ } catch {
6896
+ return false;
6897
+ }
6898
+ if (moved) editor.view.focus();
6899
+ return moved;
6900
+ }
6834
6901
  case "delete-row": return editor.chain().focus().deleteRow().run();
6835
6902
  case "delete-column": return editor.chain().focus().deleteColumn().run();
6836
6903
  case "delete-table": return editor.chain().focus().deleteTable().run();
@@ -6907,6 +6974,19 @@ function findTable(editor) {
6907
6974
  function findSelectedCellPosition(editor) {
6908
6975
  return cellAround(editor.state.selection.$from)?.pos ?? null;
6909
6976
  }
6977
+ function selectedTableCell(editor) {
6978
+ const table = findTable(editor);
6979
+ const cellPos = findSelectedCellPosition(editor);
6980
+ if (!table || cellPos === null) return null;
6981
+ const relative = cellPos - table.pos - 1;
6982
+ if (relative < 0 || relative >= table.node.content.size) return null;
6983
+ const rect = TableMap.get(table.node).findCell(relative);
6984
+ return {
6985
+ row: rect.top,
6986
+ column: rect.left,
6987
+ cellPos
6988
+ };
6989
+ }
6910
6990
  function selectTableAxis(editor, axis, rowIndex, columnIndex) {
6911
6991
  const tableInfo = findTable(editor);
6912
6992
  if (!tableInfo) return false;
@@ -7007,7 +7087,7 @@ function handleTableOverlayAction(editor, detail) {
7007
7087
  if (!tableInfo) return false;
7008
7088
  const { action } = detail;
7009
7089
  if (action === "select-row" || action === "select-column") return selectTableAxis(editor, action === "select-row" ? "row" : "column", detail.rowIndex, detail.columnIndex);
7010
- if (action === "open-cell-menu") return true;
7090
+ if (action === "open-cell-menu" || action === "open-row-menu" || action === "open-column-menu") return true;
7011
7091
  if (!("boundaryIndex" in detail)) return false;
7012
7092
  const { boundaryIndex } = detail;
7013
7093
  const { pos: tablePos, node: table } = tableInfo;
@@ -22,6 +22,12 @@ export interface InsertTableAtRangeOptions {
22
22
  * Tiptap's schema/selection rules or optimistically enabling invalid actions.
23
23
  */
24
24
  export interface TableActionCapabilities {
25
+ canToggleHeaderRow: boolean;
26
+ canToggleHeaderColumn: boolean;
27
+ canMoveRowUp: boolean;
28
+ canMoveRowDown: boolean;
29
+ canMoveColumnLeft: boolean;
30
+ canMoveColumnRight: boolean;
25
31
  canAddRowBefore: boolean;
26
32
  canAddRowAfter: boolean;
27
33
  canAddColumnBefore: boolean;
@@ -43,6 +49,8 @@ export interface ActiveTableUiState {
43
49
  showToolbar: boolean;
44
50
  cellAlignment: TableCellAlignment;
45
51
  cellBackground: TableCellBackground;
52
+ headerRow: boolean;
53
+ headerColumn: boolean;
46
54
  capabilities: TableActionCapabilities;
47
55
  }
48
56
  /**
package/editor/icons.d.ts CHANGED
@@ -9,7 +9,9 @@ export declare const LOOMA_ICONS: {
9
9
  'book-user': IconNode;
10
10
  braces: IconNode;
11
11
  calculator: IconNode;
12
+ check: IconNode;
12
13
  'circle-check': IconNode;
14
+ 'circle-dot': IconNode;
13
15
  'circle-x': IconNode;
14
16
  'chevron-down': IconNode;
15
17
  'chevron-left': IconNode;
@@ -32,6 +34,7 @@ export declare const LOOMA_ICONS: {
32
34
  info: IconNode;
33
35
  italic: IconNode;
34
36
  'layout-dashboard': IconNode;
37
+ link: IconNode;
35
38
  list: IconNode;
36
39
  'list-ordered': IconNode;
37
40
  'list-todo': IconNode;
@@ -58,8 +61,10 @@ export declare const LOOMA_ICONS: {
58
61
  'triangle-alert': IconNode;
59
62
  truck: IconNode;
60
63
  underline: IconNode;
64
+ 'user-round': IconNode;
61
65
  users: IconNode;
62
66
  undo: IconNode;
67
+ x: IconNode;
63
68
  };
64
69
  /** Stable key selecting an icon from Looma's shipped interaction vocabulary. */
65
70
  export type LoomaIconName = keyof typeof LOOMA_ICONS;
package/editor/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { n as TABLE_CELL_BACKGROUND_PRESETS, t as TABLE_CELL_BACKGROUND_OPTIONS } from "./chunks/table-backgrounds.js";
2
2
  import { n as resolveTableCellAt, t as measureTableOverlayGeometry } from "./chunks/ui.js";
3
3
  import { A as LOOMA_ACTIVE_BLOCK_CLASS, C as DEFAULT_MENTION_RESULT_LIMIT, D as LOOMA_CALLOUT_TONES, E as normalizeMentionResultLimit, M as LoomaActiveBlock, N as LoomaActiveBlockPluginKey, O as LoomaCallout, S as createLoomaMentionExtension, T as filterLoomaMentionItems, _ as getActiveTableCellBackground, a as handleTableAction, b as LoomaSmartPaste, c as normalizeActiveTableColumnWidths, d as getDefaultEditorExtensions, f as getLoomaTableExtensions, g as getActiveTableCellAlignment, h as LoomaTableHeader, i as getActiveTableUiState, j as LOOMA_ACTIVE_BLOCK_TYPING_IDLE_MS, k as LOOMA_ACTIVE_BLOCK_BLUR_GRACE_MS, l as shouldShowTextFormattingToolbar, m as LoomaTableCell, n as createLoomaSlashCommandExtension, o as handleTableOverlayAction, p as LoomaTable, r as getDefaultSlashCommands, s as insertTableAtRange, t as LoomaSlashCommand, u as LoomaTableKit, v as setActiveTableCellAlignment, w as MAX_MENTION_RESULT_LIMIT, x as LoomaMentionSuggestionPluginKey, y as setActiveTableCellBackground } from "./chunks/extensions.js";
4
- import { AlignCenter, AlignLeft, AlignRight, ArrowLeft, Bold, BookUser, Braces, Calculator, ChevronDown, ChevronLeft, ChevronRight, CircleCheck, CircleQuestionMark, CircleX, CodeXml, Columns3, CreditCard, Ellipsis, Eraser, FileText, Folder, GripHorizontal, GripVertical, Heading1, Heading2, Heading3, Highlighter, Image, Info, Italic, LayoutDashboard, List, ListOrdered, ListTodo, LoaderCircle, Merge, Minus, NotebookPen, PaintBucket, PanelBottom, PanelLeft, PanelRight, PanelTop, Pilcrow, Plus, Quote, Receipt, Redo2, Rows3, Settings, Split, Strikethrough, Table2, Trash2, TriangleAlert, Truck, Underline, Undo2, Users } from "lucide";
4
+ import { AlignCenter, AlignLeft, AlignRight, ArrowLeft, Bold, BookUser, Braces, Calculator, Check, ChevronDown, ChevronLeft, ChevronRight, CircleCheck, CircleDot, CircleQuestionMark, CircleX, CodeXml, Columns3, CreditCard, Ellipsis, Eraser, FileText, Folder, GripHorizontal, GripVertical, Heading1, Heading2, Heading3, Highlighter, Image, Info, Italic, LayoutDashboard, Link, List, ListOrdered, ListTodo, LoaderCircle, Merge, Minus, NotebookPen, PaintBucket, PanelBottom, PanelLeft, PanelRight, PanelTop, Pilcrow, Plus, Quote, Receipt, Redo2, Rows3, Settings, Split, Strikethrough, Table2, Trash2, TriangleAlert, Truck, Underline, Undo2, UserRound, Users, X } from "lucide";
5
5
  //#region src/editor/icons.ts
6
6
  /** The opinionated Lucide set used by Looma's shipped interaction surfaces. */
7
7
  var LOOMA_ICONS = {
@@ -13,7 +13,9 @@ var LOOMA_ICONS = {
13
13
  "book-user": BookUser,
14
14
  braces: Braces,
15
15
  calculator: Calculator,
16
+ check: Check,
16
17
  "circle-check": CircleCheck,
18
+ "circle-dot": CircleDot,
17
19
  "circle-x": CircleX,
18
20
  "chevron-down": ChevronDown,
19
21
  "chevron-left": ChevronLeft,
@@ -36,6 +38,7 @@ var LOOMA_ICONS = {
36
38
  info: Info,
37
39
  italic: Italic,
38
40
  "layout-dashboard": LayoutDashboard,
41
+ link: Link,
39
42
  list: List,
40
43
  "list-ordered": ListOrdered,
41
44
  "list-todo": ListTodo,
@@ -62,8 +65,10 @@ var LOOMA_ICONS = {
62
65
  "triangle-alert": TriangleAlert,
63
66
  truck: Truck,
64
67
  underline: Underline,
68
+ "user-round": UserRound,
65
69
  users: Users,
66
- undo: Undo2
70
+ undo: Undo2,
71
+ x: X
67
72
  };
68
73
  function serializeAttributes(attributes) {
69
74
  return Object.entries(attributes).map(([name, value]) => ` ${name}="${escapeAttribute(value)}"`).join("");
@@ -1,5 +1,5 @@
1
1
  /** Event contract for the declarative table-dimension picker. */
2
- /** Confirmed table dimensions emitted after preview state has been committed. */
2
+ /** Table dimensions emitted when a cell is activated. */
3
3
  export interface InsertTableEventDetail {
4
4
  rows: number;
5
5
  cols: number;
@@ -2,8 +2,10 @@
2
2
  /** Zero-based candidate position requested by pointer-driven menu highlighting. */
3
3
  export interface MentionMenuHighlightEventDetail {
4
4
  index: number;
5
+ value: string;
5
6
  }
6
7
  /** Zero-based candidate position the host should commit as the chosen mention. */
7
8
  export interface MentionMenuSelectEventDetail {
8
9
  index: number;
10
+ value: string;
9
11
  }
@@ -6,6 +6,7 @@ import type { LoomaIconName } from "./icons.js";
6
6
  * headless extension executes the command from its current ephemeral snapshot.
7
7
  */
8
8
  export interface SlashMenuItem {
9
+ value?: string;
9
10
  title: string;
10
11
  description: string;
11
12
  icon: LoomaIconName;
@@ -13,10 +14,12 @@ export interface SlashMenuItem {
13
14
  /** Pointer-hover request; selection remains owned by the suggestion extension. */
14
15
  export interface SlashMenuHighlightEventDetail {
15
16
  index: number;
17
+ value: string;
16
18
  }
17
19
  /** Activation request for an item in the current published snapshot. */
18
20
  export interface SlashMenuSelectEventDetail {
19
21
  index: number;
22
+ value: string;
20
23
  }
21
24
  /**
22
25
  * A viewport rectangle accepted by the slash-menu anchor.
@@ -5,7 +5,7 @@ import type { TableCellBackgroundAction } from "./table-backgrounds.js";
5
5
  * Keeping this as data prevents the reusable menu from importing or mutating a
6
6
  * particular editor implementation.
7
7
  */
8
- export type TableContextMenuAction = "align-left" | "align-center" | "align-right" | TableCellBackgroundAction | "add-row-before" | "add-row-after" | "add-column-before" | "add-column-after" | "delete-row" | "delete-column" | "delete-table" | "clear-cells" | "merge-cells" | "split-cell";
8
+ export type TableContextMenuAction = "align-left" | "align-center" | "align-right" | TableCellBackgroundAction | "add-row-before" | "add-row-after" | "add-column-before" | "add-column-after" | "toggle-header-row" | "toggle-header-column" | "move-row-up" | "move-row-down" | "move-column-left" | "move-column-right" | "delete-row" | "delete-column" | "delete-table" | "clear-cells" | "merge-cells" | "split-cell";
9
9
  /** Adapter-facing payload that keeps the menu independent of editor commands. */
10
10
  export interface TableContextMenuActionEventDetail {
11
11
  action: TableContextMenuAction;
@@ -9,7 +9,7 @@ export type TableInsertionAction = "add-row-before" | "add-row-after" | "add-col
9
9
  * UI stays independent of Tiptap/ProseMirror positions; adapters translate
10
10
  * these logical coordinates with `handleTableOverlayAction`.
11
11
  */
12
- export type TableOverlayAction = TableInsertionAction | "select-row" | "select-column" | "open-cell-menu";
12
+ export type TableOverlayAction = TableInsertionAction | "select-row" | "select-column" | "open-cell-menu" | "open-row-menu" | "open-column-menu";
13
13
  /**
14
14
  * Discriminated action payload.
15
15
  * Boundary indices refer to entries in the measured boundary arrays. Cell
@@ -24,7 +24,7 @@ export type TableOverlayActionEventDetail = {
24
24
  rowIndex: number;
25
25
  columnIndex: number;
26
26
  } | {
27
- action: "open-cell-menu";
27
+ action: "open-cell-menu" | "open-row-menu" | "open-column-menu";
28
28
  rowIndex: number;
29
29
  columnIndex: number;
30
30
  anchor: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@threadlabs/looma",
3
- "version": "0.14.8",
3
+ "version": "0.15.0",
4
4
  "type": "module",
5
5
  "description": "Looma components as HTML, Vue, and plain DOM, with design tokens.",
6
6
  "license": "MIT",
@@ -36,7 +36,7 @@
36
36
  justify-content: center;
37
37
  inline-size: 2.5rem;
38
38
  block-size: 2.5rem;
39
- border-radius: 999px;
39
+ border-radius: var(--ui-radius-round);
40
40
  border: 1px solid var(--ui-border-strong);
41
41
  background: var(--ui-surface-elevated);
42
42
  color: var(--ui-text-primary);
@@ -72,7 +72,6 @@
72
72
  :where([data-slotted], [data-slotted] *):is(*) {
73
73
  margin-inline-start: -0.5rem;
74
74
  flex-shrink: 0;
75
- border-radius: 999px;
76
75
  }
77
76
 
78
77
  :where([data-slotted], [data-slotted] *):is(*:first-child) {
@@ -3,6 +3,10 @@
3
3
  syntax: "*";
4
4
  inherits: false;
5
5
  }
6
+ @property --ui-avatar-radius {
7
+ syntax: "*";
8
+ inherits: false;
9
+ }
6
10
  @property --ui-avatar-surface {
7
11
  syntax: "*";
8
12
  inherits: false;
@@ -19,12 +23,13 @@
19
23
  /* This component's hooks style the element they are set on, and never a nested one. */
20
24
 
21
25
  :scope {
26
+ --_ui-default-icon-size: 1.25rem;
22
27
  display: inline-grid;
23
28
  place-items: center;
24
29
  overflow: hidden;
25
30
  inline-size: 2.5rem;
26
31
  block-size: 2.5rem;
27
- border-radius: 999px;
32
+ border-radius: var(--ui-avatar-radius, var(--ui-radius-round));
28
33
  border: 1px solid var(--ui-avatar-border, var(--ui-border-strong));
29
34
  background: var(--ui-avatar-surface, var(--ui-accent-soft));
30
35
  color: var(--ui-avatar-text, var(--ui-accent-subtle-text, var(--ui-accent-solid)));
@@ -35,11 +40,16 @@
35
40
  }
36
41
 
37
42
  :scope[data-ui-avatar-state~="size=sm"] {
43
+ --_ui-default-icon-size: 1rem;
38
44
  inline-size: 1.75rem;
39
45
  block-size: 1.75rem;
40
46
  font-size: var(--ui-font-size-xs);
41
47
  }
42
48
 
49
+ :scope[data-ui-avatar-state~="shape=square"] {
50
+ border-radius: var(--ui-avatar-radius, var(--ui-radius-md));
51
+ }
52
+
43
53
  /* An outline, not a dot: the avatar clips its content to the circle, and an outline is drawn
44
54
  outside the box, so the ring survives the clip and the overlap in an Avatar Group. */
45
55
  :scope[data-ui-avatar-state~="active"] {
@@ -47,6 +47,7 @@
47
47
  --_badge-text: var(--ui-text-secondary);
48
48
  /* Every tone's edge is its fill, so it is unseen until forced colors draw it. */
49
49
  --_badge-border: var(--ui-surface-subtle);
50
+ --_badge-outline-surface: var(--ui-badge-surface, var(--_badge-surface));
50
51
 
51
52
  display: inline-flex;
52
53
  align-items: center;
@@ -55,7 +56,7 @@
55
56
  padding: var(--ui-badge-padding-block, var(--ui-space-0-5)) var(--ui-badge-padding-inline, var(--ui-space-2));
56
57
  border: 1px solid var(--ui-badge-border, var(--_badge-border));
57
58
  border-radius: var(--ui-radius-round);
58
- background: var(--ui-badge-surface, var(--_badge-surface));
59
+ background: var(--_badge-outline-surface);
59
60
  color: var(--ui-badge-text, var(--_badge-text));
60
61
  font-family: var(--ui-font-family-sans);
61
62
  font-size: var(--ui-badge-font-size, var(--ui-font-size-sm));
@@ -138,6 +139,37 @@
138
139
  --_badge-text: var(--ui-info-subtle-text, var(--ui-info-solid));
139
140
  }
140
141
 
142
+ :scope[data-ui-badge-state~="variant=outline"] {
143
+ --_badge-surface: var(--ui-surface-default);
144
+ --_badge-border: var(--ui-border-strong);
145
+ --_badge-text: var(--ui-text-secondary);
146
+ }
147
+
148
+ :scope[data-ui-badge-state~="variant=outline"][data-ui-badge-state~="tone=accent"] {
149
+ --_badge-border: var(--ui-accent-solid);
150
+ --_badge-text: var(--ui-accent-subtle-text, var(--ui-accent-solid));
151
+ }
152
+
153
+ :scope[data-ui-badge-state~="variant=outline"][data-ui-badge-state~="tone=danger"] {
154
+ --_badge-border: var(--ui-danger-solid);
155
+ --_badge-text: var(--ui-danger-subtle-text, var(--ui-danger-solid));
156
+ }
157
+
158
+ :scope[data-ui-badge-state~="variant=outline"][data-ui-badge-state~="tone=success"] {
159
+ --_badge-border: var(--ui-success-solid);
160
+ --_badge-text: var(--ui-success-subtle-text, var(--ui-success-solid));
161
+ }
162
+
163
+ :scope[data-ui-badge-state~="variant=outline"][data-ui-badge-state~="tone=warning"] {
164
+ --_badge-border: var(--ui-warning-solid);
165
+ --_badge-text: var(--ui-warning-subtle-text, var(--ui-warning-solid));
166
+ }
167
+
168
+ :scope[data-ui-badge-state~="variant=outline"][data-ui-badge-state~="tone=info"] {
169
+ --_badge-border: var(--ui-info-solid);
170
+ --_badge-text: var(--ui-info-subtle-text, var(--ui-info-solid));
171
+ }
172
+
141
173
  /* A tag is flat at the start and points at the end. The point is cut from the box, so it has no
142
174
  outline to follow: the edge is the fill. The end padding grows by the point's depth so the
143
175
  label never runs into it. */
@@ -156,6 +188,40 @@
156
188
  clip-path: polygon(var(--_badge-point) 0, 100% 0, 100% 100%, var(--_badge-point) 100%, 0 50%);
157
189
  }
158
190
 
191
+ /* The tag clips its point, including the native border. Draw the outer shape in the border
192
+ colour and an inset inner shape in the surface colour to keep a visible diagonal edge. */
193
+ :scope[data-ui-badge-state~="variant=outline"][data-ui-badge-state~="shape=tag"] {
194
+ position: relative;
195
+ isolation: isolate;
196
+ background: var(--ui-badge-border, var(--_badge-border));
197
+ }
198
+
199
+ :scope[data-ui-badge-state~="variant=outline"][data-ui-badge-state~="shape=tag"]::before {
200
+ content: "";
201
+ position: absolute;
202
+ inset: 1px;
203
+ z-index: -1;
204
+ background: var(--_badge-outline-surface);
205
+ clip-path: polygon(0 0, calc(100% - var(--_badge-point)) 0, 100% 50%, calc(100% - var(--_badge-point)) 100%, 0 100%);
206
+ pointer-events: none;
207
+ }
208
+
209
+ :scope[data-ui-badge-state~="variant=outline"][data-ui-badge-state~="shape=tag"]:dir(rtl)::before {
210
+ clip-path: polygon(var(--_badge-point) 0, 100% 0, 100% 100%, var(--_badge-point) 100%, 0 50%);
211
+ }
212
+
213
+ @media (forced-colors: active) {
214
+ :scope[data-ui-badge-state~="variant=outline"][data-ui-badge-state~="shape=tag"] {
215
+ forced-color-adjust: none;
216
+ background: CanvasText;
217
+ color: CanvasText;
218
+ }
219
+
220
+ :scope[data-ui-badge-state~="variant=outline"][data-ui-badge-state~="shape=tag"]::before {
221
+ background: Canvas;
222
+ }
223
+ }
224
+
159
225
  /* A component that sets its display still honours the hidden attribute on its root. */
160
226
  :scope[hidden] {
161
227
  display: none;
@@ -174,5 +240,11 @@
174
240
  outline to follow: the edge is the fill. The end padding grows by the point's depth so the
175
241
  label never runs into it. */
176
242
 
243
+ /* The tag clips its point, including the native border. Draw the outer shape in the border
244
+ colour and an inset inner shape in the surface colour to keep a visible diagonal edge. */
245
+
246
+ @media (forced-colors: active) {
247
+ }
248
+
177
249
  /* A component that sets its display still honours the hidden attribute on its root. */
178
250
  }
@@ -106,7 +106,7 @@
106
106
  border-style: solid;
107
107
  border-width: 1px;
108
108
  border-color: var(--ui-button-border, var(--_tone));
109
- border-radius: var(--ui-button-radius, var(--ui-radius-md));
109
+ border-radius: var(--ui-button-radius, var(--ui-action-radius, var(--ui-radius-md)));
110
110
  background-color: var(--ui-button-surface, oklch(from var(--_tone) l c h / 5%));
111
111
  color: var(--ui-button-text, var(--_tone-text));
112
112
  font: inherit;
@@ -125,6 +125,10 @@
125
125
  margin: 0;
126
126
  }
127
127
 
128
+ .pending-spinner {
129
+ margin-inline-end: var(--ui-space-2);
130
+ }
131
+
128
132
  @supports (text-box-trim: trim-both) {
129
133
  :scope {
130
134
  text-box-trim: trim-both;
@@ -265,6 +269,10 @@
265
269
  box-shadow: none;
266
270
  }
267
271
 
272
+ :scope[data-ui-button-state~="pending"]:focus-visible {
273
+ box-shadow: var(--ui-focus-halo);
274
+ }
275
+
268
276
  /* Ghost has no hover to fall back on, so disabled is the one state it has to state outright:
269
277
  it takes a surface rather than reading as plain text. The surface is a wash of the faded tone,
270
278
  the way hover washes the live one, so it stays light in every tone. An opaque mix toward the
@@ -91,7 +91,7 @@
91
91
  min-inline-size: 0;
92
92
  }
93
93
 
94
- :scope[data-ui-callout-state~="tone=note"] {
94
+ :scope[data-ui-callout-state~="tone=neutral"], :scope[data-ui-callout-state~="tone=note"] {
95
95
  --_callout-surface: var(--ui-surface-muted);
96
96
  --_callout-border: var(--ui-border-strong);
97
97
  --_callout-icon: var(--ui-text-secondary);
@@ -3,6 +3,10 @@
3
3
  syntax: "*";
4
4
  inherits: false;
5
5
  }
6
+ @property --ui-checkbox-invalid-border {
7
+ syntax: "*";
8
+ inherits: false;
9
+ }
6
10
  @property --ui-checkbox-size {
7
11
  syntax: "*";
8
12
  inherits: false;
@@ -13,6 +17,7 @@
13
17
  :scope {
14
18
  /* Hooks do not inherit, so the parts below read them from the root. */
15
19
  --_ui-checkbox-size: var(--ui-checkbox-size);
20
+ --_ui-checkbox-invalid-border: var(--ui-checkbox-invalid-border, var(--ui-field-danger, var(--ui-danger-solid)));
16
21
 
17
22
  display: inline-flex;
18
23
  align-items: flex-start;
@@ -110,6 +115,10 @@
110
115
  outline-offset: 2px;
111
116
  }
112
117
 
118
+ :scope[data-ui-checkbox-state~="invalid"] input {
119
+ border-color: var(--_ui-checkbox-invalid-border);
120
+ }
121
+
113
122
  :scope[data-ui-checkbox-state~="disabled"] {
114
123
  color: var(--ui-disabled-text);
115
124
  cursor: not-allowed;
@@ -39,6 +39,30 @@
39
39
  syntax: "*";
40
40
  inherits: false;
41
41
  }
42
+ @property --ui-combobox-radius {
43
+ syntax: "*";
44
+ inherits: false;
45
+ }
46
+ @property --ui-combobox-invalid-border {
47
+ syntax: "*";
48
+ inherits: false;
49
+ }
50
+ @property --ui-combobox-popup-surface {
51
+ syntax: "*";
52
+ inherits: false;
53
+ }
54
+ @property --ui-combobox-popup-border {
55
+ syntax: "*";
56
+ inherits: false;
57
+ }
58
+ @property --ui-combobox-popup-radius {
59
+ syntax: "*";
60
+ inherits: false;
61
+ }
62
+ @property --ui-combobox-popup-shadow {
63
+ syntax: "*";
64
+ inherits: false;
65
+ }
42
66
  @scope ([data-component~="ui-combobox"]) to ([data-component], [data-slotted]) {
43
67
  /* This component's hooks style the element they are set on, and never a nested one. */
44
68
 
@@ -54,6 +78,12 @@
54
78
  --_ui-combobox-item-min-block-size: var(--ui-combobox-item-min-block-size);
55
79
  --_ui-combobox-item-input-min-inline-size: var(--ui-combobox-item-input-min-inline-size);
56
80
  --_ui-combobox-item-item-max-inline-size: var(--ui-combobox-item-item-max-inline-size);
81
+ --_ui-combobox-radius: var(--ui-combobox-radius);
82
+ --_ui-combobox-invalid-border: var(--ui-combobox-invalid-border);
83
+ --_ui-combobox-popup-surface: var(--ui-combobox-popup-surface);
84
+ --_ui-combobox-popup-border: var(--ui-combobox-popup-border);
85
+ --_ui-combobox-popup-radius: var(--ui-combobox-popup-radius);
86
+ --_ui-combobox-popup-shadow: var(--ui-combobox-popup-shadow);
57
87
 
58
88
  display: grid;
59
89
  gap: var(--ui-space-1);
@@ -80,7 +110,7 @@
80
110
  display: flex;
81
111
  min-inline-size: 0;
82
112
  border: 1px solid var(--ui-control-border, var(--ui-border-default));
83
- border-radius: var(--ui-radius-md);
113
+ border-radius: var(--_ui-combobox-radius, var(--ui-field-radius, var(--ui-radius-md)));
84
114
  background: var(--ui-control-surface, var(--ui-surface-default));
85
115
  box-shadow: var(--ui-control-inset);
86
116
  transition: border-color var(--ui-motion-fast) var(--ui-motion-ease), box-shadow var(--ui-motion-fast) var(--ui-motion-ease);
@@ -198,8 +228,9 @@
198
228
  .field:has(input:disabled) {
199
229
  background: var(--ui-control-surface-disabled, var(--ui-surface-muted));
200
230
  }
201
- :scope[data-ui-combobox-state~="validationStatus=error"] .field {
202
- border-color: var(--ui-danger-solid, var(--ui-accent-active));
231
+ :scope[data-ui-combobox-state~="validationStatus=error"] .field,
232
+ :scope[data-ui-combobox-state~="invalid"] .field {
233
+ border-color: var(--_ui-combobox-invalid-border, var(--ui-field-danger, var(--ui-danger-solid, var(--ui-accent-active))));
203
234
  }
204
235
  .popup {
205
236
  box-sizing: border-box;
@@ -209,11 +240,11 @@
209
240
  overflow: auto;
210
241
  margin: 0;
211
242
  padding: var(--ui-space-1);
212
- border: 1px solid var(--ui-border-default);
213
- border-radius: var(--ui-radius-md);
214
- background: var(--ui-surface-elevated);
243
+ border: 1px solid var(--_ui-combobox-popup-border, var(--ui-overlay-border, var(--ui-border-default)));
244
+ border-radius: var(--_ui-combobox-popup-radius, var(--ui-overlay-radius, var(--ui-radius-md)));
245
+ background: var(--_ui-combobox-popup-surface, var(--ui-overlay-surface, var(--ui-surface-elevated)));
215
246
  color: var(--ui-text-primary);
216
- box-shadow: var(--ui-elevation-overlay, var(--ui-shadow-lg));
247
+ box-shadow: var(--_ui-combobox-popup-shadow, var(--ui-overlay-shadow, var(--ui-elevation-overlay, var(--ui-shadow-lg))));
217
248
  }
218
249
  [hidden] {
219
250
  display: none;