@threadlabs/looma 0.5.0 → 0.5.2

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 (313) hide show
  1. package/README.md +1 -1
  2. package/components/shared/input-modality.d.ts +8 -0
  3. package/components/shared/input-modality.js +2 -0
  4. package/components/ui-button/ui-button.html +42 -1
  5. package/components/ui-combobox/ui-combobox.html +12 -4
  6. package/components/ui-dialog/ui-dialog.html +13 -0
  7. package/components/ui-editor-insert-table-grid/ui-editor-insert-table-grid.html +1 -1
  8. package/components/ui-editor-mention-menu/ui-editor-mention-menu.html +1 -1
  9. package/components/ui-editor-table-context-menu/ui-editor-table-context-menu.html +6 -2
  10. package/components/ui-editor-table-overlay/ui-editor-table-overlay.html +20 -4
  11. package/components/ui-editor-table-toolbar/ui-editor-table-toolbar.html +8 -4
  12. package/components/ui-form-field/ui-form-field.html +18 -7
  13. package/components/ui-icon/ui-icon.html +5 -1
  14. package/components/ui-icon-button/ui-icon-button.html +44 -1
  15. package/components/ui-popover/ui-popover.js +10 -2
  16. package/components/ui-search-shell/ui-search-shell.html +7 -0
  17. package/components/ui-search-shell/ui-search-shell.js +9 -0
  18. package/components/ui-tabs/ui-tabs.html +1 -1
  19. package/components/ui-toast-region/ui-toast-region.html +1 -1
  20. package/components/ui-tree-item/ui-tree-item.html +6 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.js +2 -2
  23. package/package.json +2 -2
  24. package/styles/ui-affordance-scope.css +1 -1
  25. package/styles/ui-avatar-group.css +1 -1
  26. package/styles/ui-avatar.css +1 -1
  27. package/styles/ui-badge.css +1 -1
  28. package/styles/ui-button.css +42 -2
  29. package/styles/ui-callout.css +1 -1
  30. package/styles/ui-checkbox.css +1 -1
  31. package/styles/ui-cluster.css +1 -1
  32. package/styles/ui-combobox.css +1 -1
  33. package/styles/ui-container.css +1 -1
  34. package/styles/ui-context-menu.css +1 -1
  35. package/styles/ui-dialog.css +18 -1
  36. package/styles/ui-disclosure.css +1 -1
  37. package/styles/ui-editable.css +1 -1
  38. package/styles/ui-editor-insert-table-grid.css +1 -1
  39. package/styles/ui-editor-mention-menu.css +1 -1
  40. package/styles/ui-editor-slash-menu.css +1 -1
  41. package/styles/ui-editor-table-context-menu.css +1 -1
  42. package/styles/ui-editor-table-overlay.css +1 -1
  43. package/styles/ui-editor-table-toolbar.css +1 -1
  44. package/styles/ui-editor-toolbar.css +1 -1
  45. package/styles/ui-floating-action-button.css +1 -1
  46. package/styles/ui-form-field.css +24 -10
  47. package/styles/ui-grid.css +1 -1
  48. package/styles/ui-icon-button.css +52 -2
  49. package/styles/ui-icon.css +1 -1
  50. package/styles/ui-input.css +1 -1
  51. package/styles/ui-menu-item.css +1 -1
  52. package/styles/ui-menu.css +1 -1
  53. package/styles/ui-popover.css +1 -1
  54. package/styles/ui-radio-group.css +1 -1
  55. package/styles/ui-radio.css +1 -1
  56. package/styles/ui-reel.css +1 -1
  57. package/styles/ui-search-result-row.css +1 -1
  58. package/styles/ui-search-shell.css +11 -2
  59. package/styles/ui-select.css +1 -1
  60. package/styles/ui-separator.css +1 -1
  61. package/styles/ui-sidebar.css +1 -1
  62. package/styles/ui-stack.css +1 -1
  63. package/styles/ui-switch.css +1 -1
  64. package/styles/ui-switcher.css +1 -1
  65. package/styles/ui-tabs.css +1 -1
  66. package/styles/ui-textarea.css +1 -1
  67. package/styles/ui-toast-region.css +1 -1
  68. package/styles/ui-tooltip.css +1 -1
  69. package/styles/ui-top-bar.css +1 -1
  70. package/styles/ui-tree-item.css +10 -2
  71. package/styles/ui-tree.css +1 -1
  72. package/vanilla/UiAffordanceScope.d.ts +1 -1
  73. package/vanilla/UiAffordanceScope.js +2 -2
  74. package/vanilla/UiAvatar.d.ts +1 -1
  75. package/vanilla/UiAvatar.js +2 -2
  76. package/vanilla/UiAvatarGroup.d.ts +1 -1
  77. package/vanilla/UiAvatarGroup.js +2 -2
  78. package/vanilla/UiBadge.d.ts +1 -1
  79. package/vanilla/UiBadge.js +2 -2
  80. package/vanilla/UiButton.d.ts +3 -1
  81. package/vanilla/UiButton.js +3 -3
  82. package/vanilla/UiCallout.d.ts +1 -1
  83. package/vanilla/UiCallout.js +2 -2
  84. package/vanilla/UiCheckbox.d.ts +1 -1
  85. package/vanilla/UiCheckbox.js +2 -2
  86. package/vanilla/UiCluster.d.ts +1 -1
  87. package/vanilla/UiCluster.js +2 -2
  88. package/vanilla/UiCombobox.d.ts +1 -1
  89. package/vanilla/UiCombobox.js +3 -3
  90. package/vanilla/UiContainer.d.ts +1 -1
  91. package/vanilla/UiContainer.js +2 -2
  92. package/vanilla/UiContextMenu.d.ts +1 -1
  93. package/vanilla/UiContextMenu.js +2 -2
  94. package/vanilla/UiDialog.d.ts +1 -1
  95. package/vanilla/UiDialog.js +2 -2
  96. package/vanilla/UiDisclosure.d.ts +1 -1
  97. package/vanilla/UiDisclosure.js +2 -2
  98. package/vanilla/UiEditable.d.ts +1 -1
  99. package/vanilla/UiEditable.js +2 -2
  100. package/vanilla/UiEditorInsertTableGrid.d.ts +1 -1
  101. package/vanilla/UiEditorInsertTableGrid.js +3 -3
  102. package/vanilla/UiEditorMentionMenu.d.ts +1 -1
  103. package/vanilla/UiEditorMentionMenu.js +3 -3
  104. package/vanilla/UiEditorSlashMenu.d.ts +1 -1
  105. package/vanilla/UiEditorSlashMenu.js +2 -2
  106. package/vanilla/UiEditorTableContextMenu.d.ts +1 -1
  107. package/vanilla/UiEditorTableContextMenu.js +3 -3
  108. package/vanilla/UiEditorTableOverlay.d.ts +1 -1
  109. package/vanilla/UiEditorTableOverlay.js +3 -3
  110. package/vanilla/UiEditorTableToolbar.d.ts +1 -1
  111. package/vanilla/UiEditorTableToolbar.js +3 -3
  112. package/vanilla/UiEditorToolbar.d.ts +1 -1
  113. package/vanilla/UiEditorToolbar.js +2 -2
  114. package/vanilla/UiFloatingActionButton.d.ts +1 -1
  115. package/vanilla/UiFloatingActionButton.js +2 -2
  116. package/vanilla/UiFormField.d.ts +1 -1
  117. package/vanilla/UiFormField.js +15 -6
  118. package/vanilla/UiGrid.d.ts +1 -1
  119. package/vanilla/UiGrid.js +2 -2
  120. package/vanilla/UiIcon.d.ts +1 -1
  121. package/vanilla/UiIcon.js +3 -3
  122. package/vanilla/UiIconButton.d.ts +1 -1
  123. package/vanilla/UiIconButton.js +2 -2
  124. package/vanilla/UiInput.d.ts +1 -1
  125. package/vanilla/UiInput.js +2 -2
  126. package/vanilla/UiMenu.d.ts +1 -1
  127. package/vanilla/UiMenu.js +2 -2
  128. package/vanilla/UiMenuItem.d.ts +1 -1
  129. package/vanilla/UiMenuItem.js +2 -2
  130. package/vanilla/UiPopover.d.ts +1 -1
  131. package/vanilla/UiPopover.js +2 -2
  132. package/vanilla/UiRadio.d.ts +1 -1
  133. package/vanilla/UiRadio.js +2 -2
  134. package/vanilla/UiRadioGroup.d.ts +1 -1
  135. package/vanilla/UiRadioGroup.js +2 -2
  136. package/vanilla/UiReel.d.ts +1 -1
  137. package/vanilla/UiReel.js +2 -2
  138. package/vanilla/UiSearchResultRow.d.ts +1 -1
  139. package/vanilla/UiSearchResultRow.js +2 -2
  140. package/vanilla/UiSearchShell.d.ts +1 -1
  141. package/vanilla/UiSearchShell.js +2 -2
  142. package/vanilla/UiSelect.d.ts +1 -1
  143. package/vanilla/UiSelect.js +2 -2
  144. package/vanilla/UiSeparator.d.ts +1 -1
  145. package/vanilla/UiSeparator.js +2 -2
  146. package/vanilla/UiSidebar.d.ts +1 -1
  147. package/vanilla/UiSidebar.js +2 -2
  148. package/vanilla/UiStack.d.ts +1 -1
  149. package/vanilla/UiStack.js +2 -2
  150. package/vanilla/UiSwitch.d.ts +1 -1
  151. package/vanilla/UiSwitch.js +2 -2
  152. package/vanilla/UiSwitcher.d.ts +1 -1
  153. package/vanilla/UiSwitcher.js +2 -2
  154. package/vanilla/UiTabs.d.ts +1 -1
  155. package/vanilla/UiTabs.js +3 -3
  156. package/vanilla/UiTextarea.d.ts +1 -1
  157. package/vanilla/UiTextarea.js +2 -2
  158. package/vanilla/UiToastRegion.d.ts +1 -1
  159. package/vanilla/UiToastRegion.js +3 -3
  160. package/vanilla/UiTooltip.d.ts +1 -1
  161. package/vanilla/UiTooltip.js +2 -2
  162. package/vanilla/UiTopBar.d.ts +1 -1
  163. package/vanilla/UiTopBar.js +1 -1
  164. package/vanilla/UiTree.d.ts +1 -1
  165. package/vanilla/UiTree.js +2 -2
  166. package/vanilla/UiTreeItem.d.ts +1 -1
  167. package/vanilla/UiTreeItem.js +2 -2
  168. package/vue/UiAffordanceScope.d.ts +2 -2
  169. package/vue/UiAffordanceScope.vue +92 -73
  170. package/vue/UiAvatar.d.ts +7 -7
  171. package/vue/UiAvatar.vue +145 -105
  172. package/vue/UiAvatarGroup.d.ts +4 -4
  173. package/vue/UiAvatarGroup.vue +134 -118
  174. package/vue/UiBadge.d.ts +4 -4
  175. package/vue/UiBadge.vue +113 -114
  176. package/vue/UiButton.d.ts +10 -6
  177. package/vue/UiButton.vue +289 -220
  178. package/vue/UiCallout.d.ts +2 -2
  179. package/vue/UiCallout.vue +154 -87
  180. package/vue/UiCheckbox.d.ts +14 -10
  181. package/vue/UiCheckbox.vue +228 -162
  182. package/vue/UiCluster.d.ts +2 -2
  183. package/vue/UiCluster.vue +53 -60
  184. package/vue/UiCombobox.d.ts +36 -32
  185. package/vue/UiCombobox.vue +1005 -416
  186. package/vue/UiContainer.d.ts +2 -2
  187. package/vue/UiContainer.vue +48 -51
  188. package/vue/UiContextMenu.d.ts +6 -4
  189. package/vue/UiContextMenu.vue +205 -116
  190. package/vue/UiDialog.d.ts +11 -9
  191. package/vue/UiDialog.vue +287 -212
  192. package/vue/UiDisclosure.d.ts +8 -6
  193. package/vue/UiDisclosure.vue +248 -159
  194. package/vue/UiEditable.d.ts +16 -12
  195. package/vue/UiEditable.vue +325 -205
  196. package/vue/UiEditorInsertTableGrid.d.ts +8 -8
  197. package/vue/UiEditorInsertTableGrid.vue +216 -157
  198. package/vue/UiEditorMentionMenu.d.ts +9 -9
  199. package/vue/UiEditorMentionMenu.vue +265 -222
  200. package/vue/UiEditorSlashMenu.d.ts +7 -7
  201. package/vue/UiEditorSlashMenu.vue +286 -240
  202. package/vue/UiEditorTableContextMenu.d.ts +5 -5
  203. package/vue/UiEditorTableContextMenu.vue +306 -193
  204. package/vue/UiEditorTableOverlay.d.ts +2 -2
  205. package/vue/UiEditorTableOverlay.vue +609 -369
  206. package/vue/UiEditorTableToolbar.d.ts +7 -7
  207. package/vue/UiEditorTableToolbar.vue +443 -268
  208. package/vue/UiEditorToolbar.d.ts +2 -2
  209. package/vue/UiEditorToolbar.vue +134 -121
  210. package/vue/UiFloatingActionButton.d.ts +6 -6
  211. package/vue/UiFloatingActionButton.vue +100 -99
  212. package/vue/UiFormField.d.ts +6 -6
  213. package/vue/UiFormField.vue +112 -80
  214. package/vue/UiGrid.d.ts +2 -2
  215. package/vue/UiGrid.vue +51 -57
  216. package/vue/UiIcon.d.ts +2 -2
  217. package/vue/UiIcon.vue +118 -89
  218. package/vue/UiIconButton.d.ts +11 -11
  219. package/vue/UiIconButton.vue +285 -206
  220. package/vue/UiInput.d.ts +9 -9
  221. package/vue/UiInput.vue +153 -127
  222. package/vue/UiMenu.d.ts +8 -6
  223. package/vue/UiMenu.vue +217 -143
  224. package/vue/UiMenuItem.d.ts +4 -4
  225. package/vue/UiMenuItem.vue +52 -46
  226. package/vue/UiPopover.d.ts +8 -6
  227. package/vue/UiPopover.vue +197 -137
  228. package/vue/UiRadio.d.ts +14 -10
  229. package/vue/UiRadio.vue +183 -117
  230. package/vue/UiRadioGroup.d.ts +14 -12
  231. package/vue/UiRadioGroup.vue +172 -111
  232. package/vue/UiReel.d.ts +3 -3
  233. package/vue/UiReel.vue +77 -77
  234. package/vue/UiSearchResultRow.d.ts +4 -4
  235. package/vue/UiSearchResultRow.vue +124 -115
  236. package/vue/UiSearchShell.d.ts +10 -8
  237. package/vue/UiSearchShell.vue +245 -176
  238. package/vue/UiSelect.d.ts +9 -9
  239. package/vue/UiSelect.vue +162 -134
  240. package/vue/UiSeparator.d.ts +2 -2
  241. package/vue/UiSeparator.vue +22 -27
  242. package/vue/UiSidebar.d.ts +20 -18
  243. package/vue/UiSidebar.vue +312 -224
  244. package/vue/UiStack.d.ts +3 -3
  245. package/vue/UiStack.vue +64 -70
  246. package/vue/UiSwitch.d.ts +12 -8
  247. package/vue/UiSwitch.vue +218 -150
  248. package/vue/UiSwitcher.d.ts +3 -3
  249. package/vue/UiSwitcher.vue +73 -75
  250. package/vue/UiTabs.d.ts +10 -8
  251. package/vue/UiTabs.vue +251 -210
  252. package/vue/UiTextarea.d.ts +11 -11
  253. package/vue/UiTextarea.vue +155 -128
  254. package/vue/UiToastRegion.d.ts +10 -8
  255. package/vue/UiToastRegion.vue +261 -198
  256. package/vue/UiTooltip.d.ts +14 -12
  257. package/vue/UiTooltip.vue +241 -177
  258. package/vue/UiTopBar.vue +51 -42
  259. package/vue/UiTree.d.ts +8 -6
  260. package/vue/UiTree.vue +157 -70
  261. package/vue/UiTreeItem.d.ts +24 -22
  262. package/vue/UiTreeItem.vue +456 -339
  263. package/vue/chunks/UiAffordanceScope.js +9 -16
  264. package/vue/chunks/UiAvatar.js +23 -29
  265. package/vue/chunks/UiAvatarGroup.js +16 -39
  266. package/vue/chunks/UiBadge.js +3 -12
  267. package/vue/chunks/UiButton.js +15 -18
  268. package/vue/chunks/UiCallout.js +8 -17
  269. package/vue/chunks/UiCheckbox.js +37 -40
  270. package/vue/chunks/UiCluster.js +3 -12
  271. package/vue/chunks/UiCombobox.js +224 -266
  272. package/vue/chunks/UiContainer.js +3 -12
  273. package/vue/chunks/UiContextMenu.js +39 -34
  274. package/vue/chunks/UiDialog.js +36 -39
  275. package/vue/chunks/UiDisclosure.js +43 -48
  276. package/vue/chunks/UiEditable.js +55 -57
  277. package/vue/chunks/UiEditorInsertTableGrid.js +55 -73
  278. package/vue/chunks/UiEditorMentionMenu.js +40 -81
  279. package/vue/chunks/UiEditorSlashMenu.js +28 -52
  280. package/vue/chunks/UiEditorTableContextMenu.js +32 -56
  281. package/vue/chunks/UiEditorTableOverlay.js +58 -82
  282. package/vue/chunks/UiEditorTableToolbar.js +61 -85
  283. package/vue/chunks/UiEditorToolbar.js +4 -13
  284. package/vue/chunks/UiFloatingActionButton.js +7 -21
  285. package/vue/chunks/UiFormField.js +15 -12
  286. package/vue/chunks/UiGrid.js +3 -12
  287. package/vue/chunks/UiIcon.js +20 -43
  288. package/vue/chunks/UiIconButton.js +16 -28
  289. package/vue/chunks/UiInput.js +20 -25
  290. package/vue/chunks/UiMenu.js +29 -33
  291. package/vue/chunks/UiMenuItem.js +4 -10
  292. package/vue/chunks/UiPopover.js +28 -29
  293. package/vue/chunks/UiRadio.js +36 -39
  294. package/vue/chunks/UiRadioGroup.js +30 -34
  295. package/vue/chunks/UiReel.js +6 -15
  296. package/vue/chunks/UiSearchResultRow.js +6 -19
  297. package/vue/chunks/UiSearchShell.js +25 -28
  298. package/vue/chunks/UiSelect.js +20 -23
  299. package/vue/chunks/UiSeparator.js +2 -8
  300. package/vue/chunks/UiSidebar.js +39 -44
  301. package/vue/chunks/UiStack.js +6 -15
  302. package/vue/chunks/UiSwitch.js +35 -38
  303. package/vue/chunks/UiSwitcher.js +6 -15
  304. package/vue/chunks/UiTabs.js +47 -85
  305. package/vue/chunks/UiTextarea.js +21 -26
  306. package/vue/chunks/UiToastRegion.js +38 -72
  307. package/vue/chunks/UiTooltip.js +34 -35
  308. package/vue/chunks/UiTopBar.js +1 -1
  309. package/vue/chunks/UiTree.js +20 -15
  310. package/vue/chunks/UiTreeItem.js +85 -102
  311. package/vue/components.css +3994 -3764
  312. package/vue/index.d.ts +1 -0
  313. package/vue/index.js +2 -1
