@bagelink/vue 1.2.81 → 1.2.85
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/dist/components/AddressSearch.vue.d.ts.map +1 -1
- package/dist/components/Btn.vue.d.ts +1 -1
- package/dist/components/Btn.vue.d.ts.map +1 -1
- package/dist/components/DataPreview.vue.d.ts +16 -5
- package/dist/components/DataPreview.vue.d.ts.map +1 -1
- package/dist/components/Dropdown.vue.d.ts.map +1 -1
- package/dist/components/Icon/Icon.vue.d.ts +4 -1
- package/dist/components/Icon/Icon.vue.d.ts.map +1 -1
- package/dist/components/ModalForm.vue.d.ts +2 -1
- package/dist/components/ModalForm.vue.d.ts.map +1 -1
- package/dist/components/calendar/views/CalendarPopover.vue.d.ts +2 -2
- package/dist/components/calendar/views/CalendarPopover.vue.d.ts.map +1 -1
- package/dist/components/dataTable/DataTable.vue.d.ts.map +1 -1
- package/dist/components/dataTable/useSorting.d.ts +1 -1
- package/dist/components/dataTable/useSorting.d.ts.map +1 -1
- package/dist/components/dataTable/useTableData.d.ts +7 -6
- package/dist/components/dataTable/useTableData.d.ts.map +1 -1
- package/dist/components/dataTable/useTableVirtualization.d.ts.map +1 -1
- package/dist/components/form/BagelForm.vue.d.ts +4 -10
- package/dist/components/form/BagelForm.vue.d.ts.map +1 -1
- package/dist/components/form/BglMultiStepForm.vue.d.ts +6 -4
- package/dist/components/form/BglMultiStepForm.vue.d.ts.map +1 -1
- package/dist/components/form/FieldArray.vue.d.ts +3 -2
- package/dist/components/form/FieldArray.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
- package/dist/composables/index.d.ts +5 -5
- package/dist/composables/index.d.ts.map +1 -1
- package/dist/composables/useSchemaField.d.ts +5 -12
- package/dist/composables/useSchemaField.d.ts.map +1 -1
- package/dist/index.cjs +146 -230
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +147 -231
- package/dist/plugins/modalTypes.d.ts +3 -2
- package/dist/plugins/modalTypes.d.ts.map +1 -1
- package/dist/style.css +183 -183
- package/dist/types/BagelForm.d.ts +12 -9
- package/dist/types/BagelForm.d.ts.map +1 -1
- package/dist/types/TableSchema.d.ts +9 -9
- package/dist/types/TableSchema.d.ts.map +1 -1
- package/dist/types/timeago.d.ts +23 -0
- package/dist/types/timeago.d.ts.map +1 -0
- package/dist/utils/BagelFormUtils.d.ts +5 -3
- package/dist/utils/BagelFormUtils.d.ts.map +1 -1
- package/dist/utils/useSearch.d.ts +44 -0
- package/dist/utils/useSearch.d.ts.map +1 -0
- package/package.json +2 -2
- package/src/components/DataPreview.vue +16 -5
- package/src/components/Icon/Icon.vue +12 -3
- package/src/components/ModalForm.vue +6 -9
- package/src/components/dataTable/DataTable.vue +11 -14
- package/src/components/dataTable/useSorting.ts +1 -1
- package/src/components/dataTable/useTableData.ts +19 -42
- package/src/components/dataTable/useTableVirtualization.ts +4 -8
- package/src/components/form/BagelForm.vue +32 -97
- package/src/components/form/BglMultiStepForm.vue +9 -7
- package/src/components/form/FieldArray.vue +54 -45
- package/src/components/form/inputs/RichText/index.vue +1 -1
- package/src/composables/index.ts +12 -13
- package/src/composables/useSchemaField.ts +36 -34
- package/src/index.ts +1 -1
- package/src/plugins/modalTypes.ts +3 -2
- package/src/types/BagelForm.ts +21 -13
- package/src/types/TableSchema.ts +9 -9
- package/src/utils/BagelFormUtils.ts +6 -4
- package/src/utils/{search.ts → useSearch.ts} +1 -2
- package/dist/components/Carousel2.vue.d.ts +0 -89
- package/dist/components/Carousel2.vue.d.ts.map +0 -1
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
<script setup lang="ts" generic="T extends {[key:string]:any}, P">
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
import {
|
|
5
|
-
import { onMounted, watch, ref, toRef, computed } from 'vue'
|
|
1
|
+
<script setup lang="ts" generic="T extends {[key:string]:any}, P extends Path<T>">
|
|
2
|
+
import type { Field, BglFormSchemaT, Path, BaseBagelField } from '@bagelink/vue'
|
|
3
|
+
import type { MaybeRefOrGetter } from 'vue'
|
|
4
|
+
import { onMounted, watch, ref, computed, toValue } from 'vue'
|
|
6
5
|
import { useSchemaField } from '../../composables/useSchemaField'
|
|
7
6
|
import { getNestedValue } from '../../utils'
|
|
8
7
|
|
|
9
8
|
const props = withDefaults(defineProps<{
|
|
10
9
|
modelValue?: T
|
|
11
|
-
schema?:
|
|
10
|
+
schema?: MaybeRefOrGetter<BglFormSchemaT<T>>
|
|
12
11
|
tag?: 'form' | 'template'
|
|
13
12
|
class?: string
|
|
14
13
|
onSubmit?: (data: T) => Promise<unknown> | unknown
|
|
@@ -31,10 +30,8 @@ const form = ref<HTMLFormElement>()
|
|
|
31
30
|
const formData = ref<T>(clone(props.modelValue ?? {}) as T)
|
|
32
31
|
const initialFormData = ref<T>(clone(props.modelValue ?? {}) as T)
|
|
33
32
|
const formState = ref<'success' | 'error' | 'idle' | 'submitting'>('idle')
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
const schemaRef = toRef(props, 'schema')
|
|
37
|
-
const resolvedSchema = computed(() => resolvedSchemaData.value)
|
|
33
|
+
const resolvedSchema = computed(() => toValue(props.schema))
|
|
34
|
+
|
|
38
35
|
const isDirty = computed(() => {
|
|
39
36
|
try {
|
|
40
37
|
return JSON.stringify(formData.value) !== JSON.stringify(initialFormData.value)
|
|
@@ -46,7 +43,6 @@ const isDirty = computed(() => {
|
|
|
46
43
|
// Initialize on mount
|
|
47
44
|
onMounted(() => {
|
|
48
45
|
if (props.modelValue) initialFormData.value = clone(props.modelValue)
|
|
49
|
-
refreshSchema()
|
|
50
46
|
})
|
|
51
47
|
|
|
52
48
|
// Watch for model changes
|
|
@@ -54,47 +50,9 @@ watch(() => props.modelValue, (val) => {
|
|
|
54
50
|
if (val !== undefined) formData.value = clone(val)
|
|
55
51
|
}, { immediate: true, deep: true })
|
|
56
52
|
|
|
57
|
-
// Schema resolution
|
|
58
|
-
async function resolveSchema(schema?: BglFormSchemaFnT<T>) {
|
|
59
|
-
if (!schema) {
|
|
60
|
-
resolvedSchemaData.value = undefined
|
|
61
|
-
schemaState.value = 'loaded'
|
|
62
|
-
return
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
try {
|
|
66
|
-
schemaState.value = 'loading'
|
|
67
|
-
const isPromise = (obj: any) => obj && typeof obj.then === 'function'
|
|
68
|
-
|
|
69
|
-
let result: any
|
|
70
|
-
if (typeof schema === 'function') {
|
|
71
|
-
result = schema()
|
|
72
|
-
result = isPromise(result) ? await result : result
|
|
73
|
-
} else {
|
|
74
|
-
result = isPromise(schema) ? await schema : schema
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
resolvedSchemaData.value = result
|
|
78
|
-
schemaState.value = 'loaded'
|
|
79
|
-
} catch (error) {
|
|
80
|
-
console.error('Schema error:', error)
|
|
81
|
-
schemaState.value = 'error'
|
|
82
|
-
resolvedSchemaData.value = undefined
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Public refresh method
|
|
87
|
-
async function refreshSchema() {
|
|
88
|
-
await resolveSchema(props.schema)
|
|
89
|
-
return resolvedSchemaData.value
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Watch schema changes
|
|
93
|
-
watch(schemaRef, resolveSchema, { immediate: true, deep: true })
|
|
94
|
-
|
|
95
53
|
// Update form data
|
|
96
|
-
function updateFormData(fieldId: string, value: any) {
|
|
97
|
-
const keys = fieldId
|
|
54
|
+
function updateFormData({ fieldId, value }: { fieldId?: string, value: any }) {
|
|
55
|
+
const keys = fieldId?.split('.') || []
|
|
98
56
|
const newData = clone(formData.value) as { [key: string]: any }
|
|
99
57
|
let current = newData
|
|
100
58
|
|
|
@@ -131,7 +89,7 @@ async function handleSubmit() {
|
|
|
131
89
|
}
|
|
132
90
|
}
|
|
133
91
|
|
|
134
|
-
// Field
|
|
92
|
+
// Field renderingks
|
|
135
93
|
const { renderField } = useSchemaField<T, P>({
|
|
136
94
|
mode: 'form',
|
|
137
95
|
getFormData: () => ({
|
|
@@ -141,23 +99,23 @@ const { renderField } = useSchemaField<T, P>({
|
|
|
141
99
|
onUpdateModelValue: (field, value) => {
|
|
142
100
|
if (!field.id) return
|
|
143
101
|
|
|
144
|
-
updateFormData(field.id, value)
|
|
102
|
+
updateFormData({ fieldId: field.id, value })
|
|
145
103
|
field.onUpdate?.(value, formData.value)
|
|
146
104
|
}
|
|
147
105
|
})
|
|
148
106
|
|
|
149
|
-
const renderSchemaField = (field: Field<T>)
|
|
107
|
+
const renderSchemaField = (field: Field<T>) => renderField(field as BaseBagelField<T, P>)
|
|
150
108
|
|
|
151
109
|
// Add new method to handle slot input changes
|
|
152
110
|
function handleSlotInputChange(event: Event) {
|
|
153
111
|
const input = event.target as HTMLInputElement
|
|
154
112
|
if (input.name) {
|
|
155
113
|
const value = input.type === 'checkbox' ? input.checked : input.value
|
|
156
|
-
updateFormData(input.name, value)
|
|
114
|
+
updateFormData({ fieldId: input.name, value })
|
|
157
115
|
}
|
|
158
116
|
}
|
|
159
117
|
|
|
160
|
-
defineExpose({ form, isDirty, validateForm,
|
|
118
|
+
defineExpose({ form, isDirty, validateForm, checkValidity })
|
|
161
119
|
</script>
|
|
162
120
|
|
|
163
121
|
<template>
|
|
@@ -168,27 +126,14 @@ defineExpose({ form, isDirty, validateForm, resolveSchema, refreshSchema, checkV
|
|
|
168
126
|
@submit.prevent="handleSubmit"
|
|
169
127
|
@input="handleSlotInputChange"
|
|
170
128
|
>
|
|
171
|
-
<!-- Loading state -->
|
|
172
|
-
<slot v-if="schemaState === 'loading'" name="loading">
|
|
173
|
-
<div class="flex-center h-300px">
|
|
174
|
-
<Loading />
|
|
175
|
-
</div>
|
|
176
|
-
</slot>
|
|
177
|
-
|
|
178
|
-
<!-- Error state -->
|
|
179
|
-
<slot v-else-if="schemaState === 'error'" name="schema-error">
|
|
180
|
-
<div class="flex-center h-300px txt-red">
|
|
181
|
-
Error loading form
|
|
182
|
-
</div>
|
|
183
|
-
</slot>
|
|
184
|
-
|
|
185
129
|
<!-- Render fields -->
|
|
186
|
-
<
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
130
|
+
<template v-if="resolvedSchema">
|
|
131
|
+
<Component
|
|
132
|
+
:is="renderSchemaField(field)"
|
|
133
|
+
v-for="field in resolvedSchema"
|
|
134
|
+
:key="field.id"
|
|
135
|
+
/>
|
|
136
|
+
</template>
|
|
192
137
|
|
|
193
138
|
<!-- Default slot -->
|
|
194
139
|
<slot v-else />
|
|
@@ -196,32 +141,22 @@ defineExpose({ form, isDirty, validateForm, resolveSchema, refreshSchema, checkV
|
|
|
196
141
|
<slot
|
|
197
142
|
name="submit"
|
|
198
143
|
:submit="handleSubmit"
|
|
199
|
-
:isDirty
|
|
200
|
-
:validateForm
|
|
201
|
-
:formState
|
|
202
|
-
:schemaState="schemaState"
|
|
144
|
+
:isDirty
|
|
145
|
+
:validateForm
|
|
146
|
+
:formState
|
|
203
147
|
/>
|
|
204
148
|
</form>
|
|
205
149
|
|
|
206
150
|
<!-- Template mode -->
|
|
207
151
|
<template v-else>
|
|
208
|
-
<
|
|
209
|
-
<
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
</slot>
|
|
217
|
-
|
|
218
|
-
<component
|
|
219
|
-
:is="renderSchemaField(field)"
|
|
220
|
-
v-for="field in resolvedSchema"
|
|
221
|
-
v-else-if="resolvedSchema"
|
|
222
|
-
:key="field.id"
|
|
223
|
-
:class="props.class"
|
|
224
|
-
/>
|
|
152
|
+
<template v-if="resolvedSchema">
|
|
153
|
+
<component
|
|
154
|
+
:is="renderSchemaField(field)"
|
|
155
|
+
v-for="field in resolvedSchema"
|
|
156
|
+
:key="field.id"
|
|
157
|
+
:class="props.class"
|
|
158
|
+
/>
|
|
159
|
+
</template>
|
|
225
160
|
</template>
|
|
226
161
|
</template>
|
|
227
162
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
<script setup lang="ts" generic="T extends {[key:string]:any}, P">
|
|
2
|
-
import type {
|
|
1
|
+
<script setup lang="ts" generic="T extends {[key:string]:any}, P extends Path<T>">
|
|
2
|
+
import type { BglFormSchemaT, Path } from '@bagelink/vue'
|
|
3
3
|
|
|
4
|
+
import type { MaybeRefOrGetter } from 'vue'
|
|
4
5
|
import type { ComponentExposed, ComponentProps } from 'vue-component-type-helpers'
|
|
5
6
|
import { BagelForm, Btn, useBglSchema, sleep } from '@bagelink/vue'
|
|
6
|
-
import { ref, watch, computed, nextTick } from 'vue'
|
|
7
|
+
import { ref, watch, computed, nextTick, toValue } from 'vue'
|
|
7
8
|
|
|
8
9
|
const props = withDefaults(
|
|
9
10
|
defineProps<{
|
|
@@ -13,7 +14,7 @@ const props = withDefaults(
|
|
|
13
14
|
'schema' | `${string}modelValue` | `ref${string}` | `onVnode${string}` | 'onSubmit'
|
|
14
15
|
)
|
|
15
16
|
>
|
|
16
|
-
schema?:
|
|
17
|
+
schema?: MaybeRefOrGetter<BglFormSchemaT<T>>
|
|
17
18
|
showProgress?: boolean
|
|
18
19
|
rtl?: boolean
|
|
19
20
|
stepLabels?: string[]
|
|
@@ -59,13 +60,13 @@ function reportValidity() {
|
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
const computedSchema = computed(
|
|
62
|
-
() => useBglSchema({ schema: props.schema })
|
|
63
|
+
() => useBglSchema({ schema: toValue(props.schema) })
|
|
63
64
|
)
|
|
64
65
|
|
|
65
66
|
// Filter out steps with vIf conditions that evaluate to false
|
|
66
67
|
const filteredSchema = computed(() => {
|
|
67
68
|
const schema = computedSchema.value
|
|
68
|
-
return schema.filter((step,
|
|
69
|
+
return schema.filter((step, _index) => {
|
|
69
70
|
// Skip steps that have vIf or v-if returning false
|
|
70
71
|
if (step.vIf !== undefined || step['v-if'] !== undefined) {
|
|
71
72
|
const condition = step.vIf ?? step['v-if']
|
|
@@ -220,8 +221,9 @@ defineExpose({
|
|
|
220
221
|
checkValidity: formRef.value?.checkValidity,
|
|
221
222
|
isDirty: computed(() => formRef.value?.isDirty),
|
|
222
223
|
reset,
|
|
224
|
+
isLastStep,
|
|
223
225
|
goToStep,
|
|
224
|
-
currentStep
|
|
226
|
+
currentStep,
|
|
225
227
|
totalSteps: computed(() => numberOfSteps.value),
|
|
226
228
|
isStepValid,
|
|
227
229
|
nextStep,
|
|
@@ -5,12 +5,13 @@ import type {
|
|
|
5
5
|
Attributes,
|
|
6
6
|
BagelFieldOptions,
|
|
7
7
|
BaseBagelField,
|
|
8
|
-
|
|
8
|
+
BglFormSchemaT,
|
|
9
9
|
Field,
|
|
10
10
|
Path
|
|
11
11
|
} from '@bagelink/vue'
|
|
12
|
+
import type { MaybeRefOrGetter } from 'vue'
|
|
12
13
|
import { BagelForm, Btn, Loading, Icon } from '@bagelink/vue'
|
|
13
|
-
import { ref,
|
|
14
|
+
import { ref, computed, watch, toValue } from 'vue'
|
|
14
15
|
|
|
15
16
|
export interface FieldArrayProps<T, P extends Path<T>> {
|
|
16
17
|
el?: any
|
|
@@ -28,7 +29,7 @@ export interface FieldArrayProps<T, P extends Path<T>> {
|
|
|
28
29
|
add?: boolean
|
|
29
30
|
delete?: boolean
|
|
30
31
|
transform?: (value: T) => T
|
|
31
|
-
schema?:
|
|
32
|
+
schema?: MaybeRefOrGetter<BglFormSchemaT<T>>
|
|
32
33
|
modelValue: T[]
|
|
33
34
|
type?: 'object' | 'number' | 'text'
|
|
34
35
|
}
|
|
@@ -53,12 +54,6 @@ const emit = defineEmits(['update:modelValue'])
|
|
|
53
54
|
const minimizedItems = ref<boolean[]>([])
|
|
54
55
|
const internalData = ref<any[]>(props.modelValue || [])
|
|
55
56
|
const schemaState = ref<'loading' | 'loaded' | 'error'>('loaded')
|
|
56
|
-
const resolvedSchemaData = ref<any[]>([])
|
|
57
|
-
|
|
58
|
-
// Watch for external changes to modelValue
|
|
59
|
-
watch(() => props.modelValue, (newValue) => {
|
|
60
|
-
internalData.value = newValue || []
|
|
61
|
-
}, { deep: true })
|
|
62
57
|
|
|
63
58
|
// Generate schema for primitive types
|
|
64
59
|
const primitiveSchema = computed<PrimitiveArrFieldT[]>(() => {
|
|
@@ -70,46 +65,57 @@ const primitiveSchema = computed<PrimitiveArrFieldT[]>(() => {
|
|
|
70
65
|
return []
|
|
71
66
|
})
|
|
72
67
|
|
|
68
|
+
const resolvedSchemaData = $computed(() => {
|
|
69
|
+
if (props.type !== 'object') return primitiveSchema.value as BglFormSchemaT<T>
|
|
70
|
+
|
|
71
|
+
return toValue(props.schema)
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
// Watch for external changes to modelValue
|
|
75
|
+
watch(() => props.modelValue, (newValue) => {
|
|
76
|
+
internalData.value = newValue || []
|
|
77
|
+
}, { deep: true })
|
|
78
|
+
|
|
73
79
|
// Resolve schema
|
|
74
|
-
async function resolveSchema() {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
// async function resolveSchema() {
|
|
81
|
+
// // For primitive types, use the predefined schemaks
|
|
82
|
+
// if (props.type !== 'object') {
|
|
83
|
+
// resolvedSchemaData.value = primitiveSchema.value
|
|
84
|
+
// schemaState.value = 'loaded'
|
|
85
|
+
// return
|
|
86
|
+
// }
|
|
81
87
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
// // For object type without schema
|
|
89
|
+
// if (!props.schema) {
|
|
90
|
+
// resolvedSchemaData.value = []
|
|
91
|
+
// schemaState.value = 'loaded'
|
|
92
|
+
// return
|
|
93
|
+
// }
|
|
88
94
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
95
|
+
// // For object type with schema
|
|
96
|
+
// try {
|
|
97
|
+
// // schemaState.value = 'loading'
|
|
98
|
+
// const isPromise = (obj: any) => obj && typeof obj.then === 'function'
|
|
93
99
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
100
|
+
// let result: any
|
|
101
|
+
// if (typeof props.schema === 'function') {
|
|
102
|
+
// result = props.schema()
|
|
103
|
+
// result = isPromise(result) ? await result : result
|
|
104
|
+
// } else {
|
|
105
|
+
// result = isPromise(props.schema) ? await props.schema : props.schema
|
|
106
|
+
// }
|
|
101
107
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
108
|
+
// resolvedSchemaData.value = result
|
|
109
|
+
// schemaState.value = 'loaded'
|
|
110
|
+
// } catch (error) {
|
|
111
|
+
// console.error('Schema error:', error)
|
|
112
|
+
// schemaState.value = 'error'
|
|
113
|
+
// resolvedSchemaData.value = []
|
|
114
|
+
// }
|
|
115
|
+
// }
|
|
110
116
|
|
|
111
|
-
// Initialize schema on mount
|
|
112
|
-
onMounted(resolveSchema)
|
|
117
|
+
// // Initialize schema on mount
|
|
118
|
+
// onMounted(resolveSchema)
|
|
113
119
|
|
|
114
120
|
// Event handlers
|
|
115
121
|
function emitValue() {
|
|
@@ -148,10 +154,13 @@ function updateItem(index: number, value: any) {
|
|
|
148
154
|
|
|
149
155
|
// Computed properties for rendering
|
|
150
156
|
const isPrimitiveType = computed(() => props.type === 'text' || props.type === 'number')
|
|
151
|
-
const canRenderItems = computed(
|
|
157
|
+
const canRenderItems = computed(
|
|
158
|
+
() => isPrimitiveType.value || (
|
|
159
|
+
props.type === 'object' && Number(resolvedSchemaData?.length) > 0
|
|
160
|
+
)
|
|
152
161
|
)
|
|
153
162
|
const showMinimizeButton = computed(() => {
|
|
154
|
-
return resolvedSchemaData
|
|
163
|
+
return Number(resolvedSchemaData?.length) > 2 || resolvedSchemaData?.some(schema => schema.$el === 'richtext')
|
|
155
164
|
})
|
|
156
165
|
</script>
|
|
157
166
|
|
|
@@ -147,7 +147,7 @@ watch(() => props.modelValue, (newValue, oldValue) => {
|
|
|
147
147
|
})
|
|
148
148
|
|
|
149
149
|
watch(() => editor.state.content, (newValue) => {
|
|
150
|
-
if (editor.state.doc?.body
|
|
150
|
+
if (editor.state.doc?.body) {
|
|
151
151
|
editor.state.doc.body.dir = hasRTL ? 'rtl' : 'ltr'
|
|
152
152
|
}
|
|
153
153
|
emit('update:modelValue', newValue)
|
package/src/composables/index.ts
CHANGED
|
@@ -1,33 +1,32 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { BglFormSchemaT, IfAny } from '@bagelink/vue'
|
|
2
2
|
|
|
3
|
-
import type { Ref, UnwrapRef } from 'vue'
|
|
3
|
+
import type { MaybeRefOrGetter, Ref, UnwrapRef } from 'vue'
|
|
4
4
|
import { getFallbackSchema } from '@bagelink/vue'
|
|
5
|
-
import { ref, watch } from 'vue'
|
|
5
|
+
import { ref, toValue, watch } from 'vue'
|
|
6
6
|
|
|
7
7
|
export { useDevice } from './useDevice'
|
|
8
8
|
export { usePolling } from './usePolling'
|
|
9
9
|
export { useValidateFieldValue } from './useValidateFieldValue'
|
|
10
10
|
interface UseBglSchemaParamsT<T> {
|
|
11
|
-
schema?:
|
|
12
|
-
columns?: string[]
|
|
13
|
-
data?:
|
|
11
|
+
schema?: MaybeRefOrGetter<BglFormSchemaT<T>>
|
|
12
|
+
columns?: MaybeRefOrGetter<string[]>
|
|
13
|
+
data?: T[]
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
export function useBglSchema<T = { [key: string]: unknown }>(
|
|
17
17
|
{ schema, columns, data }: UseBglSchemaParamsT<T> = {}
|
|
18
18
|
): BglFormSchemaT<T> {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
19
|
+
const _schema = $computed(() => toValue(schema))
|
|
20
|
+
const _columns = $computed(() => toValue(columns))
|
|
21
|
+
|
|
23
22
|
if (_schema) {
|
|
24
23
|
return (
|
|
25
|
-
|
|
26
|
-
? _schema.filter(f =>
|
|
24
|
+
_columns && _columns.length > 0
|
|
25
|
+
? _schema.filter(f => _columns.includes(f.id as string))
|
|
27
26
|
: _schema
|
|
28
27
|
) as BglFormSchemaT<T>
|
|
29
28
|
}
|
|
30
|
-
return getFallbackSchema(data,
|
|
29
|
+
return getFallbackSchema(data, _columns)
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
export function localRef<T>(
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { VNode } from 'vue'
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
import type { Field, Attributes, Path, SchemaChild, BaseBagelField, VNodeFn } from '../types/BagelForm'
|
|
3
4
|
import {
|
|
4
5
|
TextInput,
|
|
5
6
|
NumberInput,
|
|
@@ -20,26 +21,20 @@ import {
|
|
|
20
21
|
RangeInput,
|
|
21
22
|
EmailInput
|
|
22
23
|
} from '@bagelink/vue'
|
|
23
|
-
|
|
24
24
|
import { h, isVNode } from 'vue'
|
|
25
25
|
|
|
26
26
|
const SLOT_VALUE_COMPONENTS = new Set(['div', 'span', 'p'])
|
|
27
27
|
|
|
28
28
|
const SRC_VALUE_COMPONENTS = new Set(['img', 'iframe'])
|
|
29
29
|
|
|
30
|
-
export interface UseSchemaFieldOptions<T
|
|
30
|
+
export interface UseSchemaFieldOptions<T, SFP extends Path<T>> {
|
|
31
31
|
mode?: 'form' | 'preview' | 'table'
|
|
32
32
|
getFormData?: () => T
|
|
33
|
-
onUpdateModelValue?: (field:
|
|
33
|
+
onUpdateModelValue?: (field: BaseBagelField<T, SFP>, value: any) => void
|
|
34
34
|
includeUnset?: boolean
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
interface SlotProps<T> { row?: T, field: Field<T> }
|
|
39
|
-
type SlotFunction<T> = (props: SlotProps<T>) => any
|
|
40
|
-
type SupportedSlot<T> = BglFormSchemaT<T> | VNode | SlotFunction<T>
|
|
41
|
-
|
|
42
|
-
export function useSchemaField<T extends { [key: string]: any }, _P>(optns: UseSchemaFieldOptions<T>) {
|
|
37
|
+
export function useSchemaField<T extends { [key: string]: any }, SP extends Path<T>>(optns: UseSchemaFieldOptions<T, SP>) {
|
|
43
38
|
const { mode = 'form', getFormData, onUpdateModelValue, includeUnset = false } = optns
|
|
44
39
|
|
|
45
40
|
// Helper function to render objects recursively
|
|
@@ -101,21 +96,21 @@ export function useSchemaField<T extends { [key: string]: any }, _P>(optns: UseS
|
|
|
101
96
|
return typeof field.$el === 'object' ? field.$el : componentMap[field.$el as keyof typeof componentMap] ?? field.$el ?? 'div'
|
|
102
97
|
}
|
|
103
98
|
|
|
104
|
-
function renderChild(child:
|
|
99
|
+
function renderChild(child: SchemaChild<T, SP>, slots?: BaseBagelField<T, SP>['slots']) {
|
|
105
100
|
if (typeof child === 'string') return child
|
|
106
101
|
if (isVNode(child)) return child
|
|
107
102
|
return renderField(
|
|
108
|
-
child,
|
|
103
|
+
child as BaseBagelField<T, SP>,
|
|
109
104
|
slots
|
|
110
105
|
)
|
|
111
106
|
}
|
|
112
107
|
|
|
113
108
|
function renderField(
|
|
114
|
-
field:
|
|
115
|
-
slots?:
|
|
116
|
-
): VNode |
|
|
117
|
-
const Component = getComponent(field)
|
|
118
|
-
if (!Component) return
|
|
109
|
+
field: BaseBagelField<T, SP>,
|
|
110
|
+
slots?: BaseBagelField<T, SP>['slots']
|
|
111
|
+
): VNode | undefined {
|
|
112
|
+
const Component = getComponent(field as Field<T>)
|
|
113
|
+
if (!Component) return
|
|
119
114
|
|
|
120
115
|
const rowData = (getFormData?.() || {}) as T | undefined
|
|
121
116
|
|
|
@@ -129,14 +124,14 @@ export function useSchemaField<T extends { [key: string]: any }, _P>(optns: UseS
|
|
|
129
124
|
rowData
|
|
130
125
|
)
|
|
131
126
|
) {
|
|
132
|
-
return
|
|
127
|
+
return
|
|
133
128
|
}
|
|
134
129
|
} else if (typeof condition === 'string') {
|
|
135
130
|
if (!rowData?.[condition]) {
|
|
136
|
-
return
|
|
131
|
+
return
|
|
137
132
|
}
|
|
138
133
|
} else if (!condition) {
|
|
139
|
-
return
|
|
134
|
+
return
|
|
140
135
|
}
|
|
141
136
|
}
|
|
142
137
|
|
|
@@ -234,7 +229,8 @@ export function useSchemaField<T extends { [key: string]: any }, _P>(optns: UseS
|
|
|
234
229
|
props.class = classify(currentValue, rowData, fieldClass, props.class)
|
|
235
230
|
|
|
236
231
|
// Handle component slots with vIf aware child rendering
|
|
237
|
-
const componentSlots: { [
|
|
232
|
+
// const componentSlots: { [name: string]: Slot } = {}
|
|
233
|
+
const componentSlots: Parameters<typeof h>[1] = {}
|
|
238
234
|
|
|
239
235
|
// Add default slot if there are children
|
|
240
236
|
if (children?.length) {
|
|
@@ -254,29 +250,35 @@ export function useSchemaField<T extends { [key: string]: any }, _P>(optns: UseS
|
|
|
254
250
|
componentSlots[name] = () => {
|
|
255
251
|
if (Array.isArray(slot)) {
|
|
256
252
|
// Handle BglFormSchemaT array
|
|
257
|
-
return slot.map(schemaField =>
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
253
|
+
return slot.map((schemaField) => {
|
|
254
|
+
if (typeof schemaField === 'function') {
|
|
255
|
+
// Handle function slot
|
|
256
|
+
const slotFn = schemaField
|
|
257
|
+
return slotFn({ row: rowData, field })
|
|
258
|
+
}
|
|
259
|
+
if (isVNode(schemaField)) {
|
|
260
|
+
// Handle VNode
|
|
261
|
+
return schemaField
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return renderField(schemaField as BaseBagelField<T, SP>, slots)
|
|
265
|
+
})
|
|
265
266
|
}
|
|
266
|
-
return slot
|
|
267
267
|
}
|
|
268
268
|
})
|
|
269
269
|
}
|
|
270
270
|
|
|
271
271
|
// Handle custom slot content from parent
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
272
|
+
|
|
273
|
+
const slotContent = field.id ? (slots?.[field.id] as VNodeFn<T, SP> | undefined)?.({ row: rowData, field }) : undefined
|
|
274
|
+
// field.id && slots?.[field.id] && typeof slots[field.id] === 'function' && !Array.isArray(slots?.[field.id])
|
|
275
|
+
// ? (slots[field.id])({ row: rowData, field })
|
|
276
|
+
// : undefined
|
|
275
277
|
|
|
276
278
|
if (mode === 'preview') {
|
|
277
279
|
// Skip rendering if value is unset and includeUnset is false
|
|
278
280
|
if (!includeUnset && (transformedValue === undefined || transformedValue === null || transformedValue.length === 0)) {
|
|
279
|
-
return
|
|
281
|
+
return
|
|
280
282
|
}
|
|
281
283
|
|
|
282
284
|
return h('div', { class: 'preview-field' }, [
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { BglFormSchemaT, BtnOptions, ThemeType } from '@bagelink/vue'
|
|
2
|
+
import type { MaybeRefOrGetter } from 'vue'
|
|
2
3
|
|
|
3
4
|
export interface ModalOptions {
|
|
4
5
|
title?: string
|
|
@@ -37,7 +38,7 @@ export interface ModalFormComponentProps<T extends { [key: string]: any }> exten
|
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
export interface ModalFormOptions<T extends { [key: string]: any }> {
|
|
40
|
-
'schema':
|
|
41
|
+
'schema': MaybeRefOrGetter<BglFormSchemaT<T>>
|
|
41
42
|
'modelValue'?: T
|
|
42
43
|
'onUpdate:modelValue'?: (val: T) => void
|
|
43
44
|
'onSubmit'?: (formData: T) => any
|