sprintify-ui 0.12.0 → 0.12.1
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/sprintify-ui.es.js +9864 -9174
- package/dist/types/components/BaseDropdown.vue.d.ts +9 -0
- package/dist/types/index.d.ts +2 -0
- package/package.json +3 -1
- package/src/components/BaseDropdown.vue +16 -2
- package/src/components/BaseTipTap.vue +252 -43
- package/src/lang/en.json +1 -0
- package/src/lang/fr.json +1 -0
|
@@ -22,6 +22,10 @@ declare const __VLS_component: import("vue").DefineComponent<import("vue").Extra
|
|
|
22
22
|
default: string;
|
|
23
23
|
type: PropType<Placement>;
|
|
24
24
|
};
|
|
25
|
+
twButton: {
|
|
26
|
+
default: string;
|
|
27
|
+
type: StringConstructor;
|
|
28
|
+
};
|
|
25
29
|
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
26
30
|
animated: {
|
|
27
31
|
default: boolean;
|
|
@@ -35,8 +39,13 @@ declare const __VLS_component: import("vue").DefineComponent<import("vue").Extra
|
|
|
35
39
|
default: string;
|
|
36
40
|
type: PropType<Placement>;
|
|
37
41
|
};
|
|
42
|
+
twButton: {
|
|
43
|
+
default: string;
|
|
44
|
+
type: StringConstructor;
|
|
45
|
+
};
|
|
38
46
|
}>> & Readonly<{}>, {
|
|
39
47
|
placement: Placement;
|
|
48
|
+
twButton: string;
|
|
40
49
|
animated: boolean;
|
|
41
50
|
keepAlive: boolean;
|
|
42
51
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -68,6 +68,7 @@ declare const messages: {
|
|
|
68
68
|
page: string;
|
|
69
69
|
pagination_detail_1: string;
|
|
70
70
|
pagination_detail_2: string;
|
|
71
|
+
paste_link: string;
|
|
71
72
|
postal_code_zip_code: string;
|
|
72
73
|
previous: string;
|
|
73
74
|
previous_month: string;
|
|
@@ -170,6 +171,7 @@ declare const messages: {
|
|
|
170
171
|
page: string;
|
|
171
172
|
pagination_detail_1: string;
|
|
172
173
|
pagination_detail_2: string;
|
|
174
|
+
paste_link: string;
|
|
173
175
|
postal_code_zip_code: string;
|
|
174
176
|
previous: string;
|
|
175
177
|
previous_month: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sprintify-ui",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"generate-llm-txt": "node scripts/generate-llm-txt.js",
|
|
@@ -38,6 +38,8 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@floating-ui/vue": "^1.0.6",
|
|
40
40
|
"@headlessui/vue": "^1.7.19",
|
|
41
|
+
"@tiptap/extension-highlight": "^3.22.4",
|
|
42
|
+
"@tiptap/extension-image": "^3.22.4",
|
|
41
43
|
"@tiptap/extension-subscript": "^3.20.4",
|
|
42
44
|
"@tiptap/extension-superscript": "^3.20.4",
|
|
43
45
|
"color2k": "^2.0.3",
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<Popover v-slot="{ open }">
|
|
3
|
-
<PopoverButton
|
|
3
|
+
<PopoverButton
|
|
4
|
+
:class="twButtonInternal"
|
|
5
|
+
>
|
|
4
6
|
<div ref="buttonRef">
|
|
5
7
|
<slot name="button" />
|
|
6
8
|
</div>
|
|
@@ -43,6 +45,7 @@
|
|
|
43
45
|
import { autoUpdate, offset, flip, shift, useFloating, Placement } from '@floating-ui/vue';
|
|
44
46
|
import { Popover, PopoverButton, PopoverPanel } from '@headlessui/vue';
|
|
45
47
|
import { unrefElement } from '@vueuse/core';
|
|
48
|
+
import { twMerge } from 'tailwind-merge';
|
|
46
49
|
import { PropType } from 'vue';
|
|
47
50
|
|
|
48
51
|
const buttonRef = ref<InstanceType<typeof PopoverButton> | null>(null);
|
|
@@ -62,7 +65,11 @@ const props = defineProps({
|
|
|
62
65
|
placement: {
|
|
63
66
|
default: 'bottom-end',
|
|
64
67
|
type: String as PropType<Placement>,
|
|
65
|
-
}
|
|
68
|
+
},
|
|
69
|
+
twButton: {
|
|
70
|
+
default: 'outline-none',
|
|
71
|
+
type: String,
|
|
72
|
+
},
|
|
66
73
|
});
|
|
67
74
|
|
|
68
75
|
const { floatingStyles } = useFloating(buttonRefEl, dropdownRef, {
|
|
@@ -71,4 +78,11 @@ const { floatingStyles } = useFloating(buttonRefEl, dropdownRef, {
|
|
|
71
78
|
whileElementsMounted: autoUpdate,
|
|
72
79
|
});
|
|
73
80
|
|
|
81
|
+
const twButtonInternal = computed(() => {
|
|
82
|
+
return twMerge(
|
|
83
|
+
'outline-none',
|
|
84
|
+
props.twButton,
|
|
85
|
+
);
|
|
86
|
+
});
|
|
87
|
+
|
|
74
88
|
</script>
|
|
@@ -6,20 +6,122 @@
|
|
|
6
6
|
noMargin ? 'tip-tap-no-margin' : ''
|
|
7
7
|
]"
|
|
8
8
|
>
|
|
9
|
-
<div class="
|
|
10
|
-
<
|
|
9
|
+
<div class="px-1 py-1 border-b flex items-center">
|
|
10
|
+
<template
|
|
11
11
|
v-for="action in filteredActions"
|
|
12
12
|
:key="action.name"
|
|
13
|
-
:class="[buttonClass, editor.isActive(action.name) ? 'bg-slate-200' : '']"
|
|
14
|
-
type="button"
|
|
15
|
-
:disabled="disabled"
|
|
16
|
-
@click="action.command()"
|
|
17
13
|
>
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
<BaseDropdown
|
|
15
|
+
v-if="action.name === 'highlight'"
|
|
16
|
+
placement="bottom"
|
|
17
|
+
tw-button="block"
|
|
18
|
+
>
|
|
19
|
+
<template #button>
|
|
20
|
+
<div :class="[buttonClass, editor.isActive('highlight') ? 'bg-slate-200' : '']">
|
|
21
|
+
<BaseIcon
|
|
22
|
+
class="h-4 w-4 text-slate-600"
|
|
23
|
+
:icon="action.icon"
|
|
24
|
+
/>
|
|
25
|
+
</div>
|
|
26
|
+
</template>
|
|
27
|
+
<template #dropdown="{ close }">
|
|
28
|
+
<div class="bg-white rounded-full shadow-lg border border-slate-200 px-4 py-3 flex items-center gap-2">
|
|
29
|
+
<button
|
|
30
|
+
v-for="color in highlightColors"
|
|
31
|
+
:key="color"
|
|
32
|
+
type="button"
|
|
33
|
+
class="w-5 h-5 rounded-full ring-inset ring-1 ring-black/20"
|
|
34
|
+
:style="{ backgroundColor: color }"
|
|
35
|
+
@click="setHighlight(color); close()"
|
|
36
|
+
/>
|
|
37
|
+
<div class="w-px h-5 bg-slate-200" />
|
|
38
|
+
<button
|
|
39
|
+
type="button"
|
|
40
|
+
class="w-5 h-5 flex items-center justify-center bg-white "
|
|
41
|
+
@click="unsetHighlight(); close()"
|
|
42
|
+
>
|
|
43
|
+
<BaseIcon
|
|
44
|
+
class="h-5 w-5 text-slate-600"
|
|
45
|
+
icon="lucide:ban"
|
|
46
|
+
/>
|
|
47
|
+
</button>
|
|
48
|
+
</div>
|
|
49
|
+
</template>
|
|
50
|
+
</BaseDropdown>
|
|
51
|
+
<BaseDropdown
|
|
52
|
+
v-else-if="action.name === 'link'"
|
|
53
|
+
placement="bottom"
|
|
54
|
+
tw-button="block"
|
|
55
|
+
>
|
|
56
|
+
<template #button>
|
|
57
|
+
<div
|
|
58
|
+
:class="[buttonClass, editor.isActive('link') ? 'bg-slate-200' : '']"
|
|
59
|
+
@click="openLinkDropdown"
|
|
60
|
+
>
|
|
61
|
+
<BaseIcon
|
|
62
|
+
class="h-4 w-4 text-slate-600"
|
|
63
|
+
:icon="action.icon"
|
|
64
|
+
/>
|
|
65
|
+
</div>
|
|
66
|
+
</template>
|
|
67
|
+
<template #dropdown="{ close }">
|
|
68
|
+
<div class="bg-white rounded-full shadow-lg border border-slate-200 pl-4 pr-3 py-2 flex items-center gap-2 focus:outline-none outline-none">
|
|
69
|
+
<input
|
|
70
|
+
:ref="focusLinkInput"
|
|
71
|
+
v-model="linkUrl"
|
|
72
|
+
type="text"
|
|
73
|
+
class="bg-transparent border-none border-0 border-transparent shadow-none focus:border-none focus:outline-none focus:ring-0 focus:shadow-none outline-none ring-0 text-sm text-slate-700 placeholder-slate-400 w-56 py-1 px-2"
|
|
74
|
+
:placeholder="t('sui.paste_link')"
|
|
75
|
+
@keydown.enter.prevent="applyLink(); close()"
|
|
76
|
+
>
|
|
77
|
+
<button
|
|
78
|
+
type="button"
|
|
79
|
+
class="w-7 h-7 flex items-center justify-center rounded-full hover:bg-slate-100"
|
|
80
|
+
@click="applyLink(); close()"
|
|
81
|
+
>
|
|
82
|
+
<BaseIcon
|
|
83
|
+
class="h-4 w-4 text-slate-600"
|
|
84
|
+
icon="lucide:corner-down-left"
|
|
85
|
+
/>
|
|
86
|
+
</button>
|
|
87
|
+
<div class="w-px h-5 bg-slate-200" />
|
|
88
|
+
<button
|
|
89
|
+
type="button"
|
|
90
|
+
class="w-7 h-7 flex items-center justify-center rounded-full hover:bg-slate-100 disabled:opacity-40 disabled:hover:bg-transparent"
|
|
91
|
+
:disabled="!linkUrl"
|
|
92
|
+
@click="openLink(linkUrl)"
|
|
93
|
+
>
|
|
94
|
+
<BaseIcon
|
|
95
|
+
class="h-4 w-4 text-slate-600"
|
|
96
|
+
icon="lucide:external-link"
|
|
97
|
+
/>
|
|
98
|
+
</button>
|
|
99
|
+
<button
|
|
100
|
+
type="button"
|
|
101
|
+
class="w-7 h-7 flex items-center justify-center rounded-full hover:bg-slate-100"
|
|
102
|
+
@click="removeLink(); close()"
|
|
103
|
+
>
|
|
104
|
+
<BaseIcon
|
|
105
|
+
class="h-4 w-4 text-slate-600"
|
|
106
|
+
icon="lucide:trash-2"
|
|
107
|
+
/>
|
|
108
|
+
</button>
|
|
109
|
+
</div>
|
|
110
|
+
</template>
|
|
111
|
+
</BaseDropdown>
|
|
112
|
+
<button
|
|
113
|
+
v-else
|
|
114
|
+
:class="[buttonClass, editor.isActive(action.name) ? 'bg-slate-200' : '']"
|
|
115
|
+
type="button"
|
|
116
|
+
:disabled="disabled"
|
|
117
|
+
@click="action.command()"
|
|
118
|
+
>
|
|
119
|
+
<BaseIcon
|
|
120
|
+
class="h-4 w-4 text-slate-600"
|
|
121
|
+
:icon="action.icon"
|
|
122
|
+
/>
|
|
123
|
+
</button>
|
|
124
|
+
</template>
|
|
23
125
|
</div>
|
|
24
126
|
|
|
25
127
|
<div
|
|
@@ -31,6 +133,14 @@
|
|
|
31
133
|
:editor="editor"
|
|
32
134
|
/>
|
|
33
135
|
</div>
|
|
136
|
+
|
|
137
|
+
<input
|
|
138
|
+
ref="imageInput"
|
|
139
|
+
type="file"
|
|
140
|
+
accept="image/*"
|
|
141
|
+
class="hidden"
|
|
142
|
+
@change="onImageSelected"
|
|
143
|
+
>
|
|
34
144
|
</div>
|
|
35
145
|
</template>
|
|
36
146
|
|
|
@@ -41,9 +151,14 @@ import Link from '@tiptap/extension-link';
|
|
|
41
151
|
import Superscript from '@tiptap/extension-superscript';
|
|
42
152
|
import Subscript from '@tiptap/extension-subscript';
|
|
43
153
|
import Strike from '@tiptap/extension-strike'
|
|
154
|
+
import Image from '@tiptap/extension-image';
|
|
155
|
+
import Highlight from '@tiptap/extension-highlight';
|
|
44
156
|
import { Placeholder } from '@tiptap/extensions'
|
|
45
157
|
import { Footnotes, FootnoteReference, Footnote } from "tiptap-footnotes";
|
|
46
158
|
import StarterKit from '@tiptap/starter-kit';
|
|
159
|
+
import resizeImageForUpload from '@/utils/resizeImageForUpload';
|
|
160
|
+
import BaseDropdown from './BaseDropdown.vue';
|
|
161
|
+
import { t } from '@/i18n';
|
|
47
162
|
|
|
48
163
|
const emit = defineEmits(['update:modelValue']);
|
|
49
164
|
|
|
@@ -78,13 +193,20 @@ const editor = new Editor({
|
|
|
78
193
|
Strike,
|
|
79
194
|
Superscript,
|
|
80
195
|
Subscript,
|
|
196
|
+
Image.configure({
|
|
197
|
+
inline: false,
|
|
198
|
+
allowBase64: true,
|
|
199
|
+
}),
|
|
200
|
+
Highlight.configure({
|
|
201
|
+
multicolor: true,
|
|
202
|
+
}),
|
|
81
203
|
Footnotes,
|
|
82
204
|
Footnote,
|
|
83
205
|
FootnoteReference,
|
|
84
206
|
],
|
|
85
207
|
editorProps: {
|
|
86
208
|
attributes: {
|
|
87
|
-
class: 'prose prose-sm
|
|
209
|
+
class: 'prose prose-sm focus:outline-none',
|
|
88
210
|
},
|
|
89
211
|
},
|
|
90
212
|
content: props.modelValue,
|
|
@@ -143,37 +265,117 @@ onBeforeUnmount(() => {
|
|
|
143
265
|
}
|
|
144
266
|
});
|
|
145
267
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
268
|
+
const imageInput = ref<HTMLInputElement | null>(null);
|
|
269
|
+
|
|
270
|
+
function pickImage() {
|
|
271
|
+
imageInput.value?.click();
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const highlightColors = [
|
|
275
|
+
'#BBF7D0',
|
|
276
|
+
'#BFDBFE',
|
|
277
|
+
'#FECACA',
|
|
278
|
+
'#E9D5FF',
|
|
279
|
+
'#FEF08A',
|
|
280
|
+
];
|
|
281
|
+
|
|
282
|
+
function setHighlight(color: string) {
|
|
283
|
+
editor.chain().focus().setHighlight({ color }).run();
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function unsetHighlight() {
|
|
287
|
+
editor.chain().focus().unsetHighlight().run();
|
|
288
|
+
}
|
|
149
289
|
|
|
150
|
-
|
|
151
|
-
|
|
290
|
+
const MAX_IMAGE_BYTES = 1024 * 1024;
|
|
291
|
+
|
|
292
|
+
async function onImageSelected(event: Event) {
|
|
293
|
+
const target = event.target as HTMLInputElement;
|
|
294
|
+
const file = target.files?.[0];
|
|
295
|
+
target.value = '';
|
|
296
|
+
|
|
297
|
+
if (!file) {
|
|
152
298
|
return;
|
|
153
299
|
}
|
|
154
300
|
|
|
155
|
-
|
|
301
|
+
let blob: Blob = file;
|
|
302
|
+
|
|
303
|
+
try {
|
|
304
|
+
blob = await resizeImageForUpload(file, { maxBytes: MAX_IMAGE_BYTES });
|
|
305
|
+
} catch (error) {
|
|
306
|
+
console.error(error);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const reader = new FileReader();
|
|
310
|
+
|
|
311
|
+
reader.onload = () => {
|
|
312
|
+
const src = reader.result;
|
|
313
|
+
|
|
314
|
+
if (typeof src === 'string') {
|
|
315
|
+
editor.chain().focus().setImage({ src }).run();
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
reader.readAsDataURL(blob);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const linkUrl = ref('');
|
|
323
|
+
|
|
324
|
+
function openLinkDropdown() {
|
|
325
|
+
linkUrl.value = editor.getAttributes('link').href ?? '';
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
let focusedLinkInput: HTMLInputElement | null = null;
|
|
329
|
+
|
|
330
|
+
function focusLinkInput(el: unknown) {
|
|
331
|
+
if (el instanceof HTMLInputElement) {
|
|
332
|
+
if (focusedLinkInput === el) {
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
focusedLinkInput = el;
|
|
337
|
+
el.focus();
|
|
338
|
+
el.select();
|
|
339
|
+
} else {
|
|
340
|
+
focusedLinkInput = null;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function applyLink() {
|
|
345
|
+
const url = linkUrl.value.trim();
|
|
346
|
+
|
|
156
347
|
if (url === '') {
|
|
157
348
|
editor.chain().focus().extendMarkRange('link').unsetLink().run();
|
|
158
349
|
|
|
159
350
|
return;
|
|
160
351
|
}
|
|
161
352
|
|
|
162
|
-
// update link
|
|
163
353
|
editor.chain().focus().extendMarkRange('link').setLink({ href: url }).run();
|
|
164
354
|
}
|
|
165
355
|
|
|
356
|
+
function removeLink() {
|
|
357
|
+
editor.chain().focus().extendMarkRange('link').unsetLink().run();
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function openLink(url: string) {
|
|
361
|
+
if (!url) {
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
window.open(url, '_blank', 'noopener,noreferrer');
|
|
366
|
+
}
|
|
367
|
+
|
|
166
368
|
const buttonClass = computed(() => {
|
|
167
369
|
const sizeClass = {
|
|
168
370
|
xs: 'p-1',
|
|
169
371
|
sm: 'p-1.5',
|
|
170
|
-
md: '
|
|
171
|
-
lg: '
|
|
172
|
-
xl: '
|
|
372
|
+
md: 'px-2 py-1.5',
|
|
373
|
+
lg: 'px-2.5 py-2',
|
|
374
|
+
xl: 'px-3 py-2.5',
|
|
173
375
|
}
|
|
174
376
|
|
|
175
377
|
return [
|
|
176
|
-
'hover:bg-slate-100',
|
|
378
|
+
'block hover:bg-slate-100 rounded-lg',
|
|
177
379
|
'disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-white',
|
|
178
380
|
sizeClass[props.size || 'md'] || sizeClass['md'],
|
|
179
381
|
];
|
|
@@ -189,87 +391,92 @@ const actions = computed<Action[]>(() => {
|
|
|
189
391
|
return [
|
|
190
392
|
{
|
|
191
393
|
name: 'undo',
|
|
192
|
-
icon: '
|
|
394
|
+
icon: 'lucide:undo-2',
|
|
193
395
|
command: () => editor.chain().focus().undo().run(),
|
|
194
396
|
},
|
|
195
397
|
{
|
|
196
398
|
name: 'redo',
|
|
197
|
-
icon: '
|
|
399
|
+
icon: 'lucide:redo-2',
|
|
198
400
|
command: () => editor.chain().focus().redo().run(),
|
|
199
401
|
},
|
|
200
402
|
{
|
|
201
403
|
name: 'paragraph',
|
|
202
|
-
icon: '
|
|
404
|
+
icon: 'lucide:pilcrow',
|
|
203
405
|
command: () => editor.chain().focus().setParagraph().run(),
|
|
204
406
|
},
|
|
205
407
|
{
|
|
206
408
|
name: 'heading-2',
|
|
207
|
-
icon: '
|
|
409
|
+
icon: 'lucide:heading-2',
|
|
208
410
|
command: () => editor.chain().focus().setHeading({ level: 2 }).run(),
|
|
209
411
|
},
|
|
210
412
|
{
|
|
211
413
|
name: 'heading-3',
|
|
212
|
-
icon: '
|
|
414
|
+
icon: 'lucide:heading-3',
|
|
213
415
|
command: () => editor.chain().focus().setHeading({ level: 3 }).run(),
|
|
214
416
|
},
|
|
215
417
|
{
|
|
216
418
|
name: 'bold',
|
|
217
|
-
icon: '
|
|
419
|
+
icon: 'lucide:bold',
|
|
218
420
|
command: () => editor.chain().focus().toggleBold().run(),
|
|
219
421
|
},
|
|
220
422
|
{
|
|
221
423
|
name: 'italic',
|
|
222
|
-
icon: '
|
|
424
|
+
icon: 'lucide:italic',
|
|
223
425
|
command: () => editor.chain().focus().toggleItalic().run(),
|
|
224
426
|
},
|
|
225
427
|
{
|
|
226
428
|
name: 'underline',
|
|
227
|
-
icon: '
|
|
429
|
+
icon: 'lucide:underline',
|
|
228
430
|
command: () => editor.chain().focus().toggleUnderline().run(),
|
|
229
431
|
},
|
|
230
432
|
{
|
|
231
433
|
name: 'strikethrough',
|
|
232
|
-
icon: '
|
|
434
|
+
icon: 'lucide:strikethrough',
|
|
233
435
|
command: () => editor.chain().focus().toggleStrike().run(),
|
|
234
436
|
},
|
|
235
437
|
{
|
|
236
438
|
name: 'superscript',
|
|
237
|
-
icon: '
|
|
439
|
+
icon: 'lucide:superscript',
|
|
238
440
|
command: () => editor.chain().focus().toggleSuperscript().run(),
|
|
239
441
|
},
|
|
240
442
|
{
|
|
241
443
|
name: 'subscript',
|
|
242
|
-
icon: '
|
|
444
|
+
icon: 'lucide:subscript',
|
|
243
445
|
command: () => editor.chain().focus().toggleSubscript().run(),
|
|
244
446
|
},
|
|
447
|
+
{
|
|
448
|
+
name: 'highlight',
|
|
449
|
+
icon: 'lucide:highlighter',
|
|
450
|
+
command: () => { },
|
|
451
|
+
},
|
|
245
452
|
{
|
|
246
453
|
name: 'link',
|
|
247
|
-
icon: '
|
|
248
|
-
command: () =>
|
|
454
|
+
icon: 'lucide:link',
|
|
455
|
+
command: () => { },
|
|
249
456
|
},
|
|
250
457
|
{
|
|
251
|
-
name: '
|
|
252
|
-
icon: '
|
|
253
|
-
command: () =>
|
|
458
|
+
name: 'image',
|
|
459
|
+
icon: 'lucide:image',
|
|
460
|
+
command: () => pickImage(),
|
|
254
461
|
},
|
|
255
462
|
{
|
|
256
463
|
name: 'bulletList',
|
|
257
|
-
icon: '
|
|
464
|
+
icon: 'lucide:list',
|
|
258
465
|
command: () => editor.chain().focus().toggleBulletList().run(),
|
|
259
466
|
},
|
|
260
467
|
{
|
|
261
468
|
name: 'orderedList',
|
|
262
|
-
icon: '
|
|
469
|
+
icon: 'lucide:list-ordered',
|
|
263
470
|
command: () => editor.chain().focus().toggleOrderedList().run(),
|
|
264
471
|
},
|
|
265
472
|
{
|
|
266
473
|
name: 'footnote',
|
|
267
|
-
icon: '
|
|
474
|
+
icon: 'lucide:asterisk',
|
|
268
475
|
command: () => editor?.commands.addFootnote(),
|
|
269
476
|
},
|
|
270
477
|
{
|
|
271
478
|
name: 'nonBreakingSpace',
|
|
272
|
-
icon: '
|
|
479
|
+
icon: 'lucide:space',
|
|
273
480
|
command: () => editor.chain().focus().insertContent('\u00A0').run(),
|
|
274
481
|
},
|
|
275
482
|
|
|
@@ -289,8 +496,10 @@ const toolbarTemplates: Record<string, string[]> = {
|
|
|
289
496
|
'underline',
|
|
290
497
|
'superscript',
|
|
291
498
|
'subscript',
|
|
499
|
+
'highlight',
|
|
292
500
|
'link',
|
|
293
501
|
'unlink',
|
|
502
|
+
'image',
|
|
294
503
|
'bulletList',
|
|
295
504
|
'orderedList',
|
|
296
505
|
'footnote',
|
package/src/lang/en.json
CHANGED
package/src/lang/fr.json
CHANGED