@@ -1,339 +1,514 @@
1
- <!-- Generated by HTML Next 1.0.0-alpha.1 for Vue 3.5. Do not edit. -->
1
+ <!-- Generated by HTML Next 1.0.0-alpha.2 for Vue 3.5. Do not edit. -->
2
2
  <script setup lang="ts">
3
- import { computed, onBeforeUnmount, onMounted, ref, shallowRef, watchEffect } from "vue";
4
- import UiIcon from "./UiIcon.vue";
5
- import * as controllerModule from "../components/ui-editor-table-toolbar/ui-editor-table-toolbar.js";
6
-
7
- defineOptions({ inheritAttrs: false });
8
-
9
- const hn = {
10
- t: (v: unknown): boolean => v === true || (typeof v === "string" ? v.length > 0 : typeof v === "number" ? v !== 0 && v === v : Array.isArray(v) ? v.length > 0 : v !== null && typeof v === "object" ? Object.keys(v).length > 0 : false),
11
- text: (v: unknown): string => v === undefined || v === null ? "" : Array.isArray(v) ? v.map(hn.text).join(" ") : typeof v === "object" ? "" : String(v),
12
- attr: (v: unknown): any => v === undefined || v === null || v === false ? undefined : v === true ? "" : Array.isArray(v) ? v.map(hn.text).join(" ") : typeof v === "object" ? undefined : String(v),
13
- enumerated: (v: unknown): any => typeof v === "boolean" ? String(v) : hn.attr(v),
14
- shape: (items: unknown, where: ((item: any) => unknown) | undefined, sort: readonly string[], limit: unknown): any[] => {
15
- let list = Array.isArray(items) ? items.slice() : [];
16
- if (where !== undefined) list = list.filter((item) => hn.t(where(item)));
17
- if (sort.length > 0) {
18
- const field = (item: unknown, path: string): unknown => item !== null && typeof item === "object" && !Array.isArray(item)
19
- ? path.split(".").reduce<unknown>((value, key) => (value as Record<string, unknown> | undefined)?.[key], item)
20
- : item;
21
- const compare = (a: unknown, b: unknown): number => typeof a === "number" && typeof b === "number" ? a - b : hn.text(a).localeCompare(hn.text(b));
22
- list.sort((a, b) => {
23
- for (const key of sort) {
24
- const descending = key.startsWith("-");
25
- const order = compare(field(a, descending ? key.slice(1) : key), field(b, descending ? key.slice(1) : key));
26
- if (order !== 0) return descending ? -order : order;
27
- }
28
- return 0;
29
- });
30
- }
31
- return typeof limit === "number" ? list.slice(0, Math.max(0, Math.trunc(limit))) : list;
3
+ import { computed, onBeforeUnmount, onMounted, ref, shallowRef, watchEffect } from 'vue'
4
+ import * as controllerModule from '../components/ui-editor-table-toolbar/ui-editor-table-toolbar.js'
5
+ import UiIcon from './UiIcon.vue'
6
+
7
+ defineOptions({ inheritAttrs: false })
8
+
9
+ const props = withDefaults(
10
+ defineProps<{
11
+ actions?:
12
+ readonly (
13
+ | 'align-left'
14
+ | 'align-center'
15
+ | 'align-right'
16
+ | 'background-none'
17
+ | 'background-gray'
18
+ | 'background-yellow'
19
+ | 'background-blue'
20
+ | 'background-green'
21
+ | 'background-red'
22
+ | 'add-row-before'
23
+ | 'add-row-after'
24
+ | 'add-column-before'
25
+ | 'add-column-after'
26
+ | 'clear-cells'
27
+ | 'merge-cells'
28
+ | 'split-cell'
29
+ | 'delete-row'
30
+ | 'delete-column'
31
+ | 'delete-table'
32
+ )[]
33
+ cellAlignment?: 'left' | 'center' | 'right'
34
+ cellBackground?: string
35
+ open?: boolean
36
+ }>(),
37
+ {
38
+ cellAlignment: 'left',
39
+ cellBackground: '',
40
+ open: false,
32
41
  },
33
- };
34
-
35
- const props = withDefaults(defineProps<{
36
- actions?: readonly ("align-left" | "align-center" | "align-right" | "background-none" | "background-gray" | "background-yellow" | "background-blue" | "background-green" | "background-red" | "add-row-before" | "add-row-after" | "add-column-before" | "add-column-after" | "clear-cells" | "merge-cells" | "split-cell" | "delete-row" | "delete-column" | "delete-table")[] | null;
37
- cellAlignment?: "left" | "center" | "right" | null;
38
- cellBackground?: string | null;
39
- open?: boolean | null;
40
- }>(), {
41
- cellAlignment: "left",
42
- cellBackground: "",
43
- open: false,
44
- });
42
+ )
45
43
  const emit = defineEmits<{
46
- "action": [detail: { readonly action: "align-left" | "align-center" | "align-right" | "background-none" | "background-gray" | "background-yellow" | "background-blue" | "background-green" | "background-red" | "add-row-before" | "add-row-after" | "add-column-before" | "add-column-after" | "clear-cells" | "merge-cells" | "split-cell" | "delete-row" | "delete-column" | "delete-table" }];
47
- }>();
48
- const root = ref<HTMLElement | null>(null);
49
- const refs: Record<string, Element | undefined> = {};
50
- const state_alignments = ref<any>([]);
51
- const state_structure = ref<any>([]);
52
- const state_swatches = ref<any>([]);
53
- const state_sections = ref<any>([]);
54
- const state_hasOverflow = ref<any>(false);
55
- const state_overflowOpen = ref<any>(false);
44
+ action: [
45
+ detail: {
46
+ readonly action:
47
+ | 'align-left'
48
+ | 'align-center'
49
+ | 'align-right'
50
+ | 'background-none'
51
+ | 'background-gray'
52
+ | 'background-yellow'
53
+ | 'background-blue'
54
+ | 'background-green'
55
+ | 'background-red'
56
+ | 'add-row-before'
57
+ | 'add-row-after'
58
+ | 'add-column-before'
59
+ | 'add-column-after'
60
+ | 'clear-cells'
61
+ | 'merge-cells'
62
+ | 'split-cell'
63
+ | 'delete-row'
64
+ | 'delete-column'
65
+ | 'delete-table'
66
+ },
67
+ ]
68
+ }>()
69
+
70
+ const root = ref<HTMLElement | null>(null)
71
+ const alignments = ref<
72
+ { action: 'align-left' | 'align-center' | 'align-right'; label: string; active: boolean }[]
73
+ >([])
74
+ const structure = ref<
75
+ { action: 'add-row-after' | 'add-column-after'; label: string; icon: string }[]
76
+ >([])
77
+ const swatches = ref<{ action: string; label: string; color: string; selected: boolean }[]>([])
78
+ const sections = ref<
79
+ { heading: string; items: { action: string; label: string; icon: string; danger: boolean }[] }[]
80
+ >([])
81
+ const hasOverflow = ref(false)
82
+ const overflowOpen = ref(false)
56
83
 
