@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,358 +0,0 @@
1
- <script setup lang="ts">
2
- /**
3
- * Dialog - Native dialog wrapper with animations
4
- *
5
- * Uses native <dialog> element for:
6
- * - Automatic focus trap
7
- * - ESC key handling
8
- * - Backdrop via ::backdrop
9
- * - Browser-managed z-index stacking
10
- */
11
- import type { DialogWidth, DialogPosition } from './dialogTypes'
12
- import { ref, computed, onMounted, watch } from 'vue'
13
- import { DIALOG_WIDTHS } from './dialogTypes'
14
-
15
- const props = withDefaults(defineProps<{
16
- open: boolean
17
- title?: string
18
- width?: DialogWidth
19
- position?: DialogPosition
20
- dismissable?: boolean
21
- }>(), {
22
- width: 'm',
23
- position: 'center',
24
- dismissable: true
25
- })
26
-
27
- const emit = defineEmits<{
28
- 'update:open': [value: boolean]
29
- 'close': []
30
- }>()
31
-
32
- const dialogRef = ref<HTMLDialogElement | null>(null)
33
- const isClosing = ref(false)
34
-
35
- const widthStyle = computed(() => DIALOG_WIDTHS[props.width])
36
-
37
- const positionClass = computed(() => {
38
- if (props.position === 'left') return 'dialog-left'
39
- if (props.position === 'right') return 'dialog-right'
40
- return 'dialog-center'
41
- })
42
-
43
- // Handle open/close
44
- watch(() => props.open, (isOpen) => {
45
- if (isOpen) {
46
- dialogRef.value?.showModal()
47
- isClosing.value = false
48
- } else {
49
- closeWithAnimation()
50
- }
51
- })
52
-
53
- onMounted(() => {
54
- if (props.open) {
55
- dialogRef.value?.showModal()
56
- }
57
- })
58
-
59
- function closeWithAnimation() {
60
- if (isClosing.value) return
61
- isClosing.value = true
62
- }
63
-
64
- function onAnimationEnd() {
65
- if (isClosing.value) {
66
- dialogRef.value?.close()
67
- isClosing.value = false
68
- emit('close')
69
- }
70
- }
71
-
72
- function onBackdropClick(e: MouseEvent) {
73
- // Only close if clicking directly on the dialog backdrop (not content)
74
- if (e.target === dialogRef.value && props.dismissable) {
75
- emit('update:open', false)
76
- }
77
- }
78
-
79
- function onCancel(e: Event) {
80
- // Native ESC key triggers cancel event
81
- if (!props.dismissable) {
82
- e.preventDefault()
83
- return
84
- }
85
- emit('update:open', false)
86
- }
87
-
88
- function close() {
89
- emit('update:open', false)
90
- }
91
-
92
- defineExpose({ close })
93
- </script>
94
-
95
- <template>
96
- <dialog
97
- ref="dialogRef" :class="[positionClass, { 'is-closing': isClosing }]"
98
- :style="{ '--dialog-width': widthStyle }" @click="onBackdropClick" @cancel="onCancel"
99
- @animationend="onAnimationEnd"
100
- >
101
- <div class="dialog-content" @click.stop>
102
- <!-- Header -->
103
- <header v-if="title || dismissable" class="dialog-header">
104
- <h2 v-if="title" class="dialog-title">
105
- {{ title }}
106
- </h2>
107
- <button v-if="dismissable" type="button" class="dialog-close" aria-label="Close" @click="close">
108
- <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
109
- <path d="M18 6L6 18M6 6l12 12" />
110
- </svg>
111
- </button>
112
- </header>
113
-
114
- <!-- Body -->
115
- <div class="dialog-body">
116
- <slot />
117
- </div>
118
-
119
- <!-- Footer -->
120
- <footer v-if="$slots.footer" class="dialog-footer">
121
- <slot name="footer" />
122
- </footer>
123
- </div>
124
- </dialog>
125
- </template>
126
-
127
- <style scoped>
128
- dialog {
129
- border: none;
130
- border-radius: var(--bgl-card-radius, 12px);
131
- padding: 0;
132
- max-width: var(--dialog-width);
133
- width: calc(100% - 2rem);
134
- max-height: calc(100vh - 2rem);
135
- background: var(--bgl-popup-bg, #fff);
136
- color: var(--bgl-text, #1a1a1a);
137
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
138
- overflow: hidden;
139
- }
140
-
141
- dialog::backdrop {
142
- background: var(--bgl-dark-bg, rgba(0, 0, 0, 0.5));
143
- opacity: 0;
144
- transition: opacity 0.2s ease-out;
145
- }
146
-
147
- dialog[open]::backdrop {
148
- opacity: 1;
149
- }
150
-
151
- /* Center position (default) */
152
- dialog.dialog-center {
153
- margin: auto;
154
- }
155
-
156
- dialog.dialog-center[open] {
157
- animation: dialog-fade-in 0.2s ease-out;
158
- }
159
-
160
- dialog.dialog-center.is-closing {
161
- animation: dialog-fade-out 0.15s ease-in forwards;
162
- }
163
-
164
- @keyframes dialog-fade-in {
165
- from {
166
- opacity: 0;
167
- transform: scale(0.95) translateY(10px);
168
- }
169
-
170
- to {
171
- opacity: 1;
172
- transform: scale(1) translateY(0);
173
- }
174
- }
175
-
176
- @keyframes dialog-fade-out {
177
- from {
178
- opacity: 1;
179
- transform: scale(1) translateY(0);
180
- }
181
-
182
- to {
183
- opacity: 0;
184
- transform: scale(0.95) translateY(10px);
185
- }
186
- }
187
-
188
- /* Right position */
189
- dialog.dialog-right {
190
- margin: 0;
191
- margin-inline-start: auto;
192
- margin-inline-end: 1rem;
193
- margin-top: 1rem;
194
- margin-bottom: 1rem;
195
- height: calc(100vh - 2rem);
196
- max-height: calc(100vh - 2rem);
197
- border-radius: var(--bgl-card-radius, 12px);
198
- }
199
-
200
- dialog.dialog-right[open] {
201
- animation: dialog-slide-in-right 0.25s ease-out;
202
- }
203
-
204
- dialog.dialog-right.is-closing {
205
- animation: dialog-slide-out-right 0.2s ease-in forwards;
206
- }
207
-
208
- @keyframes dialog-slide-in-right {
209
- from {
210
- opacity: 0;
211
- transform: translateX(100%);
212
- }
213
-
214
- to {
215
- opacity: 1;
216
- transform: translateX(0);
217
- }
218
- }
219
-
220
- @keyframes dialog-slide-out-right {
221
- from {
222
- opacity: 1;
223
- transform: translateX(0);
224
- }
225
-
226
- to {
227
- opacity: 0;
228
- transform: translateX(100%);
229
- }
230
- }
231
-
232
- /* Left position */
233
- dialog.dialog-left {
234
- margin: 0;
235
- margin-inline-end: auto;
236
- margin-inline-start: 1rem;
237
- margin-top: 1rem;
238
- margin-bottom: 1rem;
239
- height: calc(100vh - 2rem);
240
- max-height: calc(100vh - 2rem);
241
- border-radius: var(--bgl-card-radius, 12px);
242
- }
243
-
244
- dialog.dialog-left[open] {
245
- animation: dialog-slide-in-left 0.25s ease-out;
246
- }
247
-
248
- dialog.dialog-left.is-closing {
249
- animation: dialog-slide-out-left 0.2s ease-in forwards;
250
- }
251
-
252
- @keyframes dialog-slide-in-left {
253
- from {
254
- opacity: 0;
255
- transform: translateX(-100%);
256
- }
257
-
258
- to {
259
- opacity: 1;
260
- transform: translateX(0);
261
- }
262
- }
263
-
264
- @keyframes dialog-slide-out-left {
265
- from {
266
- opacity: 1;
267
- transform: translateX(0);
268
- }
269
-
270
- to {
271
- opacity: 0;
272
- transform: translateX(-100%);
273
- }
274
- }
275
-
276
- /* Content structure */
277
- .dialog-content {
278
- display: flex;
279
- flex-direction: column;
280
- height: 100%;
281
- max-height: inherit;
282
- }
283
-
284
- .dialog-header {
285
- display: flex;
286
- align-items: center;
287
- justify-content: space-between;
288
- padding: 1rem 1.5rem;
289
- border-bottom: 1px solid var(--bgl-border-color, #e5e5e5);
290
- flex-shrink: 0;
291
- }
292
-
293
- .dialog-title {
294
- margin: 0;
295
- font-size: 1.125rem;
296
- font-weight: 600;
297
- }
298
-
299
- .dialog-close {
300
- display: flex;
301
- align-items: center;
302
- justify-content: center;
303
- width: 32px;
304
- height: 32px;
305
- border: none;
306
- background: transparent;
307
- border-radius: 6px;
308
- cursor: pointer;
309
- color: var(--bgl-text-secondary, #666);
310
- transition: background 0.15s ease, color 0.15s ease;
311
- }
312
-
313
- .dialog-close:hover {
314
- background: var(--bgl-gray-tint, #f0f0f0);
315
- color: var(--bgl-text, #1a1a1a);
316
- }
317
-
318
- .dialog-body {
319
- flex: 1;
320
- padding: 1.5rem;
321
- overflow-y: auto;
322
- }
323
-
324
- .dialog-footer {
325
- display: flex;
326
- align-items: center;
327
- justify-content: flex-end;
328
- gap: 0.75rem;
329
- padding: 1rem 1.5rem;
330
- border-top: 1px solid var(--bgl-border-color, #e5e5e5);
331
- flex-shrink: 0;
332
- }
333
-
334
- /* Full width */
335
- dialog[style*="--dialog-width: 100%"] {
336
- max-width: calc(100vw - 2rem);
337
- }
338
-
339
- dialog.dialog-left[style*="--dialog-width: 100%"],
340
- dialog.dialog-right[style*="--dialog-width: 100%"] {
341
- max-width: calc(100vw - 2rem);
342
- width: calc(100vw - 2rem);
343
- }
344
-
345
- /* Mobile adjustments */
346
- @media screen and (max-width: 640px) {
347
-
348
- dialog.dialog-left,
349
- dialog.dialog-right {
350
- margin: 0;
351
- width: 100%;
352
- max-width: 100%;
353
- height: 100vh;
354
- max-height: 100vh;
355
- border-radius: 0;
356
- }
357
- }
358
- </style>
@@ -1,61 +0,0 @@
1
- import type { MaybeRefOrGetter } from 'vue'
2
- import type { BtnOptions, ThemeType } from '../types'
3
- import type { BglFormSchemaT } from '../types/BagelForm'
4
-
5
- export interface ModalOptions {
6
- title?: string
7
- dismissable?: boolean
8
- side?: boolean
9
- width?: string
10
- actions?: BtnOptions[]
11
- class?: string
12
- visible?: boolean
13
- zIndex?: number
14
- }
15
-
16
- export interface ModalConfirmOptions {
17
- 'title': string
18
- 'message': string
19
- 'confirmText'?: string
20
- 'confirmBtnColor'?: ThemeType
21
- 'cancelText'?: string
22
- 'cancelBtnColor'?: ThemeType
23
- 'resolve': (val: boolean) => void
24
- 'onUpdate:visible': () => void
25
- 'visible': boolean
26
- }
27
-
28
- export type ModalType = 'modal' | 'modalForm' | 'confirmModal'
29
- export type ConfirmModalUserOptions = string | {
30
- title: string
31
- message: string
32
- confirmText?: string
33
- cancelText?: string
34
- confirmBtnColor?: string
35
- cancelBtnColor?: string
36
- }
37
-
38
- export interface ModalComponentProps<T extends { [key: string]: any }> {
39
- componentSlots: { [key: string]: any }
40
- modalType: ModalType
41
- modalOptions: ModalOptions | ModalFormOptions<T> | ModalConfirmOptions
42
- }
43
-
44
- export interface ModalFormComponentProps<T extends { [key: string]: any }> extends ModalComponentProps<T> {
45
- modalType: 'modalForm'
46
- modalOptions: ModalFormOptions<T>
47
- }
48
-
49
- export interface ModalFormOptions<T> extends ModalOptions {
50
- 'schema': MaybeRefOrGetter<BglFormSchemaT<T>>
51
- 'modelValue'?: T
52
- 'onUpdate:modelValue'?: (val: T) => void
53
- 'onSubmit'?: (formData: T) => any
54
- 'onDelete'?: (formData: T) => Promise<void>
55
- 'onDuplicate'?: (formData: T) => Promise<void>
56
- 'submitText'?: string
57
- 'cancelText'?: string
58
- 'deleteText'?: string
59
- 'duplicateText'?: string
60
- 'onError'?: (err: any) => void
61
- }
@@ -1,225 +0,0 @@
1
- import type { App, InjectionKey, Plugin } from 'vue'
2
- import type { ComponentProps } from 'vue-component-type-helpers'
3
- import type {
4
- ModalComponentProps,
5
- ModalFormComponentProps,
6
- ModalFormOptions,
7
- ModalOptions,
8
- ModalType,
9
- ConfirmModalUserOptions,
10
- ModalConfirmOptions
11
- } from './modalTypes'
12
- import { createApp, defineComponent, h, inject, reactive, shallowReactive } from 'vue'
13
- import { Modal, ModalConfirm, ModalForm } from '../components'
14
-
15
- export interface ModalApi {
16
- showModal: <T extends { [key: string]: any }>(
17
- options: ModalOptions,
18
- slots?: { [key: string]: any }
19
- ) => ModalComponentProps<T> | undefined
20
- showModalForm: <T extends { [key: string]: any }>(
21
- options: ModalFormOptions<T>,
22
- slots?: { [key: string]: any }
23
- ) => ModalFormComponentProps<T> | undefined
24
- hideModal: (index?: number) => void
25
- confirmModal: (options: ConfirmModalUserOptions) => Promise<boolean>
26
- hideAllModals: () => void
27
- }
28
-
29
- export const ModalSymbol: InjectionKey<ModalApi> = Symbol('modal')
30
-
31
- // Global singleton instance as fallback (created on first plugin install)
32
- let globalModalApi: ModalApi | null = null
33
-
34
- export function useModal(): ModalApi {
35
- const modalApi = inject(ModalSymbol, null)
36
- if (!modalApi) {
37
- // Fallback to global singleton if injection fails
38
- if (globalModalApi) {
39
- return globalModalApi
40
- }
41
- throw new Error('Modal API not provided. Make sure ModalPlugin is installed via app.use(ModalPlugin)')
42
- }
43
- return modalApi
44
- }
45
-
46
- export const ModalPlugin: Plugin = {
47
- install: (app: App) => {
48
- const BASE_Z_INDEX = 1000
49
- const modalStack = reactive<ModalComponentProps<object>[]>([])
50
-
51
- const hideModal = (index?: number) => {
52
- if (index === undefined || index >= modalStack.length - 1) {
53
- // Close top modal
54
- modalStack.splice(modalStack.length - 1, 1)
55
- } else {
56
- modalStack.splice(index, 1)
57
- }
58
- }
59
-
60
- const hideAllModals = () => {
61
- modalStack.splice(0, modalStack.length)
62
- }
63
-
64
- const confirmModal = (options: ConfirmModalUserOptions): Promise<boolean> => {
65
- return new Promise((resolve) => {
66
- const confirmOptions = typeof options === 'string' ? { title: '', message: options } : options
67
- modalStack.push({
68
- modalOptions: shallowReactive({ ...confirmOptions, resolve }),
69
- modalType: 'confirmModal',
70
- componentSlots: {},
71
- })
72
- })
73
- }
74
-
75
- const showModal = <T extends { [key: string]: any }>(
76
- modalType: ModalType,
77
- options: ModalOptions | ModalFormOptions<T>,
78
- slots: { [key: string]: any } = {}
79
- ): ModalComponentProps<T> | ModalFormComponentProps<T> | undefined => {
80
- // Make options reactive so updates propagate
81
- const reactiveOptions = reactive(options) as ModalOptions | ModalFormOptions<T>
82
-
83
- // Ensure visible is set for modals
84
- if (!('visible' in reactiveOptions)) {
85
- reactiveOptions.visible = true
86
- }
87
-
88
- const modalComponent = {
89
- modalOptions: reactiveOptions,
90
- modalType,
91
- componentSlots: slots,
92
- }
93
- modalStack.push(modalComponent)
94
-
95
- if (modalType === 'modalForm') {
96
- return modalComponent as ModalFormComponentProps<T>
97
- }
98
- return modalComponent
99
- }
100
-
101
- const api: ModalApi = {
102
- showModal: (options: ModalOptions, slots?: { [key: string]: any }) => showModal('modal', options, slots),
103
-
104
- showModalForm: <T extends { [key: string]: any }>(
105
- options: ModalFormOptions<T>,
106
- slots?: { [key: string]: any }
107
- ) => showModal<T>('modalForm', options, slots) as ModalFormComponentProps<T>,
108
-
109
- confirmModal: (options: ConfirmModalUserOptions) => confirmModal(options),
110
-
111
- hideModal,
112
-
113
- hideAllModals,
114
- }
115
-
116
- // Set global singleton on first install
117
- if (!globalModalApi) {
118
- globalModalApi = api
119
- }
120
-
121
- app.provide(ModalSymbol, api)
122
-
123
- // Modal container component
124
- const ModalContainerComponent = defineComponent({
125
- name: 'ModalContainer',
126
- setup() {
127
- // Handle ESC key - only close top modal
128
- const handleEscape = (e: KeyboardEvent) => {
129
- if (e.key === 'Escape' && modalStack.length > 0) {
130
- const topModal = modalStack[modalStack.length - 1]
131
- // Check if top modal is dismissable
132
- const modalOptions = topModal.modalOptions as ModalOptions
133
- if (modalOptions.dismissable !== false) {
134
- hideModal()
135
- }
136
- }
137
- }
138
-
139
- return {
140
- modalStack,
141
- handleEscape,
142
- }
143
- },
144
- mounted() {
145
- document.addEventListener('keydown', this.handleEscape)
146
- },
147
- unmounted() {
148
- document.removeEventListener('keydown', this.handleEscape)
149
- },
150
- render() {
151
- return this.modalStack.map((modal, index) => {
152
- // Calculate z-index based on stack position
153
- const zIndex = BASE_Z_INDEX + index * 10
154
-
155
- if (!modal || !modal.modalOptions) {
156
- console.error('[BageLink Modal] Invalid modal in stack:', modal)
157
- return null
158
- }
159
-
160
- const props = {
161
- ...modal.modalOptions,
162
- 'visible': true,
163
- 'zIndex': zIndex,
164
- 'onUpdate:visible': () => { hideModal(index) },
165
- }
166
-
167
- switch (modal.modalType) {
168
- case 'modalForm': {
169
- const formOptions = modal.modalOptions as ModalFormOptions<any>
170
- if (!formOptions.schema) {
171
- console.error('[BageLink Modal] ModalForm requires a schema', modal.modalOptions)
172
- return null
173
- }
174
- return h(ModalForm, props as ComponentProps<typeof ModalForm>, modal.componentSlots)
175
- }
176
- case 'confirmModal':
177
- return h(ModalConfirm, props as ModalConfirmOptions, {})
178
- default:
179
- return h(Modal, props, modal.componentSlots)
180
- }
181
- })
182
- },
183
- })
184
-
185
- // Register the component so users can manually add it if needed
186
- app.component('ModalContainer', ModalContainerComponent)
187
-
188
- // Auto-mount modal container to document.body
189
- if (typeof document !== 'undefined' && typeof window !== 'undefined') {
190
- const mountModalContainer = () => {
191
- const existingContainer = document.getElementById('bagelink-modal-root')
192
- if (!existingContainer) {
193
- // Create mount point
194
- const container = document.createElement('div')
195
- container.id = 'bagelink-modal-root'
196
- document.body.appendChild(container)
197
-
198
- // Create a separate app instance for modals to avoid context issues
199
- const modalApp = createApp(ModalContainerComponent)
200
-
201
- // Share the same context/plugins
202
- modalApp._context = app._context
203
-
204
- // Mount it
205
- modalApp.mount(container)
206
- }
207
- }
208
-
209
- // Try to mount immediately if DOM is ready
210
- if (document.body) {
211
- mountModalContainer()
212
- }
213
-
214
- // Also use mixin as fallback for cases where plugin is installed before DOM ready
215
- app.mixin({
216
- mounted() {
217
- // Only run once on the root component
218
- if (this.$root === this) {
219
- mountModalContainer()
220
- }
221
- }
222
- })
223
- }
224
- },
225
- }