@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,44 +1,167 @@
1
1
  <script setup lang="ts">
2
- import type { IconType, ExtendedThemeType } from '@bagelink/vue'
3
- import { Icon } from '@bagelink/vue'
4
- import { computed } from 'vue'
2
+ defineOptions({ name: 'BglBadge' })
3
+ import type { IconType, ThemeType } from '@bagelink/vue'
4
+ import type { SetupContext } from 'vue'
5
+ import { Btn, Icon } from '@bagelink/vue'
6
+ import { computed, useSlots } from 'vue'
5
7
  import '../styles/base-colors.css'
6
8
 
7
- interface Props {
8
- color?: ExtendedThemeType
9
- text: string
9
+ interface BtnProp {
10
10
  icon?: IconType
11
- iconEnd?: IconType
11
+ onClick: () => void
12
+ value?: string
12
13
  }
13
14
 
14
- const props = defineProps<Props>()
15
+ const props = defineProps<{
16
+ disabled?: boolean
17
+ icon?: IconType
18
+ iconEnd?: IconType
19
+ color?: ThemeType
20
+ variant?: 'solid' | 'flat' | 'outline'
21
+ /** Boolean variant shorthands: <Badge flat /> — same as variant="flat" */
22
+ flat?: boolean
23
+ outline?: boolean
24
+ /** @deprecated Use `outline` */
25
+ border?: boolean
26
+ loading?: boolean
27
+ value?: string
28
+ round?: boolean
29
+ btn?: BtnProp
30
+ btnEnd?: BtnProp
31
+ size?: 'sm' | 'md' | 'lg'
32
+ /** Boolean size shorthands: <Badge sm value="New" /> */
33
+ sm?: boolean
34
+ lg?: boolean
35
+ uppercase?: boolean
36
+ }>()
37
+
38
+ const slots: SetupContext['slots'] = useSlots()
39
+
40
+ const computedTheme = computed(
41
+ () => {
42
+ if (props.disabled) { return 'gray-light' }
43
+ return props.color as ThemeType
44
+ },
45
+ )
15
46
 
16
47
  const computedPairClass = computed(() => {
17
- const theme = props.color
48
+ const theme = computedTheme.value
18
49
  if (!theme) return 'pair-primary'
19
50
  return `pair-${theme}`
20
51
  })
52
+
53
+ const computedSize = computed(() => {
54
+ if (props.size) { return props.size }
55
+ if (props.sm) { return 'sm' }
56
+ if (props.lg) { return 'lg' }
57
+ return 'md'
58
+ })
59
+
60
+ const computedVariant = computed(() => {
61
+ if (props.variant) { return props.variant }
62
+ if (props.flat) { return 'flat' }
63
+ if (props.outline || props.border) { return 'outline' }
64
+ return 'solid'
65
+ })
66
+
67
+ const computedClasses = computed(() => {
68
+ const classes: Record<string, boolean> = {
69
+ 'bgl_pill': !props.icon || !!slots.default || !!props.value,
70
+ 'round': props.round,
71
+ 'bgl_flatPill': computedVariant.value === 'flat',
72
+ 'bgl_pill-border': computedVariant.value === 'outline',
73
+ 'pillLarge': computedSize.value === 'lg',
74
+ 'pillSmall': computedSize.value === 'sm',
75
+ }
76
+
77
+ // Add the pair class
78
+ classes[computedPairClass.value] = true
79
+
80
+ return classes
81
+ })
21
82
  </script>
22
83
 
23
84
  <template>
24
- <div class="bgl_badge" :class="computedPairClass">
25
- <Icon v-if="icon" class="inline line-height-1" size="0.5" :icon="icon" />
26
- {{ text }}
27
- <Icon v-if="iconEnd" class="inline line-height-1" size="0.5" :icon="iconEnd" />
85
+ <div
86
+ class="bgl_pill"
87
+ style="height: var(--bgl-pill-height);"
88
+ :disabled="disabled"
89
+ :class="computedClasses"
90
+ >
91
+ <div class="flex h-100 justify-content-center relative ">
92
+ <div v-if="loading" class="loading absolute inset-0 mx-auto" />
93
+ <div class="px-025 flex gap-025 justify-content-center" :class="{ 'opacity-0': loading }">
94
+ <Btn v-if="btn" class="bgl_pill-btn -ms-025" icon-size="0.8" round v-bind="btn" />
95
+ <Icon v-if="icon" class="line-height-0" :icon="icon" style="font-size: var(--bgl-pill-font-size)" />
96
+ <slot :class="{ uppercase }" />
97
+ <template v-if="!slots.default">
98
+ <p class="pillText inline" :class="{ uppercase }">
99
+ {{ value }}
100
+ </p>
101
+ </template>
102
+ <Icon v-if="iconEnd" class="line-height-0" :icon="iconEnd" style="font-size: var(--bgl-pill-font-size)" />
103
+ <Btn v-if="btnEnd" class="bgl_pill-btn -me-025" icon-size="0.8" round v-bind="btnEnd" />
104
+ </div>
105
+ </div>
28
106
  </div>
29
107
  </template>
30
108
 
31
109
  <style scoped>
32
- .inline {
33
- display: inline;
110
+ .pillLarge{
111
+ --bgl-pill-font-size: var(--bgl-font-size);
112
+ --bgl-pill-height:auto;
113
+ }
114
+ .pillSmall{
115
+ --bgl-pill-font-size: 9px;
116
+ --bgl-pill-height:15px;
117
+ }
118
+ .pillText{
119
+ font-size: var(--bgl-pill-font-size);
120
+ }
121
+ .bgl_pill-btn{
122
+ color: var(--bgl-pill-btn-color);
123
+ background: var(--bgl-pill-btn-bg);
124
+ width: calc(var(--bgl-pill-height) / 1.25)!important;
125
+ height: calc(var(--bgl-pill-height) / 1.25)!important;
126
+ }
127
+ .loading {
128
+ border: 1px solid var(--bgl-light-text);
129
+ border-bottom: 2px solid var(--bgl-light-text);
130
+ animation: spin 1s linear infinite;
131
+ border-radius: 100px;
132
+ width: 1rem;
133
+ height: 1rem;
134
+ margin: auto;
135
+ }
136
+ .bgl_flatPill .loading {
137
+ border-bottom: 2px solid var(--bgl-text-color);
34
138
  }
35
139
 
36
- .bgl_badge {
37
- border-radius: 10px;
38
- padding: 4px 8px;
39
- font-size: 10px;
40
- white-space: nowrap;
41
- display: inline;
42
- margin-inline-end: 0.25rem;
140
+ @keyframes spin {
141
+ 0% {
142
+ transform: rotate(0deg);
143
+ }
144
+ 100% {
145
+ transform: rotate(360deg);
146
+ }
147
+ }
148
+
149
+ .bgl_pill {
150
+ padding-inline: calc(var(--bgl-pill-font-size) / 6);
151
+ padding-block: calc(var(--bgl-pill-font-size) / 24);
152
+ transition: var(--bgl-transition);
153
+ display: inline-block;
154
+ margin-inline-end: 0.25rem;
155
+ border-radius: var(--bgl-pill-border-radius);
156
+ min-height: var(--bgl-pill-height);
157
+ vertical-align: middle;
158
+ }
159
+
160
+ .bgl_pill[disabled="true"] {
161
+ opacity: 0.5;
162
+ cursor: not-allowed;
163
+ }
164
+ .bgl_pill.round {
165
+ border-radius: 1000px;
43
166
  }
44
167
  </style>
@@ -98,7 +98,7 @@ const videoUrl = computed(() => {
98
98
  const regularMatch = props.src?.match(regularVimeoRegex) ?? null
99
99
 
100
100
  const videoId = playerMatch?.[1] ?? regularMatch?.[3]
101
- console.log(videoId, { playerMatch, regularMatch })
101
+ // console.log(videoId, { playerMatch, regularMatch })
102
102
  return `https://player.vimeo.com/video/${videoId}`
103
103
  }
104
104
  return props.src
@@ -128,13 +128,13 @@ const videoUrl = computed(() => {
128
128
  height: auto;
129
129
  display: block;
130
130
  margin: auto;
131
- border-radius: var(--input-border-radius);
131
+ border-radius: var(--bgl-input-border-radius);
132
132
  }
133
133
 
134
134
  .bgl_vid.vid_empty {
135
135
  padding-top: 56.25%;
136
- background: var(--input-bg);
137
- border-radius: var(--input-border-radius);
136
+ background: var(--bgl-input-bg);
137
+ border-radius: var(--bgl-input-border-radius);
138
138
  }
139
139
 
140
140
  .bgl_vid.vid_short {
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  import type { IconType, ExtendedThemeType, TranslatableString } from '@bagelink/vue'
3
3
  import type { SetupContext } from 'vue'
4
- import { Icon, Loading, useModal, useI18n, resolveI18n } from '@bagelink/vue'
4
+ import { Icon, Loading, useDialog, useI18n, resolveI18n, MOBILE_BREAKPOINT } from '@bagelink/vue'
5
5
  import { useSlots, ref, onMounted, onUnmounted, computed } from 'vue'
6
6
  import { RouterLink } from 'vue-router'
7
7
  defineOptions({ name: 'BglBtn' })
@@ -13,12 +13,20 @@ const props = withDefaults(
13
13
  iconSize?: number | string
14
14
  iconMobileSize?: number | string
15
15
  color?: ExtendedThemeType
16
- theme?: ExtendedThemeType
16
+ variant?: 'solid' | 'flat' | 'outline'
17
+ /** Boolean variant shorthands: <Btn flat /> — same as variant="flat" */
17
18
  flat?: boolean
18
- border?: boolean
19
19
  outline?: boolean
20
+ /** @deprecated Use `outline` */
21
+ border?: boolean
20
22
  thin?: boolean
21
- size?: 'xs' | 's' | 'm' | 'l' | 'xl' | 'extra-small' | 'small' | 'medium' | 'large' | 'extra-large'
23
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'
24
+ /** Boolean size shorthands: <Btn sm value="Click me" /> */
25
+ xs?: boolean
26
+ sm?: boolean
27
+ md?: boolean
28
+ lg?: boolean
29
+ xl?: boolean
22
30
  type?: 'button' | 'submit' | 'reset'
23
31
  loading?: boolean
24
32
  role?: string
@@ -59,11 +67,18 @@ const emit = defineEmits<{
59
67
 
60
68
  const { $t } = useI18n()
61
69
 
70
+ const computedVariant = computed(() => {
71
+ if (props.variant) { return props.variant }
72
+ if (props.flat) { return 'flat' }
73
+ if (props.outline || props.border) { return 'outline' }
74
+ return 'solid'
75
+ })
76
+
62
77
  const computedPairClass = computed(() => {
63
- const theme = props.color || props.theme
78
+ const theme = props.color
64
79
  if (!theme) {
65
- // Only flat/border buttons get a default for visibility
66
- if (props.flat || props.border || props.outline) {
80
+ // Only flat/outline buttons get a default for visibility
81
+ if (computedVariant.value !== 'solid') {
67
82
  return 'pair-black'
68
83
  }
69
84
  return 'pair-default'
@@ -71,10 +86,20 @@ const computedPairClass = computed(() => {
71
86
  return `pair-${theme}`
72
87
  })
73
88
 
89
+ const computedSize = computed(() => {
90
+ if (props.size) { return props.size }
91
+ if (props.xs) { return 'xs' }
92
+ if (props.sm) { return 'sm' }
93
+ if (props.md) { return 'md' }
94
+ if (props.lg) { return 'lg' }
95
+ if (props.xl) { return 'xl' }
96
+ return undefined
97
+ })
98
+
74
99
  const isMobileScreen = ref(false)
75
100
 
76
101
  function checkMobile() {
77
- isMobileScreen.value = window.innerWidth <= 910
102
+ isMobileScreen.value = window.innerWidth <= MOBILE_BREAKPOINT
78
103
  }
79
104
 
80
105
  onMounted(() => {
@@ -88,9 +113,9 @@ onUnmounted(() => {
88
113
 
89
114
  async function handleClick(event: MouseEvent) {
90
115
  if (props.confirm !== undefined && props.confirm !== false) {
91
- const { confirmModal } = useModal()
116
+ const { confirm } = useDialog()
92
117
  const message = typeof props.confirm === 'string' ? props.confirm : $t('modalConfirm.message')
93
- const confirmed = await confirmModal({
118
+ const confirmed = await confirm({
94
119
  title: $t('modalConfirm.title'),
95
120
  message
96
121
  })
@@ -108,22 +133,9 @@ const iconSizeComputed = computed(() => {
108
133
  if (props.iconSize !== undefined) { return props.iconSize }
109
134
 
110
135
  // Default icon sizes based on button size
111
- const sizeMap = {
112
- 'xs': 0.7,
113
- 'extra-small': 0.7,
114
- 's': 0.9,
115
- 'small': 0.9,
116
- 'm': 1,
117
- 'medium': 1,
118
- 'l': 1.3,
119
- 'large': 1.3,
120
- 'xl': 1.6,
121
- 'extra-large': 1.6
122
- }
123
-
124
- if (props.size && sizeMap[props.size as keyof typeof sizeMap]) {
125
- return sizeMap[props.size as keyof typeof sizeMap]
126
- }
136
+ const sizeMap = { xs: 0.7, sm: 0.9, md: 1, lg: 1.3, xl: 1.6 }
137
+ const size = computedSize.value
138
+ if (size && sizeMap[size]) { return sizeMap[size] }
127
139
 
128
140
  return isMobileScreen.value ? 1 : 1.2
129
141
  })
@@ -155,11 +167,11 @@ const slots: SetupContext['slots'] = useSlots()
155
167
  :is="isComponent" v-ripple="ripple" v-bind="bind" :disabled="disabled" class="bgl_btn" :class="[{
156
168
  'bgl_btn-icon': icon && !slots.default && !value,
157
169
  thin,
158
- 'bgl_btn_xsSize': size === 'xs' || size === 'extra-small',
159
- 'bgl_btn_sSize': size === 's' || size === 'small',
160
- 'bgl_btn_mSize': size === 'm' || size === 'medium',
161
- 'bgl_btn_lSize': size === 'l' || size === 'large',
162
- 'bgl_btn_xlSize': size === 'xl' || size === 'extra-large',
170
+ 'bgl_btn_xsSize': computedSize === 'xs',
171
+ 'bgl_btn_sSize': computedSize === 'sm',
172
+ 'bgl_btn_mSize': computedSize === 'md',
173
+ 'bgl_btn_lSize': computedSize === 'lg',
174
+ 'bgl_btn_xlSize': computedSize === 'xl',
163
175
  'bgl_btn_fullWidth': fullWidth,
164
176
  'bgl_btn_fullWidthMobile': fullWidthMobile,
165
177
  'bgl_btn_alignStart': alignTxt === 'start',
@@ -167,8 +179,8 @@ const slots: SetupContext['slots'] = useSlots()
167
179
  'bgl_btn_alignStartMobile': alignTxtMobile === 'start',
168
180
  'bgl_btn_alignEndMobile': alignTxtMobile === 'end',
169
181
  round,
170
- 'bgl_flatPill': flat,
171
- 'bgl_pill-border': border || outline,
182
+ 'bgl_flatPill': computedVariant === 'flat',
183
+ 'bgl_pill-border': computedVariant === 'outline',
172
184
  }, computedPairClass]" :tabindex="disabled ? -1 : 0" @click.stop="handleClick" @keydown.enter="handleClick" @keydown.space="handleClick"
173
185
  >
174
186
  <Loading v-if="loading" class="h-100p" size="15" color="currentColor" />
@@ -193,8 +205,8 @@ const slots: SetupContext['slots'] = useSlots()
193
205
  /* @import '../styles/base-colors.css'; */
194
206
 
195
207
  .bgl_btn {
196
- padding-left: var(--btn-padding);
197
- padding-right: var(--btn-padding);
208
+ padding-left: var(--bgl-btn-padding);
209
+ padding-right: var(--bgl-btn-padding);
198
210
  transition: var(--bgl-transition);
199
211
  text-decoration: none;
200
212
  /* Colors now handled by pair-* classes */
@@ -203,8 +215,8 @@ const slots: SetupContext['slots'] = useSlots()
203
215
  .bgl_btn.bgl_btn-icon {
204
216
  padding-left: 0;
205
217
  padding-right: 0;
206
- height: var(--btn-height);
207
- width: var(--btn-height);
218
+ height: var(--bgl-btn-height);
219
+ width: var(--bgl-btn-height);
208
220
  border-radius: 100%;
209
221
  font-size: 1rem;
210
222
  flex-shrink: 0;
@@ -223,7 +235,7 @@ a {
223
235
  }
224
236
 
225
237
  .bgl_btn .bgl_btn-icon {
226
- font-size: calc(var(--input-font-size) * 1.3);
238
+ font-size: calc(var(--bgl-input-font-size) * 1.3);
227
239
  }
228
240
 
229
241
  .bgl_btn:hover,
@@ -265,20 +277,20 @@ a {
265
277
 
266
278
  /* xs size */
267
279
  .bgl_btn_xsSize {
268
- padding-inline: calc(var(--btn-padding) / 6);
269
- border-radius: calc(var(--btn-border-radius) / 2);
270
- font-size: calc(var(--input-font-size) * 0.6);
280
+ padding-inline: calc(var(--bgl-btn-padding) / 6);
281
+ border-radius: calc(var(--bgl-btn-border-radius) / 2);
282
+ font-size: calc(var(--bgl-input-font-size) * 0.6);
271
283
  }
272
284
 
273
285
  .bgl_btn-icon.bgl_btn_xsSize {
274
- height: calc(var(--btn-height) / 2);
275
- width: calc(var(--btn-height) / 2);
286
+ height: calc(var(--bgl-btn-height) / 2);
287
+ width: calc(var(--bgl-btn-height) / 2);
276
288
  line-height: normal;
277
289
  }
278
290
 
279
291
  .bgl_btn_xsSize {
280
- height: calc(var(--btn-height) / 2);
281
- line-height: calc(var(--btn-height) / 2);
292
+ height: calc(var(--bgl-btn-height) / 2);
293
+ line-height: calc(var(--bgl-btn-height) / 2);
282
294
  }
283
295
 
284
296
  .bgl_btn_xsSize .bgl_btn-flex {
@@ -288,60 +300,60 @@ a {
288
300
  /* s size */
289
301
  .bgl_btn.thin,
290
302
  .bgl_btn_sSize {
291
- padding-inline: calc(var(--btn-padding) / 3);
292
- border-radius: calc(var(--btn-border-radius) / 1.5);
303
+ padding-inline: calc(var(--bgl-btn-padding) / 3);
304
+ border-radius: calc(var(--bgl-btn-border-radius) / 1.5);
293
305
  }
294
306
 
295
307
  .bgl_btn-icon.thin,
296
308
  .bgl_btn-icon.bgl_btn_sSize {
297
- height: calc(var(--btn-height) / 1.5);
298
- width: calc(var(--btn-height) / 1.5);
309
+ height: calc(var(--bgl-btn-height) / 1.5);
310
+ width: calc(var(--bgl-btn-height) / 1.5);
299
311
  line-height: normal;
300
312
  }
301
313
 
302
314
  .bgl_btn.thin,
303
315
  .bgl_btn_sSize {
304
- height: calc(var(--btn-height) * 0.7);
305
- line-height: calc(var(--btn-height) * 0.7);
316
+ height: calc(var(--bgl-btn-height) * 0.7);
317
+ line-height: calc(var(--bgl-btn-height) * 0.7);
306
318
  }
307
319
 
308
320
  /* m size */
309
321
  .bgl_btn_mSize {
310
- padding-inline: var(--btn-padding);
311
- font-size: var(--input-font-size);
312
- height: var(--btn-height);
313
- line-height: var(--btn-height);
322
+ padding-inline: var(--bgl-btn-padding);
323
+ font-size: var(--bgl-input-font-size);
324
+ height: var(--bgl-btn-height);
325
+ line-height: var(--bgl-btn-height);
314
326
  }
315
327
 
316
328
  .bgl_btn-icon.bgl_btn_mSize {
317
- height: var(--btn-height);
318
- width: var(--btn-height);
329
+ height: var(--bgl-btn-height);
330
+ width: var(--bgl-btn-height);
319
331
  }
320
332
 
321
333
  /* l size */
322
334
  .bgl_btn_lSize {
323
- padding-inline: calc(var(--btn-padding) * 1.3);
324
- font-size: calc(var(--input-font-size) * 1.1);
325
- height: calc(var(--btn-height) * 1.2);
326
- line-height: calc(var(--btn-height) * 1.2);
335
+ padding-inline: calc(var(--bgl-btn-padding) * 1.3);
336
+ font-size: calc(var(--bgl-input-font-size) * 1.1);
337
+ height: calc(var(--bgl-btn-height) * 1.2);
338
+ line-height: calc(var(--bgl-btn-height) * 1.2);
327
339
  }
328
340
 
329
341
  .bgl_btn-icon.bgl_btn_lSize {
330
- height: calc(var(--btn-height) * 1.2);
331
- width: calc(var(--btn-height) * 1.2);
342
+ height: calc(var(--bgl-btn-height) * 1.2);
343
+ width: calc(var(--bgl-btn-height) * 1.2);
332
344
  }
333
345
 
334
346
  /* xl size */
335
347
  .bgl_btn_xlSize {
336
- padding-inline: calc(var(--btn-padding) * 1.6);
337
- font-size: calc(var(--input-font-size) * 1.3);
338
- height: calc(var(--btn-height) * 1.5);
339
- line-height: calc(var(--btn-height) * 1.5);
348
+ padding-inline: calc(var(--bgl-btn-padding) * 1.6);
349
+ font-size: calc(var(--bgl-input-font-size) * 1.3);
350
+ height: calc(var(--bgl-btn-height) * 1.5);
351
+ line-height: calc(var(--bgl-btn-height) * 1.5);
340
352
  }
341
353
 
342
354
  .bgl_btn-icon.bgl_btn_xlSize {
343
- height: calc(var(--btn-height) * 1.5);
344
- width: calc(var(--btn-height) * 1.5);
355
+ height: calc(var(--bgl-btn-height) * 1.5);
356
+ width: calc(var(--bgl-btn-height) * 1.5);
345
357
  }
346
358
 
347
359
  .bgl_btn_fullWidth {
@@ -1,4 +1,5 @@
1
1
  <script setup lang="ts">
2
+ defineOptions({ name: 'BglCard' })
2
3
  import { computed } from 'vue'
3
4
 
4
5
  const props = defineProps<{
@@ -60,7 +61,7 @@ const is = computed(() => {
60
61
 
61
62
  <style>
62
63
  .card_frame {
63
- border: 1px solid var(--border-color);
64
+ border: 1px solid var(--bgl-border-color);
64
65
  }
65
66
  .card_label {
66
67
  font-size: 1rem;
@@ -68,7 +69,7 @@ const is = computed(() => {
68
69
  top: -0.5rem;
69
70
  padding: 0.75rem 0;
70
71
  display: block;
71
- border-bottom: 1px solid var(--border-color);
72
+ border-bottom: 1px solid var(--bgl-border-color);
72
73
  margin-bottom: 1rem;
73
74
  }
74
75
 
@@ -80,14 +81,14 @@ const is = computed(() => {
80
81
  position: absolute;
81
82
  top: -0.5rem;
82
83
  inset-inline-start: 1rem;
83
- border-left: 1px solid var(--border-color);
84
- border-right: 1px solid var(--border-color);
84
+ border-left: 1px solid var(--bgl-border-color);
85
+ border-right: 1px solid var(--bgl-border-color);
85
86
  border-bottom: unset;
86
87
 
87
88
  }
88
89
 
89
90
  .bgl_card {
90
- border-radius: var(--card-border-radius);
91
+ border-radius: var(--bgl-card-border-radius);
91
92
  background: var(--bgl-box-bg);
92
93
  padding: 2rem 2rem;
93
94
  position: relative;
@@ -98,7 +99,7 @@ const is = computed(() => {
98
99
  }
99
100
 
100
101
  .bgl_card.border {
101
- border: 1px solid var(--border-color);
102
+ border: 1px solid var(--bgl-border-color);
102
103
  background-color: transparent;
103
104
  }
104
105
 
@@ -2,7 +2,7 @@
2
2
  <!-- eslint-disable -->
3
3
  <script setup lang="ts">
4
4
  import type { IconType, ThemeType } from '@bagelink/vue'
5
- import { Btn, useDevice } from '@bagelink/vue'
5
+ import { Btn, useDevice, useEscapeKey } from '@bagelink/vue'
6
6
  import { autoPlacement, computePosition, flip, offset, shift } from '@floating-ui/dom'
7
7
  import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
8
8
 
@@ -67,10 +67,10 @@ const popoverRef = ref<HTMLElement | null>(null)
67
67
  const bglId = `bgl-dd-${++_bglIdCounter}`
68
68
  const teleportTarget = ref<string | Element>('body')
69
69
 
70
- const { isMobile, innerWidth } = useDevice()
70
+ const { isMobile } = useDevice()
71
71
 
72
72
  const shouldDisablePositioning = computed(() => props.disablePlacement && isMobile.value)
73
- const isSmallScreen = computed(() => innerWidth.value < 910)
73
+ const isSmallScreen = isMobile
74
74
 
75
75
  const effectiveTriggers = computed(() =>
76
76
  isSmallScreen.value
@@ -206,13 +206,8 @@ function onDocumentPointerDown(e: PointerEvent) {
206
206
  internalHide()
207
207
  }
208
208
 
209
- // Esc key
210
- function onKeydown(e: KeyboardEvent) {
211
- if (e.key === 'Escape' && isOpen()) {
212
- e.stopPropagation()
213
- internalHide()
214
- }
215
- }
209
+ // Esc key — LIFO via shared composable (nested layers close first)
210
+ useEscapeKey(() => internalHide(), () => isOpen())
216
211
 
217
212
  // Hover delay timers
218
213
  let showTimer: ReturnType<typeof setTimeout> | undefined
@@ -248,7 +243,6 @@ function onScroll() {
248
243
 
249
244
  onMounted(() => {
250
245
  document.addEventListener('pointerdown', onDocumentPointerDown, true)
251
- document.addEventListener('keydown', onKeydown)
252
246
  document.addEventListener('scroll', onScroll, { capture: true, passive: true })
253
247
  if (props.showGroup) {
254
248
  if (!groupRegistry.has(props.showGroup)) groupRegistry.set(props.showGroup, new Set())
@@ -258,7 +252,6 @@ onMounted(() => {
258
252
 
259
253
  onBeforeUnmount(() => {
260
254
  document.removeEventListener('pointerdown', onDocumentPointerDown, true)
261
- document.removeEventListener('keydown', onKeydown)
262
255
  document.removeEventListener('scroll', onScroll, true)
263
256
  clearTimers()
264
257
  if (props.showGroup) groupRegistry.get(props.showGroup)?.delete(internalHide)
@@ -289,14 +282,14 @@ defineExpose({ show, hide, shown })
289
282
  <Teleport :to="teleportTarget">
290
283
  <div
291
284
  ref="popoverRef" popover="manual" class="bgl-dropdown m-0 p-0 border-none"
292
- style="border-radius: var(--card-border-radius);"
285
+ style="border-radius: var(--bgl-card-border-radius);"
293
286
  :class="{ 'bgl-dropdown--no-positioning': shouldDisablePositioning, 'bg-white shadow': props.card }"
294
287
  @toggle="onPopoverToggle" @mouseenter="onPopoverMouseenter" @mouseleave="onPopoverMouseleave"
295
288
  @focus="onPopoverMouseenter" @blur="onPopoverMouseleave"
296
289
  >
297
290
  <div class="bgl-dropdown__backdrop" />
298
291
  <div class="bgl-dropdown__content overflow-hidden" :class="{ 'display-flex column': props.card }"
299
- style="border-radius: var(--card-border-radius);">
292
+ style="border-radius: var(--bgl-card-border-radius);">
300
293
  <slot :hide :show :shown />
301
294
  </div>
302
295
  </div>
@@ -16,8 +16,8 @@ defineProps<{
16
16
 
17
17
  <style scoped>
18
18
  fieldset {
19
- border: 1px solid var(--border-color);
20
- border-radius: var(--card-border-radius);
19
+ border: 1px solid var(--bgl-border-color);
20
+ border-radius: var(--bgl-card-border-radius);
21
21
  padding: var(--space-md);
22
22
  }
23
23
  </style>
@@ -486,7 +486,7 @@ function onConnectorChange(id: string, connector: LogicalOperator) {
486
486
 
487
487
  <!-- Remove button -->
488
488
  <Btn
489
- icon="close" thin flat size="small" class="m_bg-gray-40 m_px-3 m_mx-auto"
489
+ icon="close" thin flat size="sm" class="m_bg-gray-40 m_px-3 m_mx-auto"
490
490
  @click="removeCondition(index)"
491
491
  />
492
492
  </div>
@@ -513,7 +513,7 @@ function onConnectorChange(id: string, connector: LogicalOperator) {
513
513
 
514
514
  <style>
515
515
  .and-or-select {
516
- --input-font-size: 12px !important;
516
+ --bgl-input-font-size: 12px !important;
517
517
  --input-background-color: transparent !important;
518
518
  }
519
519
 
@@ -574,6 +574,6 @@ function onConnectorChange(id: string, connector: LogicalOperator) {
574
574
  }
575
575
 
576
576
  .borderHover:hover {
577
- --border-color: var(--bgl-primary);
577
+ --bgl-border-color: var(--bgl-primary);
578
578
  }
579
579
  </style>
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
- import { Skeleton, normalizeDimension, appendScript, normalizeURL, Icon, pathKeyToURL } from '@bagelink/vue'
2
+ defineOptions({ name: 'BglImage' })
3
+ import { Skeleton, normalizeDimension, appendScript, awaitGlobal, normalizeURL, Icon, pathKeyToURL } from '@bagelink/vue'
3
4
  import { ref, watch } from 'vue'
4
5
 
5
6
  interface ImageProps {
@@ -54,9 +55,10 @@ async function cacheImage(url: string, blob: Blob) {
54
55
 
55
56
  async function convertHeicImage(url: string): Promise<string> {
56
57
  await appendScript('https://cdnjs.cloudflare.com/ajax/libs/heic2any/0.0.1/index.min.js')
58
+ const heic2any = await awaitGlobal<(opts: { blob: Blob }) => Promise<Blob>>('heic2any')
57
59
  const response = await fetch(normalizeURL(url))
58
60
  const blob = await response.blob()
59
- const convertedBlob = await window.heic2any({ blob }) as Blob
61
+ const convertedBlob = await heic2any({ blob })
60
62
  await cacheImage(url, convertedBlob)
61
63
  return URL.createObjectURL(convertedBlob)
62
64
  }
@@ -144,6 +146,6 @@ watch(() => [props.src, props.pathKey, props.modelValue], loadImage, { immediate
144
146
  width: 100%;
145
147
  }
146
148
  .error-image {
147
- background-color: var(--skeleton-bg);
149
+ background-color: var(--bgl-skeleton-bg);
148
150
  }
149
151
  </style>