@onereach/ui-components 4.1.1 → 4.2.0-beta.2544.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 (123) hide show
  1. package/dist/bundled/v2/components/OrCode/OrCode.js +6 -3727
  2. package/dist/bundled/v2/components/OrCode/index.js +6 -2
  3. package/dist/bundled/v2/components/OrCode/lang.js +3897 -3
  4. package/dist/bundled/v2/components/OrCode/theme.js +2 -1
  5. package/dist/bundled/v2/components/OrConfirm/OrConfirm.js +1 -0
  6. package/dist/bundled/v2/components/OrConfirm/index.js +1 -0
  7. package/dist/bundled/v2/components/OrModal/OrModal.js +3 -1266
  8. package/dist/bundled/v2/components/OrModal/index.js +1 -0
  9. package/dist/bundled/v2/components/OrRichTextEditorV3/OrRichTextEditor.js +1988 -0
  10. package/dist/bundled/v2/components/OrRichTextEditorV3/OrRichTextEditor.vue.d.ts +170 -0
  11. package/dist/bundled/v2/components/OrRichTextEditorV3/index.d.ts +1 -0
  12. package/dist/bundled/v2/components/OrRichTextEditorV3/index.js +68 -0
  13. package/dist/bundled/v2/components/OrRichTextEditorV3/styles.d.ts +6 -0
  14. package/dist/bundled/v2/components/OrRichTextEditorV3/styles.js +38 -0
  15. package/dist/bundled/v2/components/OrRichTextEditorV3/utils/codemirror/codemirrorNode.d.ts +3 -0
  16. package/dist/bundled/v2/components/OrRichTextEditorV3/utils/codemirror/codemirrorNode.js +45 -0
  17. package/dist/bundled/v2/components/OrRichTextEditorV3/utils/codemirror/codemirrorView.d.ts +27 -0
  18. package/dist/bundled/v2/components/OrRichTextEditorV3/utils/codemirror/codemirrorView.js +184 -0
  19. package/dist/bundled/v2/components/OrRichTextEditorV3/utils/codemirror/index.d.ts +1 -0
  20. package/dist/bundled/v2/components/OrRichTextEditorV3/utils/codemirror/index.js +5 -0
  21. package/dist/bundled/v2/components/OrRichTextEditorV3/utils/codemirror/theme.d.ts +24 -0
  22. package/dist/bundled/v2/components/OrRichTextEditorV3/utils/codemirror/theme.js +190 -0
  23. package/dist/bundled/v2/components/OrRichTextEditorV3/utils/codemirror/types.d.ts +19 -0
  24. package/dist/bundled/v2/components/OrRichTextEditorV3/utils/codemirror/types.js +1 -0
  25. package/dist/bundled/v2/components/OrRichTextEditorV3/utils/markdown.d.ts +3 -0
  26. package/dist/bundled/v2/components/OrRichTextEditorV3/utils/markdown.js +5 -0
  27. package/dist/bundled/v2/components/index.d.ts +1 -0
  28. package/dist/bundled/v2/components/index.js +15 -2
  29. package/dist/bundled/{v3/OrCode.vue_vue_type_script_lang-c5a9adb7.js → v2/index-16aee5bc.js} +14 -234
  30. package/dist/bundled/v2/index-62c3221b.js +6956 -0
  31. package/dist/bundled/{v3/lang-02d2bb2d.js → v2/index-70ca38c5.js} +73 -3965
  32. package/dist/bundled/v2/{index-6976c52a.js → index-f5487f12.js} +3 -115
  33. package/dist/bundled/v2/index.es-3f39f316.js +115 -0
  34. package/dist/bundled/v2/index.js +18 -5
  35. package/dist/bundled/v2/markdown-516daba9.js +18737 -0
  36. package/dist/bundled/v2/tiptap-core.esm-f85402b1.js +9360 -0
  37. package/dist/bundled/{v3/OrModal.vue_vue_type_script_lang-d5fb0b11.js → v2/useFocusTrap-9567b3c8.js} +3 -105
  38. package/dist/bundled/v3/OrCode.vue_vue_type_script_lang-f6f74339.js +236 -0
  39. package/dist/bundled/v3/{OrConfirm.vue_vue_type_script_lang-806d209b.js → OrConfirm.vue_vue_type_script_lang-36318ca2.js} +1 -1
  40. package/dist/bundled/v3/OrModal.vue_vue_type_script_lang-af0c4288.js +107 -0
  41. package/dist/bundled/v3/OrRichTextEditor.vue_vue_type_script_lang-2bb9d87f.js +1765 -0
  42. package/dist/bundled/v3/components/OrCode/OrCode.js +10 -6
  43. package/dist/bundled/v3/components/OrCode/index.js +8 -4
  44. package/dist/bundled/v3/components/OrCode/lang.js +3897 -3
  45. package/dist/bundled/v3/components/OrCode/theme.js +2 -1
  46. package/dist/bundled/v3/components/OrConfirm/OrConfirm.js +4 -3
  47. package/dist/bundled/v3/components/OrConfirm/index.js +3 -2
  48. package/dist/bundled/v3/components/OrModal/OrModal.js +3 -2
  49. package/dist/bundled/v3/components/OrModal/index.js +2 -1
  50. package/dist/bundled/v3/components/OrRichTextEditorV3/OrRichTextEditor.js +227 -0
  51. package/dist/bundled/v3/components/OrRichTextEditorV3/OrRichTextEditor.vue.d.ts +170 -0
  52. package/dist/bundled/v3/components/OrRichTextEditorV3/index.d.ts +1 -0
  53. package/dist/bundled/v3/components/OrRichTextEditorV3/index.js +84 -0
  54. package/dist/bundled/v3/components/OrRichTextEditorV3/styles.d.ts +6 -0
  55. package/dist/bundled/v3/components/OrRichTextEditorV3/styles.js +38 -0
  56. package/dist/bundled/v3/components/OrRichTextEditorV3/utils/codemirror/codemirrorNode.d.ts +3 -0
  57. package/dist/bundled/v3/components/OrRichTextEditorV3/utils/codemirror/codemirrorNode.js +45 -0
  58. package/dist/bundled/v3/components/OrRichTextEditorV3/utils/codemirror/codemirrorView.d.ts +27 -0
  59. package/dist/bundled/v3/components/OrRichTextEditorV3/utils/codemirror/codemirrorView.js +184 -0
  60. package/dist/bundled/v3/components/OrRichTextEditorV3/utils/codemirror/index.d.ts +1 -0
  61. package/dist/bundled/v3/components/OrRichTextEditorV3/utils/codemirror/index.js +5 -0
  62. package/dist/bundled/v3/components/OrRichTextEditorV3/utils/codemirror/theme.d.ts +24 -0
  63. package/dist/bundled/v3/components/OrRichTextEditorV3/utils/codemirror/theme.js +190 -0
  64. package/dist/bundled/v3/components/OrRichTextEditorV3/utils/codemirror/types.d.ts +19 -0
  65. package/dist/bundled/v3/components/OrRichTextEditorV3/utils/codemirror/types.js +1 -0
  66. package/dist/bundled/v3/components/OrRichTextEditorV3/utils/markdown.d.ts +3 -0
  67. package/dist/bundled/v3/components/OrRichTextEditorV3/utils/markdown.js +5 -0
  68. package/dist/bundled/v3/components/index.d.ts +1 -0
  69. package/dist/bundled/v3/components/index.js +19 -5
  70. package/dist/bundled/v3/index-16aee5bc.js +3740 -0
  71. package/dist/bundled/v3/index-62c3221b.js +6956 -0
  72. package/dist/bundled/{v2/lang-02d2bb2d.js → v3/index-70ca38c5.js} +73 -3965
  73. package/dist/bundled/v3/{index-6976c52a.js → index-f5487f12.js} +3 -115
  74. package/dist/bundled/v3/index.es-3f39f316.js +115 -0
  75. package/dist/bundled/v3/index.js +23 -9
  76. package/dist/bundled/v3/markdown-516daba9.js +18737 -0
  77. package/dist/bundled/v3/tiptap-core.esm-f85402b1.js +9360 -0
  78. package/dist/bundled/v3/useFocusTrap-9567b3c8.js +1268 -0
  79. package/dist/esm/v2/OrRichTextEditor-dfddef2b.js +722 -0
  80. package/dist/esm/v2/codemirrorView-be2c7423.js +353 -0
  81. package/dist/esm/v2/components/index.d.ts +1 -0
  82. package/dist/esm/v2/components/index.js +24 -0
  83. package/dist/esm/v2/components/or-rich-text-editor-v3/OrRichTextEditor.vue.d.ts +170 -0
  84. package/dist/esm/v2/components/or-rich-text-editor-v3/index.d.ts +1 -0
  85. package/dist/esm/v2/components/or-rich-text-editor-v3/index.js +59 -0
  86. package/dist/esm/v2/components/or-rich-text-editor-v3/styles.d.ts +6 -0
  87. package/dist/esm/v2/components/or-rich-text-editor-v3/utils/codemirror/codemirrorNode.d.ts +3 -0
  88. package/dist/esm/v2/components/or-rich-text-editor-v3/utils/codemirror/codemirrorView.d.ts +27 -0
  89. package/dist/esm/v2/components/or-rich-text-editor-v3/utils/codemirror/index.d.ts +1 -0
  90. package/dist/esm/v2/components/or-rich-text-editor-v3/utils/codemirror/index.js +7 -0
  91. package/dist/esm/v2/components/or-rich-text-editor-v3/utils/codemirror/theme.d.ts +24 -0
  92. package/dist/esm/v2/components/or-rich-text-editor-v3/utils/codemirror/types.d.ts +19 -0
  93. package/dist/esm/v2/components/or-rich-text-editor-v3/utils/markdown.d.ts +3 -0
  94. package/dist/esm/v2/index.js +24 -0
  95. package/dist/esm/v3/OrRichTextEditor-f4ce18ef.js +686 -0
  96. package/dist/esm/v3/codemirrorView-be2c7423.js +353 -0
  97. package/dist/esm/v3/components/index.d.ts +1 -0
  98. package/dist/esm/v3/components/index.js +24 -0
  99. package/dist/esm/v3/components/or-rich-text-editor-v3/OrRichTextEditor.vue.d.ts +170 -0
  100. package/dist/esm/v3/components/or-rich-text-editor-v3/index.d.ts +1 -0
  101. package/dist/esm/v3/components/or-rich-text-editor-v3/index.js +57 -0
  102. package/dist/esm/v3/components/or-rich-text-editor-v3/styles.d.ts +6 -0
  103. package/dist/esm/v3/components/or-rich-text-editor-v3/utils/codemirror/codemirrorNode.d.ts +3 -0
  104. package/dist/esm/v3/components/or-rich-text-editor-v3/utils/codemirror/codemirrorView.d.ts +27 -0
  105. package/dist/esm/v3/components/or-rich-text-editor-v3/utils/codemirror/index.d.ts +1 -0
  106. package/dist/esm/v3/components/or-rich-text-editor-v3/utils/codemirror/index.js +7 -0
  107. package/dist/esm/v3/components/or-rich-text-editor-v3/utils/codemirror/theme.d.ts +24 -0
  108. package/dist/esm/v3/components/or-rich-text-editor-v3/utils/codemirror/types.d.ts +19 -0
  109. package/dist/esm/v3/components/or-rich-text-editor-v3/utils/markdown.d.ts +3 -0
  110. package/dist/esm/v3/index.js +24 -0
  111. package/package.json +25 -5
  112. package/src/components/index.ts +1 -0
  113. package/src/components/or-rich-text-editor-v3/OrRichTextEditor.docs.mdx +7 -0
  114. package/src/components/or-rich-text-editor-v3/OrRichTextEditor.stories3.ts +103 -0
  115. package/src/components/or-rich-text-editor-v3/OrRichTextEditor.vue +624 -0
  116. package/src/components/or-rich-text-editor-v3/index.ts +1 -0
  117. package/src/components/or-rich-text-editor-v3/styles.ts +64 -0
  118. package/src/components/or-rich-text-editor-v3/utils/codemirror/codemirrorNode.ts +40 -0
  119. package/src/components/or-rich-text-editor-v3/utils/codemirror/codemirrorView.ts +254 -0
  120. package/src/components/or-rich-text-editor-v3/utils/codemirror/index.ts +1 -0
  121. package/src/components/or-rich-text-editor-v3/utils/codemirror/theme.ts +213 -0
  122. package/src/components/or-rich-text-editor-v3/utils/codemirror/types.ts +22 -0
  123. package/src/components/or-rich-text-editor-v3/utils/markdown.ts +117 -0
