@onereach/ui-components 2.67.4 → 2.68.0-beta.2001.0

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 (50) hide show
  1. package/dist/bundled/v2/{OrCode-edc7a1f5.js → OrCode-0cd991a1.js} +1 -114
  2. package/dist/bundled/v2/{OrConfirm-1d396830.js → OrConfirm-22c7622d.js} +1 -1
  3. package/dist/bundled/v2/components/index.js +3 -2
  4. package/dist/bundled/v2/components/or-code/index.js +2 -1
  5. package/dist/bundled/v2/components/or-confirm-v3/index.js +1 -1
  6. package/dist/bundled/v2/components/or-rich-text-editor-v3/OrRichTextEditor.stories3.d.ts +12 -0
  7. package/dist/bundled/v2/components/or-rich-text-editor-v3/OrRichTextEditor.vue.d.ts +149 -0
  8. package/dist/bundled/v2/components/or-rich-text-editor-v3/index.d.ts +1 -0
  9. package/dist/bundled/v2/components/or-rich-text-editor-v3/index.js +36840 -0
  10. package/dist/bundled/v2/components/or-rich-text-editor-v3/styles.d.ts +6 -0
  11. package/dist/bundled/v2/index.es-3f39f316.js +115 -0
  12. package/dist/bundled/v2/index.js +4 -3
  13. package/dist/bundled/v3/{OrCode.vue_vue_type_script_lang-ef5e7f04.js → OrCode.vue_vue_type_script_lang-6c5f94a6.js} +1 -114
  14. package/dist/bundled/v3/OrMenu-08aa60de.js +29 -0
  15. package/dist/bundled/v3/{OrTabs.vue_vue_type_script_lang-ca57f9d9.js → OrTabs.vue_vue_type_script_lang-2fdbd2f2.js} +10 -36
  16. package/dist/bundled/v3/components/index.js +4 -2
  17. package/dist/bundled/v3/components/or-code/index.js +2 -1
  18. package/dist/bundled/v3/components/or-rich-text-editor-v3/OrRichTextEditor.stories3.d.ts +12 -0
  19. package/dist/bundled/v3/components/or-rich-text-editor-v3/OrRichTextEditor.vue.d.ts +149 -0
  20. package/dist/bundled/v3/components/or-rich-text-editor-v3/index.d.ts +1 -0
  21. package/dist/bundled/v3/components/or-rich-text-editor-v3/index.js +36811 -0
  22. package/dist/bundled/v3/components/or-rich-text-editor-v3/styles.d.ts +6 -0
  23. package/dist/bundled/v3/components/or-tabs-v3/index.js +2 -1
  24. package/dist/bundled/v3/index.es-3f39f316.js +115 -0
  25. package/dist/bundled/v3/index.js +8 -6
  26. package/dist/esm/v2/{OrConfirm-e3b3418f.js → OrConfirm-367ac968.js} +1 -1
  27. package/dist/esm/v2/components/index.js +1 -1
  28. package/dist/esm/v2/components/or-confirm-v3/index.js +1 -1
  29. package/dist/esm/v2/components/or-rich-text-editor-v3/OrRichTextEditor.stories3.d.ts +12 -0
  30. package/dist/esm/v2/components/or-rich-text-editor-v3/OrRichTextEditor.vue.d.ts +149 -0
  31. package/dist/esm/v2/components/or-rich-text-editor-v3/index.d.ts +1 -0
  32. package/dist/esm/v2/components/or-rich-text-editor-v3/index.js +524 -0
  33. package/dist/esm/v2/components/or-rich-text-editor-v3/styles.d.ts +6 -0
  34. package/dist/esm/v2/index.js +1 -1
  35. package/dist/esm/v3/{OrConfirm-b78c5299.js → OrConfirm-e6735cc8.js} +1 -1
  36. package/dist/esm/v3/components/index.js +1 -1
  37. package/dist/esm/v3/components/or-confirm-v3/index.js +1 -1
  38. package/dist/esm/v3/components/or-rich-text-editor-v3/OrRichTextEditor.stories3.d.ts +12 -0
  39. package/dist/esm/v3/components/or-rich-text-editor-v3/OrRichTextEditor.vue.d.ts +149 -0
  40. package/dist/esm/v3/components/or-rich-text-editor-v3/index.d.ts +1 -0
  41. package/dist/esm/v3/components/or-rich-text-editor-v3/index.js +493 -0
  42. package/dist/esm/v3/components/or-rich-text-editor-v3/styles.d.ts +6 -0
  43. package/dist/esm/v3/index.js +1 -1
  44. package/package.json +20 -3
  45. package/src/components/or-confirm-v3/OrConfirm.vue +1 -1
  46. package/src/components/or-rich-text-editor-v3/OrRichTextEditor.docs.mdx +16 -0
  47. package/src/components/or-rich-text-editor-v3/OrRichTextEditor.stories3.ts +62 -0
  48. package/src/components/or-rich-text-editor-v3/OrRichTextEditor.vue +520 -0
  49. package/src/components/or-rich-text-editor-v3/index.ts +1 -0
  50. package/src/components/or-rich-text-editor-v3/styles.ts +65 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onereach/ui-components",
