@ditojs/admin 2.33.1 → 2.34.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ditojs/admin",
3
- "version": "2.33.1",
3
+ "version": "2.34.0",
4
4
  "type": "module",
5
5
  "description": "Dito.js Admin is a schema based admin interface for Dito.js Server, featuring auto-generated views and forms and built with Vue.js",
6
6
  "repository": "https://github.com/ditojs/dito/tree/master/packages/admin",
@@ -39,31 +39,33 @@
39
39
  "not ie_mob > 0"
40
40
  ],
41
41
  "dependencies": {
42
- "@ditojs/ui": "^2.33.0",
43
- "@ditojs/utils": "^2.33.0",
42
+ "@ditojs/ui": "^2.34.0",
43
+ "@ditojs/utils": "^2.34.0",
44
44
  "@kyvg/vue3-notification": "^3.3.0",
45
45
  "@lk77/vue3-color": "^3.0.6",
46
- "@tiptap/core": "^2.7.1",
47
- "@tiptap/extension-blockquote": "^2.7.1",
48
- "@tiptap/extension-bold": "^2.7.1",
49
- "@tiptap/extension-bullet-list": "^2.7.1",
50
- "@tiptap/extension-code": "^2.7.1",
51
- "@tiptap/extension-code-block": "^2.7.1",
52
- "@tiptap/extension-document": "^2.7.1",
53
- "@tiptap/extension-hard-break": "^2.7.1",
54
- "@tiptap/extension-heading": "^2.7.1",
55
- "@tiptap/extension-history": "^2.7.1",
56
- "@tiptap/extension-horizontal-rule": "^2.7.1",
57
- "@tiptap/extension-italic": "^2.7.1",
58
- "@tiptap/extension-link": "^2.7.1",
59
- "@tiptap/extension-list-item": "^2.7.1",
60
- "@tiptap/extension-ordered-list": "^2.7.1",
61
- "@tiptap/extension-paragraph": "^2.7.1",
62
- "@tiptap/extension-strike": "^2.7.1",
63
- "@tiptap/extension-text": "^2.7.1",
64
- "@tiptap/extension-underline": "^2.7.1",
65
- "@tiptap/pm": "^2.7.1",
66
- "@tiptap/vue-3": "^2.7.1",
46
+ "@tiptap/core": "^2.7.2",
47
+ "@tiptap/extension-blockquote": "^2.7.2",
48
+ "@tiptap/extension-bold": "^2.7.2",
49
+ "@tiptap/extension-bullet-list": "^2.7.2",
50
+ "@tiptap/extension-code": "^2.7.2",
51
+ "@tiptap/extension-code-block": "^2.7.2",
52
+ "@tiptap/extension-document": "^2.7.2",
53
+ "@tiptap/extension-hard-break": "^2.7.2",
54
+ "@tiptap/extension-heading": "^2.7.2",
55
+ "@tiptap/extension-history": "^2.7.2",
56
+ "@tiptap/extension-horizontal-rule": "^2.7.2",
57
+ "@tiptap/extension-italic": "^2.7.2",
58
+ "@tiptap/extension-link": "^2.7.2",
59
+ "@tiptap/extension-list-item": "^2.7.2",
60
+ "@tiptap/extension-ordered-list": "^2.7.2",
61
+ "@tiptap/extension-paragraph": "^2.7.2",
62
+ "@tiptap/extension-strike": "^2.7.2",
63
+ "@tiptap/extension-subscript": "^2.7.2",
64
+ "@tiptap/extension-superscript": "^2.7.2",
65
+ "@tiptap/extension-text": "^2.7.2",
66
+ "@tiptap/extension-underline": "^2.7.2",
67
+ "@tiptap/pm": "^2.7.2",
68
+ "@tiptap/vue-3": "^2.7.2",
67
69
  "@vueuse/integrations": "^11.1.0",
68
70
  "codeflask": "^1.4.1",
69
71
  "filesize": "^10.1.6",
@@ -74,20 +76,20 @@
74
76
  "tinycolor2": "^1.6.0",
75
77
  "tippy.js": "^6.3.7",
76
78
  "type-fest": "^4.26.1",
77
- "vue": "^3.5.6",
79
+ "vue": "^3.5.8",
78
80
  "vue-multiselect": "^3.1.0",
79
81
  "vue-router": "^4.4.5",
80
82
  "vue-upload-component": "^3.1.17"
81
83
  },
82
84
  "devDependencies": {
83
- "@ditojs/build": "^2.33.0",
85
+ "@ditojs/build": "^2.34.0",
84
86
  "@vitejs/plugin-vue": "^5.1.4",
85
- "@vue/compiler-sfc": "^3.5.6",
87
+ "@vue/compiler-sfc": "^3.5.8",
86
88
  "pug": "^3.0.3",
87
- "sass": "^1.78.0",
89
+ "sass": "^1.79.3",
88
90
  "typescript": "^5.6.2",
89
- "vite": "^5.4.6"
91
+ "vite": "^5.4.8"
90
92
  },
