@bagelink/vue 1.14.13 → 1.15.0

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 (238) hide show
  1. package/dist/components/AddressSearch.vue.d.ts +6 -7
  2. package/dist/components/Alert.vue.d.ts.map +1 -1
  3. package/dist/components/Avatar.vue.d.ts.map +1 -1
  4. package/dist/components/Badge.vue.d.ts.map +1 -1
  5. package/dist/components/Btn.vue.d.ts +1 -1
  6. package/dist/components/Btn.vue.d.ts.map +1 -1
  7. package/dist/components/Card.vue.d.ts.map +1 -1
  8. package/dist/components/Carousel.vue.d.ts +0 -11
  9. package/dist/components/Dropdown.vue.d.ts +0 -2
  10. package/dist/components/Dropdown.vue.d.ts.map +1 -1
  11. package/dist/components/Filter.vue.d.ts +30 -0
  12. package/dist/components/Filter.vue.d.ts.map +1 -0
  13. package/dist/components/FilterQuery.vue.d.ts +8 -3
  14. package/dist/components/Image.vue.d.ts.map +1 -1
  15. package/dist/components/ImportData.vue.d.ts.map +1 -1
  16. package/dist/components/ListItem.vue.d.ts.map +1 -1
  17. package/dist/components/MapEmbed/Index.vue.d.ts.map +1 -1
  18. package/dist/components/Modal.vue.d.ts +0 -1
  19. package/dist/components/Pagination.vue.d.ts.map +1 -1
  20. package/dist/components/Pill.vue.d.ts.map +1 -1
  21. package/dist/components/QueryFilter.vue.d.ts +30 -0
  22. package/dist/components/QueryFilter.vue.d.ts.map +1 -0
  23. package/dist/components/Swiper.vue.d.ts +6 -12
  24. package/dist/components/Swiper.vue.d.ts.map +1 -1
  25. package/dist/components/Toast.vue.d.ts.map +1 -1
  26. package/dist/components/analytics/PieChart.vue.d.ts +2 -2
  27. package/dist/components/calendar/CalendarPopover.vue.d.ts +8 -4
  28. package/dist/components/calendar/CalendarPopover.vue.d.ts.map +1 -1
  29. package/dist/components/calendar/CalendarTypes.d.ts +0 -10
  30. package/dist/components/calendar/Index.vue.d.ts +4 -20
  31. package/dist/components/calendar/views/WeekView.vue.d.ts +1 -9
  32. package/dist/components/dataTable/DataTable.vue.d.ts.map +1 -1
  33. package/dist/components/form/index.d.ts.map +1 -1
  34. package/dist/components/form/inputs/ArrayInput.vue.d.ts +2 -4
  35. package/dist/components/form/inputs/CheckInput.vue.d.ts +1 -2
  36. package/dist/components/form/inputs/Checkbox.vue.d.ts.map +1 -1
  37. package/dist/components/form/inputs/CodeEditor/Index.vue.d.ts +0 -54
  38. package/dist/components/form/inputs/ColorInput.vue.d.ts +1 -3
  39. package/dist/components/form/inputs/DateInput.vue.d.ts +1 -2
  40. package/dist/components/form/inputs/DatePicker.vue.d.ts +0 -1
  41. package/dist/components/form/inputs/EmailInput.vue.d.ts +2 -5
  42. package/dist/components/form/inputs/JSONInput.vue.d.ts +1 -2
  43. package/dist/components/form/inputs/MarkdownEditor.vue.d.ts +2 -7
  44. package/dist/components/form/inputs/NumberInput.vue.d.ts +1 -2
  45. package/dist/components/form/inputs/OTP.vue.d.ts +1 -2
  46. package/dist/components/form/inputs/PasswordInput.vue.d.ts +10 -16
  47. package/dist/components/form/inputs/RadioGroup.vue.d.ts +1 -3
  48. package/dist/components/form/inputs/RangeInput.vue.d.ts +1 -6
  49. package/dist/components/form/inputs/RichText/index.vue.d.ts +1 -2
  50. package/dist/components/form/inputs/RichText/index.vue.d.ts.map +1 -1
  51. package/dist/components/form/inputs/RichText/utils/media.d.ts.map +1 -1
  52. package/dist/components/form/inputs/SelectBtn.vue.d.ts +2 -2
  53. package/dist/components/form/inputs/SelectInput.vue.d.ts +13 -20
  54. package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
  55. package/dist/components/form/inputs/SignaturePad.vue.d.ts +1 -6
  56. package/dist/components/form/inputs/TableField.vue.d.ts +1 -2
  57. package/dist/components/form/inputs/TelInput.vue.d.ts +1 -2
  58. package/dist/components/form/inputs/TextInput.vue.d.ts +2 -3
  59. package/dist/components/form/inputs/ToggleInput.vue.d.ts +1 -2
  60. package/dist/components/form/inputs/Upload/UploadInput.vue.d.ts +6 -27
  61. package/dist/components/form/inputs/Upload/upload.d.ts +1 -1
  62. package/dist/components/form/inputs/index.d.ts +0 -1
  63. package/dist/components/index.d.ts +1 -3
  64. package/dist/components/index.d.ts.map +1 -1
  65. package/dist/components/layout/AppContent.vue.d.ts +1 -1
  66. package/dist/components/layout/AppContent.vue.d.ts.map +1 -1
  67. package/dist/components/layout/AppLayout.vue.d.ts +0 -2
  68. package/dist/components/layout/AppLayout.vue.d.ts.map +1 -1
  69. package/dist/components/layout/AppSidebar.vue.d.ts +1 -5
  70. package/dist/components/layout/AppSidebar.vue.d.ts.map +1 -1
  71. package/dist/components/layout/Panel.vue.d.ts.map +1 -1
  72. package/dist/components/layout/Resizable.vue.d.ts.map +1 -1
  73. package/dist/components/layout/Skeleton.vue.d.ts.map +1 -1
  74. package/dist/components/layout/TabsNav.vue.d.ts +1 -12
  75. package/dist/components/layout/TabsNav.vue.d.ts.map +1 -1
  76. package/dist/components/layout/appLayoutContext.d.ts +24 -0
  77. package/dist/components/layout/appLayoutContext.d.ts.map +1 -0
  78. package/dist/components/layout/index.d.ts.map +1 -1
  79. package/dist/components/lightbox/Lightbox.vue.d.ts.map +1 -1
  80. package/dist/composables/index.d.ts.map +1 -1
  81. package/dist/composables/useDevice.d.ts.map +1 -1
  82. package/dist/composables/useEscapeKey.d.ts +12 -0
  83. package/dist/composables/useEscapeKey.d.ts.map +1 -0
  84. package/dist/composables/useSchemaField.d.ts.map +1 -1
  85. package/dist/composables/useTheme.d.ts.map +1 -1
  86. package/dist/dialog/Dialog.vue.d.ts.map +1 -1
  87. package/dist/dialog/DialogConfirm.vue.d.ts.map +1 -1
  88. package/dist/form-flow/FormFlow.vue.d.ts.map +1 -1
  89. package/dist/form-flow/MultiStepForm.vue.d.ts +1 -6
  90. package/dist/form-flow/form-flow.d.ts +1 -24
  91. package/dist/form-flow/form-flow.d.ts.map +1 -1
  92. package/dist/i18n/index.d.ts +0 -838
  93. package/dist/index.cjs +245 -222
  94. package/dist/index.d.ts +0 -2
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.mjs +42201 -51162
  97. package/dist/plugins/bagel.d.ts.map +1 -1
  98. package/dist/style.css +1 -2
  99. package/dist/types/BagelForm.d.ts +1 -10
  100. package/dist/types/BagelForm.d.ts.map +1 -1
  101. package/dist/types/BtnOptions.d.ts.map +1 -1
  102. package/dist/types/NavLink.d.ts +1 -2
  103. package/dist/types/TableSchema.d.ts.map +1 -1
  104. package/dist/types/index.d.ts +1 -2
  105. package/dist/types/index.d.ts.map +1 -1
  106. package/dist/utils/BagelFormUtils.d.ts +0 -1
  107. package/dist/utils/calendar/dateUtils.d.ts +2 -2
  108. package/dist/utils/calendar/dateUtils.d.ts.map +1 -1
  109. package/dist/utils/constants.d.ts.map +1 -1
  110. package/dist/utils/date.d.ts +116 -0
  111. package/dist/utils/date.d.ts.map +1 -0
  112. package/dist/utils/fetch.d.ts +29 -0
  113. package/dist/utils/fetch.d.ts.map +1 -0
  114. package/dist/utils/index.d.ts +1 -1
  115. package/dist/utils/index.d.ts.map +1 -1
  116. package/dist/utils/string.d.ts +7 -0
  117. package/dist/utils/string.d.ts.map +1 -0
  118. package/dist/utils/useSearch.d.ts +1 -1
  119. package/package.json +3 -10
  120. package/src/components/AccordionItem.vue +5 -5
  121. package/src/components/Alert.vue +37 -16
  122. package/src/components/Avatar.vue +2 -1
  123. package/src/components/Badge.vue +145 -22
  124. package/src/components/BglVideo.vue +4 -4
  125. package/src/components/Btn.vue +81 -69
  126. package/src/components/Card.vue +7 -6
  127. package/src/components/Dropdown.vue +7 -14
  128. package/src/components/FieldSetVue.vue +2 -2
  129. package/src/components/FilterQuery.vue +3 -3
  130. package/src/components/Image.vue +5 -3
  131. package/src/components/JSONSchema.vue +4 -4
  132. package/src/components/JsonBuilder.vue +3 -3
  133. package/src/components/ListItem.vue +2 -4
  134. package/src/components/MapEmbed/Index.vue +18 -17
  135. package/src/components/NavBar.vue +2 -2
  136. package/src/components/Spreadsheet/Index.vue +4 -4
  137. package/src/components/Spreadsheet/SpreadsheetTable.vue +10 -10
  138. package/src/components/Swiper.vue +3 -1
  139. package/src/components/Toast.vue +57 -36
  140. package/src/components/calendar/CalendarPopover.vue +1 -1
  141. package/src/components/calendar/Index.vue +5 -5
  142. package/src/components/calendar/views/AgendaView.vue +2 -2
  143. package/src/components/calendar/views/DayView.vue +1 -1
  144. package/src/components/calendar/views/MonthView.vue +8 -8
  145. package/src/components/dataTable/DataTable.vue +68 -10
  146. package/src/components/form/index.ts +0 -4
  147. package/src/components/form/inputs/ArrayInput.vue +1 -1
  148. package/src/components/form/inputs/CheckInput.vue +6 -6
  149. package/src/components/form/inputs/Checkbox.vue +5 -4
  150. package/src/components/form/inputs/CodeEditor/Index.vue +1 -1
  151. package/src/components/form/inputs/ColorInput.vue +5 -5
  152. package/src/components/form/inputs/DatePicker.vue +3 -3
  153. package/src/components/form/inputs/EmailInput.vue +15 -15
  154. package/src/components/form/inputs/NumberInput.vue +11 -11
  155. package/src/components/form/inputs/OTP.vue +4 -4
  156. package/src/components/form/inputs/PasswordInput.vue +3 -3
  157. package/src/components/form/inputs/RadioGroup.vue +1 -1
  158. package/src/components/form/inputs/RichText/editor.css +4 -4
  159. package/src/components/form/inputs/RichText/index.vue +39 -39
  160. package/src/components/form/inputs/RichText/utils/media.ts +1 -92
  161. package/src/components/form/inputs/RichText/utils/table.ts +4 -4
  162. package/src/components/form/inputs/SelectBtn.vue +1 -1
  163. package/src/components/form/inputs/SelectInput.vue +16 -16
  164. package/src/components/form/inputs/SignaturePad.vue +6 -6
  165. package/src/components/form/inputs/TableField.vue +7 -7
  166. package/src/components/form/inputs/TelInput.vue +12 -12
  167. package/src/components/form/inputs/TextInput.vue +11 -11
  168. package/src/components/form/inputs/ToggleInput.vue +11 -11
  169. package/src/components/form/inputs/Upload/upload.css +16 -16
  170. package/src/components/index.ts +2 -9
  171. package/src/components/layout/AppContent.vue +5 -19
  172. package/src/components/layout/AppLayout.vue +47 -18
  173. package/src/components/layout/AppSidebar.vue +19 -36
  174. package/src/components/layout/BottomMenu.vue +1 -1
  175. package/src/components/layout/Resizable.vue +5 -2
  176. package/src/components/layout/Skeleton.vue +5 -4
  177. package/src/components/layout/TabsNav.vue +23 -23
  178. package/src/components/layout/appLayoutContext.ts +44 -0
  179. package/src/components/layout/index.ts +2 -0
  180. package/src/components/lightbox/Lightbox.vue +3 -9
  181. package/src/composables/index.ts +1 -0
  182. package/src/composables/useDevice.ts +2 -1
  183. package/src/composables/useEscapeKey.ts +56 -0
  184. package/src/composables/useSchemaField.ts +2 -17
  185. package/src/composables/useTheme.ts +23 -19
  186. package/src/form-flow/FormFlow.vue +2 -0
  187. package/src/form-flow/form-flow.ts +7 -0
  188. package/src/index.ts +0 -3
  189. package/src/plugins/bagel.ts +0 -15
  190. package/src/styles/app-layout.css +231 -0
  191. package/src/styles/appearance.css +179 -21
  192. package/src/styles/bagel.css +103 -97
  193. package/src/styles/buttons.css +8 -8
  194. package/src/styles/colors.css +0 -103
  195. package/src/styles/dark.css +25 -26
  196. package/src/styles/input-variants.css +11 -11
  197. package/src/styles/inputs.css +44 -61
  198. package/src/styles/layout.css +445 -1258
  199. package/src/styles/loginCard.css +1 -1
  200. package/src/styles/mobilLayout.css +153 -28
  201. package/src/styles/text.css +500 -1508
  202. package/src/styles/theme.css +199 -435
  203. package/src/styles/transitions.css +4 -4
  204. package/src/types/BagelForm.ts +46 -151
  205. package/src/types/BtnOptions.ts +5 -3
  206. package/src/types/TableSchema.ts +1 -0
  207. package/src/types/index.ts +0 -5
  208. package/src/utils/calendar/dateUtils.ts +2 -3
  209. package/src/utils/constants.ts +7 -0
  210. package/src/utils/date.ts +482 -0
  211. package/src/utils/fetch.ts +128 -0
  212. package/src/utils/index.ts +54 -3
  213. package/src/utils/sizeParsing.ts +5 -5
  214. package/src/utils/string.ts +56 -0
  215. package/vite.config.ts +5 -1
  216. package/bin/generateFormSchema.ts +0 -1035
  217. package/bin/utils.ts +0 -223
  218. package/src/components/Carousel.vue +0 -724
  219. package/src/components/ImportData.vue +0 -1749
  220. package/src/components/Modal.vue +0 -184
  221. package/src/components/ModalConfirm.vue +0 -42
  222. package/src/components/ModalForm.vue +0 -102
  223. package/src/components/Pill.vue +0 -149
  224. package/src/components/Slider.vue +0 -1446
  225. package/src/components/Title.vue +0 -23
  226. package/src/components/ToolBar.vue +0 -9
  227. package/src/components/form/BagelForm.vue +0 -219
  228. package/src/components/form/BglFieldSet.vue +0 -14
  229. package/src/components/form/BglMultiStepForm.vue +0 -469
  230. package/src/components/form/FieldArray.vue +0 -422
  231. package/src/components/form/useBagelFormState.ts +0 -76
  232. package/src/composables/useFormField.ts +0 -38
  233. package/src/dialog/DialogOLD.vue +0 -358
  234. package/src/plugins/modalTypes.ts +0 -61
  235. package/src/plugins/useModal.ts +0 -225
  236. package/src/styles/modal.css +0 -120
  237. package/src/styles/pillColors.css +0 -0
  238. package/src/utils/BagelFormUtils.ts +0 -684
