@koumoul/vjsf 3.0.0-beta.24 → 3.0.0-beta.26
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 +27 -13
- package/src/components/nodes/list.vue +9 -3
- package/src/components/nodes/one-of-select.vue +11 -9
- package/src/composables/use-vjsf.js +1 -1
- package/types/compat/v2.d.ts.map +1 -1
- package/types/components/fragments/select-item.vue.d.ts +2 -2
- package/types/components/vjsf.vue.d.ts +2 -2
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.26",
|
|
4
4
|
"description": "Generate forms for the vuetify UI library (vuejs) based on annotated JSON schemas.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "vitest",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"vuetify": "^3.6.8"
|
|
77
77
|
},
|
|
78
78
|
"dependencies": {
|
|
79
|
-
"@json-layout/core": "0.
|
|
79
|
+
"@json-layout/core": "0.22.0",
|
|
80
80
|
"@vueuse/core": "^10.5.0",
|
|
81
81
|
"debug": "^4.3.4",
|
|
82
82
|
"ejs": "^3.1.9"
|
package/src/compat/v2.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ajvModule from 'ajv'
|
|
2
2
|
import addFormats from 'ajv-formats'
|
|
3
|
-
import {
|
|
3
|
+
import { resolveLocaleRefs, clone } from '@json-layout/core'
|
|
4
4
|
import { isPartialGetItemsObj } from '@json-layout/vocabulary'
|
|
5
5
|
|
|
6
6
|
// @ts-ignore
|
|
@@ -59,7 +59,17 @@ const fixExpression = (expression, type = 'js-eval') => {
|
|
|
59
59
|
return { type, expr, pure }
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
/**
|
|
63
|
+
*
|
|
64
|
+
* @param {import("ajv").SchemaObject} schema
|
|
65
|
+
* @param {(schemaId: string, ref: string) => [any, string, string]} getJSONRef
|
|
66
|
+
* @param {string} schemaId
|
|
67
|
+
*/
|
|
68
|
+
const processFragment = (schema, getJSONRef, schemaId) => {
|
|
69
|
+
if (schema.$ref) {
|
|
70
|
+
const [refFragment, refSchemaId] = getJSONRef(schemaId, schema.$ref)
|
|
71
|
+
processFragment(refFragment, getJSONRef, refSchemaId)
|
|
72
|
+
}
|
|
63
73
|
if (!schema.layout) {
|
|
64
74
|
/** @type import('@json-layout/vocabulary').PartialCompObject */
|
|
65
75
|
const layout = {}
|
|
@@ -123,6 +133,10 @@ const processFragment = (/** @type {import("ajv").SchemaObject} */schema) => {
|
|
|
123
133
|
delete schema['x-itemsProp']
|
|
124
134
|
}
|
|
125
135
|
|
|
136
|
+
if (schema['x-cols']) {
|
|
137
|
+
layout.cols = schema['x-cols']
|
|
138
|
+
}
|
|
139
|
+
|
|
126
140
|
// compact the layout keyword if possible
|
|
127
141
|
if (Object.keys(layout).length === 1 && 'comp' in layout) {
|
|
128
142
|
schema.layout = layout.comp
|
|
@@ -133,12 +147,12 @@ const processFragment = (/** @type {import("ajv").SchemaObject} */schema) => {
|
|
|
133
147
|
|
|
134
148
|
if (schema.properties) {
|
|
135
149
|
for (const propertyKey of Object.keys(schema.properties)) {
|
|
136
|
-
processFragment(schema.properties[propertyKey])
|
|
150
|
+
processFragment(schema.properties[propertyKey], getJSONRef, schemaId)
|
|
137
151
|
}
|
|
138
152
|
}
|
|
139
153
|
|
|
140
154
|
if (schema.allOf) {
|
|
141
|
-
for (const item of schema.allOf) processFragment(item)
|
|
155
|
+
for (const item of schema.allOf) processFragment(item, getJSONRef, schemaId)
|
|
142
156
|
}
|
|
143
157
|
|
|
144
158
|
if (schema.oneOf) {
|
|
@@ -153,28 +167,28 @@ const processFragment = (/** @type {import("ajv").SchemaObject} */schema) => {
|
|
|
153
167
|
}
|
|
154
168
|
}
|
|
155
169
|
}
|
|
156
|
-
for (const item of schema.oneOf) processFragment(item)
|
|
170
|
+
for (const item of schema.oneOf) processFragment(item, getJSONRef, schemaId)
|
|
157
171
|
}
|
|
158
172
|
|
|
159
173
|
if (schema.anyOf) {
|
|
160
|
-
for (const item of schema.anyOf) processFragment(item)
|
|
174
|
+
for (const item of schema.anyOf) processFragment(item, getJSONRef, schemaId)
|
|
161
175
|
}
|
|
162
176
|
|
|
163
177
|
if (schema.type === 'array' && schema.items) {
|
|
164
178
|
if (Array.isArray(schema.items)) {
|
|
165
|
-
for (const item of schema.items) processFragment(item)
|
|
179
|
+
for (const item of schema.items) processFragment(item, getJSONRef, schemaId)
|
|
166
180
|
} else {
|
|
167
|
-
processFragment(schema.items)
|
|
181
|
+
processFragment(schema.items, getJSONRef, schemaId)
|
|
168
182
|
}
|
|
169
183
|
}
|
|
170
184
|
if (schema.dependencies) {
|
|
171
185
|
for (const key of Object.keys(schema.dependencies)) {
|
|
172
|
-
processFragment(schema.dependencies[key])
|
|
186
|
+
processFragment(schema.dependencies[key], getJSONRef, schemaId)
|
|
173
187
|
}
|
|
174
188
|
}
|
|
175
189
|
if (schema.if) {
|
|
176
|
-
if (schema.then) processFragment(schema.then)
|
|
177
|
-
if (schema.else) processFragment(schema.else)
|
|
190
|
+
if (schema.then) processFragment(schema.then, getJSONRef, schemaId)
|
|
191
|
+
if (schema.else) processFragment(schema.else, getJSONRef, schemaId)
|
|
178
192
|
}
|
|
179
193
|
}
|
|
180
194
|
|
|
@@ -197,7 +211,7 @@ export function v2compat (_schema, _ajv, lang = 'en') {
|
|
|
197
211
|
|
|
198
212
|
const schema = /** @type {import("ajv").SchemaObject} */ (clone(_schema))
|
|
199
213
|
schema.$id = schema.$id ?? '_jl'
|
|
200
|
-
|
|
201
|
-
processFragment(schema)
|
|
214
|
+
const getJSONRef = resolveLocaleRefs(schema, ajv, lang)
|
|
215
|
+
processFragment(schema, getJSONRef, schema.$id)
|
|
202
216
|
return schema
|
|
203
217
|
}
|
|
@@ -30,7 +30,7 @@ watch(() => props.modelValue.children, (array) => { sortableArray.value = array
|
|
|
30
30
|
|
|
31
31
|
/* manage hovered and edited items */
|
|
32
32
|
const editedItem = computed(() => {
|
|
33
|
-
return props.statefulLayout.
|
|
33
|
+
return props.statefulLayout.activatedItems[props.modelValue.fullKey]
|
|
34
34
|
})
|
|
35
35
|
const menuOpened = ref(-1)
|
|
36
36
|
const activeItem = computed(() => {
|
|
@@ -54,7 +54,9 @@ const buttonDensity = computed(() => {
|
|
|
54
54
|
const pushEmptyItem = () => {
|
|
55
55
|
const newData = (props.modelValue.data ?? []).concat([undefined])
|
|
56
56
|
props.statefulLayout.input(props.modelValue, newData)
|
|
57
|
-
|
|
57
|
+
if (props.modelValue.layout.listEditMode === 'inline-single') {
|
|
58
|
+
props.statefulLayout.activateItem(props.modelValue, newData.length - 1)
|
|
59
|
+
}
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
/**
|
|
@@ -73,13 +75,17 @@ const deleteItem = (childIndex) => {
|
|
|
73
75
|
const duplicateItem = (child, childIndex) => {
|
|
74
76
|
const newData = [...props.modelValue.data.slice(0, childIndex), clone(child.data), ...props.modelValue.data.slice(childIndex)]
|
|
75
77
|
props.statefulLayout.input(props.modelValue, newData)
|
|
76
|
-
props.
|
|
78
|
+
if (props.modelValue.layout.listEditMode === 'inline-single') {
|
|
79
|
+
props.statefulLayout.activateItem(props.modelValue, childIndex + 1)
|
|
80
|
+
}
|
|
77
81
|
menuOpened.value = -1
|
|
78
82
|
}
|
|
79
83
|
|
|
80
84
|
const itemBorderColor = computed(() => (/** @type {import('@json-layout/core').StateNode} */child, /** @type {number} */childIndex) => {
|
|
81
85
|
if (editedItem.value === childIndex) return theme.current.value.colors.primary
|
|
82
86
|
if (child.validated && (child.error || child.childError)) return theme.current.value.colors.error
|
|
87
|
+
if (props.modelValue.options.readOnly) return 'transparent'
|
|
88
|
+
if (activeItem.value === childIndex) return theme.current.value.colors.primary
|
|
83
89
|
return 'transparent'
|
|
84
90
|
})
|
|
85
91
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { VSelect, VRow, VCol } from 'vuetify/components'
|
|
3
|
-
import {
|
|
3
|
+
import { ref, watch, computed, h } from 'vue'
|
|
4
4
|
import { isSection } from '@json-layout/core'
|
|
5
5
|
import { isCompObject } from '@json-layout/vocabulary'
|
|
6
6
|
import { getInputProps } from '../../utils/index.js'
|
|
@@ -19,18 +19,19 @@ const props = defineProps({
|
|
|
19
19
|
}
|
|
20
20
|
})
|
|
21
21
|
|
|
22
|
-
/** @type import('vue').
|
|
23
|
-
const activeChildTree =
|
|
22
|
+
/** @type import('vue').Ref<string | undefined> */
|
|
23
|
+
const activeChildTree = ref(undefined)
|
|
24
24
|
watch(() => props.modelValue, () => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
if (props.modelValue.children?.length === 1) {
|
|
26
|
+
if (typeof props.modelValue.children[0].key === 'number') {
|
|
27
|
+
activeChildTree.value = props.modelValue.skeleton.childrenTrees?.[props.modelValue.children[0].key]
|
|
28
|
+
}
|
|
28
29
|
} else {
|
|
29
30
|
activeChildTree.value = undefined
|
|
30
31
|
}
|
|
31
32
|
}, { immediate: true })
|
|
32
33
|
|
|
33
|
-
const onChange = (/** @type
|
|
34
|
+
const onChange = (/** @type {string} */childTree) => {
|
|
34
35
|
if (!props.modelValue.skeleton.childrenTrees) return
|
|
35
36
|
props.statefulLayout.activateItem(props.modelValue, props.modelValue.skeleton.childrenTrees.indexOf(childTree))
|
|
36
37
|
}
|
|
@@ -39,9 +40,9 @@ const fieldProps = computed(() => {
|
|
|
39
40
|
const fieldProps = getInputProps(props.modelValue, props.statefulLayout)
|
|
40
41
|
fieldProps.modelValue = activeChildTree.value
|
|
41
42
|
fieldProps['onUpdate:modelValue'] = onChange
|
|
42
|
-
fieldProps.returnObject = true
|
|
43
43
|
const items = []
|
|
44
|
-
for (const
|
|
44
|
+
for (const childTreePointer of props.modelValue.skeleton.childrenTrees || []) {
|
|
45
|
+
const childTree = props.statefulLayout.compiledLayout.skeletonTrees[childTreePointer]
|
|
45
46
|
const childLayout = props.statefulLayout.compiledLayout.normalizedLayouts[childTree.root.pointer]
|
|
46
47
|
if (!isCompObject(childLayout) || !childLayout.if || !!props.statefulLayout.evalNodeExpression(props.modelValue, childLayout.if, props.modelValue.data)) {
|
|
47
48
|
items.push(childTree)
|
|
@@ -49,6 +50,7 @@ const fieldProps = computed(() => {
|
|
|
49
50
|
}
|
|
50
51
|
fieldProps.items = items
|
|
51
52
|
fieldProps.itemTitle = 'title'
|
|
53
|
+
fieldProps.itemValue = (/** @type {import('@json-layout/core').SkeletonTree} */childTree) => childTree.root.pointer
|
|
52
54
|
return fieldProps
|
|
53
55
|
})
|
|
54
56
|
</script>
|
|
@@ -96,7 +96,7 @@ export const useVjsf = (schema, modelValue, options, nodeComponents, emit, compi
|
|
|
96
96
|
// @ts-ignore
|
|
97
97
|
const _statefulLayout = /** @type {import('../types.js').VjsfStatefulLayout} */(new StatefulLayout(
|
|
98
98
|
toRaw(compiledLayout.value),
|
|
99
|
-
toRaw(compiledLayout.value.
|
|
99
|
+
toRaw(compiledLayout.value.skeletonTrees[compiledLayout.value.mainTree]),
|
|
100
100
|
toRaw(fullOptions.value),
|
|
101
101
|
toRaw(modelValue.value)
|
|
102
102
|
))
|
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":"AAkMA;;;;;;GAMG;AACH,kCALW,MAAM,+CAEN,MAAM,0BAkBhB;sBAxNqB,KAAK"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
declare const _default: import("vue").DefineComponent<{}, {
|
|
2
2
|
multiple: boolean;
|
|
3
|
-
itemProps: Record<string, any>;
|
|
4
3
|
item: import("../../../../node_modules/@json-layout/vocabulary/types/normalized-layout/types.js").SelectItem;
|
|
4
|
+
itemProps: Record<string, any>;
|
|
5
5
|
$props: {
|
|
6
6
|
readonly multiple?: boolean | undefined;
|
|
7
|
-
readonly itemProps?: Record<string, any> | undefined;
|
|
8
7
|
readonly item?: import("../../../../node_modules/@json-layout/vocabulary/types/normalized-layout/types.js").SelectItem | undefined;
|
|
8
|
+
readonly itemProps?: Record<string, any> | undefined;
|
|
9
9
|
};
|
|
10
10
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
|
|
11
11
|
export default _default;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
declare const _default: import("vue").DefineComponent<{}, {
|
|
2
2
|
$emit: ((event: "update:modelValue", data: any) => void) & ((event: "update:state", state: import("../types.js").VjsfStatefulLayout) => void);
|
|
3
|
-
modelValue: any;
|
|
4
3
|
options: Partial<Omit<import("../types.js").VjsfOptions, "width" | "vjsfSlots">> | null;
|
|
4
|
+
modelValue: any;
|
|
5
5
|
schema: Record<string, any>;
|
|
6
6
|
precompiledLayout: import("../../../node_modules/@json-layout/core/types/compile/types.js").CompiledLayout;
|
|
7
7
|
$props: {
|
|
8
|
-
readonly modelValue?: any;
|
|
9
8
|
readonly options?: Partial<Omit<import("../types.js").VjsfOptions, "width" | "vjsfSlots">> | null | undefined;
|
|
9
|
+
readonly modelValue?: any;
|
|
10
10
|
readonly schema?: Record<string, any> | undefined;
|
|
11
11
|
readonly precompiledLayout?: import("../../../node_modules/@json-layout/core/types/compile/types.js").CompiledLayout | undefined;
|
|
12
12
|
};
|