1
1
<template >
2
- <div
3
- :class =" [
4
- 'prefixed-input',
5
- { 'vertical-layout': valueType === 'object' || valueType === 'array' },
6
- ]"
7
- v-if =" control.visible"
8
- >
9
- <v-select
10
- v-if =" mixedRenderInfos && mixedRenderInfos.length > 1"
11
- :class =" ['prefix']"
12
- v-disabled-icon-focus
13
- :id =" control.id + '-input-selector'"
14
- :disabled =" !control.enabled"
15
- :label =" computedLabel"
16
- :required =" control.required"
17
- :error-messages =" control.errors"
18
- :items =" mixedRenderInfos"
19
- :clearable =" control.enabled"
20
- @update:model-value =" handleSelectChange"
21
- :item-title =" (item: SchemaRenderInfo) => t(item.label, item.label)"
22
- item-value =" index"
23
- v-model =" selectedIndex"
24
- v-bind =" vuetifyProps('v-select')"
25
- @focus =" handleFocus"
26
- @blur =" handleBlur"
27
- >
28
- </v-select >
29
- <dispatch-renderer
30
- :class =" ['input']"
31
- v-if =" schema && !(nullable && control.data === null)"
32
- :schema =" schema"
33
- :uischema =" uischema"
34
- :path =" path"
35
- :renderers =" control.renderers"
36
- :cells =" control.cells"
37
- :enabled =" control.enabled"
38
- >
39
- </dispatch-renderer >
2
+ <div :class =" ['prefixed-input']" v-if =" control.visible" >
3
+ <template v-if =" valueType === ' array' || valueType === ' object' " >
4
+ <v-expansion-panels accordion flat v-model =" currentlyExpanded" >
5
+ <v-expansion-panel >
6
+ <v-expansion-panel-title class =" py-0 px-0" >
7
+ <v-container class =" py-0" >
8
+ <v-row >
9
+ <v-col align-self =" center" class =" pl-0"
10
+ ><v-select
11
+ v-if =" mixedRenderInfos && mixedRenderInfos.length > 1"
12
+ v-disabled-icon-focus
13
+ :id =" control.id + '-input-selector'"
14
+ :disabled =" !control.enabled"
15
+ :label =" computedLabel"
16
+ :required =" control.required"
17
+ :error-messages =" control.errors"
18
+ :items =" mixedRenderInfos"
19
+ :clearable =" control.enabled"
20
+ @update:model-value =" handleSelectChange"
21
+ :item-title ="
22
+ (item: SchemaRenderInfo) => t(item.label, item.label)
23
+ "
24
+ item-value =" index"
25
+ v-model =" selectedIndex"
26
+ v-bind =" vuetifyProps('v-select')"
27
+ @click.stop
28
+ @focus =" handleFocus"
29
+ @blur =" handleBlur"
30
+ >
31
+ </v-select
32
+ ></v-col >
33
+ </v-row >
34
+ </v-container >
35
+ </v-expansion-panel-title >
36
+ <v-expansion-panel-text >
37
+ <dispatch-renderer
38
+ :class =" ['input']"
39
+ v-if =" schema && !(nullable && control.data === null)"
40
+ :schema =" schema"
41
+ :uischema =" uischema"
42
+ :path =" path"
43
+ :renderers =" control.renderers"
44
+ :cells =" control.cells"
45
+ :enabled =" control.enabled"
46
+ >
47
+ </dispatch-renderer >
48
+ </v-expansion-panel-text >
49
+ </v-expansion-panel >
50
+ </v-expansion-panels >
51
+ </template >
52
+ <template v-else >
53
+ <v-select
54
+ v-if =" mixedRenderInfos && mixedRenderInfos.length > 1"
55
+ v-disabled-icon-focus
56
+ :id =" control.id + '-input-selector'"
57
+ :disabled =" !control.enabled"
58
+ :label =" computedLabel"
59
+ :required =" control.required"
60
+ :error-messages =" control.errors"
61
+ :items =" mixedRenderInfos"
62
+ :clearable =" control.enabled"
63
+ @update:model-value =" handleSelectChange"
64
+ :item-title =" (item: SchemaRenderInfo) => t(item.label, item.label)"
65
+ item-value =" index"
66
+ v-model =" selectedIndex"
67
+ v-bind =" vuetifyProps('v-select')"
68
+ @focus =" handleFocus"
69
+ @blur =" handleBlur"
70
+ >
71
+ </v-select >
72
+ <dispatch-renderer
73
+ :class =" ['input']"
74
+ v-if =" schema && !(nullable && control.data === null)"
75
+ :schema =" schema"
76
+ :uischema =" uischema"
77
+ :path =" path"
78
+ :renderers =" control.renderers"
79
+ :cells =" control.cells"
80
+ :enabled =" control.enabled"
81
+ >
82
+ </dispatch-renderer >
83
+ </template >
40
84
</div >
41
85
</template >
42
86
@@ -56,11 +100,20 @@ import {
56
100
useJsonFormsControl ,
57
101
type RendererProps ,
58
102
} from ' @jsonforms/vue' ;
59
- import { computed , defineComponent , ref , watch } from ' vue' ;
60
- import { VSelect , VBtn } from ' vuetify/components' ;
103
+ import { computed , defineComponent , provide , ref , watch } from ' vue' ;
104
+ import {
105
+ VCol ,
106
+ VContainer ,
107
+ VExpansionPanel ,
108
+ VExpansionPanelText ,
109
+ VExpansionPanelTitle ,
110
+ VRow ,
111
+ VSelect ,
112
+ } from ' vuetify/components' ;
61
113
import { DisabledIconFocus } from ' ../controls' ;
62
114
import {
63
115
useCombinatorTranslations ,
116
+ UseDefaultValueKey ,
64
117
useIcons ,
65
118
useJsonForms ,
66
119
useTranslator ,
@@ -179,7 +232,7 @@ const createMixedRenderInfos = (
179
232
: false ;
180
233
} else if (schema .type === ' array' ) {
181
234
schema .items = schema .items ?? {};
182
- if (! (schema .items as any )) {
235
+ if (! (schema .items as any ). type ) {
183
236
(schema .items as any ).type = [
184
237
' array' ,
185
238
' boolean' ,
@@ -204,7 +257,10 @@ const createMixedRenderInfos = (
204
257
... control ,
205
258
options: { ... control .options , detail: detailsForSchema },
206
259
}
207
- : control ;
260
+ : {
261
+ ... control ,
262
+ scope: control .scope ,
263
+ };
208
264
209
265
return {
210
266
schema ,
@@ -244,8 +300,13 @@ const controlRenderer = defineComponent({
244
300
name: ' mixed-renderer' ,
245
301
components: {
246
302
DispatchRenderer ,
247
- VBtn ,
248
303
VSelect ,
304
+ VExpansionPanel ,
305
+ VExpansionPanelTitle ,
306
+ VExpansionPanelText ,
307
+ VContainer ,
308
+ VRow ,
309
+ VCol ,
249
310
},
250
311
directives: {
251
312
DisabledIconFocus ,
@@ -334,6 +395,10 @@ const controlRenderer = defineComponent({
334
395
: undefined ,
335
396
);
336
397
398
+ const currentlyExpanded = ref <number | null >(null );
399
+ // use the default value since all properties are dynamic so preserve the property key
400
+ provide (UseDefaultValueKey , true );
401
+
337
402
return {
338
403
... useCombinatorTranslations (useVuetifyControl (input )),
339
404
nullable ,
@@ -345,6 +410,7 @@ const controlRenderer = defineComponent({
345
410
uischema ,
346
411
path ,
347
412
icons ,
413
+ currentlyExpanded ,
348
414
};
349
415
},
350
416
methods: {
@@ -367,6 +433,8 @@ const controlRenderer = defineComponent({
367
433
? this .mixedRenderInfos [newIndex ]?.schema ?.type
368
434
: null ;
369
435
this .valueType = type as string | null; // we know that this should be either a string or null
436
+
437
+ this .currentlyExpanded = 0 ;
370
438
},
371
439
},
372
440
});
@@ -379,16 +447,12 @@ export default controlRenderer;
379
447
align-items : center ;
380
448
}
381
449
382
- .vertical-layout {
383
- flex-direction : column ;
384
- align-items : flex-start ;
385
- }
386
-
387
- .prefix {
388
- }
389
-
390
450
.input {
391
451
flex-grow : 1 ;
392
452
width : 100% ;
393
453
}
454
+
455
+ :deep(.v-expansion-panel-text__wrapper ) {
456
+ padding : 0px ;
457
+ }
394
458
</style >
0 commit comments