@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.
Files changed (68) hide show
  1. package/dist/components/AddressSearch.vue.d.ts.map +1 -1
  2. package/dist/components/Btn.vue.d.ts +1 -1
  3. package/dist/components/Btn.vue.d.ts.map +1 -1
  4. package/dist/components/DataPreview.vue.d.ts +16 -5
  5. package/dist/components/DataPreview.vue.d.ts.map +1 -1
  6. package/dist/components/Dropdown.vue.d.ts.map +1 -1
  7. package/dist/components/Icon/Icon.vue.d.ts +4 -1
  8. package/dist/components/Icon/Icon.vue.d.ts.map +1 -1
  9. package/dist/components/ModalForm.vue.d.ts +2 -1
  10. package/dist/components/ModalForm.vue.d.ts.map +1 -1
  11. package/dist/components/calendar/views/CalendarPopover.vue.d.ts +2 -2
  12. package/dist/components/calendar/views/CalendarPopover.vue.d.ts.map +1 -1
  13. package/dist/components/dataTable/DataTable.vue.d.ts.map +1 -1
  14. package/dist/components/dataTable/useSorting.d.ts +1 -1
  15. package/dist/components/dataTable/useSorting.d.ts.map +1 -1
  16. package/dist/components/dataTable/useTableData.d.ts +7 -6
  17. package/dist/components/dataTable/useTableData.d.ts.map +1 -1
  18. package/dist/components/dataTable/useTableVirtualization.d.ts.map +1 -1
  19. package/dist/components/form/BagelForm.vue.d.ts +4 -10
  20. package/dist/components/form/BagelForm.vue.d.ts.map +1 -1
  21. package/dist/components/form/BglMultiStepForm.vue.d.ts +6 -4
  22. package/dist/components/form/BglMultiStepForm.vue.d.ts.map +1 -1
  23. package/dist/components/form/FieldArray.vue.d.ts +3 -2
  24. package/dist/components/form/FieldArray.vue.d.ts.map +1 -1
  25. package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
  26. package/dist/composables/index.d.ts +5 -5
  27. package/dist/composables/index.d.ts.map +1 -1
  28. package/dist/composables/useSchemaField.d.ts +5 -12
  29. package/dist/composables/useSchemaField.d.ts.map +1 -1
  30. package/dist/index.cjs +146 -230
  31. package/dist/index.d.ts +1 -1
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.mjs +147 -231
  34. package/dist/plugins/modalTypes.d.ts +3 -2
  35. package/dist/plugins/modalTypes.d.ts.map +1 -1
  36. package/dist/style.css +183 -183
  37. package/dist/types/BagelForm.d.ts +12 -9
  38. package/dist/types/BagelForm.d.ts.map +1 -1
  39. package/dist/types/TableSchema.d.ts +9 -9
  40. package/dist/types/TableSchema.d.ts.map +1 -1
  41. package/dist/types/timeago.d.ts +23 -0
  42. package/dist/types/timeago.d.ts.map +1 -0
  43. package/dist/utils/BagelFormUtils.d.ts +5 -3
  44. package/dist/utils/BagelFormUtils.d.ts.map +1 -1
  45. package/dist/utils/useSearch.d.ts +44 -0
  46. package/dist/utils/useSearch.d.ts.map +1 -0
  47. package/package.json +2 -2
  48. package/src/components/DataPreview.vue +16 -5
  49. package/src/components/Icon/Icon.vue +12 -3
  50. package/src/components/ModalForm.vue +6 -9
  51. package/src/components/dataTable/DataTable.vue +11 -14
  52. package/src/components/dataTable/useSorting.ts +1 -1
  53. package/src/components/dataTable/useTableData.ts +19 -42
  54. package/src/components/dataTable/useTableVirtualization.ts +4 -8
  55. package/src/components/form/BagelForm.vue +32 -97
  56. package/src/components/form/BglMultiStepForm.vue +9 -7
  57. package/src/components/form/FieldArray.vue +54 -45
  58. package/src/components/form/inputs/RichText/index.vue +1 -1
  59. package/src/composables/index.ts +12 -13
  60. package/src/composables/useSchemaField.ts +36 -34
  61. package/src/index.ts +1 -1
  62. package/src/plugins/modalTypes.ts +3 -2
  63. package/src/types/BagelForm.ts +21 -13
  64. package/src/types/TableSchema.ts +9 -9
  65. package/src/utils/BagelFormUtils.ts +6 -4
  66. package/src/utils/{search.ts → useSearch.ts} +1 -2
  67. package/dist/components/Carousel2.vue.d.ts +0 -89
  68. 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 { BglFormSchemaFnT, Field, BglFormSchemaT } from '@bagelink/vue'
