@koumoul/vjsf 3.0.0-alpha.4 → 3.0.0-alpha.6

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 (107) hide show
  1. package/package.json +27 -6
  2. package/src/compile/index.js +18 -4
  3. package/src/compile/options.js +19 -0
  4. package/src/compile/v-jsf-compiled.vue.ejs +28 -10
  5. package/src/components/fragments/help-message.vue +2 -1
  6. package/src/components/fragments/node-slot.vue +3 -3
  7. package/src/components/fragments/section-header.vue +2 -1
  8. package/src/components/fragments/text-field-menu.vue +3 -3
  9. package/src/components/node.vue +12 -8
  10. package/src/components/nodes/autocomplete.vue +3 -4
  11. package/src/components/nodes/checkbox.vue +3 -3
  12. package/src/components/nodes/color-picker.vue +3 -3
  13. package/src/components/nodes/combobox.vue +3 -4
  14. package/src/components/nodes/date-picker.vue +3 -4
  15. package/src/components/nodes/date-time-picker.vue +2 -2
  16. package/src/components/nodes/expansion-panels.vue +3 -3
  17. package/src/components/nodes/file-input.vue +43 -0
  18. package/src/components/nodes/list.vue +4 -4
  19. package/src/components/nodes/number-combobox.vue +3 -4
  20. package/src/components/nodes/number-field.vue +3 -4
  21. package/src/components/nodes/one-of-select.vue +3 -3
  22. package/src/components/nodes/section.vue +3 -3
  23. package/src/components/nodes/select.vue +3 -4
  24. package/src/components/nodes/slider.vue +3 -3
  25. package/src/components/nodes/stepper.vue +3 -5
  26. package/src/components/nodes/switch.vue +3 -3
  27. package/src/components/nodes/tabs.vue +3 -3
  28. package/src/components/nodes/text-field.vue +3 -4
  29. package/src/components/nodes/textarea.vue +3 -4
  30. package/src/components/nodes/vertical-tabs.vue +3 -3
  31. package/src/components/options.js +9 -6
  32. package/src/components/tree.vue +2 -2
  33. package/src/components/vjsf.vue +9 -13
  34. package/src/composables/use-dnd.js +1 -1
  35. package/src/composables/use-vjsf.js +9 -8
  36. package/src/index.js +1 -0
  37. package/src/{components/types.ts → types.ts} +18 -2
  38. package/src/utils/global-register.js +10 -0
  39. package/src/utils/index.js +5 -0
  40. package/src/utils/props.js +4 -4
  41. package/src/utils/slots.js +2 -3
  42. package/types/compile/index.d.ts +3 -2
  43. package/types/compile/index.d.ts.map +1 -1
  44. package/types/compile/options.d.ts +4 -0
  45. package/types/compile/options.d.ts.map +1 -0
  46. package/types/components/fragments/help-message.vue.d.ts +2 -2
  47. package/types/components/fragments/node-slot.vue.d.ts +8 -8
  48. package/types/components/fragments/node-slot.vue.d.ts.map +1 -1
  49. package/types/components/fragments/section-header.vue.d.ts +2 -2
  50. package/types/components/fragments/select-item.vue.d.ts +2 -2
  51. package/types/components/fragments/text-field-menu.vue.d.ts +4 -4
  52. package/types/components/fragments/text-field-menu.vue.d.ts.map +1 -1
  53. package/types/components/global-register.d.ts +8 -0
  54. package/types/components/global-register.d.ts.map +1 -0
  55. package/types/components/node.vue.d.ts +4 -4
  56. package/types/components/nodes/autocomplete.vue.d.ts +8 -8
  57. package/types/components/nodes/autocomplete.vue.d.ts.map +1 -1
  58. package/types/components/nodes/checkbox.vue.d.ts +4 -4
  59. package/types/components/nodes/color-picker.vue.d.ts +4 -4
  60. package/types/components/nodes/combobox.vue.d.ts +8 -8
  61. package/types/components/nodes/combobox.vue.d.ts.map +1 -1
  62. package/types/components/nodes/date-picker.vue.d.ts +4 -4
  63. package/types/components/nodes/date-time-picker.vue.d.ts +4 -4
  64. package/types/components/nodes/expansion-panels.vue.d.ts +4 -4
  65. package/types/components/nodes/file-input.vue.d.ts +27 -0
  66. package/types/components/nodes/file-input.vue.d.ts.map +1 -0
  67. package/types/components/nodes/list.vue.d.ts +4 -4
  68. package/types/components/nodes/number-combobox.vue.d.ts +8 -8
  69. package/types/components/nodes/number-combobox.vue.d.ts.map +1 -1
  70. package/types/components/nodes/number-field.vue.d.ts +8 -8
  71. package/types/components/nodes/number-field.vue.d.ts.map +1 -1
  72. package/types/components/nodes/one-of-select.vue.d.ts +4 -4
  73. package/types/components/nodes/section.vue.d.ts +4 -4
  74. package/types/components/nodes/select.vue.d.ts +8 -8
  75. package/types/components/nodes/select.vue.d.ts.map +1 -1
  76. package/types/components/nodes/slider.vue.d.ts +4 -4
  77. package/types/components/nodes/stepper.vue.d.ts +4 -4
  78. package/types/components/nodes/switch.vue.d.ts +4 -4
  79. package/types/components/nodes/tabs.vue.d.ts +4 -4
  80. package/types/components/nodes/text-field.vue.d.ts +8 -8
  81. package/types/components/nodes/text-field.vue.d.ts.map +1 -1
  82. package/types/components/nodes/textarea.vue.d.ts +8 -8
  83. package/types/components/nodes/textarea.vue.d.ts.map +1 -1
  84. package/types/components/nodes/vertical-tabs.vue.d.ts +4 -4
  85. package/types/components/options.d.ts +3 -3
  86. package/types/components/options.d.ts.map +1 -1
  87. package/types/components/tree.vue.d.ts +2 -2
  88. package/types/components/types.d.ts +14 -2
  89. package/types/components/types.d.ts.map +1 -1
  90. package/types/components/vjsf.vue.d.ts +3 -3
  91. package/types/composables/use-dnd.d.ts +5 -1
  92. package/types/composables/use-dnd.d.ts.map +1 -1
  93. package/types/composables/use-vjsf.d.ts +4 -5
  94. package/types/composables/use-vjsf.d.ts.map +1 -1
  95. package/types/index.d.ts +1 -0
  96. package/types/index.d.ts.map +1 -1
  97. package/types/types.d.ts +95 -0
  98. package/types/types.d.ts.map +1 -0
  99. package/types/utils/global-register.d.ts +8 -0
  100. package/types/utils/global-register.d.ts.map +1 -0
  101. package/types/utils/index.d.ts +6 -0
  102. package/types/utils/index.d.ts.map +1 -0
  103. package/types/utils/props.d.ts +3 -3
  104. package/types/utils/props.d.ts.map +1 -1
  105. package/types/utils/slots.d.ts +3 -3
  106. package/types/utils/slots.d.ts.map +1 -1
  107. package/src/components/nodes/markdown.vue +0 -341