57
84
  /** Dispatches a component event to Vue listeners and, for controllers and page code, on the root. */
58
- const dispatch = (name: string, detail?: unknown): boolean => {
59
- const declared = {"action":{"bubbles":true,"composed":true,"cancelable":false}} as Record<string, EventInit | undefined>;
85
+ function dispatch(name: string, detail?: unknown): boolean {
86
+ const declared: Record<string, EventInit | undefined> = {
87
+ action: { bubbles: true, composed: true, cancelable: false },
88
+ }
60
89
  const checks: Record<string, (detail: unknown) => boolean> = {
61
- "action": (detail: unknown) => (detail !== null && typeof detail === "object" && !Array.isArray(detail) && ((detail as Record<string, unknown>)["action"] === "align-left" || (detail as Record<string, unknown>)["action"] === "align-center" || (detail as Record<string, unknown>)["action"] === "align-right" || (detail as Record<string, unknown>)["action"] === "background-none" || (detail as Record<string, unknown>)["action"] === "background-gray" || (detail as Record<string, unknown>)["action"] === "background-yellow" || (detail as Record<string, unknown>)["action"] === "background-blue" || (detail as Record<string, unknown>)["action"] === "background-green" || (detail as Record<string, unknown>)["action"] === "background-red" || (detail as Record<string, unknown>)["action"] === "add-row-before" || (detail as Record<string, unknown>)["action"] === "add-row-after" || (detail as Record<string, unknown>)["action"] === "add-column-before" || (detail as Record<string, unknown>)["action"] === "add-column-after" || (detail as Record<string, unknown>)["action"] === "clear-cells" || (detail as Record<string, unknown>)["action"] === "merge-cells" || (detail as Record<string, unknown>)["action"] === "split-cell" || (detail as Record<string, unknown>)["action"] === "delete-row" || (detail as Record<string, unknown>)["action"] === "delete-column" || (detail as Record<string, unknown>)["action"] === "delete-table") && Object.keys(detail as object).every((key) => ["action"].includes(key))),
62
- };
90
+ action: (detail) =>
91
+ detail !== null && typeof detail === 'object' && !Array.isArray(detail)
92
+ && ((detail as Record<string, unknown>)['action'] === 'align-left'
93
+ || (detail as Record<string, unknown>)['action'] === 'align-center'
94
+ || (detail as Record<string, unknown>)['action'] === 'align-right'
95
+ || (detail as Record<string, unknown>)['action'] === 'background-none'
96
+ || (detail as Record<string, unknown>)['action'] === 'background-gray'
97
+ || (detail as Record<string, unknown>)['action'] === 'background-yellow'
98
+ || (detail as Record<string, unknown>)['action'] === 'background-blue'
99
+ || (detail as Record<string, unknown>)['action'] === 'background-green'
100
+ || (detail as Record<string, unknown>)['action'] === 'background-red'
101
+ || (detail as Record<string, unknown>)['action'] === 'add-row-before'
102
+ || (detail as Record<string, unknown>)['action'] === 'add-row-after'
103
+ || (detail as Record<string, unknown>)['action'] === 'add-column-before'
104
+ || (detail as Record<string, unknown>)['action'] === 'add-column-after'
105
+ || (detail as Record<string, unknown>)['action'] === 'clear-cells'
106
+ || (detail as Record<string, unknown>)['action'] === 'merge-cells'
107
+ || (detail as Record<string, unknown>)['action'] === 'split-cell'
108
+ || (detail as Record<string, unknown>)['action'] === 'delete-row'
109
+ || (detail as Record<string, unknown>)['action'] === 'delete-column'
110
+ || (detail as Record<string, unknown>)['action'] === 'delete-table')
111
+ && Object.keys(detail as object).every((key) => ['action'].includes(key)),
112
+ }
63
113
  if (detail !== undefined && checks[name] !== undefined && !checks[name]!(detail)) {
64
- throw new TypeError(`HR002: Event \`${name}\` detail does not satisfy its declared type.`);
114
+ throw new TypeError(`HR002: Event \`${name}\` detail does not satisfy its declared type.`)
65
115
  }
66
- (emit as (name: string, detail: unknown) => void)(name, detail);
67
- return root.value?.dispatchEvent(new CustomEvent(name, { bubbles: true, composed: true, ...declared[name], detail })) ?? true;
68
- };
116
+ const emitEvent = emit as (name: string, detail: unknown) => void
117
+ emitEvent(name, detail)
118
+ return root.value?.dispatchEvent(
119
+ new CustomEvent(name, { bubbles: true, composed: true, ...declared[name], detail }),
120
+ ) ?? true
121
+ }
69
122
 
