@threadlabs/looma 0.31.1 → 0.31.3

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.
@@ -1,4 +1,4 @@
1
- import { computed, defineComponent, h, nextTick, onBeforeUnmount, onMounted, onUpdated, reactive, ref, shallowRef, useId, watch } from "vue";
1
+ import { Teleport, computed, defineComponent, h, nextTick, onBeforeUnmount, onMounted, onUpdated, reactive, ref, shallowRef, useId, watch } from "vue";
2
2
  import { DEFAULT_MENTION_RESULT_LIMIT, LOOMA_ICONS, createLoomaMentionExtension, createLoomaSlashCommandExtension, getActiveTableUiState, getDefaultEditorExtensions, getDefaultSlashCommands, getTableOfContentsEntries, getVisualViewportRect, handleTableAction, handleTableOverlayAction, measureTableOverlayGeometry, normalizeActiveTableColumnWidths, normalizeTableOfContentsConfig } from "@threadlabs/looma/editor";
3
3
  import { Button, Card, EditorBlockActions, EditorChipEditor, EditorCodeLanguage, EditorFootnoteEditor, EditorImageToolbar, EditorInsertTableGrid, EditorLinkCard, EditorLinkForm, EditorMentionMenu, EditorMentionMenuItem, EditorSlashMenu, EditorSlashMenuGroup, EditorSlashMenuItem, EditorSurface, EditorTableContextMenu, EditorTableOverlay, EditorTableToolbar, EditorToolbar, IconButton, Popover, Stack, StatusMessage, Text, Tooltip } from "@threadlabs/looma/vue";
4
4
  import { Editor, Extension, InputRule, Node as Node$1, PasteRule, getText, getTextSerializersFromSchema, isNodeSelection, mergeAttributes, nodeInputRule, posToDOMRect } from "@tiptap/core";
@@ -427,7 +427,8 @@ function createViewportSurface$1(surface, options = {}) {
427
427
  else Object.assign(surface.style, {
428
428
  padding: "0",
429
429
  border: "0",
430
- background: "transparent"
430
+ background: "transparent",
431
+ overflow: "visible"
431
432
  });
432
433
  }
433
434
  const hideSurface = () => {
@@ -2291,25 +2292,10 @@ function tableControls(state, selectionInTable, narrow) {
2291
2292
  capabilities: state.capabilities
2292
2293
  };
2293
2294
  }
