@threadlabs/looma 0.1.13 → 0.1.15

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 (69) hide show
  1. package/dist/{chunk-DQZJTDIB.js → chunk-SVINNT3E.js} +29 -27
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/looma.cjs.js +1 -1
  4. package/dist/cjs/ui-tree-item.cjs.entry.js +694 -0
  5. package/dist/cjs/ui-tree.cjs.entry.js +257 -0
  6. package/dist/collection/collection-manifest.json +3 -1
  7. package/dist/collection/components/ui-tree/ui-tree.css +11 -0
  8. package/dist/collection/components/ui-tree/ui-tree.js +252 -0
  9. package/dist/collection/components/ui-tree-item/ui-tree-item.css +213 -0
  10. package/dist/collection/components/ui-tree-item/ui-tree-item.js +347 -0
  11. package/dist/collection/utils/drag-drop.js +51 -0
  12. package/dist/components/index.d.ts +4 -0
  13. package/dist/components/index.js +1 -1
  14. package/dist/components/ui-tree-item.d.ts +11 -0
  15. package/dist/components/ui-tree-item.js +13 -0
  16. package/dist/components/ui-tree.d.ts +11 -0
  17. package/dist/components/ui-tree.js +1 -0
  18. package/dist/esm/loader.js +1 -1
  19. package/dist/esm/looma.js +1 -1
  20. package/dist/esm/ui-tree-item.entry.js +692 -0
  21. package/dist/esm/ui-tree.entry.js +255 -0
  22. package/dist/index.cjs +687 -15
  23. package/dist/index.d.cts +17 -1
  24. package/dist/index.d.ts +17 -1
  25. package/dist/index.js +44 -3
  26. package/dist/looma/looma.esm.js +1 -1
  27. package/dist/looma/p-95368dee.entry.js +1 -0
  28. package/dist/looma/p-ef9ca2ed.entry.js +13 -0
  29. package/dist/types/components/ui-tree/ui-tree.d.ts +28 -0
  30. package/dist/types/components/ui-tree-item/ui-tree-item.d.ts +36 -0
  31. package/dist/types/components.d.ts +176 -0
  32. package/dist/types/utils/drag-drop.d.ts +15 -0
  33. package/dist/{ui-affordance-scope.entry-SWTDTGGU.js → ui-affordance-scope.entry-PFP2TDKO.js} +1 -1
  34. package/dist/{ui-avatar-group.entry-VUYE2XOM.js → ui-avatar-group.entry-DQDP325O.js} +1 -1
  35. package/dist/{ui-avatar.entry-2CKHEJTS.js → ui-avatar.entry-WYIDMOFE.js} +1 -1
  36. package/dist/{ui-badge.entry-4SWSD3R5.js → ui-badge.entry-VGHXPEDT.js} +1 -1
  37. package/dist/{ui-button.entry-SS3AS32R.js → ui-button.entry-LKPLOJ22.js} +1 -1
  38. package/dist/{ui-checkbox.entry-V7OYTOLW.js → ui-checkbox.entry-J74HEA22.js} +1 -1
  39. package/dist/{ui-context-menu.entry-UCLTQESP.js → ui-context-menu.entry-MQM2FCLI.js} +1 -1
  40. package/dist/{ui-dialog.entry-PXIVZF7D.js → ui-dialog.entry-DQMMDO4Z.js} +1 -1
  41. package/dist/{ui-disclosure.entry-ZADBPM2D.js → ui-disclosure.entry-ONF7UZDC.js} +1 -1
  42. package/dist/{ui-floating-action-button.entry-WNBWY36T.js → ui-floating-action-button.entry-FKTGVC5T.js} +1 -1
  43. package/dist/{ui-form-field.entry-RZPSWN6Y.js → ui-form-field.entry-M3ISWQNU.js} +1 -1
  44. package/dist/{ui-icon-button.entry-ILU7RD7M.js → ui-icon-button.entry-AWFIQUHM.js} +1 -1
  45. package/dist/{ui-input.entry-FEIUK4EE.js → ui-input.entry-JZ6RETMT.js} +1 -1
  46. package/dist/{ui-menu-item.entry-UJVECPSK.js → ui-menu-item.entry-5MFR5LFL.js} +1 -1
  47. package/dist/{ui-menu.entry-MTCE3F5U.js → ui-menu.entry-IOEIDATQ.js} +1 -1
  48. package/dist/{ui-popover.entry-OAME35VB.js → ui-popover.entry-ELCMKO6Y.js} +1 -1
  49. package/dist/{ui-radio-group.entry-CPFX4LVA.js → ui-radio-group.entry-RJHUPPEM.js} +1 -1
  50. package/dist/{ui-radio.entry-44OTRYPB.js → ui-radio.entry-3VRDPOY4.js} +1 -1
  51. package/dist/{ui-search-result-row.entry-ZU5SL5OP.js → ui-search-result-row.entry-J34YPAV7.js} +1 -1
  52. package/dist/{ui-search-shell.entry-G7HG4RKU.js → ui-search-shell.entry-IJ4UUP27.js} +1 -1
  53. package/dist/{ui-select.entry-NAONXMFG.js → ui-select.entry-C6YD3HQ5.js} +1 -1
  54. package/dist/{ui-switch.entry-SE4ZTCS2.js → ui-switch.entry-UZDF5QTI.js} +1 -1
  55. package/dist/{ui-tabs.entry-2YG2JE3K.js → ui-tabs.entry-YRAKWOMR.js} +1 -1
  56. package/dist/{ui-textarea.entry-PV3APDLY.js → ui-textarea.entry-JLDKFT3K.js} +1 -1
  57. package/dist/{ui-toast-region.entry-WH2OL3FR.js → ui-toast-region.entry-GC7C7KXF.js} +1 -1
  58. package/dist/{ui-tooltip.entry-FY563DP4.js → ui-tooltip.entry-F26XDTYX.js} +1 -1
  59. package/dist/{ui-top-bar.entry-LJSZXFAH.js → ui-top-bar.entry-5W5UA5KV.js} +1 -1
  60. package/dist/ui-tree-item.entry-3LM7IXIK.js +385 -0
  61. package/dist/ui-tree.entry-X4FU42A6.js +244 -0
  62. package/editor.css +42 -0
  63. package/package.json +1 -1
  64. package/styles.css +18 -6
  65. package/vue/{chunk-YN4IUYVY.js → chunk-IITL6UBR.js} +7 -1
  66. package/vue/editor/index.d.ts +41 -3
  67. package/vue/editor/index.js +273 -4
  68. package/vue/index.d.ts +24 -1
  69. package/vue/index.js +5 -1
