@ditojs/admin 2.0.4 → 2.1.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 (116) hide show
  1. package/dist/dito-admin.es.js +2065 -1969
  2. package/dist/dito-admin.umd.js +4 -4
  3. package/dist/style.css +1 -1
  4. package/package.json +32 -31
  5. package/src/DitoAdmin.js +66 -31
  6. package/src/DitoComponent.js +4 -1
  7. package/src/DitoContext.js +13 -5
  8. package/src/{TypeComponent.js → DitoTypeComponent.js} +8 -5
  9. package/src/components/DitoAccount.vue +20 -19
  10. package/src/components/DitoButtons.vue +14 -12
  11. package/src/components/DitoClipboard.vue +16 -8
  12. package/src/components/DitoContainer.vue +56 -43
  13. package/src/components/DitoCreateButton.vue +20 -15
  14. package/src/components/DitoDialog.vue +78 -53
  15. package/src/components/DitoEditButtons.vue +16 -14
  16. package/src/components/DitoElement.vue +2 -3
  17. package/src/components/DitoErrors.vue +18 -13
  18. package/src/components/DitoForm.vue +41 -24
  19. package/src/components/DitoFormNested.vue +12 -10
  20. package/src/components/DitoHeader.vue +103 -69
  21. package/src/components/DitoLabel.vue +108 -81
  22. package/src/components/DitoMenu.vue +52 -36
  23. package/src/components/DitoPagination.vue +9 -7
  24. package/src/components/DitoPane.vue +53 -45
  25. package/src/components/DitoPanel.vue +62 -42
  26. package/src/components/DitoPanels.vue +11 -10
  27. package/src/components/DitoRoot.vue +57 -46
  28. package/src/components/DitoSchema.vue +179 -131
  29. package/src/components/DitoSchemaInlined.vue +39 -28
  30. package/src/components/DitoScopes.vue +41 -31
  31. package/src/components/DitoSpinner.vue +31 -40
  32. package/src/components/DitoTableCell.vue +9 -9
  33. package/src/components/DitoTableHead.vue +52 -37
  34. package/src/components/DitoTabs.vue +39 -29
  35. package/src/components/DitoTreeItem.vue +140 -86
  36. package/src/components/DitoVNode.vue +1 -1
  37. package/src/components/DitoView.vue +13 -11
  38. package/src/mixins/DataMixin.js +11 -9
  39. package/src/mixins/DitoMixin.js +47 -25
  40. package/src/mixins/EmitterMixin.js +2 -1
  41. package/src/mixins/ItemMixin.js +15 -10
  42. package/src/mixins/LoadingMixin.js +2 -1
  43. package/src/mixins/NumberMixin.js +15 -10
  44. package/src/mixins/OptionsMixin.js +24 -12
  45. package/src/mixins/ResourceMixin.js +42 -34
  46. package/src/mixins/RouteMixin.js +8 -8
  47. package/src/mixins/SortableMixin.js +1 -1
  48. package/src/mixins/SourceMixin.js +68 -34
  49. package/src/mixins/TypeMixin.js +5 -4
  50. package/src/mixins/ValidationMixin.js +3 -0
  51. package/src/styles/_base.scss +17 -0
  52. package/src/styles/_button.scss +212 -0
  53. package/src/styles/_imports.scss +2 -0
  54. package/src/styles/_layout.scss +22 -0
  55. package/src/styles/_notifications.scss +54 -0
  56. package/src/styles/_pulldown.scss +39 -0
  57. package/src/styles/_scroll.scss +15 -0
  58. package/src/styles/_settings.scss +68 -0
  59. package/src/styles/_sortable.scss +13 -0
  60. package/src/styles/_table.scss +224 -0
  61. package/src/styles/style.scss +9 -0
  62. package/src/types/DitoTypeButton.vue +72 -0
  63. package/src/types/{TypeCheckbox.vue → DitoTypeCheckbox.vue} +12 -11
  64. package/src/types/{TypeCheckboxes.vue → DitoTypeCheckboxes.vue} +21 -15
  65. package/src/types/{TypeCode.vue → DitoTypeCode.vue} +46 -34
  66. package/src/types/{TypeColor.vue → DitoTypeColor.vue} +71 -52
  67. package/src/types/{TypeComponent.vue → DitoTypeComponent.vue} +2 -2
  68. package/src/types/DitoTypeComputed.vue +54 -0
  69. package/src/types/DitoTypeDate.vue +64 -0
  70. package/src/types/DitoTypeLabel.vue +23 -0
  71. package/src/types/{TypeList.vue → DitoTypeList.vue} +83 -61
  72. package/src/types/{TypeMarkup.vue → DitoTypeMarkup.vue} +172 -122
  73. package/src/types/DitoTypeMultiselect.vue +434 -0
  74. package/src/types/DitoTypeNumber.vue +46 -0
  75. package/src/types/{TypeObject.vue → DitoTypeObject.vue} +41 -26
  76. package/src/types/{TypePanel.vue → DitoTypePanel.vue} +2 -2
  77. package/src/types/{TypeProgress.vue → DitoTypeProgress.vue} +4 -6
  78. package/src/types/{TypeRadio.vue → DitoTypeRadio.vue} +17 -13
  79. package/src/types/{TypeSection.vue → DitoTypeSection.vue} +17 -17
  80. package/src/types/{TypeSelect.vue → DitoTypeSelect.vue} +39 -35
  81. package/src/types/{TypeSlider.vue → DitoTypeSlider.vue} +29 -23
  82. package/src/types/{TypeSwitch.vue → DitoTypeSwitch.vue} +15 -13
  83. package/src/types/DitoTypeText.vue +77 -0
  84. package/src/types/{TypeTextarea.vue → DitoTypeTextarea.vue} +17 -14
  85. package/src/types/DitoTypeTreeList.vue +191 -0
  86. package/src/types/{TypeUpload.vue → DitoTypeUpload.vue} +92 -65
  87. package/src/types/index.js +26 -26
  88. package/src/utils/SchemaGraph.js +21 -13
  89. package/src/utils/accessor.js +17 -9
  90. package/src/utils/data.js +4 -1
  91. package/src/utils/filter.js +8 -10
  92. package/src/utils/options.js +3 -3
  93. package/src/utils/resource.js +12 -10
  94. package/src/utils/schema.js +190 -125
  95. package/src/utils/type.js +31 -20
  96. package/src/validations/_decimals.js +1 -2
  97. package/types/index.d.ts +27 -23
  98. package/src/styles/_base.sass +0 -15
  99. package/src/styles/_button.sass +0 -127
  100. package/src/styles/_imports.sass +0 -2
  101. package/src/styles/_layout.sass +0 -13
  102. package/src/styles/_notifications.sass +0 -33
  103. package/src/styles/_pulldown.sass +0 -26
  104. package/src/styles/_scroll.sass +0 -13
  105. package/src/styles/_settings.sass +0 -55
  106. package/src/styles/_sortable.sass +0 -9
  107. package/src/styles/_table.sass +0 -153
  108. package/src/styles/style.sass +0 -10
  109. package/src/types/TypeButton.vue +0 -73
  110. package/src/types/TypeComputed.vue +0 -53
  111. package/src/types/TypeDate.vue +0 -64
  112. package/src/types/TypeLabel.vue +0 -19
  113. package/src/types/TypeMultiselect.vue +0 -376
  114. package/src/types/TypeNumber.vue +0 -44
  115. package/src/types/TypeText.vue +0 -67
  116. package/src/types/TypeTreeList.vue +0 -164
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ditojs/admin",
3
- "version": "2.0.4",
3
+ "version": "2.1.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",
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "./style.css": "./dist/style.css",
17
17
  "./src": "./src/index.js",
