@threadlabs/looma 0.2.20 → 0.3.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.
- package/dist/{chunk-A5MSXQ7Y.js → chunk-3NVMCHGR.js} +2225 -1255
- package/dist/chunk-XDNZIKNI.js +2721 -0
- package/dist/declarative-generated.cjs +93 -79
- package/dist/declarative-generated.d.cts +7 -1
- package/dist/declarative-generated.d.ts +7 -1
- package/dist/declarative-generated.js +91 -78
- package/dist/declarative.cjs +1499 -1702
- package/dist/declarative.d.cts +77 -3
- package/dist/declarative.d.ts +77 -3
- package/dist/declarative.js +5 -3
- package/dist/index.cjs +3732 -3025
- package/dist/index.d.cts +211 -35
- package/dist/index.d.ts +211 -35
- package/dist/index.js +6 -61
- package/dist/loader.cjs +3725 -2962
- package/dist/loader.js +2 -2
- package/editor/{chunk-VAXI7Q6T.js → chunk-U36XNFJN.js} +105 -77
- package/editor/extensions/index.d.ts +272 -27
- package/editor/index.d.ts +1 -1
- package/editor/index.js +1 -1
- package/editor/{table-overlay-DoiLie4h.d.ts → table-overlay-DZFGHQDt.d.ts} +48 -6
- package/editor/ui.d.ts +15 -11
- package/editor/ui.js +1 -1
- package/layout/index.cjs +197 -340
- package/layout/index.d.cts +11 -0
- package/layout/index.d.ts +11 -0
- package/layout/index.js +197 -340
- package/layout.css +31 -134
- package/package.json +24 -11
- package/react/index.d.ts +1276 -0
- package/react/index.js +1526 -0
- package/styles.css +5 -10
- package/svelte/index.d.ts +204 -0
- package/svelte/index.js +1881 -0
- package/theme-dark.css +81 -2
- package/theme-high-contrast.css +14 -0
- package/theme-light.css +30 -1
- package/tokens.css +45 -1
- package/vue/chunk-UZMTYDP6.js +4355 -0
- package/vue/editor/index.d.ts +78 -8
- package/vue/editor/index.js +54 -49
- package/vue/index.d.ts +67 -78
- package/vue/index.js +3 -9
- package/dist/chunk-ECJQ4YGC.js +0 -2925
- package/dist/valibot.cjs +0 -31
- package/dist/valibot.d.cts +0 -10
- package/dist/valibot.d.ts +0 -10
- package/dist/valibot.js +0 -9
- package/dist/validation-bxcou-l-.d.cts +0 -58
- package/dist/validation-bxcou-l-.d.ts +0 -58
- package/vue/chunk-P7BZ2KJZ.js +0 -3559
package/dist/loader.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
// src/ui.ts
|
|
6
6
|
import { registerLoomaPackage } from "@threadlabs/looma/core/declarative";
|
|
7
7
|
|
|
8
|
-
//
|
|
8
|
+
// src/declarative/components/controllers/ui-editor-insert-table-grid.js
|
|
9
9
|
var ui_editor_insert_table_grid_exports = {};
|
|
10
10
|
__export(ui_editor_insert_table_grid_exports, {
|
|
11
11
|
default: () => controller
|
|
@@ -20,7 +20,8 @@ function controller(host) {
|
|
|
20
20
|
let selectedCols = 3;
|
|
21
21
|
let previewRows = null;
|
|
22
22
|
let previewCols = null;
|
|
23
|
-
let
|
|
23
|
+
let lastHeaderRow = Boolean(host.state.headerRow);
|
|
24
|
+
let withHeaderRow = lastHeaderRow;
|
|
24
25
|
let selectionCommitted = false;
|
|
25
26
|
const updateSelection = () => {
|
|
26
27
|
const activeRows = previewRows ?? selectedRows;
|
|
@@ -34,6 +35,11 @@ function controller(host) {
|
|
|
34
35
|
}
|
|
35
36
|
};
|
|
36
37
|
const render = () => {
|
|
38
|
+
const configuredHeaderRow = Boolean(host.state.headerRow);
|
|
39
|
+
if (configuredHeaderRow !== lastHeaderRow) {
|
|
40
|
+
lastHeaderRow = configuredHeaderRow;
|
|
41
|
+
withHeaderRow = configuredHeaderRow;
|
|
42
|
+
}
|
|
37
43
|
element.hidden = !host.state.open;
|
|
38
44
|
if (!host.state.open) return;
|
|
39
45
|
const maxRows = bounded(host.state.maxRows, 8);
|
|
@@ -65,7 +71,7 @@ function controller(host) {
|
|
|
65
71
|
return;
|
|
66
72
|
}
|
|
67
73
|
if (event.target.closest?.("[data-insert-table]")) {
|
|
68
|
-
host.dispatch("
|
|
74
|
+
host.dispatch("insert", { rows: selectedRows, cols: selectedCols, withHeaderRow });
|
|
69
75
|
}
|
|
70
76
|
};
|
|
71
77
|
const onMouseover = (event) => {
|
|
@@ -98,13 +104,13 @@ function controller(host) {
|
|
|
98
104
|
};
|
|
99
105
|
}
|
|
100
106
|
|
|
101
|
-
//
|
|
107
|
+
// src/declarative/components/controllers/ui-editor-mention-menu.js
|
|
102
108
|
var ui_editor_mention_menu_exports = {};
|
|
103
109
|
__export(ui_editor_mention_menu_exports, {
|
|
104
110
|
default: () => controller2
|
|
105
111
|
});
|
|
106
112
|
|
|
107
|
-
//
|
|
113
|
+
// src/declarative/components/controllers/shared/editor.js
|
|
108
114
|
var backgrounds = [
|
|
109
115
|
["background-none", "Default", ""],
|
|
110
116
|
["background-gray", "Gray", "#f3f4f6"],
|
|
@@ -168,7 +174,7 @@ function viewport() {
|
|
|
168
174
|
return { left, top, width, height, right: left + width, bottom: top + height };
|
|
169
175
|
}
|
|
170
176
|
|
|
171
|
-
//
|
|
177
|
+
// src/declarative/components/controllers/ui-editor-mention-menu.js
|
|
172
178
|
function controller2(host) {
|
|
173
179
|
const element = host.element;
|
|
174
180
|
let selectedIndex = Number(host.state.selectedIndex ?? 0);
|
|
@@ -220,7 +226,7 @@ function controller2(host) {
|
|
|
220
226
|
const onMousedown = (event) => event.preventDefault();
|
|
221
227
|
const onClick = (event) => {
|
|
222
228
|
const option = event.target.closest?.("[data-index]");
|
|
223
|
-
if (option) host.dispatch("
|
|
229
|
+
if (option) host.dispatch("select", { index: Number(option.dataset.index) });
|
|
224
230
|
};
|
|
225
231
|
const onMouseover = (event) => {
|
|
226
232
|
const option = event.target.closest?.("[data-index]");
|
|
@@ -228,7 +234,7 @@ function controller2(host) {
|
|
|
228
234
|
if (!Number.isFinite(index) || index === selectedIndex) return;
|
|
229
235
|
selectedIndex = index;
|
|
230
236
|
syncSelection();
|
|
231
|
-
host.dispatch("
|
|
237
|
+
host.dispatch("highlight", { index });
|
|
232
238
|
};
|
|
233
239
|
const onViewport = () => {
|
|
234
240
|
if (host.state.open) position();
|
|
@@ -256,7 +262,7 @@ function controller2(host) {
|
|
|
256
262
|
};
|
|
257
263
|
}
|
|
258
264
|
|
|
259
|
-
//
|
|
265
|
+
// src/declarative/components/controllers/ui-editor-slash-menu.js
|
|
260
266
|
var ui_editor_slash_menu_exports = {};
|
|
261
267
|
__export(ui_editor_slash_menu_exports, {
|
|
262
268
|
default: () => controller3
|
|
@@ -308,7 +314,7 @@ function controller3(host) {
|
|
|
308
314
|
const onMousedown = (event) => event.preventDefault();
|
|
309
315
|
const onClick = (event) => {
|
|
310
316
|
const option = event.target.closest?.("[data-index]");
|
|
311
|
-
if (option) host.dispatch("
|
|
317
|
+
if (option) host.dispatch("select", { index: Number(option.dataset.index) });
|
|
312
318
|
};
|
|
313
319
|
const onMouseover = (event) => {
|
|
314
320
|
const option = event.target.closest?.("[data-index]");
|
|
@@ -316,7 +322,7 @@ function controller3(host) {
|
|
|
316
322
|
if (!Number.isFinite(index) || index === selectedIndex) return;
|
|
317
323
|
selectedIndex = index;
|
|
318
324
|
syncSelection();
|
|
319
|
-
host.dispatch("
|
|
325
|
+
host.dispatch("highlight", { index });
|
|
320
326
|
};
|
|
321
327
|
const onViewport = () => {
|
|
322
328
|
if (host.state.open) position();
|
|
@@ -344,27 +350,27 @@ function controller3(host) {
|
|
|
344
350
|
};
|
|
345
351
|
}
|
|
346
352
|
|
|
347
|
-
//
|
|
353
|
+
// src/declarative/components/controllers/ui-editor-table-context-menu.js
|
|
348
354
|
var ui_editor_table_context_menu_exports = {};
|
|
349
355
|
__export(ui_editor_table_context_menu_exports, {
|
|
350
356
|
default: () => controller4
|
|
351
357
|
});
|
|
352
358
|
var sections = [
|
|
353
359
|
["Structure", [
|
|
354
|
-
["add-row-before", "Add row above", "panel-top"
|
|
355
|
-
["add-row-after", "Add row below", "panel-bottom"
|
|
356
|
-
["add-column-before", "Add column left", "panel-left"
|
|
357
|
-
["add-column-after", "Add column right", "panel-right"
|
|
360
|
+
["add-row-before", "Add row above", "panel-top"],
|
|
361
|
+
["add-row-after", "Add row below", "panel-bottom"],
|
|
362
|
+
["add-column-before", "Add column left", "panel-left"],
|
|
363
|
+
["add-column-after", "Add column right", "panel-right"]
|
|
358
364
|
]],
|
|
359
365
|
["Cells", [
|
|
360
366
|
["clear-cells", "Clear selected cells", "eraser"],
|
|
361
|
-
["merge-cells", "Merge cells", "merge"
|
|
362
|
-
["split-cell", "Split cell", "split"
|
|
367
|
+
["merge-cells", "Merge cells", "merge"],
|
|
368
|
+
["split-cell", "Split cell", "split"]
|
|
363
369
|
]],
|
|
364
370
|
["Table", [
|
|
365
|
-
["delete-row", "Delete row", "trash", "
|
|
366
|
-
["delete-column", "Delete column", "trash", "
|
|
367
|
-
["delete-table", "Delete table", "trash", "
|
|
371
|
+
["delete-row", "Delete row", "trash", "danger"],
|
|
372
|
+
["delete-column", "Delete column", "trash", "danger"],
|
|
373
|
+
["delete-table", "Delete table", "trash", "danger"]
|
|
368
374
|
]]
|
|
369
375
|
];
|
|
370
376
|
function controller4(host) {
|
|
@@ -393,24 +399,25 @@ function controller4(host) {
|
|
|
393
399
|
const render = () => {
|
|
394
400
|
element.hidden = !host.state.open;
|
|
395
401
|
if (!host.state.open) return;
|
|
402
|
+
const enabled = new Set(Array.isArray(host.state.actions) ? host.state.actions : []);
|
|
396
403
|
const background = String(host.state.cellBackground ?? "");
|
|
397
404
|
const rendered = [];
|
|
398
|
-
const swatches = backgrounds.map(([action, label, swatch]) => {
|
|
405
|
+
const swatches = backgrounds.filter(([action]) => enabled.has(action)).map(([action, label, swatch]) => {
|
|
399
406
|
const selected = swatch === background;
|
|
400
407
|
return `<button type="button" class="ui-editor-table-context-menu__swatch-button" role="menuitemradio" aria-checked="${selected}" data-action="${action}"${selected ? ' data-selected="true"' : ""}><span class="ui-editor-table-context-menu__swatch${swatch ? "" : " ui-editor-table-context-menu__swatch--default"}"${swatch ? ` style="--ui-editor-table-context-swatch:${swatch}"` : ""}></span><span class="ui-editor-table-context-menu__swatch-label">${label}</span></button>`;
|
|
401
408
|
}).join("");
|
|
402
|
-
rendered.push(`<div class="ui-editor-table-context-menu__section" role="none"><div class="ui-editor-table-context-menu__heading" role="presentation">Cell background</div><div class="ui-editor-table-context-menu__swatches" role="group" aria-label="Cell background">${swatches}</div></div>`);
|
|
409
|
+
if (swatches) rendered.push(`<div class="ui-editor-table-context-menu__section" role="none"><div class="ui-editor-table-context-menu__heading" role="presentation">Cell background</div><div class="ui-editor-table-context-menu__swatches" role="group" aria-label="Cell background">${swatches}</div></div>`);
|
|
403
410
|
for (const [heading, actions] of sections) {
|
|
404
|
-
const available = actions.filter(([
|
|
411
|
+
const available = actions.filter(([action]) => enabled.has(action));
|
|
405
412
|
if (!available.length) continue;
|
|
406
|
-
rendered.push(`<div class="ui-editor-table-context-menu__sep"></div><div class="ui-editor-table-context-menu__section" role="none"><div class="ui-editor-table-context-menu__heading" role="presentation">${heading}</div>${available.map(([action, label, iconName,
|
|
413
|
+
rendered.push(`<div class="ui-editor-table-context-menu__sep"></div><div class="ui-editor-table-context-menu__section" role="none"><div class="ui-editor-table-context-menu__heading" role="presentation">${heading}</div>${available.map(([action, label, iconName, tone]) => `<button type="button" role="menuitem" data-action="${action}"${tone ? ` data-tone="${tone}"` : ""}>${icon(iconName)}<span>${label}</span></button>`).join("")}</div>`);
|
|
407
414
|
}
|
|
408
415
|
element.innerHTML = `<div class="ui-editor-table-context-menu" role="menu">${rendered.join("")}</div>`;
|
|
409
416
|
schedule();
|
|
410
417
|
};
|
|
411
418
|
const onClick = (event) => {
|
|
412
419
|
const action = event.target.closest?.("[data-action]")?.dataset.action;
|
|
413
|
-
if (action) host.dispatch("
|
|
420
|
+
if (action) host.dispatch("action", { action });
|
|
414
421
|
};
|
|
415
422
|
element.addEventListener("click", onClick);
|
|
416
423
|
window.addEventListener("resize", schedule);
|
|
@@ -428,28 +435,14 @@ function controller4(host) {
|
|
|
428
435
|
};
|
|
429
436
|
}
|
|
430
437
|
|
|
431
|
-
//
|
|
438
|
+
// src/declarative/components/controllers/ui-editor-table-overlay.js
|
|
432
439
|
var ui_editor_table_overlay_exports = {};
|
|
433
440
|
__export(ui_editor_table_overlay_exports, {
|
|
434
441
|
default: () => controller5
|
|
435
442
|
});
|
|
436
|
-
function bounded2(value, fallback) {
|
|
437
|
-
const parsed = Number.parseInt(String(value ?? fallback), 10);
|
|
438
|
-
return Number.isFinite(parsed) ? Math.min(100, Math.max(1, parsed)) : fallback;
|
|
439
|
-
}
|
|
440
443
|
function fallbackBoundaries(segments, length) {
|
|
441
444
|
return Array.from({ length: segments + 1 }, (_, index) => index * length / segments);
|
|
442
445
|
}
|
|
443
|
-
function numbers(value) {
|
|
444
|
-
const values = Array.isArray(value) ? value.map(Number) : typeof value === "string" ? value.split(/[\s,]+/).filter(Boolean).map(Number) : [];
|
|
445
|
-
return values.every(Number.isFinite) ? values : [];
|
|
446
|
-
}
|
|
447
|
-
function cellFrom(value) {
|
|
448
|
-
const values = numbers(value);
|
|
449
|
-
if (values.length !== 6) return null;
|
|
450
|
-
const [left, top, width, height, rowIndex, columnIndex] = values;
|
|
451
|
-
return { left, top, width, height, rowIndex, columnIndex };
|
|
452
|
-
}
|
|
453
446
|
function createProximity(scope, selector = ".ui-editor-table-overlay__handle[data-ui-affordance]", radius = 16) {
|
|
454
447
|
const owner = scope.ownerDocument.defaultView;
|
|
455
448
|
const pointerTarget = scope.ownerDocument;
|
|
@@ -517,13 +510,12 @@ function controller5(host) {
|
|
|
517
510
|
const element = host.element;
|
|
518
511
|
let activeControlKey = null;
|
|
519
512
|
const proximity = createProximity(element);
|
|
520
|
-
const boundaries = (axis
|
|
513
|
+
const boundaries = (axis) => {
|
|
521
514
|
const geometry = host.state.geometry;
|
|
522
|
-
const values = geometry?.[axis === "row" ? "rowBoundaries" : "columnBoundaries"]
|
|
523
|
-
|
|
524
|
-
if (parsed.length === segments + 1) return parsed;
|
|
515
|
+
const values = geometry?.[axis === "row" ? "rowBoundaries" : "columnBoundaries"];
|
|
516
|
+
if (Array.isArray(values) && values.length >= 2 && values.every(Number.isFinite)) return values;
|
|
525
517
|
const rect = element.getBoundingClientRect();
|
|
526
|
-
return fallbackBoundaries(
|
|
518
|
+
return fallbackBoundaries(3, axis === "row" ? rect.height : rect.width);
|
|
527
519
|
};
|
|
528
520
|
const insertion = (axis, index, position) => {
|
|
529
521
|
const first = index === 0;
|
|
@@ -545,13 +537,11 @@ function controller5(host) {
|
|
|
545
537
|
activeControlKey = null;
|
|
546
538
|
return;
|
|
547
539
|
}
|
|
548
|
-
const
|
|
549
|
-
const
|
|
550
|
-
const rowBoundaries = boundaries("row", rows);
|
|
551
|
-
const columnBoundaries = boundaries("column", cols);
|
|
540
|
+
const rowBoundaries = boundaries("row");
|
|
541
|
+
const columnBoundaries = boundaries("column");
|
|
552
542
|
const geometry = host.state.geometry;
|
|
553
|
-
const active = geometry?.activeCell ??
|
|
554
|
-
const hovered = geometry?.hoveredCell ??
|
|
543
|
+
const active = geometry?.activeCell ?? null;
|
|
544
|
+
const hovered = geometry?.hoveredCell ?? null;
|
|
555
545
|
element.innerHTML = `<div class="ui-editor-table-overlay" aria-label="Table controls"><div class="ui-editor-table-overlay__rows">${rowBoundaries.map((position, index) => insertion("row", index, position)).join("")}</div><div class="ui-editor-table-overlay__cols">${columnBoundaries.map((position, index) => insertion("col", index, position)).join("")}</div>${hovered ? selectors(hovered) : ""}${active ? menu(active) : ""}</div>`;
|
|
556
546
|
proximity.refresh();
|
|
557
547
|
};
|
|
@@ -565,15 +555,15 @@ function controller5(host) {
|
|
|
565
555
|
if (!button) return;
|
|
566
556
|
const action = button.dataset.action;
|
|
567
557
|
if (action === "select-row" || action === "select-column") {
|
|
568
|
-
host.dispatch("
|
|
558
|
+
host.dispatch("action", { action, rowIndex: Number(button.dataset.rowIndex), columnIndex: Number(button.dataset.columnIndex) });
|
|
569
559
|
return;
|
|
570
560
|
}
|
|
571
561
|
if (action === "open-cell-menu") {
|
|
572
562
|
const rect = button.getBoundingClientRect();
|
|
573
|
-
host.dispatch("
|
|
563
|
+
host.dispatch("action", { action, rowIndex: Number(button.dataset.rowIndex), columnIndex: Number(button.dataset.columnIndex), anchor: { left: rect.left, top: rect.top, right: rect.right, bottom: rect.bottom } });
|
|
574
564
|
return;
|
|
575
565
|
}
|
|
576
|
-
host.dispatch("
|
|
566
|
+
host.dispatch("action", { action, boundaryIndex: Number(button.dataset.boundaryIndex) });
|
|
577
567
|
};
|
|
578
568
|
const enter = (event) => setActive(event.target.closest?.("[data-control-key]")?.dataset.controlKey ?? null);
|
|
579
569
|
const leave = (event) => setActive(event.relatedTarget instanceof Element ? event.relatedTarget.closest?.("[data-control-key]")?.dataset.controlKey ?? null : null);
|
|
@@ -595,15 +585,15 @@ function controller5(host) {
|
|
|
595
585
|
};
|
|
596
586
|
}
|
|
597
587
|
|
|
598
|
-
//
|
|
588
|
+
// src/declarative/components/controllers/ui-editor-table-toolbar.js
|
|
599
589
|
var ui_editor_table_toolbar_exports = {};
|
|
600
590
|
__export(ui_editor_table_toolbar_exports, {
|
|
601
591
|
default: () => controller6
|
|
602
592
|
});
|
|
603
593
|
var overflowSections = [
|
|
604
|
-
["Structure", [["add-row-before", "Add row above", "panel-top"
|
|
605
|
-
["Cells", [["clear-cells", "Clear selected cells", "eraser"], ["merge-cells", "Merge selected cells", "merge"
|
|
606
|
-
["Table", [["delete-row", "Delete row", "trash", "
|
|
594
|
+
["Structure", [["add-row-before", "Add row above", "panel-top"], ["add-column-before", "Add column left", "panel-left"]]],
|
|
595
|
+
["Cells", [["clear-cells", "Clear selected cells", "eraser"], ["merge-cells", "Merge selected cells", "merge"], ["split-cell", "Split merged cell", "split"]]],
|
|
596
|
+
["Table", [["delete-row", "Delete row", "trash", "danger"], ["delete-column", "Delete column", "trash", "danger"], ["delete-table", "Delete table", "trash", "danger"]]]
|
|
607
597
|
];
|
|
608
598
|
function controller6(host) {
|
|
609
599
|
const element = host.element;
|
|
@@ -614,18 +604,24 @@ function controller6(host) {
|
|
|
614
604
|
overflowOpen = false;
|
|
615
605
|
return;
|
|
616
606
|
}
|
|
607
|
+
const enabled = new Set(Array.isArray(host.state.actions) ? host.state.actions : []);
|
|
617
608
|
const active = `align-${host.state.cellAlignment === "center" || host.state.cellAlignment === "right" ? host.state.cellAlignment : "left"}`;
|
|
618
|
-
const alignments = [["align-left", "Align left"], ["align-center", "Align center"], ["align-right", "Align right"]];
|
|
619
|
-
const structure = [["add-row-after", "Add row", "rows"
|
|
609
|
+
const alignments = [["align-left", "Align left"], ["align-center", "Align center"], ["align-right", "Align right"]].filter(([action]) => enabled.has(action));
|
|
610
|
+
const structure = [["add-row-after", "Add row", "rows"], ["add-column-after", "Add column", "columns"]].filter(([action]) => enabled.has(action));
|
|
620
611
|
const background = String(host.state.cellBackground ?? "");
|
|
621
|
-
const
|
|
612
|
+
const backgroundActions = backgrounds.filter(([action]) => enabled.has(action));
|
|
613
|
+
const overflowGroups = overflowSections.map(([heading, actions]) => [heading, actions.filter(([action]) => enabled.has(action))]);
|
|
614
|
+
const hasOverflow = backgroundActions.length > 0 || overflowGroups.some(([, actions]) => actions.length > 0);
|
|
615
|
+
if (!hasOverflow) overflowOpen = false;
|
|
616
|
+
const menu = overflowOpen ? `<div class="ui-editor-table-toolbar__menu" role="menu" aria-label="More table actions">${backgroundActions.length ? `<div class="ui-editor-table-toolbar__menu-section" role="none"><div class="ui-editor-table-toolbar__menu-heading" role="presentation">Background</div><div class="ui-editor-table-toolbar__swatches" role="group" aria-label="Cell background">${backgroundActions.map(([action, label, swatch]) => {
|
|
622
617
|
const selected = swatch === background;
|
|
623
618
|
return `<button type="button" class="ui-editor-table-toolbar__swatch-button" role="menuitemradio" aria-checked="${selected}" data-action="${action}"${selected ? ' data-selected="true"' : ""}><span class="ui-editor-table-toolbar__swatch${swatch ? "" : " ui-editor-table-toolbar__swatch--default"}"${swatch ? ` style="--ui-editor-table-toolbar-swatch:${swatch}"` : ""}></span><span>${label}</span></button>`;
|
|
624
|
-
}).join("")}</div></div
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
}).join("")}</div>`
|
|
628
|
-
|
|
619
|
+
}).join("")}</div></div>` : ""}${overflowGroups.map(([heading, actions]) => actions.length ? `<div class="ui-editor-table-toolbar__menu-section ui-editor-table-toolbar__menu-section--divided" role="none"><div class="ui-editor-table-toolbar__menu-heading" role="presentation">${heading}</div>${actions.map(([action, label, iconName, tone]) => `<button type="button" role="menuitem" data-action="${action}"${tone ? ` data-tone="${tone}"` : ""}>${icon(iconName)}<span>${label}</span></button>`).join("")}</div>` : "").join("")}</div>` : "";
|
|
620
|
+
const groups = [];
|
|
621
|
+
if (alignments.length) groups.push(`<div class="ui-editor-table-toolbar__group" role="group" aria-label="Cell alignment">${alignments.map(([action, label]) => `<button type="button" class="ui-editor-table-toolbar__icon-button" data-action="${action}" aria-label="${label}" title="${label}" aria-pressed="${action === active}" data-active="${action === active}">${icon(action)}</button>`).join("")}</div>`);
|
|
622
|
+
if (structure.length) groups.push(`<div class="ui-editor-table-toolbar__group" role="group" aria-label="Table structure">${structure.map(([action, label, iconName]) => `<button type="button" data-action="${action}">${icon(iconName)}<span>${label}</span></button>`).join("")}</div>`);
|
|
623
|
+
if (hasOverflow) groups.push(`<div class="ui-editor-table-toolbar__overflow"><button type="button" class="ui-editor-table-toolbar__more" data-action="toggle-overflow" aria-haspopup="menu" aria-expanded="${overflowOpen}">${icon("table")}<span>Table options</span>${icon("chevron-down", "looma-icon looma-icon--chevron")}</button>${menu}</div>`);
|
|
624
|
+
element.innerHTML = `<div class="ui-editor-table-toolbar" role="toolbar" aria-label="Table actions">${groups.join('<div class="ui-editor-table-toolbar__sep" aria-hidden="true"></div>')}</div>`;
|
|
629
625
|
};
|
|
630
626
|
const onClick = (event) => {
|
|
631
627
|
const action = event.target.closest?.("[data-action]")?.dataset.action;
|
|
@@ -637,7 +633,7 @@ function controller6(host) {
|
|
|
637
633
|
}
|
|
638
634
|
overflowOpen = false;
|
|
639
635
|
render();
|
|
640
|
-
host.dispatch("
|
|
636
|
+
host.dispatch("action", { action });
|
|
641
637
|
};
|
|
642
638
|
const onOutside = (event) => {
|
|
643
639
|
if (!overflowOpen || event.composedPath().includes(element)) return;
|
|
@@ -655,7 +651,7 @@ function controller6(host) {
|
|
|
655
651
|
};
|
|
656
652
|
}
|
|
657
653
|
|
|
658
|
-
//
|
|
654
|
+
// src/declarative/components/controllers/ui-editor-toolbar.js
|
|
659
655
|
var ui_editor_toolbar_exports = {};
|
|
660
656
|
__export(ui_editor_toolbar_exports, {
|
|
661
657
|
default: () => controller7
|
|
@@ -666,14 +662,14 @@ function controller7(host) {
|
|
|
666
662
|
if (!element.hasAttribute("aria-label")) element.setAttribute("aria-label", "Editor toolbar");
|
|
667
663
|
}
|
|
668
664
|
|
|
669
|
-
//
|
|
665
|
+
// src/declarative/registry.js
|
|
670
666
|
var records = [
|
|
671
|
-
{ tag: "ui-editor-insert-table-grid", source: '<template component="ui-editor-insert-table-grid" status="early" summary="Looma ui-editor-insert-table-grid editor surface." controller="./controllers/ui-editor-insert-table-grid.js">\n <defs>\n <prop name="open" type="boolean" default="false">open value.</prop>\n <prop name="maxRows" type="integer" default="8">maxRows value.</prop>\n <prop name="maxCols" type="integer" default="8">maxCols value.</prop>\n <event name="
|
|
672
|
-
{ tag: "ui-editor-mention-menu", source: '<template component="ui-editor-mention-menu" status="early" summary="Looma ui-editor-mention-menu editor surface." controller="./controllers/ui-editor-mention-menu.js">\n <defs>\n <prop name="open" type="boolean" default="false">open value.</prop>\n <prop name="query" type="string" default="">query value.</prop>\n <prop name="items" type="list(object({ id: string, label: string, detail?: string, initials?: string }))">items value.</prop>\n <prop name="selectedIndex" type="integer" default="0">selectedIndex value.</prop>\n <prop name="loading" type="boolean" default="false">loading value.</prop>\n <prop name="anchorRect" type="object({ left?: number, top?: number, right?: number, bottom?: number, x?: number, y?: number, width?: number, height?: number }) | null">anchorRect value.</prop>\n <event name="
|
|
673
|
-
{ tag: "ui-editor-slash-menu", source: '<template component="ui-editor-slash-menu" status="early" summary="Looma ui-editor-slash-menu editor surface." controller="./controllers/ui-editor-slash-menu.js">\n <defs>\n <prop name="open" type="boolean" default="false">open value.</prop>\n <prop name="query" type="string" default="">query value.</prop>\n <prop name="items" type="list(object({ title: string, description: string, icon: string }))">items value.</prop>\n <prop name="selectedIndex" type="integer" default="0">selectedIndex value.</prop>\n <prop name="anchorRect" type="object({ left?: number, top?: number, right?: number, bottom?: number, x?: number, y?: number, width?: number, height?: number }) | null">anchorRect value.</prop>\n <event name="
|
|
674
|
-
{ tag: "ui-editor-table-context-menu", source: '<template component="ui-editor-table-context-menu" status="early" summary="
|
|
675
|
-
{ tag: "ui-editor-table-overlay", source: '<template component="ui-editor-table-overlay" status="early" summary="
|
|
676
|
-
{ tag: "ui-editor-table-toolbar", source: '<template component="ui-editor-table-toolbar" status="early" summary="
|
|
667
|
+
{ tag: "ui-editor-insert-table-grid", source: '<template component="ui-editor-insert-table-grid" status="early" summary="Looma ui-editor-insert-table-grid editor surface." controller="./controllers/ui-editor-insert-table-grid.js">\n <defs>\n <prop name="open" type="boolean" default="false">open value.</prop>\n <prop name="maxRows" type="integer" default="8">maxRows value.</prop>\n <prop name="maxCols" type="integer" default="8">maxCols value.</prop>\n <prop name="headerRow" type="boolean" default="false">Whether table insertion initially includes a header row.</prop>\n <event name="insert" type="object({ rows: integer, cols: integer, withHeaderRow: boolean })"></event>\n </defs>\n <div></div>\n</template>\n', controller: ui_editor_insert_table_grid_exports },
|
|
668
|
+
{ tag: "ui-editor-mention-menu", source: '<template component="ui-editor-mention-menu" status="early" summary="Looma ui-editor-mention-menu editor surface." controller="./controllers/ui-editor-mention-menu.js">\n <defs>\n <prop name="open" type="boolean" default="false">open value.</prop>\n <prop name="query" type="string" default="">query value.</prop>\n <prop name="items" type="list(object({ id: string, label: string, detail?: string, initials?: string }))">items value.</prop>\n <prop name="selectedIndex" type="integer" default="0">selectedIndex value.</prop>\n <prop name="loading" type="boolean" default="false">loading value.</prop>\n <prop name="anchorRect" type="object({ left?: number, top?: number, right?: number, bottom?: number, x?: number, y?: number, width?: number, height?: number }) | null">anchorRect value.</prop>\n <event name="highlight" type="object({ index: integer })"></event>\n <event name="select" type="object({ index: integer })"></event>\n </defs>\n <div></div>\n</template>\n', controller: ui_editor_mention_menu_exports },
|
|
669
|
+
{ tag: "ui-editor-slash-menu", source: '<template component="ui-editor-slash-menu" status="early" summary="Looma ui-editor-slash-menu editor surface." controller="./controllers/ui-editor-slash-menu.js">\n <defs>\n <prop name="open" type="boolean" default="false">open value.</prop>\n <prop name="query" type="string" default="">query value.</prop>\n <prop name="items" type="list(object({ title: string, description: string, icon: string }))">items value.</prop>\n <prop name="selectedIndex" type="integer" default="0">selectedIndex value.</prop>\n <prop name="anchorRect" type="object({ left?: number, top?: number, right?: number, bottom?: number, x?: number, y?: number, width?: number, height?: number }) | null">anchorRect value.</prop>\n <event name="highlight" type="object({ index: integer })"></event>\n <event name="select" type="object({ index: integer })"></event>\n </defs>\n <div></div>\n</template>\n', controller: ui_editor_slash_menu_exports },
|
|
670
|
+
{ tag: "ui-editor-table-context-menu", source: '<template component="ui-editor-table-context-menu" status="early" summary="Presents the table commands an editor explicitly enables for the current cell selection." controller="./controllers/ui-editor-table-context-menu.js">\n <defs>\n <prop name="open" type="boolean" default="false">Shows the menu at the position owned by the editor integration.</prop>\n <prop name="cellBackground" type="string" default="">Identifies the background choice that is active for the current cell.</prop>\n <prop name="actions" type="list(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)">The complete set of commands the current selection permits; omitted commands are not rendered.</prop>\n <event name="action" type="object({ action: string })"></event>\n </defs>\n <div></div>\n</template>\n', controller: ui_editor_table_context_menu_exports },
|
|
671
|
+
{ tag: "ui-editor-table-overlay", source: '<template component="ui-editor-table-overlay" status="early" summary="Projects editor-measured table geometry into insertion, selection, and cell-action controls without owning document mutations." controller="./controllers/ui-editor-table-overlay.js">\n <defs>\n <prop name="open" type="boolean" default="false">Shows the controls after the editor has supplied current geometry.</prop>\n <prop name="geometry" type="object({ rowBoundaries: list(number), columnBoundaries: list(number), activeCell: object({ left: number, top: number, width: number, height: number, rowIndex: integer, columnIndex: integer }) | null, hoveredCell?: object({ left: number, top: number, width: number, height: number, rowIndex: integer, columnIndex: integer }) | null }) | null">The authoritative editor-measured table boundaries and active or hovered cell rectangles.</prop>\n <event name="action" type="object({ action: string, boundaryIndex?: integer, rowIndex?: integer, columnIndex?: integer, anchor?: object({ left: number, top: number, right: number, bottom: number }) })"></event>\n </defs>\n <div></div>\n</template>\n', controller: ui_editor_table_overlay_exports },
|
|
672
|
+
{ tag: "ui-editor-table-toolbar", source: '<template component="ui-editor-table-toolbar" status="early" summary="Offers selection-aware table commands without deciding which mutations the editor performs." controller="./controllers/ui-editor-table-toolbar.js">\n <defs>\n <prop name="open" type="boolean" default="false">Shows the toolbar while a table selection is active.</prop>\n <prop name="cellAlignment" type="left | center | right" default="left">Marks the alignment command that is active for the current cell.</prop>\n <prop name="cellBackground" type="string" default="">Identifies the background choice that is active for the current cell.</prop>\n <prop name="actions" type="list(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)">The complete set of commands the current selection permits; omitted commands are not rendered.</prop>\n <event name="action" type="object({ action: string })"></event>\n </defs>\n <div></div>\n</template>\n', controller: ui_editor_table_toolbar_exports },
|
|
677
673
|
{ tag: "ui-editor-toolbar", source: '<template component="ui-editor-toolbar" status="early" summary="Looma ui-editor-toolbar editor surface." controller="./controllers/ui-editor-toolbar.js">\n <defs>\n\n </defs>\n <div><slot></slot></div>\n</template>\n', controller: ui_editor_toolbar_exports }
|
|
678
674
|
];
|
|
679
675
|
var styles = `/**
|
|
@@ -983,6 +979,38 @@ var styles = `/**
|
|
|
983
979
|
stroke-width: var(--ui-editor-toolbar-icon-stroke-width, 1.75);
|
|
984
980
|
}
|
|
985
981
|
|
|
982
|
+
.looma-editor__sticky-toolbar-shell {
|
|
983
|
+
position: sticky;
|
|
984
|
+
top: var(--ui-editor-sticky-toolbar-top, 0);
|
|
985
|
+
z-index: var(--ui-editor-toolbar-z-index, 10);
|
|
986
|
+
min-width: 0;
|
|
987
|
+
background: var(--ui-editor-toolbar-bg, var(--ui-surface, #fff));
|
|
988
|
+
border-bottom: 1px solid var(--ui-editor-toolbar-border, var(--ui-border, #e5e7eb));
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
.looma-editor__sticky-toolbar-shell [data-component-root~="ui-editor-toolbar"] {
|
|
992
|
+
display: flex;
|
|
993
|
+
align-items: center;
|
|
994
|
+
justify-content: flex-start;
|
|
995
|
+
gap: var(--ui-editor-toolbar-gap, 2px);
|
|
996
|
+
min-height: var(--ui-editor-toolbar-min-height, 48px);
|
|
997
|
+
padding:
|
|
998
|
+
var(--ui-editor-toolbar-padding-block, 6px)
|
|
999
|
+
var(--ui-editor-toolbar-padding-inline, 12px);
|
|
1000
|
+
overflow-x: auto;
|
|
1001
|
+
overscroll-behavior-inline: contain;
|
|
1002
|
+
scrollbar-width: none;
|
|
1003
|
+
white-space: nowrap;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
.looma-editor__sticky-toolbar-shell [data-component-root~="ui-editor-toolbar"]::-webkit-scrollbar {
|
|
1007
|
+
display: none;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
.looma-editor__sticky-toolbar-shell [data-component-root~="ui-editor-toolbar"] > * {
|
|
1011
|
+
flex: 0 0 auto;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
986
1014
|
.looma-editor__table-picker-popover,
|
|
987
1015
|
.looma-editor__table-toolbar-shell,
|
|
988
1016
|
.looma-editor__table-menu-shell {
|
|
@@ -2425,7 +2453,7 @@ if (typeof HTMLElement !== "undefined") {
|
|
|
2425
2453
|
}
|
|
2426
2454
|
dispatch(detail) {
|
|
2427
2455
|
this.dispatchEvent(new CustomEvent(
|
|
2428
|
-
"
|
|
2456
|
+
"action",
|
|
2429
2457
|
{ detail, bubbles: true, composed: true }
|
|
2430
2458
|
));
|
|
2431
2459
|
}
|