70
123
  function read(name: string): unknown {
71
- if (name === "alignments") return state_alignments.value;
72
- if (name === "structure") return state_structure.value;
73
- if (name === "swatches") return state_swatches.value;
74
- if (name === "sections") return state_sections.value;
75
- if (name === "hasOverflow") return state_hasOverflow.value;
76
- if (name === "overflowOpen") return state_overflowOpen.value;
77
- return (props as Record<string, unknown>)[name];
124
+ if (name === 'alignments') return alignments.value
125
+ if (name === 'structure') return structure.value
126
+ if (name === 'swatches') return swatches.value
127
+ if (name === 'sections') return sections.value
128
+ if (name === 'hasOverflow') return hasOverflow.value
129
+ if (name === 'overflowOpen') return overflowOpen.value
130
+ return (props as Record<string, unknown>)[name]
78
131
  }
79
132
 
80
133
  function write(name: string, value: unknown): boolean {
81
- if (name === "alignments") { state_alignments.value = value; return true; }
82
- if (name === "structure") { state_structure.value = value; return true; }
83
- if (name === "swatches") { state_swatches.value = value; return true; }
84
- if (name === "sections") { state_sections.value = value; return true; }
85
- if (name === "hasOverflow") { state_hasOverflow.value = value; return true; }
86
- if (name === "overflowOpen") { state_overflowOpen.value = value; return true; }
87
- throw new TypeError(`Only declared state is writable; \`${name}\` is not.`);
134
+ if (name === 'alignments') {
135
+ alignments.value = value as never
136
+ return true
137
+ }
138
+ if (name === 'structure') {
139
+ structure.value = value as never
140
+ return true
141
+ }
142
+ if (name === 'swatches') {
143
+ swatches.value = value as never
144
+ return true
145
+ }
146
+ if (name === 'sections') {
147
+ sections.value = value as never
148
+ return true
149
+ }
150
+ if (name === 'hasOverflow') {
151
+ hasOverflow.value = value as never
152
+ return true
153
+ }
154
+ if (name === 'overflowOpen') {
155
+ overflowOpen.value = value as never
156
+ return true
157
+ }
158
+ throw new TypeError(`Only declared state is writable; \`${name}\` is not.`)
88
159
  }
