@ditojs/admin 2.8.0 → 2.8.2
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/dito-admin.es.js +1699 -1666
- package/dist/dito-admin.umd.js +5 -5
- package/dist/style.css +1 -1
- package/package.json +2 -2
- package/src/components/DitoClipboard.vue +4 -0
- package/src/components/DitoCreateButton.vue +17 -1
- package/src/components/DitoDraggable.vue +71 -2
- package/src/components/DitoEditButtons.vue +31 -25
- package/src/components/DitoElement.vue +2 -2
- package/src/components/DitoLabel.vue +3 -2
- package/src/components/DitoPane.vue +8 -4
- package/src/components/DitoSchema.vue +19 -16
- package/src/components/DitoSchemaInlined.vue +3 -10
- package/src/components/DitoTreeItem.vue +2 -2
- package/src/mixins/SortableMixin.js +9 -8
- package/src/mixins/TypeMixin.js +9 -30
- package/src/styles/_layout.scss +1 -1
- package/src/styles/style.scss +0 -1
- package/src/types/DitoTypeList.vue +1 -1
- package/src/types/DitoTypeMultiselect.vue +28 -22
- package/src/types/DitoTypeSelect.vue +2 -1
- package/src/types/DitoTypeUpload.vue +1 -1
- package/src/utils/schema.js +12 -9
- package/src/styles/_sortable.scss +0 -13
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ditojs/admin",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.2",
|
|
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",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"vite": "^4.3.5"
|
|
84
84
|
},
|
|
85
85
|
"types": "types",
|
|
86
|
-
"gitHead": "
|
|
86
|
+
"gitHead": "d9a0905b7c93d509a3710b36c749cc6e651401d3",
|
|
87
87
|
"scripts": {
|
|
88
88
|
"build": "vite build",
|
|
89
89
|
"watch": "yarn build --mode 'development' --watch",
|
|
@@ -73,6 +73,10 @@ export default DitoComponent.component('DitoClipboard', {
|
|
|
73
73
|
}
|
|
74
74
|
},
|
|
75
75
|
|
|
76
|
+
watch: {
|
|
77
|
+
'appState.clipboardData': 'checkClipboard'
|
|
78
|
+
},
|
|
79
|
+
|
|
76
80
|
mounted() {
|
|
77
81
|
// Check clipboard content whenever something gets copied or the window gets
|
|
78
82
|
// (re)activated, as those are the moments when the clipboard can change:
|
|
@@ -40,6 +40,15 @@ export default DitoComponent.component('DitoCreateButton', {
|
|
|
40
40
|
|
|
41
41
|
props: {
|
|
42
42
|
schema: { type: Object, required: true },
|
|
43
|
+
// The next four props are there for `DitoContext` and the `context()`
|
|
44
|
+
// getter in `DitoMixin`.
|
|
45
|
+
// TODO: Should they be moved to shared mixin that defines them as required
|
|
46
|
+
// and also provides the `context()` getter, perhaps `ContextMixin`?
|
|
47
|
+
// `schema` could be included as well, and `ContextMixin` could be used in
|
|
48
|
+
// `DitoForm`, `DitoView`, `DitoPanel`, `DitoSchema`, `DitoEditButtons`,
|
|
49
|
+
// etc? But the problem with the root components is that they don't have
|
|
50
|
+
// these props. We could add a `contextAttributes()` getter for easy passing
|
|
51
|
+
// on as `v-bind="contextAttributes"`.
|
|
43
52
|
dataPath: { type: String, required: true },
|
|
44
53
|
data: { type: [Object, Array], default: null },
|
|
45
54
|
meta: { type: Object, required: true },
|
|
@@ -72,7 +81,14 @@ export default DitoComponent.component('DitoCreateButton', {
|
|
|
72
81
|
isFormCreatable(form) {
|
|
73
82
|
// Forms can be excluded from the list by providing `if: false` or
|
|
74
83
|
// `creatable: false`.
|
|
75
|
-
return
|
|
84
|
+
return (
|
|
85
|
+
this.shouldRenderSchema(form) &&
|
|
86
|
+
this.getSchemaValue('creatable', {
|
|
87
|
+
type: Boolean,
|
|
88
|
+
default: true,
|
|
89
|
+
schema: form
|
|
90
|
+
})
|
|
91
|
+
)
|
|
76
92
|
},
|
|
77
93
|
|
|
78
94
|
createItem(form, type = null) {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
UseSortable(
|
|
2
|
+
UseSortable.dito-draggable(
|
|
3
3
|
v-if="draggable"
|
|
4
|
+
:class="{ 'dito-draggable--dragging': isDragging }"
|
|
4
5
|
:tag="tag"
|
|
5
6
|
:modelValue="modelValue"
|
|
6
|
-
:options="options"
|
|
7
|
+
:options="{ ...options, onStart, onEnd }"
|
|
7
8
|
@update:modelValue="$emit('update:modelValue', $event)"
|
|
8
9
|
)
|
|
9
10
|
slot
|
|
@@ -15,6 +16,7 @@ component(
|
|
|
15
16
|
</template>
|
|
16
17
|
|
|
17
18
|
<script>
|
|
19
|
+
import { addEvents } from '@ditojs/ui'
|
|
18
20
|
import DitoComponent from '../DitoComponent'
|
|
19
21
|
import { UseSortable } from '@vueuse/integrations/useSortable/component'
|
|
20
22
|
|
|
@@ -40,6 +42,73 @@ export default DitoComponent.component('DitoDraggable', {
|
|
|
40
42
|
type: Boolean,
|
|
41
43
|
default: true
|
|
42
44
|
}
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
data() {
|
|
48
|
+
return {
|
|
49
|
+
mouseEvents: null,
|
|
50
|
+
isDragging: false
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
methods: {
|
|
55
|
+
onStart(event) {
|
|
56
|
+
this.isDragging = true
|
|
57
|
+
this.options.onStart?.(event)
|
|
58
|
+
this.mouseEvents?.remove()
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
onEnd(event) {
|
|
62
|
+
this.options.onEnd?.(event)
|
|
63
|
+
// Keep `isDragging` true until the next mouse interaction so that
|
|
64
|
+
// confused hover states are cleared before removing the hover catcher.
|
|
65
|
+
this.mouseEvents = addEvents(this.$el, {
|
|
66
|
+
mousedown: this.onMouse,
|
|
67
|
+
mousemove: this.onMouse,
|
|
68
|
+
mouseleave: this.onMouse
|
|
69
|
+
})
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
onMouse() {
|
|
73
|
+
this.isDragging = false
|
|
74
|
+
this.mouseEvents.remove()
|
|
75
|
+
this.mouseEvents = null
|
|
76
|
+
}
|
|
43
77
|
}
|
|
44
78
|
})
|
|
45
79
|
</script>
|
|
80
|
+
|
|
81
|
+
<style lang="scss">
|
|
82
|
+
@import '../styles/_imports';
|
|
83
|
+
|
|
84
|
+
.dito-draggable {
|
|
85
|
+
// Overlay a hover catcher while we're dragging to prevent hover states from
|
|
86
|
+
// getting stuck / confused.
|
|
87
|
+
&:has(&__chosen),
|
|
88
|
+
&--dragging {
|
|
89
|
+
> * {
|
|
90
|
+
position: relative;
|
|
91
|
+
|
|
92
|
+
> :first-child::after {
|
|
93
|
+
content: '';
|
|
94
|
+
position: absolute;
|
|
95
|
+
inset: 0;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
&__fallback {
|
|
101
|
+
filter: drop-shadow(0 2px 4px $color-shadow);
|
|
102
|
+
|
|
103
|
+
// Nested <td> need to also switch to `display: flex` style during dragging.
|
|
104
|
+
&,
|
|
105
|
+
td {
|
|
106
|
+
display: flex;
|
|
107
|
+
|
|
108
|
+
> * {
|
|
109
|
+
flex: 1;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
</style>
|
|
@@ -10,18 +10,18 @@ DitoButtons.dito-edit-buttons.dito-buttons-round(
|
|
|
10
10
|
)
|
|
11
11
|
//- Firefox doesn't like <button> here, so use <a> instead:
|
|
12
12
|
a.dito-button(
|
|
13
|
-
v-if="
|
|
14
|
-
:class="{ 'dito-disabled':
|
|
13
|
+
v-if="draggable"
|
|
14
|
+
:class="{ 'dito-disabled': isDraggableDisabled }"
|
|
15
15
|
v-bind="getButtonAttributes(verbs.drag)"
|
|
16
16
|
)
|
|
17
17
|
RouterLink.dito-button(
|
|
18
|
-
v-if="
|
|
19
|
-
:class="{ 'dito-disabled':
|
|
18
|
+
v-if="editable"
|
|
19
|
+
:class="{ 'dito-disabled': isEditableDisabled }"
|
|
20
20
|
:to="editPath ? { path: editPath } : {}"
|
|
21
21
|
v-bind="getButtonAttributes(verbs.edit)"
|
|
22
22
|
)
|
|
23
23
|
DitoCreateButton(
|
|
24
|
-
v-if="
|
|
24
|
+
v-if="creatable"
|
|
25
25
|
:schema="schema"
|
|
26
26
|
:dataPath="dataPath"
|
|
27
27
|
:data="data"
|
|
@@ -30,12 +30,12 @@ DitoButtons.dito-edit-buttons.dito-buttons-round(
|
|
|
30
30
|
:path="createPath"
|
|
31
31
|
:verb="verbs.create"
|
|
32
32
|
:text="createButtonText"
|
|
33
|
-
:disabled="
|
|
33
|
+
:disabled="isCreatableDisabled"
|
|
34
34
|
)
|
|
35
35
|
button.dito-button(
|
|
36
|
-
v-if="
|
|
36
|
+
v-if="deletable"
|
|
37
37
|
type="button"
|
|
38
|
-
:disabled="
|
|
38
|
+
:disabled="isDeletableDisabled"
|
|
39
39
|
v-bind="getButtonAttributes(verbs.delete)"
|
|
40
40
|
@click="$emit('delete')"
|
|
41
41
|
)
|
|
@@ -70,24 +70,28 @@ export default DitoComponent.component('DitoEditButtons', {
|
|
|
70
70
|
return this.getLabel(this.schema.form)
|
|
71
71
|
},
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
return this.
|
|
73
|
+
isDraggableDisabled() {
|
|
74
|
+
return this.disabled || !this.hasSchemaOption('draggable')
|
|
75
75
|
},
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
return this.
|
|
77
|
+
isDeletableDisabled() {
|
|
78
|
+
return this.disabled || !this.hasSchemaOption('deletable')
|
|
79
79
|
},
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
return
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
81
|
+
isEditableDisabled() {
|
|
82
|
+
return (
|
|
83
|
+
this.disabled ||
|
|
84
|
+
!this.editPath ||
|
|
85
|
+
!this.hasSchemaOption('editable')
|
|
86
|
+
)
|
|
87
87
|
},
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
return
|
|
89
|
+
isCreatableDisabled() {
|
|
90
|
+
return (
|
|
91
|
+
this.disabled ||
|
|
92
|
+
!this.createPath ||
|
|
93
|
+
!this.hasSchemaOption('creatable')
|
|
94
|
+
)
|
|
91
95
|
},
|
|
92
96
|
|
|
93
97
|
createButtonText() {
|
|
@@ -105,11 +109,13 @@ export default DitoComponent.component('DitoEditButtons', {
|
|
|
105
109
|
},
|
|
106
110
|
|
|
107
111
|
methods: {
|
|
108
|
-
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
|
|
112
|
-
|
|
112
|
+
hasSchemaOption(name) {
|
|
113
|
+
// All options can be disabled on a per-form basis by setting
|
|
114
|
+
// `schema[name]` to `false` or a callback returning `false`.
|
|
115
|
+
return this.getSchemaValue(name, {
|
|
116
|
+
type: Boolean,
|
|
117
|
+
default: true
|
|
118
|
+
})
|
|
113
119
|
}
|
|
114
120
|
}
|
|
115
121
|
})
|
|
@@ -26,14 +26,14 @@ export default DitoComponent.component('DitoElement', {
|
|
|
26
26
|
|
|
27
27
|
classes() {
|
|
28
28
|
return {
|
|
29
|
-
...this.$attrs.class,
|
|
29
|
+
...asObject(this.$attrs.class),
|
|
30
30
|
...asObject(this.options.class)
|
|
31
31
|
}
|
|
32
32
|
},
|
|
33
33
|
|
|
34
34
|
styles() {
|
|
35
35
|
return {
|
|
36
|
-
...this.$attrs.style,
|
|
36
|
+
...asObject(this.$attrs.style),
|
|
37
37
|
...asObject(this.options.style)
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -123,8 +123,6 @@ export default DitoComponent.component('DitoLabel', {
|
|
|
123
123
|
label {
|
|
124
124
|
cursor: inherit;
|
|
125
125
|
font-weight: bold;
|
|
126
|
-
white-space: nowrap;
|
|
127
|
-
line-height: $input-height;
|
|
128
126
|
}
|
|
129
127
|
|
|
130
128
|
label,
|
|
@@ -132,6 +130,9 @@ export default DitoComponent.component('DitoLabel', {
|
|
|
132
130
|
&__suffix {
|
|
133
131
|
@include user-select(none);
|
|
134
132
|
@include ellipsis;
|
|
133
|
+
|
|
134
|
+
white-space: nowrap;
|
|
135
|
+
line-height: $input-height;
|
|
135
136
|
}
|
|
136
137
|
|
|
137
138
|
&__prefix + label,
|
|
@@ -219,6 +219,7 @@ export default DitoComponent.component('DitoPane', {
|
|
|
219
219
|
|
|
220
220
|
.dito-pane {
|
|
221
221
|
$self: &;
|
|
222
|
+
$root-padding: $content-padding - $form-spacing-half;
|
|
222
223
|
|
|
223
224
|
display: flex;
|
|
224
225
|
position: relative;
|
|
@@ -240,7 +241,7 @@ export default DitoComponent.component('DitoPane', {
|
|
|
240
241
|
margin: 0;
|
|
241
242
|
// Move the negative margin used to remove the padding added by
|
|
242
243
|
// `.dito-container` inside `.dito-pane` to the padding:
|
|
243
|
-
padding: $
|
|
244
|
+
padding: $root-padding;
|
|
244
245
|
|
|
245
246
|
&#{$self}--single {
|
|
246
247
|
padding: $content-padding;
|
|
@@ -260,9 +261,9 @@ export default DitoComponent.component('DitoPane', {
|
|
|
260
261
|
content: '';
|
|
261
262
|
width: 100%;
|
|
262
263
|
border-bottom: $border-style;
|
|
263
|
-
//
|
|
264
|
-
margin: (-$
|
|
265
|
-
|
|
264
|
+
// Shift ruler up by $root-padding to exclude removed $form-spacing-half.
|
|
265
|
+
margin: (-$root-padding) $form-spacing-half $root-padding;
|
|
266
|
+
padding: $form-spacing-half;
|
|
266
267
|
}
|
|
267
268
|
}
|
|
268
269
|
|
|
@@ -273,6 +274,9 @@ export default DitoComponent.component('DitoPane', {
|
|
|
273
274
|
}
|
|
274
275
|
|
|
275
276
|
.dito-break {
|
|
277
|
+
// `.dito-break` is rendered as <span> so we can use the
|
|
278
|
+
// `.dito-container:first-of-type` selector to match the first container
|
|
279
|
+
// even if it has a break before it.
|
|
276
280
|
display: block;
|
|
277
281
|
flex: 100%;
|
|
278
282
|
height: 0;
|
|
@@ -53,22 +53,24 @@ slot(name="before")
|
|
|
53
53
|
template(
|
|
54
54
|
v-if="hasTabs"
|
|
55
55
|
)
|
|
56
|
-
|
|
56
|
+
template(
|
|
57
57
|
v-for="(tabSchema, tab) in tabs"
|
|
58
|
-
v-show="selectedTab === tab"
|
|
59
|
-
ref="tabs"
|
|
60
|
-
:key="tab"
|
|
61
|
-
:tab="tab"
|
|
62
|
-
:schema="tabSchema"
|
|
63
|
-
:dataPath="dataPath"
|
|
64
|
-
:data="data"
|
|
65
|
-
:meta="meta"
|
|
66
|
-
:store="store"
|
|
67
|
-
:single="!inlined && !hasMainPane"
|
|
68
|
-
:disabled="disabled"
|
|
69
|
-
:generateLabels="generateLabels"
|
|
70
|
-
:accumulatedBasis="accumulatedBasis"
|
|
71
58
|
)
|
|
59
|
+
DitoPane.dito-pane__tab(
|
|
60
|
+
v-if="selectedTab === tab"
|
|
61
|
+
ref="tabs"
|
|
62
|
+
:key="tab"
|
|
63
|
+
:tab="tab"
|
|
64
|
+
:schema="tabSchema"
|
|
65
|
+
:dataPath="dataPath"
|
|
66
|
+
:data="data"
|
|
67
|
+
:meta="meta"
|
|
68
|
+
:store="store"
|
|
69
|
+
:single="!inlined && !hasMainPane"
|
|
70
|
+
:disabled="disabled"
|
|
71
|
+
:generateLabels="generateLabels"
|
|
72
|
+
:accumulatedBasis="accumulatedBasis"
|
|
73
|
+
)
|
|
72
74
|
DitoPane.dito-pane__main(
|
|
73
75
|
v-if="hasMainPane"
|
|
74
76
|
ref="components"
|
|
@@ -212,7 +214,7 @@ export default DitoComponent.component('DitoSchema', {
|
|
|
212
214
|
},
|
|
213
215
|
|
|
214
216
|
clipboard() {
|
|
215
|
-
return this.schema?.clipboard
|
|
217
|
+
return this.schema?.clipboard ?? null
|
|
216
218
|
},
|
|
217
219
|
|
|
218
220
|
hasHeader() {
|
|
@@ -674,6 +676,7 @@ export default DitoComponent.component('DitoSchema', {
|
|
|
674
676
|
{
|
|
675
677
|
// Needed for DitoContext handling inside `processData` and
|
|
676
678
|
// `processSchemaData()`:
|
|
679
|
+
rootData: this.rootData,
|
|
677
680
|
component: this,
|
|
678
681
|
schemaOnly,
|
|
679
682
|
target
|
|
@@ -770,7 +773,7 @@ export default DitoComponent.component('DitoSchema', {
|
|
|
770
773
|
grid-template-rows: min-content;
|
|
771
774
|
grid-template-columns: 100%;
|
|
772
775
|
|
|
773
|
-
>
|
|
776
|
+
> :only-child {
|
|
774
777
|
grid-row-end: none;
|
|
775
778
|
}
|
|
776
779
|
}
|
|
@@ -82,17 +82,10 @@ export default DitoComponent.component('DitoSchemaInlined', {
|
|
|
82
82
|
grid-template-rows: min-content;
|
|
83
83
|
grid-template-columns: 100%;
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
&:not(:hover, .dito-schema--open) {
|
|
86
86
|
> .dito-schema-header {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
.dito-label {
|
|
91
|
-
width: 100%;
|
|
92
|
-
margin: 0;
|
|
93
|
-
// Prevent collapsing to min-height when alone in
|
|
94
|
-
// .dito-schema-content, due to grid-template-rows: min-content
|
|
95
|
-
min-height: $input-height;
|
|
87
|
+
> .dito-clipboard {
|
|
88
|
+
display: none;
|
|
96
89
|
}
|
|
97
90
|
}
|
|
98
91
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
.dito-tree-item(
|
|
3
3
|
:id="dataPath"
|
|
4
4
|
:class=`{
|
|
5
|
-
'dito-dragging':
|
|
5
|
+
'dito-dragging': isDragging,
|
|
6
6
|
'dito-active': active
|
|
7
7
|
}`
|
|
8
8
|
:style="level > 0 && { '--level': level }"
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
v-if="childrenSchema"
|
|
77
77
|
v-show="opened"
|
|
78
78
|
:modelValue="updateOrder(childrenSchema, childrenList)"
|
|
79
|
-
:options="
|
|
79
|
+
:options="getDraggableOptions(true)"
|
|
80
80
|
:draggable="childrenDraggable"
|
|
81
81
|
@update:modelValue="value => (childrenList = value)"
|
|
82
82
|
)
|
|
@@ -2,19 +2,20 @@
|
|
|
2
2
|
export default {
|
|
3
3
|
data() {
|
|
4
4
|
return {
|
|
5
|
-
|
|
5
|
+
isDragging: false
|
|
6
6
|
}
|
|
7
7
|
},
|
|
8
8
|
|
|
9
9
|
methods: {
|
|
10
|
-
|
|
10
|
+
getDraggableOptions(forceFallback = false) {
|
|
11
|
+
const prefix = 'dito-draggable'
|
|
11
12
|
return {
|
|
12
13
|
animation: 150,
|
|
13
14
|
handle: '.dito-button-drag',
|
|
14
|
-
dragClass:
|
|
15
|
-
chosenClass:
|
|
16
|
-
ghostClass:
|
|
17
|
-
fallbackClass:
|
|
15
|
+
dragClass: `${prefix}__drag`,
|
|
16
|
+
chosenClass: `${prefix}__chosen`,
|
|
17
|
+
ghostClass: `${prefix}__ghost`,
|
|
18
|
+
fallbackClass: `${prefix}__fallback`,
|
|
18
19
|
forceFallback,
|
|
19
20
|
onStart: this.onStartDrag,
|
|
20
21
|
onEnd: this.onEndDrag
|
|
@@ -22,11 +23,11 @@ export default {
|
|
|
22
23
|
},
|
|
23
24
|
|
|
24
25
|
onStartDrag() {
|
|
25
|
-
this.
|
|
26
|
+
this.isDragging = true
|
|
26
27
|
},
|
|
27
28
|
|
|
28
29
|
onEndDrag({ oldIndex, newIndex }) {
|
|
29
|
-
this.
|
|
30
|
+
this.isDragging = false
|
|
30
31
|
if (oldIndex !== newIndex) {
|
|
31
32
|
this.onChange()
|
|
32
33
|
}
|
package/src/mixins/TypeMixin.js
CHANGED
|
@@ -28,7 +28,6 @@ export default {
|
|
|
28
28
|
data() {
|
|
29
29
|
return {
|
|
30
30
|
parsedValue: undefined,
|
|
31
|
-
changedValue: undefined,
|
|
32
31
|
focused: false
|
|
33
32
|
}
|
|
34
33
|
},
|
|
@@ -48,37 +47,27 @@ export default {
|
|
|
48
47
|
|
|
49
48
|
value: {
|
|
50
49
|
get() {
|
|
51
|
-
|
|
50
|
+
const value = computeValue(
|
|
52
51
|
this.schema,
|
|
53
52
|
this.data,
|
|
54
53
|
this.name,
|
|
55
54
|
this.dataPath,
|
|
56
55
|
{ component: this }
|
|
57
56
|
)
|
|
58
|
-
const { formatValue } = this.$options
|
|
59
|
-
if (formatValue) {
|
|
60
|
-
value = formatValue(this.schema, value, this.dataPath)
|
|
61
|
-
}
|
|
62
57
|
const { format } = this.schema
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return value
|
|
58
|
+
return format
|
|
59
|
+
? format(new DitoContext(this, { value }))
|
|
60
|
+
: value
|
|
67
61
|
},
|
|
68
62
|
|
|
69
63
|
set(value) {
|
|
70
|
-
const { parseValue } = this.$options
|
|
71
|
-
if (parseValue) {
|
|
72
|
-
value = parseValue(this.schema, value, this.dataPath)
|
|
73
|
-
}
|
|
74
64
|
const { parse } = this.schema
|
|
75
65
|
if (parse) {
|
|
76
66
|
value = parse(new DitoContext(this, { value }))
|
|
77
67
|
}
|
|
68
|
+
this.parsedValue = value
|
|
78
69
|
// eslint-disable-next-line vue/no-mutating-props
|
|
79
70
|
this.data[this.name] = value
|
|
80
|
-
this.parsedValue = value
|
|
81
|
-
this.changedValue = undefined
|
|
82
71
|
}
|
|
83
72
|
},
|
|
84
73
|
|
|
@@ -295,7 +284,6 @@ export default {
|
|
|
295
284
|
|
|
296
285
|
clear() {
|
|
297
286
|
this.value = null
|
|
298
|
-
this.changedValue = undefined
|
|
299
287
|
this.blur()
|
|
300
288
|
this.onChange()
|
|
301
289
|
},
|
|
@@ -318,21 +306,12 @@ export default {
|
|
|
318
306
|
},
|
|
319
307
|
|
|
320
308
|
onChange() {
|
|
321
|
-
const value =
|
|
322
|
-
this.parsedValue !== undefined ? this.parsedValue : this.value
|
|
323
|
-
|
|
324
|
-
if (this.$options.nativeField) {
|
|
325
|
-
// For some odd reason, the native change event now sometimes fires
|
|
326
|
-
// twice on Vue3. Filter out second call.
|
|
327
|
-
// TODO: Investigate why this happens, and if it's a bug in Vue3.
|
|
328
|
-
if (value === this.changedValue) return
|
|
329
|
-
this.changedValue = value
|
|
330
|
-
}
|
|
331
|
-
|
|
332
309
|
this.markDirty()
|
|
333
310
|
this.emitEvent('change', {
|
|
334
|
-
|
|
335
|
-
|
|
311
|
+
context: {
|
|
312
|
+
// Prevent endless parse recursion:
|
|
313
|
+
value: this.parsedValue !== undefined ? this.parsedValue : this.value
|
|
314
|
+
},
|
|
336
315
|
// Pass `schemaComponent` as parent, so change events can propagate up.
|
|
337
316
|
parent: this.schemaComponent
|
|
338
317
|
})
|
package/src/styles/_layout.scss
CHANGED
package/src/styles/style.scss
CHANGED