@ditojs/admin 2.5.2 → 2.6.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 (38) hide show
  1. package/dist/dito-admin.es.js +1222 -1204
  2. package/dist/dito-admin.umd.js +6 -6
  3. package/dist/style.css +1 -1
  4. package/package.json +4 -4
  5. package/src/DitoTypeComponent.js +0 -1
  6. package/src/components/DitoAccount.vue +1 -0
  7. package/src/components/DitoContainer.vue +15 -36
  8. package/src/components/DitoDialog.vue +3 -1
  9. package/src/components/DitoHeader.vue +11 -14
  10. package/src/components/DitoNavigation.vue +40 -0
  11. package/src/components/DitoPane.vue +64 -37
  12. package/src/components/DitoPanels.vue +3 -2
  13. package/src/components/DitoRoot.vue +37 -13
  14. package/src/components/DitoSchema.vue +21 -16
  15. package/src/components/DitoSchemaInlined.vue +1 -3
  16. package/src/components/DitoSidebar.vue +6 -24
  17. package/src/components/DitoView.vue +1 -0
  18. package/src/components/index.js +2 -1
  19. package/src/mixins/TextMixin.js +1 -1
  20. package/src/styles/_layout.scss +11 -14
  21. package/src/styles/_scroll.scss +1 -2
  22. package/src/styles/_settings.scss +5 -1
  23. package/src/styles/_tippy.scss +1 -0
  24. package/src/types/DitoTypeButton.vue +8 -17
  25. package/src/types/DitoTypeCode.vue +0 -1
  26. package/src/types/DitoTypeComponent.vue +0 -1
  27. package/src/types/DitoTypeLabel.vue +1 -2
  28. package/src/types/DitoTypeList.vue +0 -1
  29. package/src/types/DitoTypeMarkup.vue +14 -16
  30. package/src/types/DitoTypeMultiselect.vue +2 -0
  31. package/src/types/DitoTypeObject.vue +0 -2
  32. package/src/types/DitoTypePanel.vue +0 -1
  33. package/src/types/DitoTypeSection.vue +0 -1
  34. package/src/types/DitoTypeTextarea.vue +0 -1
  35. package/src/types/DitoTypeTreeList.vue +0 -2
  36. package/src/types/DitoTypeUpload.vue +0 -2
  37. package/src/utils/options.js +0 -1
  38. package/src/utils/schema.js +10 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ditojs/admin",
3
- "version": "2.5.2",
3
+ "version": "2.6.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,8 +33,8 @@
33
33
  "not ie_mob > 0"
34
34
  ],
35
35
  "dependencies": {
36
- "@ditojs/ui": "^2.5.2",
37
- "@ditojs/utils": "^2.5.0",
36
+ "@ditojs/ui": "^2.6.0",
37
+ "@ditojs/utils": "^2.6.0",
38
38
  "@kyvg/vue3-notification": "^2.9.0",
39
39
  "@lk77/vue3-color": "^3.0.6",
40
40
  "@tiptap/core": "^2.0.3",
@@ -83,7 +83,7 @@
83
83
  "vite": "^4.3.4"
84
84
  },
85
85
  "types": "types",
