@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ditojs/admin",
3
- "version": "1.30.0",
3
+ "version": "2.0.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",
@@ -33,40 +33,55 @@
33
33
  "not ie_mob > 0"
34
34
  ],
35
35
  "dependencies": {
36
- "@ditojs/build": "^1.30.0",
37
- "@ditojs/ui": "^1.30.0",
38
- "@ditojs/utils": "^1.30.0",
36
+ "@ditojs/ui": "^2.0.0",
37
+ "@ditojs/utils": "^2.0.0",
38
+ "@kyvg/vue3-notification": "^2.9.0",
39
+ "@lk77/vue3-color": "^3.0.6",
40
+ "@tiptap/core": "^2.0.1",
41
+ "@tiptap/extension-blockquote": "^2.0.1",
42
+ "@tiptap/extension-bold": "^2.0.1",
43
+ "@tiptap/extension-bullet-list": "^2.0.1",
44
+ "@tiptap/extension-code": "^2.0.1",
45
+ "@tiptap/extension-code-block": "^2.0.1",
46
+ "@tiptap/extension-document": "^2.0.1",
47
+ "@tiptap/extension-hard-break": "^2.0.1",
48
+ "@tiptap/extension-heading": "^2.0.1",
49
+ "@tiptap/extension-history": "^2.0.1",
50
+ "@tiptap/extension-horizontal-rule": "^2.0.1",
51
+ "@tiptap/extension-italic": "^2.0.1",
52
+ "@tiptap/extension-link": "^2.0.1",
53
+ "@tiptap/extension-list-item": "^2.0.1",
54
+ "@tiptap/extension-ordered-list": "^2.0.1",
55
+ "@tiptap/extension-paragraph": "^2.0.1",
56
+ "@tiptap/extension-strike": "^2.0.1",
57
+ "@tiptap/extension-text": "^2.0.1",
58
+ "@tiptap/extension-underline": "^2.0.1",
59
+ "@tiptap/pm": "^2.0.1",
60
+ "@tiptap/vue-3": "^2.0.1",
39
61
  "codeflask": "^1.4.1",
40
62
  "filesize": "^10.0.6",
41
63
  "filesize-parser": "^1.5.0",
42
64
  "nanoid": "^4.0.1",
65
+ "sortablejs": "^1.15.0",
66
+ "sortablejs-vue3": "^1.2.8",
43
67
  "tinycolor2": "^1.6.0",
44
- "tiptap": "^1.32.2",
45
- "tiptap-commands": "^1.17.1",
46
- "tiptap-extensions": "^1.35.2",
47
- "to-pascal-case": "^1.0.0",
48
- "vue": "^2.7.14",
49
- "vue-color": "^2.8.1",
50
- "vue-js-modal": "^2.0.1",
51
- "vue-multiselect": "^2.1.7",
52
- "vue-notification": "^1.3.20",
53
- "vue-router": "^3.6.5",
54
- "vue-spinner": "^1.0.4",
55
- "vue-template-compiler": "^2.7.14",
56
- "vue-upload-component": "^2.8.23",
57
- "vuedraggable": "^2.24.3"
68
+ "vue": "^3.2.47",
69
+ "vue-multiselect": "^3.0.0-beta.1",
70
+ "vue-router": "^4.1.6",
71
+ "vue-upload-component": "^3.1.8"
58
72
  },
59
73
  "devDependencies": {
60
- "@ditojs/build": "^1.19.0",
74
+ "@ditojs/build": "^2.0.0",
75
+ "@vitejs/plugin-vue": "^4.1.0",
76
+ "@vue/compiler-sfc": "^3.2.47",
61
77
  "pug": "^3.0.2",
62
78
  "sass": "1.59.3",
63
79
  "type-fest": "^3.6.1",
64
80
  "typescript": "^5.0.2",
65
- "vite": "^4.2.1",
66
- "vite-plugin-vue2": "^2.0.3"
81
+ "vite": "^4.2.1"
67
82
  },
68
83
  "types": "types",