2294
- /** Space, in pixels, the toolbar needs above a table; with less it sits below. */
2295
- var ROOM_ABOVE$1 = 76;
2296
- /**
2297
- * Centers the table toolbar on the table, at most 420px wide and 12px inside the viewport's sides,
2298
- * above the table when there is room and below it otherwise.
2299
- */
2300
- function tableToolbarPlacement(table, viewportWidth) {
2301
- const width = Math.min(420, viewportWidth - 24);
2302
- const left = Math.min(Math.max(12, table.left + (table.width - width) / 2), Math.max(12, viewportWidth - width - 12));
2303
- return {
2304
- top: `${table.top > ROOM_ABOVE$1 ? table.top - 52 : table.bottom + 12}px`,
2305
- left: `${left}px`,
2306
- maxWidth: `${width}px`
2307
- };
2308
- }
2309
- /** The overlay covers the table exactly. */
2310
- var tableOverlayPlacement = (table) => ({
2311
- top: `${table.top}px`,
2312
- left: `${table.left}px`,
2295
+ /** Inline controls cover the table in the editor's coordinate system. */
2296
+ var tableOverlayPlacement = (table, editor) => ({
2297
+ top: `${table.top - editor.top}px`,
2298
+ left: `${table.left - editor.left}px`,
2313
2299
  width: `${table.width}px`,
2314
2300
  height: `${table.height}px`
2315
2301
  });
@@ -3114,8 +3100,17 @@ function formatEditorShortcut(keys, apple) {
3114
3100
  ].filter(Boolean).join("+");
3115
3101
  }
3116
3102
  var isApplePlatform = () => typeof navigator !== "undefined" && /mac|iphone|ipad|ipod/i.test(navigator.userAgentData?.platform || navigator.platform || navigator.userAgent);
3103
+ //#endregion
3104
+ //#region src/components/shared/tooltip.js
3105
+ /** Resolve the inherited pointer-intent delay; CSS time values and millisecond numbers are accepted. */
3106
+ function tooltipShowDelay$1(element, fallback = 500) {
3107
+ if (!element) return fallback;
3108
+ const value = element.ownerDocument.defaultView.getComputedStyle(element).getPropertyValue("--ui-tooltip-show-delay").trim();
3109
+ const match = /^([0-9]+(?:\.[0-9]+)?)(ms|s)?$/.exec(value);
3110
+ return match ? Number(match[1]) * (match[2] === "s" ? 1e3 : 1) : fallback;
3111
+ }
3117
3112
  /** Calls `onChange` after every state change. */
3118
- function createToolbarTooltip(onChange) {
3113
+ function createToolbarTooltip(onChange, delay = () => 400) {
3119
3114
  let state = {
3120
3115
  for: "",
3121
3116
  label: "",
@@ -3150,7 +3145,7 @@ function createToolbarTooltip(onChange) {
3150
3145
  if (!open) timer = setTimeout(() => {
3151
3146
  timer = void 0;
3152
3147
  set({ open: true });
3153
- }, 400);
3148
+ }, delay());
3154
3149
  },
3155
3150
  hide() {
3156
3151
  clear();
@@ -4770,7 +4765,8 @@ function createViewportSurface(surface, options = {}) {
4770
4765
  else Object.assign(surface.style, {
4771
4766
  padding: "0",
4772
4767
  border: "0",
4773
- background: "transparent"
4768
+ background: "transparent",
4769
+ overflow: "visible"
4774
4770
  });
4775
4771
  }
4776
4772
  const hideSurface = () => {
@@ -8984,6 +8980,14 @@ var S$9 = {
8984
8980
  var D$9 = {
8985
8981
  g: "ui-popover",
8986
8982
  props: {
8983
+ "bare": {
8984
+ "required": false,
8985
+ "default": false,
8986
+ c: checkBoolean,
8987
+ t: "boolean",
8988
+ j: 0,
8989
+ m: "b"
8990
+ },
8987
8991
  "for": {
8988
8992
  "required": false,
8989
8993
  "default": "",
@@ -9053,6 +9057,7 @@ function createUiPopover(options = {}, html) {
9053
9057
  null,
9054
9058
  null,
9055
9059
  null,
9060
+ null,
9056
9061
  null
9057
9062
  ];
9058
9063
  const B = acceptProps(element, D$9, S$9.n, v, componentProps, [], html);
@@ -9060,8 +9065,16 @@ function createUiPopover(options = {}, html) {
9060
9065
  return { n: (P1$7 ??= buildTemplate(T1$7)).cloneNode(true) };
9061
9066
  };
9062
9067
  const p0 = (r, c, d) => {
9063
- if (c & 17) {
9064
- const s0 = hostState(["internalOpen", "size"], [v[0], v[4]]);
9068
+ if (c & 35) {
9069
+ const s0 = hostState([
9070
+ "bare",
9071
+ "internalOpen",
9072
+ "size"
9073
+ ], [
9074
+ v[1],
9075
+ v[0],
9076
+ v[5]
9077
+ ]);
9065
9078
  if (s0 !== r.v0) writeAttribute(r.n, "data-ui-popover-state", (r.v0 = s0) === "" ? null : s0);
9066
9079
  }
9067
9080
  if (r.f0 === void 0) {
@@ -9097,6 +9110,7 @@ function createUiPopover(options = {}, html) {
9097
9110
  return element;
9098
9111
  }
9099
9112
  defineComponent$1("ui-popover", createUiPopover, [
9113
+ "bare",
9100
9114
  "for",
9101
9115
  "open",
9102
9116
  "placement",
@@ -10530,6 +10544,15 @@ defineComponent$1("ui-text", createUiText, [
10530
10544
  "wrap"
10531
10545
  ]);
10532
10546
  //#endregion
10547
+ //#region components/shared/tooltip.js
10548
+ /** Resolve the inherited pointer-intent delay; CSS time values and millisecond numbers are accepted. */
10549
+ function tooltipShowDelay(element, fallback = 500) {
10550
+ if (!element) return fallback;
10551
+ const value = element.ownerDocument.defaultView.getComputedStyle(element).getPropertyValue("--ui-tooltip-show-delay").trim();
10552
+ const match = /^([0-9]+(?:\.[0-9]+)?)(ms|s)?$/.exec(value);
10553
+ return match ? Number(match[1]) * (match[2] === "s" ? 1e3 : 1) : fallback;
10554
+ }
10555
+ //#endregion
10533
10556
  //#region components/ui-tooltip/ui-tooltip.js
10534
10557
  var ui_tooltip_exports = /* @__PURE__ */ __exportAll({ connect: () => connect$4 });
10535
10558
  var warmTooltips = /* @__PURE__ */ new WeakMap();
@@ -10606,7 +10629,7 @@ function connect$4(host) {
10606
10629
  showTimer = setTimeout(() => {
10607
10630
  showTimer = null;
10608
10631
  setOpen(true, "pointer");
10609
- }, warm.active > 0 || warm.until > Date.now() ? 0 : Math.max(0, Number(host.props.showDelay.value ?? 500)));
10632
+ }, warm.active > 0 || warm.until > Date.now() ? 0 : Math.max(0, host.props.showDelay.inputValue != null ? Number(host.props.showDelay.value) : tooltipShowDelay(element)));
10610
10633
  };
10611
10634
  const onLeave = () => {
10612
10635
  clearShow();
@@ -10676,6 +10699,7 @@ function connect$4(host) {
10676
10699
  if (how === "hover") {
10677
10700
  trigger.addEventListener("pointerenter", onEnter);
10678
10701
  trigger.addEventListener("pointerleave", onLeave);
10702
+ if (trigger.matches(":hover")) onEnter({ pointerType: "mouse" });
10679
10703
  }
10680
10704
  trigger.addEventListener("focusin", onFocusin);
10681
10705
  trigger.addEventListener("focusout", onFocusout);
@@ -14758,7 +14782,7 @@ var LoomaEditor = defineComponent({
14758
14782
  const toolbarScope = `looma-editor-tool-${useId().replace(/[^a-zA-Z0-9_-]/g, "")}`;
14759
14783
  const toolbarTooltip = createToolbarTooltip((state) => {
14760
14784
  tooltip.value = state;
14761
- });
14785
+ }, () => tooltipShowDelay$1(root.value));
14762
14786
  const tooltip = shallowRef(toolbarTooltip.state);
14763
14787
  const resizeHintFor = ref("");
14764
14788
  let resizeHintSequence = 0;
@@ -14830,7 +14854,7 @@ var LoomaEditor = defineComponent({
14830
14854
  rows: 0,
14831
14855
  cols: 0,
14832
14856
  geometry: null,
14833
- toolbarStyle: {},
14857
+ toolbarTarget: null,
14834
14858
  overlayStyle: {},
14835
14859
  menuStyle: {},
14836
14860
  capabilities: LOOMA_TABLE_CONTROLS_CLOSED.capabilities
@@ -15362,8 +15386,8 @@ var LoomaEditor = defineComponent({
15362
15386
  tableUi.rows = Math.max(0, geometry.rowBoundaries.length - 1);
15363
15387
  tableUi.cols = Math.max(0, geometry.columnBoundaries.length - 1);
15364
15388
  tableUi.geometry = geometry;
15365
- tableUi.toolbarStyle = tableToolbarPlacement(rect, window.innerWidth);
15366
- tableUi.overlayStyle = tableOverlayPlacement(rect);
15389
+ tableUi.toolbarTarget = table.closest("[data-looma-table-block]")?.querySelector("[data-looma-table-toolbar-host]") ?? null;
15390
+ tableUi.overlayStyle = tableOverlayPlacement(rect, root.value.getBoundingClientRect());
15367
15391
  };
15368
15392
  const onEditorFocus = () => {
15369
15393
  editorFocused.value = true;
@@ -15429,13 +15453,10 @@ var LoomaEditor = defineComponent({
15429
15453
  presentation?.show();
15430
15454
  };
15431
15455
  };
15432
- const tableToolbarRef = popupRef(tableToolbarShell);
15433
15456
  const codeLanguageRef = popupRef(codeLanguageShell, true);
15434
15457
  const mobileToolbarRef = popupRef(mobileToolbarShell, true);
15435
- const presentTableOverlay = popupRef(tableOverlayShell);
15436
15458
  const tableOverlayRef = (node) => {
15437
- presentTableOverlay(node);
15438
- if (node instanceof HTMLElement) node.hidden = !tableUi.overlayOpen;
15459
+ tableOverlayShell.value = node instanceof HTMLElement ? node : null;
15439
15460
  };
15440
15461
  const onDocumentPointerDown = (event) => {
15441
15462
  const path = typeof event.composedPath === "function" ? event.composedPath() : [];
@@ -16048,8 +16069,6 @@ var LoomaEditor = defineComponent({
16048
16069
  }, [
16049
16070
  resizeHintFor.value ? h(Tooltip, {
16050
16071
  for: resizeHintFor.value,
16051
- open: true,
16052
- trigger: "focus",
16053
16072
  placement: "top",
16054
16073
  inverse: true
16055
16074
  }, () => "Drag to resize column") : null,
@@ -16065,6 +16084,7 @@ var LoomaEditor = defineComponent({
16065
16084
  }, [props.toolbarMode === "contextual" && floatingFormattingMode() && formattingActive() ? null : renderLinkContextCard(instance)])]) : null,
16066
16085
  instance && props.editable && !mobile.value && props.toolbarMode === "popover" && props.toolbarTriggerId ? h(Popover, {
16067
16086
  class: "looma-editor__formatting-popover",
16087
+ bare: true,
16068
16088
  role: "region",
16069
16089
  "aria-label": "Formatting tools",
16070
16090
  open: props.toolbarOpen,
@@ -16194,6 +16214,7 @@ var LoomaEditor = defineComponent({
16194
16214
  props.editable && props.compactToolbar && !mobile.value ? h(Popover, {
16195
16215
  class: "looma-editor__compact-formatting",
16196
16216
  for: formatAnchorId,
16217
+ bare: true,
16197
16218
  open: formatOpen.value,
16198
16219
  placement: "bottom-start",
16199
16220
  onOpen: () => {
@@ -16263,12 +16284,11 @@ var LoomaEditor = defineComponent({
16263
16284
  mention.select?.(event.detail.index);
16264
16285
  }
16265
16286
  }) : null,
16266
- tableUi.toolbarOpen ? h("div", {
16287
+ tableUi.toolbarOpen && tableUi.toolbarTarget ? h(Teleport, { to: tableUi.toolbarTarget }, [h("div", {
16267
16288
  key: "looma-table-toolbar-shell",
16268
- ref: tableToolbarRef,
16269
- class: "looma-editor__table-toolbar-shell",
16270
- style: tableUi.toolbarStyle
16271
- }, [h(EditorTableToolbar, tableProps)]) : null,
16289
+ ref: tableToolbarShell,
16290
+ class: "looma-editor__table-toolbar-shell"
16291
+ }, [h(EditorTableToolbar, tableProps)])]) : null,
16272
16292
  instance && props.editable && !mobile.value ? h("div", {
16273
16293
  key: "looma-table-overlay-shell",
16274
16294
  ref: tableOverlayRef,