@ditojs/admin 1.30.0 → 2.0.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 (78) hide show
  1. package/dist/dito-admin.es.js +5291 -6856
  2. package/dist/dito-admin.umd.js +5 -5
  3. package/dist/style.css +1 -1
  4. package/package.json +37 -22
  5. package/src/DitoAdmin.js +44 -58
  6. package/src/DitoComponent.js +18 -50
  7. package/src/DitoContext.js +7 -3
  8. package/src/TypeComponent.js +15 -13
  9. package/src/appState.js +4 -2
  10. package/src/components/DitoAccount.vue +14 -14
  11. package/src/components/DitoButtons.vue +18 -10
  12. package/src/components/DitoClipboard.vue +16 -16
  13. package/src/components/DitoContainer.vue +32 -32
  14. package/src/components/DitoCreateButton.vue +22 -23
  15. package/src/components/DitoDialog.vue +73 -18
  16. package/src/components/DitoEditButtons.vue +31 -31
  17. package/src/components/DitoElement.vue +6 -6
  18. package/src/components/DitoErrors.vue +6 -6
  19. package/src/components/DitoForm.vue +42 -43
  20. package/src/components/DitoFormNested.vue +7 -3
  21. package/src/components/DitoHeader.vue +19 -19
  22. package/src/components/DitoLabel.vue +25 -25
  23. package/src/components/DitoMenu.vue +9 -9
  24. package/src/components/DitoPagination.vue +5 -5
  25. package/src/components/DitoPane.vue +32 -32
  26. package/src/components/DitoPanel.vue +18 -18
  27. package/src/components/DitoPanels.vue +5 -3
  28. package/src/components/DitoRoot.vue +107 -30
  29. package/src/components/DitoSchema.vue +76 -74
  30. package/src/components/DitoSchemaInlined.vue +29 -29
  31. package/src/components/DitoScopes.vue +14 -13
  32. package/src/components/DitoSpinner.vue +101 -0
  33. package/src/components/DitoTableCell.vue +19 -25
  34. package/src/components/DitoTableHead.vue +10 -7
  35. package/src/components/DitoTabs.vue +7 -6
  36. package/src/components/DitoTreeItem.vue +89 -85
  37. package/src/components/DitoVNode.vue +9 -7
  38. package/src/components/DitoView.vue +25 -21
  39. package/src/mixins/DataMixin.js +2 -2
  40. package/src/mixins/DitoMixin.js +43 -46
  41. package/src/mixins/DomMixin.js +1 -1
  42. package/src/mixins/EmitterMixin.js +11 -11
  43. package/src/mixins/RouteMixin.js +20 -10
  44. package/src/mixins/SchemaParentMixin.js +2 -2
  45. package/src/mixins/SourceMixin.js +7 -9
  46. package/src/mixins/TypeMixin.js +29 -34
  47. package/src/mixins/ValidationMixin.js +4 -19
  48. package/src/types/TypeButton.vue +11 -15
  49. package/src/types/TypeCheckbox.vue +7 -8
  50. package/src/types/TypeCheckboxes.vue +14 -15
  51. package/src/types/TypeCode.vue +5 -5
  52. package/src/types/TypeColor.vue +9 -12
  53. package/src/types/TypeComponent.vue +12 -7
  54. package/src/types/TypeComputed.vue +13 -12
  55. package/src/types/TypeDate.vue +10 -11
  56. package/src/types/TypeLabel.vue +1 -1
  57. package/src/types/TypeList.vue +115 -92
  58. package/src/types/TypeMarkup.vue +166 -125
  59. package/src/types/TypeMultiselect.vue +37 -47
  60. package/src/types/TypeNumber.vue +10 -11
  61. package/src/types/TypeObject.vue +62 -46
  62. package/src/types/TypeProgress.vue +7 -8
  63. package/src/types/TypeRadio.vue +15 -14
  64. package/src/types/TypeSection.vue +10 -10
  65. package/src/types/TypeSelect.vue +32 -33
  66. package/src/types/TypeSlider.vue +20 -22
  67. package/src/types/TypeSwitch.vue +8 -9
  68. package/src/types/TypeText.vue +7 -8
  69. package/src/types/TypeTextarea.vue +8 -9
  70. package/src/types/TypeTreeList.vue +40 -34
  71. package/src/types/TypeUpload.vue +61 -61
  72. package/src/utils/accessor.js +1 -1
  73. package/src/utils/data.js +0 -4
  74. package/src/utils/options.js +48 -0
  75. package/src/utils/path.js +5 -0
  76. package/src/utils/schema.js +73 -56
  77. package/src/utils/vue.js +11 -0
  78. package/types/index.d.ts +1 -1