3
- import type { VNode } from 'vue'
4
- import { Loading } from '@bagelink/vue'
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?: BglFormSchemaFnT<T>
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 schemaState = ref<'loading' | 'loaded' | 'error'>('loaded')
35
- const resolvedSchemaData = ref<BglFormSchemaT<T>>()
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.split('.')
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 rendering
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>): VNode | null => renderField(field)
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, resolveSchema, refreshSchema, checkValidity })
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
- <component
187
- :is="renderSchemaField(field)"
188
- v-for="field in resolvedSchema"
189
- v-else-if="resolvedSchema"
190
- :key="field.id"
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="isDirty"
200
- :validateForm="validateForm"
201
- :formState="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
- <slot v-if="schemaState === 'loading'" name="loading">
209
- <Loading />
210
- </slot>
211
-
212
- <slot v-else-if="schemaState === 'error'" name="schema-error">
213
- <div class="flex-center h-300px txt-red">
214
- Error loading form
215
- </div>
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 { BglFormSchemaFnT } from '@bagelink/vue'
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?: BglFormSchemaFnT<T>
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, index) => {
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: computed(() => currentStep.value),
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
- BglFormSchemaFnT,
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, onMounted, computed, watch } from 'vue'
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?: BglFormSchemaFnT<T>
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
- // For primitive types, use the predefined schemaks
76
- if (props.type !== 'object') {
77
- resolvedSchemaData.value = primitiveSchema.value
78
- schemaState.value = 'loaded'
79
- return
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
- // For object type without schema
83
- if (!props.schema) {
84
- resolvedSchemaData.value = []
85
- schemaState.value = 'loaded'
86
- return
87
- }
88
+ // // For object type without schema
89
+ // if (!props.schema) {
90
+ // resolvedSchemaData.value = []
91
+ // schemaState.value = 'loaded'
92
+ // return
93
+ // }
88
94
 
89
- // For object type with schema
90
- try {
91
- schemaState.value = 'loading'
92
- const isPromise = (obj: any) => obj && typeof obj.then === 'function'
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
- let result: any
95
- if (typeof props.schema === 'function') {
96
- result = props.schema()
97
- result = isPromise(result) ? await result : result
98
- } else {
99
- result = isPromise(props.schema) ? await props.schema : props.schema
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
- resolvedSchemaData.value = result
103
- schemaState.value = 'loaded'
104
- } catch (error) {
105
- console.error('Schema error:', error)
106
- schemaState.value = 'error'
107
- resolvedSchemaData.value = []
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(() => isPrimitiveType.value || (props.type === 'object' && resolvedSchemaData.value.length > 0)
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.value.length > 2 || resolvedSchemaData.value.some(schema => schema.$el === 'richtext')
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.innerHTML) {
150
+ if (editor.state.doc?.body) {
151
151
  editor.state.doc.body.dir = hasRTL ? 'rtl' : 'ltr'
152
152
  }
153
153
  emit('update:modelValue', newValue)
@@ -1,33 +1,32 @@
1
- import type { BglFormSchemaFnT, BglFormSchemaT, IfAny } from '@bagelink/vue'
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?: BglFormSchemaFnT<T>
12
- columns?: string[]
13
- data?: any[]
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
- let _schema = schema
20
- if (typeof _schema === 'function') {
21
- _schema = _schema()
22
- }
19
+ const _schema = $computed(() => toValue(schema))
20
+ const _columns = $computed(() => toValue(columns))
21
+
23
22
  if (_schema) {
24
23
  return (
25
- columns && columns.length > 0
26
- ? _schema.filter(f => columns.includes(f.id as string))
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, columns)
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
- import type { Field, BglFormSchemaT, SchemaChildrenT, Attributes, Path } from '../types/BagelForm'
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: Field<T>, value: any) => void
33
+ onUpdateModelValue?: (field: BaseBagelField<T, SFP>, value: any) => void
34
34
  includeUnset?: boolean
35
35
  }
36
36
 
37
- // Add type for supported child types
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: SchemaChildrenT<T>[number], slots?: Record<string, SupportedSlot<T>>): any {
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: Field<T>,
115
- slots?: Record<string, SupportedSlot<T>>
116
- ): VNode | null {
117
- const Component = getComponent(field)
118
- if (!Component) return null
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 null
127
+ return
133
128
  }
134
129
  } else if (typeof condition === 'string') {
135
130
  if (!rowData?.[condition]) {
136
- return null
131
+ return
137
132
  }
138
133
  } else if (!condition) {
139
- return null
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: { [key: string]: any } = {}
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 => renderField(schemaField, slots))
258
- } if (isVNode(slot)) {
259
- // Handle VNode
260
- return slot
261
- } if (typeof slot === 'function') {
262
- // Handle function slot
263
- const slotFn = slot as (props: SlotProps<T>) => any
264
- return slotFn({ row: rowData, field })
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
- const slotContent = field.id && slots?.[field.id]
273
- ? (slots[field.id] as SlotFunction<T>)({ row: rowData, field })
274
- : undefined
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 null
281
+ return
280
282
  }
281
283
 
282
284
  return h('div', { class: 'preview-field' }, [
package/src/index.ts CHANGED
@@ -17,4 +17,4 @@ export * from './utils/calendar/dateUtils'
17
17
  import './styles/bagel.css'
18
18
 
19
19
  export * from './utils/constants'
20
- export * from './utils/search'
20
+ export * from './utils/useSearch'
@@ -1,4 +1,5 @@
1
- import type { BglFormSchemaFnT, BtnOptions, ThemeType } from '@bagelink/vue'
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': BglFormSchemaFnT<T>
41
+ 'schema': MaybeRefOrGetter<BglFormSchemaT<T>>
41
42
  'modelValue'?: T
42
43
  'onUpdate:modelValue'?: (val: T) => void
43
44
  'onSubmit'?: (formData: T) => any