@@ -0,0 +1,624 @@
1
+ <template>
2
+ <div
3
+ ref="root"
4
+ :class="rootStyles"
5
+ >
6
+ <or-label>
7
+ {{ description }}
8
+ </or-label>
9
+ <div
10
+ ref="containerRef"
11
+ :class="containerStyles"
12
+ @click="handleEditorClick()"
13
+ >
14
+ <div :class="toolbarContainerStyles">
15
+ <div
16
+ v-for="(tool, index) in toolbar"
17
+ :key="index"
18
+ :class="toolbarStyles"
19
+ >
20
+ <div
21
+ v-for="item in tool"
22
+ :key="item"
23
+ class="flex gap-md"
24
+ >
25
+ <or-icon-button
26
+ v-if="item==='heading'"
27
+ ref="toolbarButtonRef"
28
+ :selected="isActive[item]"
29
+ :disabled="!isFocused"
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
+ :selected="isActive[item]"
38
+ :disabled="!isFocused"
39
+ :icon="{icon: iconsEnum[item], variant: 'inherit', size: 'm'}"
40
+ @click="handleToolbarClick(item)"
41
+ />
42
+ </div>
43
+ </div>
44
+ </div>
45
+ <div class="p-sm">
46
+ <div
47
+ ref="editorRef"
48
+ :class="editorInputStyles"
49
+ />
50
+ <slot name="files" />
51
+ </div>
52
+ </div>
53
+ <or-menu
54
+ v-if="toolbarButtonRef"
55
+ ref="menuRef"
56
+ :trigger="toolbarButtonRef[getIndexOfHeading].root"
57
+ placement="bottom-start"
58
+ >
59
+ <or-menu-item
60
+ v-for="heading in headingLevels"
61
+ :key="heading"
62
+ @click="handleToolbarClick('heading', heading)"
63
+ >
64
+ Heading {{ heading }}
65
+ </or-menu-item>
66
+ <or-menu-item
67
+ @click="handleToolbarClick('heading')"
68
+ >
69
+ None
70
+ </or-menu-item>
71
+ </or-menu>
72
+ <or-modal
73
+ :is-open="isOpenLinkModal"
74
+ size="s"
75
+ >
76
+ <template v-slot:header>
77
+ <p class="text-headline-2">
78
+ Add Link
79
+ </p>
80
+ </template>
81
+ <div>
82
+ <or-label>
83
+ Text
84
+ </or-label>
85
+ <or-input
86
+ v-model="text"
87
+ placeholder="Placeholder"
88
+ class="pb-md"
89
+ />
90
+ <or-label>
91
+ Link
92
+ </or-label>
93
+ <or-input
94
+ v-model="link"
95
+ placeholder="Placeholder"
96
+ />
97
+ </div>
98
+ <template v-slot:footer>
99
+ <div class="flex ml-auto gap-md">
100
+ <or-button
101
+ variant="outlined"
102
+ @click="discardLink"
103
+ >
104
+ <p>Cancel</p>
105
+ </or-button>
106
+ <or-button
107
+ @click="attachLink"
108
+ >
109
+ <p>Save</p>
110
+ </or-button>
111
+ </div>
112
+ </template>
113
+ </or-modal>
114
+ </div>
115
+ </template>
116
+
117
+ <script lang="ts">
118
+ import { defineComponent, ref, computed, onBeforeUnmount, onMounted, watch } from 'vue-demi';
119
+ import { useFocusTrap, UseFocusTrapReturn } from '@vueuse/integrations/useFocusTrap';
120
+ import { onClickOutside } from '@vueuse/core';
121
+ import { serialize, deserialize } from './utils/markdown';
122
+
123
+ import { OrIconButtonV3 as OrIconButton } from '../or-icon-button-v3';
124
+ import { OrLabelV3 as OrLabel } from '../or-label-v3';
125
+ import { OrMenuV3 as OrMenu } from '../or-menu-v3';
126
+ import { OrMenuItemV3 as OrMenuItem } from '../or-menu-item-v3';
127
+ import { OrModalV3 as OrModal } from '../or-modal-v3';
128
+ import { OrInputV3 as OrInput } from '../or-input-v3';
129
+ import { OrButtonV3 as OrButton } from '../or-button-v3';
130
+
131
+ import {
132
+ EditorContainer,
133
+ ToolbarContainer,
134
+ Toolbar,
135
+ ToolbarButtonFocused,
136
+ ToolbarButton,
137
+ EditorInput,
138
+ } from './styles';
139
+
140
+ import { Editor, mergeAttributes } from '@tiptap/core';
141
+ import StarterKit from '@tiptap/starter-kit';
142
+ import Underline from '@tiptap/extension-underline';
143
+ import Link from '@tiptap/extension-link';
144
+ import Highlight from '@tiptap/extension-highlight';
145
+ import Heading, { Level } from '@tiptap/extension-heading';
146
+ import Placeholder from '@tiptap/extension-placeholder';
147
+
148
+ import codemirrorNode from './utils/codemirror/codemirrorNode';
149
+
150
+ export default defineComponent({
151
+ name: 'OrRichTextEditor',
152
+
153
+ components: {
154
+ OrIconButton,
155
+ OrLabel,
156
+ OrMenuItem,
157
+ OrMenu,
158
+ OrModal,
159
+ OrInput,
160
+ OrButton,
161
+ },
162
+
163
+ inheritAttrs: false,
164
+
165
+ model: {
166
+ prop: 'modelValue',
167
+ event: 'update:modelValue',
168
+ },
169
+
170
+ props: {
171
+ modelValue: {
172
+ type: String,
173
+ default: undefined,
174
+ },
175
+ toolbar: {
176
+ type: Array,
177
+ default: () => [],
178
+ },
179
+ description: {
180
+ type: String,
181
+ default: '',
182
+ },
183
+ placeholder: {
184
+ type: String,
185
+ default: '',
186
+ },
187
+ autofocus: {
188
+ type: Boolean,
189
+ default: false,
190
+ },
191
+ markdownFormat: {
192
+ type: Boolean,
193
+ default: false,
194
+ },
195
+ fullHeight: {
196
+ type: Boolean,
197
+ default: false,
198
+ },
199
+ },
200
+
201
+ emits: [
202
+ 'update:modelValue',
203
+
204
+ 'input',
205
+ 'file-upload',
206
+ ],
207
+
208
+ expose: [
209
+ 'root',
210
+ ],
211
+
212
+ setup(props, context) {
213
+ // Refs
214
+ const root = ref<HTMLElement>();
215
+ let editor = null as Editor | null;
216
+ const editorRef = ref<HTMLDivElement>();
217
+ const containerRef = ref<HTMLDivElement>();
218
+ const toolbarButtonRef = ref<InstanceType<typeof OrIconButton>>();
219
+ const menuRef = ref<InstanceType<typeof OrMenu>>();
220
+ const isActive = ref<{[key: string]: boolean;}>({});
221
+ const isFocused = ref<boolean>(props.autofocus);
222
+ const headingLevels = [1, 2, 3, 4] as Level[];
223
+ const activeHeadingLevel = ref<number>(0);
224
+ const markdownOutput = ref<string>('');
225
+ const isOpenLinkModal = ref<boolean>(false);
226
+ const text = ref<string>('');
227
+ const link = ref<string>('');
228
+ let trap: UseFocusTrapReturn = useFocusTrap(editorRef, {
229
+ immediate: true,
230
+ fallbackFocus: '.container',
231
+ allowOutsideClick: true,
232
+ });
233
+ const iconsEnum = ref<{[key: string]: string;}>({
234
+ bold: 'format_bold',
235
+ italic: 'format_italic',
236
+ underline: 'format_underlined',
237
+ strike: 'format_strikethrough',
238
+ bulletList: 'format_list_bulleted',
239
+ orderedList: 'format_list_numbered',
240
+ link: 'link',
241
+ highlight: 'highlight',
242
+ redo: 'redo',
243
+ undo: 'undo',
244
+ codeBlock: 'code_blocks',
245
+ blockquote: 'format_quote',
246
+ file: 'attach_file',
247
+ });
248
+ const iconTooltipsEnum = ref<{[key: string]: string;}>({
249
+ bold: 'Bold',
250
+ italic: 'Italic',
251
+ underline: 'Underline',
252
+ strike: 'Strike',
253
+ bulletList: 'Bulleted List',
254
+ orderedList: 'Numbered List',
255
+ link: 'Link',
256
+ highlight: 'Highlight',
257
+ redo: 'Redo',
258
+ undo: 'Undo',
259
+ codeBlock: 'Code Block',
260
+ blockquote: 'Quote',
261
+ file: 'File',
262
+ });
263
+
264
+ onMounted(() => {
265
+ editor = new Editor({
266
+ onUpdate: ({ editor }) => {
267
+ isFocused.value = true;
268
+ setActiveFormats();
269
+ const html = editor.getHTML();
270
+ const text = editor.getText();
271
+ if (props.markdownFormat) {
272
+ markdownOutput.value = serialize(editor.schema, editor.getJSON());
273
+ proxyModelValue.value = markdownOutput.value;
274
+ } else {
275
+ proxyModelValue.value = text === '' ? text : html;
276
+ }
277
+ },
278
+ onCreate: ({ editor }) => {
279
+ if (props.markdownFormat) {
280
+ const deserialized = deserialize(editor.schema, proxyModelValue.value);
281
+ editor.commands.setContent(deserialized);
282
+ } else {
283
+ editor.commands.setContent(proxyModelValue.value as string);
284
+ }
285
+ },
286
+ element: editorRef.value,
287
+ autofocus: props.autofocus,
288
+ extensions: [
289
+ codemirrorNode,
290
+ StarterKit.configure({
291
+ heading: false,
292
+ codeBlock: false,
293
+ }),
294
+ Heading.configure({ levels: headingLevels }).extend({
295
+ levels: headingLevels,
296
+ renderHTML({ node, HTMLAttributes }) {
297
+ return [
298
+ 'h' + node.attrs.level,
299
+ mergeAttributes(HTMLAttributes, {
300
+ class: `typography-headline-${node.attrs.level}`,
301
+ }),
302
+ 0,
303
+ ];
304
+ },
305
+ }),
306
+ Underline,
307
+ Link.configure({
308
+ openOnClick: true,
309
+ linkOnPaste: true,
310
+ autolink: false,
311
+ protocols: ['ftp', 'mailto', 'http', 'https'],
312
+ validate: href => /^https?:\/\//.test(href),
313
+ HTMLAttributes: {
314
+ class: 'text-primary cursor-pointer',
315
+ },
316
+ }),
317
+ Highlight,
318
+ Placeholder
319
+ .configure({
320
+ placeholder: props.placeholder,
321
+ emptyEditorClass: 'is-editor-empty text-outline',
322
+ }),
323
+ ],
324
+ editorProps: {
325
+ attributes: {
326
+ class: 'focus:outline-none',
327
+ },
328
+ },
329
+ });
330
+ setActiveFormats();
331
+ trap.activate();
332
+ });
333
+
334
+ onBeforeUnmount(() => {
335
+ editor?.destroy();
336
+ });
337
+
338
+ onClickOutside(root, () => {
339
+ isFocused.value = false;
340
+ trap.deactivate();
341
+ });
342
+
343
+ // Computed
344
+ const proxyModelValue = computed({
345
+ get: () => {
346
+ return props.modelValue;
347
+ },
348
+
349
+ set: (value) => {
350
+ context.emit('input', value);
351
+ context.emit('update:modelValue', value);
352
+ },
353
+ });
354
+
355
+ const getIndexOfHeading = computed(() => {
356
+ return props.toolbar.flat().indexOf('heading');
357
+ });
358
+
359
+ const headingIcon = computed(() => {
360
+ if (activeHeadingLevel.value && isActive.value.heading) {
361
+ return `format_h${activeHeadingLevel.value}`;
362
+ }
363
+ return 'format_paragraph';
364
+ });
365
+
366
+ //Methods
367
+ const handleEditorClick = () => {
368
+ setActiveFormats();
369
+ isFocused.value = true;
370
+ editor?.commands.focus();
371
+ activeHeadingLevel.value = editor?.getAttributes('heading')?.level || 0;
372
+ };
373
+
374
+ const handleToolbarClick = (item: string, level?: number) => {
375
+ switch (item) {
376
+ case 'bulletList':
377
+ case 'orderedList':
378
+ item === 'bulletList' ? editor?.commands.toggleBulletList() : editor?.commands.toggleOrderedList();
379
+ break;
380
+ case 'link':
381
+ if (editor) {
382
+ const cursorPosition = editor?.state.selection.$anchor.pos || 0;
383
+ const { from, to, empty } = editor.state.selection;
384
+ const isLink = editor.view.state.doc.nodeAt(cursorPosition)?.marks.filter((mark) => mark.type.name === 'link');
385
+ const existedText = isLink?.length ? editor.view.state.doc.nodeAt(cursorPosition)?.text || '' : '';
386
+
387
+ text.value = empty ? existedText : editor.state.doc.textBetween(from, to, ' ');
388
+ link.value = editor.getAttributes('link').href || '';
389
+ }
390
+ isOpenLinkModal.value = !isOpenLinkModal.value;
391
+ break;
392
+ case 'blockquote':
393
+ editor?.chain().focus().toggleBlockquote().run();
394
+ break;
395
+ case 'codeBlock':
396
+ if (!isActive.value['codeBlock']) {
397
+ editor?.commands.setNode(item, { language: 'javascript' });
398
+ } else {
399
+ editor?.commands.setNode('paragraph');
400
+ }
401
+ break;
402
+ case 'heading':
403
+ if (!level) {
404
+ editor?.commands.toggleHeading({ level: 0 as Level });
405
+ activeHeadingLevel.value = 0;
406
+ } else {
407
+ activeHeadingLevel.value = level;
408
+ editor?.commands.toggleHeading({ level: level as Level });
409
+ }
410
+ editor?.commands.focus();
411
+ break;
412
+ case 'undo':
413
+ case 'redo':
414
+ item === 'undo' ? editor?.commands.undo() : editor?.commands.redo();
415
+ break;
416
+ case 'file':
417
+ context.emit('file-upload');
418
+ break;
419
+ default:
420
+ editor?.chain().focus().toggleMark(item).run();
421
+ break;
422
+ }
423
+ };
424
+
425
+ const attachLink = async () => {
426
+ // empty
427
+ if (link.value === '') {
428
+ editor?.chain().focus().extendMarkRange('link').unsetLink().run();
429
+ }
430
+
431
+ const isEmptySelection = editor?.state.selection.empty;
432
+ const cursorPosition = editor?.state.selection.$anchor.pos || 0;
433
+ const isLink = editor?.view.state.doc.nodeAt(cursorPosition)?.marks.filter((mark) => mark.type.name === 'link');
434
+ const existedText = isLink?.length ? editor?.view.state.doc.nodeAt(cursorPosition)?.text : '';
435
+
436
+ if (link.value && isEmptySelection && !existedText) {
437
+ editor?.chain()
438
+ .focus()
439
+ .setMark('link', {
440
+ href: link.value,
441
+ target: '__blank',
442
+ })
443
+ .command(({ tr }) => {
444
+ const preparedValue = text.value[text.value.length - 1] === ' ' ? text.value : `${text.value} `;
445
+ tr.insertText(preparedValue);
446
+ return true;
447
+ })
448
+ .run();
449
+ }
450
+
451
+ if (link.value && existedText === text.value && isEmptySelection) {
452
+ editor?.chain()
453
+ .extendMarkRange('link')
454
+ .updateAttributes('link', {
455
+ href: link.value,
456
+ })
457
+ .run();
458
+ }
459
+
460
+ if (link.value && !isEmptySelection) {
461
+ editor?.chain()
462
+ .focus()
463
+ .setMark('link', {
464
+ href: link.value,
465
+ target: '__blank',
466
+ })
467
+ .run();
468
+ }
469
+
470
+ text.value = '';
471
+ link.value = '';
472
+
473
+ isOpenLinkModal.value = false;
474
+ };
475
+
476
+ const discardLink = () => {
477
+ isOpenLinkModal.value = false;
478
+ };
479
+
480
+ const setActiveFormats = () => {
481
+ const toolbarList = props.toolbar.flat() as string[];
482
+ toolbarList.forEach((item) => {
483
+ isActive.value[item] = editor?.isActive(item) || false;
484
+ });
485
+ };
486
+
487
+ // Styles
488
+ const rootStyles = computed(() => {
489
+ return [
490
+ 'or-rich-text-editor',
491
+ ...props.fullHeight ? ['h-full'] : [],
492
+ ];
493
+ });
494
+
495
+ const containerStyles = computed(() => {
496
+ return [
497
+ ...EditorContainer,
498
+ ...props.fullHeight ? ['h-full'] : [],
499
+ ];
500
+ });
501
+
502
+ const toolbarContainerStyles = computed(() => {
503
+ return [
504
+ ...ToolbarContainer,
505
+ ];
506
+ });
507
+
508
+ const toolbarStyles = computed(() => {
509
+ return [
510
+ ...Toolbar,
511
+ ...isFocused.value ? ToolbarButtonFocused : ToolbarButton,
512
+ ];
513
+ });
514
+
515
+ const editorInputStyles = computed(() => {
516
+ return [
517
+ 'tiptap-editor',
518
+ ...props.fullHeight ? ['h-full'] : [],
519
+ ...EditorInput,
520
+ ];
521
+ });
522
+
523
+ //Effects
524
+ watch(proxyModelValue, (value) => {
525
+ if (value !== editor?.getHTML() && !props.markdownFormat) {
526
+ editor?.commands.setContent(value as string);
527
+ }
528
+ if (props.markdownFormat && value !== markdownOutput.value) {
529
+ const deserialized = deserialize(editor?.schema, value);
530
+ editor?.commands.setContent(deserialized);
531
+ }
532
+ });
533
+
534
+ return {
535
+ editor,
536
+ editorRef,
537
+ containerRef,
538
+ toolbarButtonRef,
539
+ menuRef,
540
+ iconsEnum,
541
+ handleToolbarClick,
542
+ handleEditorClick,
543
+ isActive,
544
+ iconTooltipsEnum,
545
+ containerStyles,
546
+ toolbarContainerStyles,
547
+ toolbarStyles,
548
+ rootStyles,
549
+ root,
550
+ editorInputStyles,
551
+ getIndexOfHeading,
552
+ headingLevels,
553
+ headingIcon,
554
+ attachLink,
555
+ discardLink,
556
+ isOpenLinkModal,
557
+ text,
558
+ link,
559
+ isFocused,
560
+ };
561
+ },
562
+ });
563
+ </script>
564
+
565
+ <style lang="scss">
566
+ .tiptap-editor {
567
+ ol { //see if editor can not inherit it
568
+ margin: 0 24px;
569
+ list-style: decimal;
570
+ }
571
+
572
+ ul {
573
+ margin: 0 24px;
574
+ list-style: initial;
575
+ }
576
+
577
+ pre { //TODO: test styles for code block, need to discuss with team
578
+ background-color: rgba($color: #bad1ec, $alpha: .3);
579
+ padding: 4px 8px;
580
+ margin: 4px 0;
581
+ width: 100%;
582
+ border-radius: 4px;
583
+ }
584
+
585
+ blockquote {
586
+ margin: 8px 24px;
587
+ padding: 0 24px;
588
+ border-left: 4px solid #bad1ec;
589
+ }
590
+
591
+ .is-editor-empty::before {
592
+ content: attr(data-placeholder);
593
+ height: 0;
594
+ pointer-events: none;
595
+ float: left;
596
+ }
597
+
598
+ .cm-editor {
599
+ border: none;
600
+ border-radius: 4px;
601
+
602
+ .cm-scroller {
603
+ border-radius: 4px;
604
+ }
605
+
606
+ &.cm-focused {
607
+ outline: none;
608
+ }
609
+
610
+ .cm-gutters {
611
+ background-color: rgba(0, 95, 177, 0.08);
612
+ border: none;
613
+
614
+ .cm-gutterElement {
615
+ padding: 0 10px;
616
+
617
+ &.cm-activeLineGutter {
618
+ background-color: rgba(0, 95, 177, 0.07)
619
+ }
620
+ }
621
+ }
622
+ }
623
+ }
624
+ </style>
@@ -0,0 +1 @@
1
+ export { default as OrRichTextEditorV3 } from './OrRichTextEditor.vue';
@@ -0,0 +1,64 @@
1
+ export const EditorContainer: string[] = [
2
+ // Colors
3
+ 'border-outline',
4
+ 'dark:border-outline-dark',
5
+ 'focus-within:theme-border-1-primary',
6
+ 'dark:focus-within:theme-border-1-primary-dark',
7
+ 'focus-within:bg-primary-opacity-0-08',
8
+ 'dark:focus-within:bg-primary-opacity-0-08-dark',
9
+ 'focus-within:theme-outline-primary',
10
+ 'dark:focus-within:theme-outline-primary-dark',
11
+
12
+ // Sizing
13
+ 'border-1',
14
+ 'rounded-md',
15
+ 'w-full',
16
+ ];
17
+
18
+ export const ToolbarContainer: string[] = [
19
+ // Layout
20
+ 'flex',
21
+ //Spacing
22
+ 'py-sm',
23
+ //Sizing
24
+ 'border-b-1',
25
+ //Colors
26
+ 'border-b-outline',
27
+ 'dark:border-b-outline-dark',
28
+ ];
29
+
30
+ export const Toolbar: string[] = [
31
+ // Layout
32
+ 'flex',
33
+ // Spacing
34
+ 'px-sm',
35
+ 'gap-md',
36
+ // Sizing
37
+ 'border-r-1',
38
+ //Colors
39
+ 'border-r-disabled',
40
+ 'dark:border-r-outline-dark',
41
+ // Last child
42
+ 'last-of-type:border-none',
43
+ ];
44
+
45
+ export const ToolbarButton: string[] = [
46
+ // Typography
47
+ 'text-on-disabled',
48
+ 'dark:text-on-disabled-dark',
49
+ ];
50
+
51
+ export const ToolbarButtonFocused: string[] = [
52
+ // Typography
53
+ 'text-outline',
54
+ 'dark:text-outline-dark',
55
+ ];
56
+
57
+ export const EditorInput: string[] = [
58
+ // Typography
59
+ 'typography-body-2-regular',
60
+ 'text-on-background',
61
+ 'dark:text-on-background-dark',
62
+ // Sizing
63
+ 'min-h-[88px]',
64
+ ];