@threadlabs/looma 0.18.6 → 0.19.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 (215) hide show
  1. package/components/ui-editor-table-overlay/ui-editor-table-overlay.html +34 -3
  2. package/components/ui-editor-table-overlay/ui-editor-table-overlay.js +55 -0
  3. package/components/ui-editor-table-toolbar/ui-editor-table-toolbar.html +7 -2
  4. package/components/ui-editor-table-toolbar/ui-editor-table-toolbar.js +29 -0
  5. package/dist/index.js +1 -1
  6. package/editor/chunks/extensions.js +24 -3
  7. package/editor/extensions/preset.d.ts +2 -0
  8. package/editor/extensions/table-commands.d.ts +1 -1
  9. package/editor/table-overlay.d.ts +8 -3
  10. package/package.json +2 -1
  11. package/styles/ui-editor-table-overlay.css +30 -0
  12. package/styles/ui-editor-table-toolbar.css +7 -2
  13. package/vanilla/UiEditorTableOverlay.d.ts +1 -1
  14. package/vanilla/UiEditorTableOverlay.js +9 -3
  15. package/vue/UiEditorTableOverlay.d.ts +8 -0
  16. package/vue/UiEditorTableOverlay.vue +45 -2
  17. package/vue/UiEditorTableToolbar.vue +7 -2
  18. package/vue/chunks/1c.js +106 -0
  19. package/vue/chunks/UiEditorTableOverlay.js +14 -4
  20. package/vue/chunks/UiEditorTableToolbar.js +1 -1
  21. package/vue/chunks/abnf.js +61 -0
  22. package/vue/chunks/accesslog.js +72 -0
  23. package/vue/chunks/actionscript.js +139 -0
  24. package/vue/chunks/ada.js +183 -0
  25. package/vue/chunks/angelscript.js +141 -0
  26. package/vue/chunks/apache.js +88 -0
  27. package/vue/chunks/applescript.js +99 -0
  28. package/vue/chunks/arcade.js +405 -0
  29. package/vue/chunks/arduino.js +871 -0
  30. package/vue/chunks/armasm.js +65 -0
  31. package/vue/chunks/asciidoc.js +181 -0
  32. package/vue/chunks/aspectj.js +202 -0
  33. package/vue/chunks/autohotkey.js +54 -0
  34. package/vue/chunks/autoit.js +132 -0
  35. package/vue/chunks/avrasm.js +46 -0
  36. package/vue/chunks/awk.js +58 -0
  37. package/vue/chunks/axapta.js +167 -0
  38. package/vue/chunks/bash.js +358 -0
  39. package/vue/chunks/basic.js +221 -0
  40. package/vue/chunks/bnf.js +27 -0
  41. package/vue/chunks/brainfuck.js +40 -0
  42. package/vue/chunks/c.js +265 -0
  43. package/vue/chunks/cal.js +136 -0
  44. package/vue/chunks/capnproto.js +86 -0
  45. package/vue/chunks/ceylon.js +125 -0
  46. package/vue/chunks/clean.js +54 -0
  47. package/vue/chunks/clojure-repl.js +17 -0
  48. package/vue/chunks/clojure.js +133 -0
  49. package/vue/chunks/cmake.js +23 -0
  50. package/vue/chunks/coffeescript.js +291 -0
  51. package/vue/chunks/coq.js +436 -0
  52. package/vue/chunks/cos.js +77 -0
  53. package/vue/chunks/cpp.js +492 -0
  54. package/vue/chunks/crmsh.js +80 -0
  55. package/vue/chunks/crystal.js +260 -0
  56. package/vue/chunks/csharp.js +376 -0
  57. package/vue/chunks/csp.js +52 -0
  58. package/vue/chunks/css.js +890 -0
  59. package/vue/chunks/d.js +184 -0
  60. package/vue/chunks/dart.js +226 -0
  61. package/vue/chunks/delphi.js +227 -0
  62. package/vue/chunks/diff.js +40 -0
  63. package/vue/chunks/django.js +43 -0
  64. package/vue/chunks/dns.js +66 -0
  65. package/vue/chunks/dockerfile.js +35 -0
  66. package/vue/chunks/dos.js +147 -0
  67. package/vue/chunks/dsconfig.js +55 -0
  68. package/vue/chunks/dts.js +119 -0
  69. package/vue/chunks/dust.js +33 -0
  70. package/vue/chunks/ebnf.js +40 -0
  71. package/vue/chunks/elixir.js +241 -0
  72. package/vue/chunks/elm.js +103 -0
  73. package/vue/chunks/erb.js +17 -0
  74. package/vue/chunks/erlang-repl.js +41 -0
  75. package/vue/chunks/erlang.js +236 -0
  76. package/vue/chunks/excel.js +562 -0
  77. package/vue/chunks/fix.js +30 -0
  78. package/vue/chunks/flix.js +60 -0
  79. package/vue/chunks/fortran.js +543 -0
  80. package/vue/chunks/fsharp.js +440 -0
  81. package/vue/chunks/gams.js +134 -0
  82. package/vue/chunks/gauss.js +167 -0
  83. package/vue/chunks/gcode.js +131 -0
  84. package/vue/chunks/gherkin.js +41 -0
  85. package/vue/chunks/glsl.js +25 -0
  86. package/vue/chunks/gml.js +3119 -0
  87. package/vue/chunks/go.js +140 -0
  88. package/vue/chunks/golo.js +72 -0
  89. package/vue/chunks/gradle.js +181 -0
  90. package/vue/chunks/graphql.js +68 -0
  91. package/vue/chunks/groovy.js +159 -0
  92. package/vue/chunks/haml.js +96 -0
  93. package/vue/chunks/handlebars.js +191 -0
  94. package/vue/chunks/haskell.js +149 -0
  95. package/vue/chunks/haxe.js +142 -0
  96. package/vue/chunks/hsp.js +45 -0
  97. package/vue/chunks/http.js +77 -0
  98. package/vue/chunks/hy.js +92 -0
  99. package/vue/chunks/inform7.js +45 -0
  100. package/vue/chunks/ini.js +94 -0
  101. package/vue/chunks/irpf90.js +52 -0
  102. package/vue/chunks/isbl.js +112 -0
  103. package/vue/chunks/java.js +237 -0
  104. package/vue/chunks/javascript.js +570 -0
  105. package/vue/chunks/jboss-cli.js +46 -0
  106. package/vue/chunks/json.js +45 -0
  107. package/vue/chunks/julia-repl.js +18 -0
  108. package/vue/chunks/julia.js +353 -0
  109. package/vue/chunks/kotlin.js +216 -0
  110. package/vue/chunks/lasso.js +127 -0
  111. package/vue/chunks/latex.js +206 -0
  112. package/vue/chunks/ldif.js +25 -0
  113. package/vue/chunks/leaf.js +72 -0
  114. package/vue/chunks/less.js +953 -0
  115. package/vue/chunks/lisp.js +119 -0
  116. package/vue/chunks/livecodeserver.js +86 -0
  117. package/vue/chunks/livescript.js +309 -0
  118. package/vue/chunks/llvm.js +77 -0
  119. package/vue/chunks/lsl.js +55 -0
  120. package/vue/chunks/lua.js +49 -0
  121. package/vue/chunks/makefile.js +62 -0
  122. package/vue/chunks/markdown.js +194 -0
  123. package/vue/chunks/mathematica.js +7317 -0
  124. package/vue/chunks/matlab.js +70 -0
  125. package/vue/chunks/maxima.js +38 -0
  126. package/vue/chunks/mel.js +24 -0
  127. package/vue/chunks/mercury.js +62 -0
  128. package/vue/chunks/mipsasm.js +53 -0
  129. package/vue/chunks/mizar.js +10 -0
  130. package/vue/chunks/mojolicious.js +27 -0
  131. package/vue/chunks/monkey.js +158 -0
  132. package/vue/chunks/moonscript.js +102 -0
  133. package/vue/chunks/n1ql.js +346 -0
  134. package/vue/chunks/nestedtext.js +66 -0
  135. package/vue/chunks/nginx.js +127 -0
  136. package/vue/chunks/nim.js +174 -0
  137. package/vue/chunks/nix.js +334 -0
  138. package/vue/chunks/node-repl.js +20 -0
  139. package/vue/chunks/nsis.js +515 -0
  140. package/vue/chunks/objectivec.js +235 -0
  141. package/vue/chunks/ocaml.js +52 -0
  142. package/vue/chunks/openscad.js +66 -0
  143. package/vue/chunks/oxygene.js +58 -0
  144. package/vue/chunks/parser3.js +40 -0
  145. package/vue/chunks/perl.js +454 -0
  146. package/vue/chunks/pf.js +30 -0
  147. package/vue/chunks/pgsql.js +196 -0
  148. package/vue/chunks/php-template.js +43 -0
  149. package/vue/chunks/php.js +527 -0
  150. package/vue/chunks/plaintext.js +10 -0
  151. package/vue/chunks/pony.js +60 -0
  152. package/vue/chunks/powershell.js +208 -0
  153. package/vue/chunks/processing.js +407 -0
  154. package/vue/chunks/profile.js +38 -0
  155. package/vue/chunks/prolog.js +62 -0
  156. package/vue/chunks/properties.js +45 -0
  157. package/vue/chunks/protobuf.js +63 -0
  158. package/vue/chunks/puppet.js +87 -0
  159. package/vue/chunks/purebasic.js +42 -0
  160. package/vue/chunks/python-repl.js +19 -0
  161. package/vue/chunks/python.js +357 -0
  162. package/vue/chunks/q.js +21 -0
  163. package/vue/chunks/qml.js +134 -0
  164. package/vue/chunks/r.js +145 -0
  165. package/vue/chunks/reasonml.js +134 -0
  166. package/vue/chunks/rib.js +16 -0
  167. package/vue/chunks/roboconf.js +54 -0
  168. package/vue/chunks/routeros.js +109 -0
  169. package/vue/chunks/rsl.js +138 -0
  170. package/vue/chunks/ruby.js +322 -0
  171. package/vue/chunks/ruleslanguage.js +26 -0
  172. package/vue/chunks/rust.js +296 -0
  173. package/vue/chunks/sas.js +533 -0
  174. package/vue/chunks/scala.js +173 -0
  175. package/vue/chunks/scheme.js +118 -0
  176. package/vue/chunks/scilab.js +45 -0
  177. package/vue/chunks/scss.js +900 -0
  178. package/vue/chunks/shell.js +18 -0
  179. package/vue/chunks/smali.js +113 -0
  180. package/vue/chunks/smalltalk.js +59 -0
  181. package/vue/chunks/sml.js +49 -0
  182. package/vue/chunks/sqf.js +2599 -0
  183. package/vue/chunks/sql.js +624 -0
  184. package/vue/chunks/stan.js +471 -0
  185. package/vue/chunks/stata.js +33 -0
  186. package/vue/chunks/step21.js +53 -0
  187. package/vue/chunks/stylus.js +925 -0
  188. package/vue/chunks/subunit.js +34 -0
  189. package/vue/chunks/swift.js +699 -0
  190. package/vue/chunks/taggerscript.js +37 -0
  191. package/vue/chunks/tap.js +30 -0
  192. package/vue/chunks/tcl.js +165 -0
  193. package/vue/chunks/thrift.js +65 -0
  194. package/vue/chunks/tp.js +155 -0
  195. package/vue/chunks/twig.js +232 -0
  196. package/vue/chunks/typescript.js +672 -0
  197. package/vue/chunks/vala.js +39 -0
  198. package/vue/chunks/vbnet.js +86 -0
  199. package/vue/chunks/vbscript-html.js +14 -0
  200. package/vue/chunks/vbscript.js +200 -0
  201. package/vue/chunks/verilog.js +534 -0
  202. package/vue/chunks/vhdl.js +190 -0
  203. package/vue/chunks/vim.js +54 -0
  204. package/vue/chunks/wasm.js +111 -0
  205. package/vue/chunks/wren.js +229 -0
  206. package/vue/chunks/x86asm.js +64 -0
  207. package/vue/chunks/xl.js +192 -0
  208. package/vue/chunks/xml.js +175 -0
  209. package/vue/chunks/xquery.js +303 -0
  210. package/vue/chunks/yaml.js +159 -0
  211. package/vue/chunks/zephir.js +74 -0
  212. package/vue/components.css +119 -85
  213. package/vue/editor/LoomaEditor.d.ts +7 -7
  214. package/vue/editor/code-language-catalog.d.ts +196 -0
  215. package/vue/editor/index.js +290 -20