18
- "./imports.sass": "./src/styles/_imports.sass"
18
+ "./imports.scss": "./src/styles/_imports.scss"
19
19
  },
20
20
  "files": [
21
21
  "src/",
@@ -33,55 +33,56 @@
33
33
  "not ie_mob > 0"
34
34
  ],
35
35
  "dependencies": {
36
- "@ditojs/ui": "^2.0.4",
37
- "@ditojs/utils": "^2.0.1",
36
+ "@ditojs/ui": "^2.1.0",
37
+ "@ditojs/utils": "^2.1.0",
38
38
  "@kyvg/vue3-notification": "^2.9.0",
39
39
  "@lk77/vue3-color": "^3.0.6",
40
- "@tiptap/core": "^2.0.2",
41
- "@tiptap/extension-blockquote": "^2.0.2",
42
- "@tiptap/extension-bold": "^2.0.2",
43
- "@tiptap/extension-bullet-list": "^2.0.2",
44
- "@tiptap/extension-code": "^2.0.2",
45
- "@tiptap/extension-code-block": "^2.0.2",
46
- "@tiptap/extension-document": "^2.0.2",
47
- "@tiptap/extension-hard-break": "^2.0.2",
48
- "@tiptap/extension-heading": "^2.0.2",
49
- "@tiptap/extension-history": "^2.0.2",
50
- "@tiptap/extension-horizontal-rule": "^2.0.2",
51
- "@tiptap/extension-italic": "^2.0.2",
52
- "@tiptap/extension-link": "^2.0.2",
53
- "@tiptap/extension-list-item": "^2.0.2",
54
- "@tiptap/extension-ordered-list": "^2.0.2",
55
- "@tiptap/extension-paragraph": "^2.0.2",
56
- "@tiptap/extension-strike": "^2.0.2",
57
- "@tiptap/extension-text": "^2.0.2",
58
- "@tiptap/extension-underline": "^2.0.2",
59
- "@tiptap/pm": "^2.0.2",
60
- "@tiptap/vue-3": "^2.0.2",
61
- "@vueuse/integrations": "^10.0.0-beta.2",
40
+ "@tiptap/core": "^2.0.3",
41
+ "@tiptap/extension-blockquote": "^2.0.3",
42
+ "@tiptap/extension-bold": "^2.0.3",
43
+ "@tiptap/extension-bullet-list": "^2.0.3",
44
+ "@tiptap/extension-code": "^2.0.3",
45
+ "@tiptap/extension-code-block": "^2.0.3",
46
+ "@tiptap/extension-document": "^2.0.3",
47
+ "@tiptap/extension-hard-break": "^2.0.3",
48
+ "@tiptap/extension-heading": "^2.0.3",
49
+ "@tiptap/extension-history": "^2.0.3",
50
+ "@tiptap/extension-horizontal-rule": "^2.0.3",
51
+ "@tiptap/extension-italic": "^2.0.3",
52
+ "@tiptap/extension-link": "^2.0.3",
53
+ "@tiptap/extension-list-item": "^2.0.3",
54
+ "@tiptap/extension-ordered-list": "^2.0.3",
55
+ "@tiptap/extension-paragraph": "^2.0.3",
56
+ "@tiptap/extension-strike": "^2.0.3",
57
+ "@tiptap/extension-text": "^2.0.3",
58
+ "@tiptap/extension-underline": "^2.0.3",
59
+ "@tiptap/pm": "^2.0.3",
60
+ "@tiptap/vue-3": "^2.0.3",
61
+ "@vueuse/integrations": "^10.0.0-beta.4",
62
62
  "codeflask": "^1.4.1",
63
63
  "filesize": "^10.0.7",
64
64
  "filesize-parser": "^1.5.0",
65
+ "focus-trap": "^7.4.0",
65
66
  "nanoid": "^4.0.2",
66
67
  "sortablejs": "^1.15.0",
67
68
  "tinycolor2": "^1.6.0",
69
+ "type-fest": "^3.8.0",
68
70
  "vue": "^3.2.47",
69
71
  "vue-multiselect": "^3.0.0-beta.1",
70
72
  "vue-router": "^4.1.6",
71
73
  "vue-upload-component": "^3.1.8"
72
74
  },