89
160
 
90
- const stops: Array<() => void> = [];
161
+ const stops: Array<() => void> = []
91
162
  const host = {
92
- get element(): Element { return root.value as Element; },
163
+ get element(): Element {
164
+ return root.value as Element
165
+ },
93
166
  state: new Proxy({} as Record<string, unknown>, {
94
- get: (_target, name) => typeof name === "string" ? read(name) : undefined,
95
- set: (_target, name, value) => typeof name === "string" && write(name, value),
167
+ get: (_target, name) => typeof name === 'string' ? read(name) : undefined,
168
+ set: (_target, name, value) => typeof name === 'string' && write(name, value),
96
169
  }),
97
- refs: refs as Readonly<Record<string, Element>>,
170
+ refs: {} as Readonly<Record<string, Element>>,
98
171
  elements: new Proxy({} as Record<string, Element | RadioNodeList | undefined>, {
99
172
  get: (_target, name) => {
100
- if (typeof name !== "string" || root.value === null) return undefined;
101
- const form = root.value instanceof HTMLFormElement ? root.value : root.value.querySelector("form");
102
- return form?.elements.namedItem(name) ?? root.value.querySelector(`[name="${CSS.escape(name)}"]`) ?? undefined;
173
+ if (typeof name !== 'string' || root.value === null) return undefined
174
+ const form = root.value instanceof HTMLFormElement
175
+ ? root.value
176
+ : root.value.querySelector('form')
177
+ return form?.elements.namedItem(name)
178
+ ?? root.value.querySelector(`[name="${CSS.escape(name)}"]`) ?? undefined
103
179
  },
104
180
  }),
105
181
  signal<T>(initialValue: T) {
106
- const value = shallowRef(initialValue);
182
+ const value = shallowRef(initialValue)
107
183
  return {
108
184
  get: (): T => value.value,
109
- set: (next: T): void => { if (!Object.is(value.value, next)) value.value = next; },
110
- update: (next: (current: T) => T): void => { const updated = next(value.value); if (!Object.is(value.value, updated)) value.value = updated; },
111
- };
185
+ set: (next: T): void => {
186
+ if (!Object.is(value.value, next)) value.value = next
187
+ },
188
+ update: (next: (current: T) => T): void => {
189
+ const updated = next(value.value)
190
+ if (!Object.is(value.value, updated)) value.value = updated
191
+ },
192
+ }
112
193
  },
113
194
  computed<T>(compute: () => T) {
114
- const value = computed(compute);
115
- return { get: (): T => value.value };
195
+ const value = computed(compute)
196
+ return { get: (): T => value.value }
116
197
  },
117
198
  effect(run: () => void | (() => void)): () => void {
118
199
  const stop = watchEffect((onCleanup) => {
119
- const cleanup = run();
120
- if (typeof cleanup === "function") onCleanup(cleanup);
121
- }, { flush: "post" });
122
- stops.push(stop);
123
- return stop;
200
+ const cleanup = run()
201
+ if (typeof cleanup === 'function') onCleanup(cleanup)
202
+ }, { flush: 'post' })
203
+ stops.push(stop)
204
+ return stop
124
205
  },
125
206
  on(event: string, listener: EventListener): () => void {
126
- const element = root.value;
127
- element?.addEventListener(event, listener);
128
- const off = (): void => element?.removeEventListener(event, listener);
129
- stops.push(off);
130
- return off;
207
+ const element = root.value
208
+ element?.addEventListener(event, listener)
209
+ const off = (): void => element?.removeEventListener(event, listener)
210
+ stops.push(off)
211
+ return off
131
212
  },