91
93
  "types": "types",
92
- "gitHead": "1a73730c672ab5d1157cf8e91767a6f8640e1487"
94
+ "gitHead": "0258ece4af0f7dfbb9c11102bdf9defec72b1f15"
93
95
  }
@@ -34,11 +34,18 @@ Trigger.dito-color(
34
34
  <script>
35
35
  import tinycolor from 'tinycolor2'
36
36
  import { Sketch as SketchPicker } from '@lk77/vue3-color'
37
- import { isObject } from '@ditojs/utils'
37
+ import { isObject, isString } from '@ditojs/utils'
38
38
  import { Trigger } from '@ditojs/ui/src'
39
39
  import DitoTypeComponent from '../DitoTypeComponent.js'
40
40
  import { getSchemaAccessor } from '../utils/accessor.js'
41
41
 
42
+ // Monkey-patch the `SketchPicker's` `hex` computed property to return lowercase
43
+ // hex values instead of uppercase ones.
44
+ const { hex } = SketchPicker.computed
45
+ SketchPicker.computed.hex = function () {
46
+ return hex.call(this).toLowerCase()
47
+ }
48
+
42
49
  // @vue/component
43
50
  export default DitoTypeComponent.register('color', {
44
51
  components: { Trigger, SketchPicker },
@@ -66,7 +73,6 @@ export default DitoTypeComponent.register('color', {
66
73
 
67
74
  set(value) {
68
75
  this.value = convertColor(value, this.colorFormat)
69
- this.onChange()
70
76
  }
71
77
  },
72
78
 
@@ -77,7 +83,7 @@ export default DitoTypeComponent.register('color', {
77
83
  ? color
78
84
  .toString(color.getAlpha() < 1 ? 'hex8' : 'hex6')
79
85
  .slice(1)
80
- .toUpperCase()
86
+ .toLowerCase()
81
87
  : null
82
88
  },
83
89
 
@@ -140,54 +146,59 @@ export default DitoTypeComponent.register('color', {
140
146
  },
141
147
 
142
148
  watch: {
149
+ value: 'onChange',
150
+
143
151
  canUpdateValue(canUpdateValue) {
144
152
  if (canUpdateValue && this.convertedValue !== null) {
145
153
  this.value = this.convertedValue
146
154
  this.convertedValue = null
147
155
  }
148
156
  }
149
- },
150
-
151
- methods: {}
157
+ }
152
158
  })
153
159
 
154
160
  function convertColor(color, format) {
155
161
  return isObject(color) // a vue3-color color object
156
- ? color[
157
- {
158
- hex: color?.a < 1 ? 'hex8' : 'hex',
159
- rgb: 'rgba'
160
- }[format] ||
161
- format
162
- ]
163
- : toColorFormat(tinycolor(color), format)
162
+ ? toVue3ColorFormat(color, format)
163
+ : toTinyColorFormat(tinycolor(color), format)
164
+ }
165
+
166
+ function toVue3ColorFormat(color, format) {
167
+ const value =
168
+ color[
169
+ {
170
+ hex: color?.a < 1 ? 'hex8' : 'hex',
171
+ rgb: 'rgba'
172
+ }[format] ||
173
+ format
174
+ ]
175
+ return isString(value) && value[0] === '#' ? value.toLowerCase() : value
164
176
  }
165
177
 
166
178
  // This should really be in tinycolor, but it only has the string equivalent
167
179
  // of it.
168
- function toColorFormat(color, format) {
180
+ function toTinyColorFormat(color, format) {
169
181
  switch (format) {
170
182
  case 'rgb':
171
183
  return color.toRgb()
172
184
  case 'prgb':
173
185
  return color.toPercentageRgb()
174
- case 'hex':
175
- case 'hex6':
176
- return color.toHex()
177
- case 'hex3':
178
- return color.toHex(true)
179
- case 'hex4':
180
- return color.toHex8(true)
181
- case 'hex8':
182
- return color.toHex8()
183
186
  case 'name':
184
187
  return color.toName()
185
188
  case 'hsl':
186
189
  return color.toHsl()
187
190
  case 'hsv':
188
191
  return color.toHsv()
192
+ case 'hex3':
193
+ return `#${color.toHex(true)}`
194
+ case 'hex4':
195
+ return `#${color.toHex8(true)}`
196
+ case 'hex8':
197
+ return `#${color.toHex8()}`
198
+ case 'hex':
199
+ case 'hex6':
189
200
  default:
190
- return color.toHex()
201
+ return `#${color.toHex()}`
191
202
  }
192
203
  }
193
204
  </script>
@@ -1,6 +1,6 @@
1
1
  <template lang="pug">
2
2
  DitoLabel.dito-label-component(
3
- :label="value ?? label"
3
+ :label="value"
4
4
  :dataPath="dataPath"
5
5
  )
6
6
  </template>
@@ -39,6 +39,8 @@ import { Code } from '@tiptap/extension-code'
39
39
  import { Italic } from '@tiptap/extension-italic'
40
40
  import { Link } from '@tiptap/extension-link'
41
41
  import { Strike } from '@tiptap/extension-strike'
42
+ import { Subscript } from '@tiptap/extension-subscript'
43
+ import { Superscript } from '@tiptap/extension-superscript'
42
44
  import { Underline } from '@tiptap/extension-underline'
43
45
  // Nodes:
44
46
  import { Blockquote } from '@tiptap/extension-blockquote'
@@ -87,6 +89,10 @@ export default DitoTypeComponent.register('markup', {
87
89
  return this.schema.lines || 10
88
90
  },
89
91
 
92
+ hardBreak() {
93
+ return !!this.schema.hardBreak
94
+ },
95
+
90
96
  styles() {
91
97
  return {
92
98
  height: this.height || `calc(${this.lines}em * var(--line-height))`
@@ -101,6 +107,8 @@ export default DitoTypeComponent.register('markup', {
101
107
  strike: true,
102
108
  small: true,
103
109
  code: true,
110
+ subscript: true,
111
+ superscript: true,
104
112
  link: {
105
113
  onClick: editor => this.onClickLink(editor)
106
114
  }
@@ -196,48 +204,46 @@ export default DitoTypeComponent.register('markup', {
196
204
  },
197
205
 
198
206
  created() {
199
- let changed = false
200
207
  let ignoreWatch = false
201
208
 
202
- const onChange = () => {
203
- if (!this.focused && changed) {
204
- changed = false
205
- this.onChange()
206
- }
207
- }
208
-
209
209
  const onFocus = () => this.onFocus()
210
210
 
211
- const onBlur = ({ editor }) => {
212
- // This change handling code on blur is only needed to make e2e testing
213
- // through puppeteer work, since we couldn't figure out how to trigger
214
- // tiptap's update events programmatically from the outside.
215
- const value = editor.getHTML()
216
- if (value !== this.value) {
217
- this.value = value
218
- changed = true
219
- }
211
+ const onBlur = () => {
220
212
  this.onBlur()
221
- onChange()
213
+ updateValue()
222
214
  }
223
215
 
224
- const setValueDebounced = debounce(editor => {
216
+ const onUpdate = () => {
217
+ setValueDebounced()
218
+ this.onInput()
219
+ }
220
+
221
+ const setValueDebounced = debounce(() => {
225
222
  ignoreWatch = true
226
- this.value = editor.getHTML()
227
- changed = true
228
- onChange()
223
+ updateValue()
229
224
  }, 100)
230
225
 
231
- const onUpdate = ({ editor }) => {
232
- setValueDebounced(editor)
233
- this.onInput()
226
+ const updateValue = () => {
227
+ const content = this.editor.getHTML()
228
+ const value = this.hardBreak
229
+ ? content.replace(/^<p>(.*?)<\/p>$/s, '$1')
230
+ : content
231
+ if (value !== this.value) {
232
+ this.value = value
233
+ if (!this.focused) {
234
+ this.onChange()
235
+ }
236
+ }
234
237
  }
235
238
 
236
239
  this.$watch('value', value => {
237
240
  if (ignoreWatch) {
238
241
  ignoreWatch = false
239
242
  } else {
240
- this.editor.commands.setContent(value, false, this.parseOptions)
243
+ const content = this.hardBreak
244
+ ? `<p>${value}</p>`
245
+ : value
246
+ this.editor.commands.setContent(content, false, this.parseOptions)
241
247
  }
242
248
  })
243
249
 
@@ -346,12 +352,13 @@ export default DitoTypeComponent.register('markup', {
346
352
  marks.strike && Strike,
347
353
  marks.small && Small,
348
354
  marks.code && Code,
355
+ marks.subscript && Superscript,
356
+ marks.superscript && Subscript,
349
357
  marks.link && LinkWithTitle,
350
358
 
351
359
  // Nodes: `schema.nodes`
352
360
  nodes.blockquote && Blockquote,
353
361
  nodes.codeBlock && CodeBlock,
354
- HardBreak, // TODO: Should this always on?
355
362
  nodes.heading && Heading.configure({ levels: nodes.heading }),
356
363
  nodes.horizontalRule && HorizontalRule,
357
364
  (nodes.orderedList || nodes.bulletList) && ListItem,
@@ -362,7 +369,15 @@ export default DitoTypeComponent.register('markup', {
362
369
  // nodes.todoList && TodoList,
363
370
 
364
371
  // Tools: `schema.tools`
365
- tools.history && History
372
+ tools.history && History,
373
+
374
+ HardBreak.extend({
375
+ addKeyboardShortcuts() {
376
+ return this.hardBreak
377
+ ? { Enter: () => this.editor.commands.setHardBreak() }
378
+ : {}
379
+ }
380
+ })
366
381
  ].filter(extension => !!extension)
367
382
  },
368
383