73
75
  "devDependencies": {
74
- "@ditojs/build": "^2.0.0",
76
+ "@ditojs/build": "^2.1.0",
75
77
  "@vitejs/plugin-vue": "^4.1.0",
76
78
  "@vue/compiler-sfc": "^3.2.47",
77
79
  "pug": "^3.0.2",
78
- "sass": "1.60.0",
79
- "type-fest": "^3.7.2",
80
- "typescript": "^5.0.3",
80
+ "sass": "1.62.0",
81
+ "typescript": "^5.0.4",
81
82
  "vite": "^4.2.1"
82
83
  },
83
84
  "types": "types",
84
- "gitHead": "e2236a6758c7716a20f8e9fc7c7787521782d6d4",
85
+ "gitHead": "5c5048b661395268e720b9ec402d4301bb4a34aa",
85
86
  "scripts": {
86
87
  "build": "vite build",
87
88
  "watch": "yarn build --mode 'development' --watch",
package/src/DitoAdmin.js CHANGED
@@ -2,14 +2,19 @@ import { createApp, h as createElement } from 'vue'
2
2
  import { createRouter, createWebHistory } from 'vue-router'
3
3
  import VueNotifications from '@kyvg/vue3-notification'
4
4
  import {
5
- isString, isArray, asArray, isAbsoluteUrl,
6
- merge, hyphenate, camelize,
5
+ isString,
6
+ isArray,
7
+ asArray,
8
+ isAbsoluteUrl,
9
+ merge,
10
+ hyphenate,
11
+ camelize,
7
12
  defaultFormats
8
13
  } from '@ditojs/utils'
9
14
  import * as components from './components/index.js'
10
15
  import * as types from './types/index.js'
11
16
  import DitoRoot from './components/DitoRoot.vue'
12
- import TypeComponent from './TypeComponent.js'
17
+ import DitoTypeComponent from './DitoTypeComponent.js'
13
18
  import { getResource } from './utils/resource.js'
14
19
  import { deprecate } from './utils/deprecate.js'
15
20
  import verbs from './verbs.js'
@@ -40,6 +45,23 @@ export default class DitoAdmin {
40
45
  api.normalizePath ||= api.normalizePaths ? hyphenate : val => val
41
46
  api.denormalizePath ||= api.normalizePaths ? camelize : val => val
42
47
 
48
+ // Allow definition of defaults for admin component types, nested per type:
49
+ // api.defaults = {
50
+ // 'multiselect': {
51
+ // selectable: true
52
+ // },
53
+ // 'fake-type': schema => {
54
+ // // Return defaults, or directly modify the schema:
55
+ // Object.assign(schema, {
56
+ // type: 'real-type',
57
+ // format: ({ value }) => `Formatted ${value}`,
58
+ // process: ({ value }) => `Processed ${value}`
59
+ // })
60
+ // }
61
+ // }
62
+
63
+ api.defaults ||= {}
64
+
43
65
  // Allow the configuration of all auth resources, like so:
44
66
  // api.users = {
45
67
  // path: '/admins',
@@ -57,7 +79,7 @@ export default class DitoAdmin {
57
79
  // method: 'get'
58
80
  // }
59
81
  // }
60
- const users = api.users = getResource(api.users, {
82
+ const users = getResource(api.users, {
61
83
  type: 'collection'
62
84
  }) || {}
63
85
  users.login = getResource(users.login || 'login', {
@@ -72,6 +94,7 @@ export default class DitoAdmin {
72
94
  method: 'get',
73
95
  parent: users
74
96
  })
97
+ api.users = users
75
98
 
76
99
  // Allow overriding of resource path handlers:
77
100
  // api.resources = {
@@ -127,7 +150,7 @@ export default class DitoAdmin {
127
150
  el = document.querySelector(el)
128
151
  }
129
152
 
130
- const app = this.app = createApp({
153
+ const app = (this.app = createApp({
131
154
  components: {
132
155
  DitoRoot,
133
156
  VueNotifications,
@@ -162,13 +185,14 @@ export default class DitoAdmin {
162
185
  $tabComponent: () => null
163
186
  },
164
187
 
165
- render: () => createElement(DitoRoot, {
166
- ref: 'root',
167
- class: dito.settings.rootClass,
168
- unresolvedViews: views,
169
- options
170
- })
171
- })
188
+ render: () =>
189
+ createElement(DitoRoot, {
190
+ ref: 'root',
191
+ class: dito.settings.rootClass,
192
+ unresolvedViews: views,
193
+ options
194
+ })
195
+ }))
172
196
 
173
197
  app.use(VueNotifications, {
174
198
  name: 'notify',
@@ -177,32 +201,40 @@ export default class DitoAdmin {
177
201
 
178
202
  // root.component('vue-modal', VueModal)
179
203
 
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
- }))
204
+ app.use(
205
+ createRouter({
206
+ // Start with a catch-all route, to be replaced by the actual routes
207
+ // once the schemas are loaded, to prevent vue-router from complaining,
208
+ // see: `resolveViews()` in `DitoRoot` for the actual route setup.
209
+ routes: [
210
+ {
211
+ name: 'catch-all',
212
+ path: '/:_(.*)',
213
+ components: {}
214
+ }
215
+ ],
216
+ history: createWebHistory(dito.base),
217
+ linkActiveClass: '',
218
+ linkExactActiveClass: ''
219
+ })
220
+ )
193
221
 
194
222
  el.classList.add('dito-app')
195
223
  app.mount(el)
196
224
  }
197
225
 
198
226
  register(type, options) {
199
- return TypeComponent.register(type, options)
227
+ return DitoTypeComponent.register(type, options)
200
228
  }
201
229
  }
202
230
 
203
231
  class RequestError extends Error {
204
232
  constructor(response) {
205
- super(`Request failed with status code: ${response.status} (${response.statusText})`)
233
+ super(
234
+ `Request failed with status code: ${response.status} (${
235
+ response.statusText
236
+ })`
237
+ )
206
238
  this.response = response
207
239
  }
208
240
  }
@@ -218,7 +250,9 @@ async function request(api, {
218
250
  data = null
219
251
  }) {
220
252
  if (params) {
221
- deprecate(`request.params is deprecated. Use action.method and action.path instead.`)
253
+ deprecate(
254
+ `request.params is deprecated. Use action.method and action.path instead.`
255
+ )
222
256
  }
223
257
 
224
258
  const isApiUrl = api.isApiUrl(url)
@@ -230,9 +264,10 @@ async function request(api, {
230
264
  ...(isApiUrl && api.headers),
231
265
  ...headers
232
266
  },
233
- credentials: isApiUrl && api.cors?.credentials
234
- ? 'include'
235
- : 'same-origin'
267
+ credentials:
268
+ isApiUrl && api.cors?.credentials
269
+ ? 'include'
270
+ : 'same-origin'
236
271
  })
237
272
 
238
273
  if (response.headers.get('Content-Type')?.includes('application/json')) {
@@ -7,9 +7,9 @@ const components = {}
7
7
 
8
8
  // @vue/component
9
9
  export default {
10
+ mixins: [DitoMixin],
10
11
  // Make sure that registered components are present in all DitoComponent.
11
12
  components,
12
- mixins: [DitoMixin],
13
13
 
14
14
  component(name, definition) {
15
15
  if (definition) {
@@ -22,6 +22,9 @@ export default {
22
22
  }
23
23
  components[name] = definition
24
24
  }
25
+ if (!(name in components)) {
26
+ throw new Error(`Component "${name}" not registered`)
27
+ }
25
28
  return components[name]
26
29
  },
27
30
 
@@ -1,8 +1,12 @@
1
1
  import { toRaw } from 'vue'
2
2
  import { isFunction } from '@ditojs/utils'
3
3
  import {
4
- getItemDataPath, getParentItemDataPath, getParentItem, getItem,
5
- getLastDataPathName, getLastDataPathIndex
4
+ getItemDataPath,
5
+ getParentItemDataPath,
6
+ getParentItem,
7
+ getItem,
8
+ getLastDataPathName,
9
+ getLastDataPathIndex
6
10
  } from './utils/data.js'
7
11
 
8
12
  const { hasOwnProperty } = Object.prototype
@@ -35,7 +39,9 @@ export default class DitoContext {
35
39
  constructor(component, context) {
36
40
  // Use the provided params object / function, or create a new one:
37
41
  context = context
38
- ? (isFunction(context) ? context() : { ...context })
42
+ ? isFunction(context)
43
+ ? context()
44
+ : { ...context }
39
45
  : {}
40
46
  // If not explicitly set (to false), default to true so we don't fall back
41
47
  // to `component` for its value.
@@ -109,8 +115,10 @@ export default class DitoContext {
109
115
  // parent. If needed, we could expose this data here too, as we can do all
110
116
  // sorts of data processing with `rootData` and `dataPath`.
111
117
  get parentItem() {
112
- const parentItem =
113
- getParentItem(this.rootItem, this.dataPath, this.nested) || null
118
+ const parentItem = (
119
+ getParentItem(this.rootItem, this.dataPath, this.nested) ||
120
+ null
121
+ )
114
122
  return parentItem !== this.item ? parentItem : null
115
123
  }
116
124
 
@@ -1,7 +1,7 @@
1
- // TypeComponent is the abstract base component for all other type components
2
- // inside the types/ folder. There's also a separate concrete
3
- // `TypeComponent.vue` component, use to render the `type: 'component'` types.
4
- import { asArray } from '@ditojs/utils'
1
+ // DitoTypeComponent is the abstract base component for all other type
2
+ // components inside the types/ folder. There's also a separate concrete
3
+ // `DitoTypeComponent.vue` component, use to render `{ type: 'component' }`
4
+ import { asArray, camelize } from '@ditojs/utils'
5
5
  import DitoComponent from './DitoComponent.js'
6
6
  import TypeMixin from './mixins/TypeMixin.js'
7
7
  import { registerTypeComponent, getTypeComponent } from './utils/schema.js'
@@ -29,7 +29,10 @@ export default {
29
29
 
30
30
  register(types, definition = {}) {
31
31
  types = asArray(types)
32
- const component = this.component(`dito-type-${types[0]}`, definition)
32
+ const component = this.component(
33
+ `DitoType${camelize(types[0], true)}`,
34
+ definition
35
+ )
33
36
  for (const type of types) {
34
37
  registerTypeComponent(type, component)
35
38
  }
@@ -4,9 +4,7 @@
4
4
  @mousedown.stop="onPulldownMouseDown()"
5
5
  )
6
6
  span {{ user.username }}
7
- ul.dito-pulldown(
8
- :class="{ 'dito-open': pulldown.open }"
9
- )
7
+ ul.dito-pulldown(:class="{ 'dito-open': pulldown.open }")
10
8
  li(
11
9
  v-for="(label, value) of items"
12
10
  )
@@ -16,21 +14,12 @@
16
14
  ) {{ label }}
17
15
  </template>
18
16
 
19
- <style lang="sass">
20
- @import '../styles/_imports'
21
-
22
- .dito-account
23
- position: relative
24
- .dito-pulldown
25
- top: $pulldown-padding-ver
26
- </style>
27
-
28
17
  <script>
29
18
  import DitoComponent from '../DitoComponent.js'
30
19
  import PulldownMixin from '../mixins/PulldownMixin.js'
31
20
 
32
21
  // @vue/component
33
- export default DitoComponent.component('dito-account', {
22
+ export default DitoComponent.component('DitoAccount', {
34
23
  mixins: [PulldownMixin],
35
24
 
36
25
  data() {
@@ -45,14 +34,26 @@ export default DitoComponent.component('dito-account', {
45
34
  methods: {
46
35
  onPulldownSelect(value) {
47
36
  switch (value) {
48
- case 'logout':
49
- this.rootComponent.logout()
50
- break
51
- case 'settings':
52
- console.info('TODO: Implement Settings')
53
- break
37
+ case 'logout':
38
+ this.rootComponent.logout()
39
+ break
40
+ case 'settings':
41
+ console.info('TODO: Implement Settings')
42
+ break
54
43
  }
55
44
  }
56
45
  }
57
46
  })
58
47
  </script>
48
+
49
+ <style lang="scss">
50
+ @import '../styles/_imports';
51
+
52
+ .dito-account {
53
+ position: relative;
54
+
55
+ .dito-pulldown {
56
+ top: $pulldown-padding-ver;
57
+ }
58
+ }
59
+ </style>
@@ -5,7 +5,7 @@
5
5
  template(
6
6
  v-for="(buttonSchema, buttonDataPath) in buttonSchemas"
7
7
  )
8
- dito-container(
8
+ DitoContainer(
9
9
  v-if="shouldRender(buttonSchema)"
10
10
  :key="buttonDataPath"
11
11
  :schema="buttonSchema"
@@ -24,22 +24,16 @@
24
24
  .dito-container(
25
25
  v-if="hasVNodeContent(vnode)"
26
26
  )
27
- dito-vnode(:vnode="vnode")
27
+ DitoVnode(:vnode="vnode")
28
28
  </template>
29
29
 
30
- <style lang="sass">
31
- .dito-buttons
32
- > .dito-container
33
- padding: 0
34
- </style>
35
-
36
30
  <script>
37
31
  import DitoComponent from '../DitoComponent.js'
38
32
  import { appendDataPath } from '../utils/data.js'
39
33
  import { hasSlotContent, hasVNodeContent } from '../utils/vue.js'
40
34
 
41
35
  // @vue/component
42
- export default DitoComponent.component('dito-buttons', {
36
+ export default DitoComponent.component('DitoButtons', {
43
37
  provide: {
44
38
  $tabComponent: () => null
45
39
  },
@@ -59,9 +53,9 @@ export default DitoComponent.component('dito-buttons', {
59
53
  const { dataPath, buttons } = this
60
54
  return buttons
61
55
  ? Object.values(buttons).reduce((schemas, button) => {
62
- schemas[appendDataPath(dataPath, button.name)] = button
63
- return schemas
64
- }, {})
56
+ schemas[appendDataPath(dataPath, button.name)] = button
57
+ return schemas
58
+ }, {})
65
59
  : null
66
60
  }
67
61
  },
@@ -72,3 +66,11 @@ export default DitoComponent.component('dito-buttons', {
72
66
  }
73
67
  })
74
68
  </script>
69
+
70
+ <style lang="scss">
71
+ .dito-buttons {
72
+ > .dito-container {
73
+ padding: 0;
74
+ }
75
+ }
76
+ </style>
@@ -3,8 +3,8 @@
3
3
  v-if="clipboard"
4
4
  )
5
5
  button.dito-button.dito-button-copy(
6
- type="button"
7
6
  ref="copyData"
7
+ type="button"
8
8
  title="Copy Data"
9
9
  :disabled="!copyEnabled"
10
10
  @click="onCopy"
@@ -24,7 +24,7 @@ import DitoContext from '../DitoContext.js'
24
24
  import DomMixin from '../mixins/DomMixin.js'
25
25
 
26
26
  // @vue/component
27
- export default DitoComponent.component('dito-clipboard', {
27
+ export default DitoComponent.component('DitoClipboard', {
28
28
  mixins: [DomMixin],
29
29
 
30
30
  props: {
@@ -49,18 +49,26 @@ export default DitoComponent.component('dito-clipboard', {
49
49
  copyData() {
50
50
  const { copy } = this.clipboardOptions
51
51
  return copy
52
- ? clipboardData => copy.call(this, new DitoContext(this, {
53
- clipboardData
54
- }))
52
+ ? clipboardData =>
53
+ copy.call(
54
+ this,
55
+ new DitoContext(this, {
56
+ clipboardData
57
+ })
58
+ )
55
59
  : clipboardData => clone(clipboardData)
56
60
  },
57
61
 
58
62
  pasteData() {
59
63
  const { paste } = this.clipboardOptions
60
64
  return paste
61
- ? clipboardData => paste.call(this, new DitoContext(this, {
62
- clipboardData
63
- }))
65
+ ? clipboardData =>
66
+ paste.call(
67
+ this,
68
+ new DitoContext(this, {
69
+ clipboardData
70
+ })
71
+ )
64
72
  : clipboardData => clipboardData
65
73
  }
66
74
  },
@@ -4,7 +4,7 @@
4
4
  :class="containerClass"
5
5
  :style="containerStyle"
6
6
  )
7
- dito-label(
7
+ DitoLabel(
8
8
  v-if="label"
9
9
  :label="label"
10
10
  :dataPath="labelDataPath"
@@ -23,43 +23,9 @@
23
23
  :class="componentClass"
24
24
  @errors="onErrors"
25
25
  )
26
- dito-errors(
27
- :errors="errors"
28
- )
26
+ DitoErrors(:errors="errors")
29
27
  </template>
30
28
 
31
- <style lang="sass">
32
- @import '../styles/_imports'
33
-
34
- .dito-container
35
- // Needed for better vertical alignment:
36
- align-self: stretch
37
- box-sizing: border-box
38
- // To prevent list tables from blowing out of their flex box containers.
39
- max-width: 100%
40
- // Cannot use margin here as it needs to be part of box-sizing for
41
- // percentages in flex-basis to work.
42
- padding: $form-spacing $form-spacing-half
43
- &:empty
44
- padding: 0
45
- &.dito-omit-padding
46
- padding: 0
47
- > .dito-label
48
- margin: $form-spacing $form-spacing-half 0
49
- &.dito-single
50
- height: 100% // So that list buttons can be sticky at the bottom
51
- // NOTE: This is not nested inside `.dito-container` so that other
52
- // type components can override `.dito-width-fill` class (filter precedence).
53
- .dito-component
54
- &.dito-width-fill
55
- width: 100%
56
- &.dito-checkbox,
57
- &.dito-radio-button
58
- // WebKit doesn't like changed width on checkboxes and radios, override:
59
- display: inline-block
60
- width: auto
61
- </style>
62
-
63
29
  <script>
64
30
  import { isString, isNumber } from '@ditojs/utils'
65
31
  import DitoComponent from '../DitoComponent.js'
@@ -69,7 +35,7 @@ import { getTypeComponent, shouldOmitPadding } from '../utils/schema.js'
69
35
  import { parseFraction } from '../utils/math.js'
70
36
 
71
37
  // @vue/component
72
- export default DitoComponent.component('dito-container', {
38
+ export default DitoComponent.component('DitoContainer', {
73
39
  props: {
74
40
  schema: { type: Object, required: true },
75
41
  dataPath: { type: String, default: '' },
@@ -170,12 +136,13 @@ export default DitoComponent.component('dito-container', {
170
136
  componentBasis() {
171
137
  const width = this.componentWidth
172
138
  // 'auto' = no fitting:
173
- const basis = (
174
- [null, 'auto', 'fill'].includes(width) ? 'auto'
175
- : /%$/.test(width) ? parseFloat(width) // percentage
176
- : /[a-z]/.test(width) ? width // native units
177
- : parseFraction(width) * 100 // fraction
178
- )
139
+ const basis = [null, 'auto', 'fill'].includes(width)
140
+ ? 'auto'
141
+ : /%$/.test(width)
142
+ ? parseFloat(width) // percentage
143
+ : /[a-z]/.test(width)
144
+ ? width // native units
145
+ : parseFraction(width) * 100 // fraction
179
146
  return isNumber(basis) ? `${basis}%` : basis
180
147
  },
181
148
 
@@ -211,3 +178,49 @@ export default DitoComponent.component('dito-container', {
211
178
  }
212
179
  })
213
180
  </script>
181
+
182
+ <style lang="scss">
183
+ @import '../styles/_imports';
184
+
185
+ .dito-container {
186
+ // Needed for better vertical alignment:
187
+ align-self: stretch;
188
+ box-sizing: border-box;
189
+ // To prevent list tables from blowing out of their flex box containers.
190
+ max-width: 100%;
191
+ // Cannot use margin here as it needs to be part of box-sizing for
192
+ // percentages in flex-basis to work.
193
+ padding: $form-spacing $form-spacing-half;
194
+
195
+ &:empty {
196
+ padding: 0;
197
+ }
198
+
199
+ &.dito-omit-padding {
200
+ padding: 0;
201
+
202
+ > .dito-label {
203
+ margin: $form-spacing $form-spacing-half 0;
204
+ }
205
+ }
206
+
207
+ &.dito-single {
208
+ height: 100%; // So that list buttons can be sticky at the bottom;
209
+ }
210
+ }
211
+
212
+ // NOTE: This is not nested inside `.dito-container` so that other
213
+ // type components can override `.dito-width-fill` class (filter precedence).
214
+ .dito-component {
215
+ &.dito-width-fill {
216
+ width: 100%;
217
+
218
+ &.dito-checkbox,
219
+ &.dito-radio-button {
220
+ // WebKit doesn't like changed width on checkboxes and radios, override:
221
+ display: inline-block;
222
+ width: auto;
223
+ }
224
+ }
225
+ }
226
+ </style>