132
213
  dispatch,
133
- };
214
+ }
134
215
 
135
- let cleanup: void | (() => void);
136
- let ready: Promise<void> | undefined;
216
+ let cleanup: void | (() => void)
217
+ let ready: Promise<void> | undefined
137
218
  onMounted(() => {
138
- ready = Promise.resolve(controllerModule.default(host as never)).then((result) => { cleanup = result; });
139
- });
219
+ ready = Promise.resolve(controllerModule.default(host as never)).then((result) => {
220
+ cleanup = result
221
+ })
222
+ })
140
223
  onBeforeUnmount(() => {
141
- for (const stop of stops.splice(0)) stop();
142
- if (typeof cleanup === "function") cleanup();
143
- });
224
+ for (const stop of stops.splice(0)) stop()
225
+ if (typeof cleanup === 'function') cleanup()
226
+ })
144
227
  </script>
145
228
 
146
229
  <template>
147
- <div data-component="ui-editor-table-toolbar" role="toolbar" aria-label="Table actions" v-bind="$attrs" :hidden="hn.attr(!hn.t(props.open))" ref="root"><template v-if="hn.t(state_alignments)"><div class="group" role="group" aria-label="Cell alignment"><template v-for="(item, index) in hn.shape(state_alignments, undefined, [], undefined)" :key="(item)?.action"><button type="button" class="icon-button" :data-action="hn.attr((item)?.action)" :aria-label="hn.enumerated((item)?.label)" :title="hn.attr((item)?.label)" :aria-pressed="hn.enumerated((item)?.active)" :class="{ 'active': hn.t((item)?.active) }"><UiIcon :name="(item)?.action"></UiIcon></button></template></div></template><template v-if="hn.t((hn.t(state_alignments) && hn.t(state_structure)))"><div class="sep" aria-hidden="true"></div></template><template v-if="hn.t(state_structure)"><div class="group" role="group" aria-label="Table structure"><template v-for="(item, index) in hn.shape(state_structure, undefined, [], undefined)" :key="(item)?.action"><button type="button" :data-action="hn.attr((item)?.action)"><UiIcon :name="(item)?.icon"></UiIcon><span>{{ hn.text((item)?.label) }}</span></button></template></div></template><template v-if="hn.t((hn.t((hn.t(state_alignments) || hn.t(state_structure))) && hn.t(state_hasOverflow)))"><div class="sep" aria-hidden="true"></div></template><template v-if="hn.t(state_hasOverflow)"><div class="overflow"><button type="button" class="more" data-action="toggle-overflow" aria-haspopup="menu" :aria-expanded="hn.enumerated(state_overflowOpen)"><UiIcon name="table"></UiIcon><span>Table options</span><span class="chevron"><UiIcon name="chevron-down"></UiIcon></span></button><template v-if="hn.t(state_overflowOpen)"><div class="menu" role="menu" aria-label="More table actions"><template v-if="hn.t(state_swatches)"><div class="menu-section" role="none"><div class="menu-heading" role="presentation">Background</div><div class="swatches" role="group" aria-label="Cell background"><template v-for="(swatch, index) in hn.shape(state_swatches, undefined, [], undefined)" :key="(swatch)?.action"><button type="button" class="swatch-button" role="menuitemradio" :aria-checked="hn.enumerated((swatch)?.selected)" :data-action="hn.attr((swatch)?.action)" :class="{ 'selected': hn.t((swatch)?.selected) }"><span class="swatch" :class="{ 'default': hn.t(!hn.t((swatch)?.color)) }" :style="{ '--ui-editor-table-toolbar-swatch': hn.text((swatch)?.color) }"></span><span>{{ hn.text((swatch)?.label) }}</span></button></template></div></div></template><template v-for="(section, index) in hn.shape(state_sections, undefined, [], undefined)" :key="(section)?.heading"><div class="menu-section divided" role="none"><div class="menu-heading" role="presentation">{{ hn.text((section)?.heading) }}</div><template v-for="(item, index) in hn.shape((section)?.items, undefined, [], undefined)" :key="(item)?.action"><button type="button" role="menuitem" :data-action="hn.attr((item)?.action)" :class="{ 'danger': hn.t((item)?.danger) }"><UiIcon :name="(item)?.icon"></UiIcon><span>{{ hn.text((item)?.label) }}</span></button></template></div></template></div></template></div></template></div>
230
+ <div
231
+ data-component="ui-editor-table-toolbar"
232
+ role="toolbar"
233
+ aria-label="Table actions"
234
+ v-bind="$attrs"
235
+ :hidden="!open"
236
+ ref="root"
237
+ >
238
+ <div v-if="alignments.length" class="group" role="group" aria-label="Cell alignment">
239
+ <button
240
+ v-for="item in alignments"
241
+ :key="item.action"
242
+ type="button"
243
+ class="icon-button"
244
+ :data-action="item.action"
245
+ :aria-label="item.label"
246
+ :title="item.label"
247
+ :aria-pressed="item.active"
248
+ :class="{ active: item.active }"
249
+ >
250
+ <UiIcon :name="item.action" />
251
+ </button>
252
+ </div>
253
+ <div v-if="alignments.length && structure.length" class="sep" aria-hidden="true"></div>
254
+ <div v-if="structure.length" class="group" role="group" aria-label="Table structure">
255
+ <button v-for="item in structure" :key="item.action" type="button" :data-action="item.action">
256
+ <UiIcon :name="item.icon" />
257
+ <span>{{ item.label }}</span>
258
+ </button>
259
+ </div>
260
+ <div
261
+ v-if="(alignments.length || structure.length) && hasOverflow"
262
+ class="sep"
263
+ aria-hidden="true"
264
+ >
265
+ </div>
266
+ <div v-if="hasOverflow" class="overflow">
267
+ <button
268
+ type="button"
269
+ class="more"
270
+ data-action="toggle-overflow"
271
+ aria-haspopup="menu"
272
+ :aria-expanded="overflowOpen"
273
+ >
274
+ <UiIcon name="table" />
275
+ <span>Table options</span>
276
+ <span class="chevron"><UiIcon name="chevron-down" /></span>
277
+ </button>
278
+ <div v-if="overflowOpen" class="menu" role="menu" aria-label="More table actions">
279
+ <div v-if="swatches.length" class="menu-section" role="none">
280
+ <div class="menu-heading" role="presentation">Background</div>
281
+ <div class="swatches" role="group" aria-label="Cell background">
282
+ <button
283
+ v-for="swatch in swatches"
284
+ :key="swatch.action"
285
+ type="button"
286
+ class="swatch-button"
287
+ role="menuitemradio"
288
+ :aria-checked="swatch.selected"
289
+ :data-action="swatch.action"
290
+ :class="{ selected: swatch.selected }"
291
+ >
292
+ <span
293
+ class="swatch"
294
+ :class="{ default: !swatch.color }"
295
+ :style="{ '--ui-editor-table-toolbar-swatch': swatch.color }"
296
+ ></span>
297
+ <span>{{ swatch.label }}</span>
298
+ </button>
299
+ </div>
300
+ </div>
301
+ <div
302
+ v-for="section in sections"
303
+ :key="section.heading"
304
+ class="menu-section divided"
305
+ role="none"
306
+ >
307
+ <div class="menu-heading" role="presentation">{{ section.heading }}</div>
308
+ <button
309
+ v-for="item in section.items"
310
+ :key="item.action"
311
+ type="button"
312
+ role="menuitem"
313
+ :data-action="item.action"
314
+ :class="{ danger: item.danger }"
315
+ >
316
+ <UiIcon :name="item.icon" />
317
+ <span>{{ item.label }}</span>
318
+ </button>
319
+ </div>
320
+ </div>
321
+ </div>
322
+ </div>
148
323
  </template>
