@bagelink/vue 0.0.1117 → 0.0.1119

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bagelink/vue",
3
3
  "type": "module",
4
- "version": "0.0.1117",
4
+ "version": "0.0.1119",
5
5
  "description": "Bagel core sdk packages",
6
6
  "author": {
7
7
  "name": "Neveh Allon",
@@ -1,12 +1,6 @@
1
1
  <script lang="ts" setup>
2
- import {
3
- BagelForm,
4
- type BglFormSchemaFnT,
5
- Btn,
6
- type BtnOptions,
7
- Modal,
8
- useBagel,
9
- } from '@bagelink/vue'
2
+ import type { BglFormSchemaFnT, BtnOptions, BagelForm } from '@bagelink/vue'
3
+ import { Btn, Modal, useBagel, BagelForm2 } from '@bagelink/vue'
10
4
 
11
5
  const props = defineProps<{
12
6
  side?: boolean
@@ -80,15 +74,16 @@ defineExpose({ setFormValues })
80
74
  :visible="visible"
81
75
  :dismissable
82
76
  :title
83
- @update:visible="($event) => emit('update:visible', $event)"
77
+ @update:visible="($event: boolean) => emit('update:visible', $event)"
84
78
  >
85
- <BagelForm
79
+ <BagelForm2 v-model="formData" :schema="computedFormSchema" @submit="runSubmit" />
80
+ <!-- <BagelForm
86
81
  v-if="visible"
87
82
  ref="form"
88
83
  v-model="formData"
89
84
  :schema="computedFormSchema"
90
85
  @submit="runSubmit"
91
- />
86
+ /> -->
92
87
  <template v-if="onDelete || onSubmit" #footer>
93
88
  <div>
94
89
  <Btn thin flat value="Cancel" @click="closeModal" />
@@ -0,0 +1,150 @@
1
+ <script setup lang="ts">
2
+ import type { BglFormSchemaT, BglFormSchemaFnT, Field } from '@bagelink/vue'
3
+ import type { VNode } from 'vue'
4
+ import { BglForm, CheckInput, DateInput, FieldArray, FileUpload, NumberInput, RichText, SelectInput, TabsNav, TextInput, ToggleInput, UploadInput } from '@bagelink/vue'
5
+ import { h, watch } from 'vue'
6
+
7
+ interface Props {
8
+ modelValue: Record<string, any>
9
+ schema?: BglFormSchemaFnT
10
+ }
11
+
12
+ const props = withDefaults(defineProps<Props>(), {
13
+ modelValue: () => ({}),
14
+ schema: undefined
15
+ })
16
+
17
+ const emit = defineEmits<{
18
+ (e: 'update:modelValue', value: Record<string, any>): void
19
+ (e: 'submit', value: Record<string, any>): void
20
+ }>()
21
+
22
+ const form = $ref<HTMLFormElement>()
23
+ let formData = $ref({ ...props.modelValue })
24
+ let initialFormData = $ref({ ...props.modelValue })
25
+
26
+ // Keep formData in sync with modelValue prop
27
+ watch(() => props.modelValue, (newValue) => {
28
+ formData = { ...newValue }
29
+ }, { immediate: true, deep: true })
30
+
31
+ const resolvedSchema = $computed<BglFormSchemaT | undefined>(() => {
32
+ if (!props.schema) return undefined
33
+ return typeof props.schema === 'function' ? props.schema() : props.schema
34
+ })
35
+
36
+ const isDirty = $computed(() => {
37
+ const current = JSON.stringify(formData)
38
+ const initial = JSON.stringify(initialFormData)
39
+ return current !== initial
40
+ })
41
+
42
+ function getComponent(field: Field) {
43
+ const componentMap = {
44
+ text: TextInput,
45
+ textarea: TextInput,
46
+ number: NumberInput,
47
+ array: FieldArray,
48
+ select: SelectInput,
49
+ toggle: ToggleInput,
50
+ check: CheckInput,
51
+ richtext: RichText,
52
+ upload: UploadInput,
53
+ file: FileUpload,
54
+ date: DateInput,
55
+ tabs: TabsNav,
56
+ bglform: BglForm
57
+ }
58
+
59
+ if (field.$el === 'textarea' && !field.attrs?.multiline) {
60
+ field.attrs = { ...field.attrs, multiline: true }
61
+ }
62
+
63
+ return componentMap[field.$el as keyof typeof componentMap] ?? field.$el ?? 'div'
64
+ }
65
+
66
+ function processFieldValue(fieldType: any, value: any): any {
67
+ if (value == null) return value
68
+ if (fieldType === 'select' && typeof value === 'object') return value.value
69
+ if (typeof value === 'object' && 'value' in value) return value.value
70
+ return value
71
+ }
72
+
73
+ function updateFormData(fieldId: string, value: any, fieldType?: any) {
74
+ formData = {
75
+ ...formData,
76
+ [fieldId]: processFieldValue(fieldType, value)
77
+ }
78
+ emit('update:modelValue', formData)
79
+ }
80
+
81
+ function handleSubmit() {
82
+ emit('submit', formData)
83
+ initialFormData = { ...formData }
84
+ }
85
+
86
+ function renderSchemaField(field: Field): VNode | null {
87
+ const Component = getComponent(field)
88
+ if (!Component) return null
89
+
90
+ const { $el, vIf, 'v-if': vIf2, children, ...fieldProps } = field
91
+ const currentValue = field.id ? formData[field.id] : undefined
92
+
93
+ const props: Record<string, any> = {
94
+ ...fieldProps,
95
+ 'modelValue': processFieldValue(field.$el, currentValue),
96
+ 'onUpdate:modelValue': (value: any) => {
97
+ if (!field.id) return
98
+ updateFormData(field.id, value, field.$el)
99
+ field.onUpdate?.(value, formData)
100
+ }
101
+ }
102
+
103
+ // Handle dynamic props
104
+ if (field.attrs) {
105
+ Object.entries(field.attrs).forEach(([key, value]) => {
106
+ props[key] = typeof value === 'function' ? value(field, formData) : value
107
+ })
108
+ }
109
+
110
+ if (field.class) {
111
+ props.class = typeof field.class === 'function'
112
+ ? field.class(field, formData)
113
+ : field.class
114
+ }
115
+
116
+ const slots = field.children?.length
117
+ ? {
118
+ default: () => field.children!.map(child => typeof child === 'string' ? child : renderSchemaField(child)
119
+ )
120
+ }
121
+ : undefined
122
+
123
+ return h(Component as any, props, slots)
124
+ }
125
+
126
+ function shouldRenderField(field: Field): boolean {
127
+ const condition = field.vIf ?? field['v-if']
128
+ if (condition === undefined) return true
129
+ return typeof condition === 'function'
130
+ ? condition(formData[field.id as string], formData)
131
+ : !!condition
132
+ }
133
+
134
+ defineExpose({ form, isDirty })
135
+ </script>
136
+
137
+ <template>
138
+ <form ref="form" @submit.prevent="handleSubmit">
139
+ <template v-if="resolvedSchema">
140
+ <template v-for="(field, index) in resolvedSchema" :key="field.id || index">
141
+ <component
142
+ :is="renderSchemaField(field)"
143
+ v-if="shouldRenderField(field)"
144
+ />
145
+ </template>
146
+ </template>
147
+ <slot v-else />
148
+ <slot name="submit" :submit="handleSubmit" :isDirty="isDirty" />
149
+ </form>
150
+ </template>
@@ -1,6 +1,6 @@
1
+ export { default as BagelForm2 } from './BagelForm.vue'
1
2
  export { default as BglField } from './BglField.vue'
2
3
  export { default as BglForm } from './BglForm.vue'
3
4
  export { default as BagelForm } from './BglForm.vue'
4
- export { default as BglMultiStepForm } from './BglMultiStepForm.vue'
5
5
  export { default as FieldArray } from './FieldArray.vue'
6
6
  export * from './inputs'
@@ -5,7 +5,7 @@ import { watch } from 'vue'
5
5
  type NumberLayout = 'default' | 'vertical' | 'horizontal'
6
6
 
7
7
  interface NumberInputProps {
8
- modelValue?: number
8
+ modelValue?: number | string
9
9
  min?: number
10
10
  max?: number
11
11
  step?: number
@@ -43,7 +43,7 @@ const {
43
43
 
44
44
  const emit = defineEmits(['update:modelValue'])
45
45
 
46
- let numberValue = $ref(modelValue || 0)
46
+ let numberValue = $ref(Number.parseFloat(`${modelValue}`) || 0)
47
47
 
48
48
  const btnLayouts: NumberLayout[] = ['horizontal', 'vertical']
49
49
 
@@ -88,7 +88,7 @@ watch(() => numberValue, () => {
88
88
 
89
89
  watch(() => modelValue, (newVal) => {
90
90
  if (newVal !== numberValue) {
91
- numberValue = newVal || 0
91
+ numberValue = Number.parseFloat(`${newVal}`) || 0
92
92
  }
93
93
  }, { immediate: true })
94
94
  </script>