@@ -0,0 +1,244 @@
1
+ import {
2
+ dispatchDetail
3
+ } from "./chunk-UL7UIUJZ.js";
4
+ import {
5
+ Host,
6
+ getElement,
7
+ h,
8
+ registerInstance
9
+ } from "./chunk-SVINNT3E.js";
10
+
11
+ // dist/esm/ui-tree.entry.js
12
+ function classifyDropPosition(rect, clientY, acceptsChildren) {
13
+ const progress = rect.height > 0 ? Math.min(1, Math.max(0, (clientY - rect.top) / rect.height)) : 0.5;
14
+ if (!acceptsChildren)
15
+ return progress < 0.5 ? "before" : "after";
16
+ if (progress < 0.25)
17
+ return "before";
18
+ if (progress > 0.75)
19
+ return "after";
20
+ return "inside";
21
+ }
22
+ function setElementDragImage(dataTransfer, element) {
23
+ if (!dataTransfer || typeof dataTransfer.setDragImage !== "function")
24
+ return;
25
+ const { height } = element.getBoundingClientRect();
26
+ dataTransfer.setDragImage(element, 16, Math.max(0, height / 2));
27
+ }
28
+ function createHoverIntent(delay, onIntent) {
29
+ let timer;
30
+ let pendingKey;
31
+ function cancel() {
32
+ if (timer)
33
+ clearTimeout(timer);
34
+ timer = void 0;
35
+ pendingKey = void 0;
36
+ }
37
+ return {
38
+ schedule(key) {
39
+ if (pendingKey === key && timer)
40
+ return;
41
+ cancel();
42
+ pendingKey = key;
43
+ timer = setTimeout(() => {
44
+ timer = void 0;
45
+ const resolvedKey = pendingKey;
46
+ pendingKey = void 0;
47
+ if (resolvedKey)
48
+ onIntent(resolvedKey);
49
+ }, Math.max(0, delay));
50
+ },
51
+ cancel,
52
+ destroy: cancel
53
+ };
54
+ }
55
+ var uiTreeCss = () => `:host{--ui-tree-indent:16px;display:block;min-inline-size:0;padding-inline-start:var(--ui-tree-gutter, 22px)}::slotted(ui-tree-item){--ui-tree-indent:inherit}`;
56
+ var UITree = class {
57
+ constructor(hostRef) {
58
+ registerInstance(this, hostRef);
59
+ }
60
+ get host() {
61
+ return getElement(this);
62
+ }
63
+ label = "Tree";
64
+ hoverExpandDelay = 700;
65
+ source = null;
66
+ target = null;
67
+ position = null;
68
+ hoverIntent = null;
69
+ componentDidLoad() {
70
+ this.hoverIntent = createHoverIntent(this.hoverExpandDelay, this.expandTarget);
71
+ this.host.addEventListener("dragstart", this.onDragStart);
72
+ this.host.addEventListener("dragover", this.onDragOver);
73
+ this.host.addEventListener("dragleave", this.onDragLeave);
74
+ this.host.addEventListener("drop", this.onDrop);
75
+ this.host.addEventListener("dragend", this.onDragEnd);
76
+ this.host.addEventListener("keydown", this.onKeyDown);
77
+ }
78
+ disconnectedCallback() {
79
+ this.hoverIntent?.destroy();
80
+ this.host.removeEventListener("dragstart", this.onDragStart);
81
+ this.host.removeEventListener("dragover", this.onDragOver);
82
+ this.host.removeEventListener("dragleave", this.onDragLeave);
83
+ this.host.removeEventListener("drop", this.onDrop);
84
+ this.host.removeEventListener("dragend", this.onDragEnd);
85
+ this.host.removeEventListener("keydown", this.onKeyDown);
86
+ }
87
+ itemFromEvent(event) {
88
+ return event.composedPath().find((node) => node instanceof HTMLElement && node.localName === "ui-tree-item") ?? null;
89
+ }
90
+ itemId(item) {
91
+ return item.itemId || item.getAttribute("item-id") || "";
92
+ }
93
+ rowFor(item) {
94
+ return item.shadowRoot?.querySelector('[part="row"]') ?? null;
95
+ }
96
+ acceptsChildren(item) {
97
+ return Boolean(item.container ?? item.hasAttribute("container")) && !Boolean(item.disabled ?? item.hasAttribute("disabled"));
98
+ }
99
+ itemMetadata(item) {
100
+ return {
101
+ type: item.getAttribute("data-drag-type") || item.getAttribute("drag-type") || "item",
102
+ scope: item.getAttribute("data-drop-scope") || item.getAttribute("drop-scope") || "",
103
+ accepts: (item.getAttribute("data-accepts") || item.getAttribute("accepts") || "").split(",").map((value) => value.trim()).filter(Boolean)
104
+ };
105
+ }
106
+ permitsDrop(source, target, position) {
107
+ if (source.contains(target))
108
+ return false;
109
+ const sourceMeta = this.itemMetadata(source);
110
+ const targetMeta = this.itemMetadata(target);
111
+ if (position === "inside") {
112
+ return this.acceptsChildren(target) && (targetMeta.accepts.length === 0 || targetMeta.accepts.includes(sourceMeta.type));
113
+ }
114
+ return sourceMeta.type === targetMeta.type;
115
+ }
116
+ clearTarget() {
117
+ this.target?.removeAttribute("data-drop-position");
118
+ this.target = null;
119
+ this.position = null;
120
+ this.hoverIntent?.cancel();
121
+ }
122
+ finishDrag() {
123
+ this.source?.removeAttribute("data-dragging");
124
+ this.source = null;
125
+ this.clearTarget();
126
+ }
127
+ expandTarget = (itemId) => {
128
+ const item = Array.from(this.host.querySelectorAll("ui-tree-item")).find((candidate) => this.itemId(candidate) === itemId);
129
+ if (!item || item.getAttribute("aria-expanded") !== "false")
130
+ return;
131
+ item.dispatchEvent(new CustomEvent("ui-tree-auto-expand"));
132
+ };
133
+ onDragStart = (event) => {
134
+ const item = this.itemFromEvent(event);
135
+ if (!item || !Boolean(item.sortable ?? item.hasAttribute("sortable")) || Boolean(item.disabled ?? item.hasAttribute("disabled")))
136
+ return;
137
+ const fromHandle = event.composedPath().some((node) => node instanceof HTMLElement && node.getAttribute("part") === "drag-handle");
138
+ if (!fromHandle) {
139
+ event.preventDefault();
140
+ return;
141
+ }
142
+ const sourceId = this.itemId(item);
143
+ const row = this.rowFor(item);
144
+ if (!sourceId || !row) {
145
+ event.preventDefault();
146
+ return;
147
+ }
148
+ this.source = item;
149
+ item.setAttribute("data-dragging", "true");
150
+ if (event.dataTransfer) {
151
+ event.dataTransfer.effectAllowed = "move";
152
+ event.dataTransfer.setData("text/plain", sourceId);
153
+ }
154
+ setElementDragImage(event.dataTransfer, row);
155
+ };
156
+ onDragOver = (event) => {
157
+ if (!this.source)
158
+ return;
159
+ const target = this.itemFromEvent(event);
160
+ if (!target || target === this.source) {
161
+ this.clearTarget();
162
+ return;
163
+ }
164
+ const row = this.rowFor(target);
165
+ if (!row)
166
+ return;
167
+ const position = classifyDropPosition(row.getBoundingClientRect(), event.clientY, this.acceptsChildren(target));
168
+ if (!this.permitsDrop(this.source, target, position)) {
169
+ if (event.dataTransfer)
170
+ event.dataTransfer.dropEffect = "none";
171
+ this.clearTarget();
172
+ return;
173
+ }
174
+ event.preventDefault();
175
+ if (event.dataTransfer)
176
+ event.dataTransfer.dropEffect = "move";
177
+ if (this.target !== target || this.position !== position) {
178
+ this.clearTarget();
179
+ this.target = target;
180
+ this.position = position;
181
+ target.setAttribute("data-drop-position", position);
182
+ }
183
+ if (position === "inside" && target.getAttribute("aria-expanded") === "false") {
184
+ this.hoverIntent?.schedule(this.itemId(target));
185
+ } else {
186
+ this.hoverIntent?.cancel();
187
+ }
188
+ };
189
+ onDragLeave = (event) => {
190
+ const related = event.relatedTarget;
191
+ if (related instanceof Node && this.host.contains(related))
192
+ return;
193
+ this.clearTarget();
194
+ };
195
+ onDrop = (event) => {
196
+ if (!this.source || !this.target || !this.position)
197
+ return;
198
+ event.preventDefault();
199
+ const sourceId = this.itemId(this.source);
200
+ const targetId = this.itemId(this.target);
201
+ if (sourceId && targetId) {
202
+ const sourceMeta = this.itemMetadata(this.source);
203
+ const targetMeta = this.itemMetadata(this.target);
204
+ dispatchDetail(this.host, "reorder", {
205
+ sourceId,
206
+ targetId,
207
+ position: this.position,
208
+ sourceType: sourceMeta.type,
209
+ targetType: targetMeta.type,
210
+ sourceScope: sourceMeta.scope,
211
+ targetScope: targetMeta.scope,
212
+ trigger: "pointer"
213
+ });
214
+ }
215
+ this.finishDrag();
216
+ };
217
+ onDragEnd = () => {
218
+ this.finishDrag();
219
+ };
220
+ visibleItems() {
221
+ return Array.from(this.host.querySelectorAll("ui-tree-item")).filter((item) => item.getClientRects().length > 0 && !item.hasAttribute("disabled"));
222
+ }
223
+ onKeyDown = (event) => {
224
+ const current = this.itemFromEvent(event);
225
+ if (!current)
226
+ return;
227
+ const items = this.visibleItems();
228
+ const index = items.indexOf(current);
229
+ if (index < 0)
230
+ return;
231
+ const next = event.key === "ArrowDown" ? items[index + 1] : event.key === "ArrowUp" ? items[index - 1] : null;
232
+ if (!next)
233
+ return;
234
+ event.preventDefault();
235
+ next.focus();
236
+ };
237
+ render() {
238
+ return h(Host, { key: "5761d2840d2694340a4b937d46522f15f81973ac", role: "tree", "aria-label": this.label || "Tree" }, h("slot", { key: "08e5a7b489eed4f4eae9de6462104fd12defd336" }));
239
+ }
240
+ };
241
+ UITree.style = uiTreeCss();
242
+ export {
243
+ UITree as ui_tree
244
+ };
package/editor.css CHANGED
@@ -149,10 +149,16 @@
149
149
 