@@ -1,469 +0,0 @@
1
- <script setup lang="ts" generic="T extends {[key:string]:any}, P extends Path<T>">
2
- import type { BglFormSchemaT, Path } from '@bagelink/vue'
3
-
4
- import type { MaybeRefOrGetter } from 'vue'
5
- import type { ComponentExposed, ComponentProps } from 'vue-component-type-helpers'
6
- import { BagelForm, Btn, useBglSchema, sleep } from '@bagelink/vue'
7
- import { ref, watch, computed, nextTick, toValue } from 'vue'
8
-
9
- const props = withDefaults(
10
- defineProps<{
11
- bagelFormProps?: Omit<
12
- ComponentProps<typeof BagelForm<T, P>>,
13
- (
14
- 'schema' | `${string}modelValue` | `ref${string}` | `onVnode${string}` | 'onSubmit'
15
- )
16
- >
17
- schema?: MaybeRefOrGetter<BglFormSchemaT<T>>
18
- showProgress?: boolean
19
- rtl?: boolean
20
- stepLabels?: string[]
21
- allowStepNavigation?: boolean
22
- validateOnSteps?: boolean
23
- /** Animation direction - auto detects based on step change or can be forced */
24
- direction?: 'auto' | 'left' | 'right'
25
- }>(),
26
- {
27
- bagelFormProps: () => ({}),
28
- showProgress: false,
29
- rtl: false,
30
- allowStepNavigation: false,
31
- validateOnSteps: true,
32
- direction: 'auto'
33
- }
34
- )
35
-
36
- const emits = defineEmits(['submit', 'stepChange'])
37
-
38
- type BagelFormT = ComponentExposed<typeof BagelForm<T, P>>
39
-
40
- const formRef = ref<BagelFormT>()
41
-
42
- const formData = defineModel<T>('modelValue', {
43
- default: () => ({}),
44
- required: true
45
- })
46
-
47
- const currentStep = ref(0)
48
- const previousStep = ref(0)
49
- const validatedSteps = ref<number[]>([])
50
-
51
- function reportValidity() {
52
- if (!formRef.value) { return false }
53
- const isValid = formRef.value.validateForm()
54
-
55
- if (isValid && !validatedSteps.value.includes(currentStep.value)) {
56
- validatedSteps.value.push(currentStep.value)
57
- }
58
-
59
- return isValid
60
- }
61
-
62
- const computedSchema = computed(
63
- () => useBglSchema({ schema: toValue(props.schema) })
64
- )
65
-
66
- // Filter out steps with vIf conditions that evaluate to false
67
- const filteredSchema = computed(() => {
68
- const schema = computedSchema.value
69
- return schema.filter((step, _index) => {
70
- // Skip steps that have vIf or v-if returning false
71
- if ((step as any).vIf !== undefined || (step as any)['v-if'] !== undefined) {
72
- const condition = (step as any).vIf ?? (step as any)['v-if']
73
- // If condition is a function, evaluate it with current form data
74
- if (typeof condition === 'function') {
75
- return condition(undefined, formData.value)
76
- }
77
- // If condition is a boolean, use it directly
78
- if (typeof condition === 'boolean') {
79
- return condition
80
- }
81
- // If condition is a string, evaluate it (treat non-empty as true)
82
- if (typeof condition === 'string') {
83
- return !!condition
84
- }
85
- }
86
- // Include steps with no vIf condition or ones that evaluate to true
87
- return true
88
- })
89
- })
90
-
91
- const numberOfSteps = computed(() => filteredSchema.value.length)
92
-
93
- // Map the filtered step index to the actual schema index
94
- const schemaIndexMap = computed(() => {
95
- const map: number[] = []
96
- computedSchema.value.forEach((step, index) => {
97
- const vIfCondition = (step as any).vIf ?? (step as any)['v-if']
98
- let shouldInclude = true
99
-
100
- if (vIfCondition !== undefined) {
101
- if (typeof vIfCondition === 'function') {
102
- shouldInclude = vIfCondition(undefined, formData.value)
103
- } else if (typeof vIfCondition === 'boolean') {
104
- shouldInclude = vIfCondition
105
- } else if (typeof vIfCondition === 'string') {
106
- shouldInclude = !!vIfCondition
107
- }
108
- }
109
-
110
- if (shouldInclude) {
111
- map.push(index)
112
- }
113
- })
114
- return map
115
- })
116
-
117
- // Get current step schema using the mapping
118
- const currentStepSchema = computed(() => {
119
- const actualIndex = schemaIndexMap.value[currentStep.value]
120
- return [computedSchema.value[actualIndex]]
121
- })
122
-
123
- // Tracks which way we're sliding (left or right)
124
- const slideDirection = ref(props.rtl ? 'right' : 'left')
125
-
126
- watch(
127
- () => currentStep.value,
128
- (newStep, oldStep) => {
129
- // Set direction based on step change
130
- if (props.direction === 'auto') {
131
- slideDirection.value = props.rtl
132
- ? (newStep > oldStep ? 'right' : 'left')
133
- : (newStep > oldStep ? 'left' : 'right')
134
- } else {
135
- slideDirection.value = props.direction
136
- }
137
-
138
- previousStep.value = oldStep
139
- // We don't need isStepping flag anymore
140
- emits('stepChange', {
141
- newStep,
142
- oldStep,
143
- totalSteps: numberOfSteps.value,
144
- direction: slideDirection.value
145
- })
146
- }
147
- )
148
-
149
- const isLastStep = computed(() => currentStep.value === numberOfSteps.value - 1)
150
-
151
- const isStepValidated = computed(() => (stepIndex: number) => validatedSteps.value.includes(stepIndex))
152
-
153
- // Add a computed property to check if current step is valid
154
- const isStepValid = ref(false)
155
-
156
- async function checkCurrentStepValidity() {
157
- await nextTick()
158
- if (!props.validateOnSteps) { isStepValid.value = true }
159
- else { isStepValid.value = formRef.value?.checkValidity() ?? false }
160
- }
161
-
162
- function prevStep() {
163
- if (currentStep.value > 0) { currentStep.value-- }
164
- }
165
-
166
- const formContainer = ref<HTMLElement>()
167
-
168
- async function nextStep() {
169
- // Always use reportValidity when attempting to move to next step
170
- // This will show validation errors to the user
171
- if (props.validateOnSteps && reportValidity() === false) { return }
172
- if (!isLastStep.value) { currentStep.value++ }
173
- await sleep(400)
174
- checkCurrentStepValidity()
175
- }
176
-
177
- async function goToStep(stepIndex: number) {
178
- // Can always go back, or to already validated steps
179
- if (stepIndex < currentStep.value || validatedSteps.value.includes(stepIndex)) {
180
- currentStep.value = stepIndex
181
- return true
182
- }
183
-
184
- // For forward navigation, validate each step sequentially until target or invalid step
185
- if (stepIndex > currentStep.value) {
186
- // Validate current step first
187
- if (props.validateOnSteps && reportValidity() === false) {
188
- return false
189
- }
190
-
191
- // Move forward step by step, validating each one
192
- for (let step = currentStep.value + 1; step <= stepIndex; step++) {
193
- // Move to the next step
194
- currentStep.value = step
195
-
196
- // Wait for the form to update with new step's fields
197
- await nextTick()
198
- await sleep(100) // Give time for form to render
199
-
200
- // Validate this step if validation is enabled
201
- if (props.validateOnSteps) {
202
- // Check if the step is valid without showing validation errors for intermediate steps
203
- const isValid = formRef.value?.checkValidity() ?? false
204
-
205
- if (!isValid) {
206
- // If this step is invalid, stop here
207
- return false
208
- }
209
- // Mark this step as validated
210
- if (!validatedSteps.value.includes(step)) {
211
- validatedSteps.value.push(step)
212
- }
213
- }
214
- }
215
-
216
- return true
217
- }
218
-
219
- return false
220
- }
221
-
222
- function handleSubmit() {
223
- // Show validation errors to the user when submitting
224
- if (reportValidity() === false) { return }
225
- emits('submit', formData.value)
226
- }
227
-
228
- function reset() {
229
- validatedSteps.value = []
230
- currentStep.value = 0
231
- }
232
-
233
- // Re-evaluate filtered steps when formData changes
234
- watch(() => formData.value, () => {
235
- checkCurrentStepValidity()
236
- if (currentStep.value >= numberOfSteps.value && numberOfSteps.value > 0) {
237
- currentStep.value = 0
238
- }
239
- }, { deep: true })
240
-
241
- defineExpose({
242
- submit: handleSubmit,
243
- validateForm: reportValidity,
244
- checkValidity: formRef.value?.checkValidity,
245
- isDirty: computed(() => formRef.value?.isDirty),
246
- reset,
247
- isLastStep,
248
- goToStep,
249
- currentStep,
250
- totalSteps: computed(() => numberOfSteps.value),
251
- isStepValid,
252
- nextStep,
253
- prevStep,
254
- })
255
- </script>
256
-
257
- <template>
258
- <div class="bgl-multi-step-form">
259
- <!-- Progress indicator -->
260
- <div v-if="showProgress" class="bgl-step-progress">
261
- <slot
262
- name="progress" v-bind="{
263
- currentStep,
264
- totalSteps: numberOfSteps,
265
- goToStep,
266
- stepLabels: props.stepLabels,
267
- allowStepNavigation: props.allowStepNavigation,
268
- isStepValidated,
269
- }"
270
- >
271
- <div class="bgl-steps-indicator">
272
- <div
273
- v-for="(_, index) in numberOfSteps" :key="index" class="bgl-step-indicator" :class="[
274
- { active: index === currentStep },
275
- { completed: index < currentStep || isStepValidated(index) },
276
- { clickable: props.allowStepNavigation },
277
- ]" @click="props.allowStepNavigation && goToStep(index)"
278
- >
279
- <span>{{ index + 1 }}</span>
280
- <span v-if="props.stepLabels && props.stepLabels[index]" class="bgl-step-label">
281
- {{ props.stepLabels[index] }}
282
- </span>
283
- </div>
284
- </div>
285
- </slot>
286
- </div>
287
-
288
- <div class="bgl-form-wrapper">
289
- <transition :name="slideDirection === 'right' ? 'slide-right' : 'slide-left'" mode="out-in">
290
- <div :key="currentStep" ref="formContainer" class="bgl-form-container">
291
- <BagelForm ref="formRef" v-model="formData" :schema="currentStepSchema" v-bind="bagelFormProps">
292
- <template v-if="$slots.success" #success>
293
- <slot name="success" />
294
- </template>
295
- <template v-if="$slots.error" #error>
296
- <slot name="error" />
297
- </template>
298
- </BagelForm>
299
-
300
- <!-- Navigation buttons inside the form container to animate together -->
301
- </div>
302
- </transition>
303
- <div class="bgl-step-controls">
304
- <slot
305
- name="steppers" v-bind="{
306
- prevStep,
307
- nextStep,
308
- submit: handleSubmit,
309
- currentStep,
310
- totalSteps: numberOfSteps,
311
- isLastStep,
312
- isStepValid,
313
- }"
314
- >
315
- <Btn v-if="currentStep !== 0" color="gray" icon="arrow_back" @click="prevStep" />
316
- <Btn
317
- v-if="!isLastStep" icon="arrow_forward" :disabled="props.validateOnSteps && !isStepValid"
318
- @click="nextStep"
319
- />
320
- <Btn v-else value="Submit" @click="handleSubmit" />
321
- </slot>
322
- </div>
323
- </div>
324
- </div>
325
- </template>
326
-
327
- <style scoped>
328
- .bgl-multi-step-form {
329
- display: flex;
330
- flex-direction: column;
331
- gap: 1rem;
332
- width: 100%;
333
- /* Default transition duration */
334
- --transition-duration: 300ms;
335
- --move-distance: 35%;
336
- --ease-in: cubic-bezier(0.42, 0, 0.58, 1);
337
- --ease-out: cubic-bezier(0.42, 0, 0.58, 1);
338
- }
339
-
340
- .bgl-steps-indicator {
341
- display: flex;
342
- justify-content: space-between;
343
- align-items: center;
344
- margin-bottom: 1rem;
345
- }
346
-
347
- .bgl-step-indicator {
348
- display: flex;
349
- flex-direction: column;
350
- align-items: center;
351
- position: relative;
352
- }
353
-
354
- .bgl-step-indicator::before {
355
- content: '';
356
- position: absolute;
357
- top: 50%;
358
- right: 50%;
359
- height: 2px;
360
- width: 100%;
361
- background: #e0e0e0;
362
- z-index: -1;
363
- }
364
-
365
- .bgl-step-indicator:first-child::before {
366
- display: none;
367
- }
368
-
369
- .bgl-step-indicator>span:first-child {
370
- width: 30px;
371
- height: 30px;
372
- border-radius: 50%;
373
- background: #e0e0e0;
374
- color: #555;
375
- display: flex;
376
- align-items: center;
377
- justify-content: center;
378
- margin-bottom: 0.5rem;
379
- }
380
-
381
- .bgl-step-indicator.active>span:first-child {
382
- background: var(--primary-color, #4CAF50);
383
- color: white;
384
- }
385
-
386
- .bgl-step-indicator.completed>span:first-child {
387
- background: var(--success-color, #8BC34A);
388
- color: white;
389
- }
390
-
391
- .bgl-step-indicator.clickable {
392
- cursor: pointer;
393
- }
394
-
395
- .bgl-step-label {
396
- font-size: 0.8rem;
397
- max-width: 100px;
398
- text-align: center;
399
- }
400
-
401
- .bgl-form-wrapper {
402
- display: grid;
403
- overflow: clip;
404
- height: auto;
405
- transition: height var(--transition-duration) ease;
406
- interpolate-size: allow-keywords;
407
- }
408
-
409
- .bgl-form-wrapper>div {
410
- grid-area: 1 / 1;
411
-
412
- }
413
-
414
- .bgl-form-container {
415
- width: 100%;
416
- display: flex;
417
- flex-direction: column;
418
- }
419
-
420
- .bgl-step-controls {
421
- display: flex;
422
- justify-content: center;
423
- gap: 1rem;
424
- grid-area: unset !important;
425
- margin-top: 2rem;
426
- }
427
-
428
- /* Slide Left Animation (going forward) */
429
- .slide-left-enter-active {
430
- transition: opacity var(--transition-duration) var(--ease-in),
431
- transform var(--transition-duration) var(--ease-in);
432
- }
433
-
434
- .slide-left-leave-active {
435
- transition: opacity var(--transition-duration) var(--ease-out),
436
- transform var(--transition-duration) var(--ease-out);
437
- }
438
-
439
- .slide-left-enter-from {
440
- opacity: 0;
441
- transform: translateX(var(--move-distance));
442
- }
443
-
444
- .slide-left-leave-to {
445
- opacity: 0;
446
- transform: translateX(-30%);
447
- }
448
-
449
- /* Slide Right Animation (going back) */
450
- .slide-right-enter-active {
451
- transition: opacity var(--transition-duration) var(--ease-in),
452
- transform var(--transition-duration) var(--ease-in);
453
- }
454
-
455
- .slide-right-leave-active {
456
- transition: opacity var(--transition-duration) var(--ease-out),
457
- transform var(--transition-duration) var(--ease-out);
458
- }
459
-
460
- .slide-right-enter-from {
461
- opacity: 0;
462
- transform: translateX(-30%);
463
- }
464
-
465
- .slide-right-leave-to {
466
- opacity: 0;
467
- transform: translateX(var(--move-distance));
468
- }
469
- </style>