@@ -9290,8 +9290,8 @@ function getLoomaTableExtensions() {
9290
9290
  * the code and explicit language stay in the document schema.
9291
9291
  */
9292
9292
  function getDefaultEditorExtensions(options = {}) {
9293
- const { placeholder = "Type “/” for commands, or start writing…", linkOpenOnClick = false, imageInline = false, mention = createLoomaMentionExtension(), disableHighlight = false, codeLanguages, codeBlockNodeView } = options;
9294
- const codeBlock = LoomaCodeBlock.configure({ lowlight: createLowlight(codeLanguages) });
9293
+ const { placeholder = "Type “/” for commands, or start writing…", linkOpenOnClick = false, imageInline = false, mention = createLoomaMentionExtension(), disableHighlight = false, codeLanguages, codeLowlight, codeBlockNodeView } = options;
9294
+ const codeBlock = LoomaCodeBlock.configure({ lowlight: codeLowlight ?? createLowlight(codeLanguages) });
9295
9295
  return [
9296
9296
  Document,
9297
9297
  Paragraph,
@@ -9663,7 +9663,7 @@ function normalizeActiveTableColumnWidths(editor, tableElement, minWidth = 25) {
9663
9663
  *
9664
9664
  * Boundary indices address the visual grid edges measured by the overlay. The
9665
9665
  * helper maps them into the current table transaction, rejects indices that do
9666
- * not represent a legal insertion edge, dispatches once, and restores editor
9666
+ * not represent a legal insertion edge or reorder destination, dispatches once, and restores editor
9667
9667
  * focus. `open-cell-menu` returns handled without editing because menu ownership
9668
9668
  * remains with the application/adapter.
9669
9669
  *
@@ -9676,6 +9676,27 @@ function handleTableOverlayAction(editor, detail) {
9676
9676
  const tableInfo = findTable(editor);
9677
9677
  if (!tableInfo) return false;
9678
9678
  const { action } = detail;
9679
+ if (action === "reorder-row" || action === "reorder-column") {
9680
+ const { fromIndex, toIndex } = detail;
9681
+ const { pos: tablePos, node: table } = tableInfo;
9682
+ const map = TableMap.get(table);
9683
+ const axis = action === "reorder-row" ? "row" : "column";
9684
+ const limit = axis === "row" ? map.height : map.width;
9685
+ if (!Number.isInteger(fromIndex) || !Number.isInteger(toIndex) || fromIndex < 0 || toIndex < 0 || fromIndex >= limit || toIndex >= limit || fromIndex === toIndex) return false;
9686
+ const cellPos = tablePos + 1 + map.map[axis === "row" ? fromIndex * map.width : fromIndex];
9687
+ const command = axis === "row" ? moveTableRow : moveTableColumn;
9688
+ try {
9689
+ const moved = command({
9690
+ from: fromIndex,
9691
+ to: toIndex,
9692
+ pos: cellPos
9693
+ })(editor.state, editor.view.dispatch);
9694
+ if (moved) editor.view.focus();
9695
+ return moved;
9696
+ } catch {
9697
+ return false;
9698
+ }
9699
+ }
9679
9700
  if (action === "select-row" || action === "select-column") return selectTableAxis(editor, action === "select-row" ? "row" : "column", detail.rowIndex, detail.columnIndex);
9680
9701
  if (action === "open-cell-menu" || action === "open-row-menu" || action === "open-column-menu") return true;
9681
9702
  if (!("boundaryIndex" in detail)) return false;
@@ -29,6 +29,8 @@ export interface DefaultEditorExtensionsOptions {
29
29
  disableHighlight?: boolean;
30
30
  /** Code block grammars to register. None are loaded by default. */
31
31
  codeLanguages?: LoomaCodeLanguages;
32
+ /** Shared highlighter that can receive grammars after editor creation. */
33
+ codeLowlight?: ReturnType<typeof createLowlight>;
32
34
  /** Optional presentation for a code block; the Vue editor supplies its language control. */
33
35
  codeBlockNodeView?: NodeViewRenderer;
34
36
  }
@@ -110,7 +110,7 @@ export declare function normalizeActiveTableColumnWidths(editor: Editor, tableEl
110
110
  *
111
111
  * Boundary indices address the visual grid edges measured by the overlay. The
112
112
  * helper maps them into the current table transaction, rejects indices that do
113
- * not represent a legal insertion edge, dispatches once, and restores editor
113
+ * not represent a legal insertion edge or reorder destination, dispatches once, and restores editor
114
114
  * focus. `open-cell-menu` returns handled without editing because menu ownership
115
115
  * remains with the application/adapter.
116
116
  *
@@ -9,16 +9,21 @@ 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" | "open-row-menu" | "open-column-menu";
12
+ export type TableOverlayAction = TableInsertionAction | "select-row" | "select-column" | "reorder-row" | "reorder-column" | "open-cell-menu" | "open-row-menu" | "open-column-menu";
13
13
  /**
14
14
  * Discriminated action payload.
15
- * Boundary indices refer to entries in the measured boundary arrays. Cell
16
- * indices refer to the logical grid after row/column spans are expanded. The
15
+ * Boundary indices refer to entries in the measured boundary arrays. Reorder
16
+ * indices refer to source and destination rows or columns. Cell indices refer
17
+ * to the logical grid after row/column spans are expanded. The
17
18
  * menu anchor uses CSS-pixel viewport coordinates suitable for fixed surfaces.
18
19
  */
19
20
  export type TableOverlayActionEventDetail = {
20
21
  action: TableInsertionAction;
21
22
  boundaryIndex: number;
23
+ } | {
24
+ action: "reorder-row" | "reorder-column";
25
+ fromIndex: number;
26
+ toIndex: number;
22
27
  } | {
23
28
  action: "select-row" | "select-column";
24
29
  rowIndex: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@threadlabs/looma",
3
- "version": "0.18.6",
3
+ "version": "0.19.0",
4
4
  "type": "module",
5
5
  "description": "Looma components as HTML, Vue, and plain DOM, with design tokens.",
6
6
  "license": "MIT",
@@ -79,6 +79,7 @@
79
79
  "dependencies": {
80
80
  "@nextwebwg/html-next": "1.0.0-alpha.7",
81
81
  "dompurify": "3.4.15",
82
+ "highlight.js": "11.11.2",
82
83
  "lowlight": "^3.3.0",
83
84
  "markdown-it": "14.3.1",
84
85
  "lucide": "~0.554.0"
@@ -223,6 +223,12 @@
223
223
 
224
224
  .selector {
225
225
  border-radius: var(--ui-radius-round);
226
+ touch-action: none;
227
+ cursor: grab;
228
+ }
229
+
230
+ .selector:active {
231
+ cursor: grabbing;
226
232
  }
227
233
 
228
234
  .selector::before {
@@ -308,6 +314,30 @@
308
314
  --_ui-default-icon-stroke-width: 2;
309
315
  }
310
316
 
317
+ .drop-indicator {
318
+ position: absolute;
319
+ z-index: 3;
320
+ background: var(--ui-accent-solid);
321
+ box-shadow: 0 0 0 2px var(--ui-surface);
322
+ pointer-events: none;
323
+ }
324
+
325
+ .drop-indicator.row {
326
+ left: 0;
327
+ width: 100%;
328
+ height: 2px;
329
+ }
330
+
331
+ .drop-indicator.column {
332
+ top: 0;
333
+ width: 2px;
334
+ height: 100%;
335
+ }
336
+
337
+ .drop-indicator[hidden] {
338
+ display: none;
339
+ }
340
+
311
341
  :scope[hidden] {
312
342
  display: none;
313
343
  }
@@ -118,10 +118,12 @@
118
118
  }
119
119
 
120
120
  .menu {
121
+ box-sizing: border-box;
121
122
  position: absolute;
122
123
  top: calc(100% + var(--ui-space-2));
123
124
  right: 0;
124
125
  min-width: 12rem;
126
+ max-width: min(17rem, calc(100vw - 24px));
125
127
  padding: var(--ui-space-1);
126
128
  background: var(--ui-surface);
127
129
  border: 1px solid var(--ui-border-strong);
@@ -131,6 +133,9 @@
131
133
  flex-direction: column;
132
134
  gap: 2px;
133
135
  z-index: 2;
136
+ overflow-y: auto;
137
+ overscroll-behavior: contain;
138
+ scrollbar-width: thin;
134
139
  }
135
140
 
136
141
  .menu-section + .menu-section {
@@ -157,7 +162,7 @@
157
162
 
158
163
  .swatches {
159
164
  display: grid;
160
- grid-template-columns: repeat(3, minmax(0, 1fr));
165
+ grid-template-columns: repeat(2, minmax(0, 1fr));
161
166
  gap: 2px;
162
167
  }
163
168
 
@@ -171,7 +176,7 @@
171
176
  height: 14px;
172
177
  flex: 0 0 14px;
173
178
  border: 1px solid color-mix(in srgb, var(--ui-border) 80%, #000);
174
- border-radius: 3px;
179
+ border-radius: var(--ui-radius-round);
175
180
  background: var(--_swatch);
176
181
  }
177
182
 
@@ -1,6 +1,6 @@
1
1
  // Generated by HTML Next 1.0.0-alpha.7 for Vanilla DOM. Do not edit.
2
2
  export interface UiEditorTableOverlayEventMap {
3
- action: CustomEvent<{ readonly action: "add-row-before" | "add-row-after" | "add-column-before" | "add-column-after"; readonly boundaryIndex: number } | { readonly action: "select-row" | "select-column"; readonly rowIndex: number; readonly columnIndex: number } | { readonly action: "open-cell-menu" | "open-row-menu" | "open-column-menu"; readonly rowIndex: number; readonly columnIndex: number; readonly anchor: { readonly left: number; readonly top: number; readonly right: number; readonly bottom: number } }>;
3
+ action: CustomEvent<{ readonly action: "add-row-before" | "add-row-after" | "add-column-before" | "add-column-after"; readonly boundaryIndex: number } | { readonly action: "select-row" | "select-column"; readonly rowIndex: number; readonly columnIndex: number } | { readonly action: "reorder-row" | "reorder-column"; readonly fromIndex: number; readonly toIndex: number } | { readonly action: "open-cell-menu" | "open-row-menu" | "open-column-menu"; readonly rowIndex: number; readonly columnIndex: number; readonly anchor: { readonly left: number; readonly top: number; readonly right: number; readonly bottom: number } }>;
4
4
  }
5
5
  export interface UiEditorTableOverlayElement extends HTMLDivElement {
6
6
  addEventListener<K extends keyof UiEditorTableOverlayEventMap>(type: K, listener: (this: UiEditorTableOverlayElement, event: UiEditorTableOverlayEventMap[K]) => unknown, options?: boolean | AddEventListenerOptions): void;
@@ -3,7 +3,7 @@ import { manageComponentLifecycle } from "@nextwebwg/html-next/runtime";
3
3
  import * as controller from "../components/ui-editor-table-overlay/ui-editor-table-overlay.js";
4
4
  import "../styles/ui-editor-table-overlay.css";
5
5
 
6
- const definition = {...{"contract":{"tag":"ui-editor-table-overlay","props":{"geometry":{"type":{"kind":"union","members":[{"kind":"object","fields":[{"name":"rowBoundaries","type":{"kind":"list","item":{"kind":"terminal","name":"number"}},"optional":false},{"name":"columnBoundaries","type":{"kind":"list","item":{"kind":"terminal","name":"number"}},"optional":false},{"name":"activeCell","type":{"kind":"union","members":[{"kind":"object","fields":[{"name":"left","type":{"kind":"terminal","name":"number"},"optional":false},{"name":"top","type":{"kind":"terminal","name":"number"},"optional":false},{"name":"width","type":{"kind":"terminal","name":"number"},"optional":false},{"name":"height","type":{"kind":"terminal","name":"number"},"optional":false},{"name":"rowIndex","type":{"kind":"terminal","name":"integer"},"optional":false},{"name":"columnIndex","type":{"kind":"terminal","name":"integer"},"optional":false}],"open":false},{"kind":"terminal","name":"null"}]},"optional":false},{"name":"hoveredCell","type":{"kind":"union","members":[{"kind":"object","fields":[{"name":"left","type":{"kind":"terminal","name":"number"},"optional":false},{"name":"top","type":{"kind":"terminal","name":"number"},"optional":false},{"name":"width","type":{"kind":"terminal","name":"number"},"optional":false},{"name":"height","type":{"kind":"terminal","name":"number"},"optional":false},{"name":"rowIndex","type":{"kind":"terminal","name":"integer"},"optional":false},{"name":"columnIndex","type":{"kind":"terminal","name":"integer"},"optional":false}],"open":false},{"kind":"terminal","name":"null"}]},"optional":true}],"open":false},{"kind":"terminal","name":"null"}]},"required":false,"target":{"attribute":"geometry"}},"open":{"type":"boolean","required":false,"target":{"attribute":"open"},"default":false}}},"template":{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"aria-label","value":"Table controls"},{"kind":"attribute","name":"hidden","expression":"not open","expressionPlan":{"source":"not open","ast":{"kind":"unary","op":"not","operand":{"kind":"id","name":"open"}},"dependencies":["open"]}}],"children":[{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"class","value":"rows"}],"children":[{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"class","value":"control row"},{"kind":"attribute","name":"active","expression":"control.key = activeKey","expressionPlan":{"source":"control.key = activeKey","ast":{"kind":"binary","op":"=","left":{"kind":"member","object":{"kind":"id","name":"control"},"key":"key"},"right":{"kind":"id","name":"activeKey"}},"dependencies":["activeKey","control.key"]},"target":"class"},{"kind":"attribute","name":"top","expression":"control.offset","expressionPlan":{"source":"control.offset","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"offset"},"dependencies":["control.offset"]},"target":"style"},{"kind":"attribute","name":"data-control-key","expression":"control.key","expressionPlan":{"source":"control.key","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"key"},"dependencies":["control.key"]}}],"children":[{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"line"},{"kind":"literal","name":"aria-hidden","value":"true"}],"children":[]},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"guide"},{"kind":"literal","name":"data-ui-guide","value":""},{"kind":"literal","name":"aria-hidden","value":"true"}],"children":[]},{"kind":"element","name":"button","attributes":[{"kind":"literal","name":"type","value":"button"},{"kind":"literal","name":"class","value":"handle"},{"kind":"attribute","name":"data-ui-affordance","expression":"control.affordance","expressionPlan":{"source":"control.affordance","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"affordance"},"dependencies":["control.affordance"]}},{"kind":"attribute","name":"data-action","expression":"control.action","expressionPlan":{"source":"control.action","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"action"},"dependencies":["control.action"]}},{"kind":"attribute","name":"data-boundary-index","expression":"control.index","expressionPlan":{"source":"control.index","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"index"},"dependencies":["control.index"]}},{"kind":"attribute","name":"aria-label","expression":"control.label","expressionPlan":{"source":"control.label","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"label"},"dependencies":["control.label"]}}],"children":[{"kind":"element","name":"ui-icon","attributes":[{"kind":"literal","name":"name","value":"plus"}],"children":[]},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"tooltip"},{"kind":"literal","name":"role","value":"tooltip"},{"kind":"directive","name":"value","expression":"control.label","expressionPlan":{"source":"control.label","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"label"},"dependencies":["control.label"]}}],"children":[]}]}],"flow":{"kind":"each","item":"control","list":"rows","listPlan":{"source":"rows","ast":{"kind":"id","name":"rows"},"dependencies":["rows"]},"key":"control.key","keyPlan":{"source":"control.key","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"key"},"dependencies":["control.key"]}}}]},{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"class","value":"cols"}],"children":[{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"class","value":"control col"},{"kind":"attribute","name":"active","expression":"control.key = activeKey","expressionPlan":{"source":"control.key = activeKey","ast":{"kind":"binary","op":"=","left":{"kind":"member","object":{"kind":"id","name":"control"},"key":"key"},"right":{"kind":"id","name":"activeKey"}},"dependencies":["activeKey","control.key"]},"target":"class"},{"kind":"attribute","name":"left","expression":"control.offset","expressionPlan":{"source":"control.offset","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"offset"},"dependencies":["control.offset"]},"target":"style"},{"kind":"attribute","name":"data-control-key","expression":"control.key","expressionPlan":{"source":"control.key","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"key"},"dependencies":["control.key"]}}],"children":[{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"line"},{"kind":"literal","name":"aria-hidden","value":"true"}],"children":[]},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"guide"},{"kind":"literal","name":"data-ui-guide","value":""},{"kind":"literal","name":"aria-hidden","value":"true"}],"children":[]},{"kind":"element","name":"button","attributes":[{"kind":"literal","name":"type","value":"button"},{"kind":"literal","name":"class","value":"handle"},{"kind":"attribute","name":"data-ui-affordance","expression":"control.affordance","expressionPlan":{"source":"control.affordance","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"affordance"},"dependencies":["control.affordance"]}},{"kind":"attribute","name":"data-action","expression":"control.action","expressionPlan":{"source":"control.action","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"action"},"dependencies":["control.action"]}},{"kind":"attribute","name":"data-boundary-index","expression":"control.index","expressionPlan":{"source":"control.index","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"index"},"dependencies":["control.index"]}},{"kind":"attribute","name":"aria-label","expression":"control.label","expressionPlan":{"source":"control.label","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"label"},"dependencies":["control.label"]}}],"children":[{"kind":"element","name":"ui-icon","attributes":[{"kind":"literal","name":"name","value":"plus"}],"children":[]},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"tooltip"},{"kind":"literal","name":"role","value":"tooltip"},{"kind":"directive","name":"value","expression":"control.label","expressionPlan":{"source":"control.label","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"label"},"dependencies":["control.label"]}}],"children":[]}]}],"flow":{"kind":"each","item":"control","list":"cols","listPlan":{"source":"cols","ast":{"kind":"id","name":"cols"},"dependencies":["cols"]},"key":"control.key","keyPlan":{"source":"control.key","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"key"},"dependencies":["control.key"]}}}]},{"kind":"element","name":"template","attributes":[],"children":[{"kind":"element","name":"button","attributes":[{"kind":"literal","name":"type","value":"button"},{"kind":"literal","name":"class","value":"selector row"},{"kind":"attribute","name":"top","expression":"hovered.rowOffset","expressionPlan":{"source":"hovered.rowOffset","ast":{"kind":"member","object":{"kind":"id","name":"hovered"},"key":"rowOffset"},"dependencies":["hovered.rowOffset"]},"target":"style"},{"kind":"literal","name":"data-action","value":"select-row"},{"kind":"attribute","name":"data-row-index","expression":"hovered.rowIndex","expressionPlan":{"source":"hovered.rowIndex","ast":{"kind":"member","object":{"kind":"id","name":"hovered"},"key":"rowIndex"},"dependencies":["hovered.rowIndex"]}},{"kind":"attribute","name":"data-column-index","expression":"hovered.columnIndex","expressionPlan":{"source":"hovered.columnIndex","ast":{"kind":"member","object":{"kind":"id","name":"hovered"},"key":"columnIndex"},"dependencies":["hovered.columnIndex"]}},{"kind":"literal","name":"title","value":"Row actions"},{"kind":"literal","name":"aria-label","value":"Row actions"}],"children":[{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"glyph"}],"children":[{"kind":"element","name":"ui-icon","attributes":[{"kind":"literal","name":"name","value":"grip-vertical"}],"children":[]}]}]},{"kind":"element","name":"button","attributes":[{"kind":"literal","name":"type","value":"button"},{"kind":"literal","name":"class","value":"selector column"},{"kind":"attribute","name":"left","expression":"hovered.columnOffset","expressionPlan":{"source":"hovered.columnOffset","ast":{"kind":"member","object":{"kind":"id","name":"hovered"},"key":"columnOffset"},"dependencies":["hovered.columnOffset"]},"target":"style"},{"kind":"literal","name":"data-action","value":"select-column"},{"kind":"attribute","name":"data-row-index","expression":"hovered.rowIndex","expressionPlan":{"source":"hovered.rowIndex","ast":{"kind":"member","object":{"kind":"id","name":"hovered"},"key":"rowIndex"},"dependencies":["hovered.rowIndex"]}},{"kind":"attribute","name":"data-column-index","expression":"hovered.columnIndex","expressionPlan":{"source":"hovered.columnIndex","ast":{"kind":"member","object":{"kind":"id","name":"hovered"},"key":"columnIndex"},"dependencies":["hovered.columnIndex"]}},{"kind":"literal","name":"title","value":"Column actions"},{"kind":"literal","name":"aria-label","value":"Column actions"}],"children":[{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"glyph"}],"children":[{"kind":"element","name":"ui-icon","attributes":[{"kind":"literal","name":"name","value":"grip-horizontal"}],"children":[]}]}]}],"flow":{"kind":"if","test":"hovered","testPlan":{"source":"hovered","ast":{"kind":"id","name":"hovered"},"dependencies":["hovered"]}}},{"kind":"element","name":"button","attributes":[{"kind":"literal","name":"type","value":"button"},{"kind":"literal","name":"class","value":"cell-menu"},{"kind":"attribute","name":"left","expression":"active.menuLeft","expressionPlan":{"source":"active.menuLeft","ast":{"kind":"member","object":{"kind":"id","name":"active"},"key":"menuLeft"},"dependencies":["active.menuLeft"]},"target":"style"},{"kind":"attribute","name":"top","expression":"active.menuTop","expressionPlan":{"source":"active.menuTop","ast":{"kind":"member","object":{"kind":"id","name":"active"},"key":"menuTop"},"dependencies":["active.menuTop"]},"target":"style"},{"kind":"literal","name":"data-action","value":"open-cell-menu"},{"kind":"attribute","name":"data-row-index","expression":"active.rowIndex","expressionPlan":{"source":"active.rowIndex","ast":{"kind":"member","object":{"kind":"id","name":"active"},"key":"rowIndex"},"dependencies":["active.rowIndex"]}},{"kind":"attribute","name":"data-column-index","expression":"active.columnIndex","expressionPlan":{"source":"active.columnIndex","ast":{"kind":"member","object":{"kind":"id","name":"active"},"key":"columnIndex"},"dependencies":["active.columnIndex"]}},{"kind":"literal","name":"title","value":"Cell actions"},{"kind":"literal","name":"aria-label","value":"Cell actions"}],"children":[{"kind":"element","name":"ui-icon","attributes":[{"kind":"literal","name":"name","value":"chevron-down"}],"children":[]}],"flow":{"kind":"if","test":"active","testPlan":{"source":"active","ast":{"kind":"id","name":"active"},"dependencies":["active"]}}}]},"declarations":[{"kind":"state","name":"rows","type":"list(object({ key: string, index: integer, offset: string, affordance: insert-row | insert-column, action: add-row-before | add-row-after | add-column-before | add-column-after, label: string }))","expression":{"source":"[]","ast":{"kind":"array","items":[]},"dependencies":[]}},{"kind":"state","name":"cols","type":"list(object({ key: string, index: integer, offset: string, affordance: insert-row | insert-column, action: add-row-before | add-row-after | add-column-before | add-column-after, label: string }))","expression":{"source":"[]","ast":{"kind":"array","items":[]},"dependencies":[]}},{"kind":"state","name":"hovered","type":"object({ left: number, top: number, width: number, height: number, rowIndex: integer, columnIndex: integer, rowOffset: string, columnOffset: string }) | null","expression":{"source":"null","ast":{"kind":"literal","value":null},"dependencies":[]}},{"kind":"state","name":"active","type":"object({ left: number, top: number, width: number, height: number, rowIndex: integer, columnIndex: integer, menuLeft: string, menuTop: string }) | null","expression":{"source":"null","ast":{"kind":"literal","value":null},"dependencies":[]}},{"kind":"state","name":"activeKey","expression":{"source":"''","ast":{"kind":"literal","value":""},"dependencies":[]}},{"kind":"event","name":"action","type":"object({ action: add-row-before | add-row-after | add-column-before | add-column-after, boundaryIndex: integer }) | object({ action: select-row | select-column, rowIndex: integer, columnIndex: integer }) | object({ action: open-cell-menu | open-row-menu | open-column-menu, rowIndex: integer, columnIndex: integer, anchor: object({ left: number, top: number, right: number, bottom: number }) })","bubbles":true,"composed":true,"cancelable":false}],"root":{"kind":"native","element":"div","choices":["div"]}},source:{file:import.meta.url},css:""};
6
+ const definition = {...{"contract":{"tag":"ui-editor-table-overlay","props":{"geometry":{"type":{"kind":"union","members":[{"kind":"object","fields":[{"name":"rowBoundaries","type":{"kind":"list","item":{"kind":"terminal","name":"number"}},"optional":false},{"name":"columnBoundaries","type":{"kind":"list","item":{"kind":"terminal","name":"number"}},"optional":false},{"name":"activeCell","type":{"kind":"union","members":[{"kind":"object","fields":[{"name":"left","type":{"kind":"terminal","name":"number"},"optional":false},{"name":"top","type":{"kind":"terminal","name":"number"},"optional":false},{"name":"width","type":{"kind":"terminal","name":"number"},"optional":false},{"name":"height","type":{"kind":"terminal","name":"number"},"optional":false},{"name":"rowIndex","type":{"kind":"terminal","name":"integer"},"optional":false},{"name":"columnIndex","type":{"kind":"terminal","name":"integer"},"optional":false}],"open":false},{"kind":"terminal","name":"null"}]},"optional":false},{"name":"hoveredCell","type":{"kind":"union","members":[{"kind":"object","fields":[{"name":"left","type":{"kind":"terminal","name":"number"},"optional":false},{"name":"top","type":{"kind":"terminal","name":"number"},"optional":false},{"name":"width","type":{"kind":"terminal","name":"number"},"optional":false},{"name":"height","type":{"kind":"terminal","name":"number"},"optional":false},{"name":"rowIndex","type":{"kind":"terminal","name":"integer"},"optional":false},{"name":"columnIndex","type":{"kind":"terminal","name":"integer"},"optional":false}],"open":false},{"kind":"terminal","name":"null"}]},"optional":true}],"open":false},{"kind":"terminal","name":"null"}]},"required":false,"target":{"attribute":"geometry"}},"open":{"type":"boolean","required":false,"target":{"attribute":"open"},"default":false}}},"template":{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"aria-label","value":"Table controls"},{"kind":"attribute","name":"hidden","expression":"not open","expressionPlan":{"source":"not open","ast":{"kind":"unary","op":"not","operand":{"kind":"id","name":"open"}},"dependencies":["open"]}}],"children":[{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"class","value":"rows"}],"children":[{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"class","value":"control row"},{"kind":"attribute","name":"active","expression":"control.key = activeKey","expressionPlan":{"source":"control.key = activeKey","ast":{"kind":"binary","op":"=","left":{"kind":"member","object":{"kind":"id","name":"control"},"key":"key"},"right":{"kind":"id","name":"activeKey"}},"dependencies":["activeKey","control.key"]},"target":"class"},{"kind":"attribute","name":"top","expression":"control.offset","expressionPlan":{"source":"control.offset","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"offset"},"dependencies":["control.offset"]},"target":"style"},{"kind":"attribute","name":"data-control-key","expression":"control.key","expressionPlan":{"source":"control.key","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"key"},"dependencies":["control.key"]}}],"children":[{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"line"},{"kind":"literal","name":"aria-hidden","value":"true"}],"children":[]},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"guide"},{"kind":"literal","name":"data-ui-guide","value":""},{"kind":"literal","name":"aria-hidden","value":"true"}],"children":[]},{"kind":"element","name":"button","attributes":[{"kind":"literal","name":"type","value":"button"},{"kind":"literal","name":"class","value":"handle"},{"kind":"attribute","name":"data-ui-affordance","expression":"control.affordance","expressionPlan":{"source":"control.affordance","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"affordance"},"dependencies":["control.affordance"]}},{"kind":"attribute","name":"data-action","expression":"control.action","expressionPlan":{"source":"control.action","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"action"},"dependencies":["control.action"]}},{"kind":"attribute","name":"data-boundary-index","expression":"control.index","expressionPlan":{"source":"control.index","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"index"},"dependencies":["control.index"]}},{"kind":"attribute","name":"aria-label","expression":"control.label","expressionPlan":{"source":"control.label","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"label"},"dependencies":["control.label"]}}],"children":[{"kind":"element","name":"ui-icon","attributes":[{"kind":"literal","name":"name","value":"plus"}],"children":[]},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"tooltip"},{"kind":"literal","name":"role","value":"tooltip"},{"kind":"directive","name":"value","expression":"control.label","expressionPlan":{"source":"control.label","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"label"},"dependencies":["control.label"]}}],"children":[]}]}],"flow":{"kind":"each","item":"control","list":"rows","listPlan":{"source":"rows","ast":{"kind":"id","name":"rows"},"dependencies":["rows"]},"key":"control.key","keyPlan":{"source":"control.key","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"key"},"dependencies":["control.key"]}}}]},{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"class","value":"cols"}],"children":[{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"class","value":"control col"},{"kind":"attribute","name":"active","expression":"control.key = activeKey","expressionPlan":{"source":"control.key = activeKey","ast":{"kind":"binary","op":"=","left":{"kind":"member","object":{"kind":"id","name":"control"},"key":"key"},"right":{"kind":"id","name":"activeKey"}},"dependencies":["activeKey","control.key"]},"target":"class"},{"kind":"attribute","name":"left","expression":"control.offset","expressionPlan":{"source":"control.offset","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"offset"},"dependencies":["control.offset"]},"target":"style"},{"kind":"attribute","name":"data-control-key","expression":"control.key","expressionPlan":{"source":"control.key","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"key"},"dependencies":["control.key"]}}],"children":[{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"line"},{"kind":"literal","name":"aria-hidden","value":"true"}],"children":[]},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"guide"},{"kind":"literal","name":"data-ui-guide","value":""},{"kind":"literal","name":"aria-hidden","value":"true"}],"children":[]},{"kind":"element","name":"button","attributes":[{"kind":"literal","name":"type","value":"button"},{"kind":"literal","name":"class","value":"handle"},{"kind":"attribute","name":"data-ui-affordance","expression":"control.affordance","expressionPlan":{"source":"control.affordance","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"affordance"},"dependencies":["control.affordance"]}},{"kind":"attribute","name":"data-action","expression":"control.action","expressionPlan":{"source":"control.action","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"action"},"dependencies":["control.action"]}},{"kind":"attribute","name":"data-boundary-index","expression":"control.index","expressionPlan":{"source":"control.index","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"index"},"dependencies":["control.index"]}},{"kind":"attribute","name":"aria-label","expression":"control.label","expressionPlan":{"source":"control.label","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"label"},"dependencies":["control.label"]}}],"children":[{"kind":"element","name":"ui-icon","attributes":[{"kind":"literal","name":"name","value":"plus"}],"children":[]},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"tooltip"},{"kind":"literal","name":"role","value":"tooltip"},{"kind":"directive","name":"value","expression":"control.label","expressionPlan":{"source":"control.label","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"label"},"dependencies":["control.label"]}}],"children":[]}]}],"flow":{"kind":"each","item":"control","list":"cols","listPlan":{"source":"cols","ast":{"kind":"id","name":"cols"},"dependencies":["cols"]},"key":"control.key","keyPlan":{"source":"control.key","ast":{"kind":"member","object":{"kind":"id","name":"control"},"key":"key"},"dependencies":["control.key"]}}}]},{"kind":"element","name":"template","attributes":[],"children":[{"kind":"element","name":"button","attributes":[{"kind":"literal","name":"type","value":"button"},{"kind":"literal","name":"class","value":"selector row"},{"kind":"attribute","name":"top","expression":"hovered.rowOffset","expressionPlan":{"source":"hovered.rowOffset","ast":{"kind":"member","object":{"kind":"id","name":"hovered"},"key":"rowOffset"},"dependencies":["hovered.rowOffset"]},"target":"style"},{"kind":"literal","name":"data-action","value":"select-row"},{"kind":"attribute","name":"data-row-index","expression":"hovered.rowIndex","expressionPlan":{"source":"hovered.rowIndex","ast":{"kind":"member","object":{"kind":"id","name":"hovered"},"key":"rowIndex"},"dependencies":["hovered.rowIndex"]}},{"kind":"attribute","name":"data-column-index","expression":"hovered.columnIndex","expressionPlan":{"source":"hovered.columnIndex","ast":{"kind":"member","object":{"kind":"id","name":"hovered"},"key":"columnIndex"},"dependencies":["hovered.columnIndex"]}},{"kind":"literal","name":"title","value":"Drag row to reorder; click for actions"},{"kind":"literal","name":"aria-label","value":"Row actions"}],"children":[{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"glyph"}],"children":[{"kind":"element","name":"ui-icon","attributes":[{"kind":"literal","name":"name","value":"grip-vertical"}],"children":[]}]}]},{"kind":"element","name":"button","attributes":[{"kind":"literal","name":"type","value":"button"},{"kind":"literal","name":"class","value":"selector column"},{"kind":"attribute","name":"left","expression":"hovered.columnOffset","expressionPlan":{"source":"hovered.columnOffset","ast":{"kind":"member","object":{"kind":"id","name":"hovered"},"key":"columnOffset"},"dependencies":["hovered.columnOffset"]},"target":"style"},{"kind":"literal","name":"data-action","value":"select-column"},{"kind":"attribute","name":"data-row-index","expression":"hovered.rowIndex","expressionPlan":{"source":"hovered.rowIndex","ast":{"kind":"member","object":{"kind":"id","name":"hovered"},"key":"rowIndex"},"dependencies":["hovered.rowIndex"]}},{"kind":"attribute","name":"data-column-index","expression":"hovered.columnIndex","expressionPlan":{"source":"hovered.columnIndex","ast":{"kind":"member","object":{"kind":"id","name":"hovered"},"key":"columnIndex"},"dependencies":["hovered.columnIndex"]}},{"kind":"literal","name":"title","value":"Drag column to reorder; click for actions"},{"kind":"literal","name":"aria-label","value":"Column actions"}],"children":[{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"glyph"}],"children":[{"kind":"element","name":"ui-icon","attributes":[{"kind":"literal","name":"name","value":"grip-horizontal"}],"children":[]}]}]}],"flow":{"kind":"if","test":"hovered","testPlan":{"source":"hovered","ast":{"kind":"id","name":"hovered"},"dependencies":["hovered"]}}},{"kind":"element","name":"button","attributes":[{"kind":"literal","name":"type","value":"button"},{"kind":"literal","name":"class","value":"cell-menu"},{"kind":"attribute","name":"left","expression":"active.menuLeft","expressionPlan":{"source":"active.menuLeft","ast":{"kind":"member","object":{"kind":"id","name":"active"},"key":"menuLeft"},"dependencies":["active.menuLeft"]},"target":"style"},{"kind":"attribute","name":"top","expression":"active.menuTop","expressionPlan":{"source":"active.menuTop","ast":{"kind":"member","object":{"kind":"id","name":"active"},"key":"menuTop"},"dependencies":["active.menuTop"]},"target":"style"},{"kind":"literal","name":"data-action","value":"open-cell-menu"},{"kind":"attribute","name":"data-row-index","expression":"active.rowIndex","expressionPlan":{"source":"active.rowIndex","ast":{"kind":"member","object":{"kind":"id","name":"active"},"key":"rowIndex"},"dependencies":["active.rowIndex"]}},{"kind":"attribute","name":"data-column-index","expression":"active.columnIndex","expressionPlan":{"source":"active.columnIndex","ast":{"kind":"member","object":{"kind":"id","name":"active"},"key":"columnIndex"},"dependencies":["active.columnIndex"]}},{"kind":"literal","name":"title","value":"Cell actions"},{"kind":"literal","name":"aria-label","value":"Cell actions"}],"children":[{"kind":"element","name":"ui-icon","attributes":[{"kind":"literal","name":"name","value":"chevron-down"}],"children":[]}],"flow":{"kind":"if","test":"active","testPlan":{"source":"active","ast":{"kind":"id","name":"active"},"dependencies":["active"]}}},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"drop-indicator"},{"kind":"literal","name":"data-drop-indicator","value":""},{"kind":"literal","name":"hidden","value":""},{"kind":"literal","name":"aria-hidden","value":"true"}],"children":[]}]},"declarations":[{"kind":"state","name":"rows","type":"list(object({ key: string, index: integer, offset: string, affordance: insert-row | insert-column, action: add-row-before | add-row-after | add-column-before | add-column-after, label: string }))","expression":{"source":"[]","ast":{"kind":"array","items":[]},"dependencies":[]}},{"kind":"state","name":"cols","type":"list(object({ key: string, index: integer, offset: string, affordance: insert-row | insert-column, action: add-row-before | add-row-after | add-column-before | add-column-after, label: string }))","expression":{"source":"[]","ast":{"kind":"array","items":[]},"dependencies":[]}},{"kind":"state","name":"hovered","type":"object({ left: number, top: number, width: number, height: number, rowIndex: integer, columnIndex: integer, rowOffset: string, columnOffset: string }) | null","expression":{"source":"null","ast":{"kind":"literal","value":null},"dependencies":[]}},{"kind":"state","name":"active","type":"object({ left: number, top: number, width: number, height: number, rowIndex: integer, columnIndex: integer, menuLeft: string, menuTop: string }) | null","expression":{"source":"null","ast":{"kind":"literal","value":null},"dependencies":[]}},{"kind":"state","name":"activeKey","expression":{"source":"''","ast":{"kind":"literal","value":""},"dependencies":[]}},{"kind":"event","name":"action","type":"object({ action: add-row-before | add-row-after | add-column-before | add-column-after, boundaryIndex: integer }) | object({ action: select-row | select-column, rowIndex: integer, columnIndex: integer }) | object({ action: reorder-row | reorder-column, fromIndex: integer, toIndex: integer }) | object({ action: open-cell-menu | open-row-menu | open-column-menu, rowIndex: integer, columnIndex: integer, anchor: object({ left: number, top: number, right: number, bottom: number }) })","bubbles":true,"composed":true,"cancelable":false}],"root":{"kind":"native","element":"div","choices":["div"]}},source:{file:import.meta.url},css:""};
7
7
 
8
8
  export function createUiEditorTableOverlay(options = {}) {
9
9
  const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
@@ -72,7 +72,7 @@ export function createUiEditorTableOverlay(options = {}) {
72
72
  element15.setAttribute("type", "button");
73
73
  element15.setAttribute("class", "selector row");
74
74
  element15.setAttribute("data-action", "select-row");
75
- element15.setAttribute("title", "Row actions");
75
+ element15.setAttribute("title", "Drag row to reorder; click for actions");
76
76
  element15.setAttribute("aria-label", "Row actions");
77
77
  const element16 = document.createElement("span");
78
78
  element16.setAttribute("class", "glyph");
@@ -85,7 +85,7 @@ export function createUiEditorTableOverlay(options = {}) {
85
85
  element18.setAttribute("type", "button");
86
86
  element18.setAttribute("class", "selector column");
87
87
  element18.setAttribute("data-action", "select-column");
88
- element18.setAttribute("title", "Column actions");
88
+ element18.setAttribute("title", "Drag column to reorder; click for actions");
89
89
  element18.setAttribute("aria-label", "Column actions");
90
90
  const element19 = document.createElement("span");
91
91
  element19.setAttribute("class", "glyph");
@@ -105,6 +105,12 @@ export function createUiEditorTableOverlay(options = {}) {
105
105
  element22.setAttribute("name", "chevron-down");
106
106
  element21.append(element22);
107
107
  element.append(element21);
108
+ const element23 = document.createElement("span");
109
+ element23.setAttribute("class", "drop-indicator");
110
+ element23.setAttribute("data-drop-indicator", "");
111
+ element23.setAttribute("hidden", "");
112
+ element23.setAttribute("aria-hidden", "true");
113
+ element.append(element23);
108
114
  manageComponentLifecycle(element, definition, { props: componentProps, projected,
109
115
  controller,
110
116
  });
@@ -29,6 +29,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
29
29
  readonly action: "select-row" | "select-column";
30
30
  readonly rowIndex: number;
31
31
  readonly columnIndex: number;
32
+ } | {
33
+ readonly action: "reorder-row" | "reorder-column";
34
+ readonly fromIndex: number;
35
+ readonly toIndex: number;
32
36
  } | {
33
37
  readonly action: "open-cell-menu" | "open-row-menu" | "open-column-menu";
34
38
  readonly rowIndex: number;
@@ -48,6 +52,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
48
52
  readonly action: "select-row" | "select-column";
49
53
  readonly rowIndex: number;
50
54
  readonly columnIndex: number;
55
+ } | {
56
+ readonly action: "reorder-row" | "reorder-column";
57
+ readonly fromIndex: number;
58
+ readonly toIndex: number;
51
59
  } | {
52
60
  readonly action: "open-cell-menu" | "open-row-menu" | "open-column-menu";
53
61
  readonly rowIndex: number;
@@ -44,6 +44,10 @@ const emit = defineEmits<{
44
44
  readonly action: 'select-row' | 'select-column'
45
45
  readonly rowIndex: number
46
46
  readonly columnIndex: number
47
+ } | {
48
+ readonly action: 'reorder-row' | 'reorder-column'
49
+ readonly fromIndex: number
50
+ readonly toIndex: number
47
51
  } | {
48
52
  readonly action: 'open-cell-menu' | 'open-row-menu' | 'open-column-menu'
49
53
  readonly rowIndex: number
@@ -121,6 +125,14 @@ const isActionDetail = (detail: unknown): boolean =>
121
125
  && Object.keys(detail as object).every((key) =>
122
126
  ['action', 'rowIndex', 'columnIndex'].includes(key)
123
127
  ))
128
+ || (detail !== null && typeof detail === 'object' && !Array.isArray(detail)
129
+ && ((detail as Record<string, unknown>)['action'] === 'reorder-row'
130
+ || (detail as Record<string, unknown>)['action'] === 'reorder-column')
131
+ && Number.isInteger((detail as Record<string, unknown>)['fromIndex'])
132
+ && Number.isInteger((detail as Record<string, unknown>)['toIndex'])
133
+ && Object.keys(detail as object).every((key) =>
134
+ ['action', 'fromIndex', 'toIndex'].includes(key)
135
+ ))
124
136
  || (detail !== null && typeof detail === 'object' && !Array.isArray(detail)
125
137
  && ((detail as Record<string, unknown>)['action'] === 'open-cell-menu'
126
138
  || (detail as Record<string, unknown>)['action'] === 'open-row-menu'
@@ -231,7 +243,7 @@ useComponentHost(controllerModule.default, {
231
243
  type="button"
232
244
  class="selector row"
233
245
  data-action="select-row"
234
- title="Row actions"
246
+ title="Drag row to reorder; click for actions"
235
247
  aria-label="Row actions"
236
248
  :data-row-index="hovered?.rowIndex"
237
249
  :data-column-index="hovered?.columnIndex"
@@ -243,7 +255,7 @@ useComponentHost(controllerModule.default, {
243
255
  type="button"
244
256
  class="selector column"
245
257
  data-action="select-column"
246
- title="Column actions"
258
+ title="Drag column to reorder; click for actions"
247
259
  aria-label="Column actions"
248
260
  :data-row-index="hovered?.rowIndex"
249
261
  :data-column-index="hovered?.columnIndex"
@@ -264,6 +276,7 @@ useComponentHost(controllerModule.default, {
264
276
  >
265
277
  <UiIcon name="chevron-down" />
266
278
  </button>
279
+ <span class="drop-indicator" data-drop-indicator="" hidden="" aria-hidden="true"></span>
267
280
  </div>
268
281
  </template>
269
282
 
@@ -491,6 +504,12 @@ useComponentHost(controllerModule.default, {
491
504
 
492
505
  .selector {
493
506
  border-radius: var(--ui-radius-round);
507
+ touch-action: none;
508
+ cursor: grab;
509
+ }
510
+
511
+ .selector:active {
512
+ cursor: grabbing;
494
513
  }
495
514
 
496
515
  .selector::before {
@@ -576,6 +595,30 @@ useComponentHost(controllerModule.default, {
576
595
  --_ui-default-icon-stroke-width: 2;
577
596
  }
578
597
 
598
+ .drop-indicator {
599
+ position: absolute;
600
+ z-index: 3;
601
+ background: var(--ui-accent-solid);
602
+ box-shadow: 0 0 0 2px var(--ui-surface);
603
+ pointer-events: none;
604
+ }
605
+
606
+ .drop-indicator.row {
607
+ left: 0;
608
+ width: 100%;
609
+ height: 2px;
610
+ }
611
+
612
+ .drop-indicator.column {
613
+ top: 0;
614
+ width: 2px;
615
+ height: 100%;
616
+ }
617
+
618
+ .drop-indicator[hidden] {
619
+ display: none;
620
+ }
621
+
579
622
  [data-component~="ui-editor-table-overlay"][hidden] {
580
623
  display: none;
581
624
  }
@@ -381,10 +381,12 @@ function attribute(value: unknown): any {
381
381
  }
382
382
 
383
383
  .menu {
384
+ box-sizing: border-box;
384
385
  position: absolute;
385
386
  top: calc(100% + var(--ui-space-2));
386
387
  right: 0;
387
388
  min-width: 12rem;
389
+ max-width: min(17rem, calc(100vw - 24px));
388
390
  padding: var(--ui-space-1);
389
391
  background: var(--ui-surface);
390
392
  border: 1px solid var(--ui-border-strong);
@@ -394,6 +396,9 @@ function attribute(value: unknown): any {
394
396
  flex-direction: column;
395
397
  gap: 2px;
396
398
  z-index: 2;
399
+ overflow-y: auto;
400
+ overscroll-behavior: contain;
401
+ scrollbar-width: thin;
397
402
  }
398
403
 
399
404
  .menu-section + .menu-section {
@@ -420,7 +425,7 @@ function attribute(value: unknown): any {
420
425
 
421
426
  .swatches {
422
427
  display: grid;
423
- grid-template-columns: repeat(3, minmax(0, 1fr));
428
+ grid-template-columns: repeat(2, minmax(0, 1fr));
424
429
  gap: 2px;
425
430
  }
426
431
 
@@ -434,7 +439,7 @@ function attribute(value: unknown): any {
434
439
  height: 14px;
435
440
  flex: 0 0 14px;
436
441
  border: 1px solid color-mix(in srgb, var(--ui-border) 80%, #000);
437
- border-radius: 3px;
442
+ border-radius: var(--ui-radius-round);
438
443
  background: var(--_swatch);
439
444
  }
440
445