86
- "gitHead": "8c5737b77ba43617cd95ba65fbabcdc2941542a8",
86
+ "gitHead": "ce98ce03662c08e040ad7f9cb93cc0f48e11edb9",
87
87
  "scripts": {
88
88
  "build": "vite build",
89
89
  "watch": "yarn build --mode 'development' --watch",
@@ -21,7 +21,6 @@ export default {
21
21
  generateLabel: true,
22
22
  excludeValue: false,
23
23
  ignoreMissingValue: null,
24
- keepAligned: true,
25
24
  omitPadding: false,
26
25
 
27
26
  component: DitoComponent.component,
@@ -51,6 +51,7 @@ export default DitoComponent.component('DitoAccount', {
51
51
 
52
52
  .dito-account {
53
53
  position: relative;
54
+ display: inline-block;
54
55
 
55
56
  .dito-pulldown {
56
57
  top: $pulldown-padding-ver;
@@ -34,7 +34,7 @@ import { isString, isNumber } from '@ditojs/utils'
34
34
  import DitoComponent from '../DitoComponent.js'
35
35
  import DitoContext from '../DitoContext.js'
36
36
  import { getSchemaAccessor } from '../utils/accessor.js'
37
- import { getTypeComponent, keepAligned, omitPadding } from '../utils/schema.js'
37
+ import { getTypeComponent, hasLabel, omitPadding } from '../utils/schema.js'
38
38
  import { parseFraction } from '../utils/math.js'
39
39
 
40
40
  // @vue/component
@@ -49,8 +49,7 @@ export default DitoComponent.component('DitoContainer', {
49
49
  nested: { type: Boolean, default: true },
50
50
  disabled: { type: Boolean, required: true },
51
51
  generateLabels: { type: Boolean, default: false },
52
- firstInRow: { type: Boolean, default: false },
53
- lastInRow: { type: Boolean, default: false }
52
+ inLabeledRow: { type: Boolean, default: false }
54
53
  },
55
54
 
56
55
  data() {
@@ -69,13 +68,7 @@ export default DitoComponent.component('DitoContainer', {
69
68
  },
70
69
 
71
70
  hasLabel() {
72
- const { label } = this.schema
73
- return (
74
- label !== false && (
75
- !!label ||
76
- this.generateLabels && this.typeComponent?.generateLabel
77
- )
78
- )
71
+ return hasLabel(this.schema, this.generateLabels)
79
72
  },
80
73
 
81
74
  label() {
@@ -162,12 +155,8 @@ export default DitoComponent.component('DitoContainer', {
162
155
  const prefix = 'dito-container'
163
156
  return {
164
157
  [`${prefix}--single`]: this.single,
165
- [`${prefix}--has-label`]: this.hasLabel,
166
- [`${prefix}--aligned`]: keepAligned(this.schema),
158
+ [`${prefix}--labeled-row`]: this.inLabeledRow,
167
159
  [`${prefix}--omit-padding`]: omitPadding(this.schema),
168
- [`${prefix}--first-in-row`]: this.firstInRow,
169
- [`${prefix}--last-in-row`]: this.lastInRow,
170
- [`${prefix}--alone-in-row`]: this.firstInRow && this.lastInRow,
171
160
  ...(
172
161
  isString(containerClass)
173
162
  ? { [containerClass]: true }
@@ -214,8 +203,6 @@ export default DitoComponent.component('DitoContainer', {
214
203
  @import '../styles/_imports';
215
204
 
216
205
  .dito-container {
217
- $self: &;
218
-
219
206
  position: relative;
220
207
  display: flex;
221
208
  flex-flow: column;
@@ -229,6 +216,12 @@ export default DitoComponent.component('DitoContainer', {
229
216
  // percentages in flex-basis to work.
230
217
  padding: $form-spacing $form-spacing-half;
231
218
 
219
+ .dito-sidebar & {
220
+ @container (width < #{$sidebar-max-width - 2 * $content-padding}) {
221
+ flex-grow: 1 !important;
222
+ }
223
+ }
224
+
232
225
  &:empty {
233
226
  padding: 0;
234
227
  }
@@ -239,25 +232,11 @@ export default DitoComponent.component('DitoContainer', {
239
232
  padding: 0;
240
233
  }
241
234
 
242
- &--aligned {
243
- // For components with labels, align the label at the top and the component
244
- // at the bottom.
245
- --justify: space-between;
246
-
247
- &:has(> :only-child) {
248
- // But if there is no label, still align the component to the bottom.
249
- --justify: flex-end;
250
- }
251
-
252
- &:not(#{$self}--alone-in-row) {
253
- // Now only apply alignment if there are neighbouring components no the
254
- // same row that also align.
255
- // Look ahead:
256
- &:not(#{$self}--last-in-row) + #{&}:not(#{$self}--first-in-row),
257
- // Look behind:
258
- &:not(#{$self}--last-in-row):has(+ #{&}:not(#{$self}--first-in-row)) {
259
- justify-content: var(--justify);
260
- }
235
+ &--labeled-row {
236
+ // For components without labels in rows with other components that have
237
+ // labels, add some spacing to the top to align with the other components:
238
+ > .dito-component:first-child {
239
+ margin-top: $line-height * $font-size + $form-spacing-half;
261
240
  }
262
241
  }
263
242
 
@@ -147,7 +147,9 @@ export default DitoComponent.component('DitoDialog', {
147
147
  },
148
148
 
149
149
  cancel() {
150
- this.resolve(null)
150
+ // When cancelling, resolve as `undefined` so we can have dialogs
151
+ // returning null as a defined value as well.
152
+ this.resolve(undefined)
151
153
  },
152
154
 
153
155
  close() {
@@ -20,7 +20,7 @@ nav.dito-header
20
20
  v-if="isLoading"
21
21
  )
22
22
  //- Teleport target for `.dito-schema-header`:
23
- .dito-header__menu
23
+ .dito-title
24
24
  slot
25
25
  </template>
26
26
 
@@ -88,19 +88,27 @@ export default DitoComponent.component('DitoHeader', {
88
88
  display: inline-block;
89
89
  padding: $header-padding;
90
90
  color: $color-white;
91
+
92
+ &:empty {
93
+ &::after {
94
+ content: '\200b';
95
+ }
96
+ }
91
97
  }
92
98
 
93
99
  .dito-trail {
94
100
  display: flex;
95
101
  box-sizing: border-box;
96
102
  height: 3em;
97
- width: 100%;
98
- max-width: $content-width + $content-padding;
99
103
 
100
104
  ul {
101
105
  display: flex;
102
106
  }
103
107
 
108
+ li {
109
+ white-space: nowrap;
110
+ }
111
+
104
112
  a {
105
113
  position: relative;
106
114
  display: block;
@@ -152,16 +160,5 @@ export default DitoComponent.component('DitoHeader', {
152
160
  border-radius: 100%;
153
161
  }
154
162
  }
155
-
156
- .dito-account,
157
- .dito-login {
158
- position: absolute;
159
- top: 0;
160
- cursor: pointer;
161
- }
162
-
163
- .dito-account {
164
- left: $content-width + $content-padding * 2;
165
- }
166
163
  }
167
164
  </style>
@@ -0,0 +1,40 @@
1
+ <template lang="pug">
2
+ nav.dito-navigation.dito-scroll-parent
3
+ h1
4
+ RouterLink.dito-link(to="/") {{ appState.title }}
5
+ DitoMenu.dito-scroll(:items="views")
6
+ </template>
7
+
8
+ <script>
9
+ import DitoComponent from '../DitoComponent.js'
10
+
11
+ // @vue/component
12
+ export default DitoComponent.component('DitoNavigation', {})
13
+ </script>
14
+
15
+ <style lang="scss">
16
+ @import '../styles/_imports';
17
+
18
+ .dito-navigation {
19
+ @include user-select(none);
20
+
21
+ flex: 0 0 min-content;
22
+ font-size: $menu-font-size;
23
+ white-space: nowrap;
24
+ background: $color-lighter;
25
+
26
+ h1 {
27
+ display: block;
28
+ line-height: $header-line-height;
29
+ font-weight: bold;
30
+ background: $color-darker;
31
+ border-right: $border-width solid $color-darkest;
32
+ color: $color-white;
33
+
34
+ .dito-link {
35
+ display: block;
36
+ padding: $header-padding;
37
+ }
38
+ }
39
+ }
40
+ </style>
@@ -22,7 +22,7 @@
22
22
  DitoContainer(
23
23
  v-if="shouldRenderSchema(schema)"
24
24
  :key="nestedDataPath"
25
- v-resize="event => onResize(index, event)"
25
+ v-resize="event => onResizeContainer(index, event)"
26
26
  :schema="schema"
27
27
  :dataPath="dataPath"
28
28
  :data="data"
@@ -32,8 +32,7 @@
32
32
  :nested="nested"
33
33
  :disabled="disabled"
34
34
  :generateLabels="generateLabels"
35
- :firstInRow="schema.break === 'before' || isFirstInRow(index)"
36
- :lastInRow="schema.break === 'after' || isLastInRow(index)"
35
+ :inLabeledRow="isInLabeledRow(index)"
37
36
  )
38
37
  .dito-break(
39
38
  v-if="schema.break === 'after'"
@@ -43,7 +42,7 @@
43
42
  <script>
44
43
  import DitoComponent from '../DitoComponent.js'
45
44
  import { appendDataPath } from '../utils/data.js'
46
- import { getAllPanelEntries, isNested } from '../utils/schema.js'
45
+ import { getAllPanelEntries, hasLabel, isNested } from '../utils/schema.js'
47
46
 
48
47
  // @vue/component
49
48
  export default DitoComponent.component('DitoPane', {
@@ -124,6 +123,63 @@ export default DitoComponent.component('DitoPane', {
124
123
 
125
124
  isSingleComponent() {
126
125
  return this.single && this.componentSchemas.length === 1
126
+ },
127
+
128
+ labeledRowsByIndices() {
129
+ const { positions } = this
130
+
131
+ const isLastInRow = index => (
132
+ positions[index] !== null && (
133
+ index === positions.length - 1 ||
134
+ findNextPosition(index) > positions[index]
135
+ )
136
+ )
137
+
138
+ const findNextPosition = index => {
139
+ for (let i = index + 1; i < positions.length; i++) {
140
+ if (positions[i]) return positions[i]
141
+ }
142
+ return 0
143
+ }
144
+
145
+ const rows = []
146
+ let row = []
147
+ for (let index = 0; index < positions.length; index++) {
148
+ row.push(index)
149
+ if (isLastInRow(index)) {
150
+ rows.push(row)
151
+ row = []
152
+ }
153
+ }
154
+ if (row.length > 0) {
155
+ rows.push(row)
156
+ }
157
+
158
+ const labeledRowsByIndices = []
159
+
160
+ for (const row of rows) {
161
+ let hasLabelsInRow = false
162
+ for (const index of row) {
163
+ const { schema } = this.componentSchemas[index]
164
+ // TODO: Handle nested schemas, e.g. 'section' or 'object' and detect
165
+ // labels there too.
166
+ if (hasLabel(schema, this.generateLabels)) {
167
+ hasLabelsInRow = true
168
+ break
169
+ }
170
+ }
171
+ for (const index of row) {
172
+ labeledRowsByIndices[index] = hasLabelsInRow
173
+ }
174
+ }
175
+
176
+ return labeledRowsByIndices
177
+ }
178
+ },
179
+
180
+ watch: {
181
+ 'componentSchemas.length'(length) {
182
+ this.positions.length = length
127
183
  }
128
184
  },
129
185
 
@@ -146,48 +202,22 @@ export default DitoComponent.component('DitoPane', {
146
202
  }
147
203
  },
148
204
 
149
- onResize(index, { target }) {
205
+ onResizeContainer(index, { target }) {
150
206
  const { y, width, height } = target.getBoundingClientRect()
151
207
  this.positions[index] = width > 0 && height > 0 ? y : null
152
208
  },
153
209
 
154
- isFirstInRow(index) {
155
- const { positions } = this
156
- return (
157
- positions[index] !== null && (
158
- index === 0 ||
159
- (findNextPosition(positions, index, -1, Infinity) < positions[index])
160
- )
161
- )
162
- },
163
-
164
- isLastInRow(index) {
165
- const { positions } = this
166
- return (
167
- positions[index] !== null && (
168
- index === positions.length - 1 ||
169
- findNextPosition(positions, index, +1, 0) > positions[index]
170
- )
171
- )
210
+ isInLabeledRow(index) {
211
+ return this.labeledRowsByIndices[index]
172
212
  }
173
213
  }
174
214
  })
175
-
176
- function findNextPosition(positions, index, step, fallback) {
177
- for (let i = index + step; i >= 0 && i < positions.length; i += step) {
178
- const position = positions[i]
179
- if (position) return position
180
- }
181
- return fallback
182
- }
183
215
  </script>
184
216
 
185
217
  <style lang="scss">
186
218
  @import '../styles/_imports';
187
219
 
188
220
  .dito-pane {
189
- $max-width: $content-width + 2 * $content-padding;
190
-
191
221
  display: flex;
192
222
  position: relative;
193
223
  flex-flow: row wrap;
@@ -196,16 +226,13 @@ function findNextPosition(positions, index, step, fallback) {
196
226
  padding: $content-padding;
197
227
  // Remove the padding added by `.dito-container` inside `.dito-pane`:
198
228
  margin: (-$form-spacing) (-$form-spacing-half);
199
- // Add removed horizontal margin again to max-width:
200
- max-width: $max-width + 2 * $form-spacing-half;
201
229
  // Use `flex: 0%` for all `.dito-pane` except `.dito-pane-main`,
202
230
  // so that the `.dito-buttons-main` can be moved all the way to the bottom.
203
231
  flex: 0%;
204
232
 
205
233
  &--single {
206
- // Clear settings from above.
234
+ // Clear margin from above.
207
235
  margin: 0;
208
- max-width: $max-width;
209
236
  }
210
237
 
211
238
  &.dito-pane-main {
@@ -45,7 +45,8 @@ export default DitoComponent.component('DitoPanels', {
45
45
  @import '../styles/_imports';
46
46
 
47
47
  .dito-panels {
48
- max-width: $content-sidebar-width;
49
- min-width: calc($content-sidebar-width / 2);
48
+ padding: $content-padding;
49
+ // For the `@container` rule in `.dito-container` to work:
50
+ container-type: inline-size;
50
51
  }
51
52
  </style>
@@ -20,21 +20,25 @@
20
20
  :settings="dialog.settings"
21
21
  @remove="removeDialog(key)"
22
22
  )
23
- DitoSidebar
24
- main.dito-page.dito-scroll-parent
23
+ DitoNavigation
24
+ main.dito-page.dito-scroll-parent(:class="appState.pageClass")
25
25
  DitoHeader(
26
26
  :spinner="options.spinner"
27
27
  :isLoading="isLoading"
28
28
  )
29
- DitoAccount(
30
- v-if="user"
31
- )
32
- a.dito-login(
33
- v-else-if="allowLogin"
34
- @click="rootComponent.login()"
35
- )
36
- span Login
37
29
  RouterView
30
+ DitoSidebar
31
+ DitoAccount(
32
+ v-if="user"
33
+ )
34
+ a.dito-login(
35
+ v-else-if="allowLogin"
36
+ @click="rootComponent.login()"
37
+ )
38
+ span Login
39
+ .dito-fill
40
+ .dito-header
41
+ span
38
42
  </template>
39
43
 
40
44
  <script>
@@ -467,12 +471,32 @@ function addRoutes(router, routes) {
467
471
  display: flex;
468
472
  }
469
473
 
470
- .dito-root {
471
- .dito-page {
472
- background: $content-color-background;
474
+ .dito-page {
475
+ flex: 1 1 $content-width;
476
+ background: $content-color-background;
477
+ max-width: $content-width;
478
+
479
+ &--wide {
480
+ max-width: $content-width-wide;
481
+ }
482
+ }
483
+
484
+ .dito-fill {
485
+ flex: 1;
486
+
487
+ .dito-header {
488
+ span {
489
+ padding-left: 0;
490
+ padding-right: 0;
491
+ }
473
492
  }
474
493
  }
475
494
 
495
+ .dito-account,
496
+ .dito-login {
497
+ cursor: pointer;
498
+ }
499
+
476
500
  .dito-drag-overlay {
477
501
  position: fixed;
478
502
  top: 0;
@@ -8,7 +8,7 @@ slot(name="before")
8
8
  :class="{ 'dito-scroll': scrollable }"
9
9
  )
10
10
  Teleport(
11
- to=".dito-header__menu"
11
+ to=".dito-title"
12
12
  :disabled="!headerInMenu"
13
13
  )
14
14
  .dito-schema-header(
@@ -81,8 +81,9 @@ slot(name="before")
81
81
  v-if="!hasLabel"
82
82
  name="edit-buttons"
83
83
  )
84
- template(
84
+ Teleport(
85
85
  v-else-if="isPopulated"
86
+ to=".dito-sidebar"
86
87
  )
87
88
  DitoPanels(
88
89
  :class="{ 'dito-scroll': scrollable }"
@@ -116,7 +117,7 @@ import {
116
117
  processData,
117
118
  isForm
118
119
  } from '../utils/schema.js'
119
- import { getStoreAccessor } from '../utils/accessor.js'
120
+ import { getSchemaAccessor, getStoreAccessor } from '../utils/accessor.js'
120
121
 
121
122
  // @vue/component
122
123
  export default DitoComponent.component('DitoSchema', {
@@ -334,7 +335,12 @@ export default DitoComponent.component('DitoSchema', {
334
335
 
335
336
  panelsByDataPath() {
336
337
  return this._listEntriesByDataPath(this.panelsRegistry)
337
- }
338
+ },
339
+
340
+ wide: getSchemaAccessor('wide', {
341
+ type: Boolean,
342
+ default: false
343
+ })
338
344
  },
339
345
 
340
346
  watch: {
@@ -385,11 +391,17 @@ export default DitoComponent.component('DitoSchema', {
385
391
  // Delegate change events through to parent schema:
386
392
  this.delegate('change', this.parentSchemaComponent)
387
393
  this.emitEvent('initialize') // Not `'create'`, since that's for data.
394
+ if (this.scrollable && this.wide) {
395
+ this.appState.pageClass = 'dito-page--wide'
396
+ }
388
397
  },
389
398
 
390
399
  unmounted() {
391
400
  this.emitEvent('destroy')
392
401
  this._register(false)
402
+ if (this.scrollable && this.wide) {
403
+ this.appState.pageClass = null
404
+ }
393
405
  },
394
406
 
395
407
  methods: {
@@ -750,10 +762,11 @@ export default DitoComponent.component('DitoSchema', {
750
762
  min-height: 100%;
751
763
 
752
764
  > .dito-schema-content {
753
- flex: 1 1 100%;
765
+ flex: 0 1 100%;
766
+ max-width: 100%;
754
767
  // So that schema buttons can be sticky to the bottom:
755
- display: grid;
756
- grid-template-rows: min-content;
768
+ display: flex;
769
+ flex-direction: column;
757
770
 
758
771
  > *:only-child {
759
772
  grid-row-end: none;
@@ -763,12 +776,9 @@ export default DitoComponent.component('DitoSchema', {
763
776
  // Eat up negative margin of the last child to prevent overscroll.
764
777
  content: '';
765
778
  }
766
-
767
- max-width: $content-width + 2 * $content-padding;
768
779
  }
769
780
 
770
- > .dito-buttons,
771
- > .dito-panels {
781
+ > .dito-buttons {
772
782
  flex: 1 1 0%;
773
783
  }
774
784
 
@@ -776,10 +786,6 @@ export default DitoComponent.component('DitoSchema', {
776
786
  margin-left: $form-spacing;
777
787
  }
778
788
 
779
- > .dito-panels {
780
- padding: $content-padding $content-padding $content-padding 0;
781
- }
782
-
783
789
  // Display a ruler between tabbed components and towards the .dito-buttons
784
790
  .dito-pane-tab + .dito-pane-main {
785
791
  &::before {
@@ -824,7 +830,6 @@ export default DitoComponent.component('DitoSchema', {
824
830
  position: absolute;
825
831
  height: $header-height;
826
832
  padding: 0 $header-padding-hor;
827
- max-width: $content-width;
828
833
  top: 0;
829
834
  left: 0;
830
835
  right: 0;
@@ -82,11 +82,9 @@ export default DitoComponent.component('DitoSchemaInlined', {
82
82
  margin: 0;
83
83
  width: 100%;
84
84
  box-sizing: content-box;
85
- // Because tables have a funny way of allowing too much width growth:
86
- max-width: $content-width;
87
85
  // Prevent collapsing to min-height when alone in
88
86
  // .dito-schema-content, due to grid-template-rows: min-content
89
- min-height: 2em;
87
+ min-height: $input-height;
90
88
  }
91
89
  }
92
90
 
@@ -1,8 +1,7 @@
1
1
  <template lang="pug">
2
- nav.dito-sidebar.dito-scroll-parent
3
- h1
4
- RouterLink.dito-link(to="/") {{ appState.title }}
5
- DitoMenu.dito-scroll(:items="views")
2
+ aside.dito-sidebar.dito-scroll-parent
3
+ nav.dito-header
4
+ slot
6
5
  </template>
7
6
 
8
7
  <script>
@@ -16,25 +15,8 @@ export default DitoComponent.component('DitoSidebar', {})
16
15
  @import '../styles/_imports';
17
16
 
18
17
  .dito-sidebar {
19
- @include user-select(none);
20
-
21
- flex: initial;
22
- font-size: $menu-font-size;
23
- white-space: nowrap;
24
- background: $color-lighter;
25
-
26
- h1 {
27
- display: block;
28
- line-height: $header-line-height;
29
- font-weight: bold;
30
- background: $color-darker;
31
- border-right: $border-width solid $color-darkest;
32
- color: $color-white;
33
-
34
- .dito-link {
35
- display: block;
36
- padding: $header-padding;
37
- }
38
- }
18
+ flex: 0 4 $sidebar-max-width;
19
+ max-width: $sidebar-max-width;
20
+ min-width: $sidebar-min-width;
39
21
  }
40
22
  </style>
@@ -15,6 +15,7 @@ template(
15
15
  :data-resource="sourceSchema.path"
16
16
  )
17
17
  DitoSchema(
18
+ :key="name"
18
19
  :schema="viewSchema"
19
20
  :data="data"
20
21
  :meta="meta"
@@ -5,8 +5,9 @@
5
5
 
6
6
  export { default as DitoRoot } from './DitoRoot.vue'
7
7
  export { default as DitoMenu } from './DitoMenu.vue'
8
- export { default as DitoSidebar } from './DitoSidebar.vue'
9
8
  export { default as DitoHeader } from './DitoHeader.vue'
9
+ export { default as DitoNavigation } from './DitoNavigation.vue'
10
+ export { default as DitoSidebar } from './DitoSidebar.vue'
10
11
  export { default as DitoAccount } from './DitoAccount.vue'
11
12
  export { default as DitoDialog } from './DitoDialog.vue'
12
13
  export { default as DitoElement } from './DitoElement.vue'
@@ -10,6 +10,6 @@ export default {
10
10
  },
11
11
 
12
12
  processValue(schema, value) {
13
- return schema.trim ? value?.trim() : value
13
+ return schema.trim && value != null ? value.trim() : value
14
14
  }
15
15
  }