150
150
  .looma-editor .ProseMirror img {
151
151
  max-width: 100%;
152
+ height: auto;
152
153
  margin: var(--ui-space-3) 0;
153
154
  border-radius: var(--ui-radius-2);
154
155
  }
155
156
 
157
+ .looma-editor .ProseMirror img[data-looma-image]:focus-visible {
158
+ outline: 2px solid var(--ui-focus-ring);
159
+ outline-offset: 3px;
160
+ }
161
+
156
162
  .looma-editor__file-input {
157
163
  position: absolute;
158
164
  width: 0;
@@ -161,6 +167,42 @@
161
167
  pointer-events: none;
162
168
  }
163
169
 
170
+ .looma-editor__upload-error {
171
+ display: flex;
172
+ align-items: center;
173
+ justify-content: space-between;
174
+ gap: var(--ui-space-3);
175
+ margin-top: var(--ui-space-3);
176
+ padding: var(--ui-space-2) var(--ui-space-3);
177
+ border: 1px solid var(--ui-danger-solid);
178
+ border-radius: var(--ui-radius-2);
179
+ background: var(--ui-danger-soft);
180
+ color: var(--ui-text);
181
+ font-size: var(--ui-font-size-sm);
182
+ }
183
+
184
+ .looma-editor__upload-error button {
185
+ min-height: 2rem;
186
+ padding: 0 var(--ui-space-3);
187
+ border: 0;
188
+ border-radius: var(--ui-radius-1);
189
+ background: var(--ui-danger-solid);
190
+ color: var(--ui-text-on-accent);
191
+ cursor: pointer;
192
+ font: inherit;
193
+ font-weight: var(--ui-font-semibold);
194
+ }
195
+
196
+ .looma-editor__upload-error button:focus-visible {
197
+ outline: 2px solid var(--ui-focus-ring);
198
+ outline-offset: 2px;
199
+ }
200
+
201
+ .looma-editor__upload-error button:disabled {
202
+ cursor: wait;
203
+ opacity: 0.65;
204
+ }
205
+
164
206
  .looma-editor__drop-overlay {
165
207
  position: absolute;
166
208
  z-index: var(--ui-editor-drop-overlay-z-index, 10);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@threadlabs/looma",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "type": "module",
5
5
  "description": "Looma web components, responsive layout primitives, a complete editor, and supported Vue adapters.",
6
6
  "license": "MIT",
package/styles.css CHANGED
@@ -18,7 +18,9 @@
18
18
  ui-radio,
19
19
  ui-badge,
20
20
  ui-avatar,
21
- ui-avatar-group
21
+ ui-avatar-group,
22
+ ui-tree,
23
+ ui-tree-item
22
24
  ),