@@ -3,11 +3,11 @@ import {
3
3
  getValueAtDataPath, labelize, hyphenate, format
4
4
  } from '@ditojs/utils'
5
5
  import appState from '../appState.js'
6
- import DitoComponent from '../DitoComponent.js'
7
6
  import DitoContext from '../DitoContext.js'
8
7
  import EmitterMixin from './EmitterMixin.js'
9
8
  import { isMatchingType, convertType } from '../utils/type.js'
10
9
  import { getResource, getMemberResource } from '../utils/resource.js'
10
+ import { reactive } from 'vue'
11
11
 
12
12
  // @vue/component
13
13
  export default {
@@ -18,6 +18,7 @@ export default {
18
18
  '$verbs',
19
19
  '$views',
20
20
  '$isPopulated',
21
+ '$parentComponent',
21
22
  '$schemaComponent',
22
23
  '$routeComponent',
23
24
  '$dataComponent',
@@ -30,8 +31,13 @@ export default {
30
31
 
31
32
  provide() {
32
33
  return this.providesData
33
- ? { $dataComponent: () => this }
34
- : {}
34
+ ? {
35
+ $parentComponent: () => this,
36
+ $dataComponent: () => this
37
+ }
38
+ : {
39
+ $parentComponent: () => this
40
+ }
35
41
  },
36
42
 
37
43
  data() {
@@ -42,6 +48,11 @@ export default {
42
48
  },
43
49
 
44
50
  computed: {
51
+ providesData() {
52
+ // NOTE: This is overridden in ResourceMixin, used by lists.
53
+ return false
54
+ },
55
+
45
56
  sourceSchema() {
46
57
  return this.meta?.schema
47
58
  },
@@ -74,18 +85,20 @@ export default {
74
85
  },
75
86
 
76
87
  rootComponent() {
77
- return this.$root.$children[0]
88
+ return this.$root.$refs.root
89
+ },
90
+
91
+ // Use computed properties as links to injects, so DitoSchema can
92
+ // override the property and return `this` instead of the parent.
93
+ parentComponent() {
94
+ return this.$parentComponent()
78
95
  },
79
96
 
80
97
  schemaComponent() {
81
- // Use computed properties as links to injects, so DitoSchema can
82
- // override the property and return `this` instead of the parent.
83
98
  return this.$schemaComponent()
84
99
  },
85
100
 
86
101
  routeComponent() {
87
- // Use computed properties as links to injects, so RouteMixin can
88
- // override the property and return `this` instead of the parent.
89
102
  return this.$routeComponent()
90
103
  },
91
104
 
@@ -127,15 +140,15 @@ export default {
127
140
  },
128
141
 
129
142
  parentSchemaComponent() {
130
- return this.schemaComponent?.$parent.schemaComponent
143
+ return this.schemaComponent?.parentComponent.schemaComponent
131
144
  },
132
145
 
133
146
  parentRouteComponent() {
134
- return this.routeComponent?.$parent.routeComponent
147
+ return this.routeComponent?.parentComponent.routeComponent
135
148
  },
136
149
 
137
150
  parentFormComponent() {
138
- return this.formComponent?.$parent.formComponent
151
+ return this.formComponent?.parentComponent.formComponent
139
152
  },
140
153
 
141
154
  // Returns the data of the first route component in the chain of parents
@@ -146,7 +159,10 @@ export default {
146
159
  },
147
160
 
148
161
  beforeCreate() {
149
- this.$uid = ++uid
162
+ const uid = nextUid++
163
+ Object.defineProperty(this, '$uid', {
164
+ get() { return uid }
165
+ })
150
166
  },
151
167
 
152
168
  methods: {
@@ -163,11 +179,12 @@ export default {
163
179
  },
164
180
 
165
181
  setStore(key, value) {
166
- return this.$set(this.store, key, value)
182
+ this.store[key] = value
183
+ return value
167
184
  },
168
185
 
169
186
  getChildStore(key) {
170
- return this.getStore(key) || this.setStore(key, {})
187
+ return this.getStore(key) || this.setStore(key, reactive({}))
171
188
  },
172
189
 
173
190
  getSchemaValue(
@@ -241,6 +258,7 @@ export default {
241
258
  }
242
259
  },
243
260
 
261
+ // TODO: Rename *Link() to *Route().
244
262
  getQueryLink(query) {
245
263
  return {
246
264
  query,
@@ -257,30 +275,6 @@ export default {
257
275
  })
258
276
  },
259
277
 
260
- showDialog({
261
- components,
262
- buttons,
263
- data,
264
- settings = {
265
- width: 480,
266
- height: 'auto',
267
- clickToClose: false
268
- }
269
- }) {
270
- // Shows a dito-dialog component through vue-js-modal, and wraps it in a
271
- // promise so that the buttons in the dialog can use `dialog.resolve()`
272
- // and `dialog.reject()` to close the modal dialog and resolve / reject
273
- // the promise at once.
274
- return new Promise((resolve, reject) => {
275
- this.$modal.show(DitoComponent.component('dito-dialog'), {
276
- components,
277
- buttons,
278
- data,
279
- promise: { resolve, reject }
280
- }, settings)
281
- })
282
- },
283
-
284
278
  getResourcePath(resource) {
285
279
  resource = getResource(resource)
286
280
  // Resources without a parent inherit the one from `dataComponent`
@@ -315,6 +309,15 @@ export default {
315
309
  return response
316
310
  },
317
311
 
312
+ showDialog({ components, buttons, data, settings }) {
313
+ return this.rootComponent.showDialog({
314
+ components,
315
+ buttons,
316
+ data,
317
+ settings
318
+ })
319
+ },
320
+
318
321
  request({ cache, ...options }) {
319
322
  // Allow caching of loaded data on two levels:
320
323
  // - 'global': cache globally, for the entire admin session
@@ -367,13 +370,7 @@ export default {
367
370
  },
368
371
 
369
372
  async navigate(location) {
370
- return new Promise(resolve => {
371
- this.$router.push(
372
- location,
373
- () => resolve(true),
374
- () => resolve(false)
375
- )
376
- })
373
+ return this.$router.push(location)
377
374
  },
378
375
 
379
376
  download(options = {}) {
@@ -506,4 +503,4 @@ export default {
506
503
  }
507
504
  }
508
505
 
509
- let uid = 0
506
+ let nextUid = 0
@@ -9,7 +9,7 @@ export default {
9
9
  }
10
10
  },
11
11
 
12
- beforeDestroy() {
12
+ beforeUnmount() {
13
13
  for (const { remove } of this.domHandlers) {
14
14
  remove()
15
15
  }
@@ -4,14 +4,14 @@ import { isArray, isPlainObject } from '@ditojs/utils'
4
4
  export default {
5
5
  data() {
6
6
  return {
7
- $events: null
7
+ listeners: null
8
8
  }
9
9
  },
10
10
 
11
11
  methods: {
12
- // Async versions of Vue's $on() and $off() methods that keep track of the
13
- // events added / removed, and provide a hasListeners() method that checks
14
- // if the component has listeners for a given event.
12
+ // Async on() and $off() methods that keep track of the events added /
13
+ // removed, and provide a hasListeners() method that checks if the component
14
+ // has listeners for a given event.
15
15
 
16
16
  // Also adds proper handling of async events, including a async emit() that
17
17
  // deals with proper event queueing.
@@ -25,8 +25,8 @@ export default {
25
25
  this.on(key, event[key])
26
26
  }
27
27
  } else {
28
- const events = this.$events || (this.$events = Object.create(null))
29
- const { callbacks } = events[event] || (events[event] = {
28
+ const listeners = (this.listeners ||= Object.create(null))
29
+ const { callbacks } = (listeners[event] ||= {
30
30
  callbacks: [],
31
31
  queue: []
32
32
  })
@@ -47,7 +47,7 @@ export default {
47
47
  off(event, callback) {
48
48
  if (!arguments.length) {
49
49
  // Remove all events
50
- delete this.$events
50
+ delete this.listeners
51
51
  } else if (isArray(event)) {
52
52
  for (const ev of event) {
53
53
  this.off(ev, callback)
@@ -58,11 +58,11 @@ export default {
58
58
  }
59
59
  } else {
60
60
  // Remove specific event
61
- const entry = this.$events?.[event]
61
+ const entry = this.listeners?.[event]
62
62
  if (entry) {
63
63
  if (!callback) {
64
64
  // Remove all handlers for this event
65
- delete this.$events[event]
65
+ delete this.listeners[event]
66
66
  } else {
67
67
  // Remove a specific handler: find the index in callbacks
68
68
  const { callbacks } = entry
@@ -81,7 +81,7 @@ export default {
81
81
 
82
82
  emit(event, ...args) {
83
83
  // Only queue event if there actually are listeners for it.
84
- const entry = this.$events?.[event]
84
+ const entry = this.listeners?.[event]
85
85
  if (entry) {
86
86
  const { queue, callbacks } = entry
87
87
  return new Promise(resolve => {
@@ -129,7 +129,7 @@ export default {
129
129
  }
130
130
  return event.length > 0
131
131
  } else {
132
- return !!this.$events?.[event]
132
+ return !!this.listeners?.[event]
133
133
  }
134
134
  },
135
135
 
@@ -12,11 +12,11 @@ export default {
12
12
  },
13
13
 
14
14
  beforeRouteUpdate(to, from, next) {
15
- this.beforeRouteChange(to, from, next)
15
+ this?.beforeRouteChange(to, from, next)
16
16
  },
17
17
 
18
18
  beforeRouteLeave(to, from, next) {
19
- this.beforeRouteChange(to, from, next)
19
+ this?.beforeRouteChange(to, from, next)
20
20
  },
21
21
 
22
22
  data() {
@@ -36,11 +36,17 @@ export default {
36
36
  return this
37
37
  },
38
38
 
39
+ routeLevel() {
40
+ let level = 0
41
+ let routeComponent = this
42
+ while ((routeComponent = routeComponent.parentComponent.routeComponent)) {
43
+ level++
44
+ }
45
+ return level
46
+ },
47
+
39
48
  routeRecord() {
40
- // TODO: Can this.$route.currentRoute be of use somewhere here?
41
- // Retrieve the route-record to which this component was mapped to:
42
- // https://github.com/vuejs/vue-router/issues/1338#issuecomment-296381459
43
- return this.$route.matched[this.$vnode.data.routerViewDepth]
49
+ return this.$route.matched[this.routeLevel]
44
50
  },
45
51
 
46
52
  isLastRoute() {
@@ -66,8 +72,12 @@ export default {
66
72
  return this.meta.nested
67
73
  },
68
74
 
75
+ isView() {
76
+ return false
77
+ },
78
+
69
79
  meta() {
70
- return this.routeRecord?.meta
80
+ return this.routeRecord.meta
71
81
  },
72
82
 
73
83
  path() {
@@ -95,7 +105,7 @@ export default {
95
105
  },
96
106
 
97
107
  // @overridable, see DitoForm
98
- doesMutate() {
108
+ isMutating() {
99
109
  return false
100
110
  }
101
111
  },
@@ -107,7 +117,7 @@ export default {
107
117
  this.appState.routeComponents.push(this)
108
118
  },
109
119
 
110
- destroyed() {
120
+ unmounted() {
111
121
  const { routeComponents } = this.appState
112
122
  routeComponents.splice(routeComponents.indexOf(this), 1)
113
123
  },
@@ -131,7 +141,7 @@ export default {
131
141
  )
132
142
  )
133
143
  if (isClosing) {
134
- if (this.doesMutate) {
144
+ if (this.isMutating) {
135
145
  // For active directly mutating (nested) forms that were not validated
136
146
  // yet, validate them once. If the user then still wants to leave
137
147
  // them, they can click close / navigate away again.
@@ -19,8 +19,8 @@ export default {
19
19
  },
20
20
 
21
21
  methods: {
22
- // This method is called by `DitoSchema.created()/destroyed()` on its
23
- // $parent, if the parent uses the `SchemaParentMixin`:
22
+ // This method is called by `DitoSchema.created()/unmounted()` on its
23
+ // `$schemaParentComponent`, if the parent uses the `SchemaParentMixin`:
24
24
  _registerSchemaComponent(schemaComponent, add) {
25
25
  const { schemaComponents } = this
26
26
  if (add) {
@@ -313,16 +313,16 @@ export default {
313
313
 
314
314
  wrappedPrimitives: {
315
315
  deep: true,
316
- handler(newValue, oldValue) {
316
+ handler(to, from) {
317
317
  const { wrapPrimitives } = this
318
318
  // Skip the initial setting of wrappedPrimitives array
319
- if (wrapPrimitives && oldValue !== null) {
319
+ if (wrapPrimitives && from !== null) {
320
320
  // Whenever the wrappedPrimitives change, map their values back to
321
321
  // the array of primitives, in a primitive way :)
322
322
  // But set `unwrappingPrimitives = true`, so the `listData` computed
323
323
  // property knows about it, which sets it to `false` again.
324
324
  this.unwrappingPrimitives = true
325
- this.value = newValue.map(object => object[wrapPrimitives])
325
+ this.value = to.map(object => object[wrapPrimitives])
326
326
  }
327
327
  }
328
328
  }
@@ -509,15 +509,13 @@ export default {
509
509
  callOnComplete()
510
510
  } else {
511
511
  // Navigate to the component's path, then call `onComplete()`_:
512
- this.$router.push(
513
- { path },
512
+ this.$router.push({ path })
513
+ .catch(reject)
514
514
  // Wait for the last route component to be mounted in the next
515
515
  // tick before calling `onComplete()`
516
- () => {
516
+ .then(() => {
517
517
  this.$nextTick(callOnComplete)
518
- },
519
- reject
520
- )
518
+ })
521
519
  }
522
520
  }
523
521
  // Keep removing the last part until we find a match.
@@ -3,7 +3,7 @@ import ValidationMixin from './ValidationMixin.js'
3
3
  import { getSchemaAccessor } from '../utils/accessor.js'
4
4
  import { computeValue } from '../utils/schema.js'
5
5
  import { getItem, getParentItem } from '../utils/data.js'
6
- import { isString, asArray } from '@ditojs/utils'
6
+ import { isString, asArray, camelize } from '@ditojs/utils'
7
7
 
8
8
  // @vue/component
9
9
  export default {
@@ -38,10 +38,6 @@ export default {
38
38
  return this.schema.type
39
39
  },
40
40
 
41
- component() {
42
- return this.resolveTypeComponent(this.schema.component)
43
- },
44
-
45
41
  context() {
46
42
  return new DitoContext(this, { nested: this.nested })
47
43
  },
@@ -70,7 +66,8 @@ export default {
70
66
  this.parsedValue = parse
71
67
  ? parse.call(this, new DitoContext(this, { value }))
72
68
  : value
73
- this.$set(this.data, this.name, this.parsedValue)
69
+ // eslint-disable-next-line vue/no-mutating-props
70
+ this.data[this.name] = this.parsedValue
74
71
  }
75
72
  },
76
73
 
@@ -119,7 +116,7 @@ export default {
119
116
  visible: getSchemaAccessor('visible', {
120
117
  type: Boolean,
121
118
  default() {
122
- return this.typeOptions.defaultVisible
119
+ return this.$options.defaultVisible
123
120
  }
124
121
  }),
125
122
 
@@ -178,20 +175,26 @@ export default {
178
175
  attributes.autocomplete = this.autocomplete
179
176
  }
180
177
  }
181
- return attributes
178
+
179
+ return {
180
+ ...Object.fromEntries(
181
+ Object.entries(this.$attrs).filter(([key]) => key.startsWith('on'))
182
+ ),
183
+ ...this.events,
184
+ ...attributes
185
+ }
182
186
  },
183
187
 
184
- listeners() {
185
- const listeners = this.getListeners()
186
- const { events = {} } = this.schema
187
- if (events) {
188
- // Register callbacks for all provides non-recognized events,
189
- // assuming they are native events.
190
- for (const event of Object.keys(events)) {
191
- listeners[event] ||= () => this.emitEvent(event)
192
- }
188
+ events() {
189
+ const events = this.getEvents()
190
+ // Register callbacks for all provides non-recognized events,
191
+ // assuming they are native events.
192
+ // TODO: Move to vue3-style `on[A-Z]` event handlers naming that aren't
193
+ // namespaced in `schema.events` once the transition is complete.
194
+ for (const event of Object.keys(this.schema.events || {})) {
195
+ events[`on${camelize(event, true)}`] ||= () => this.emitEvent(event)
193
196
  }
194
- return listeners
197
+ return events
195
198
  },
196
199
 
197
200
  validations() {
@@ -210,11 +213,6 @@ export default {
210
213
  return validations
211
214
  },
212
215
 
213
- providesData() {
214
- // NOTE: This is overridden in ResourceMixin, used by lists.
215
- return false
216
- },
217
-
218
216
  showClearButton() {
219
217
  return this.clearable && this.value != null
220
218
  }
@@ -225,7 +223,7 @@ export default {
225
223
  this.setupSchemaFields()
226
224
  },
227
225
 
228
- beforeDestroy() {
226
+ beforeUnmount() {
229
227
  this._register(false)
230
228
  },
231
229
 
@@ -234,20 +232,13 @@ export default {
234
232
  // Prevent unnested type components from overriding parent data paths
235
233
  if (this.nested) {
236
234
  this.schemaComponent._registerComponent(this, add)
237
- // Install / remove the field events to watch of changes and handle
238
- // validation flags. `events` is provided by `ValidationMixin.events()`
239
- this[add ? 'on' : 'off'](this.events)
240
235
  }
241
236
  },
242
237
 
243
238
  // @overridable
244
- getListeners() {
245
- return {
246
- focus: this.onFocus,
247
- blur: this.onBlur,
248
- input: this.onInput,
249
- change: this.onChange
250
- }
239
+ getEvents() {
240
+ const { onFocus, onBlur, onInput, onChange } = this
241
+ return { onFocus, onBlur, onInput, onChange }
251
242
  },
252
243
 
253
244
  // @overridable
@@ -284,19 +275,23 @@ export default {
284
275
 
285
276
  onFocus() {
286
277
  this.focused = true
278
+ this.markTouched()
287
279
  this.emitEvent('focus')
288
280
  },
289
281
 
290
282
  onBlur() {
291
283
  this.focused = false
284
+ this.validate()
292
285
  this.emitEvent('blur')
293
286
  },
294
287
 
295
288
  onInput() {
289
+ this.markDirty()
296
290
  this.emitEvent('input')
297
291
  },
298
292
 
299
293
  onChange() {
294
+ this.markDirty()
300
295
  this.emitEvent('change', {
301
296
  context: this.parsedValue !== undefined
302
297
  ? { value: this.parsedValue }
@@ -13,25 +13,6 @@ export default {
13
13
  }
14
14
  },
15
15
 
16
- computed: {
17
- events() {
18
- return {
19
- focus: () => {
20
- this.isTouched = true
21
- },
22
- blur: () => {
23
- this.validate()
24
- },
25
- change: () => {
26
- this.markDirty()
27
- },
28
- input: () => {
29
- this.markDirty()
30
- }
31
- }
32
- }
33
- },
34
-
35
16
  methods: {
36
17
  resetValidation() {
37
18
  this.isTouched = false
@@ -74,6 +55,10 @@ export default {
74
55
  return this.validate(false)
75
56
  },
76
57
 
58
+ markTouched() {
59
+ this.isTouched = true
60
+ },
61
+
77
62
  markDirty() {
78
63
  this.isDirty = true
79
64
  this.isValidated = false
@@ -1,13 +1,12 @@
1
1
  <template lang="pug">
2
- button.dito-button(
3
- ref="element"
4
- :id="dataPath"
5
- :type="type"
6
- :title="text"
7
- :class="`dito-button-${verb}`"
8
- v-bind="attributes"
9
- v-on="listeners"
10
- ) {{ text }}
2
+ button.dito-button(
3
+ ref="element"
4
+ :id="dataPath"
5
+ :type="type"
6
+ :title="text"
7
+ :class="`dito-button-${verb}`"
8
+ v-bind="attributes"
9
+ ) {{ text }}
11
10
  </template>
12
11
 
13
12
  <script>
@@ -47,12 +46,9 @@ export default TypeComponent.register([
47
46
 
48
47
  methods: {
49
48
  // @override
50
- getListeners() {
51
- return {
52
- focus: this.onFocus,
53
- blur: this.onBlur,
54
- click: this.onClick
55
- }
49
+ getEvents() {
50
+ const { onFocus, onBlur, onClick } = this
51
+ return { onFocus, onBlur, onClick }
56
52
  },
57
53
 
58
54
  async submit(options) {
@@ -1,12 +1,11 @@
1
1
  <template lang="pug">
2
- input.dito-checkbox(
3
- ref="element"
4
- :id="dataPath"
5
- type="checkbox"
6
- v-model="value"
7
- v-bind="attributes"
8
- v-on="listeners"
9
- )
2
+ input.dito-checkbox(
3
+ ref="element"
4
+ :id="dataPath"
5
+ type="checkbox"
6
+ v-model="value"
7
+ v-bind="attributes"
8
+ )
10
9
  </template>
11
10
 
12
11
  <style lang="sass">
@@ -1,19 +1,18 @@
1
1
  <template lang="pug">
2
- ul.dito-checkboxes(
3
- :id="dataPath"
4
- :class="`dito-layout-${schema.layout || 'vertical'}`"
5
- )
6
- li(v-for="option in options")
7
- label
8
- input.dito-checkbox(
9
- ref="element"
10
- type="checkbox"
11
- :value="getValueForOption(option)"
12
- v-model="selectedOptions"
13
- v-bind="attributes"
14
- v-on="listeners"
15
- )
16
- | {{ getLabelForOption(option) }}
2
+ ul.dito-checkboxes(
3
+ :id="dataPath"
4
+ :class="`dito-layout-${schema.layout || 'vertical'}`"
5
+ )
6
+ li(v-for="option in options")
7
+ label
8
+ input.dito-checkbox(
9
+ ref="element"
10
+ type="checkbox"
11
+ :value="getValueForOption(option)"
12
+ v-model="selectedOptions"
13
+ v-bind="attributes"
14
+ )
15
+ | {{ getLabelForOption(option) }}
17
16
  </template>
18
17
 
19
18
  <style lang="sass">
@@ -1,9 +1,9 @@
1
1
  <template lang="pug">
2
- .dito-code(
3
- ref="code"
4
- :id="dataPath"
5
- :style="style"
6
- )
2
+ .dito-code(
3
+ ref="code"
4
+ :id="dataPath"
5
+ :style="style"
6
+ )
7
7
  </template>
8
8
 
9
9
  <style lang="sass">