@@ -1,341 +0,0 @@
1
- <script>
2
- import { defineComponent, h, computed, onMounted, ref, onUnmounted, watch } from 'vue'
3
- import { useTheme } from 'vuetify'
4
- import { VInput, VLabel } from 'vuetify/components'
5
- import { marked } from 'marked'
6
- import { getInputProps } from '../../utils/props.js'
7
- import { getCompSlots } from '../../utils/slots.js'
8
- import 'easymde/dist/easymde.min.css'
9
-
10
- export default defineComponent({
11
- props: {
12
- modelValue: {
13
- /** @type import('vue').PropType<import('../types.js').VjsfTextareaNode> */
14
- type: Object,
15
- required: true
16
- },
17
- statefulLayout: {
18
- /** @type import('vue').PropType<import('@json-layout/core').StatefulLayout> */
19
- type: Object,
20
- required: true
21
- }
22
- },
23
- setup (props, { expose }) {
24
- /** @type {import('vue').Ref<null | HTMLElement>} */
25
- const element = ref(null)
26
-
27
- const renderedValue = computed(() => {
28
- return props.modelValue.data && marked.parse(props.modelValue.data)
29
- })
30
-
31
- const fieldProps = computed(() => getInputProps(props.modelValue, props.statefulLayout))
32
- const fieldSlots = computed(() => {
33
- const fieldSlots = getCompSlots(props.modelValue, props.statefulLayout)
34
- fieldSlots.default = () => {
35
- const children = [
36
- h(VLabel, { text: fieldProps.value.label }),
37
- h('textarea', { ref: element })
38
- ]
39
- if (props.modelValue.options.summary) {
40
- children.push(h('div', { innerHTML: renderedValue.value }))
41
- }
42
- return h('div', { class: 'vjsf-node-markdown-content' }, children)
43
- }
44
- return fieldSlots
45
- })
46
-
47
- /** @type {ReturnType<typeof setTimeout> | null} */
48
- let blurTimeout = null
49
-
50
- /** @type {EasyMDE | null} */
51
- let easymde = null
52
-
53
- const initEasyMDE = async () => {
54
- if (easymde) {
55
- easymde.toTextArea()
56
- easymde = null
57
- }
58
- if (props.modelValue.options.readOnly) return
59
- if (!element.value) throw new Error('component was not mounted for markdown editor')
60
-
61
- const EasyMDE = (await import('easymde')).default
62
-
63
- const messages = props.modelValue.messages
64
-
65
- const config = {
66
- element: element.value,
67
- initialValue: props.modelValue.data ?? '',
68
- renderingConfig: {},
69
- status: false,
70
- autoDownloadFontAwesome: false,
71
- spellChecker: false,
72
- minHeight: '300px',
73
- insertTexts: {
74
- link: [messages.mdeLink1, messages.mdeLink2],
75
- image: [messages.mdeImg1, messages.mdeImg2],
76
- table: [messages.mdeTable1, messages.mdeTable2],
77
- horizontalRule: ['', '\n\n-----\n\n']
78
- },
79
- // cf https://github.com/Ionaru/easy-markdown-editor/blob/master/src/js/easymde.js#L1380
80
- toolbar: [{
81
- name: 'bold',
82
- action: EasyMDE.toggleBold,
83
- className: 'mdi mdi-format-bold',
84
- title: messages.bold
85
- }, {
86
- name: 'italic',
87
- action: EasyMDE.toggleItalic,
88
- className: 'mdi mdi-format-italic',
89
- title: messages.italic
90
- }, {
91
- name: 'heading',
92
- action: EasyMDE.toggleHeadingSmaller,
93
- className: 'mdi mdi-format-title',
94
- title: messages.heading
95
- }, /* {
96
- name: 'heading-1',
97
- action: EasyMDE.toggleHeading1,
98
- className: 'mdi mdi-format-title',
99
- title: 'Titre 1'
100
- }, {
101
- name: 'heading-2',
102
- action: EasyMDE.toggleHeading2,
103
- className: 'mdi mdi-format-title',
104
- title: 'Titre 2'
105
- }, {
106
- name: 'heading-3',
107
- action: EasyMDE.toggleHeading3,
108
- className: 'mdi mdi-format-title',
109
- title: 'Titre 3'
110
- }, */
111
- '|',
112
- {
113
- name: 'quote',
114
- action: EasyMDE.toggleBlockquote,
115
- className: 'mdi mdi-format-quote-open',
116
- title: messages.quote
117
- },
118
- {
119
- name: 'unordered-list',
120
- action: EasyMDE.toggleUnorderedList,
121
- className: 'mdi mdi-format-list-bulleted',
122
- title: messages.unorderedList
123
- },
124
- {
125
- name: 'ordered-list',
126
- action: EasyMDE.toggleOrderedList,
127
- className: 'mdi mdi-format-list-numbered',
128
- title: messages.orderedList
129
- },
130
- '|',
131
- {
132
- name: 'link',
133
- action: EasyMDE.drawLink,
134
- className: 'mdi mdi-link',
135
- title: messages.createLink
136
- },
137
- {
138
- name: 'image',
139
- action: EasyMDE.drawImage,
140
- className: 'mdi mdi-image',
141
- title: messages.insertImage
142
- },
143
- {
144
- name: 'table',
145
- action: EasyMDE.drawTable,
146
- className: 'mdi mdi-table',
147
- title: messages.createTable
148
- },
149
- '|',
150
- {
151
- name: 'preview',
152
- action: EasyMDE.togglePreview,
153
- className: 'mdi mdi-eye text-accent',
154
- title: messages.preview,
155
- noDisable: true
156
- },
157
- '|',
158
- {
159
- name: 'undo',
160
- action: EasyMDE.undo,
161
- className: 'mdi mdi-undo',
162
- title: messages.undo,
163
- noDisable: true
164
- },
165
- {
166
- name: 'redo',
167
- action: EasyMDE.redo,
168
- className: 'mdi mdi-redo',
169
- title: messages.redo,
170
- noDisable: true
171
- },
172
- '|',
173
- {
174
- name: 'guide',
175
- action: 'https://simplemde.com/markdown-guide',
176
- className: 'mdi mdi-help-circle text-success',
177
- title: messages.mdeGuide,
178
- noDisable: true
179
- }],
180
- ...props.modelValue.options.easyMDEOptions
181
- }
182
- // @ts-ignore
183
- easymde = new EasyMDE(config)
184
-
185
- let changed = false
186
- easymde.codemirror.on('change', () => {
187
- changed = true
188
- if (easymde) props.statefulLayout.input(props.modelValue, easymde.value())
189
- })
190
- easymde.codemirror.on('blur', () => {
191
- console.log('onblur')
192
- // timeout to prevent triggering save when clicking on a menu button
193
- blurTimeout = setTimeout(() => {
194
- if (changed) props.statefulLayout.blur(props.modelValue)
195
- changed = false
196
- }, 500)
197
- })
198
- easymde.codemirror.on('focus', () => {
199
- if (blurTimeout) clearTimeout(blurTimeout)
200
- })
201
-
202
- if (props.modelValue.autofocus) {
203
- easymde.codemirror.focus()
204
- }
205
- }
206
-
207
- onMounted(initEasyMDE)
208
-
209
- onUnmounted(() => {
210
- if (easymde) easymde.toTextArea()
211
- })
212
-
213
- // update data from outside
214
- watch(() => props.modelValue, () => {
215
- if (easymde && (easymde.value() !== props.modelValue.data ?? '')) {
216
- easymde.value(props.modelValue.data ?? '')
217
- }
218
- })
219
-
220
- // update easymde config from outside
221
- watch(() => [props.modelValue.options.readOnly, props.modelValue.messages, props.modelValue.options.easyMDEOptions], (newValues, oldValues) => {
222
- if (newValues[0] !== oldValues[0] || newValues[1] !== oldValues[1] || newValues[2] !== oldValues[2]) {
223
- initEasyMDE()
224
- }
225
- })
226
-
227
- props.statefulLayout.events.on('autofocus', () => {
228
- console.log('focus code mirror ?')
229
- if (props.modelValue.autofocus && easymde) {
230
- easymde.codemirror.focus()
231
- }
232
- })
233
-
234
- const theme = useTheme()
235
- const darkStyle = computed(() => getDarkStyle(theme))
236
-
237
- return () => [
238
- h('style', { innerHTML: darkStyle.value }),
239
- h(VInput, fieldProps.value, fieldSlots.value)
240
- ]
241
- }
242
- })
243
-
244
- const getDarkStyle = (/** @type {import('vuetify').ThemeInstance} */theme) => {
245
- // Inspired by https://github.com/Ionaru/easy-markdown-editor/issues/131#issuecomment-1738202589
246
- return `
247
- .vjsf-node-markdown.vjsf-dark .EasyMDEContainer .CodeMirror {
248
- color: white;
249
- border-color: ${theme.current.value.variables['border-color']};
250
- background-color: ${theme.current.value.colors.surface};
251
- }
252
- .vjsf-node-markdown.vjsf-dark .EasyMDEContainer .cm-s-easymde .CodeMirror-cursor {
253
- border-color: white;
254
- }
255
- .vjsf-node-markdown.vjsf-dark .CodeMirror-cursor {
256
- border-left:1px solid white;
257
- border-right:none;width:0;
258
- }
259
- .vjsf-node-markdown.vjsf-dark .EasyMDEContainer .editor-toolbar > * {
260
- border-color: ${theme.current.value.colors.surface};
261
- }
262
- .vjsf-node-markdown.vjsf-dark .editor-toolbar {
263
- border-top: 1px solid ${theme.current.value.variables['border-color']};
264
- border-left: 1px solid ${theme.current.value.variables['border-color']};
265
- border-right: 1px solid ${theme.current.value.variables['border-color']};
266
- }
267
- .vjsf-node-markdown.vjsf-dark .editor-toolbar i.separator {
268
- border-left: 1px solid ${theme.current.value.variables['border-color']};
269
- border-right: 1px solid ${theme.current.value.variables['border-color']};
270
- }
271
- .vjsf-node-markdown.vjsf-dark .EasyMDEContainer .editor-toolbar > .active, .editor-toolbar > button:hover, .editor-preview pre, .cm-s-easymde .cm-comment {
272
- background-color: ${theme.current.value.colors.surface};
273
- }
274
- .vjsf-node-markdown.vjsf-dark .EasyMDEContainer .CodeMirror-fullscreen {
275
- background: ${theme.current.value.colors.surface};
276
- }
277
- .vjsf-node-markdown.vjsf-dark .editor-toolbar.fullscreen {
278
- background: ${theme.current.value.colors.surface};
279
- }
280
- .vjsf-node-markdown.vjsf-dark .editor-preview {
281
- background: ${theme.current.value.colors.surface};
282
- }
283
- .vjsf-node-markdown.vjsf-dark .editor-preview-side {
284
- border-color: ${theme.current.value.variables['border-color']};
285
- }
286
- .vjsf-node-markdown.vjsf-dark .CodeMirror-selected {
287
- background: ${theme.current.value.colors.secondary};
288
- }
289
- .vjsf-node-markdown.vjsf-dark .CodeMirror-focused .CodeMirror-selected {
290
- background: ${theme.current.value.colors.secondary};
291
- }
292
- .vjsf-node-markdown.vjsf-dark .CodeMirror-line::selection,.CodeMirror-line>span::selection,.CodeMirror-line>span>span::selection {
293
- background:${theme.current.value.colors.secondary}
294
- }
295
- .vjsf-node-markdown.vjsf-dark .CodeMirror-line::-moz-selection,.CodeMirror-line>span::-moz-selection,.CodeMirror-line>span>span::-moz-selection {
296
- background:${theme.current.value.colors.secondary}
297
- }
298
- .vjsf-node-markdown.vjsf-dark .EasyMDEContainer .CodeMirror-focused .CodeMirror-selected {
299
- background: ${theme.current.value.colors.secondary}
300
- }
301
- `
302
- }
303
-
304
- </script>
305
-
306
- <style>
307
- .vjsf-node-markdown .vjsf-node-markdown-content {
308
- width: 100%;
309
- }
310
-
311
- /* adjust to density */
312
- .vjsf-node-markdown .v-input--density-compact .editor-toolbar {
313
- padding: 0;
314
- }
315
- .vjsf-node-markdown .v-input--density-comfortable .editor-toolbar {
316
- padding: 4px;
317
- }
318
- .vjsf-node-markdown .v-input--density-compact .CodeMirror-wrap {
319
- padding-top: 2px;
320
- padding-bottom: 2px;
321
- }
322
- .vjsf-node-markdown .v-input--density-comfortable .CodeMirror-wrap {
323
- padding-top: 6px;
324
- padding-bottom: 6px;
325
- }
326
-
327
- /* adjust to readOnly/summary mode */
328
- .vjsf-node-markdown.vjsf-readonly .EasyMDEContainer .CodeMirror {
329
- border-width: 0;
330
- padding: 0;
331
- }
332
- .vjsf-node-markdown.vjsf-summary .vjsf-node-markdown-content {
333
- height: 96px;
334
- overflow: hidden;
335
- mask-image: linear-gradient(180deg, #000 66%, transparent 90%);
336
- }
337
- .vjsf-node-markdown.vjsf-readonly .vjsf-node-markdown-content textarea {
338
- display: none;
339
- }
340
-
341
- </style>