3
- "version": "2.67.4",
3
+ "version": "2.68.0-beta.2001.0",
4
4
  "description": "Vue components library for v2/3",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/auto/index.js",
@@ -39,6 +39,21 @@
39
39
  "@floating-ui/dom": "0.3.1",
40
40
  "@onereach/styles": "^2.32.0",
41
41
  "@splidejs/splide": "4.0.6",
42
+ "@tiptap/core": "2.0.0-beta.209",
43
+ "@tiptap/extension-bold": "2.0.0-beta.209",
44
+ "@tiptap/extension-bullet-list": "2.0.0-beta.209",
45
+ "@tiptap/extension-hard-break": "2.0.0-beta.209",
46
+ "@tiptap/extension-heading": "2.0.0-beta.209",
47
+ "@tiptap/extension-highlight": "2.0.0-beta.209",
48
+ "@tiptap/extension-italic": "2.0.0-beta.209",
49
+ "@tiptap/extension-link": "2.0.0-beta.209",
50
+ "@tiptap/extension-list-item": "2.0.0-beta.209",
51
+ "@tiptap/extension-ordered-list": "2.0.0-beta.209",
52
+ "@tiptap/extension-paragraph": "2.0.0-beta.209",
53
+ "@tiptap/extension-placeholder": "2.0.0-beta.209",
54
+ "@tiptap/extension-strike": "2.0.0-beta.209",
55
+ "@tiptap/extension-underline": "2.0.0-beta.209",
56
+ "@tiptap/starter-kit": "2.0.0-beta.209",
42
57
  "@types/lodash": "4.14.173",
43
58
  "@types/sortablejs": "1.10.7",
44
59
  "@types/uuid": "8.3.1",
@@ -47,6 +62,8 @@
47
62
  "@vueuse/math": "9.5.0",
48
63
  "codemirror": "6.0.1",
49
64
  "focus-trap": "7.2.0",
65
+ "marked": "4.2.12",
66
+ "prosemirror-markdown": "^1.10.1",
50
67
  "sortablejs": "1.14.0",
51
68
  "uuid": "8.3.2",
52
69
  "vue-demi": "0.13.11"
@@ -61,6 +78,7 @@
61
78
  "@storybook/testing-library": "^0.0.13",
62
79
  "@storybook/vue3": "6.5.15",
63
80
  "@types/faker": "5.5.9",
81
+ "@types/marked": "4.0.8",
64
82
  "@vue/composition-api": "1.7.0",
65
83
  "faker": "5.5.3",
66
84
  "sass": "1.32.8",
@@ -123,6 +141,5 @@
123
141
  "default": "./dist/bundled/v3/components/*/index.js"
124
142
  },
125
143
  "./package.json": "./package.json"
126
- },
127
- "gitHead": "acdc7ab9290ea97b4b82958b4b0c8c1ce5624c7e"
144
+ }
128
145
  }
@@ -15,7 +15,7 @@
15
15
  </slot>
16
16
  </div>
17
17
 
18
- <div :class="['grow', 'overflow-y-auto', 'overflow-x-hidden']">
18
+ <div :class="['grow', 'overflow-y-auto']">
19
19
  <slot />
20
20
  <div
21
21
  v-if="confirmationText"
