@threadlabs/looma 0.26.24 → 0.26.26
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/components/ui-icon-button/ui-icon-button.html +12 -2
- package/components/ui-tooltip/ui-tooltip.html +2 -1
- package/components/ui-tooltip/ui-tooltip.js +20 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/styles/ui-icon-button.css +9 -2
- package/vanilla/UiIconButton.d.ts +1 -0
- package/vanilla/UiIconButton.js +14 -14
- package/vue/UiIconButton.d.ts +9 -0
- package/vue/UiIconButton.vue +31 -2
- package/vue/UiTooltip.vue +1 -1
- package/vue/chunks/UiIconButton.js +26 -1
- package/vue/chunks/UiTooltip.js +2 -2
- package/vue/components.css +82 -76
- package/vue/editor/index.js +51 -67
package/vue/editor/index.js
CHANGED
|
@@ -1760,6 +1760,7 @@ var LoomaEditor = defineComponent({
|
|
|
1760
1760
|
const linkContextEditing = ref(false);
|
|
1761
1761
|
const linkHref = ref("");
|
|
1762
1762
|
const linkText = ref("");
|
|
1763
|
+
const linkTextEditable = ref(false);
|
|
1763
1764
|
const linkNewTab = ref(true);
|
|
1764
1765
|
const linkError = ref("");
|
|
1765
1766
|
const linkMode = ref("url");
|
|
@@ -2129,6 +2130,8 @@ var LoomaEditor = defineComponent({
|
|
|
2129
2130
|
linkResults.value = [];
|
|
2130
2131
|
linkNewTab.value = false;
|
|
2131
2132
|
linkError.value = "";
|
|
2133
|
+
if (linkTextEditable.value && !linkText.value.trim()) linkText.value = target.label;
|
|
2134
|
+
applyLink();
|
|
2132
2135
|
};
|
|
2133
2136
|
const moveLinkResultFocus = (event, offset) => {
|
|
2134
2137
|
const buttons = [...linkFormRoot.value?.querySelectorAll("[data-link-result]") ?? []];
|
|
@@ -2157,6 +2160,7 @@ var LoomaEditor = defineComponent({
|
|
|
2157
2160
|
to,
|
|
2158
2161
|
existing
|
|
2159
2162
|
};
|
|
2163
|
+
linkTextEditable.value = empty && !existing;
|
|
2160
2164
|
const attrs = existing ? instance.getAttributes("link") : {};
|
|
2161
2165
|
linkHref.value = typeof attrs.href === "string" ? attrs.href : "";
|
|
2162
2166
|
linkNewTab.value = attrs.target !== "_self";
|
|
@@ -2183,36 +2187,40 @@ var LoomaEditor = defineComponent({
|
|
|
2183
2187
|
(linkMode.value === "url" ? linkDestinationInput() : linkFormRoot.value?.querySelector("[data-link-search]"))?.focus();
|
|
2184
2188
|
});
|
|
2185
2189
|
};
|
|
2186
|
-
const
|
|
2190
|
+
const applyLink = (reportError = false) => {
|
|
2187
2191
|
const instance = editor.value;
|
|
2188
2192
|
const selection = linkSelection;
|
|
2189
|
-
if (!instance || !selection) return;
|
|
2193
|
+
if (!instance || !selection) return false;
|
|
2190
2194
|
const href = linkMode.value === "target" ? validLinkHref(linkSelectedTarget.value?.href ?? "") : validLinkHref(linkHref.value);
|
|
2191
2195
|
if (!href) {
|
|
2192
|
-
linkError.value = linkMode.value === "target" ? "Choose a destination from the results." : "Enter an http, https, mailto, tel, or relative URL.";
|
|
2193
|
-
|
|
2194
|
-
return;
|
|
2196
|
+
if (reportError) linkError.value = linkMode.value === "target" ? "Choose a destination from the results." : "Enter an http, https, mailto, tel, or relative URL.";
|
|
2197
|
+
return false;
|
|
2195
2198
|
}
|
|
2196
2199
|
if (linkMode.value === "url" && props.linkSearch && !selection.existing && !/^(https?:|mailto:|tel:)/i.test(href)) {
|
|
2197
|
-
linkError.value = "Enter a full website, email, or phone URL, or choose a destination.";
|
|
2198
|
-
|
|
2199
|
-
return;
|
|
2200
|
+
if (reportError) linkError.value = "Enter a full website, email, or phone URL, or choose a destination.";
|
|
2201
|
+
return false;
|
|
2200
2202
|
}
|
|
2201
2203
|
const attrs = {
|
|
2202
2204
|
href: props.linkBaseUrl ? siteRelativeHref(href, props.linkBaseUrl) : href,
|
|
2203
2205
|
target: linkNewTab.value ? "_blank" : "_self",
|
|
2204
2206
|
rel: linkNewTab.value ? "noopener noreferrer" : null
|
|
2205
2207
|
};
|
|
2206
|
-
const
|
|
2208
|
+
const current = instance.state.selection;
|
|
2209
|
+
const chain = instance.chain().setTextSelection({
|
|
2207
2210
|
from: selection.from,
|
|
2208
2211
|
to: selection.to
|
|
2209
2212
|
});
|
|
2210
|
-
if (
|
|
2213
|
+
if (linkTextEditable.value) {
|
|
2211
2214
|
const text = linkText.value.trim();
|
|
2212
2215
|
if (!text) {
|
|
2213
|
-
linkError.value = "Enter link text.";
|
|
2214
|
-
return;
|
|
2216
|
+
if (reportError) linkError.value = "Enter link text.";
|
|
2217
|
+
return false;
|
|
2215
2218
|
}
|
|
2219
|
+
linkSelection = {
|
|
2220
|
+
from: selection.from,
|
|
2221
|
+
to: selection.from + text.length,
|
|
2222
|
+
existing: true
|
|
2223
|
+
};
|
|
2216
2224
|
chain.insertContent({
|
|
2217
2225
|
type: "text",
|
|
2218
2226
|
text,
|
|
@@ -2220,24 +2228,17 @@ var LoomaEditor = defineComponent({
|
|
|
2220
2228
|
type: "link",
|
|
2221
2229
|
attrs
|
|
2222
2230
|
}]
|
|
2223
|
-
}).run();
|
|
2231
|
+
}).setTextSelection(selection.from).run();
|
|
2224
2232
|
} else {
|
|
2225
2233
|
if (selection.existing && selection.from === selection.to) chain.extendMarkRange("link");
|
|
2226
|
-
chain.setLink(attrs).setTextSelection(
|
|
2234
|
+
chain.setLink(attrs).setTextSelection({
|
|
2235
|
+
from: current.from,
|
|
2236
|
+
to: current.to
|
|
2237
|
+
}).run();
|
|
2238
|
+
selection.existing = true;
|
|
2227
2239
|
}
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
};
|
|
2231
|
-
const removeLink = () => {
|
|
2232
|
-
const instance = editor.value;
|
|
2233
|
-
const selection = linkSelection;
|
|
2234
|
-
if (!instance || !selection?.existing) return;
|
|
2235
|
-
instance.chain().focus().setTextSelection({
|
|
2236
|
-
from: selection.from,
|
|
2237
|
-
to: selection.to
|
|
2238
|
-
}).extendMarkRange("link").unsetLink().setTextSelection(selection.to).run();
|
|
2239
|
-
linkOpen.value = false;
|
|
2240
|
-
linkContextEditing.value = false;
|
|
2240
|
+
linkError.value = "";
|
|
2241
|
+
return true;
|
|
2241
2242
|
};
|
|
2242
2243
|
const removeCurrentLink = () => {
|
|
2243
2244
|
const instance = editor.value;
|
|
@@ -2245,11 +2246,14 @@ var LoomaEditor = defineComponent({
|
|
|
2245
2246
|
instance.chain().focus().extendMarkRange("link").unsetLink().run();
|
|
2246
2247
|
linkContextEditing.value = false;
|
|
2247
2248
|
};
|
|
2248
|
-
const
|
|
2249
|
+
const dismissLink = (restoreFocus = true) => {
|
|
2249
2250
|
linkOpen.value = false;
|
|
2250
2251
|
linkContextEditing.value = false;
|
|
2251
2252
|
const selection = linkSelection;
|
|
2252
|
-
if (selection) editor.value?.chain().focus().setTextSelection(selection.to).run();
|
|
2253
|
+
if (restoreFocus && selection) editor.value?.chain().focus().setTextSelection(selection.to).run();
|
|
2254
|
+
dismissedFormattingSelection = editor.value?.state.selection ?? null;
|
|
2255
|
+
linkPopup?.hide();
|
|
2256
|
+
formattingPopup?.hide();
|
|
2253
2257
|
};
|
|
2254
2258
|
const renderLinkDestination = (mode) => [h(FormField, { invalid: Boolean(linkError.value) }, {
|
|
2255
2259
|
label: () => h("label", props.linkSearch ? "Link destination" : "URL"),
|
|
@@ -2278,6 +2282,7 @@ var LoomaEditor = defineComponent({
|
|
|
2278
2282
|
}
|
|
2279
2283
|
linkHref.value = value;
|
|
2280
2284
|
linkError.value = "";
|
|
2285
|
+
applyLink();
|
|
2281
2286
|
},
|
|
2282
2287
|
onKeydown: (event) => {
|
|
2283
2288
|
if (mode === "target" && event.key === "ArrowDown") moveLinkResultFocus(event, 1);
|
|
@@ -2351,6 +2356,7 @@ var LoomaEditor = defineComponent({
|
|
|
2351
2356
|
checked: linkNewTab.value,
|
|
2352
2357
|
onChange: (event) => {
|
|
2353
2358
|
linkNewTab.value = event.detail.checked;
|
|
2359
|
+
applyLink();
|
|
2354
2360
|
}
|
|
2355
2361
|
}, () => "Open in new tab")];
|
|
2356
2362
|
const renderLinkForm = () => h("form", {
|
|
@@ -2359,7 +2365,18 @@ var LoomaEditor = defineComponent({
|
|
|
2359
2365
|
"aria-label": "Edit link",
|
|
2360
2366
|
onSubmit: (event) => {
|
|
2361
2367
|
event.preventDefault();
|
|
2362
|
-
|
|
2368
|
+
if (applyLink(true)) dismissLink();
|
|
2369
|
+
},
|
|
2370
|
+
onKeydown: (event) => {
|
|
2371
|
+
if (event.key === "Escape") {
|
|
2372
|
+
event.preventDefault();
|
|
2373
|
+
event.stopPropagation();
|
|
2374
|
+
dismissLink();
|
|
2375
|
+
} else if (event.key === "Enter" && event.target instanceof HTMLInputElement) {
|
|
2376
|
+
event.preventDefault();
|
|
2377
|
+
event.stopPropagation();
|
|
2378
|
+
if (applyLink(true)) dismissLink();
|
|
2379
|
+
}
|
|
2363
2380
|
}
|
|
2364
2381
|
}, [h(Stack, { gap: "s" }, () => [
|
|
2365
2382
|
h(Text, {
|
|
@@ -2368,7 +2385,7 @@ var LoomaEditor = defineComponent({
|
|
|
2368
2385
|
weight: "semibold"
|
|
2369
2386
|
}, () => linkSelection?.existing ? "Edit link" : "Add link"),
|
|
2370
2387
|
h(Stack, { gap: "s" }, () => renderLinkDestination(linkMode.value)),
|
|
2371
|
-
|
|
2388
|
+
linkTextEditable.value ? h(FormField, {}, {
|
|
2372
2389
|
label: () => h("label", "Text"),
|
|
2373
2390
|
default: () => h(Input, {
|
|
2374
2391
|
size: "sm",
|
|
@@ -2376,6 +2393,7 @@ var LoomaEditor = defineComponent({
|
|
|
2376
2393
|
onInput: (event) => {
|
|
2377
2394
|
linkText.value = event.target.value;
|
|
2378
2395
|
linkError.value = "";
|
|
2396
|
+
applyLink();
|
|
2379
2397
|
}
|
|
2380
2398
|
})
|
|
2381
2399
|
}) : null,
|
|
@@ -2383,42 +2401,7 @@ var LoomaEditor = defineComponent({
|
|
|
2383
2401
|
size: "sm",
|
|
2384
2402
|
tone: "danger",
|
|
2385
2403
|
role: "alert"
|
|
2386
|
-
}, () => linkError.value) : null
|
|
2387
|
-
h(Separator),
|
|
2388
|
-
h(Cluster, {
|
|
2389
|
-
gap: "xs",
|
|
2390
|
-
justify: "between",
|
|
2391
|
-
wrap: "nowrap"
|
|
2392
|
-
}, () => [linkSelection?.existing ? h(Button, {
|
|
2393
|
-
type: "button",
|
|
2394
|
-
variant: "ghost",
|
|
2395
|
-
tone: "danger",
|
|
2396
|
-
size: "sm",
|
|
2397
|
-
onClick: removeLink
|
|
2398
|
-
}, () => "Remove link") : null, validLinkHref(linkHref.value) ? h(Button, {
|
|
2399
|
-
as: "a",
|
|
2400
|
-
variant: "outline",
|
|
2401
|
-
tone: "accent",
|
|
2402
|
-
size: "sm",
|
|
2403
|
-
href: validLinkHref(linkHref.value),
|
|
2404
|
-
target: "_blank",
|
|
2405
|
-
rel: "noopener noreferrer"
|
|
2406
|
-
}, () => "Open link") : null]),
|
|
2407
|
-
h(Cluster, {
|
|
2408
|
-
gap: "xs",
|
|
2409
|
-
justify: "end",
|
|
2410
|
-
wrap: "nowrap"
|
|
2411
|
-
}, () => [h(Button, {
|
|
2412
|
-
type: "button",
|
|
2413
|
-
variant: "outline",
|
|
2414
|
-
tone: "accent",
|
|
2415
|
-
size: "sm",
|
|
2416
|
-
onClick: cancelLink
|
|
2417
|
-
}, () => "Cancel"), h(Button, {
|
|
2418
|
-
type: "submit",
|
|
2419
|
-
variant: "solid",
|
|
2420
|
-
size: "sm"
|
|
2421
|
-
}, () => "Save link")])
|
|
2404
|
+
}, () => linkError.value) : null
|
|
2422
2405
|
])]);
|
|
2423
2406
|
const renderLinkContext = (instance) => {
|
|
2424
2407
|
if (linkContextEditing.value) return renderLinkForm();
|
|
@@ -2790,6 +2773,7 @@ var LoomaEditor = defineComponent({
|
|
|
2790
2773
|
const onDocumentPointerDown = (event) => {
|
|
2791
2774
|
const path = typeof event.composedPath === "function" ? event.composedPath() : [];
|
|
2792
2775
|
const inElement = (element) => Boolean(element && (path.includes(element) || event.target instanceof Node && element.contains(event.target)));
|
|
2776
|
+
if ((linkOpen.value || linkContextEditing.value) && !inElement(linkFormRoot.value)) dismissLink(false);
|
|
2793
2777
|
const inTableUi = inElement(tableToolbarShell.value) || inElement(tableOverlayShell.value) || inElement(tableMenuShell.value) || inElement(mobileToolbarShell.value);
|
|
2794
2778
|
tableInteractionActive = inTableUi;
|
|
2795
2779
|
if (inTableUi) setTimeout(() => {
|