@koumoul/vjsf 3.0.0-alpha.0 → 3.0.0-alpha.10

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 (129) hide show
  1. package/package.json +37 -10
  2. package/src/compat/v2.js +45 -10
  3. package/src/compile/index.js +42 -9
  4. package/src/compile/options.js +19 -0
  5. package/src/compile/v-jsf-compiled.vue.ejs +35 -57
  6. package/src/components/fragments/help-message.vue +49 -0
  7. package/src/components/fragments/node-slot.vue +3 -3
  8. package/src/components/fragments/section-header.vue +6 -2
  9. package/src/components/fragments/select-item-icon.vue +28 -0
  10. package/src/components/fragments/select-item.vue +43 -0
  11. package/src/components/fragments/select-selection.vue +35 -0
  12. package/src/components/fragments/text-field-menu.vue +4 -4
  13. package/src/components/node.vue +35 -9
  14. package/src/components/nodes/autocomplete.vue +88 -0
  15. package/src/components/nodes/checkbox.vue +3 -3
  16. package/src/components/nodes/color-picker.vue +3 -3
  17. package/src/components/nodes/combobox.vue +72 -0
  18. package/src/components/nodes/date-picker.vue +5 -6
  19. package/src/components/nodes/date-time-picker.vue +2 -2
  20. package/src/components/nodes/expansion-panels.vue +4 -4
  21. package/src/components/nodes/file-input.vue +43 -0
  22. package/src/components/nodes/list.vue +177 -91
  23. package/src/components/nodes/number-combobox.vue +72 -0
  24. package/src/components/nodes/number-field.vue +4 -6
  25. package/src/components/nodes/one-of-select.vue +4 -4
  26. package/src/components/nodes/section.vue +4 -3
  27. package/src/components/nodes/select.vue +72 -53
  28. package/src/components/nodes/slider.vue +3 -3
  29. package/src/components/nodes/stepper.vue +96 -0
  30. package/src/components/nodes/switch.vue +3 -3
  31. package/src/components/nodes/tabs.vue +4 -4
  32. package/src/components/nodes/text-field.vue +10 -5
  33. package/src/components/nodes/textarea.vue +26 -6
  34. package/src/components/nodes/vertical-tabs.vue +4 -4
  35. package/src/components/options.js +27 -2
  36. package/src/components/tree.vue +4 -3
  37. package/src/components/vjsf.vue +41 -103
  38. package/src/composables/use-dnd.js +69 -0
  39. package/src/composables/use-vjsf.js +122 -0
  40. package/src/index.js +3 -1
  41. package/src/styles/vjsf.css +14 -0
  42. package/src/{components/types.ts → types.ts} +26 -1
  43. package/src/utils/arrays.js +15 -0
  44. package/src/utils/build.js +1 -0
  45. package/src/utils/global-register.js +13 -0
  46. package/src/utils/index.js +5 -0
  47. package/src/utils/props.js +29 -10
  48. package/src/utils/slots.js +2 -3
  49. package/types/compat/v2.d.ts.map +1 -1
  50. package/types/compile/index.d.ts +3 -2
  51. package/types/compile/index.d.ts.map +1 -1
  52. package/types/compile/options.d.ts +4 -0
  53. package/types/compile/options.d.ts.map +1 -0
  54. package/types/components/fragments/help-message.vue.d.ts +8 -0
  55. package/types/components/fragments/help-message.vue.d.ts.map +1 -0
  56. package/types/components/fragments/node-slot.vue.d.ts +9 -9
  57. package/types/components/fragments/node-slot.vue.d.ts.map +1 -1
  58. package/types/components/fragments/section-header.vue.d.ts +3 -3
  59. package/types/components/fragments/select-item-icon.vue.d.ts +15 -0
  60. package/types/components/fragments/select-item-icon.vue.d.ts.map +1 -0
  61. package/types/components/fragments/select-item.vue.d.ts +12 -0
  62. package/types/components/fragments/select-item.vue.d.ts.map +1 -0
  63. package/types/components/fragments/select-selection.vue.d.ts +12 -0
  64. package/types/components/fragments/select-selection.vue.d.ts.map +1 -0
  65. package/types/components/fragments/text-field-menu.vue.d.ts +5 -5
  66. package/types/components/fragments/text-field-menu.vue.d.ts.map +1 -1
  67. package/types/components/global-register.d.ts +8 -0
  68. package/types/components/global-register.d.ts.map +1 -0
  69. package/types/components/node.vue.d.ts +5 -5
  70. package/types/components/nodes/autocomplete.vue.d.ts +27 -0
  71. package/types/components/nodes/autocomplete.vue.d.ts.map +1 -0
  72. package/types/components/nodes/checkbox.vue.d.ts +5 -5
  73. package/types/components/nodes/color-picker.vue.d.ts +5 -5
  74. package/types/components/nodes/combobox.vue.d.ts +27 -0
  75. package/types/components/nodes/combobox.vue.d.ts.map +1 -0
  76. package/types/components/nodes/date-picker.vue.d.ts +5 -5
  77. package/types/components/nodes/date-time-picker.vue.d.ts +5 -5
  78. package/types/components/nodes/expansion-panels.vue.d.ts +5 -5
  79. package/types/components/nodes/file-input.vue.d.ts +27 -0
  80. package/types/components/nodes/file-input.vue.d.ts.map +1 -0
  81. package/types/components/nodes/list.vue.d.ts +5 -5
  82. package/types/components/nodes/markdown.vue.d.ts +27 -0
  83. package/types/components/nodes/markdown.vue.d.ts.map +1 -0
  84. package/types/components/nodes/number-combobox.vue.d.ts +27 -0
  85. package/types/components/nodes/number-combobox.vue.d.ts.map +1 -0
  86. package/types/components/nodes/number-field.vue.d.ts +9 -9
  87. package/types/components/nodes/number-field.vue.d.ts.map +1 -1
  88. package/types/components/nodes/one-of-select.vue.d.ts +5 -5
  89. package/types/components/nodes/section.vue.d.ts +5 -5
  90. package/types/components/nodes/select.vue.d.ts +25 -8
  91. package/types/components/nodes/select.vue.d.ts.map +1 -1
  92. package/types/components/nodes/slider.vue.d.ts +5 -5
  93. package/types/components/nodes/stepper.vue.d.ts +10 -0
  94. package/types/components/nodes/stepper.vue.d.ts.map +1 -0
  95. package/types/components/nodes/switch.vue.d.ts +5 -5
  96. package/types/components/nodes/tabs.vue.d.ts +5 -5
  97. package/types/components/nodes/text-field.vue.d.ts +9 -9
  98. package/types/components/nodes/text-field.vue.d.ts.map +1 -1
  99. package/types/components/nodes/textarea.vue.d.ts +9 -9
  100. package/types/components/nodes/textarea.vue.d.ts.map +1 -1
  101. package/types/components/nodes/time-picker.vue.d.ts +1 -1
  102. package/types/components/nodes/vertical-tabs.vue.d.ts +5 -5
  103. package/types/components/options.d.ts +3 -2
  104. package/types/components/options.d.ts.map +1 -1
  105. package/types/components/tree.vue.d.ts +3 -3
  106. package/types/components/types.d.ts +22 -2
  107. package/types/components/types.d.ts.map +1 -1
  108. package/types/components/vjsf.vue.d.ts +8 -6
  109. package/types/composables/use-dnd.d.ts +25 -0
  110. package/types/composables/use-dnd.d.ts.map +1 -0
  111. package/types/composables/use-vjsf.d.ts +16 -0
  112. package/types/composables/use-vjsf.d.ts.map +1 -0
  113. package/types/index.d.ts +3 -1
  114. package/types/index.d.ts.map +1 -1
  115. package/types/types.d.ts +96 -0
  116. package/types/types.d.ts.map +1 -0
  117. package/types/utils/arrays.d.ts +9 -0
  118. package/types/utils/arrays.d.ts.map +1 -0
  119. package/types/utils/build.d.ts +2 -0
  120. package/types/utils/build.d.ts.map +1 -0
  121. package/types/utils/global-register.d.ts +8 -0
  122. package/types/utils/global-register.d.ts.map +1 -0
  123. package/types/utils/index.d.ts +6 -0
  124. package/types/utils/index.d.ts.map +1 -0
  125. package/types/utils/props.d.ts +8 -5
  126. package/types/utils/props.d.ts.map +1 -1
  127. package/types/utils/slots.d.ts +3 -3
  128. package/types/utils/slots.d.ts.map +1 -1
  129. package/src/utils/clone.js +0 -3
