@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
@@ -66,21 +66,21 @@ onMounted(() => {
66
66
  appearance: none;
67
67
  position: relative;
68
68
  display: inline-block;
69
- background: var(--input-bg);
70
- height: calc(var(--input-height) / 2);
71
- width: calc(var(--input-height) - 2px);
69
+ background: var(--bgl-input-bg);
70
+ height: calc(var(--bgl-input-height) / 2);
71
+ width: calc(var(--bgl-input-height) - 2px);
72
72
  vertical-align: middle;
73
73
  border-radius: 2rem;
74
74
  box-shadow: 0px 1px 3px #0003 inset;
75
75
  transition: 0.25s linear all;
76
- outline: 1px solid var(--border-color);
76
+ outline: 1px solid var(--bgl-border-color);
77
77
 
78
78
  }
79
79
  .bgl-toggle input::before {
80
80
  position: absolute;
81
81
  content: "";
82
- height: calc(var(--input-height) / 2 - 2px);
83
- width: calc(var(--input-height) / 2 - 2px);
82
+ height: calc(var(--bgl-input-height) / 2 - 2px);
83
+ width: calc(var(--bgl-input-height) / 2 - 2px);
84
84
  inset-inline-start: 1px;
85
85
  bottom: 1px;
86
86
  border-radius: 50%;
@@ -95,8 +95,8 @@ onMounted(() => {
95
95
  transition: var(--bgl-transition);
96
96
  cursor: pointer;
97
97
  user-select: none;
98
- line-height: var(--input-height);
99
- font-size: var(--input-font-size);
98
+ line-height: var(--bgl-input-height);
99
+ font-size: var(--bgl-input-font-size);
100
100
  vertical-align: middle;
101
101
  }
102
102
 
@@ -123,7 +123,7 @@ onMounted(() => {
123
123
  background: var(--bgl-input-label-active-color, var(--bgl-primary));
124
124
  }
125
125
  .bgl-toggle :checked::before{
126
- margin-inline-start:calc(var(--input-height) / 2 - 2px) ;
126
+ margin-inline-start:calc(var(--bgl-input-height) / 2 - 2px) ;
127
127
  }
128
128
  .bgl-toggle input:checked + label {
129
129
  color: var(--bgl-input-label-active-color, var(--bgl-primary)) !important;
@@ -131,13 +131,13 @@ onMounted(() => {
131
131
 
132
132
  /* ── bgl-outline variant ── */
133
133
  .bgl-outline input {
134
- outline: 1.5px solid var(--border-color) !important;
134
+ outline: 1.5px solid var(--bgl-border-color) !important;
135
135
  outline-offset: 2px;
136
136
  }
137
137
 
138
138
  /* ── frame variant ── */
139
139
  .frame input {
140
- outline: 1.5px solid var(--border-color) !important;
140
+ outline: 1.5px solid var(--bgl-border-color) !important;
141
141
  outline-offset: 2px;
142
142
  transition: outline-color 0.2s ease, box-shadow 0.2s ease;
143
143
  background: transparent;
@@ -1,19 +1,19 @@
1
1
  .fileUploadWrap {
2
- outline: 1px solid var(--border-color);
3
- border-radius: var(--input-border-radius);
2
+ outline: 1px solid var(--bgl-border-color);
3
+ border-radius: var(--bgl-input-border-radius);
4
4
  text-align: center;
5
5
  cursor: pointer;
6
6
  transition: var(--bgl-transition);
7
7
  position: relative;
8
- font-size: var(--input-font-size);
8
+ font-size: var(--bgl-input-font-size);
9
9
  overflow-y: auto;
10
- background: var(--input-bg);
10
+ background: var(--bgl-input-bg);
11
11
  height: 215px;
12
12
  outline-offset: -1px;
13
13
  }
14
14
 
15
15
  .bagel-input .fileUploadWrap.fileDropZone {
16
- background: var(--input-bg);
16
+ background: var(--bgl-input-bg);
17
17
  display: flex;
18
18
  align-items: center;
19
19
  justify-content: center;
@@ -31,21 +31,21 @@
31
31
  }
32
32
 
33
33
  .multi-image-item-preview {
34
- border: 1px solid var(--border-color) !important;
35
- border-radius: var(--input-border-radius);
34
+ border: 1px solid var(--bgl-border-color) !important;
35
+ border-radius: var(--bgl-input-border-radius);
36
36
  margin: 0.5rem !important;
37
37
  background: var(--bgl-popup-bg);
38
38
  padding: 0;
39
39
  padding-inline-end: 1rem;
40
40
  padding-inline-start: 0.25rem;
41
41
  text-align: start;
42
- color: var(--input-color);
42
+ color: var(--bgl-input-color);
43
43
  display: grid;
44
44
  grid-template-columns: auto 1fr 22px;
45
45
  gap: 0.5rem;
46
46
  align-items: center;
47
- height: var(--btn-height);
48
- font-size: var(--label-font-size);
47
+ height: var(--bgl-btn-height);
48
+ font-size: var(--bgl-label-font-size);
49
49
  }
50
50
 
51
51
  .multi-image-item-preview p {
@@ -56,9 +56,9 @@
56
56
 
57
57
  .multi-preview {
58
58
  /* width: 40px; */
59
- height: calc(var(--btn-height) - 0.5rem);
60
- max-width: calc(var(--btn-height) - 0.5rem);
61
- border-radius: calc(var(--input-border-radius) / 2);
59
+ height: calc(var(--bgl-btn-height) - 0.5rem);
60
+ max-width: calc(var(--bgl-btn-height) - 0.5rem);
61
+ border-radius: calc(var(--bgl-input-border-radius) / 2);
62
62
  object-fit: cover;
63
63
  background: var(--bgl-gray-light);
64
64
  text-align: center !important;
@@ -266,7 +266,7 @@
266
266
  }
267
267
 
268
268
  .bagel-input.has-error .fileUploadWrap {
269
- outline-color: var(--bgl-red, #dc3545);
269
+ outline-color: var(--bgl-red);
270
270
  }
271
271
 
272
272
  /* ─── Variant: frame ─────────────────────────────────────────────────────── */
@@ -274,7 +274,7 @@
274
274
  .bagel-input.frame .fileUploadWrap,
275
275
  .bagel-input.frame .fileUploadWrap.fileDropZone {
276
276
  background: transparent;
277
- outline-color: var(--border-color);
277
+ outline-color: var(--bgl-border-color);
278
278
  transition: outline-color 0.2s ease, box-shadow 0.2s ease;
279
279
  }
280
280
 
@@ -285,5 +285,5 @@
285
285
  }
286
286
 
287
287
  .bagel-input.has-error :deep(.bgl-card) {
288
- border-color: var(--bgl-red, #dc3545);
288
+ border-color: var(--bgl-red);
289
289
  }
@@ -6,11 +6,12 @@ export { default as Alert } from './Alert.vue'
6
6
  export * from './analytics'
7
7
  export { default as Avatar } from './Avatar.vue'
8
8
  export { default as Badge } from './Badge.vue'
9
+ /** @deprecated Renamed to Badge. Pill is an alias that will be removed in a future version. */
10
+ export { default as Pill } from './Badge.vue'
9
11
  export { default as BglVideo } from './BglVideo.vue'
10
12
  export { default as Btn } from './Btn.vue'
11
13
  export { default as Calendar } from './calendar/Index.vue'
12
14
  export { default as Card } from './Card.vue'
13
- export { default as Carousel } from './Carousel.vue'
14
15
  export { default as DataPreview } from './DataPreview.vue'
15
16
  export { default as DataTable } from './dataTable/DataTable.vue'
16
17
  /** @deprecated Use DataTable instead. TableSchema is an alias that will be removed in a future version. */
@@ -27,26 +28,18 @@ export { default as Icon } from './Icon/Icon.vue'
27
28
  export { FONT_AWESOME_ICONS, FONT_AWESOME_BRANDS_ICONS, MATERIAL_ICONS } from './Icon/constants'
28
29
  export { default as IframeVue } from './IframeVue.vue'
29
30
  export { default as Image } from './Image.vue'
30
- export { default as ImportData } from './ImportData.vue'
31
31
  export * from './layout'
32
32
  export { default as ListItem } from './ListItem.vue'
33
33
  export { default as ListView } from './ListView.vue'
34
34
  export { default as Loading } from './Loading.vue'
35
35
  export { default as MapEmbed } from './MapEmbed/Index.vue'
36
36
  export { default as Menu } from './Menu.vue'
37
- export { default as Modal } from './Modal.vue'
38
- export { default as ModalConfirm } from './ModalConfirm.vue'
39
- export { default as ModalForm } from './ModalForm.vue'
40
37
  export { default as NavBar } from './NavBar.vue'
41
38
  export { default as PageTitle } from './PageTitle.vue'
42
39
  export { default as Pagination } from './Pagination.vue'
43
- export { default as Pill } from './Pill.vue'
44
40
  export { default as Rating } from './Rating.vue'
45
41
  export { default as RouterWrapper } from './RouterWrapper.vue'
46
- export { default as Slider } from './Slider.vue'
47
42
  export { default as Spreadsheet } from './Spreadsheet/Index.vue'
48
43
  export { default as Swiper } from './Swiper.vue'
49
- export { default as Title } from './Title.vue'
50
- export { default as ToolBar } from './ToolBar.vue'
51
44
  export { default as TopBar } from './TopBar.vue'
52
45
  export { default as Zoomer } from './Zoomer.vue'
@@ -1,6 +1,6 @@
1
1
  <script lang="ts" setup>
2
2
  import { Btn, PageTitle } from '@bagelink/vue'
3
- import { inject, computed } from 'vue'
3
+ import { useAppLayout } from './appLayoutContext'
4
4
 
5
5
  interface Props {
6
6
  title?: string
@@ -14,28 +14,13 @@ withDefaults(defineProps<Props>(), {
14
14
  border: true,
15
15
  })
16
16
 
17
- // Inject menu state from parent
18
- const menuState = inject('menuState', {
19
- isOpen: { value: true },
20
- isMobile: { value: false },
21
- toggleMenu: () => { },
22
- }) as {
23
- isOpen: { value: boolean }
24
- isMobile: { value: boolean }
25
- toggleMenu: () => void
26
- }
27
-
28
- // Inject sidebar card style state
29
- const sidebarCardStyle = inject('sidebarCardStyle', { value: false })
30
-
31
- // Computed property to check if sidebar has card style
32
- const hasSidebarCard = computed(() => sidebarCardStyle?.value ?? false)
17
+ const { isOpen, toggleMenu, sidebarCardStyle } = useAppLayout()
33
18
  </script>
34
19
 
35
20
  <template>
36
21
  <div
37
22
  class="app-content h-100p flex column" :class="{
38
- paddingAppContent: hasSidebarCard,
23
+ paddingAppContent: sidebarCardStyle,
39
24
  }"
40
25
  >
41
26
  <!-- Header -->
@@ -48,7 +33,8 @@ const hasSidebarCard = computed(() => sidebarCardStyle?.value ?? false)
48
33
  <!-- Menu Toggle Button -->
49
34
  <Btn
50
35
  v-if="showMenuButton" flat icon="dock_to_right" class="menuToggleButton"
51
- @click="menuState.toggleMenu"
36
+ :aria-expanded="isOpen" aria-controls="bgl-app-sidebar" aria-label="Toggle sidebar"
37
+ @click="toggleMenu"
52
38
  />
53
39
 
54
40
  <!-- Back Button -->
@@ -1,35 +1,69 @@
1
1
  <script lang="ts" setup>
2
- import { ref, provide, onMounted, onUnmounted, computed } from 'vue'
2
+ import { ref, provide, onMounted, onUnmounted, computed, watch } from 'vue'
3
+ import { useEscapeKey } from '../../composables/useEscapeKey'
4
+ import { MOBILE_BREAKPOINT } from '../../utils/constants'
5
+ import { AppLayoutKey, SIDEBAR_COLLAPSED_WIDTH, SIDEBAR_COLLAPSED_WIDTH_CARD } from './appLayoutContext'
3
6
 
4
7
  interface Props {
5
8
  sidebarWidth?: string
6
9
  sidebarCardStyle?: boolean
7
10
  defaultOpen?: boolean
11
+ /** v-model:open — controlled sidebar state */
12
+ open?: boolean
13
+ /** Persist sidebar state to localStorage (desktop only). Default true. */
14
+ persist?: boolean
15
+ storageKey?: string
8
16
  }
9
17
 
10
18
  const props = withDefaults(defineProps<Props>(), {
11
19
  sidebarWidth: '260px',
12
20
  sidebarCardStyle: false,
13
21
  defaultOpen: true,
22
+ open: undefined,
23
+ persist: true,
24
+ storageKey: 'bgl-sidebar-open',
14
25
  })
15
26
 
16
- // Menu state
17
- const isOpen = ref(props.defaultOpen)
27
+ const emit = defineEmits<{ 'update:open': [value: boolean] }>()
28
+
29
+ function readStored(): boolean | undefined {
30
+ if (!props.persist || typeof localStorage === 'undefined') { return undefined }
31
+ const raw = localStorage.getItem(props.storageKey)
32
+ return raw === null ? undefined : raw === 'true'
33
+ }
34
+
35
+ const isOpen = ref(props.open ?? readStored() ?? props.defaultOpen)
18
36
  const isMobile = ref(false)
19
37
 
20
- // Check if mobile
38
+ const sidebarCollapsedWidth = props.sidebarCardStyle ? SIDEBAR_COLLAPSED_WIDTH_CARD : SIDEBAR_COLLAPSED_WIDTH
39
+
40
+ // Sync controlled prop → internal state
41
+ watch(() => props.open, (v) => {
42
+ if (v !== undefined) { isOpen.value = v }
43
+ })
44
+
45
+ watch(isOpen, (v) => {
46
+ emit('update:open', v)
47
+ // Persist only explicit desktop state — never the forced mobile collapse
48
+ if (props.persist && !isMobile.value && typeof localStorage !== 'undefined') {
49
+ localStorage.setItem(props.storageKey, String(v))
50
+ }
51
+ })
52
+
21
53
  function checkMobile() {
22
- isMobile.value = window.innerWidth < 910
54
+ isMobile.value = window.innerWidth <= MOBILE_BREAKPOINT
23
55
  if (isMobile.value) {
24
56
  isOpen.value = false
25
57
  }
26
58
  }
27
59
 
28
- // Toggle menu
29
60
  function toggleMenu() {
30
61
  isOpen.value = !isOpen.value
31
62
  }
32
63
 
64
+ // Esc closes the sidebar overlay on mobile
65
+ useEscapeKey(() => { isOpen.value = false }, () => isMobile.value && isOpen.value)
66
+
33
67
  // Close menu on mobile when clicking outside
34
68
  function closeOnMobile() {
35
69
  if (isMobile.value) {
@@ -42,26 +76,21 @@ const mainContentStyles = computed(() => {
42
76
  if (isMobile.value) {
43
77
  return { marginInlineStart: '0' }
44
78
  }
45
- const collapsedWidth = props.sidebarCardStyle ? '82px' : '66px'
46
79
  return {
47
- marginInlineStart: isOpen.value ? props.sidebarWidth : collapsedWidth
80
+ marginInlineStart: isOpen.value ? props.sidebarWidth : sidebarCollapsedWidth
48
81
  }
49
82
  })
50
83
 
51
- // Provide state to child components
52
- provide('menuState', {
84
+ provide(AppLayoutKey, {
53
85
  isOpen,
54
86
  isMobile,
55
87
  toggleMenu,
56
88
  closeOnMobile,
57
89
  sidebarWidth: props.sidebarWidth,
58
- sidebarCollapsedWidth: props.sidebarCardStyle ? '82px' : '66px'
90
+ sidebarCollapsedWidth,
91
+ sidebarCardStyle: props.sidebarCardStyle,
59
92
  })
60
93
 
61
- // Provide sidebar card style based on prop
62
- provide('sidebarCardStyle', { value: props.sidebarCardStyle })
63
-
64
- // Initialize
65
94
  onMounted(() => {
66
95
  checkMobile()
67
96
  window.addEventListener('resize', checkMobile)
@@ -82,7 +111,7 @@ onUnmounted(() => {
82
111
  />
83
112
 
84
113
  <!-- Sidebar Slot -->
85
- <slot name="sidebar" />
114
+ <slot name="sidebar" v-bind="{ isOpen, isMobile, toggleMenu, closeOnMobile }" />
86
115
 
87
116
  <!-- Main Content Area -->
88
117
  <main
@@ -90,11 +119,11 @@ onUnmounted(() => {
90
119
  :style="mainContentStyles"
91
120
  >
92
121
  <!-- Header Slot -->
93
- <slot name="header" />
122
+ <slot name="header" v-bind="{ isOpen, isMobile, toggleMenu, closeOnMobile }" />
94
123
 
95
124
  <!-- Page Content -->
96
125
  <div class="page-content overflow w-100p h-100p">
97
- <slot />
126
+ <slot v-bind="{ isOpen, isMobile, toggleMenu, closeOnMobile }" />
98
127
  </div>
99
128
  </main>
100
129
  </div>
@@ -1,9 +1,10 @@
1
1
  <script lang="ts" setup>
2
2
  import type { NavLink } from '@bagelink/vue'
3
3
  import { Btn, Icon } from '@bagelink/vue'
4
- import { inject, computed, ref, watch } from 'vue'
4
+ import { computed, ref, watch } from 'vue'
5
5
  import { useRoute } from 'vue-router'
6
6
  import { resolveI18n } from '../../i18n'
7
+ import { useAppLayout, SIDEBAR_COLLAPSED_WIDTH, SIDEBAR_COLLAPSED_WIDTH_CARD } from './appLayoutContext'
7
8
 
8
9
  // Extended interface for links with active route tracking
9
10
  interface LinkWithAction extends NavLink {
@@ -24,13 +25,11 @@ interface Props {
24
25
  frame?: boolean
25
26
  activeRoutes?: string[]
26
27
  centerlinks?: boolean
27
- defaultOpen?: boolean
28
28
  }
29
29
 
30
30
  const props = withDefaults(defineProps<Props>(), {
31
31
  card: true,
32
32
  centerlinks: false,
33
- defaultOpen: true,
34
33
  bgColor: 'var(--bgl-white)',
35
34
  textColor: 'var(--bgl-black)',
36
35
  activeColor: 'var(--bgl-black)',
@@ -43,32 +42,16 @@ const props = withDefaults(defineProps<Props>(), {
43
42
  const route = useRoute()
44
43
  const isTransitioning = ref(false)
45
44
 
46
- // Inject menu state from parent
47
- const _fallbackIsOpen = ref(props.defaultOpen)
48
- const _fallbackIsMobile = ref(false)
49
-
50
- const menuState = inject('menuState', {
51
- isOpen: _fallbackIsOpen,
52
- isMobile: _fallbackIsMobile,
53
- closeOnMobile: () => void 0,
54
- sidebarWidth: '260px',
55
- sidebarCollapsedWidth: '66px',
56
- }) as {
57
- isOpen: { value: boolean }
58
- isMobile: { value: boolean }
59
- closeOnMobile: () => void
60
- sidebarWidth: string
61
- sidebarCollapsedWidth: string
62
- }
45
+ const { isOpen, isMobile, sidebarWidth, toggleMenu, closeOnMobile } = useAppLayout()
63
46
 
64
47
  // visually "open" during transition — prevents logo/padding from jumping immediately
65
- const isVisuallyOpen = computed(() => menuState.isOpen.value || isTransitioning.value)
48
+ const isVisuallyOpen = computed(() => isOpen.value || isTransitioning.value)
66
49
 
67
50
  // Watch for changes in menu state to handle transitioning
68
51
  watch(
69
- () => menuState.isOpen.value,
52
+ () => isOpen.value,
70
53
  () => {
71
- if (!menuState.isMobile.value) {
54
+ if (!isMobile.value) {
72
55
  isTransitioning.value = true
73
56
  // Reset after transition completes
74
57
  setTimeout(() => {
@@ -134,9 +117,9 @@ function isActiveRoute(link: LinkWithAction): boolean {
134
117
  const sidebarStyles = computed(() => {
135
118
  let width = '280px'
136
119
 
137
- if (!menuState.isMobile.value) {
138
- const collapsedWidth = props.card ? '82px' : '68px'
139
- width = menuState.isOpen.value ? menuState.sidebarWidth : collapsedWidth
120
+ if (!isMobile.value) {
121
+ const collapsedWidth = props.card ? SIDEBAR_COLLAPSED_WIDTH_CARD : SIDEBAR_COLLAPSED_WIDTH
122
+ width = isOpen.value ? sidebarWidth : collapsedWidth
140
123
  }
141
124
 
142
125
  return {
@@ -147,20 +130,20 @@ const sidebarStyles = computed(() => {
147
130
 
148
131
  <template>
149
132
  <aside
133
+ id="bgl-app-sidebar"
150
134
  class="app-sidebar transition-400 fixed start top bottom h-100vh z-99" :class="{
151
- 'sidebar-mobile-open': menuState.isMobile.value && menuState.isOpen.value,
152
- 'sidebar-mobile-closed':
153
- menuState.isMobile.value && !menuState.isOpen.value,
135
+ 'sidebar-mobile-open': isMobile && isOpen,
136
+ 'sidebar-mobile-closed': isMobile && !isOpen,
154
137
  'transitioning': isTransitioning,
155
138
  'p-05': props.card,
156
- 'sidebar-collapsed': !menuState.isMobile.value && !menuState.isOpen.value,
139
+ 'sidebar-collapsed': !isMobile && !isOpen,
157
140
  }" :style="sidebarStyles"
158
141
  >
159
142
  <div
160
143
  :style="{
161
144
  backgroundColor: props.bgColor,
162
145
  color: props.textColor,
163
- ...(props.card && { borderRadius: 'var(--card-border-radius)' }),
146
+ ...(props.card && { borderRadius: 'var(--bgl-card-border-radius)' }),
164
147
  }" :class="{
165
148
  'card cardWrapSide': props.card,
166
149
  'px-05': !isVisuallyOpen,
@@ -186,7 +169,7 @@ const sidebarStyles = computed(() => {
186
169
  <nav class="sidebar-nav flex column flex-stretch gap-025 align-items-start" :class="{ 'justify-content-center': props.centerlinks }">
187
170
  <Btn
188
171
  v-for="link in props.navLinks" :key="link.to"
189
- :title="!menuState.isOpen.value && !menuState.isMobile.value ? resolveI18n(link.label) : ''" fullWidth
172
+ :title="!isOpen && !isMobile ? resolveI18n(link.label) : ''" fullWidth
190
173
  alignTxt="start" class="flex-shrink-0 px-075" :class="{ 'nav-btn-active': isActiveRoute(link) }"
191
174
  :style="{
192
175
  backgroundColor: isActiveRoute(link) ? props.activeColor : props.bgColor,
@@ -205,7 +188,7 @@ const sidebarStyles = computed(() => {
205
188
  <!-- Footer Links -->
206
189
  <Btn
207
190
  v-for="link in props.footerLinks" :key="link.to || link.label"
208
- :title="!menuState.isOpen.value && !menuState.isMobile.value ? resolveI18n(link.label) : ''"
191
+ :title="!isOpen && !isMobile ? resolveI18n(link.label) : ''"
209
192
  :style="{
210
193
  backgroundColor: isActiveRoute(link) ? props.activeColor : props.bgColor,
211
194
  color: isActiveRoute(link) ? 'white' : props.textColor,
@@ -219,7 +202,7 @@ const sidebarStyles = computed(() => {
219
202
  </span>
220
203
  </Btn>
221
204
  <!-- Custom Footer Content Slot -->
222
- <slot name="footer" />
205
+ <slot name="footer" v-bind="{ isOpen, isMobile, toggleMenu, closeOnMobile }" />
223
206
  </div>
224
207
  </div>
225
208
  </aside>
@@ -227,7 +210,7 @@ const sidebarStyles = computed(() => {
227
210
 
228
211
  <style>
229
212
  .aside_frame {
230
- outline: 1px solid var(--border-color);
213
+ outline: 1px solid var(--bgl-border-color);
231
214
  }
232
215
 
233
216
  .card .aside_frame {
@@ -236,7 +219,7 @@ const sidebarStyles = computed(() => {
236
219
 
237
220
  .app-sidebar {
238
221
  transition: width 0.4s ease;
239
- --input-font-size: 0.875rem;
222
+ --bgl-input-font-size: 0.875rem;
240
223
  /* 14px */
241
224
  }
242
225
 
@@ -59,7 +59,7 @@ defineProps<{
59
59
  }
60
60
 
61
61
  .bgl_bottombar .nav-button {
62
- border-radius: var(--card-border-radius);
62
+ border-radius: var(--bgl-card-border-radius);
63
63
 
64
64
  }
65
65
 
@@ -1,6 +1,9 @@
1
1
  <script lang="ts" setup>
2
2
  import { computed, onMounted, onUnmounted, provide, ref } from 'vue'
3
3
  import { RESIZABLE_KEY, useResizableLayoutProvider } from '../../composables/useResizableLayout'
4
+ import { MOBILE_BREAKPOINT } from '../../utils/constants'
5
+
6
+ defineOptions({ name: 'BglResizable' })
4
7
 
5
8
  interface Props {
6
9
  /** Lay panels side-by-side. Default: vertical (stacked). */
@@ -11,14 +14,14 @@ interface Props {
11
14
  * Set `:breakpoint="0"` to disable responsive switching entirely.
12
15
  */
13
16
  mobileVertical?: boolean
14
- /** Width (px) below which the mobile layout activates. @default 768 */
17
+ /** Width (px) below which the mobile layout activates. @default MOBILE_BREAKPOINT (910) */
15
18
  breakpoint?: number
16
19
  }
17
20
 
18
21
  const props = withDefaults(defineProps<Props>(), {
19
22
  horizontal: false,
20
23
  mobileVertical: true,
21
- breakpoint: 768,
24
+ breakpoint: MOBILE_BREAKPOINT,
22
25
  })
23
26
 
24
27
  const containerEl = ref<HTMLElement>()
@@ -1,9 +1,10 @@
1
1
  <script lang="ts" setup>
2
+ defineOptions({ name: 'BglSkeleton' })
2
3
  const {
3
4
  count = 1,
4
5
  height,
5
6
  width,
6
- borderRadius = 'var(--skeleton-radius)',
7
+ borderRadius = 'var(--bgl-skeleton-radius)',
7
8
  round = false,
8
9
  class: className = '',
9
10
  } = defineProps<{
@@ -31,11 +32,11 @@ const slots: SetupContext['slots'] = useSlots()
31
32
 
32
33
  <style scoped>
33
34
  .skeleton-wrap {
34
- margin-bottom: var(--skeleton-margin);
35
+ margin-bottom: var(--bgl-skeleton-margin);
35
36
  }
36
37
 
37
38
  .skeleton {
38
- background-color: var(--skeleton-bg);
39
+ background-color: var(--bgl-skeleton-bg);
39
40
  border-radius: var(--bg-card-radius);
40
41
  margin-bottom: 0.25em;
41
42
  position: relative;
@@ -44,7 +45,7 @@ const slots: SetupContext['slots'] = useSlots()
44
45
 
45
46
  .skeleton::before {
46
47
  content: "";
47
- background: linear-gradient(90deg, transparent 20%, var(--skeleton-pulse) 50%, transparent 80%);
48
+ background: linear-gradient(90deg, transparent 20%, var(--bgl-skeleton-pulse) 50%, transparent 80%);
48
49
  animation: loadingAnimation 1s ease-in-out infinite;
49
50
  position: absolute;
50
51
  inset: 0px;