23
25
  :where(
24
26
  ui-button,
@@ -39,7 +41,9 @@
39
41
  ui-radio,
40
42
  ui-badge,
41
43
  ui-avatar,
42
- ui-avatar-group
44
+ ui-avatar-group,
45
+ ui-tree,
46
+ ui-tree-item
43
47
  ) *,
44
48
  :where(
45
49
  ui-button,
@@ -60,7 +64,9 @@
60
64
  ui-radio,
61
65
  ui-badge,
62
66
  ui-avatar,
63
- ui-avatar-group
67
+ ui-avatar-group,
68
+ ui-tree,
69
+ ui-tree-item
64
70
  ) *::before,
65
71
  :where(
66
72
  ui-button,
@@ -81,7 +87,9 @@
81
87
  ui-radio,
82
88
  ui-badge,
83
89
  ui-avatar,
84
- ui-avatar-group
90
+ ui-avatar-group,
91
+ ui-tree,
92
+ ui-tree-item
85
93
  ) *::after {
86
94
  box-sizing: border-box;
87
95
  }
@@ -105,7 +113,9 @@
105
113
  ui-radio,
106
114
  ui-badge,
107
115
  ui-avatar,
108
- ui-avatar-group
116
+ ui-avatar-group,
117
+ ui-tree,
118
+ ui-tree-item
109
119
  ) {
110
120
  /* Reveal Looma's component layer instead of reverting past it. */
111
121
  all: revert-layer;
@@ -136,7 +146,9 @@
136
146
  ui-radio,
137
147
  ui-badge,
138
148
  ui-avatar,
139
- ui-avatar-group
149
+ ui-avatar-group,
150
+ ui-tree,
151
+ ui-tree-item
140
152
  )[data-ui-inherit-typography] {
141
153
  font-family: inherit;
142
154
  font-size: inherit;
@@ -131,6 +131,8 @@ var FloatingActionButton = createAdapterComponent(
131
131
  var SearchShell = createAdapterComponent("ui-search-shell", "SearchShell");
132
132
  var SearchResultRow = createAdapterComponent("ui-search-result-row", "SearchResultRow");
133
133
  var TopBar = createAdapterComponent("ui-top-bar", "TopBar");
134
+ var Tree = createAdapterComponent("ui-tree", "Tree", [["reorder", "onReorder"]]);
135
+ var TreeItem = createAdapterComponent("ui-tree-item", "TreeItem", [["expand", "onExpand"]]);
134
136
  var ADAPTER_COMPONENT_TAG_MAP = {
135
137
  Stack: "ui-stack",
136
138
  Inline: "ui-inline",
@@ -167,7 +169,9 @@ var ADAPTER_COMPONENT_TAG_MAP = {
167
169
  FloatingActionButton: "ui-floating-action-button",
168
170
  SearchShell: "ui-search-shell",
169
171
  SearchResultRow: "ui-search-result-row",
170
- TopBar: "ui-top-bar"
172
+ TopBar: "ui-top-bar",
173
+ Tree: "ui-tree",
174
+ TreeItem: "ui-tree-item"
171
175
  };
172
176
  var VUE_ADAPTER_NOTE = "Thin adapter only: attrs and slots pass through to custom elements and DOM events map to typed callbacks.";
173
177
 
@@ -210,6 +214,8 @@ export {
210
214
  SearchShell,
211
215
  SearchResultRow,
212
216
  TopBar,
217
+ Tree,
218
+ TreeItem,
213
219
  ADAPTER_COMPONENT_TAG_MAP,
214
220
  VUE_ADAPTER_NOTE
215
221
  };
@@ -4,6 +4,7 @@ import * as vue from 'vue';
4
4
  import { PropType } from 'vue';
5
5
  import { TableContextMenuActionEventDetail, InsertTableEventDetail, TableOverlayActionEventDetail, SlashMenuHighlightEventDetail, SlashMenuSelectEventDetail } from '@threadlabs/looma/editor/ui';
6
6
  import { JSONContent, AnyExtension, Editor } from '@tiptap/core';
7
+ import { OverlayTrigger } from '@threadlabs/looma/core';
7
8
 
8
9
  interface VueEditorAdapterEventMap {
9
10
  tableAction: TableContextMenuActionEventDetail;
@@ -87,9 +88,33 @@ declare const EDITOR_ADAPTER_COMPONENT_TAG_MAP: {
87
88
  readonly EditorTableOverlay: "ui-editor-table-overlay";
88
89
  };
89
90
 
90
- interface LoomaImageUploadResult {
91
- url: string;
91
+ interface LoomaImageDescriptor {
92
+ src: string;
92
93
  alt?: string;
94
+ width?: number;
95
+ height?: number;
96
+ responsive?: boolean;
97
+ }
98
+ /** Browser-only attributes resolved by a host image-delivery provider. */
99
+ interface LoomaImageRenditionAttributes {
100
+ src?: string;
101
+ srcset?: string;
102
+ sizes?: string;
103
+ loading?: "eager" | "lazy";
104
+ decoding?: "async" | "auto" | "sync";
105
+ fetchPriority?: "auto" | "high" | "low";
106
+ }
107
+ type LoomaImageAttributeResolver = (image: LoomaImageDescriptor) => LoomaImageRenditionAttributes | undefined;
108
+ type LoomaImageActivationTrigger = Exclude<OverlayTrigger, "programmatic">;
109
+ interface LoomaImageActivationDetail extends LoomaImageDescriptor {
110
+ trigger: LoomaImageActivationTrigger;
111
+ }
112
+ interface LoomaImageRenditionErrorDetail extends LoomaImageDescriptor {
113
+ trigger: "programmatic";
114
+ }
115
+
116
+ interface LoomaImageUploadResult extends Omit<LoomaImageDescriptor, "src"> {
117
+ url: string;
93
118
  }
94
119
  type LoomaImageUploader = (file: File) => Promise<string | LoomaImageUploadResult>;
95
120
  declare const LoomaEditor: vue.DefineComponent<vue.ExtractPropTypes<{
@@ -124,6 +149,10 @@ declare const LoomaEditor: vue.DefineComponent<vue.ExtractPropTypes<{
124
149
  type: PropType<LoomaImageUploader | undefined>;
125
150
  default: undefined;
126
151
  };
152
+ resolveImageAttributes: {
153
+ type: PropType<LoomaImageAttributeResolver | undefined>;
154
+ default: undefined;
155
+ };
127
156
  }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
128
157
  [key: string]: any;
129
158
  }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
@@ -131,6 +160,8 @@ declare const LoomaEditor: vue.DefineComponent<vue.ExtractPropTypes<{
131
160
  update: (_value: JSONContent) => true;
132
161
  ready: (_editor: Editor) => true;
133
162
  uploadError: (_error: unknown, _file: File) => true;
163
+ imageActivate: (_detail: LoomaImageActivationDetail) => true;
164
+ imageRenditionError: (_detail: LoomaImageRenditionErrorDetail) => true;
134
165
  }, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
135
166
  modelValue: {
136
167
  type: PropType<JSONContent>;
@@ -163,17 +194,24 @@ declare const LoomaEditor: vue.DefineComponent<vue.ExtractPropTypes<{
163
194
  type: PropType<LoomaImageUploader | undefined>;
164
195
  default: undefined;
165
196
  };
197
+ resolveImageAttributes: {
198
+ type: PropType<LoomaImageAttributeResolver | undefined>;
199
+ default: undefined;
200
+ };
166
201
  }>> & Readonly<{
167
202
  "onUpdate:modelValue"?: (_value: JSONContent) => any;
168
203
  onUpdate?: (_value: JSONContent) => any;
169
204
  onReady?: (_editor: Editor) => any;
170
205
  onUploadError?: (_error: unknown, _file: File) => any;
206
+ onImageActivate?: (_detail: LoomaImageActivationDetail) => any;
207
+ onImageRenditionError?: (_detail: LoomaImageRenditionErrorDetail) => any;
171
208
  }>, {
172
209
  placeholder: string;
173
210
  modelValue: JSONContent;
174
211
  editable: boolean;
175
212
  extensions: AnyExtension[];
176
213
  uploadImage: LoomaImageUploader | undefined;
214
+ resolveImageAttributes: LoomaImageAttributeResolver | undefined;
177
215
  }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
178
216
 
179
- export { EDITOR_ADAPTER_COMPONENT_TAG_MAP, EditorInsertTableGrid, EditorSlashMenu, EditorTableContextMenu, EditorTableOverlay, EditorTableToolbar, EditorToolbar, LoomaEditor, type LoomaImageUploadResult, type LoomaImageUploader, type VueEditorAdapterEventMap };
217
+ export { EDITOR_ADAPTER_COMPONENT_TAG_MAP, EditorInsertTableGrid, EditorSlashMenu, EditorTableContextMenu, EditorTableOverlay, EditorTableToolbar, EditorToolbar, LoomaEditor, type LoomaImageActivationDetail, type LoomaImageActivationTrigger, type LoomaImageAttributeResolver, type LoomaImageDescriptor, type LoomaImageRenditionAttributes, type LoomaImageRenditionErrorDetail, type LoomaImageUploadResult, type LoomaImageUploader, type VueEditorAdapterEventMap };