@@ -1,30 +1,50 @@
1
1
  <script setup>
2
- import nodeSlot from './fragments/node-slot.vue'
2
+ import { computed } from 'vue'
3
+ import { useTheme } from 'vuetify'
4
+ import { VCol } from 'vuetify/components'
5
+ import NodeSlot from './fragments/node-slot.vue'
6
+ import HelpMessage from './fragments/help-message.vue'
3
7
 
4
- defineProps({
8
+ const props = defineProps({
5
9
  modelValue: {
6
- /** @type import('vue').PropType<import('./types.js').VjsfNode> */
10
+ /** @type import('vue').PropType<import('../types.js').VjsfNode> */
7
11
  type: Object,
8
12
  required: true
9
13
  },
10
14
  statefulLayout: {
11
- /** @type import('vue').PropType<import('@json-layout/core').StatefulLayout> */
15
+ /** @type import('vue').PropType<import('../types.js').VjsfStatefulLayout> */
12
16
  type: Object,
13
17
  required: true
14
18
  }
15
19
  })
16
20
 
17
- /** @type Record<import('./types.js').Density, string> */
21
+ /** @type Record<import('../types.js').Density, string> */
18
22
  const beforeAfterClasses = {
19
23
  compact: 'my-1',
20
24
  comfortable: 'my-2',
21
25
  default: 'my-3'
22
26
  }
27
+
28
+ const theme = useTheme()
29
+
30
+ const nodeClasses = computed(() => {
31
+ let classes = `vjsf-node vjsf-node-${props.modelValue.layout.comp} vjsf-density-${props.modelValue.options.density}`
32
+ if (props.modelValue.options.readOnly) classes += ' vjsf-readonly'
33
+ if (props.modelValue.options.summary) classes += ' vjsf-summary'
34
+ if (theme.current.value.dark) classes += ' vjsf-dark'
35
+ return classes
36
+ })
37
+
38
+ if (!props.statefulLayout.options.nodeComponents[props.modelValue.layout.comp]) {
39
+ console.error(`vjsf: missing component to render vjsf node "${props.modelValue.layout.comp}", maybe you forgot to register a component from a plugin ?`)
40
+ }
41
+
23
42
  </script>
24
43
 
25
44
  <template>
26
45
  <v-col
27
46
  :cols="modelValue.cols"
47
+ :class="nodeClasses"
28
48
  >
29
49
  <node-slot
30
50
  v-if="modelValue.layout.slots?.before"
@@ -32,9 +52,14 @@ const beforeAfterClasses = {
32
52
  :layout-slot="modelValue.layout.slots?.before"
33
53
  :node="modelValue"
34
54
  :stateful-layout="statefulLayout"
35
- :class="beforeAfterClasses[/** @type import('./types.js').VjsfOptions */(modelValue.options).density]"
55
+ :class="beforeAfterClasses[modelValue.options.density]"
36
56
  />
37
57
 
58
+ <help-message
59
+ v-if="modelValue.layout.help"
60
+ :node="modelValue"
61
+ :class="beforeAfterClasses[modelValue.options.density]"
62
+ />
38
63
  <node-slot
39
64
  v-if="modelValue.layout.slots?.component"
40
65
  key="component"
@@ -43,18 +68,19 @@ const beforeAfterClasses = {
43
68
  :stateful-layout="statefulLayout"
44
69
  />
45
70
  <component
46
- :is="`vjsf-node-${modelValue.layout.comp}`"
47
- v-else-if="modelValue.layout.comp !== 'none'"
71
+ :is="props.statefulLayout.options.nodeComponents[modelValue.layout.comp]"
72
+ v-else-if="modelValue.layout.comp !== 'none' "
48
73
  :model-value="modelValue"
49
74
  :stateful-layout="statefulLayout"
50
75
  />
76
+
51
77
  <node-slot
52
78
  v-if="modelValue.layout.slots?.after"
53
79
  key="after"
54
80
  :layout-slot="modelValue.layout.slots?.after"
55
81
  :node="modelValue"
56
82
  :stateful-layout="statefulLayout"
57
- :class="beforeAfterClasses[/** @type import('./types.js').VjsfOptions */(modelValue.options).density]"
83
+ :class="beforeAfterClasses[modelValue.options.density]"
58
84
  />
59
85
  </v-col>
60
86
  </template>
@@ -0,0 +1,88 @@
1
+ <script>
2
+ import { VAutocomplete } from 'vuetify/components'
3
+ import { defineComponent, computed, ref, shallowRef, h } from 'vue'
4
+ import { getInputProps, getCompSlots } from '../../utils/index.js'
5
+ import SelectItem from '../fragments/select-item.vue'
6
+ import SelectSelection from '../fragments/select-selection.vue'
7
+
8
+ export default defineComponent({
9
+ props: {
10
+ modelValue: {
11
+ /** @type import('vue').PropType<import('../../types.js').VjsfSelectNode> */
12
+ type: Object,
13
+ required: true
14
+ },
15
+ statefulLayout: {
16
+ /** @type import('vue').PropType<import('../../types.js').VjsfStatefulLayout> */
17
+ type: Object,
18
+ required: true
19
+ }
20
+ },
21
+ setup (props) {
22
+ /** @type import('vue').ShallowRef<import('@json-layout/vocabulary').SelectItems> */
23
+ const items = shallowRef([])
24
+ /** @type import('vue').Ref<boolean> */
25
+ const loading = ref(false)
26
+ /** @type import('vue').Ref<string> */
27
+ const search = ref('')
28
+
29
+ const fieldProps = computed(() => {
30
+ const fieldProps = getInputProps(props.modelValue, props.statefulLayout, ['multiple'])
31
+ if (props.modelValue.options.readOnly) fieldProps.menuProps = { modelValue: false }
32
+ fieldProps.noFilter = true
33
+ fieldProps['onUpdate:search'] = (/** @type string */searchValue) => {
34
+ search.value = searchValue
35
+ refresh()
36
+ }
37
+ fieldProps['onUpdate:menu'] = refresh
38
+ fieldProps.items = items.value
39
+ fieldProps.loading = loading.value
40
+ return fieldProps
41
+ })
42
+
43
+ /** @type import('@json-layout/core').StateTree | null */
44
+ let lastStateTree = null
45
+ /** @type Record<string, any> | null */
46
+ let lastContext = null
47
+ /** @type string */
48
+ let lastSearch = ''
49
+
50
+ const refresh = async () => {
51
+ if (props.statefulLayout.stateTree === lastStateTree && props.statefulLayout.options.context === lastContext && search.value === lastSearch) return
52
+ loading.value = true
53
+ items.value = await props.statefulLayout.getItems(props.modelValue, search.value)
54
+ lastStateTree = props.statefulLayout.stateTree
55
+ lastContext = props.statefulLayout.options.context ?? null
56
+ lastSearch = search.value
57
+ loading.value = false
58
+ }
59
+
60
+ if (!props.modelValue.layout.items) {
61
+ refresh()
62
+ }
63
+
64
+ const fieldSlots = computed(() => {
65
+ const slots = getCompSlots(props.modelValue, props.statefulLayout)
66
+ if (!slots.item) {
67
+ slots.item = (/** @type {any} */ context) => h(SelectItem, {
68
+ multiple: props.modelValue.layout.multiple,
69
+ itemProps: context.props,
70
+ item: context.item.raw
71
+ })
72
+ }
73
+ if (!slots.selection) {
74
+ slots.selection = (/** @type {any} */ context) => h(SelectSelection, {
75
+ multiple: props.modelValue.layout.multiple,
76
+ last: props.modelValue.layout.multiple && context.index === props.modelValue.data.length - 1,
77
+ item: context.item.raw
78
+ })
79
+ }
80
+ return slots
81
+ })
82
+
83
+ // @ts-ignore
84
+ return () => h(VAutocomplete, fieldProps.value, fieldSlots.value)
85
+ }
86
+ })
87
+
88
+ </script>
@@ -1,16 +1,16 @@
1
1
  <script setup>
2
2
  import { VCheckbox } from 'vuetify/components'
3
3
  import { computed } from 'vue'
4
- import { getInputProps } from '../../utils/props.js'
4
+ import { getInputProps } from '../../utils/index.js'
5
5
 
6
6
  const props = defineProps({
7
7
  modelValue: {
8
- /** @type import('vue').PropType<import('../types.js').VjsfCheckboxNode> */
8
+ /** @type import('vue').PropType<import('../../types.js').VjsfCheckboxNode> */
9
9
  type: Object,
10
10
  required: true
11
11
  },
12
12
  statefulLayout: {
13
- /** @type import('vue').PropType<import('@json-layout/core').StatefulLayout> */
13
+ /** @type import('vue').PropType<import('../../types.js').VjsfStatefulLayout> */
14
14
  type: Object,
15
15
  required: true
16
16
  }
@@ -2,16 +2,16 @@
2
2
  import TextFieldMenu from '../fragments/text-field-menu.vue'
3
3
  import { VColorPicker } from 'vuetify/components'
4
4
  import { computed } from 'vue'
5
- import { getCompProps } from '../../utils/props.js'
5
+ import { getCompProps } from '../../utils/index.js'
6
6
 
7
7
  const props = defineProps({
8
8
  modelValue: {
9
- /** @type import('vue').PropType<import('../types.js').VjsfColorPickerNode> */
9
+ /** @type import('vue').PropType<import('../../types.js').VjsfColorPickerNode> */
10
10
  type: Object,
11
11
  required: true
12
12
  },
13
13
  statefulLayout: {
14
- /** @type import('vue').PropType<import('@json-layout/core').StatefulLayout> */
14
+ /** @type import('vue').PropType<import('../../types.js').VjsfStatefulLayout> */
15
15
  type: Object,
16
16
  required: true
17
17
  }
@@ -0,0 +1,72 @@
1
+ <script>
2
+ import { defineComponent, h, computed, shallowRef, ref } from 'vue'
3
+ import { VCombobox } from 'vuetify/components'
4
+ import { getInputProps, getCompSlots } from '../../utils/index.js'
5
+
6
+ export default defineComponent({
7
+ props: {
8
+ modelValue: {
9
+ /** @type import('vue').PropType<import('../../types.js').VjsfComboboxNode> */
10
+ type: Object,
11
+ required: true
12
+ },
13
+ statefulLayout: {
14
+ /** @type import('vue').PropType<import('../../types.js').VjsfStatefulLayout> */
15
+ type: Object,
16
+ required: true
17
+ }
18
+ },
19
+ setup (props) {
20
+ /** @type import('vue').Ref<import('@json-layout/vocabulary').SelectItems> */
21
+ const items = shallowRef(props.modelValue.layout.items ?? [])
22
+ /** @type import('vue').Ref<boolean> */
23
+ const loading = ref(false)
24
+
25
+ /** @type import('@json-layout/core').StateTree | null */
26
+ let lastStateTree = null
27
+ /** @type Record<string, any> | null */
28
+ let lastContext = null
29
+
30
+ const hasItems = computed(() => {
31
+ return !!(props.modelValue.layout.items || props.modelValue.layout.getItems)
32
+ })
33
+
34
+ const refresh = async () => {
35
+ if (props.modelValue.layout.items) return
36
+ if (props.statefulLayout.stateTree === lastStateTree && props.statefulLayout.options.context === lastContext) return
37
+ lastStateTree = props.statefulLayout.stateTree
38
+ lastContext = props.statefulLayout.options.context ?? null
39
+ if (hasItems.value) {
40
+ loading.value = true
41
+ items.value = await props.statefulLayout.getItems(props.modelValue)
42
+ loading.value = false
43
+ }
44
+ }
45
+
46
+ if (!props.modelValue.layout.items) {
47
+ refresh()
48
+ }
49
+
50
+ const fieldProps = computed(() => {
51
+ const fieldProps = getInputProps(props.modelValue, props.statefulLayout)
52
+ fieldProps.loading = loading.value
53
+ fieldProps.returnObject = false
54
+ if (hasItems.value) fieldProps.items = items.value
55
+ if (props.modelValue.options.readOnly) fieldProps.menuProps = { modelValue: false }
56
+ if (props.modelValue.layout.multiple) {
57
+ fieldProps.multiple = true
58
+ fieldProps.chips = true
59
+ fieldProps.closableChips = true
60
+ }
61
+ fieldProps['onUpdate:menu'] = () => refresh()
62
+ return fieldProps
63
+ })
64
+
65
+ const fieldSlots = computed(() => getCompSlots(props.modelValue, props.statefulLayout))
66
+
67
+ // @ts-ignore
68
+ return () => h(VCombobox, fieldProps.value, fieldSlots.value)
69
+ }
70
+ })
71
+
72
+ </script>
@@ -1,19 +1,18 @@
1
1
  <script setup>
2
2
  import TextFieldMenu from '../fragments/text-field-menu.vue'
3
- import { VDatePicker } from 'vuetify/labs/VDatePicker'
4
- import { useDate } from 'vuetify/labs/date'
3
+ import { VDatePicker } from 'vuetify/components/VDatePicker'
4
+ import { useDate } from 'vuetify'
5
5
  import { computed } from 'vue'
6
- import { getCompProps } from '../../utils/props.js'
7
- import { getDateTimeParts } from '../../utils/dates.js'
6
+ import { getCompProps, getDateTimeParts } from '../../utils/index.js'
8
7
 
9
8
  const props = defineProps({
10
9
  modelValue: {
11
- /** @type import('vue').PropType<import('../types.js').VjsfDatePickerNode> */
10
+ /** @type import('vue').PropType<import('../../types.js').VjsfDatePickerNode> */
12
11
  type: Object,
13
12
  required: true
14
13
  },
15
14
  statefulLayout: {
16
- /** @type import('vue').PropType<import('@json-layout/core').StatefulLayout> */
15
+ /** @type import('vue').PropType<import('../../types.js').VjsfStatefulLayout> */
17
16
  type: Object,
18
17
  required: true
19
18
  }
@@ -2,12 +2,12 @@
2
2
 
3
3
  defineProps({
4
4
  modelValue: {
5
- /** @type import('vue').PropType<import('../types.js').VjsfDateTimePickerNode> */
5
+ /** @type import('vue').PropType<import('../../types.js').VjsfDateTimePickerNode> */
6
6
  type: Object,
7
7
  required: true
8
8
  },
9
9
  statefulLayout: {
10
- /** @type import('vue').PropType<import('@json-layout/core').StatefulLayout> */
10
+ /** @type import('vue').PropType<import('../../types.js').VjsfStatefulLayout> */
11
11
  type: Object,
12
12
  required: true
13
13
  }
@@ -1,17 +1,17 @@
1
1
  <script setup>
2
- import { VExpansionPanels, VExpansionPanel, VExpansionPanelTitle, VContainer } from 'vuetify/components'
2
+ import { VExpansionPanels, VExpansionPanel, VExpansionPanelTitle, VContainer, VRow, VIcon } from 'vuetify/components'
3
3
  import { isSection } from '@json-layout/core'
4
4
  import Node from '../node.vue'
5
5
  import SectionHeader from '../fragments/section-header.vue'
6
6
 
7
7
  defineProps({
8
8
  modelValue: {
9
- /** @type import('vue').PropType<import('../types.js').VjsfExpansionPanelsNode> */
9
+ /** @type import('vue').PropType<import('../../types.js').VjsfExpansionPanelsNode> */
10
10
  type: Object,
11
11
  required: true
12
12
  },
13
13
  statefulLayout: {
14
- /** @type import('vue').PropType<import('@json-layout/core').StatefulLayout> */
14
+ /** @type import('vue').PropType<import('../../types.js').VjsfStatefulLayout> */
15
15
  type: Object,
16
16
  required: true
17
17
  }
@@ -42,7 +42,7 @@ defineProps({
42
42
  <node
43
43
  v-for="grandChild of isSection(child) ? child.children : [child]"
44
44
  :key="grandChild.fullKey"
45
- :model-value="/** @type import('../types.js').VjsfNode */(grandChild)"
45
+ :model-value="/** @type import('../../types.js').VjsfNode */(grandChild)"
46
46
  :stateful-layout="statefulLayout"
47
47
  />
48
48
  </v-row>
@@ -0,0 +1,43 @@
1
+ <script>
2
+ import { defineComponent, h, computed } from 'vue'
3
+ import { VFileInput } from 'vuetify/components'
4
+ import { getInputProps, getCompSlots } from '../../utils/index.js'
5
+
6
+ export default defineComponent({
7
+ props: {
8
+ modelValue: {
9
+ /** @type import('vue').PropType<import('../../types.js').VjsfFileInputNode> */
10
+ type: Object,
11
+ required: true
12
+ },
13
+ statefulLayout: {
14
+ /** @type import('vue').PropType<import('../../types.js').VjsfStatefulLayout> */
15
+ type: Object,
16
+ required: true
17
+ }
18
+ },
19
+ setup (props) {
20
+ const fieldProps = computed(() => {
21
+ const fieldProps = getInputProps(props.modelValue, props.statefulLayout, ['placeholder', 'accept'])
22
+ if (props.modelValue.layout.multiple) {
23
+ fieldProps.multiple = true
24
+ } else {
25
+ fieldProps.modelValue = props.modelValue.data ? [props.modelValue.data] : props.modelValue.data
26
+ fieldProps['onUpdate:modelValue'] = (/** @type string */value) => props.statefulLayout.input(props.modelValue, Array.isArray(value) ? value[0] : value)
27
+ }
28
+ return fieldProps
29
+ })
30
+ const fieldSlots = computed(() => getCompSlots(props.modelValue, props.statefulLayout))
31
+
32
+ // @ts-ignore
33
+ return () => h(VFileInput, fieldProps.value, fieldSlots.value)
34
+ }
35
+ })
36
+
37
+ </script>
38
+
39
+ <style>
40
+ .vjsf-node-text-field.vjsf-readonly.vjsf-summary input {
41
+ text-overflow: ellipsis;
42
+ }
43
+ </style>