@@ -0,0 +1,16 @@
1
+ import {
2
+ Title,
3
+ Subtitle,
4
+ Description,
5
+ Primary,
6
+ ArgsTable,
7
+ Stories,
8
+ PRIMARY_STORY
9
+ } from '@storybook/addon-docs';
10
+
11
+ <Title />
12
+ <Subtitle />
13
+ <Description />
14
+ <Primary />
15
+ <ArgsTable story={PRIMARY_STORY} />
16
+ <Stories />
@@ -0,0 +1,62 @@
1
+ import { Meta, StoryFn } from '@storybook/vue3';
2
+ import { ref } from 'vue-demi';
3
+ import OrRichTextEditorDocs from './OrRichTextEditor.docs.mdx';
4
+ import OrRichTextEditor from './OrRichTextEditor.vue';
5
+
6
+ export default {
7
+ title: 'Experimental/OrRichTextEditor',
8
+ component: OrRichTextEditor,
9
+
10
+ argTypes: {
11
+ // Props
12
+ description: {
13
+ control: { type: 'text' },
14
+ },
15
+ placeholder: {
16
+ control: { type: 'text' },
17
+ },
18
+ modelValue: {
19
+ control: { type: 'text' },
20
+ },
21
+ markdown: {
22
+ control: { type: 'boolean' },
23
+ },
24
+ },
25
+
26
+ parameters: {
27
+ docs: {
28
+ page: OrRichTextEditorDocs,
29
+ },
30
+
31
+ design: {
32
+ type: 'figma',
33
+ url: 'https://www.figma.com/file/o7DdkaznUW2PtX4wiSuhhQ/Core?node-id=608%3A2926',
34
+ },
35
+ },
36
+ } as Meta<typeof OrRichTextEditor>;
37
+
38
+ const Template: StoryFn<typeof OrRichTextEditor> = (args) => ({
39
+ components: {
40
+ OrRichTextEditor,
41
+ },
42
+
43
+ setup() {
44
+ // Refs
45
+ const text = ref('');
46
+ return {
47
+ args,
48
+ text,
49
+ };
50
+ },
51
+
52
+ template: `
53
+ <div class="p-md">
54
+ <OrRichTextEditor
55
+ v-bind="args"
56
+ v-model="text"
57
+ />
58
+ </div>
59
+ `,
60
+ });
61
+
62
+ export const RichTextEditor = Template.bind({});
@@ -0,0 +1,520 @@
1
+ <template>
2
+ <div
3
+ ref="root"
4
+ v-bind="$attrs"
5
+ :class="rootStyles"
6
+ >
7
+ <or-label>
8
+ {{ description }}
9
+ </or-label>
10
+ <div
11
+ ref="containerRef"
12
+ :class="containerStyles"
13
+ @click="handleEditorClick()"
14
+ >
15
+ <div :class="toolbarContainerStyles">
16
+ <div
17
+ v-for="tool in toolbar"
18
+ :key="tool"
19
+ :class="toolbarStyles"
20
+ >
21
+ <div
22
+ v-for="item in tool"
23
+ :key="item"
24
+ :class="toolbarButtonStyles(item)"
25
+ class="-my-xs"
26
+ >
27
+ <or-icon-button
28
+ v-if="item==='heading'"
29
+ ref="toolbarButtonRef"
30
+ :tooltip="{text: item, placement: 'top'}"
31
+ :icon="{icon: headingIcon, variant: 'inherit', size: 'm'}"
32
+ @click="menuRef.open()"
33
+ />
34
+ <or-icon-button
35
+ v-else
36
+ :tooltip="{text: iconTooltipsEnum[item], placement: 'top'}"
37
+ :icon="{icon: iconsEnum[item], variant: 'inherit', size: 'm'}"
38
+ @click="handleToolbarClick(item)"
39
+ />
40
+ </div>
41
+ </div>
42
+ </div>
43
+ <div
44
+ ref="editorRef"
45
+ :class="editorInputStyles"
46
+ />
47
+ </div>
48
+ <or-menu
49
+ v-if="toolbarButtonRef"
50
+ ref="menuRef"
51
+ :trigger="toolbarButtonRef[getIndexOfHeading].root"
52
+ placement="bottom-start"
53
+ >
54
+ <or-menu-item
55
+ v-for="heading in headingLevels"
56
+ :key="heading"
57
+ @click="handleToolbarClick('heading', heading)"
58
+ >
59
+ Heading {{ heading }}
60
+ </or-menu-item>
61
+ <or-menu-item
62
+ @click="handleToolbarClick('heading')"
63
+ >
64
+ None
65
+ </or-menu-item>
66
+ </or-menu>
67
+ </div>
68
+ </template>
69
+
70
+ <script lang="ts">
71
+ import { defineComponent, ref, onMounted, onBeforeUnmount, computed, watch } from 'vue-demi';
72
+ import { useClassAttribute } from '../../hooks';
73
+ import {
74
+ MarkdownSerializer as ProseMirrorMarkdownSerializer,
75
+ defaultMarkdownSerializer,
76
+ } from 'prosemirror-markdown';
77
+ import { DOMParser as ProseMirrorDOMParser, Node, Mark } from 'prosemirror-model';
78
+ import { marked } from 'marked';
79
+ import { OrIconButtonV3 as OrIconButton } from '../or-icon-button-v3';
80
+ import { OrLabelV3 as OrLabel } from '../or-label-v3';
81
+ import { OrMenuV3 as OrMenu } from '../or-menu-v3';
82
+ import { OrMenuItemV3 as OrMenuItem } from '../or-menu-item-v3';
83
+ import {
84
+ EditorContainer,
85
+ ToolbarContainer,
86
+ Toolbar,
87
+ ToolbarButtonActive,
88
+ ToolbarButton,
89
+ EditorInput,
90
+ } from './styles';
91
+
92
+ import { Editor, mergeAttributes } from '@tiptap/core';
93
+ import StarterKit from '@tiptap/starter-kit';
94
+ import Underline from '@tiptap/extension-underline';
95
+ import Link from '@tiptap/extension-link';
96
+ import Highlight from '@tiptap/extension-highlight';
97
+ import Heading, { Level } from '@tiptap/extension-heading';
98
+ import Placeholder from '@tiptap/extension-placeholder';
99
+ import Paragraph from '@tiptap/extension-paragraph';
100
+ import BulletList from '@tiptap/extension-bullet-list';
101
+ import ListItem from '@tiptap/extension-list-item';
102
+ import OrderedList from '@tiptap/extension-ordered-list';
103
+ import Strike from '@tiptap/extension-strike';
104
+ import Italic from '@tiptap/extension-italic';
105
+ // import HardBreak from '@tiptap/extension-hard-break';
106
+ import Bold from '@tiptap/extension-bold';
107
+
108
+ export default defineComponent({
109
+ name: 'OrRichTextEditor',
110
+
111
+ components: {
112
+ OrIconButton,
113
+ OrLabel,
114
+ OrMenuItem,
115
+ OrMenu,
116
+ },
117
+
118
+ inheritAttrs: false,
119
+
120
+ props: {
121
+ modelValue: {
122
+ type: String,
123
+ default: '',
124
+ required: false,
125
+ },
126
+ toolbar: {
127
+ type: Array,
128
+ default: () => [['heading'], ['bold', 'italic', 'strike'], ['underline', 'highlight'], ['link'], ['bulletList', 'orderedList'], ['undo', 'redo']],
129
+ },
130
+ description: {
131
+ type: String,
132
+ default: 'Description',
133
+ },
134
+ placeholder: {
135
+ type: String,
136
+ default: 'Write something...',
137
+ },
138
+ autofocus: {
139
+ type: Boolean,
140
+ default: false,
141
+ },
142
+ markdown: {
143
+ type: Boolean,
144
+ default: true,
145
+ },
146
+ },
147
+
148
+ emits: ['update:modelValue'],
149
+
150
+ setup(props, { emit }) {
151
+ // Refs
152
+ let editor = null as Editor | null;
153
+ const editorRef = ref<HTMLDivElement>();
154
+ const containerRef = ref<HTMLDivElement>();
155
+ const toolbarButtonRef = ref<InstanceType<typeof OrIconButton>>();
156
+ const menuRef = ref<InstanceType<typeof OrMenu>>();
157
+ const isActive = ref<{[key: string]: boolean;}>({});
158
+ const headingLevels = [1, 2, 3, 4] as Level[];
159
+ const previousHeadingLevel = ref<Level>();
160
+ const activeHeadingLevel = ref<number>(0);
161
+ const markdownOutput = ref<string>('');
162
+ const iconsEnum = ref<{[key: string]: string;}>({
163
+ bold: 'format_bold',
164
+ italic: 'format_italic',
165
+ underline: 'format_underlined',
166
+ strike: 'format_strikethrough',
167
+ bulletList: 'format_list_bulleted',
168
+ orderedList: 'format_list_numbered',
169
+ link: 'link',
170
+ highlight: 'highlight',
171
+ redo: 'redo',
172
+ undo: 'undo',
173
+ });
174
+
175
+ const iconTooltipsEnum = ref<{[key: string]: string;}>({
176
+ bold: 'Bold',
177
+ italic: 'Italic',
178
+ underline: 'Underline',
179
+ strike: 'Strike',
180
+ bulletList: 'Bulleted List',
181
+ orderedList: 'Numbered List',
182
+ link: 'Link',
183
+ highlight: 'Highlight',
184
+ redo: 'Redo',
185
+ undo: 'Undo',
186
+ });
187
+
188
+ const serializerMarks = {
189
+ ...defaultMarkdownSerializer.marks,
190
+ [Bold.name]: defaultMarkdownSerializer.marks.strong,
191
+ [Strike.name]: {
192
+ open: '~~',
193
+ close: '~~',
194
+ mixable: true,
195
+ expelEnclosingWhitespace: true,
196
+ },
197
+ [Italic.name]: {
198
+ open: '_',
199
+ close: '_',
200
+ mixable: true,
201
+ expelEnclosingWhitespace: true,
202
+ },
203
+ [Highlight.name]: {
204
+ open: '==',
205
+ close: '==',
206
+ mixable: true,
207
+ expelEnclosingWhitespace: true,
208
+ },
209
+ [Link.name]: {
210
+ open(state: any, mark: Mark, parent: Node, index: number) {
211
+ return isPlainURL(mark, parent, index, 1) ? '<' : '[';
212
+ },
213
+ close(state: any, mark: Mark, parent: Node, index: number) {
214
+ const href = mark.attrs.canonicalSrc || mark.attrs.href;
215
+
216
+ return isPlainURL(mark, parent, index, -1)
217
+ ? '>'
218
+ : `](${state.esc(href)}${
219
+ mark.attrs.title ? ` ${state.quote(mark.attrs.title)}` : ''
220
+ })`;
221
+ },
222
+ },
223
+
224
+ };
225
+
226
+ const serializerNodes = {
227
+ ...defaultMarkdownSerializer.nodes,
228
+ [Paragraph.name]: defaultMarkdownSerializer.nodes.paragraph,
229
+ [BulletList.name]: defaultMarkdownSerializer.nodes.bullet_list,
230
+ [ListItem.name]: defaultMarkdownSerializer.nodes.list_item,
231
+ [OrderedList.name]: defaultMarkdownSerializer.nodes.ordered_list,
232
+ // [HardBreak.name]: //TODO: add hard break
233
+ };
234
+
235
+ onMounted(() => {
236
+ editor = new Editor({
237
+ onUpdate: ({ editor }) => {
238
+ setActiveFormats();
239
+ const html = editor.getHTML();
240
+ const text = editor.getText();
241
+ if (props.markdown) {
242
+ const markdown = markdownOutput.value = serialize(editor.schema, editor.getJSON());
243
+ emit('update:modelValue', markdown);
244
+ } else {
245
+ emit('update:modelValue', text === '' ? text : html);
246
+ }
247
+ },
248
+ onCreate: ({ editor }) => {
249
+ if (props.markdown) {
250
+ const deserialized = deserialize(editor.schema, props.modelValue);
251
+ editor.commands.setContent(deserialized);
252
+ } else {
253
+ editor.commands.setContent(props.modelValue);
254
+ }
255
+ },
256
+ element: editorRef.value,
257
+ autofocus: props.autofocus,
258
+ extensions: [
259
+ StarterKit.configure({
260
+ heading: false,
261
+ }),
262
+ Heading.configure({ levels: headingLevels }).extend({
263
+ levels: headingLevels,
264
+ renderHTML({ node, HTMLAttributes }) {
265
+ return [
266
+ 'h' + node.attrs.level,
267
+ mergeAttributes(HTMLAttributes, {
268
+ class: `typography-headline-${node.attrs.level}`,
269
+ }),
270
+ 0,
271
+ ];
272
+ },
273
+ }),
274
+ Underline,
275
+ Link.configure({
276
+ openOnClick: true,
277
+ linkOnPaste: true,
278
+ autolink: false,
279
+ protocols: ['ftp', 'mailto', 'http', 'https'],
280
+ validate: href => /^https?:\/\//.test(href),
281
+ HTMLAttributes: {
282
+ class: 'text-primary cursor-pointer',
283
+ },
284
+ }),
285
+ Highlight,
286
+ Placeholder
287
+ .configure({
288
+ placeholder: props.placeholder,
289
+ emptyEditorClass: 'is-editor-empty text-outline',
290
+ }),
291
+ ],
292
+ editorProps: {
293
+ attributes: {
294
+ class: 'focus:outline-none',
295
+ },
296
+ },
297
+ });
298
+ setActiveFormats();
299
+ });
300
+
301
+ onBeforeUnmount(() => {
302
+ editor?.destroy();
303
+ });
304
+
305
+ // Computed
306
+ const getIndexOfHeading = computed(() => {
307
+ return props.toolbar.flat().indexOf('heading');
308
+ });
309
+
310
+ const headingIcon = computed(() => {
311
+ if (activeHeadingLevel.value && isActive.value.heading) {
312
+ return `format_h${activeHeadingLevel.value}`;
313
+ }
314
+ return 'format_paragraph';
315
+ });
316
+
317
+ // Methods
318
+ const handleEditorClick = () => {
319
+ setActiveFormats();
320
+ editor?.commands.focus();
321
+ };
322
+
323
+ const handleToolbarClick = (item: string, level?: number) => {
324
+ if (item === 'bulletList' || item === 'orderedList') {
325
+ item === 'bulletList' ? editor?.commands.toggleBulletList() : editor?.commands.toggleOrderedList();
326
+ }
327
+ else if (item === 'link') {
328
+ setLink();
329
+ }
330
+ else if (item === 'heading') {
331
+ if (!level) {
332
+ editor?.commands.toggleHeading({ level: previousHeadingLevel.value as Level });
333
+ activeHeadingLevel.value = 0;
334
+ } else {
335
+ activeHeadingLevel.value = level;
336
+ previousHeadingLevel.value = level as Level;
337
+ editor?.commands.toggleHeading({ level: level as Level });
338
+ }
339
+ editor?.commands.focus();
340
+ }
341
+ else if (item === 'undo' || item === 'redo') {
342
+ item === 'undo' ? editor?.commands.undo() : editor?.commands.redo();
343
+ }
344
+ else {
345
+ editor?.chain().focus().toggleMark(item).run();
346
+ }
347
+ };
348
+
349
+ const setLink = () => {
350
+ const previousUrl = editor?.getAttributes('link').href;
351
+ const url = window.prompt('URL', previousUrl);
352
+
353
+ // cancelled
354
+ if (url === null) {
355
+ return;
356
+ }
357
+
358
+ // empty
359
+ if (url === '') {
360
+ editor?.chain().focus().extendMarkRange('link').unsetLink().run();
361
+ return;
362
+ }
363
+
364
+ // update link
365
+ editor?.chain()
366
+ .focus()
367
+ .extendMarkRange('link')
368
+ .setLink({ href: url })
369
+ .run();
370
+ };
371
+
372
+ const setActiveFormats = () => {
373
+ const toolbarList = props.toolbar.flat() as string[];
374
+ toolbarList.forEach((item) => {
375
+ isActive.value[item] = editor?.isActive(item) || false;
376
+ });
377
+ };
378
+
379
+ // Styles
380
+ const classAttribute = useClassAttribute();
381
+
382
+ const rootStyles = computed(() => {
383
+ return [
384
+ 'or-rich-text-editor',
385
+ classAttribute.value,
386
+ ];
387
+ });
388
+
389
+ const containerStyles = computed(() => {
390
+ return [
391
+ ...EditorContainer,
392
+ ];
393
+ });
394
+
395
+ const toolbarContainerStyles = computed(() => {
396
+ return [
397
+ ...ToolbarContainer,
398
+ ];
399
+ });
400
+
401
+ const toolbarStyles = computed(() => {
402
+ return [
403
+ ...Toolbar,
404
+ ];
405
+ });
406
+
407
+ const editorInputStyles = computed(() => {
408
+ return [
409
+ 'tiptap-editor',
410
+ ...EditorInput,
411
+ ];
412
+ });
413
+
414
+ const toolbarButtonStyles = (item: string) => {
415
+ return [
416
+ // Layout
417
+ 'flex',
418
+ // Spacing
419
+ 'gap-md',
420
+ ...isActive.value[item] ? ToolbarButtonActive : ToolbarButton,
421
+ ];
422
+ };
423
+
424
+ const isPlainURL = (link: Mark, parent: Node, index: number, side: number) => {
425
+ if (link.attrs.title || !/^\w+:/.test(link.attrs.href)) return false;
426
+ const content = parent.child(index + (side < 0 ? -1 : 0));
427
+ if (
428
+ !content.isText ||
429
+ content.text !== link.attrs.href ||
430
+ content.marks[content.marks.length - 1] !== link
431
+ )
432
+ return false;
433
+ if (index === (side < 0 ? 1 : parent.childCount - 1)) return true;
434
+ const next = parent.child(index + (side < 0 ? -2 : 1));
435
+ return !link.isInSet(next.marks);
436
+ };
437
+
438
+ const serialize = (schema: any, content: any) => {
439
+ const proseMirrorDocument = schema.nodeFromJSON(content);
440
+ const serializer = new ProseMirrorMarkdownSerializer(
441
+ serializerNodes,
442
+ serializerMarks,
443
+ );
444
+
445
+ return serializer.serialize(proseMirrorDocument, {
446
+ tightLists: true,
447
+ });
448
+ };
449
+
450
+ const deserialize = (schema: any, content: any) => {
451
+ const html = marked.parse(content);
452
+
453
+ if (!html) return null;
454
+
455
+ const parser = new DOMParser();
456
+ const { body } = parser.parseFromString(html, 'text/html');
457
+
458
+ // append original source as a comment that nodes can access
459
+ body.append(document.createComment(content));
460
+
461
+ const state = ProseMirrorDOMParser.fromSchema(schema).parse(body);
462
+
463
+ return state.toJSON();
464
+ };
465
+
466
+ //Effects
467
+ watch(() => props.modelValue, (value) => {
468
+ if (value !== editor?.getHTML() && !props.markdown) {
469
+ editor?.commands.setContent(value);
470
+ }
471
+ if (props.markdown && value !== markdownOutput.value) {
472
+ editor?.commands.setContent(markdownOutput.value);
473
+ }
474
+ });
475
+
476
+ return {
477
+ editor,
478
+ editorRef,
479
+ containerRef,
480
+ toolbarButtonRef,
481
+ menuRef,
482
+ iconsEnum,
483
+ handleToolbarClick,
484
+ handleEditorClick,
485
+ isActive,
486
+ iconTooltipsEnum,
487
+ containerStyles,
488
+ toolbarContainerStyles,
489
+ toolbarStyles,
490
+ rootStyles,
491
+ toolbarButtonStyles,
492
+ editorInputStyles,
493
+ getIndexOfHeading,
494
+ headingLevels,
495
+ headingIcon,
496
+ };
497
+ },
498
+ });
499
+ </script>
500
+
501
+ <style lang="scss">
502
+ .tiptap-editor {
503
+ ol { //see if editor can not inherit it
504
+ margin: 0 24px;
505
+ list-style: decimal;
506
+ }
507
+
508
+ ul {
509
+ margin: 0 24px;
510
+ list-style: initial;
511
+ }
512
+
513
+ .is-editor-empty::before {
514
+ content: attr(data-placeholder);
515
+ height: 0;
516
+ pointer-events: none;
517
+ float: left;
518
+ }
519
+ }
520
+ </style>
@@ -0,0 +1 @@
1
+ export { default as OrRichTextEditor } from './OrRichTextEditor.vue';