@threadlabs/looma 0.18.3 → 0.18.5
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-combobox/ui-combobox.html +2 -1
- package/components/ui-combobox/ui-combobox.js +21 -8
- package/components/ui-popover/ui-popover.html +6 -1
- package/dist/index.js +1 -1
- package/editor/chunks/extensions.js +22 -6
- package/package.json +1 -1
- package/styles/ui-popover.css +6 -1
- package/vue/UiPopover.vue +6 -1
- package/vue/chunks/UiPopover.js +1 -1
- package/vue/components.css +81 -9
- package/vue/editor/index.js +111 -55
|
@@ -9205,12 +9205,28 @@ function setActiveTableCellBackground(editor, backgroundColor) {
|
|
|
9205
9205
|
* Default Tiptap extension preset for Looma editor.
|
|
9206
9206
|
* Uses the Vanilla JS Tiptap API; apps provide @tiptap/core and Looma ships the preset extensions.
|
|
9207
9207
|
*/
|
|
9208
|
-
var LoomaCodeBlock = CodeBlockLowlight.extend({
|
|
9209
|
-
|
|
9210
|
-
|
|
9211
|
-
|
|
9212
|
-
|
|
9213
|
-
|
|
9208
|
+
var LoomaCodeBlock = CodeBlockLowlight.extend({
|
|
9209
|
+
renderHTML({ node, HTMLAttributes }) {
|
|
9210
|
+
return [
|
|
9211
|
+
"pre",
|
|
9212
|
+
mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { spellcheck: "false" }),
|
|
9213
|
+
[
|
|
9214
|
+
"code",
|
|
9215
|
+
{
|
|
9216
|
+
class: node.attrs.language ? `${this.options.languageClassPrefix}${node.attrs.language}` : null,
|
|
9217
|
+
spellcheck: "false"
|
|
9218
|
+
},
|
|
9219
|
+
0
|
|
9220
|
+
]
|
|
9221
|
+
];
|
|
9222
|
+
},
|
|
9223
|
+
addInputRules() {
|
|
9224
|
+
return [...this.parent?.() ?? [], textblockTypeInputRule({
|
|
9225
|
+
find: /^```$/,
|
|
9226
|
+
type: this.type
|
|
9227
|
+
})];
|
|
9228
|
+
}
|
|
9229
|
+
});
|
|
9214
9230
|
var StoredOnlyHighlight = Highlight.extend({
|
|
9215
9231
|
parseHTML: () => [],
|
|
9216
9232
|
addKeyboardShortcuts: () => ({}),
|
package/package.json
CHANGED
package/styles/ui-popover.css
CHANGED
|
@@ -23,6 +23,10 @@
|
|
|
23
23
|
syntax: "*";
|
|
24
24
|
inherits: false;
|
|
25
25
|
}
|
|
26
|
+
@property --ui-popover-padding {
|
|
27
|
+
syntax: "*";
|
|
28
|
+
inherits: false;
|
|
29
|
+
}
|
|
26
30
|
@scope ([data-component~="ui-popover"]) to ([data-component], [data-slotted]) {
|
|
27
31
|
/* This component's hooks style the element they are set on, and never a nested one. */
|
|
28
32
|
|
|
@@ -31,6 +35,7 @@
|
|
|
31
35
|
--_ui-popover-border: var(--ui-popover-border);
|
|
32
36
|
--_ui-popover-radius: var(--ui-popover-radius);
|
|
33
37
|
--_ui-popover-shadow: var(--ui-popover-shadow);
|
|
38
|
+
--_ui-popover-padding: var(--ui-popover-padding);
|
|
34
39
|
box-sizing: border-box;
|
|
35
40
|
max-inline-size: min(
|
|
36
41
|
20rem,
|
|
@@ -51,7 +56,7 @@
|
|
|
51
56
|
max-inline-size: inherit;
|
|
52
57
|
max-block-size: inherit;
|
|
53
58
|
overflow: auto;
|
|
54
|
-
padding: var(--ui-space-3);
|
|
59
|
+
padding: var(--_ui-popover-padding, var(--ui-space-3));
|
|
55
60
|
background: var(--_ui-popover-surface, var(--ui-overlay-surface, var(--ui-surface-elevated)));
|
|
56
61
|
border: 1px solid var(--_ui-popover-border, var(--ui-overlay-border, var(--ui-border-strong)));
|
|
57
62
|
border-radius: var(--_ui-popover-radius, var(--ui-overlay-radius, var(--ui-radius-lg)));
|
package/vue/UiPopover.vue
CHANGED
|
@@ -120,12 +120,17 @@ useComponentHost(controllerModule.default, {
|
|
|
120
120
|
syntax: "*";
|
|
121
121
|
inherits: false;
|
|
122
122
|
}
|
|
123
|
+
@property --ui-popover-padding {
|
|
124
|
+
syntax: "*";
|
|
125
|
+
inherits: false;
|
|
126
|
+
}
|
|
123
127
|
|
|
124
128
|
[data-component~="ui-popover"] {
|
|
125
129
|
--_ui-popover-surface: var(--ui-popover-surface);
|
|
126
130
|
--_ui-popover-border: var(--ui-popover-border);
|
|
127
131
|
--_ui-popover-radius: var(--ui-popover-radius);
|
|
128
132
|
--_ui-popover-shadow: var(--ui-popover-shadow);
|
|
133
|
+
--_ui-popover-padding: var(--ui-popover-padding);
|
|
129
134
|
box-sizing: border-box;
|
|
130
135
|
max-inline-size: min(
|
|
131
136
|
20rem,
|
|
@@ -146,7 +151,7 @@ useComponentHost(controllerModule.default, {
|
|
|
146
151
|
max-inline-size: inherit;
|
|
147
152
|
max-block-size: inherit;
|
|
148
153
|
overflow: auto;
|
|
149
|
-
padding: var(--ui-space-3);
|
|
154
|
+
padding: var(--_ui-popover-padding, var(--ui-space-3));
|
|
150
155
|
background: var(--_ui-popover-surface, var(--ui-overlay-surface, var(--ui-surface-elevated)));
|
|
151
156
|
border: 1px solid var(--_ui-popover-border, var(--ui-overlay-border, var(--ui-border-strong)));
|
|
152
157
|
border-radius: var(--_ui-popover-radius, var(--ui-overlay-radius, var(--ui-radius-lg)));
|
package/vue/chunks/UiPopover.js
CHANGED
|
@@ -56,6 +56,6 @@ var UiPopover_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
|
|
|
56
56
|
}), [createElementVNode("div", _hoisted_2, [renderSlot(_ctx.$slots, "default", {}, void 0, true)])], 16, _hoisted_1);
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
|
-
}), [["__scopeId", "data-v-
|
|
59
|
+
}), [["__scopeId", "data-v-fd69c5a5"]]);
|
|
60
60
|
//#endregion
|
|
61
61
|
export { UiPopover_default as t };
|
package/vue/components.css
CHANGED
|
@@ -5732,11 +5732,16 @@ svg[data-v-9828be81-s] {
|
|
|
5732
5732
|
syntax: "*";
|
|
5733
5733
|
inherits: false;
|
|
5734
5734
|
}
|
|
5735
|
-
|
|
5735
|
+
@property --ui-popover-padding {
|
|
5736
|
+
syntax: "*";
|
|
5737
|
+
inherits: false;
|
|
5738
|
+
}
|
|
5739
|
+
[data-component~="ui-popover"][data-v-fd69c5a5] {
|
|
5736
5740
|
--_ui-popover-surface: var(--ui-popover-surface);
|
|
5737
5741
|
--_ui-popover-border: var(--ui-popover-border);
|
|
5738
5742
|
--_ui-popover-radius: var(--ui-popover-radius);
|
|
5739
5743
|
--_ui-popover-shadow: var(--ui-popover-shadow);
|
|
5744
|
+
--_ui-popover-padding: var(--ui-popover-padding);
|
|
5740
5745
|
box-sizing: border-box;
|
|
5741
5746
|
max-inline-size: min(
|
|
5742
5747
|
20rem,
|
|
@@ -5751,12 +5756,12 @@ svg[data-v-9828be81-s] {
|
|
|
5751
5756
|
background: transparent;
|
|
5752
5757
|
box-shadow: none;
|
|
5753
5758
|
}
|
|
5754
|
-
.surface[data-v-
|
|
5759
|
+
.surface[data-v-fd69c5a5] {
|
|
5755
5760
|
box-sizing: border-box;
|
|
5756
5761
|
max-inline-size: inherit;
|
|
5757
5762
|
max-block-size: inherit;
|
|
5758
5763
|
overflow: auto;
|
|
5759
|
-
padding: var(--ui-space-3);
|
|
5764
|
+
padding: var(--_ui-popover-padding, var(--ui-space-3));
|
|
5760
5765
|
background: var(--_ui-popover-surface, var(--ui-overlay-surface, var(--ui-surface-elevated)));
|
|
5761
5766
|
border: 1px solid var(--_ui-popover-border, var(--ui-overlay-border, var(--ui-border-strong)));
|
|
5762
5767
|
border-radius: var(--_ui-popover-radius, var(--ui-overlay-radius, var(--ui-radius-lg)));
|
|
@@ -5765,10 +5770,10 @@ svg[data-v-9828be81-s] {
|
|
|
5765
5770
|
var(--ui-overlay-shadow, var(--ui-elevation-overlay, var(--ui-shadow-lg)))
|
|
5766
5771
|
);
|
|
5767
5772
|
}
|
|
5768
|
-
[data-component~="ui-popover"][data-v-
|
|
5773
|
+
[data-component~="ui-popover"][data-v-fd69c5a5]:not([data-component~="ui-popover"][data-ui-popover-state~="internalOpen"]) {
|
|
5769
5774
|
display: none;
|
|
5770
5775
|
}
|
|
5771
|
-
[data-component~="ui-popover"][popover][data-v-
|
|
5776
|
+
[data-component~="ui-popover"][popover][data-v-fd69c5a5] {
|
|
5772
5777
|
position: fixed;
|
|
5773
5778
|
inset: auto;
|
|
5774
5779
|
margin: 0;
|
|
@@ -5780,21 +5785,21 @@ svg[data-v-9828be81-s] {
|
|
|
5780
5785
|
display var(--ui-motion-fast) allow-discrete,
|
|
5781
5786
|
overlay var(--ui-motion-fast) allow-discrete;
|
|
5782
5787
|
}
|
|
5783
|
-
[data-component~="ui-popover"][popover][data-v-
|
|
5788
|
+
[data-component~="ui-popover"][popover][data-v-fd69c5a5]:popover-open {
|
|
5784
5789
|
opacity: 1;
|
|
5785
5790
|
transform: translateY(0) scale(1);
|
|
5786
5791
|
}
|
|
5787
5792
|
@starting-style {
|
|
5788
|
-
[data-component~="ui-popover"][popover][data-v-
|
|
5793
|
+
[data-component~="ui-popover"][popover][data-v-fd69c5a5]:popover-open {
|
|
5789
5794
|
opacity: 0;
|
|
5790
5795
|
transform: translateY(-4px) scale(0.99);
|
|
5791
5796
|
}
|
|
5792
5797
|
}
|
|
5793
|
-
[data-component~="ui-popover"][hidden][data-v-
|
|
5798
|
+
[data-component~="ui-popover"][hidden][data-v-fd69c5a5] {
|
|
5794
5799
|
display: none;
|
|
5795
5800
|
}
|
|
5796
5801
|
@media (prefers-reduced-motion: reduce) {
|
|
5797
|
-
[data-component~="ui-popover"][popover][data-v-
|
|
5802
|
+
[data-component~="ui-popover"][popover][data-v-fd69c5a5] {
|
|
5798
5803
|
transition: none;
|
|
5799
5804
|
}
|
|
5800
5805
|
}
|
|
@@ -8884,6 +8889,73 @@ html[data-ui-input-modality="touch"]
|
|
|
8884
8889
|
inline-size: min(22rem, calc(100vw - 2rem));
|
|
8885
8890
|
}
|
|
8886
8891
|
|
|
8892
|
+
/* The floating toolbar supplies the surface; the containing popover only
|
|
8893
|
+
positions it beside the app-owned trigger. */
|
|
8894
|
+
.looma-editor__formatting-popover {
|
|
8895
|
+
--ui-popover-padding: 0;
|
|
8896
|
+
--ui-popover-surface: transparent;
|
|
8897
|
+
--ui-popover-border: transparent;
|
|
8898
|
+
--ui-popover-shadow: none;
|
|
8899
|
+
}
|
|
8900
|
+
|
|
8901
|
+
.looma-editor__link-context {
|
|
8902
|
+
box-sizing: border-box;
|
|
8903
|
+
max-width: min(24rem, calc(100vw - 1.5rem));
|
|
8904
|
+
padding: var(--ui-editor-toolbar-floating-padding, 4px);
|
|
8905
|
+
border: 1px solid var(--ui-editor-toolbar-border, var(--ui-border-strong));
|
|
8906
|
+
border-radius: var(--ui-editor-toolbar-floating-radius, var(--ui-radius-lg));
|
|
8907
|
+
background: var(--ui-editor-toolbar-surface, var(--ui-surface));
|
|
8908
|
+
box-shadow: var(--ui-editor-toolbar-floating-shadow, var(--ui-shadow-lg, 0 10px 24px rgb(0 0 0 / 0.12)));
|
|
8909
|
+
color: var(--ui-text-primary);
|
|
8910
|
+
font-family: var(--ui-font-family-sans, sans-serif);
|
|
8911
|
+
}
|
|
8912
|
+
|
|
8913
|
+
.looma-editor__link-context-actions {
|
|
8914
|
+
display: flex;
|
|
8915
|
+
align-items: center;
|
|
8916
|
+
gap: var(--ui-space-1);
|
|
8917
|
+
}
|
|
8918
|
+
|
|
8919
|
+
.looma-editor__link-context-url {
|
|
8920
|
+
min-width: 0;
|
|
8921
|
+
max-width: 10rem;
|
|
8922
|
+
overflow: hidden;
|
|
8923
|
+
padding-inline: var(--ui-space-2);
|
|
8924
|
+
color: var(--ui-text-secondary);
|
|
8925
|
+
text-overflow: ellipsis;
|
|
8926
|
+
white-space: nowrap;
|
|
8927
|
+
}
|
|
8928
|
+
|
|
8929
|
+
.looma-editor__link-context-actions :is(button, a) {
|
|
8930
|
+
display: inline-flex;
|
|
8931
|
+
flex: 0 0 auto;
|
|
8932
|
+
align-items: center;
|
|
8933
|
+
min-height: var(--ui-control-min-block-size);
|
|
8934
|
+
padding: 0 var(--ui-space-2);
|
|
8935
|
+
border: 0;
|
|
8936
|
+
border-radius: var(--ui-radius-sm);
|
|
8937
|
+
background: transparent;
|
|
8938
|
+
color: var(--ui-text-primary);
|
|
8939
|
+
font: inherit;
|
|
8940
|
+
font-size: var(--ui-font-size-sm);
|
|
8941
|
+
text-decoration: none;
|
|
8942
|
+
cursor: pointer;
|
|
8943
|
+
}
|
|
8944
|
+
|
|
8945
|
+
.looma-editor__link-context-actions :is(button, a):is(:hover, :focus-visible) {
|
|
8946
|
+
background: var(--ui-surface-subtle);
|
|
8947
|
+
}
|
|
8948
|
+
|
|
8949
|
+
.looma-editor__link-context-actions :is(button, a):focus-visible {
|
|
8950
|
+
outline: 2px solid var(--ui-focus-ring);
|
|
8951
|
+
outline-offset: 2px;
|
|
8952
|
+
}
|
|
8953
|
+
|
|
8954
|
+
.looma-editor__link-context--editing {
|
|
8955
|
+
width: min(22rem, calc(100vw - 1.5rem));
|
|
8956
|
+
padding: var(--ui-space-3);
|
|
8957
|
+
}
|
|
8958
|
+
|
|
8887
8959
|
.looma-editor__chip-popover {
|
|
8888
8960
|
inline-size: min(15rem, calc(100vw - 2rem));
|
|
8889
8961
|
}
|
package/vue/editor/index.js
CHANGED
|
@@ -370,6 +370,7 @@ var LoomaEditor = defineComponent({
|
|
|
370
370
|
const linkAnchorId = `looma-editor-link-${useId().replace(/[^a-zA-Z0-9_-]/g, "")}`;
|
|
371
371
|
const linkUrlInput = ref(null);
|
|
372
372
|
const linkOpen = ref(false);
|
|
373
|
+
const linkContextEditing = ref(false);
|
|
373
374
|
const linkHref = ref("");
|
|
374
375
|
const linkText = ref("");
|
|
375
376
|
const linkNewTab = ref(true);
|
|
@@ -550,7 +551,10 @@ var LoomaEditor = defineComponent({
|
|
|
550
551
|
} },
|
|
551
552
|
onCreate: ({ editor: instance }) => emit("ready", instance),
|
|
552
553
|
onFocus: ({ editor: instance }) => rememberSelection(instance),
|
|
553
|
-
onSelectionUpdate: ({ editor: instance }) =>
|
|
554
|
+
onSelectionUpdate: ({ editor: instance }) => {
|
|
555
|
+
rememberSelection(instance);
|
|
556
|
+
if (linkContextEditing.value && instance.state.selection.from !== linkSelection?.from) linkContextEditing.value = false;
|
|
557
|
+
},
|
|
554
558
|
onTransaction: () => {
|
|
555
559
|
editorStateVersion.value += 1;
|
|
556
560
|
},
|
|
@@ -560,7 +564,7 @@ var LoomaEditor = defineComponent({
|
|
|
560
564
|
emit("update", value);
|
|
561
565
|
}
|
|
562
566
|
});
|
|
563
|
-
const openLinkEditor = () => {
|
|
567
|
+
const openLinkEditor = (context = false) => {
|
|
564
568
|
const instance = editor.value;
|
|
565
569
|
if (!instance || !props.editable) return;
|
|
566
570
|
const current = instance.state.selection;
|
|
@@ -581,7 +585,8 @@ var LoomaEditor = defineComponent({
|
|
|
581
585
|
linkNewTab.value = attrs.target !== "_self";
|
|
582
586
|
linkText.value = empty && !existing ? "" : instance.state.doc.textBetween(from, to);
|
|
583
587
|
linkError.value = "";
|
|
584
|
-
|
|
588
|
+
linkContextEditing.value = context;
|
|
589
|
+
linkOpen.value = !context;
|
|
585
590
|
nextTick(() => linkUrlInput.value?.focus());
|
|
586
591
|
};
|
|
587
592
|
const saveLink = () => {
|
|
@@ -622,6 +627,7 @@ var LoomaEditor = defineComponent({
|
|
|
622
627
|
chain.setLink(attrs).run();
|
|
623
628
|
}
|
|
624
629
|
linkOpen.value = false;
|
|
630
|
+
linkContextEditing.value = false;
|
|
625
631
|
};
|
|
626
632
|
const removeLink = () => {
|
|
627
633
|
const instance = editor.value;
|
|
@@ -632,6 +638,92 @@ var LoomaEditor = defineComponent({
|
|
|
632
638
|
to: selection.to
|
|
633
639
|
}).extendMarkRange("link").unsetLink().run();
|
|
634
640
|
linkOpen.value = false;
|
|
641
|
+
linkContextEditing.value = false;
|
|
642
|
+
};
|
|
643
|
+
const removeCurrentLink = () => {
|
|
644
|
+
const instance = editor.value;
|
|
645
|
+
if (!instance?.isActive("link")) return;
|
|
646
|
+
instance.chain().focus().extendMarkRange("link").unsetLink().run();
|
|
647
|
+
linkContextEditing.value = false;
|
|
648
|
+
};
|
|
649
|
+
const renderLinkForm = () => h("form", {
|
|
650
|
+
class: "looma-editor__link-form",
|
|
651
|
+
"aria-label": "Edit link",
|
|
652
|
+
onSubmit: (event) => {
|
|
653
|
+
event.preventDefault();
|
|
654
|
+
saveLink();
|
|
655
|
+
}
|
|
656
|
+
}, [
|
|
657
|
+
linkSelection?.from === linkSelection?.to && !linkSelection?.existing ? h("label", [h("span", "Text"), h("input", {
|
|
658
|
+
value: linkText.value,
|
|
659
|
+
onInput: (event) => {
|
|
660
|
+
linkText.value = event.target.value;
|
|
661
|
+
linkError.value = "";
|
|
662
|
+
}
|
|
663
|
+
})]) : null,
|
|
664
|
+
h("label", [h("span", "URL"), h("input", {
|
|
665
|
+
ref: linkUrlInput,
|
|
666
|
+
type: "text",
|
|
667
|
+
inputmode: "url",
|
|
668
|
+
value: linkHref.value,
|
|
669
|
+
"aria-invalid": linkError.value ? "true" : void 0,
|
|
670
|
+
onInput: (event) => {
|
|
671
|
+
linkHref.value = event.target.value;
|
|
672
|
+
linkError.value = "";
|
|
673
|
+
}
|
|
674
|
+
})]),
|
|
675
|
+
h("label", { class: "looma-editor__link-new-tab" }, [h("input", {
|
|
676
|
+
type: "checkbox",
|
|
677
|
+
checked: linkNewTab.value,
|
|
678
|
+
onChange: (event) => {
|
|
679
|
+
linkNewTab.value = event.target.checked;
|
|
680
|
+
}
|
|
681
|
+
}), h("span", "Open in new tab")]),
|
|
682
|
+
linkError.value ? h("p", {
|
|
683
|
+
class: "looma-editor__link-error",
|
|
684
|
+
role: "alert"
|
|
685
|
+
}, linkError.value) : null,
|
|
686
|
+
validLinkHref(linkHref.value) ? h("a", {
|
|
687
|
+
class: "looma-editor__link-preview",
|
|
688
|
+
href: validLinkHref(linkHref.value),
|
|
689
|
+
target: "_blank",
|
|
690
|
+
rel: "noopener noreferrer"
|
|
691
|
+
}, "Preview link") : null,
|
|
692
|
+
h("div", { class: "looma-editor__link-actions" }, [linkSelection?.existing ? h("button", {
|
|
693
|
+
type: "button",
|
|
694
|
+
onClick: removeLink
|
|
695
|
+
}, "Remove link") : null, h("button", { type: "submit" }, "Save link")])
|
|
696
|
+
]);
|
|
697
|
+
const renderLinkContext = (instance) => {
|
|
698
|
+
if (linkContextEditing.value) return renderLinkForm();
|
|
699
|
+
const rawHref = instance.getAttributes("link").href;
|
|
700
|
+
const href = typeof rawHref === "string" ? rawHref : "";
|
|
701
|
+
const safeHref = validLinkHref(href);
|
|
702
|
+
return h("div", {
|
|
703
|
+
class: "looma-editor__link-context-actions",
|
|
704
|
+
role: "group",
|
|
705
|
+
"aria-label": "Link actions"
|
|
706
|
+
}, [
|
|
707
|
+
h("span", {
|
|
708
|
+
class: "looma-editor__link-context-url",
|
|
709
|
+
title: href
|
|
710
|
+
}, href),
|
|
711
|
+
h("button", {
|
|
712
|
+
type: "button",
|
|
713
|
+
onPointerdown: (event) => event.preventDefault(),
|
|
714
|
+
onClick: () => openLinkEditor(true)
|
|
715
|
+
}, "Edit link"),
|
|
716
|
+
h("button", {
|
|
717
|
+
type: "button",
|
|
718
|
+
onPointerdown: (event) => event.preventDefault(),
|
|
719
|
+
onClick: removeCurrentLink
|
|
720
|
+
}, "Remove link"),
|
|
721
|
+
safeHref ? h("a", {
|
|
722
|
+
href: safeHref,
|
|
723
|
+
target: "_blank",
|
|
724
|
+
rel: "noopener noreferrer"
|
|
725
|
+
}, "Open link") : null
|
|
726
|
+
]);
|
|
635
727
|
};
|
|
636
728
|
const captureBlockAction = () => {
|
|
637
729
|
const instance = editor.value;
|
|
@@ -1330,10 +1422,10 @@ var LoomaEditor = defineComponent({
|
|
|
1330
1422
|
onDblclick: onImageDoubleClick,
|
|
1331
1423
|
onKeydown: onImageKeyDown
|
|
1332
1424
|
}, [
|
|
1333
|
-
instance && props.editable && !mobile.value && (props.toolbarMode === "bubble" || props.toolbarMode === "popover"
|
|
1425
|
+
instance && props.editable && !mobile.value && (props.toolbarMode === "bubble" || props.toolbarMode === "popover") ? h(BubbleMenu, {
|
|
1334
1426
|
editor: instance,
|
|
1335
1427
|
pluginKey: "looma-text-formatting-menu",
|
|
1336
|
-
shouldShow: ({ editor: menuEditor, from, to }) => shouldShowTextFormattingToolbar(menuEditor, from, to),
|
|
1428
|
+
shouldShow: ({ editor: menuEditor, from, to }) => (props.toolbarMode !== "popover" || !props.toolbarOpen) && shouldShowTextFormattingToolbar(menuEditor, from, to),
|
|
1337
1429
|
tippyOptions: {
|
|
1338
1430
|
appendTo: () => root.value ?? document.body,
|
|
1339
1431
|
duration: 100,
|
|
@@ -1341,6 +1433,17 @@ var LoomaEditor = defineComponent({
|
|
|
1341
1433
|
placement: "top"
|
|
1342
1434
|
}
|
|
1343
1435
|
}, { default: () => renderToolbar(instance, true, props.toolbarMode === "popover") }) : null,
|
|
1436
|
+
instance && props.editable && !mobile.value ? h(BubbleMenu, {
|
|
1437
|
+
editor: instance,
|
|
1438
|
+
pluginKey: "looma-link-context-menu",
|
|
1439
|
+
shouldShow: ({ editor: menuEditor, from, to }) => from === to && menuEditor.isActive("link") && !linkOpen.value,
|
|
1440
|
+
tippyOptions: {
|
|
1441
|
+
appendTo: () => root.value ?? document.body,
|
|
1442
|
+
duration: 100,
|
|
1443
|
+
maxWidth: "none",
|
|
1444
|
+
placement: "bottom"
|
|
1445
|
+
}
|
|
1446
|
+
}, { default: () => h("div", { class: ["looma-editor__link-context", { "looma-editor__link-context--editing": linkContextEditing.value }] }, [renderLinkContext(instance)]) }) : null,
|
|
1344
1447
|
instance && props.editable && !mobile.value && props.toolbarMode === "popover" && props.toolbarTriggerId ? h(Popover, {
|
|
1345
1448
|
class: "looma-editor__formatting-popover",
|
|
1346
1449
|
role: "region",
|
|
@@ -1350,7 +1453,7 @@ var LoomaEditor = defineComponent({
|
|
|
1350
1453
|
placement: "bottom-end",
|
|
1351
1454
|
onOpen: () => emit("update:toolbarOpen", true),
|
|
1352
1455
|
onClose: () => emit("update:toolbarOpen", false)
|
|
1353
|
-
}, () => [renderToolbar(instance,
|
|
1456
|
+
}, () => [renderToolbar(instance, true)]) : null,
|
|
1354
1457
|
instance && props.editable && !mobile.value && props.toolbarMode === "sticky" ? h("div", {
|
|
1355
1458
|
class: "looma-editor__sticky-toolbar-shell",
|
|
1356
1459
|
role: "toolbar",
|
|
@@ -1467,59 +1570,12 @@ var LoomaEditor = defineComponent({
|
|
|
1467
1570
|
open: linkOpen.value,
|
|
1468
1571
|
for: linkAnchorId,
|
|
1469
1572
|
placement: mobile.value ? "top-start" : "bottom-start",
|
|
1470
|
-
onOpen: openLinkEditor,
|
|
1573
|
+
onOpen: () => openLinkEditor(),
|
|
1471
1574
|
onClose: () => {
|
|
1472
1575
|
linkOpen.value = false;
|
|
1473
1576
|
linkPressedSelection = null;
|
|
1474
1577
|
}
|
|
1475
|
-
},
|
|
1476
|
-
class: "looma-editor__link-form",
|
|
1477
|
-
"aria-label": "Edit link",
|
|
1478
|
-
onSubmit: (event) => {
|
|
1479
|
-
event.preventDefault();
|
|
1480
|
-
saveLink();
|
|
1481
|
-
}
|
|
1482
|
-
}, [
|
|
1483
|
-
linkSelection?.from === linkSelection?.to && !linkSelection?.existing ? h("label", [h("span", "Text"), h("input", {
|
|
1484
|
-
value: linkText.value,
|
|
1485
|
-
onInput: (event) => {
|
|
1486
|
-
linkText.value = event.target.value;
|
|
1487
|
-
linkError.value = "";
|
|
1488
|
-
}
|
|
1489
|
-
})]) : null,
|
|
1490
|
-
h("label", [h("span", "URL"), h("input", {
|
|
1491
|
-
ref: linkUrlInput,
|
|
1492
|
-
type: "text",
|
|
1493
|
-
inputmode: "url",
|
|
1494
|
-
value: linkHref.value,
|
|
1495
|
-
"aria-invalid": linkError.value ? "true" : void 0,
|
|
1496
|
-
onInput: (event) => {
|
|
1497
|
-
linkHref.value = event.target.value;
|
|
1498
|
-
linkError.value = "";
|
|
1499
|
-
}
|
|
1500
|
-
})]),
|
|
1501
|
-
h("label", { class: "looma-editor__link-new-tab" }, [h("input", {
|
|
1502
|
-
type: "checkbox",
|
|
1503
|
-
checked: linkNewTab.value,
|
|
1504
|
-
onChange: (event) => {
|
|
1505
|
-
linkNewTab.value = event.target.checked;
|
|
1506
|
-
}
|
|
1507
|
-
}), h("span", "Open in new tab")]),
|
|
1508
|
-
linkError.value ? h("p", {
|
|
1509
|
-
class: "looma-editor__link-error",
|
|
1510
|
-
role: "alert"
|
|
1511
|
-
}, linkError.value) : null,
|
|
1512
|
-
validLinkHref(linkHref.value) ? h("a", {
|
|
1513
|
-
class: "looma-editor__link-preview",
|
|
1514
|
-
href: validLinkHref(linkHref.value),
|
|
1515
|
-
target: "_blank",
|
|
1516
|
-
rel: "noopener noreferrer"
|
|
1517
|
-
}, "Preview link") : null,
|
|
1518
|
-
h("div", { class: "looma-editor__link-actions" }, [linkSelection?.existing ? h("button", {
|
|
1519
|
-
type: "button",
|
|
1520
|
-
onClick: removeLink
|
|
1521
|
-
}, "Remove link") : null, h("button", { type: "submit" }, "Save link")])
|
|
1522
|
-
])),
|
|
1578
|
+
}, renderLinkForm),
|
|
1523
1579
|
h(Menu, {
|
|
1524
1580
|
for: blockActionAnchorId,
|
|
1525
1581
|
placement: mobile.value ? "top-start" : "bottom-start",
|