@koumoul/vjsf 3.0.0-beta.6 → 3.0.0-beta.8
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.
- package/package.json +2 -2
- package/src/compat/v2.js +6 -0
- package/src/components/fragments/text-field-menu.vue +1 -1
- package/src/components/nodes/color-picker.vue +2 -1
- package/src/components/nodes/date-picker.vue +1 -1
- package/src/components/nodes/expansion-panels.vue +22 -12
- package/src/components/nodes/list.vue +7 -1
- package/src/composables/use-vjsf.js +7 -7
- package/src/utils/build.js +1 -1
- package/src/utils/props.js +5 -7
- package/types/compat/v2.d.ts.map +1 -1
- package/types/utils/build.d.ts +1 -1
- package/types/utils/props.d.ts +1 -2
- package/types/utils/props.d.ts.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@koumoul/vjsf",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.8",
|
|
4
4
|
"description": "Generate forms for the vuetify UI library (vuejs) based on annotated JSON schemas.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "vitest",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"vuetify": "^3.4.9"
|
|
76
76
|
},
|
|
77
77
|
"dependencies": {
|
|
78
|
-
"@json-layout/core": "0.
|
|
78
|
+
"@json-layout/core": "0.13.0",
|
|
79
79
|
"@vueuse/core": "^10.5.0",
|
|
80
80
|
"debug": "^4.3.4",
|
|
81
81
|
"ejs": "^3.1.9"
|
package/src/compat/v2.js
CHANGED
|
@@ -11,6 +11,12 @@ const processFragment = (/** @type {import("ajv").SchemaObject} */schema) => {
|
|
|
11
11
|
/** @type import('@json-layout/vocabulary').PartialCompObject */
|
|
12
12
|
const layout = {}
|
|
13
13
|
|
|
14
|
+
if (schema.separator || schema['x-separator']) {
|
|
15
|
+
layout.separator = schema.separator || schema['x-separator']
|
|
16
|
+
delete schema.separator
|
|
17
|
+
delete schema['x-separator']
|
|
18
|
+
}
|
|
19
|
+
|
|
14
20
|
if (schema['x-display'] === 'icon' && (schema.enum || schema.items?.enum)) {
|
|
15
21
|
layout.getItems = { itemIcon: schema['x-itemIcon'] || 'data.value' }
|
|
16
22
|
delete schema['x-display']
|
|
@@ -28,7 +28,7 @@ const fieldProps = computed(() => {
|
|
|
28
28
|
})
|
|
29
29
|
|
|
30
30
|
const menuProps = computed(() => {
|
|
31
|
-
const menuProps = getCompProps(props.modelValue
|
|
31
|
+
const menuProps = getCompProps(props.modelValue)
|
|
32
32
|
menuProps.closeOnContentClick = false
|
|
33
33
|
menuProps.disabled = true
|
|
34
34
|
return menuProps
|
|
@@ -18,7 +18,8 @@ const props = defineProps({
|
|
|
18
18
|
})
|
|
19
19
|
|
|
20
20
|
const colorPickerProps = computed(() => {
|
|
21
|
-
const colorPickerProps = getCompProps(props.modelValue,
|
|
21
|
+
const colorPickerProps = getCompProps(props.modelValue, true)
|
|
22
|
+
colorPickerProps.modelValue = props.modelValue.data
|
|
22
23
|
return colorPickerProps
|
|
23
24
|
})
|
|
24
25
|
</script>
|
|
@@ -21,7 +21,7 @@ const props = defineProps({
|
|
|
21
21
|
const vDate = useDate()
|
|
22
22
|
|
|
23
23
|
const datePickerProps = computed(() => {
|
|
24
|
-
const datePickerProps = getCompProps(props.modelValue,
|
|
24
|
+
const datePickerProps = getCompProps(props.modelValue, true)
|
|
25
25
|
datePickerProps.hideActions = true
|
|
26
26
|
if (props.modelValue.data) datePickerProps.modelValue = new Date(props.modelValue.data)
|
|
27
27
|
return datePickerProps
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { VExpansionPanels, VExpansionPanel, VExpansionPanelTitle, VContainer, VRow, VIcon } from 'vuetify/components'
|
|
2
|
+
import { VExpansionPanels, VExpansionPanel, VExpansionPanelTitle, VExpansionPanelText, VContainer, VRow, VIcon } from 'vuetify/components'
|
|
3
|
+
import { computed } from 'vue'
|
|
3
4
|
import { isSection } from '@json-layout/core'
|
|
4
5
|
import Node from '../node.vue'
|
|
5
6
|
import SectionHeader from '../fragments/section-header.vue'
|
|
7
|
+
import { getCompProps } from '../../utils/index.js'
|
|
6
8
|
|
|
7
9
|
defineProps({
|
|
8
10
|
modelValue: {
|
|
@@ -21,7 +23,7 @@ defineProps({
|
|
|
21
23
|
|
|
22
24
|
<template>
|
|
23
25
|
<section-header :node="modelValue" />
|
|
24
|
-
<v-expansion-panels>
|
|
26
|
+
<v-expansion-panels v-bind="getCompProps(modelValue, true)">
|
|
25
27
|
<v-expansion-panel
|
|
26
28
|
v-for="(child, i) of modelValue.children"
|
|
27
29
|
:key="child.key"
|
|
@@ -37,16 +39,24 @@ defineProps({
|
|
|
37
39
|
</v-icon>
|
|
38
40
|
{{ child.layout.title ?? child.layout.label }}
|
|
39
41
|
</v-expansion-panel-title>
|
|
40
|
-
<v-
|
|
41
|
-
<v-
|
|
42
|
-
<
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
42
|
+
<v-expansion-panel-text>
|
|
43
|
+
<v-container fluid>
|
|
44
|
+
<v-row>
|
|
45
|
+
<node
|
|
46
|
+
v-for="grandChild of isSection(child) ? child.children : [child]"
|
|
47
|
+
:key="grandChild.fullKey"
|
|
48
|
+
:model-value="/** @type import('../../types.js').VjsfNode */(grandChild)"
|
|
49
|
+
:stateful-layout="statefulLayout"
|
|
50
|
+
/>
|
|
51
|
+
</v-row>
|
|
52
|
+
</v-container>
|
|
53
|
+
</v-expansion-panel-text>
|
|
50
54
|
</v-expansion-panel>
|
|
51
55
|
</v-expansion-panels>
|
|
52
56
|
</template>
|
|
57
|
+
|
|
58
|
+
<style>
|
|
59
|
+
.vjsf-node-expansion-panels .v-expansion-panel-text__wrapper {
|
|
60
|
+
padding: 0;
|
|
61
|
+
}
|
|
62
|
+
</style>
|
|
@@ -48,6 +48,12 @@ const buttonDensity = computed(() => {
|
|
|
48
48
|
return props.modelValue.options.density
|
|
49
49
|
})
|
|
50
50
|
|
|
51
|
+
const pushEmptyItem = () => {
|
|
52
|
+
const newData = (props.modelValue.data ?? []).concat([undefined])
|
|
53
|
+
props.statefulLayout.input(props.modelValue, newData)
|
|
54
|
+
props.statefulLayout.activateItem(props.modelValue, newData.length - 1)
|
|
55
|
+
}
|
|
56
|
+
|
|
51
57
|
</script>
|
|
52
58
|
|
|
53
59
|
<template>
|
|
@@ -180,7 +186,7 @@ const buttonDensity = computed(() => {
|
|
|
180
186
|
<v-btn
|
|
181
187
|
color="primary"
|
|
182
188
|
:density="modelValue.options.density"
|
|
183
|
-
@click="
|
|
189
|
+
@click="pushEmptyItem"
|
|
184
190
|
>
|
|
185
191
|
{{ modelValue.messages.addItem }}
|
|
186
192
|
</v-btn>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { StatefulLayout, produceCompileOptions } from '@json-layout/core'
|
|
2
|
-
import { inject, shallowRef, computed, ref, watch, useSlots } from 'vue'
|
|
2
|
+
import { inject, toRaw, shallowRef, computed, ref, watch, useSlots } from 'vue'
|
|
3
3
|
import { useElementSize } from '@vueuse/core'
|
|
4
4
|
import { getFullOptions } from '../components/options.js'
|
|
5
5
|
import { registeredNodeComponents } from '../utils/index.js'
|
|
@@ -53,7 +53,7 @@ export const useVjsf = (schema, modelValue, options, nodeComponents, emit, compi
|
|
|
53
53
|
|
|
54
54
|
const slots = useSlots()
|
|
55
55
|
|
|
56
|
-
const fullOptions = computed(() => getFullOptions(options.value, form, width.value, slots, { ...nodeComponents, ...registeredNodeComponents.value }))
|
|
56
|
+
const fullOptions = computed(() => getFullOptions(options.value, form, width.value, slots, { ...nodeComponents, ...toRaw(registeredNodeComponents.value) }))
|
|
57
57
|
|
|
58
58
|
// do not use a simple computed here as we want to prevent recompiling the layout when the options are the same
|
|
59
59
|
/** @type {import('vue').Ref<import('@json-layout/core').PartialCompileOptions>} */
|
|
@@ -89,10 +89,10 @@ export const useVjsf = (schema, modelValue, options, nodeComponents, emit, compi
|
|
|
89
89
|
|
|
90
90
|
// @ts-ignore
|
|
91
91
|
const _statefulLayout = /** @type {import('../types.js').VjsfStatefulLayout} */(new StatefulLayout(
|
|
92
|
-
compiledLayout.value,
|
|
93
|
-
compiledLayout.value.skeletonTree,
|
|
94
|
-
fullOptions.value,
|
|
95
|
-
modelValue.value
|
|
92
|
+
toRaw(compiledLayout.value),
|
|
93
|
+
toRaw(compiledLayout.value.skeletonTree),
|
|
94
|
+
toRaw(fullOptions.value),
|
|
95
|
+
toRaw(modelValue.value)
|
|
96
96
|
))
|
|
97
97
|
statefulLayout.value = _statefulLayout
|
|
98
98
|
onStatefulLayoutUpdate()
|
|
@@ -122,7 +122,7 @@ export const useVjsf = (schema, modelValue, options, nodeComponents, emit, compi
|
|
|
122
122
|
|
|
123
123
|
// case where data is updated from outside
|
|
124
124
|
watch(modelValue, (newData) => {
|
|
125
|
-
if (statefulLayout.value && statefulLayout.value.data !== newData) statefulLayout.value.data = newData
|
|
125
|
+
if (statefulLayout.value && statefulLayout.value.data !== newData) statefulLayout.value.data = toRaw(newData)
|
|
126
126
|
})
|
|
127
127
|
|
|
128
128
|
// case where schema or compile options are updated from outside
|
package/src/utils/build.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { commonjsDeps } from '@json-layout/core/utils/build'
|
|
1
|
+
export { commonjsDeps, commonjsDepsPaths } from '@json-layout/core/utils/build'
|
package/src/utils/props.js
CHANGED
|
@@ -65,7 +65,7 @@ export function getInputProps (node, statefulLayout, layoutPropsMap, isMainComp
|
|
|
65
65
|
if (node.error && node.validated) {
|
|
66
66
|
fullProps.errorMessages = node.error
|
|
67
67
|
}
|
|
68
|
-
fullProps.modelValue = node.data
|
|
68
|
+
fullProps.modelValue = (typeof node.data === 'string' && node.layout.separator) ? node.data.split(/** @type {string} */(node.layout.separator)) : node.data
|
|
69
69
|
if (node.options.readOnly) {
|
|
70
70
|
fullProps.disabled = true
|
|
71
71
|
fullProps.class.push('vjsf-input--readonly')
|
|
@@ -82,7 +82,9 @@ export function getInputProps (node, statefulLayout, layoutPropsMap, isMainComp
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
if (isMainComp) {
|
|
85
|
-
fullProps['onUpdate:modelValue'] = (/** @type string */value) =>
|
|
85
|
+
fullProps['onUpdate:modelValue'] = (/** @type string */value) => {
|
|
86
|
+
return statefulLayout.input(node, (Array.isArray(value) && node.layout.separator) ? value.join(/** @type {string} */(node.layout.separator)) : value)
|
|
87
|
+
}
|
|
86
88
|
fullProps.onBlur = () => statefulLayout.blur(node)
|
|
87
89
|
}
|
|
88
90
|
|
|
@@ -92,18 +94,14 @@ export function getInputProps (node, statefulLayout, layoutPropsMap, isMainComp
|
|
|
92
94
|
// calculate the props of components that are not of the field category
|
|
93
95
|
/**
|
|
94
96
|
* @param {import('@json-layout/core').StateNode} node
|
|
95
|
-
* @param {string} comp
|
|
96
97
|
* @param {boolean} isMainComp
|
|
97
98
|
* @returns {Record<string, any>}
|
|
98
99
|
*/
|
|
99
|
-
export function getCompProps (node,
|
|
100
|
+
export function getCompProps (node, isMainComp = true) {
|
|
100
101
|
const options = /** @type import('../types.js').VjsfOptions */(node.options)
|
|
101
102
|
/** @type {(Record<string, any> | undefined)[]} */
|
|
102
103
|
const propsLevels = [{ density: options.density }]
|
|
103
|
-
propsLevels.push(/** @type Record<string, any> | undefined */(options[`${comp}Props`]))
|
|
104
|
-
if (node.options.readOnly) propsLevels.push(/** @type Record<string, any> | undefined */(options[`${comp}PropsReadOnly`]))
|
|
105
104
|
if (isMainComp) propsLevels.push(node.layout.props)
|
|
106
105
|
const fullProps = mergePropsLevels(propsLevels)
|
|
107
|
-
if (isMainComp) fullProps.modelValue = node.data
|
|
108
106
|
return fullProps
|
|
109
107
|
}
|
package/types/compat/v2.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"v2.d.ts","sourceRoot":"","sources":["../../src/compat/v2.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"v2.d.ts","sourceRoot":"","sources":["../../src/compat/v2.js"],"names":[],"mappings":"AAoGA;;;;;;GAMG;AACH,kCALW,MAAM,+CAEN,MAAM,0BAkBhB;sBA1HqB,KAAK"}
|
package/types/utils/build.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { commonjsDeps } from "@json-layout/core/utils/build";
|
|
1
|
+
export { commonjsDeps, commonjsDepsPaths } from "@json-layout/core/utils/build";
|
|
2
2
|
//# sourceMappingURL=build.d.ts.map
|
package/types/utils/props.d.ts
CHANGED
|
@@ -15,9 +15,8 @@ export function mergePropsLevels(propsLevels: (Record<string, any> | undefined)[
|
|
|
15
15
|
export function getInputProps(node: import('../types.js').VjsfNode, statefulLayout: import('../types.js').VjsfStatefulLayout, layoutPropsMap?: (string | [string, string])[] | undefined, isMainComp?: boolean | undefined): Record<string, any>;
|
|
16
16
|
/**
|
|
17
17
|
* @param {import('@json-layout/core').StateNode} node
|
|
18
|
-
* @param {string} comp
|
|
19
18
|
* @param {boolean} isMainComp
|
|
20
19
|
* @returns {Record<string, any>}
|
|
21
20
|
*/
|
|
22
|
-
export function getCompProps(node: import('@json-layout/core').StateNode,
|
|
21
|
+
export function getCompProps(node: import('@json-layout/core').StateNode, isMainComp?: boolean): Record<string, any>;
|
|
23
22
|
//# sourceMappingURL=props.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../src/utils/props.js"],"names":[],"mappings":"AAkBA;;;GAGG;AACH,8CAHW,CAAC,OAAO,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAAC,EAAE,GACjC,OAAO,MAAM,EAAE,GAAG,CAAC,GAAG;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAC,CAqBnD;AAID;;;;;;GAMG;AACH,oCANW,OAAO,aAAa,EAAE,QAAQ,kBAC9B,OAAO,aAAa,EAAE,kBAAkB,iGAGtC,OAAO,MAAM,EAAE,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../src/utils/props.js"],"names":[],"mappings":"AAkBA;;;GAGG;AACH,8CAHW,CAAC,OAAO,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAAC,EAAE,GACjC,OAAO,MAAM,EAAE,GAAG,CAAC,GAAG;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAC,CAqBnD;AAID;;;;;;GAMG;AACH,oCANW,OAAO,aAAa,EAAE,QAAQ,kBAC9B,OAAO,aAAa,EAAE,kBAAkB,iGAGtC,OAAO,MAAM,EAAE,GAAG,CAAC,CAyC/B;AAGD;;;;GAIG;AACH,mCAJW,OAAO,mBAAmB,EAAE,SAAS,eACrC,OAAO,GACL,OAAO,MAAM,EAAE,GAAG,CAAC,CAS/B"}
|