@bagelink/vue 1.0.52 → 1.0.54
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/Modal.vue.d.ts.map +1 -1
- package/dist/components/Spreadsheet/Index.vue.d.ts +2 -0
- package/dist/components/Spreadsheet/Index.vue.d.ts.map +1 -1
- package/dist/components/form/BagelForm.vue.d.ts +3 -1
- package/dist/components/form/BagelForm.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/NumberInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/PasswordInput.vue.d.ts +1 -0
- package/dist/components/form/inputs/PasswordInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/PhoneInput.vue.d.ts +2 -0
- package/dist/components/form/inputs/PhoneInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/SelectInput.vue.d.ts +4 -0
- package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/TextInput.vue.d.ts +1 -0
- package/dist/components/form/inputs/TextInput.vue.d.ts.map +1 -1
- package/dist/composables/useSchemaField.d.ts.map +1 -1
- package/dist/index.cjs +63 -18
- package/dist/index.mjs +63 -18
- package/dist/style.css +765 -484
- package/package.json +1 -1
- package/src/components/Modal.vue +1 -0
- package/src/components/form/BagelForm.vue +23 -7
- package/src/components/form/FieldArray.vue +2 -2
- package/src/components/form/inputs/NumberInput.vue +1 -1
- package/src/components/form/inputs/PasswordInput.vue +2 -0
- package/src/components/form/inputs/TextInput.vue +4 -1
- package/src/composables/useSchemaField.ts +34 -1
- package/src/styles/text.css +911 -560
- package/src/components/DataTable/tableTypes.d.ts +0 -0
package/package.json
CHANGED
package/src/components/Modal.vue
CHANGED
|
@@ -109,9 +109,14 @@ function updateFormData(fieldId: string, value: any) {
|
|
|
109
109
|
emit('update:modelValue', formData.value)
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
// Form validation
|
|
113
|
+
const validateForm = () => form.value?.reportValidity() ?? false
|
|
114
|
+
let formError = ref<Error>()
|
|
112
115
|
// Form submission
|
|
113
116
|
async function handleSubmit() {
|
|
114
117
|
try {
|
|
118
|
+
const valid = validateForm()
|
|
119
|
+
if (!valid) return
|
|
115
120
|
if (formState.value === 'submitting') return
|
|
116
121
|
formState.value = 'submitting'
|
|
117
122
|
await props.onSubmit?.(formData.value)
|
|
@@ -119,14 +124,12 @@ async function handleSubmit() {
|
|
|
119
124
|
formState.value = 'success'
|
|
120
125
|
window.parent.postMessage({ type: 'BAGEL_FORM_SUCCESS', data: JSON.stringify(formData.value) }, '*')
|
|
121
126
|
} catch (error) {
|
|
122
|
-
console.error('Submit error:', error)
|
|
123
127
|
formState.value = 'error'
|
|
128
|
+
formError.value = error as Error
|
|
129
|
+
console.error('Submit error:', formError.value)
|
|
124
130
|
}
|
|
125
131
|
}
|
|
126
132
|
|
|
127
|
-
// Form validation
|
|
128
|
-
const validateForm = () => form.value?.reportValidity() ?? false
|
|
129
|
-
|
|
130
133
|
// Field rendering
|
|
131
134
|
const { renderField } = useSchemaField<T>({
|
|
132
135
|
mode: 'form',
|
|
@@ -144,12 +147,26 @@ const { renderField } = useSchemaField<T>({
|
|
|
144
147
|
|
|
145
148
|
const renderSchemaField = (field: Field<T>): VNode | null => renderField(field)
|
|
146
149
|
|
|
150
|
+
// Add new method to handle slot input changes
|
|
151
|
+
function handleSlotInputChange(event: Event) {
|
|
152
|
+
const input = event.target as HTMLInputElement
|
|
153
|
+
if (input.name) {
|
|
154
|
+
const value = input.type === 'checkbox' ? input.checked : input.value
|
|
155
|
+
updateFormData(input.name, value)
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
147
159
|
defineExpose({ form, isDirty, validateForm, resolveSchema, refreshSchema })
|
|
148
160
|
</script>
|
|
149
161
|
|
|
150
162
|
<template>
|
|
151
163
|
<template v-if="formState !== 'success' || !$slots.success">
|
|
152
|
-
<form
|
|
164
|
+
<form
|
|
165
|
+
v-if="props.tag === 'form'" ref="form"
|
|
166
|
+
:class="props.class"
|
|
167
|
+
@submit.prevent="handleSubmit"
|
|
168
|
+
@input="handleSlotInputChange"
|
|
169
|
+
>
|
|
153
170
|
<!-- Loading state -->
|
|
154
171
|
<slot v-if="schemaState === 'loading'" name="loading">
|
|
155
172
|
<div class="flex-center h-300px">
|
|
@@ -174,7 +191,6 @@ defineExpose({ form, isDirty, validateForm, resolveSchema, refreshSchema })
|
|
|
174
191
|
|
|
175
192
|
<!-- Default slot -->
|
|
176
193
|
<slot v-else />
|
|
177
|
-
|
|
178
194
|
<!-- Submit slot -->
|
|
179
195
|
<slot
|
|
180
196
|
name="submit"
|
|
@@ -210,5 +226,5 @@ defineExpose({ form, isDirty, validateForm, resolveSchema, refreshSchema })
|
|
|
210
226
|
|
|
211
227
|
<!-- Success/error slots -->
|
|
212
228
|
<slot v-if="formState === 'success'" name="success" />
|
|
213
|
-
<slot v-if="formState === 'error'" name="error" />
|
|
229
|
+
<slot v-if="formState === 'error'" name="error" :error="formError" />
|
|
214
230
|
</template>
|
|
@@ -143,7 +143,7 @@ const isPrimitiveType = computed(() => props.type === 'text' || props.type === '
|
|
|
143
143
|
const canRenderItems = computed(() => isPrimitiveType.value || (props.type === 'object' && resolvedSchemaData.value.length > 0)
|
|
144
144
|
)
|
|
145
145
|
const showMinimizeButton = computed(() => {
|
|
146
|
-
return resolvedSchemaData.value.length >
|
|
146
|
+
return resolvedSchemaData.value.length > 2 || resolvedSchemaData.value.some(schema => schema.$el === 'richtext')
|
|
147
147
|
})
|
|
148
148
|
</script>
|
|
149
149
|
|
|
@@ -213,7 +213,7 @@ const showMinimizeButton = computed(() => {
|
|
|
213
213
|
</div>
|
|
214
214
|
|
|
215
215
|
<!-- Add Button -->
|
|
216
|
-
<Btn v-if="add" thin icon="add" color="gray" class="txt12" @click="addItem">
|
|
216
|
+
<Btn v-if="add" thin icon="add" color="gray" class="txt12 arrayAddButton" @click="addItem">
|
|
217
217
|
<p>{{ label }}</p>
|
|
218
218
|
</Btn>
|
|
219
219
|
</template>
|
|
@@ -14,6 +14,7 @@ export interface TextInputProps {
|
|
|
14
14
|
pattern?: string
|
|
15
15
|
shrink?: boolean
|
|
16
16
|
disabled?: boolean
|
|
17
|
+
name?: string
|
|
17
18
|
nativeInputAttrs?: { [key: string]: any }
|
|
18
19
|
icon?: IconType
|
|
19
20
|
iconStart?: IconType
|
|
@@ -48,6 +49,7 @@ const inputType = $computed(() => (showPwd.value ? 'text' : 'password'))
|
|
|
48
49
|
v-bind="props"
|
|
49
50
|
:type="inputType"
|
|
50
51
|
class="mb-0"
|
|
52
|
+
:name="props.name"
|
|
51
53
|
/>
|
|
52
54
|
<div class="m-password position-bottom-end flex column justify-content-center">
|
|
53
55
|
<Btn
|
|
@@ -12,6 +12,7 @@ const props = withDefaults(
|
|
|
12
12
|
id?: string
|
|
13
13
|
title?: string
|
|
14
14
|
helptext?: string
|
|
15
|
+
name?: string
|
|
15
16
|
placeholder?: string
|
|
16
17
|
modelValue?: string | number
|
|
17
18
|
label?: string
|
|
@@ -99,6 +100,7 @@ onMounted(() => {
|
|
|
99
100
|
:id
|
|
100
101
|
ref="input"
|
|
101
102
|
v-model.trim="inputVal"
|
|
103
|
+
:name
|
|
102
104
|
:title
|
|
103
105
|
:autocomplete
|
|
104
106
|
:type="type"
|
|
@@ -117,6 +119,7 @@ onMounted(() => {
|
|
|
117
119
|
:id
|
|
118
120
|
ref="input"
|
|
119
121
|
v-model="inputVal"
|
|
122
|
+
:name
|
|
120
123
|
:title
|
|
121
124
|
:type
|
|
122
125
|
:rows="inputRows"
|
|
@@ -128,7 +131,7 @@ onMounted(() => {
|
|
|
128
131
|
@input="updateInputVal"
|
|
129
132
|
@focusout="onFocusout"
|
|
130
133
|
/>
|
|
131
|
-
<p v-if="helptext">{{ helptext }}</p>
|
|
134
|
+
<p v-if="helptext" class="opacity-7 light">{{ helptext }}</p>
|
|
132
135
|
<Icon
|
|
133
136
|
v-if="iconStart"
|
|
134
137
|
class="iconStart"
|
|
@@ -42,6 +42,37 @@ type SupportedSlot<T> = BglFormSchemaT<T> | VNode | SlotFunction<T>
|
|
|
42
42
|
export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchemaFieldOptions<T>) {
|
|
43
43
|
const { mode = 'form', getRowData, onUpdate, includeUnset = false } = optns
|
|
44
44
|
|
|
45
|
+
// Helper function to render objects recursively
|
|
46
|
+
function renderObject(obj: any, depth = 0): string {
|
|
47
|
+
if (obj === null || obj === undefined) return ''
|
|
48
|
+
if (typeof obj !== 'object') return String(obj)
|
|
49
|
+
if (Array.isArray(obj)) return obj.map(item => renderObject(item, depth + 1)).join(', ')
|
|
50
|
+
|
|
51
|
+
// For objects, format as key: value pairs
|
|
52
|
+
const indent = depth > 0 ? ' '.repeat(depth) : ''
|
|
53
|
+
const nextIndent = ' '.repeat(depth + 1)
|
|
54
|
+
|
|
55
|
+
const entries = Object.entries(obj)
|
|
56
|
+
if (entries.length === 0) return '{}'
|
|
57
|
+
|
|
58
|
+
// For nested objects, format with newlines and indentation
|
|
59
|
+
if (depth > 0) {
|
|
60
|
+
return `{\n${entries
|
|
61
|
+
.map(([key, value]) => `${nextIndent}${key}: ${renderObject(value, depth + 1)}`)
|
|
62
|
+
.join(',\n')}\n${indent}}`
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// For top-level objects, format as a flat list
|
|
66
|
+
return entries
|
|
67
|
+
.map(([key, value]) => {
|
|
68
|
+
const valueStr = typeof value === 'object' && value !== null
|
|
69
|
+
? renderObject(value, depth + 1)
|
|
70
|
+
: String(value)
|
|
71
|
+
return `${key}: ${valueStr}`
|
|
72
|
+
})
|
|
73
|
+
.join('\n')
|
|
74
|
+
}
|
|
75
|
+
|
|
45
76
|
function getComponent(field: BaseBagelField<T>) {
|
|
46
77
|
const componentMap = {
|
|
47
78
|
text: TextInput,
|
|
@@ -237,7 +268,9 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
|
|
|
237
268
|
h('div', { class: 'field-value' }, [
|
|
238
269
|
slotContent || (typeof field.$el === 'object'
|
|
239
270
|
? h(Component as any, props, componentSlots)
|
|
240
|
-
: transformedValue
|
|
271
|
+
: typeof transformedValue === 'object' && transformedValue !== null
|
|
272
|
+
? h('pre', { style: 'margin: 0; white-space: pre-wrap; font-family: inherit; font-size: inherit;' }, renderObject(transformedValue))
|
|
273
|
+
: transformedValue?.toString() || '')
|
|
241
274
|
])
|
|
242
275
|
])
|
|
243
276
|
}
|