@radio-garden/ditojs-admin 2.85.2-0.5067ad799

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 (153) hide show
  1. package/README.md +180 -0
  2. package/dist/dito-admin.css +1 -0
  3. package/dist/dito-admin.es.js +12106 -0
  4. package/dist/dito-admin.umd.js +7 -0
  5. package/package.json +96 -0
  6. package/src/DitoAdmin.js +293 -0
  7. package/src/DitoComponent.js +34 -0
  8. package/src/DitoContext.js +318 -0
  9. package/src/DitoTypeComponent.js +42 -0
  10. package/src/DitoUser.js +12 -0
  11. package/src/appState.js +12 -0
  12. package/src/components/DitoAccount.vue +60 -0
  13. package/src/components/DitoAffix.vue +68 -0
  14. package/src/components/DitoAffixes.vue +200 -0
  15. package/src/components/DitoButtons.vue +80 -0
  16. package/src/components/DitoClipboard.vue +186 -0
  17. package/src/components/DitoContainer.vue +374 -0
  18. package/src/components/DitoCreateButton.vue +146 -0
  19. package/src/components/DitoDialog.vue +242 -0
  20. package/src/components/DitoDraggable.vue +117 -0
  21. package/src/components/DitoEditButtons.vue +135 -0
  22. package/src/components/DitoErrors.vue +83 -0
  23. package/src/components/DitoForm.vue +521 -0
  24. package/src/components/DitoFormInner.vue +26 -0
  25. package/src/components/DitoFormNested.vue +17 -0
  26. package/src/components/DitoHeader.vue +84 -0
  27. package/src/components/DitoLabel.vue +200 -0
  28. package/src/components/DitoMenu.vue +186 -0
  29. package/src/components/DitoNavigation.vue +40 -0
  30. package/src/components/DitoNotifications.vue +170 -0
  31. package/src/components/DitoPagination.vue +42 -0
  32. package/src/components/DitoPane.vue +334 -0
  33. package/src/components/DitoPanel.vue +256 -0
  34. package/src/components/DitoPanels.vue +61 -0
  35. package/src/components/DitoRoot.vue +524 -0
  36. package/src/components/DitoSchema.vue +846 -0
  37. package/src/components/DitoSchemaInlined.vue +97 -0
  38. package/src/components/DitoScopes.vue +76 -0
  39. package/src/components/DitoSidebar.vue +50 -0
  40. package/src/components/DitoSpinner.vue +95 -0
  41. package/src/components/DitoTableCell.vue +64 -0
  42. package/src/components/DitoTableHead.vue +121 -0
  43. package/src/components/DitoTabs.vue +103 -0
  44. package/src/components/DitoTrail.vue +124 -0
  45. package/src/components/DitoTreeItem.vue +420 -0
  46. package/src/components/DitoUploadFile.vue +199 -0
  47. package/src/components/DitoVNode.vue +14 -0
  48. package/src/components/DitoView.vue +143 -0
  49. package/src/components/index.js +42 -0
  50. package/src/directives/resize.js +83 -0
  51. package/src/index.js +1 -0
  52. package/src/mixins/ContextMixin.js +68 -0
  53. package/src/mixins/DataMixin.js +131 -0
  54. package/src/mixins/DitoMixin.js +591 -0
  55. package/src/mixins/DomMixin.js +29 -0
  56. package/src/mixins/EmitterMixin.js +158 -0
  57. package/src/mixins/ItemMixin.js +144 -0
  58. package/src/mixins/LoadingMixin.js +23 -0
  59. package/src/mixins/NumberMixin.js +118 -0
  60. package/src/mixins/OptionsMixin.js +304 -0
  61. package/src/mixins/PulldownMixin.js +63 -0
  62. package/src/mixins/ResourceMixin.js +398 -0
  63. package/src/mixins/RouteMixin.js +190 -0
  64. package/src/mixins/SchemaParentMixin.js +33 -0
  65. package/src/mixins/SortableMixin.js +49 -0
  66. package/src/mixins/SourceMixin.js +734 -0
  67. package/src/mixins/TextMixin.js +26 -0
  68. package/src/mixins/TypeMixin.js +280 -0
  69. package/src/mixins/ValidationMixin.js +119 -0
  70. package/src/mixins/ValidatorMixin.js +57 -0
  71. package/src/mixins/ValueMixin.js +31 -0
  72. package/src/styles/_base.scss +17 -0
  73. package/src/styles/_button.scss +191 -0
  74. package/src/styles/_imports.scss +3 -0
  75. package/src/styles/_info.scss +19 -0
  76. package/src/styles/_layout.scss +19 -0
  77. package/src/styles/_pulldown.scss +38 -0
  78. package/src/styles/_scroll.scss +13 -0
  79. package/src/styles/_settings.scss +88 -0
  80. package/src/styles/_table.scss +223 -0
  81. package/src/styles/_tippy.scss +45 -0
  82. package/src/styles/style.scss +9 -0
  83. package/src/types/DitoTypeButton.vue +143 -0
  84. package/src/types/DitoTypeCheckbox.vue +27 -0
  85. package/src/types/DitoTypeCheckboxes.vue +65 -0
  86. package/src/types/DitoTypeCode.vue +199 -0
  87. package/src/types/DitoTypeColor.vue +272 -0
  88. package/src/types/DitoTypeComponent.vue +31 -0
  89. package/src/types/DitoTypeComputed.vue +50 -0
  90. package/src/types/DitoTypeDate.vue +99 -0
  91. package/src/types/DitoTypeLabel.vue +23 -0
  92. package/src/types/DitoTypeList.vue +364 -0
  93. package/src/types/DitoTypeMarkup.vue +700 -0
  94. package/src/types/DitoTypeMultiselect.vue +522 -0
  95. package/src/types/DitoTypeNumber.vue +66 -0
  96. package/src/types/DitoTypeObject.vue +136 -0
  97. package/src/types/DitoTypePanel.vue +18 -0
  98. package/src/types/DitoTypeProgress.vue +40 -0
  99. package/src/types/DitoTypeRadio.vue +45 -0
  100. package/src/types/DitoTypeSection.vue +80 -0
  101. package/src/types/DitoTypeSelect.vue +133 -0
  102. package/src/types/DitoTypeSlider.vue +66 -0
  103. package/src/types/DitoTypeSpacer.vue +11 -0
  104. package/src/types/DitoTypeSwitch.vue +40 -0
  105. package/src/types/DitoTypeText.vue +101 -0
  106. package/src/types/DitoTypeTextarea.vue +48 -0
  107. package/src/types/DitoTypeTreeList.vue +193 -0
  108. package/src/types/DitoTypeUpload.vue +503 -0
  109. package/src/types/index.js +30 -0
  110. package/src/utils/SchemaGraph.js +147 -0
  111. package/src/utils/accessor.js +75 -0
  112. package/src/utils/agent.js +47 -0
  113. package/src/utils/data.js +92 -0
  114. package/src/utils/filter.js +266 -0
  115. package/src/utils/math.js +14 -0
  116. package/src/utils/options.js +48 -0
  117. package/src/utils/path.js +5 -0
  118. package/src/utils/resource.js +44 -0
  119. package/src/utils/route.js +53 -0
  120. package/src/utils/schema.js +1121 -0
  121. package/src/utils/type.js +81 -0
  122. package/src/utils/uid.js +15 -0
  123. package/src/utils/units.js +5 -0
  124. package/src/validators/_creditcard.js +6 -0
  125. package/src/validators/_decimals.js +11 -0
  126. package/src/validators/_domain.js +6 -0
  127. package/src/validators/_email.js +6 -0
  128. package/src/validators/_hostname.js +6 -0
  129. package/src/validators/_integer.js +6 -0
  130. package/src/validators/_max.js +6 -0
  131. package/src/validators/_min.js +6 -0
  132. package/src/validators/_password.js +5 -0
  133. package/src/validators/_range.js +6 -0
  134. package/src/validators/_required.js +9 -0
  135. package/src/validators/_url.js +6 -0
  136. package/src/validators/index.js +12 -0
  137. package/src/verbs.js +17 -0
  138. package/types/index.d.ts +3298 -0
  139. package/types/tests/admin.test-d.ts +27 -0
  140. package/types/tests/component-buttons.test-d.ts +44 -0
  141. package/types/tests/component-list.test-d.ts +159 -0
  142. package/types/tests/component-misc.test-d.ts +137 -0
  143. package/types/tests/component-object.test-d.ts +69 -0
  144. package/types/tests/component-section.test-d.ts +174 -0
  145. package/types/tests/component-select.test-d.ts +107 -0
  146. package/types/tests/components.test-d.ts +81 -0
  147. package/types/tests/context.test-d.ts +31 -0
  148. package/types/tests/fixtures.ts +24 -0
  149. package/types/tests/form.test-d.ts +109 -0
  150. package/types/tests/instance.test-d.ts +20 -0
  151. package/types/tests/schema-features.test-d.ts +402 -0
  152. package/types/tests/variance.test-d.ts +125 -0
  153. package/types/tests/view.test-d.ts +146 -0
