@koumoul/vjsf 3.0.0-alpha.4 → 3.0.0-alpha.6
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 +27 -6
- package/src/compile/index.js +18 -4
- package/src/compile/options.js +19 -0
- package/src/compile/v-jsf-compiled.vue.ejs +28 -10
- package/src/components/fragments/help-message.vue +2 -1
- package/src/components/fragments/node-slot.vue +3 -3
- package/src/components/fragments/section-header.vue +2 -1
- package/src/components/fragments/text-field-menu.vue +3 -3
- package/src/components/node.vue +12 -8
- package/src/components/nodes/autocomplete.vue +3 -4
- package/src/components/nodes/checkbox.vue +3 -3
- package/src/components/nodes/color-picker.vue +3 -3
- package/src/components/nodes/combobox.vue +3 -4
- package/src/components/nodes/date-picker.vue +3 -4
- package/src/components/nodes/date-time-picker.vue +2 -2
- package/src/components/nodes/expansion-panels.vue +3 -3
- package/src/components/nodes/file-input.vue +43 -0
- package/src/components/nodes/list.vue +4 -4
- package/src/components/nodes/number-combobox.vue +3 -4
- package/src/components/nodes/number-field.vue +3 -4
- package/src/components/nodes/one-of-select.vue +3 -3
- package/src/components/nodes/section.vue +3 -3
- package/src/components/nodes/select.vue +3 -4
- package/src/components/nodes/slider.vue +3 -3
- package/src/components/nodes/stepper.vue +3 -5
- package/src/components/nodes/switch.vue +3 -3
- package/src/components/nodes/tabs.vue +3 -3
- package/src/components/nodes/text-field.vue +3 -4
- package/src/components/nodes/textarea.vue +3 -4
- package/src/components/nodes/vertical-tabs.vue +3 -3
- package/src/components/options.js +9 -6
- package/src/components/tree.vue +2 -2
- package/src/components/vjsf.vue +9 -13
- package/src/composables/use-dnd.js +1 -1
- package/src/composables/use-vjsf.js +9 -8
- package/src/index.js +1 -0
- package/src/{components/types.ts → types.ts} +18 -2
- package/src/utils/global-register.js +10 -0
- package/src/utils/index.js +5 -0
- package/src/utils/props.js +4 -4
- package/src/utils/slots.js +2 -3
- package/types/compile/index.d.ts +3 -2
- package/types/compile/index.d.ts.map +1 -1
- package/types/compile/options.d.ts +4 -0
- package/types/compile/options.d.ts.map +1 -0
- package/types/components/fragments/help-message.vue.d.ts +2 -2
- package/types/components/fragments/node-slot.vue.d.ts +8 -8
- package/types/components/fragments/node-slot.vue.d.ts.map +1 -1
- package/types/components/fragments/section-header.vue.d.ts +2 -2
- package/types/components/fragments/select-item.vue.d.ts +2 -2
- package/types/components/fragments/text-field-menu.vue.d.ts +4 -4
- package/types/components/fragments/text-field-menu.vue.d.ts.map +1 -1
- package/types/components/global-register.d.ts +8 -0
- package/types/components/global-register.d.ts.map +1 -0
- package/types/components/node.vue.d.ts +4 -4
- package/types/components/nodes/autocomplete.vue.d.ts +8 -8
- package/types/components/nodes/autocomplete.vue.d.ts.map +1 -1
- package/types/components/nodes/checkbox.vue.d.ts +4 -4
- package/types/components/nodes/color-picker.vue.d.ts +4 -4
- package/types/components/nodes/combobox.vue.d.ts +8 -8
- package/types/components/nodes/combobox.vue.d.ts.map +1 -1
- package/types/components/nodes/date-picker.vue.d.ts +4 -4
- package/types/components/nodes/date-time-picker.vue.d.ts +4 -4
- package/types/components/nodes/expansion-panels.vue.d.ts +4 -4
- package/types/components/nodes/file-input.vue.d.ts +27 -0
- package/types/components/nodes/file-input.vue.d.ts.map +1 -0
- package/types/components/nodes/list.vue.d.ts +4 -4
- package/types/components/nodes/number-combobox.vue.d.ts +8 -8
- package/types/components/nodes/number-combobox.vue.d.ts.map +1 -1
- package/types/components/nodes/number-field.vue.d.ts +8 -8
- package/types/components/nodes/number-field.vue.d.ts.map +1 -1
- package/types/components/nodes/one-of-select.vue.d.ts +4 -4
- package/types/components/nodes/section.vue.d.ts +4 -4
- package/types/components/nodes/select.vue.d.ts +8 -8
- package/types/components/nodes/select.vue.d.ts.map +1 -1
- package/types/components/nodes/slider.vue.d.ts +4 -4
- package/types/components/nodes/stepper.vue.d.ts +4 -4
- package/types/components/nodes/switch.vue.d.ts +4 -4
- package/types/components/nodes/tabs.vue.d.ts +4 -4
- package/types/components/nodes/text-field.vue.d.ts +8 -8
- package/types/components/nodes/text-field.vue.d.ts.map +1 -1
- package/types/components/nodes/textarea.vue.d.ts +8 -8
- package/types/components/nodes/textarea.vue.d.ts.map +1 -1
- package/types/components/nodes/vertical-tabs.vue.d.ts +4 -4
- package/types/components/options.d.ts +3 -3
- package/types/components/options.d.ts.map +1 -1
- package/types/components/tree.vue.d.ts +2 -2
- package/types/components/types.d.ts +14 -2
- package/types/components/types.d.ts.map +1 -1
- package/types/components/vjsf.vue.d.ts +3 -3
- package/types/composables/use-dnd.d.ts +5 -1
- package/types/composables/use-dnd.d.ts.map +1 -1
- package/types/composables/use-vjsf.d.ts +4 -5
- package/types/composables/use-vjsf.d.ts.map +1 -1
- package/types/index.d.ts +1 -0
- package/types/index.d.ts.map +1 -1
- package/types/types.d.ts +95 -0
- package/types/types.d.ts.map +1 -0
- package/types/utils/global-register.d.ts +8 -0
- package/types/utils/global-register.d.ts.map +1 -0
- package/types/utils/index.d.ts +6 -0
- package/types/utils/index.d.ts.map +1 -0
- package/types/utils/props.d.ts +3 -3
- package/types/utils/props.d.ts.map +1 -1
- package/types/utils/slots.d.ts +3 -3
- package/types/utils/slots.d.ts.map +1 -1
- package/src/components/nodes/markdown.vue +0 -341
|
@@ -5,12 +5,12 @@ import SectionHeader from '../fragments/section-header.vue'
|
|
|
5
5
|
|
|
6
6
|
defineProps({
|
|
7
7
|
modelValue: {
|
|
8
|
-
/** @type import('vue').PropType<import('
|
|
8
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfSectionNode> */
|
|
9
9
|
type: Object,
|
|
10
10
|
required: true
|
|
11
11
|
},
|
|
12
12
|
statefulLayout: {
|
|
13
|
-
/** @type import('vue').PropType<import('
|
|
13
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfStatefulLayout> */
|
|
14
14
|
type: Object,
|
|
15
15
|
required: true
|
|
16
16
|
}
|
|
@@ -24,7 +24,7 @@ defineProps({
|
|
|
24
24
|
<node
|
|
25
25
|
v-for="child of modelValue.children"
|
|
26
26
|
:key="child.fullKey"
|
|
27
|
-
:model-value="/** @type import('
|
|
27
|
+
:model-value="/** @type import('../../types.js').VjsfNode */(child)"
|
|
28
28
|
:stateful-layout="statefulLayout"
|
|
29
29
|
/>
|
|
30
30
|
</v-row>
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { VSelect } from 'vuetify/components'
|
|
3
3
|
import { defineComponent, h, computed, ref, shallowRef } from 'vue'
|
|
4
|
-
import { getInputProps } from '../../utils/
|
|
5
|
-
import { getCompSlots } from '../../utils/slots.js'
|
|
4
|
+
import { getInputProps, getCompSlots } from '../../utils/index.js'
|
|
6
5
|
import SelectItem from '../fragments/select-item.vue'
|
|
7
6
|
import SelectSelection from '../fragments/select-selection.vue'
|
|
8
7
|
|
|
9
8
|
export default defineComponent({
|
|
10
9
|
props: {
|
|
11
10
|
modelValue: {
|
|
12
|
-
/** @type import('vue').PropType<import('
|
|
11
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfSelectNode> */
|
|
13
12
|
type: Object,
|
|
14
13
|
required: true
|
|
15
14
|
},
|
|
16
15
|
statefulLayout: {
|
|
17
|
-
/** @type import('vue').PropType<import('
|
|
16
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfStatefulLayout> */
|
|
18
17
|
type: Object,
|
|
19
18
|
required: true
|
|
20
19
|
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { VSlider } from 'vuetify/components'
|
|
3
3
|
import { computed } from 'vue'
|
|
4
|
-
import { getInputProps } from '../../utils/
|
|
4
|
+
import { getInputProps } from '../../utils/index.js'
|
|
5
5
|
|
|
6
6
|
const props = defineProps({
|
|
7
7
|
modelValue: {
|
|
8
|
-
/** @type import('vue').PropType<import('
|
|
8
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfSliderNode> */
|
|
9
9
|
type: Object,
|
|
10
10
|
required: true
|
|
11
11
|
},
|
|
12
12
|
statefulLayout: {
|
|
13
|
-
/** @type import('vue').PropType<import('
|
|
13
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfStatefulLayout> */
|
|
14
14
|
type: Object,
|
|
15
15
|
required: true
|
|
16
16
|
}
|
|
@@ -7,12 +7,12 @@ import SectionHeader from '../fragments/section-header.vue'
|
|
|
7
7
|
|
|
8
8
|
const props = defineProps({
|
|
9
9
|
modelValue: {
|
|
10
|
-
/** @type import('vue').PropType<import('
|
|
10
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfStepperNode> */
|
|
11
11
|
type: Object,
|
|
12
12
|
required: true
|
|
13
13
|
},
|
|
14
14
|
statefulLayout: {
|
|
15
|
-
/** @type import('vue').PropType<import('
|
|
15
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfStatefulLayout> */
|
|
16
16
|
type: Object,
|
|
17
17
|
required: true
|
|
18
18
|
}
|
|
@@ -26,10 +26,8 @@ const firstErrorIndex = computed(() => {
|
|
|
26
26
|
})
|
|
27
27
|
|
|
28
28
|
const goNext = () => {
|
|
29
|
-
console.log(props.statefulLayout.validationState)
|
|
30
29
|
const child = props.modelValue.children[step.value]
|
|
31
30
|
props.statefulLayout.validateNodeRecurse(child)
|
|
32
|
-
console.log(props.statefulLayout.validationState)
|
|
33
31
|
if (!(child.error || child.childError)) step.value++
|
|
34
32
|
}
|
|
35
33
|
</script>
|
|
@@ -65,7 +63,7 @@ const goNext = () => {
|
|
|
65
63
|
<node
|
|
66
64
|
v-for="grandChild of isSection(child) ? child.children : [child]"
|
|
67
65
|
:key="grandChild.fullKey"
|
|
68
|
-
:model-value="/** @type import('
|
|
66
|
+
:model-value="/** @type import('../../types.js').VjsfNode */(grandChild)"
|
|
69
67
|
:stateful-layout="statefulLayout"
|
|
70
68
|
/>
|
|
71
69
|
</v-row>
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { VSwitch } from 'vuetify/components'
|
|
3
3
|
import { computed } from 'vue'
|
|
4
|
-
import { getInputProps } from '../../utils/
|
|
4
|
+
import { getInputProps } from '../../utils/index.js'
|
|
5
5
|
|
|
6
6
|
const props = defineProps({
|
|
7
7
|
modelValue: {
|
|
8
|
-
/** @type import('vue').PropType<import('
|
|
8
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfSwitchNode> */
|
|
9
9
|
type: Object,
|
|
10
10
|
required: true
|
|
11
11
|
},
|
|
12
12
|
statefulLayout: {
|
|
13
|
-
/** @type import('vue').PropType<import('
|
|
13
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfStatefulLayout> */
|
|
14
14
|
type: Object,
|
|
15
15
|
required: true
|
|
16
16
|
}
|
|
@@ -7,12 +7,12 @@ import SectionHeader from '../fragments/section-header.vue'
|
|
|
7
7
|
|
|
8
8
|
defineProps({
|
|
9
9
|
modelValue: {
|
|
10
|
-
/** @type import('vue').PropType<import('
|
|
10
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfTabsNode> */
|
|
11
11
|
type: Object,
|
|
12
12
|
required: true
|
|
13
13
|
},
|
|
14
14
|
statefulLayout: {
|
|
15
|
-
/** @type import('vue').PropType<import('
|
|
15
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfStatefulLayout> */
|
|
16
16
|
type: Object,
|
|
17
17
|
required: true
|
|
18
18
|
}
|
|
@@ -52,7 +52,7 @@ const tab = ref(0)
|
|
|
52
52
|
<node
|
|
53
53
|
v-for="grandChild of isSection(child) ? child.children : [child]"
|
|
54
54
|
:key="grandChild.fullKey"
|
|
55
|
-
:model-value="/** @type import('
|
|
55
|
+
:model-value="/** @type import('../../types.js').VjsfNode */(grandChild)"
|
|
56
56
|
:stateful-layout="statefulLayout"
|
|
57
57
|
/>
|
|
58
58
|
</v-row>
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { defineComponent, h, computed } from 'vue'
|
|
3
3
|
import { VTextField } from 'vuetify/components'
|
|
4
|
-
import { getInputProps } from '../../utils/
|
|
5
|
-
import { getCompSlots } from '../../utils/slots.js'
|
|
4
|
+
import { getInputProps, getCompSlots } from '../../utils/index.js'
|
|
6
5
|
|
|
7
6
|
export default defineComponent({
|
|
8
7
|
props: {
|
|
9
8
|
modelValue: {
|
|
10
|
-
/** @type import('vue').PropType<import('
|
|
9
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfTextFieldNode> */
|
|
11
10
|
type: Object,
|
|
12
11
|
required: true
|
|
13
12
|
},
|
|
14
13
|
statefulLayout: {
|
|
15
|
-
/** @type import('vue').PropType<import('
|
|
14
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfStatefulLayout> */
|
|
16
15
|
type: Object,
|
|
17
16
|
required: true
|
|
18
17
|
}
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { defineComponent, h, computed, ref, watch } from 'vue'
|
|
3
3
|
import { VTextarea } from 'vuetify/components'
|
|
4
|
-
import { getInputProps } from '../../utils/
|
|
5
|
-
import { getCompSlots } from '../../utils/slots.js'
|
|
4
|
+
import { getInputProps, getCompSlots } from '../../utils/index.js'
|
|
6
5
|
|
|
7
6
|
export default defineComponent({
|
|
8
7
|
props: {
|
|
9
8
|
modelValue: {
|
|
10
|
-
/** @type import('vue').PropType<import('
|
|
9
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfTextareaNode> */
|
|
11
10
|
type: Object,
|
|
12
11
|
required: true
|
|
13
12
|
},
|
|
14
13
|
statefulLayout: {
|
|
15
|
-
/** @type import('vue').PropType<import('
|
|
14
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfStatefulLayout> */
|
|
16
15
|
type: Object,
|
|
17
16
|
required: true
|
|
18
17
|
}
|
|
@@ -7,12 +7,12 @@ import SectionHeader from '../fragments/section-header.vue'
|
|
|
7
7
|
|
|
8
8
|
defineProps({
|
|
9
9
|
modelValue: {
|
|
10
|
-
/** @type import('vue').PropType<import('
|
|
10
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfVerticalTabsNode> */
|
|
11
11
|
type: Object,
|
|
12
12
|
required: true
|
|
13
13
|
},
|
|
14
14
|
statefulLayout: {
|
|
15
|
-
/** @type import('vue').PropType<import('
|
|
15
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfStatefulLayout> */
|
|
16
16
|
type: Object,
|
|
17
17
|
required: true
|
|
18
18
|
}
|
|
@@ -58,7 +58,7 @@ const tab = ref(0)
|
|
|
58
58
|
<node
|
|
59
59
|
v-for="grandChild of isSection(child) ? child.children : [child]"
|
|
60
60
|
:key="grandChild.fullKey"
|
|
61
|
-
:model-value="/** @type import('
|
|
61
|
+
:model-value="/** @type import('../../types.js').VjsfNode */(grandChild)"
|
|
62
62
|
:stateful-layout="statefulLayout"
|
|
63
63
|
/>
|
|
64
64
|
</v-row>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @type import("
|
|
1
|
+
/** @type import("../types.js").PartialVjsfOptions */
|
|
2
2
|
export const defaultOptions = {
|
|
3
3
|
// matches the density prop found in many vuetify components
|
|
4
4
|
density: 'default',
|
|
@@ -22,25 +22,28 @@ export const defaultOptions = {
|
|
|
22
22
|
switchProps: { hideDetails: 'auto' },
|
|
23
23
|
switchPropsReadOnly: {},
|
|
24
24
|
errorAlertProps: { type: 'error', variant: 'tonal' },
|
|
25
|
-
easyMDEOptions: {}
|
|
25
|
+
easyMDEOptions: {},
|
|
26
|
+
nodeComponents: {}
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
30
|
*
|
|
30
|
-
* @param {Partial<import("
|
|
31
|
+
* @param {Partial<import("../types.js").VjsfOptions>} options
|
|
31
32
|
* @param {any} form
|
|
32
33
|
* @param {number} width
|
|
33
34
|
* @param {import("vue").Slots} slots
|
|
35
|
+
* @param {Record<string, import('vue').Component>} nodeComponents
|
|
34
36
|
* @returns
|
|
35
37
|
*/
|
|
36
|
-
export const getFullOptions = (options, form, width, slots) => {
|
|
38
|
+
export const getFullOptions = (options, form, width, slots, nodeComponents) => {
|
|
37
39
|
const fullOptions = {
|
|
38
40
|
...defaultOptions,
|
|
39
41
|
readOnly: !!(form && (form.isDisabled.value || form.isReadonly.value)),
|
|
40
42
|
...options,
|
|
41
43
|
context: options.context ? JSON.parse(JSON.stringify(options.context)) : {},
|
|
42
44
|
width: Math.round(width ?? 0),
|
|
43
|
-
vjsfSlots: { ...slots }
|
|
45
|
+
vjsfSlots: { ...slots },
|
|
46
|
+
nodeComponents: { ...nodeComponents, ...options.nodeComponents }
|
|
44
47
|
}
|
|
45
|
-
return /** @type import('
|
|
48
|
+
return /** @type import('../types.js').VjsfOptions */ (fullOptions)
|
|
46
49
|
}
|
package/src/components/tree.vue
CHANGED
|
@@ -9,7 +9,7 @@ defineProps({
|
|
|
9
9
|
required: true
|
|
10
10
|
},
|
|
11
11
|
statefulLayout: {
|
|
12
|
-
/** @type import('vue').PropType<import('
|
|
12
|
+
/** @type import('vue').PropType<import('../types.js').VjsfStatefulLayout> */
|
|
13
13
|
type: Object,
|
|
14
14
|
required: true
|
|
15
15
|
}
|
|
@@ -20,7 +20,7 @@ defineProps({
|
|
|
20
20
|
<v-row class="vjsf-tree">
|
|
21
21
|
<node
|
|
22
22
|
:stateful-layout="statefulLayout"
|
|
23
|
-
:model-value="/** @type import('
|
|
23
|
+
:model-value="/** @type import('../types.js').VjsfNode */(modelValue.root)"
|
|
24
24
|
/>
|
|
25
25
|
</v-row>
|
|
26
26
|
</template>
|
package/src/components/vjsf.vue
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed
|
|
2
|
+
import { computed } from 'vue'
|
|
3
3
|
|
|
4
4
|
import { compile } from '@json-layout/core'
|
|
5
5
|
import Tree from './tree.vue'
|
|
6
6
|
import { useVjsf, emits } from '../composables/use-vjsf.js'
|
|
7
7
|
import '../styles/vjsf.css'
|
|
8
|
+
import { registeredNodeComponents } from '../utils/index.js'
|
|
8
9
|
|
|
9
10
|
import NodeSection from './nodes/section.vue'
|
|
10
11
|
import NodeTextField from './nodes/text-field.vue'
|
|
@@ -26,9 +27,10 @@ import NodeNumberCombobox from './nodes/number-combobox.vue'
|
|
|
26
27
|
import NodeExpansionPanels from './nodes/expansion-panels.vue'
|
|
27
28
|
import NodeStepper from './nodes/stepper.vue'
|
|
28
29
|
import NodeList from './nodes/list.vue'
|
|
29
|
-
import
|
|
30
|
+
import NodeFileInput from './nodes/file-input.vue'
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
/** @type {Record<string, import('vue').Component>} */
|
|
33
|
+
const nodeComponents = {
|
|
32
34
|
section: NodeSection,
|
|
33
35
|
'text-field': NodeTextField,
|
|
34
36
|
textarea: NodeTextarea,
|
|
@@ -49,14 +51,8 @@ const comps = {
|
|
|
49
51
|
list: NodeList,
|
|
50
52
|
combobox: NodeCombobox,
|
|
51
53
|
'number-combobox': NodeNumberCombobox,
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const instance = getCurrentInstance()
|
|
56
|
-
for (const [name, comp] of Object.entries(comps)) {
|
|
57
|
-
if (!instance?.appContext.app.component(`vjsf-node-${name}`)) {
|
|
58
|
-
instance?.appContext.app.component(`vjsf-node-${name}`, comp)
|
|
59
|
-
}
|
|
54
|
+
'file-input': NodeFileInput,
|
|
55
|
+
...registeredNodeComponents
|
|
60
56
|
}
|
|
61
57
|
|
|
62
58
|
const props = defineProps({
|
|
@@ -74,7 +70,7 @@ const props = defineProps({
|
|
|
74
70
|
default: null
|
|
75
71
|
},
|
|
76
72
|
options: {
|
|
77
|
-
/** @type import('vue').PropType<import('
|
|
73
|
+
/** @type import('vue').PropType<import('../types.js').PartialVjsfOptions> */
|
|
78
74
|
type: Object,
|
|
79
75
|
required: true
|
|
80
76
|
}
|
|
@@ -86,6 +82,7 @@ const { el, statefulLayout, stateTree } = useVjsf(
|
|
|
86
82
|
computed(() => props.schema),
|
|
87
83
|
computed(() => props.modelValue),
|
|
88
84
|
computed(() => props.options),
|
|
85
|
+
nodeComponents,
|
|
89
86
|
emit,
|
|
90
87
|
compile,
|
|
91
88
|
computed(() => props.precompiledLayout)
|
|
@@ -100,7 +97,6 @@ const { el, statefulLayout, stateTree } = useVjsf(
|
|
|
100
97
|
>
|
|
101
98
|
<tree
|
|
102
99
|
v-if="statefulLayout && stateTree"
|
|
103
|
-
ref="tree"
|
|
104
100
|
:model-value="stateTree"
|
|
105
101
|
:stateful-layout="statefulLayout"
|
|
106
102
|
/>
|
|
@@ -9,7 +9,7 @@ export const emits = {
|
|
|
9
9
|
*/
|
|
10
10
|
'update:modelValue': (data) => true,
|
|
11
11
|
/**
|
|
12
|
-
* @arg {
|
|
12
|
+
* @arg {import('../types.js').VjsfStatefulLayout} state
|
|
13
13
|
*/
|
|
14
14
|
'update:state': (state) => true
|
|
15
15
|
}
|
|
@@ -17,16 +17,17 @@ export const emits = {
|
|
|
17
17
|
/**
|
|
18
18
|
* @param {import('vue').Ref<Object>} schema
|
|
19
19
|
* @param {import('vue').Ref<any>} modelValue
|
|
20
|
-
* @param {import('vue').Ref<import("../
|
|
20
|
+
* @param {import('vue').Ref<import("../types.js").PartialVjsfOptions>} options
|
|
21
|
+
* @param {Record<string, import('vue').Component>} nodeComponents
|
|
21
22
|
* @param {any} emit
|
|
22
23
|
* @param {typeof import('@json-layout/core').compile} [compile]
|
|
23
24
|
* @param {import('vue').Ref<import('@json-layout/core').CompiledLayout>} [precompiledLayout]
|
|
24
25
|
*/
|
|
25
|
-
export const useVjsf = (schema, modelValue, options, emit, compile, precompiledLayout) => {
|
|
26
|
+
export const useVjsf = (schema, modelValue, options, nodeComponents, emit, compile, precompiledLayout) => {
|
|
26
27
|
const el = ref(null)
|
|
27
28
|
const { width } = useElementSize(el)
|
|
28
29
|
|
|
29
|
-
/** @type import('vue').ShallowRef<
|
|
30
|
+
/** @type import('vue').ShallowRef<import('../types.js').VjsfStatefulLayout | null> */
|
|
30
31
|
const statefulLayout = shallowRef(null)
|
|
31
32
|
/** @type import('vue').ShallowRef<import('@json-layout/core').StateTree | null> */
|
|
32
33
|
const stateTree = shallowRef(null)
|
|
@@ -47,7 +48,7 @@ export const useVjsf = (schema, modelValue, options, emit, compile, precompiledL
|
|
|
47
48
|
|
|
48
49
|
const slots = useSlots()
|
|
49
50
|
|
|
50
|
-
const fullOptions = computed(() => getFullOptions(options.value, form, width.value, slots))
|
|
51
|
+
const fullOptions = computed(() => getFullOptions(options.value, form, width.value, slots, nodeComponents))
|
|
51
52
|
|
|
52
53
|
const compiledLayout = computed(() => {
|
|
53
54
|
if (precompiledLayout?.value) return precompiledLayout?.value
|
|
@@ -71,12 +72,13 @@ export const useVjsf = (schema, modelValue, options, emit, compile, precompiledL
|
|
|
71
72
|
|
|
72
73
|
const initStatefulLayout = () => {
|
|
73
74
|
if (!width.value) return
|
|
74
|
-
|
|
75
|
+
// @ts-ignore
|
|
76
|
+
const _statefulLayout = /** @type {import('../types.js').VjsfStatefulLayout} */(new StatefulLayout(
|
|
75
77
|
toRaw(compiledLayout.value),
|
|
76
78
|
toRaw(compiledLayout.value.skeletonTree),
|
|
77
79
|
toRaw(fullOptions.value),
|
|
78
80
|
toRaw(modelValue.value)
|
|
79
|
-
)
|
|
81
|
+
))
|
|
80
82
|
statefulLayout.value = _statefulLayout
|
|
81
83
|
onStatefulLayoutUpdate()
|
|
82
84
|
_statefulLayout.events.on('update', () => {
|
|
@@ -84,7 +86,6 @@ export const useVjsf = (schema, modelValue, options, emit, compile, precompiledL
|
|
|
84
86
|
})
|
|
85
87
|
emit('update:state', _statefulLayout)
|
|
86
88
|
_statefulLayout.events.on('autofocus', () => {
|
|
87
|
-
console.log('autofocus ?')
|
|
88
89
|
if (!el.value) return
|
|
89
90
|
// @ts-ignore
|
|
90
91
|
const autofocusNodeElement = el.value.querySelector('.vjsf-input--autofocus')
|
package/src/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { Component } from 'vue'
|
|
2
|
+
|
|
1
3
|
import {
|
|
4
|
+
StatefulLayout,
|
|
2
5
|
StatefulLayoutOptions,
|
|
3
6
|
StateNode,
|
|
4
7
|
CheckboxNode,
|
|
@@ -19,12 +22,14 @@ import {
|
|
|
19
22
|
VerticalTabsNode,
|
|
20
23
|
StepperNode,
|
|
21
24
|
ComboboxNode,
|
|
25
|
+
MarkdownNode,
|
|
26
|
+
FileInputNode,
|
|
22
27
|
CompileOptions
|
|
23
28
|
} from '@json-layout/core'
|
|
24
29
|
|
|
25
30
|
export type Density = 'default' | 'comfortable' | 'compact'
|
|
26
31
|
|
|
27
|
-
export type
|
|
32
|
+
export type VjsfStatefulLayoutOptions = StatefulLayoutOptions & {
|
|
28
33
|
density: Density,
|
|
29
34
|
fieldProps: Record<string, unknown>,
|
|
30
35
|
fieldPropsCompact: Record<string, unknown>,
|
|
@@ -41,8 +46,18 @@ export type VjsfOptions = StatefulLayoutOptions & CompileOptions & {
|
|
|
41
46
|
errorAlertProps: Record<string, unknown>,
|
|
42
47
|
vjsfSlots: Record<string, () => unknown>,
|
|
43
48
|
easyMDEOptions: Record<string, unknown>,
|
|
49
|
+
nodeComponents: Record<string, Component>,
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type VjsfCompileOptions = CompileOptions & {
|
|
53
|
+
nodeComponentImports: Record<string, string>
|
|
44
54
|
}
|
|
45
55
|
|
|
56
|
+
export type VjsfOptions = VjsfCompileOptions & VjsfStatefulLayoutOptions
|
|
57
|
+
|
|
58
|
+
export type VjsfStatefulLayout = Omit<StatefulLayout, 'options'> & {options: VjsfStatefulLayoutOptions}
|
|
59
|
+
|
|
60
|
+
export type PartialVjsfCompileOptions = Partial<Omit<VjsfCompileOptions, 'width'>>
|
|
46
61
|
export type PartialVjsfOptions = Partial<Omit<VjsfOptions, 'width'>>
|
|
47
62
|
|
|
48
63
|
export type VjsfNode = Omit<StateNode, 'options'> & {options: VjsfOptions}
|
|
@@ -61,7 +76,8 @@ export type VjsfSliderNode = Omit<SliderNode, 'options'> & {options: VjsfOptions
|
|
|
61
76
|
export type VjsfSwitchNode = Omit<SwitchNode, 'options'> & {options: VjsfOptions}
|
|
62
77
|
export type VjsfTextFieldNode = Omit<TextFieldNode, 'options'> & {options: VjsfOptions}
|
|
63
78
|
export type VjsfTextareaNode = Omit<TextareaNode, 'options'> & {options: VjsfOptions}
|
|
79
|
+
export type VjsfMarkdownNode = Omit<MarkdownNode, 'options'> & {options: VjsfOptions}
|
|
64
80
|
export type VjsfVerticalTabsNode = Omit<VerticalTabsNode, 'options'> & {options: VjsfOptions}
|
|
65
81
|
export type VjsfStepperNode = Omit<StepperNode, 'options'> & {options: VjsfOptions}
|
|
66
|
-
|
|
67
82
|
export type VjsfComboboxNode = Omit<ComboboxNode, 'options'> & {options: VjsfOptions}
|
|
83
|
+
export type VjsfFileInputNode = Omit<FileInputNode, 'options'> & {options: VjsfOptions}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** @type {Record<string, import('vue').Component>} */
|
|
2
|
+
export const registeredNodeComponents = {}
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @param {string} name
|
|
6
|
+
* @param {import('vue').Component} component
|
|
7
|
+
*/
|
|
8
|
+
export function registerNodeComponent (name, component) {
|
|
9
|
+
registeredNodeComponents[name] = component
|
|
10
|
+
}
|
package/src/utils/props.js
CHANGED
|
@@ -29,14 +29,14 @@ export function mergePropsLevels (propsLevels) {
|
|
|
29
29
|
// calculate the props of a field/input type component (text fields, etc)
|
|
30
30
|
// isMainComp is used to determine if this input component is also the main rendered component or if is mostly a wrapper (date picker, etc.)
|
|
31
31
|
/**
|
|
32
|
-
* @param {import('
|
|
33
|
-
* @param {import('
|
|
32
|
+
* @param {import('../types.js').VjsfNode} node
|
|
33
|
+
* @param {import('../types.js').VjsfStatefulLayout} statefulLayout
|
|
34
34
|
* @param {(string | [string, string])[]} [layoutPropsMap]
|
|
35
35
|
* @param {boolean} isMainComp
|
|
36
36
|
* @returns {Record<string, any>}
|
|
37
37
|
*/
|
|
38
38
|
export function getInputProps (node, statefulLayout, layoutPropsMap, isMainComp = true) {
|
|
39
|
-
const options =
|
|
39
|
+
const options = node.options
|
|
40
40
|
/** @type {(Record<string, any> | undefined)[]} */
|
|
41
41
|
const propsLevels = [options.fieldProps]
|
|
42
42
|
if (options.density === 'comfortable') propsLevels.push(options.fieldPropsComfortable)
|
|
@@ -86,7 +86,7 @@ export function getInputProps (node, statefulLayout, layoutPropsMap, isMainComp
|
|
|
86
86
|
* @returns {Record<string, any>}
|
|
87
87
|
*/
|
|
88
88
|
export function getCompProps (node, comp, isMainComp = true) {
|
|
89
|
-
const options = /** @type import('../
|
|
89
|
+
const options = /** @type import('../types.js').VjsfOptions */(node.options)
|
|
90
90
|
/** @type {(Record<string, any> | undefined)[]} */
|
|
91
91
|
const propsLevels = [{ density: options.density }]
|
|
92
92
|
propsLevels.push(/** @type Record<string, any> | undefined */(options[`${comp}Props`]))
|
package/src/utils/slots.js
CHANGED
|
@@ -3,13 +3,12 @@ import NodeSlot from '../components/fragments/node-slot.vue'
|
|
|
3
3
|
|
|
4
4
|
// calculate the slots of components
|
|
5
5
|
/**
|
|
6
|
-
* @param {import('
|
|
7
|
-
* @param {import('
|
|
6
|
+
* @param {import('../types.js').VjsfNode} node
|
|
7
|
+
* @param {import('../types.js').VjsfStatefulLayout} statefulLayout
|
|
8
8
|
* @returns {Record<string, any>}
|
|
9
9
|
*/
|
|
10
10
|
export function getCompSlots (node, statefulLayout) {
|
|
11
11
|
if (!node.layout.slots) return {}
|
|
12
|
-
// const options = /** @type import('../components/types.js').VjsfOptions */(node.options)
|
|
13
12
|
/** @type {Record<string, any>} */
|
|
14
13
|
const slots = {}
|
|
15
14
|
for (const [key, layoutSlot] of Object.entries(node.layout.slots)) {
|
package/types/compile/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @param {object} schema
|
|
3
|
-
* @param {
|
|
3
|
+
* @param {import('../types.js').PartialVjsfCompileOptions} [options]
|
|
4
|
+
* @param {string} [baseImport]
|
|
4
5
|
* @returns {string}
|
|
5
6
|
*/
|
|
6
|
-
export function compile(schema: object, baseImport?: string): string;
|
|
7
|
+
export function compile(schema: object, options?: Partial<Omit<import("../types.js").VjsfCompileOptions, "width">> | undefined, baseImport?: string | undefined): string;
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/compile/index.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/compile/index.js"],"names":[],"mappings":"AAmCA;;;;;GAKG;AACH,gCALW,MAAM,4HAGJ,MAAM,CAyBlB"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** @type import("../types.js").PartialVjsfCompileOptions */
|
|
2
|
+
export const defaultOptions: import("../types.js").PartialVjsfCompileOptions;
|
|
3
|
+
export function getFullOptions(options: import("../types.js").PartialVjsfCompileOptions): import("../types.js").VjsfCompileOptions;
|
|
4
|
+
//# sourceMappingURL=options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/compile/options.js"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,6BADU,OAAO,aAAa,EAAE,yBAAyB,CAKxD;AAOM,wCAHI,OAAO,aAAa,EAAE,yBAAyB,4CASzD"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
declare const _default: import("vue").DefineComponent<{}, {
|
|
2
|
-
node: import("
|
|
2
|
+
node: import("../../types.js").VjsfNode;
|
|
3
3
|
$props: {
|
|
4
|
-
readonly node?: import("
|
|
4
|
+
readonly node?: import("../../types.js").VjsfNode | undefined;
|
|
5
5
|
};
|
|
6
6
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
|
|
7
7
|
export default _default;
|
|
@@ -5,13 +5,13 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
5
5
|
required: true;
|
|
6
6
|
};
|
|
7
7
|
node: {
|
|
8
|
-
/** @type import('vue').PropType<import('
|
|
9
|
-
type: import('vue').PropType<import('
|
|
8
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfNode> */
|
|
9
|
+
type: import('vue').PropType<import('../../types.js').VjsfNode>;
|
|
10
10
|
required: true;
|
|
11
11
|
};
|
|
12
12
|
statefulLayout: {
|
|
13
|
-
/** @type import('vue').PropType<import('
|
|
14
|
-
type: import('vue').PropType<import('
|
|
13
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfStatefulLayout> */
|
|
14
|
+
type: import('vue').PropType<import('../../types.js').VjsfStatefulLayout>;
|
|
15
15
|
required: true;
|
|
16
16
|
};
|
|
17
17
|
tag: {
|
|
@@ -26,13 +26,13 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
26
26
|
required: true;
|
|
27
27
|
};
|
|
28
28
|
node: {
|
|
29
|
-
/** @type import('vue').PropType<import('
|
|
30
|
-
type: import('vue').PropType<import('
|
|
29
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfNode> */
|
|
30
|
+
type: import('vue').PropType<import('../../types.js').VjsfNode>;
|
|
31
31
|
required: true;
|
|
32
32
|
};
|
|
33
33
|
statefulLayout: {
|
|
34
|
-
/** @type import('vue').PropType<import('
|
|
35
|
-
type: import('vue').PropType<import('
|
|
34
|
+
/** @type import('vue').PropType<import('../../types.js').VjsfStatefulLayout> */
|
|
35
|
+
type: import('vue').PropType<import('../../types.js').VjsfStatefulLayout>;
|
|
36
36
|
required: true;
|
|
37
37
|
};
|
|
38
38
|
tag: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-slot.vue.d.ts","sourceRoot":"","sources":["../../../src/components/fragments/node-slot.vue.js"],"names":[],"mappings":";;QAUM,2EAA2E;cAAjE,OAAO,KAAK,EAAE,QAAQ,CAAC,OAAO,yBAAyB,EAAE,IAAI,CAAC;;;;QAKxE,
|
|
1
|
+
{"version":3,"file":"node-slot.vue.d.ts","sourceRoot":"","sources":["../../../src/components/fragments/node-slot.vue.js"],"names":[],"mappings":";;QAUM,2EAA2E;cAAjE,OAAO,KAAK,EAAE,QAAQ,CAAC,OAAO,yBAAyB,EAAE,IAAI,CAAC;;;;QAKxE,sEAAsE;cAA5D,OAAO,KAAK,EAAE,QAAQ,CAAC,OAAO,gBAAgB,EAAE,QAAQ,CAAC;;;;QAKnE,gFAAgF;cAAtE,OAAO,KAAK,EAAE,QAAQ,CAAC,OAAO,gBAAgB,EAAE,kBAAkB,CAAC;;;;QAK7E,2CAA2C;cAAjC,OAAO,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC;;;;;QAfxC,2EAA2E;cAAjE,OAAO,KAAK,EAAE,QAAQ,CAAC,OAAO,yBAAyB,EAAE,IAAI,CAAC;;;;QAKxE,sEAAsE;cAA5D,OAAO,KAAK,EAAE,QAAQ,CAAC,OAAO,gBAAgB,EAAE,QAAQ,CAAC;;;;QAKnE,gFAAgF;cAAtE,OAAO,KAAK,EAAE,QAAQ,CAAC,OAAO,gBAAgB,EAAE,kBAAkB,CAAC;;;;QAK7E,2CAA2C;cAAjC,OAAO,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
declare const _default: import("vue").DefineComponent<{}, {
|
|
2
|
-
node: import("
|
|
2
|
+
node: import("../../types.js").VjsfNode;
|
|
3
3
|
$props: {
|
|
4
|
-
readonly node?: import("
|
|
4
|
+
readonly node?: import("../../types.js").VjsfNode | undefined;
|
|
5
5
|
};
|
|
6
6
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
|
|
7
7
|
export default _default;
|