149
324
 
150
325
  <style scoped>
151
326
  .looma-editor__mobile-toolbar-shell [data-component~="ui-editor-table-toolbar"] {
152
- min-width: max-content;
153
- min-height: 100%;
154
- padding: 0;
155
- background: transparent;
156
- border: 0;
157
- border-radius: 0;
158
- box-shadow: none;
159
- backdrop-filter: none;
160
- }
327
+ min-width: max-content;
328
+ min-height: 100%;
329
+ padding: 0;
330
+ background: transparent;
331
+ border: 0;
332
+ border-radius: 0;
333
+ box-shadow: none;
334
+ backdrop-filter: none;
335
+ }
161
336
 
162
- .looma-editor__mobile-toolbar-shell [data-component~="ui-editor-table-toolbar"] button {
163
- min-height: 44px;
164
- background: transparent;
165
- }
337
+ .looma-editor__mobile-toolbar-shell [data-component~="ui-editor-table-toolbar"] button {
338
+ min-height: 44px;
339
+ background: transparent;
340
+ }
166
341
 
167
- .looma-editor__mobile-toolbar-shell [data-component~="ui-editor-table-toolbar"] button.active,
168
- .looma-editor__mobile-toolbar-shell [data-component~="ui-editor-table-toolbar"] button.selected {
169
- background: var(--ui-accent-soft, var(--ui-accent-subtle, #e8f0fb));
170
- }
342
+ .looma-editor__mobile-toolbar-shell [data-component~="ui-editor-table-toolbar"] button.active,
343
+ .looma-editor__mobile-toolbar-shell [data-component~="ui-editor-table-toolbar"] button.selected {
344
+ background: var(--ui-accent-soft, var(--ui-accent-subtle, #e8f0fb));
345
+ }
171
346
 
172
- .looma-editor__mobile-toolbar-shell [data-component~="ui-editor-table-toolbar"] .menu {
173
- top: auto;
174
- right: 0;
175
- bottom: calc(100% + var(--ui-space-2, 8px));
176
- max-height: min(50dvh, 22rem);
177
- overflow-y: auto;
178
- overscroll-behavior: contain;
179
- }
180
- [data-component~="ui-editor-table-toolbar"] {
181
- display: inline-flex;
182
- align-items: center;
183
- gap: var(--ui-space-1, 4px);
184
- padding: var(--ui-space-1, 4px);
185
- background: color-mix(in srgb, var(--ui-surface, #fff) 94%, transparent);
186
- border: 1px solid var(--ui-border, #e5e7eb);
187
- border-radius: calc(var(--ui-radius-md, 6px) + 2px);
188
- box-shadow: var(--ui-shadow-lg, 0 10px 15px -3px rgb(0 0 0 / 0.1));
189
- backdrop-filter: blur(10px);
190
- }
347
+ .looma-editor__mobile-toolbar-shell [data-component~="ui-editor-table-toolbar"] .menu {
348
+ top: auto;
349
+ right: 0;
350
+ bottom: calc(100% + var(--ui-space-2, 8px));
351
+ max-height: min(50dvh, 22rem);
352
+ overflow-y: auto;
353
+ overscroll-behavior: contain;
354
+ }
355
+ [data-component~="ui-editor-table-toolbar"] {
356
+ display: inline-flex;
357
+ align-items: center;
358
+ gap: var(--ui-space-1, 4px);
359
+ padding: var(--ui-space-1, 4px);
360
+ background: color-mix(in srgb, var(--ui-surface, #fff) 94%, transparent);
361
+ border: 1px solid var(--ui-border, #e5e7eb);
362
+ border-radius: calc(var(--ui-radius-md, 6px) + 2px);
363
+ box-shadow: var(--ui-shadow-lg, 0 10px 15px -3px rgb(0 0 0 / 0.1));
364
+ backdrop-filter: blur(10px);
365
+ }
191
366
 
192
- .group {
193
- display: inline-flex;
194
- align-items: center;
195
- gap: 2px;
196
- overflow: hidden;
197
- }
367
+ .group {
368
+ display: inline-flex;
369
+ align-items: center;
370
+ gap: 2px;
371
+ overflow: hidden;
372
+ }
198
373
 
199
- .sep {
200
- width: 1px;
201
- align-self: stretch;
202
- background: var(--ui-border, #e5e7eb);
203
- }
374
+ .sep {
375
+ width: 1px;
376
+ align-self: stretch;
377
+ background: var(--ui-border, #e5e7eb);
378
+ }
204
379
 
205
- .overflow {
206
- position: relative;
207
- }
380
+ .overflow {
381
+ position: relative;
382
+ }
208
383
 
209
- [data-component~="ui-editor-table-toolbar"] button {
210
- display: inline-flex;
211
- align-items: center;
212
- justify-content: center;
213
- gap: var(--ui-space-1-5, 6px);
214
- min-height: 32px;
215
- border: 0;
216
- border-radius: var(--ui-radius-sm, 4px);
217
- background: transparent;
218
- color: var(--ui-text-primary, #111827);
219
- cursor: pointer;
220
- font-size: var(--ui-text-sm, 0.875rem);
221
- font-weight: 500;
222
- line-height: 1;
223
- padding: var(--ui-space-1-5, 6px) var(--ui-space-2, 8px);
224
- white-space: nowrap;
225
- }
384
+ [data-component~="ui-editor-table-toolbar"] button {
385
+ display: inline-flex;
386
+ align-items: center;
387
+ justify-content: center;
388
+ gap: var(--ui-space-1-5, 6px);
389
+ min-height: 32px;
390
+ border: 0;
391
+ border-radius: var(--ui-radius-sm, 4px);
392
+ background: transparent;
393
+ color: var(--ui-text-primary, #111827);
394
+ cursor: pointer;
395
+ font-size: var(--ui-text-sm, 0.875rem);
396
+ font-weight: 500;
397
+ line-height: 1;
398
+ padding: var(--ui-space-1-5, 6px) var(--ui-space-2, 8px);
399
+ white-space: nowrap;
400
+ }
226
401
 
227
- [data-component~="ui-editor-table-toolbar"] button:hover {
228
- background: var(--ui-surface-hover, #f3f4f6);
229
- }
402
+ [data-component~="ui-editor-table-toolbar"] button:hover {
403
+ background: var(--ui-surface-hover, #f3f4f6);
404
+ }
230
405
 
231
- [data-component~="ui-editor-table-toolbar"] button.active {
232
- background: var(--ui-accent-soft, var(--ui-accent-subtle, #e8f0fb));
233
- color: var(--ui-accent-active, #003d7a);
234
- }
406
+ [data-component~="ui-editor-table-toolbar"] button.active {
407
+ background: var(--ui-accent-soft, var(--ui-accent-subtle, #e8f0fb));
408
+ color: var(--ui-accent-active, #003d7a);
409
+ }
235
410
 
236
- .group button {
237
- border-radius: var(--ui-radius-sm, 4px);
238
- }
411
+ .group button {
412
+ border-radius: var(--ui-radius-sm, 4px);
413
+ }
239
414
 
240
- .group button + button {
241
- border-left: 0;
242
- }
415
+ .group button + button {
416
+ border-left: 0;
417
+ }
243
418
 
244
- [data-component~="ui-editor-table-toolbar"] .more {
245
- border: 0;
246
- border-radius: var(--ui-radius-sm, 4px);
247
- }
419
+ [data-component~="ui-editor-table-toolbar"] .more {
420
+ border: 0;
421
+ border-radius: var(--ui-radius-sm, 4px);
422
+ }
248
423
 
249
- [data-component~="ui-editor-table-toolbar"] button.danger {
250
- color: var(--ui-danger, #dc2626);
251
- }
424
+ [data-component~="ui-editor-table-toolbar"] button.danger {
425
+ color: var(--ui-danger, #dc2626);
426
+ }
252
427
 
253
- [data-component~="ui-editor-table-toolbar"] {
254
- --ui-icon-size: var(--ui-editor-toolbar-icon-size, 1rem);
255
- --ui-icon-stroke-width: var(--ui-editor-toolbar-icon-stroke-width, 1.75);
256
- }
428
+ [data-component~="ui-editor-table-toolbar"] {
429
+ --ui-icon-size: var(--ui-editor-toolbar-icon-size, 1rem);
430
+ --ui-icon-stroke-width: var(--ui-editor-toolbar-icon-stroke-width, 1.75);
431
+ }
257
432
 
258
- .chevron {
259
- display: inline-flex;
260
- --ui-icon-size: 0.875rem;
261
- }
433
+ .chevron {
434
+ display: inline-flex;
435
+ --ui-icon-size: 0.875rem;
436
+ }
262
437
 
263
- [data-component~="ui-editor-table-toolbar"] .icon-button {
264
- width: 32px;
265
- padding-inline: 0;
266
- }
438
+ [data-component~="ui-editor-table-toolbar"] .icon-button {
439
+ width: 32px;
440
+ padding-inline: 0;
441
+ }
267
442
 
268
- .menu {
269
- position: absolute;
270
- top: calc(100% + var(--ui-space-2, 8px));
271
- right: 0;
272
- min-width: 12rem;
273
- padding: var(--ui-space-1, 4px);
274
- background: var(--ui-surface, #fff);
275
- border: 1px solid var(--ui-border, #e5e7eb);
276
- border-radius: var(--ui-radius-md, 6px);
277
- box-shadow: var(--ui-shadow-lg, 0 10px 15px -3px rgb(0 0 0 / 0.1));
278
- display: flex;
279
- flex-direction: column;
280
- gap: 2px;
281
- z-index: 2;
282
- }
443
+ .menu {
444
+ position: absolute;
445
+ top: calc(100% + var(--ui-space-2, 8px));
446
+ right: 0;
447
+ min-width: 12rem;
448
+ padding: var(--ui-space-1, 4px);
449
+ background: var(--ui-surface, #fff);
450
+ border: 1px solid var(--ui-border, #e5e7eb);
451
+ border-radius: var(--ui-radius-md, 6px);
452
+ box-shadow: var(--ui-shadow-lg, 0 10px 15px -3px rgb(0 0 0 / 0.1));
453
+ display: flex;
454
+ flex-direction: column;
455
+ gap: 2px;
456
+ z-index: 2;
457
+ }
283
458
 
284
- .menu-section + .menu-section {
285
- margin-top: var(--ui-space-1, 4px);
286
- padding-top: var(--ui-space-1, 4px);
287
- border-top: 1px solid color-mix(in srgb, var(--ui-border, #e5e7eb) 80%, transparent);
288
- }
459
+ .menu-section + .menu-section {
460
+ margin-top: var(--ui-space-1, 4px);
461
+ padding-top: var(--ui-space-1, 4px);
462
+ border-top: 1px solid color-mix(in srgb, var(--ui-border, #e5e7eb) 80%, transparent);
463
+ }
289
464
 
290
- .menu-heading {
291
- padding: var(--ui-space-1, 4px) var(--ui-space-2, 8px);
292
- font-size: 0.6875rem;
293
- font-weight: 700;
294
- letter-spacing: 0.05em;
295
- text-transform: uppercase;
296
- color: var(--ui-text-muted, #6b7280);
297
- }
465
+ .menu-heading {
466
+ padding: var(--ui-space-1, 4px) var(--ui-space-2, 8px);
467
+ font-size: 0.6875rem;
468
+ font-weight: 700;
469
+ letter-spacing: 0.05em;
470
+ text-transform: uppercase;
471
+ color: var(--ui-text-muted, #6b7280);
472
+ }
298
473
 
299
- .menu button {
300
- display: flex;
301
- justify-content: flex-start;
302
- width: 100%;
303
- text-align: left;
304
- }
474
+ .menu button {
475
+ display: flex;
476
+ justify-content: flex-start;
477
+ width: 100%;
478
+ text-align: left;
479
+ }
305
480
 
306
- .swatches {
307
- display: grid;
308
- grid-template-columns: repeat(3, minmax(0, 1fr));
309
- gap: 2px;
310
- }
481
+ .swatches {
482
+ display: grid;
483
+ grid-template-columns: repeat(3, minmax(0, 1fr));
484
+ gap: 2px;
485
+ }
311
486
 
312
- [data-component~="ui-editor-table-toolbar"] .swatch-button {
313
- gap: var(--ui-space-1, 4px);
314
- justify-content: flex-start;
315
- }
487
+ [data-component~="ui-editor-table-toolbar"] .swatch-button {
488
+ gap: var(--ui-space-1, 4px);
489
+ justify-content: flex-start;
490
+ }
316
491
 
317
- .swatch {
318
- width: 14px;
319
- height: 14px;
320
- flex: 0 0 14px;
321
- border: 1px solid color-mix(in srgb, var(--ui-border, #e5e7eb) 80%, #000);
322
- border-radius: 3px;
323
- background: var(--ui-editor-table-toolbar-swatch);
324
- }
492
+ .swatch {
493
+ width: 14px;
494
+ height: 14px;
495
+ flex: 0 0 14px;
496
+ border: 1px solid color-mix(in srgb, var(--ui-border, #e5e7eb) 80%, #000);
497
+ border-radius: 3px;
498
+ background: var(--ui-editor-table-toolbar-swatch);
499
+ }
325
500
 
326
- .swatch.default {
327
- background:
328
- linear-gradient(135deg, transparent 44%, var(--ui-danger, #dc2626) 46% 54%, transparent 56%),
329
- var(--ui-surface, #fff);
330
- }
501
+ .swatch.default {
502
+ background:
503
+ linear-gradient(135deg, transparent 44%, var(--ui-danger, #dc2626) 46% 54%, transparent 56%),
504
+ var(--ui-surface, #fff);
505
+ }
331
506
 
332
- .swatch-button.selected {
333
- background: var(--ui-accent-soft, var(--ui-accent-subtle, #e8f0fb));
334
- }
507
+ .swatch-button.selected {
508
+ background: var(--ui-accent-soft, var(--ui-accent-subtle, #e8f0fb));
509
+ }
335
510
 
336
- [data-component~="ui-editor-table-toolbar"][hidden] {
337
- display: none;
338
- }
511
+ [data-component~="ui-editor-table-toolbar"][hidden] {
512
+ display: none;
513
+ }
339
514
  </style>