@@ -0,0 +1,199 @@
1
+ <template lang="pug">
2
+ .dito-code(
3
+ :id="dataPath"
4
+ :style="style"
5
+ )
6
+ .dito-code__editor(ref="editor")
7
+ .dito-resize(
8
+ v-if="resizable"
9
+ @mousedown.stop.prevent="onDragResize"
10
+ )
11
+ </template>
12
+
13
+ <script>
14
+ import DitoTypeComponent from '../DitoTypeComponent.js'
15
+ import DomMixin from '../mixins/DomMixin.js'
16
+ import { getSchemaAccessor } from '../utils/accessor.js'
17
+ import CodeFlask from 'codeflask'
18
+
19
+ // @vue/component
20
+ export default DitoTypeComponent.register('code', {
21
+ mixins: [DomMixin],
22
+
23
+ data() {
24
+ return {
25
+ height: null
26
+ }
27
+ },
28
+
29
+ computed: {
30
+ lines: getSchemaAccessor('lines', {
31
+ type: Number,
32
+ default: 3
33
+ }),
34
+
35
+ language: getSchemaAccessor('language', {
36
+ type: String,
37
+ default: 'javascript'
38
+ }),
39
+
40
+ indentSize: getSchemaAccessor('indentSize', {
41
+ type: Number,
42
+ default: 2
43
+ }),
44
+
45
+ resizable: getSchemaAccessor('resizable', {
46
+ type: Boolean,
47
+ default: false
48
+ }),
49
+
50
+ style() {
51
+ return {
52
+ height: this.height || `calc(${this.lines}em * var(--line-height))`
53
+ }
54
+ }
55
+ },
56
+
57
+ mounted() {
58
+ const flask = new CodeFlask(this.$refs.editor, {
59
+ language: this.language,
60
+ indentSize: this.indentSize,
61
+ lineNumbers: false
62
+ })
63
+
64
+ let changed = false
65
+ let ignoreWatch = false
66
+ let ignoreUpdate = false
67
+
68
+ const onChange = () => {
69
+ if (!this.focused && changed) {
70
+ changed = false
71
+ this.onChange()
72
+ }
73
+ }
74
+
75
+ const onFocus = () => this.onFocus()
76
+
77
+ const onBlur = () => {
78
+ this.onBlur()
79
+ onChange()
80
+ }
81
+
82
+ this.domOn(this.$refs.editor.querySelector('textarea'), {
83
+ focus: onFocus,
84
+ blur: onBlur
85
+ })
86
+
87
+ const setCode = code => {
88
+ if (code !== flask.code) {
89
+ ignoreUpdate = true
90
+ flask.updateCode(code)
91
+ }
92
+ }
93
+
94
+ const setValue = value => {
95
+ if (value !== this.value) {
96
+ ignoreWatch = true
97
+ this.value = value
98
+ changed = true
99
+ onChange()
100
+ }
101
+ }
102
+
103
+ flask.onUpdate(value => {
104
+ if (ignoreUpdate) {
105
+ ignoreUpdate = false
106
+ } else {
107
+ setValue(value)
108
+ }
109
+ })
110
+
111
+ this.$watch('value', value => {
112
+ if (ignoreWatch) {
113
+ ignoreWatch = false
114
+ } else {
115
+ setCode(value || '')
116
+ }
117
+ })
118
+
119
+ this.$watch('language', language => {
120
+ flask.updateLanguage(language)
121
+ })
122
+
123
+ setCode(this.value || '')
124
+ },
125
+
126
+ methods: {
127
+ focusElement() {
128
+ this.$el.querySelector('textarea')?.focus()
129
+ },
130
+
131
+ blurElement() {
132
+ this.$el.querySelector('textarea')?.blur()
133
+ },
134
+
135
+ onDragResize(event) {
136
+ const getPoint = ({ clientX: x, clientY: y }) => ({ x, y })
137
+
138
+ let prevY = getPoint(event).y
139
+ let height = parseFloat(getComputedStyle(this.$el).height)
140
+
141
+ const mousemove = event => {
142
+ const { y } = getPoint(event)
143
+ height += y - prevY
144
+ prevY = y
145
+ this.height = `${Math.max(height, 0)}px`
146
+ }
147
+
148
+ const handlers = this.domOn(document, {
149
+ mousemove,
150
+
151
+ mouseup(event) {
152
+ mousemove(event)
153
+ handlers.remove()
154
+ }
155
+ })
156
+ }
157
+ }
158
+ })
159
+ </script>
160
+
161
+ <style lang="scss">
162
+ @import '../styles/_imports';
163
+
164
+ .dito-code {
165
+ @extend %input;
166
+
167
+ position: relative;
168
+ // For proper sizing of content along with :style="style" setting above,
169
+ // for proper line-height calculation.
170
+ padding: $input-padding;
171
+ min-height: calc(1em * var(--line-height) + 2 * $input-padding-ver);
172
+
173
+ .codeflask {
174
+ background: none;
175
+ // Ignore the parent padding defined above which is only needed to set
176
+ // the desired height with :style="style".
177
+ top: 0;
178
+ left: 0;
179
+
180
+ &__textarea,
181
+ &__pre {
182
+ // Use same padding as .dito-code
183
+ padding: $input-padding;
184
+ }
185
+
186
+ &__textarea,
187
+ &__code,
188
+ &__lines {
189
+ font-family: $font-family-mono;
190
+ font-size: var(--font-size);
191
+ line-height: var(--line-height);
192
+ }
193
+
194
+ &__lines {
195
+ padding: $input-padding;
196
+ }
197
+ }
198
+ }
199
+ </style>
@@ -0,0 +1,272 @@
1
+ <template lang="pug">
2
+ DitoTrigger.dito-color(
3
+ v-model:show="showPopup"
4
+ trigger="focus"
5
+ )
6
+ template(#trigger)
7
+ DitoInput(
8
+ :id="dataPath"
9
+ ref="element"
10
+ v-model="hexValue"
11
+ type="input"
12
+ size="8"
13
+ :focused="showPopup"
14
+ v-bind="attributes"
15
+ )
16
+ template(#prefix)
17
+ DitoAffixes(
18
+ :items="schema.prefix"
19
+ position="prefix"
20
+ mode="input"
21
+ :disabled="disabled"
22
+ :parentContext="context"
23
+ )
24
+ template(#suffix)
25
+ DitoAffixes(
26
+ :items="schema.suffix"
27
+ position="suffix"
28
+ mode="input"
29
+ :clearable="showClearButton"
30
+ :disabled="disabled"
31
+ :inlineInfo="inlineInfo"
32
+ :parentContext="context"
33
+ @clear="clear"
34
+ )
35
+ template(#append)
36
+ .dito-color__preview(
37
+ v-if="value"
38
+ )
39
+ div(:style="{ background: `#${hexValue || '00000000'}` }")
40
+ template(#popup)
41
+ SketchPicker.dito-color__picker(
42
+ v-model="colorValue"
43
+ :disableAlpha="!alpha"
44
+ :disableFields="!inputs"
45
+ :presetColors="presets"
46
+ )
47
+ </template>
48
+
49
+ <script>
50
+ import tinycolor from 'tinycolor2'
51
+ import { Sketch as SketchPicker } from '@lk77/vue3-color'
52
+ import { isObject, isString } from '@ditojs/utils'
53
+ import { DitoTrigger, DitoInput } from '@ditojs/ui/src'
54
+ import DitoTypeComponent from '../DitoTypeComponent.js'
55
+ import DitoAffixes from '../components/DitoAffixes.vue'
56
+ import { getSchemaAccessor } from '../utils/accessor.js'
57
+
58
+ // Monkey-patch the `SketchPicker's` `hex` computed property to return lowercase
59
+ // hex values instead of uppercase ones.
60
+ const { hex } = SketchPicker.computed
61
+ SketchPicker.computed.hex = function () {
62
+ return hex.call(this).toLowerCase()
63
+ }
64
+
65
+ // @vue/component
66
+ export default DitoTypeComponent.register('color', {
67
+ components: { DitoTrigger, DitoInput, DitoAffixes, SketchPicker },
68
+
69
+ data() {
70
+ return {
71
+ showPopup: false,
72
+ convertedValue: null
73
+ }
74
+ },
75
+
76
+ computed: {
77
+ canUpdateValue() {
78
+ return !this.focused || this.readonly
79
+ },
80
+
81
+ colorValue: {
82
+ get() {
83
+ return (
84
+ this.convertedValue ||
85
+ this.value ||
86
+ (this.colorFormat === 'hex' ? '' : {})
87
+ )
88
+ },
89
+
90
+ set(value) {
91
+ this.value = convertColor(value, this.colorFormat)
92
+ }
93
+ },
94
+
95
+ hexValue: {
96
+ get() {
97
+ const color = tinycolor(this.value)
98
+ return color.isValid()
99
+ ? color
100
+ .toString(color.getAlpha() < 1 ? 'hex8' : 'hex6')
101
+ .slice(1)
102
+ .toLowerCase()
103
+ : null
104
+ },
105
+
106
+ set(value) {
107
+ const color = tinycolor(value)
108
+ if (color.isValid()) {
109
+ const convertedValue = convertColor(value, this.colorFormat)
110
+ if (this.canUpdateValue) {
111
+ this.value = convertedValue
112
+ } else {
113
+ // Store to change later, once `canUpdateValue` is true again.
114
+ // See `watch` below.
115
+ this.convertedValue = convertedValue
116
+ }
117
+ }
118
+ }
119
+ },
120
+
121
+ // TODO: `format` clashes with TypeMixin.format()`, which shall be renamed
122
+ // soon to `formatValue()`. Rename `colorFormat` back to `format` after.
123
+ colorFormat: getSchemaAccessor('format', {
124
+ type: String,
125
+ default: 'hex'
126
+ }),
127
+
128
+ // TODO: Rename to `showAlpha`?
129
+ alpha: getSchemaAccessor('alpha', {
130
+ type: Boolean,
131
+ default: false
132
+ }),
133
+
134
+ // TODO: Rename to `showInputs`?
135
+ inputs: getSchemaAccessor('inputs', {
136
+ type: Boolean,
137
+ default: true
138
+ }),
139
+
140
+ presets: getSchemaAccessor('presets', {
141
+ type: Array,
142
+ default: [
143
+ '#ffffff',
144
+ '#c3c3c3',
145
+ '#7f7f7f',
146
+ '#000000',
147
+ '#880015',
148
+ '#ed1c24',
149
+ '#ff7f27',
150
+ '#fff200',
151
+
152
+ '#22b14c',
153
+ '#00a2e8',
154
+ '#3f48cc',
155
+ '#a349a4',
156
+ '#b97a57',
157
+ '#ffaec9',
158
+ '#ffc90e',
159
+ '#00000000'
160
+ ]
161
+ })
162
+ },
163
+
164
+ watch: {
165
+ value: 'onChange',
166
+
167
+ canUpdateValue(canUpdateValue) {
168
+ if (canUpdateValue && this.convertedValue !== null) {
169
+ this.value = this.convertedValue
170
+ this.convertedValue = null
171
+ }
172
+ }
173
+ }
174
+ })
175
+
176
+ function convertColor(color, format) {
177
+ return isObject(color) // a vue3-color color object
178
+ ? toVue3ColorFormat(color, format)
179
+ : toTinyColorFormat(tinycolor(color), format)
180
+ }
181
+
182
+ function toVue3ColorFormat(color, format) {
183
+ const value =
184
+ color[
185
+ {
186
+ hex: color?.a < 1 ? 'hex8' : 'hex',
187
+ rgb: 'rgba'
188
+ }[format] ||
189
+ format
190
+ ]
191
+ return isString(value) && value[0] === '#' ? value.toLowerCase() : value
192
+ }
193
+
194
+ // This should really be in tinycolor, but it only has the string equivalent
195
+ // of it.
196
+ function toTinyColorFormat(color, format) {
197
+ switch (format) {
198
+ case 'rgb':
199
+ return color.toRgb()
200
+ case 'prgb':
201
+ return color.toPercentageRgb()
202
+ case 'name':
203
+ return color.toName()
204
+ case 'hsl':
205
+ return color.toHsl()
206
+ case 'hsv':
207
+ return color.toHsv()
208
+ case 'hex3':
209
+ return `#${color.toHex(true)}`
210
+ case 'hex4':
211
+ return `#${color.toHex8(true)}`
212
+ case 'hex8':
213
+ return `#${color.toHex8()}`
214
+ case 'hex':
215
+ case 'hex6':
216
+ default:
217
+ // Preserve alpha channel if present
218
+ return color.getAlpha() < 1
219
+ ? `#${color.toHex8()}`
220
+ : `#${color.toHex()}`
221
+ }
222
+ }
223
+ </script>
224
+
225
+ <style lang="scss">
226
+ @import '../styles/_imports';
227
+
228
+ $color-swatch-width: $pattern-transparency-size;
229
+ $color-swatch-radius: $border-radius - $border-width;
230
+
231
+ .dito-color {
232
+ .dito-input {
233
+ display: flex;
234
+ position: relative;
235
+
236
+ input {
237
+ box-sizing: border-box;
238
+ font-variant-numeric: tabular-nums;
239
+ padding-right: $color-swatch-width;
240
+ }
241
+ }
242
+
243
+ &__picker {
244
+ margin: $popup-margin;
245
+ border: $border-style;
246
+ border-radius: $border-radius;
247
+ background: $color-white;
248
+ box-shadow: $shadow-window;
249
+ }
250
+
251
+ &__preview {
252
+ background: $pattern-transparency;
253
+ margin: (-$input-padding-ver) (-$input-padding-hor);
254
+ margin-left: 0;
255
+ border-left: $border-style;
256
+
257
+ &,
258
+ div {
259
+ width: $color-swatch-width;
260
+ height: calc($input-height - 2 * $border-width);
261
+ border-top-right-radius: $color-swatch-radius;
262
+ border-bottom-right-radius: $color-swatch-radius;
263
+ }
264
+ }
265
+
266
+ // Inherit input focus state
267
+ .dito-input:focus-within &__preview,
268
+ .dito-input--focus &__preview {
269
+ border-left-color: $color-active;
270
+ }
271
+ }
272
+ </style>
@@ -0,0 +1,31 @@
1
+ <template lang="pug">
2
+ component(
3
+ :is="schema.component"
4
+ v-bind="$props"
5
+ )
6
+ </template>
7
+
8
+ <script>
9
+ // This is the general purpose 'component' type, which can resolve to any custom
10
+ // component through `schema.component`, see `resolveSchemaComponent()`. This
11
+ // can be used to nest arbitrary vue components in schema:
12
+ // {
13
+ // type: 'component',
14
+ // component: import('./component')
15
+ // }
16
+
17
+ import DitoTypeComponent from '../DitoTypeComponent.js'
18
+ import { resolveSchemaComponent } from '../utils/schema.js'
19
+
20
+ // @vue/component
21
+ export default DitoTypeComponent.register('component', {
22
+ // Override the standard `defaultValue: null` to not set any data for custom
23
+ // components, unless they provide a default value.
24
+ defaultValue: () => undefined, // Callback to override `defaultValue: null`
25
+ ignoreMissingValue: ({ schema }) => !('default' in schema),
26
+
27
+ async processSchema(api, schema) {
28
+ await resolveSchemaComponent(schema)
29
+ }
30
+ })
31
+ </script>
@@ -0,0 +1,50 @@
1
+ <template lang="pug">
2
+ //- TODO: Find a better way to trigger evaluation of `value` that dose not
3
+ //- involve actually rendering it when the component is not visible.
4
+ input.dito-text.dito-input(
5
+ :id="dataPath"
6
+ ref="element"
7
+ :name="name"
8
+ type="text"
9
+ :value="value"
10
+ :disabled="disabled"
11
+ :readonly="true"
12
+ )
13
+ </template>
14
+
15
+ <script>
16
+ import DitoTypeComponent from '../DitoTypeComponent.js'
17
+ import ValueMixin from '../mixins/ValueMixin.js'
18
+ import DataMixin from '../mixins/DataMixin.js'
19
+
20
+ export default DitoTypeComponent.register(
21
+ ['computed', 'data', 'hidden'],
22
+ // @vue/component
23
+ {
24
+ mixins: [DataMixin],
25
+
26
+ defaultValue: () => undefined, // Callback to override `defaultValue: null`
27
+ defaultVisible: false,
28
+
29
+ computed: {
30
+ value: {
31
+ get() {
32
+ const { schema } = this
33
+ if (schema.data || schema.dataPath) {
34
+ const value = this.handleDataSchema(schema, 'value')
35
+ // TODO: Fix side-effects
36
+ // eslint-disable-next-line max-len
37
+ // eslint-disable-next-line vue/no-side-effects-in-computed-properties
38
+ this.data[this.name] = value
39
+ }
40
+ return ValueMixin.computed.value.get.call(this)
41
+ },
42
+
43
+ set(value) {
44
+ ValueMixin.computed.value.set.call(this, value)
45
+ }
46
+ }
47
+ }
48
+ }
49
+ )
50
+ </script>
@@ -0,0 +1,99 @@
1
+ <template lang="pug">
2
+ .dito-date
3
+ component(
4
+ :is="getComponent(type)"
5
+ :id="dataPath"
6
+ ref="element"
7
+ v-model="dateValue"
8
+ :locale="locale"
9
+ :format="formats"
10
+ v-bind="attributes"
11
+ )
12
+ template(#prefix)
13
+ DitoAffixes(
14
+ :items="schema.prefix"
15
+ position="prefix"
16
+ mode="input"
17
+ absolute
18
+ :disabled="disabled"
19
+ :parentContext="context"
20
+ )
21
+ template(#suffix)
22
+ DitoAffixes(
23
+ :items="schema.suffix"
24
+ position="suffix"
25
+ mode="input"
26
+ absolute
27
+ :clearable="showClearButton"
28
+ :disabled="disabled"
29
+ :inlineInfo="inlineInfo"
30
+ :parentContext="context"
31
+ @clear="clear"
32
+ )
33
+ </template>
34
+
35
+ <script>
36
+ import DitoTypeComponent from '../DitoTypeComponent.js'
37
+ import { getSchemaAccessor } from '../utils/accessor.js'
38
+ import DitoAffixes from '../components/DitoAffixes.vue'
39
+ import {
40
+ DitoDatePicker,
41
+ DitoTimePicker,
42
+ DitoDateTimePicker
43
+ } from '@ditojs/ui/src'
44
+ import { isDate, assignDeeply } from '@ditojs/utils'
45
+
46
+ export default DitoTypeComponent.register(
47
+ ['date', 'datetime', 'time'],
48
+ // @vue/component
49
+ {
50
+ components: { DitoAffixes },
51
+ // TODO: This is only here so we get placeholder added. Come up with a
52
+ // better way to support attributes per component (a list of actually
53
+ // supported attributes)
54
+ nativeField: true,
55
+ textField: true,
56
+
57
+ computed: {
58
+ dateValue: {
59
+ get() {
60
+ const { value } = this
61
+ return value ? new Date(value) : value
62
+ },
63
+
64
+ set(value) {
65
+ this.value = value
66
+ }
67
+ },
68
+
69
+ // TODO: Rename to `format`, once `schema.format()` was removed to
70
+ // `formatValue()`.
71
+ formats: getSchemaAccessor('formats', {
72
+ type: Object,
73
+ default: null,
74
+ get(formats) {
75
+ const { date, time } = assignDeeply({}, this.api.formats, formats)
76
+ return {
77
+ date: ['date', 'datetime'].includes(this.type) ? date : null,
78
+ time: ['time', 'datetime'].includes(this.type) ? time : null
79
+ }
80
+ }
81
+ })
82
+ },
83
+
84
+ methods: {
85
+ getComponent(type) {
86
+ return {
87
+ date: DitoDatePicker,
88
+ time: DitoTimePicker,
89
+ datetime: DitoDateTimePicker
90
+ }[type]
91
+ }
92
+ },
93
+
94
+ processValue({ value }) {
95
+ return isDate(value) ? value.toISOString() : value
96
+ }
97
+ }
98
+ )
99
+ </script>
@@ -0,0 +1,23 @@
1
+ <template lang="pug">
2
+ DitoLabel.dito-label-component(
3
+ :label="value"
4
+ :dataPath="dataPath"
5
+ )
6
+ </template>
7
+
8
+ <script>
9
+ import DitoTypeComponent from '../DitoTypeComponent.js'
10
+
11
+ // @vue/component
12
+ export default DitoTypeComponent.register('label', {
13
+ excludeValue: true,
14
+ generateLabel: false
15
+ })
16
+ </script>
17
+
18
+ <style lang="scss">
19
+ .dito-label-component {
20
+ display: flex;
21
+ height: 2em;
22
+ }
23
+ </style>