69
- "gitHead": "5d09dc24ecb77b511f3c25643275ea1b9514fb52",
84
+ "gitHead": "dde9462e778bce37bc4fa3e47127a9ba12a4d5e2",
70
85
  "scripts": {
71
86
  "build": "vite build",
72
87
  "watch": "yarn build --mode 'development' --watch",
package/src/DitoAdmin.js CHANGED
@@ -1,7 +1,6 @@
1
- import Vue from 'vue'
2
- import VueModal from 'vue-js-modal'
3
- import VueRouter from 'vue-router'
4
- import VueNotifications from 'vue-notification'
1
+ import { createApp, h as createElement } from 'vue'
2
+ import { createRouter, createWebHistory } from 'vue-router'
3
+ import VueNotifications from '@kyvg/vue3-notification'
5
4
  import {
6
5
  isString, isArray, asArray, isAbsoluteUrl,
7
6
  merge, hyphenate, camelize,
@@ -15,19 +14,6 @@ import { getResource } from './utils/resource.js'
15
14
  import { deprecate } from './utils/deprecate.js'
16
15
  import verbs from './verbs.js'
17
16
 
18
- Vue.config.productionTip = false
19
-
20
- // All global plugins that need to be registered on `Vue`:
21
- Vue.use(VueRouter)
22
- Vue.use(VueModal, { dynamic: true })
23
- Vue.use(VueNotifications)
24
-
25
- if (import.meta.hot) {
26
- // Workaround for a strange Vite hot-reloading bug, see:
27
- // https://github.com/vitejs/vite/issues/7839#issuecomment-1340109679
28
- import.meta.hot.on('vite:beforeUpdate', onBeforeViteUpdate)
29
- }
30
-
31
17
  export default class DitoAdmin {
32
18
  constructor(el, {
33
19
  // `dito` contains the base and api settings passed from `AdminController`
@@ -141,15 +127,17 @@ export default class DitoAdmin {
141
127
  el = document.querySelector(el)
142
128
  }
143
129
 
144
- this.root = new Vue({
145
- el,
146
- router: new VueRouter({
147
- mode: 'history',
148
- base: dito.base,
149
- linkActiveClass: '',
150
- linkExactActiveClass: ''
151
- }),
152
- components: { DitoRoot },
130
+ const app = this.app = createApp({
131
+ components: {
132
+ DitoRoot,
133
+ VueNotifications,
134
+ // This may only be needed to avoid tree-shacking of these components,
135
+ // since they actually handle registry internally already.
136
+ // TODO: Remove this once we have a better solution.
137
+ ...components,
138
+ ...types
139
+ },
140
+
153
141
  // Most injects are defined as functions, to preserve reactiveness across
154
142
  // provide/inject, see:
155
143
  // https://github.com/vuejs/vue/issues/7017#issuecomment-480906691
@@ -162,6 +150,7 @@ export default class DitoAdmin {
162
150
  // inject: [ '$isPopulated', '$schemaComponent', '$routeComponent' ]
163
151
  $views: () => {},
164
152
  $isPopulated: () => true,
153
+ $parentComponent: () => null,
165
154
  $schemaComponent: () => null,
166
155
  $schemaParentComponent: () => null,
167
156
  $routeComponent: () => null,
@@ -173,23 +162,37 @@ export default class DitoAdmin {
173
162
  $tabComponent: () => null
174
163
  },
175
164
 
176
- render: createElement => createElement(DitoRoot, {
177
- // Preserve the root container's id, as required by hot-reloading:
178
- attrs: {
179
- id: el.id
180
- },
181
- props: {
182
- unresolvedViews: views,
183
- options
184
- },
185
- // This may only be needed to avoid tree-shacking of these components,
186
- // since they actually handle registry internally already.
187
- components: {
188
- ...components,
189
- ...types
190
- }
165
+ render: () => createElement(DitoRoot, {
166
+ ref: 'root',
167
+ class: dito.settings.rootClass,
168
+ unresolvedViews: views,
169
+ options
191
170
  })
192
171
  })
172
+
173
+ app.use(VueNotifications, {
174
+ name: 'notify',
175
+ componentName: 'VueNotifications'
176
+ })
177
+
178
+ // root.component('vue-modal', VueModal)
179
+
180
+ app.use(createRouter({
181
+ // Start with a catch-all route, to be replaced by the actual routes once
182
+ // the schemas are loaded, to prevent vue-router from complaining, see:
183
+ // `resolveViews()` in `DitoRoot` for the actual route setup.
184
+ routes: [{
185
+ name: 'catch-all',
186
+ path: '/:_(.*)',
187
+ components: {}
188
+ }],
189
+ history: createWebHistory(dito.base),
190
+ linkActiveClass: '',
191
+ linkExactActiveClass: ''
192
+ }))
193
+
194
+ el.classList.add('dito-app')
195
+ app.mount(el)
193
196
  }
194
197
 
195
198
  register(type, options) {
@@ -280,20 +283,3 @@ function formatQuery(query) {
280
283
  )
281
284
  ).toString()
282
285
  }
283
-
284
- function onBeforeViteUpdate(event) {
285
- if (event.type === 'update') {
286
- // Patch `event.updates` to remove the version query parameter from path,
287
- // so that the update gets picked up.
288
- // Why the stored `deps` are missing this part of the URL, I cannot say…
289
- const updates = []
290
- for (const update of event.updates) {
291
- updates.push(update) // Keep the original update.
292
- const acceptedPath = update.acceptedPath.replace(/\?v=[0-9a-f]+&/i, '?')
293
- if (acceptedPath !== update.acceptedPath) {
294
- updates.push({ ...update, acceptedPath })
295
- }
296
- }
297
- event.updates = updates
298
- }
299
- }
@@ -1,63 +1,31 @@
1
- import Vue from 'vue'
2
- import { isFunction, isPromise } from '@ditojs/utils'
3
1
  import DitoMixin from './mixins/DitoMixin.js'
4
- import TypeMixin from './mixins/TypeMixin.js'
5
2
  import { getTypeComponent } from './utils/schema.js'
3
+ import { resolveMergedOptions } from './utils/options.js'
4
+ import { isPlainObject } from '@ditojs/utils'
6
5
 
7
6
  const components = {}
8
7
 
9
- const DitoComponent = Vue.extend({
8
+ // @vue/component
9
+ export default {
10
10
  // Make sure that registered components are present in all DitoComponent.
11
11
  components,
12
12
  mixins: [DitoMixin],
13
13
 
14
- methods: {
15
- getTypeComponent,
16
-
17
- resolveComponent(component, mixins = []) {
18
- // A helper method to allow three things:
19
- // - When used in a computed property, it removes the need to have to
20
- // load components with async functions `component: () => import(...)`.
21
- // instead, they can be directly provided: `component: import(...)`
22
- // - The properties passed to such components don't need to be defined.
23
- // Instead, the provided mixins are automatically inherited.
24
- // - The component can use all internal components known to Dito.js Admin.
25
- return component
26
- ? async () => {
27
- // At first, resolve component is it is loaded asynchronously.
28
- let comp = isFunction(component) ? await component()
29
- : isPromise(component) ? await component
30
- : component
31
- comp = comp?.default || comp
32
- comp.mixins = mixins
33
- comp.components = components
34
- return comp
35
- }
36
- : component
37
- },
38
-
39
- resolveDitoComponent(component) {
40
- return this.resolveComponent(component, [DitoMixin])
41
- },
42
-
43
- resolveTypeComponent(component) {
44
- return this.resolveComponent(component, [DitoMixin, TypeMixin])
14
+ component(name, definition) {
15
+ if (definition) {
16
+ if (isPlainObject(definition)) {
17
+ definition = resolveMergedOptions({
18
+ extends: this,
19
+ name,
20
+ ...definition
21
+ })
22
+ }
23
+ components[name] = definition
45
24
  }
46
- }
47
- })
25
+ return components[name]
26
+ },
48
27
 
49
- DitoComponent.component = function(name, options) {
50
- if (options) {
51
- options = {
52
- name,
53
- ...options
54
- }
55
- const ctor = this.extend(options)
56
- components[name] = ctor
57
- return ctor
58
- } else {
59
- return components[name] || Vue.component(name)
28
+ methods: {
29
+ getTypeComponent
60
30
  }
61
31
  }
62
-
63
- export default DitoComponent
@@ -1,9 +1,12 @@
1
+ import { toRaw } from 'vue'
1
2
  import { isFunction } from '@ditojs/utils'
2
3
  import {
3
4
  getItemDataPath, getParentItemDataPath, getParentItem, getItem,
4
5
  getLastDataPathName, getLastDataPathIndex
5
6
  } from './utils/data.js'
6
7
 
8
+ const { hasOwnProperty } = Object.prototype
9
+
7
10
  // `DitoContext` instances are a thin wrapper around raw `context` objects,
8
11
  // which themselves actually inherit from the linked `component` instance, so
9
12
  // that they only need to provide the values that should be different than
@@ -14,10 +17,10 @@ import {
14
17
  const contexts = new WeakMap()
15
18
 
16
19
  function get(context, key, defaultValue) {
17
- const object = contexts.get(context)
20
+ const object = contexts.get(toRaw(context))
18
21
  const value = object[key]
19
22
  // If `object` explicitly sets the key to `undefined`, return it.
20
- return value !== undefined || object.hasOwnProperty(key)
23
+ return value !== undefined || hasOwnProperty.call(object, key)
21
24
  ? value
22
25
  : isFunction(defaultValue)
23
26
  ? defaultValue()
@@ -25,7 +28,7 @@ function get(context, key, defaultValue) {
25
28
  }
26
29
 
27
30
  function set(context, key, value) {
28
- contexts.get(context)[key] = value
31
+ contexts.get(toRaw(context))[key] = value
29
32
  }
30
33
 
31
34
  export default class DitoContext {
@@ -42,6 +45,7 @@ export default class DitoContext {
42
45
  // its values and still retrieve from it, and associate it with `this`
43
46
  // through `contexts` map:
44
47
  const object = Object.setPrototypeOf(context, component)
48
+ // No need for `toRaw(this)` here as it's always raw inside the constructor.
45
49
  contexts.set(this, object)
46
50
  }
47
51
 
@@ -6,7 +6,9 @@ import DitoComponent from './DitoComponent.js'
6
6
  import TypeMixin from './mixins/TypeMixin.js'
7
7
  import { registerTypeComponent, getTypeComponent } from './utils/schema.js'
8
8
 
9
- const TypeComponent = DitoComponent.extend({
9
+ // @vue/component
10
+ export default {
11
+ extends: DitoComponent,
10
12
  mixins: [TypeMixin],
11
13
 
12
14
  nativeField: false,
@@ -19,18 +21,18 @@ const TypeComponent = DitoComponent.extend({
19
21
  generateLabel: true,
20
22
  excludeValue: false,
21
23
  ignoreMissingValue: null,
22
- omitPadding: false
23
- })
24
+ omitPadding: false,
24
25
 
25
- TypeComponent.register = function(types, definition = {}) {
26
- types = asArray(types)
27
- const component = this.component(`dito-type-${types[0]}`, definition)
28
- for (const type of types) {
29
- registerTypeComponent(type, component)
30
- }
31
- return component
32
- }
26
+ component: DitoComponent.component,
33
27
 
34
- TypeComponent.get = getTypeComponent
28
+ get: getTypeComponent,
35
29
 
36
- export default TypeComponent
30
+ register(types, definition = {}) {
31
+ types = asArray(types)
32
+ const component = this.component(`dito-type-${types[0]}`, definition)
33
+ for (const type of types) {
34
+ registerTypeComponent(type, component)
35
+ }
36
+ return component
37
+ }
38
+ }
package/src/appState.js CHANGED
@@ -1,8 +1,10 @@
1
- export default {
1
+ import { reactive } from 'vue'
2
+
3
+ export default reactive({
2
4
  title: '',
3
5
  routeComponents: [],
4
6
  user: null,
5
7
  loadCache: {}, // See TypeMixin.load()
6
8
  activeLabel: null,
7
9
  clipboardData: null
8
- }
10
+ })
@@ -1,19 +1,19 @@
1
1
  <template lang="pug">
2
- .dito-account
3
- a(
4
- @mousedown.stop="onPulldownMouseDown()"
5
- )
6
- span {{ user.username }}
7
- ul.dito-pulldown(
8
- :class="{ 'dito-open': pulldown.open }"
2
+ .dito-account
3
+ a(
4
+ @mousedown.stop="onPulldownMouseDown()"
5
+ )
6
+ span {{ user.username }}
7
+ ul.dito-pulldown(
8
+ :class="{ 'dito-open': pulldown.open }"
9
+ )
10
+ li(
11
+ v-for="(label, value) of items"
9
12
  )
10
- li(
11
- v-for="(label, value) of items"
12
- )
13
- a(
14
- @mousedown.stop="onPulldownMouseDown(value)"
15
- @mouseup="onPulldownMouseUp(value)"
16
- ) {{ label }}
13
+ a(
14
+ @mousedown.stop="onPulldownMouseDown(value)"
15
+ @mouseup="onPulldownMouseUp(value)"
16
+ ) {{ label }}
17
17
  </template>
18
18
 
19
19
  <style lang="sass">
@@ -1,11 +1,11 @@
1
1
  <template lang="pug">
2
- .dito-buttons(
3
- v-if="buttonSchemas || $slots.default"
4
- /* Pass on $listeners so that dito-edit-buttons can pass events. */
5
- v-on="$listeners"
2
+ .dito-buttons(
3
+ v-if="buttonSchemas || hasSlotContent($slots.default)"
4
+ )
5
+ template(
6
+ v-for="(buttonSchema, buttonDataPath) in buttonSchemas"
6
7
  )
7
8
  dito-container(
8
- v-for="(buttonSchema, buttonDataPath) in buttonSchemas"
9
9
  v-if="shouldRender(buttonSchema)"
10
10
  :key="buttonDataPath"
11
11
  :schema="buttonSchema"
@@ -16,13 +16,15 @@
16
16
  :disabled="disabled"
17
17
  :generateLabels="false"
18
18
  )
19
- // Render each node in the default slot through `dito-vnode`, so it can be
20
- // wrapped in a `.dito-container` class.
19
+ template(
20
+ v-for="vnode of $slots.default?.()"
21
+ )
22
+ //- Render each node in the default slot through `dito-vnode`,
23
+ //- so it can be wrapped in a `.dito-container` class.
21
24
  .dito-container(
22
- v-for="node in $slots.default"
23
- v-if="node.tag"
25
+ v-if="hasVNodeContent(vnode)"
24
26
  )
25
- dito-vnode(:node="node")
27
+ dito-vnode(:vnode="vnode")
26
28
  </template>
27
29
 
28
30
  <style lang="sass">
@@ -34,6 +36,7 @@
34
36
  <script>
35
37
  import DitoComponent from '../DitoComponent.js'
36
38
  import { appendDataPath } from '../utils/data.js'
39
+ import { hasSlotContent, hasVNodeContent } from '../utils/vue.js'
37
40
 
38
41
  // @vue/component
39
42
  export default DitoComponent.component('dito-buttons', {
@@ -61,6 +64,11 @@ export default DitoComponent.component('dito-buttons', {
61
64
  }, {})
62
65
  : null
63
66
  }
67
+ },
68
+
69
+ methods: {
70
+ hasSlotContent,
71
+ hasVNodeContent
64
72
  }
65
73
  })
66
74
  </script>
@@ -1,20 +1,20 @@
1
1
  <template lang="pug">
2
- .dito-clipboard.dito-buttons.dito-buttons-round(
3
- v-if="clipboard"
2
+ .dito-clipboard.dito-buttons.dito-buttons-round(
3
+ v-if="clipboard"
4
+ )
5
+ button.dito-button.dito-button-copy(
6
+ type="button"
7
+ ref="copyData"
8
+ title="Copy Data"
9
+ :disabled="!copyEnabled"
10
+ @click="onCopy"
11
+ )
12
+ button.dito-button.dito-button-paste(
13
+ type="button"
14
+ title="Paste Data"
15
+ :disabled="!pasteEnabled"
16
+ @click="onPaste"
4
17
  )
5
- button.dito-button.dito-button-copy(
6
- type="button"
7
- ref="copyData"
8
- title="Copy Data"
9
- :disabled="!copyEnabled"
10
- @click="onCopy"
11
- )
12
- button.dito-button.dito-button-paste(
13
- type="button"
14
- title="Paste Data"
15
- :disabled="!pasteEnabled"
16
- @click="onPaste"
17
- )
18
18
  </template>
19
19
 
20
20
  <script>
@@ -131,7 +131,7 @@ export default DitoComponent.component('dito-clipboard', {
131
131
  try {
132
132
  const json = JSON.stringify(data, null, 2)
133
133
  await navigator.clipboard?.writeText?.(json)
134
- // See if we can activate the paste button, dependding on browsers:
134
+ // See if we can activate the paste button, depending on browsers:
135
135
  await this.checkClipboard()
136
136
  } catch (err) {
137
137
  console.error(err, err.name, err.message)
@@ -1,31 +1,31 @@
1
1
  <template lang="pug">
2
- .dito-container(
3
- v-show="componentVisible"
4
- :class="containerClass"
5
- :style="containerStyle"
2
+ .dito-container(
3
+ v-show="componentVisible"
4
+ :class="containerClass"
5
+ :style="containerStyle"
6
+ )
7
+ dito-label(
8
+ v-if="label"
9
+ :label="label"
10
+ :dataPath="labelDataPath"
11
+ :class="componentClass"
12
+ )
13
+ component.dito-component(
14
+ :is="typeComponent"
15
+ :schema="schema"
16
+ :dataPath="dataPath"
17
+ :data="data"
18
+ :meta="meta"
19
+ :store="store"
20
+ :single="single"
21
+ :nested="nested"
22
+ :disabled="componentDisabled"
23
+ :class="componentClass"
24
+ @errors="onErrors"
25
+ )
26
+ dito-errors(
27
+ :errors="errors"
6
28
  )
7
- dito-label(
8
- v-if="label"
9
- :label="label"
10
- :dataPath="labelDataPath"
11
- :class="componentClass"
12
- )
13
- component.dito-component(
14
- :is="getTypeComponent(schema.type)"
15
- :schema="schema"
16
- :dataPath="dataPath"
17
- :data="data"
18
- :meta="meta"
19
- :store="store"
20
- :single="single"
21
- :nested="nested"
22
- :disabled="componentDisabled"
23
- :class="componentClass"
24
- @errors="onErrors"
25
- )
26
- dito-errors(
27
- :errors="errors"
28
- )
29
29
  </template>
30
30
 
31
31
  <style lang="sass">
@@ -65,7 +65,7 @@ import { isString, isNumber } from '@ditojs/utils'
65
65
  import DitoComponent from '../DitoComponent.js'
66
66
  import DitoContext from '../DitoContext.js'
67
67
  import { getSchemaAccessor } from '../utils/accessor.js'
68
- import { getTypeOptions, shouldOmitPadding } from '../utils/schema.js'
68
+ import { getTypeComponent, shouldOmitPadding } from '../utils/schema.js'
69
69
  import { parseFraction } from '../utils/math.js'
70
70
 
71
71
  // @vue/component
@@ -93,8 +93,8 @@ export default DitoComponent.component('dito-container', {
93
93
  return new DitoContext(this, { nested: this.nested })
94
94
  },
95
95
 
96
- typeOptions() {
97
- return getTypeOptions(this.schema) || {}
96
+ typeComponent() {
97
+ return getTypeComponent(this.schema.type)
98
98
  },
99
99
 
100
100
  hasLabel() {
@@ -102,7 +102,7 @@ export default DitoComponent.component('dito-container', {
102
102
  const { label } = schema
103
103
  return (
104
104
  label !== false &&
105
- (!!label || this.typeOptions.generateLabel && this.generateLabels)
105
+ (!!label || this.typeComponent?.generateLabel && this.generateLabels)
106
106
  )
107
107
  },
108
108
 
@@ -118,7 +118,7 @@ export default DitoComponent.component('dito-container', {
118
118
  componentWidth: getSchemaAccessor('width', {
119
119
  type: [String, Number],
120
120
  default() {
121
- return this.typeOptions.defaultWidth
121
+ return this.typeComponent?.defaultWidth
122
122
  },
123
123
  get(width) {
124
124
  // Use 100% == 1.0 as default width when nothing is set:
@@ -142,7 +142,7 @@ export default DitoComponent.component('dito-container', {
142
142
  componentVisible: getSchemaAccessor('visible', {
143
143
  type: Boolean,
144
144
  default() {
145
- return this.typeOptions.defaultVisible
145
+ return this.typeComponent?.defaultVisible
146
146
  }
147
147
  }),
148
148