@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.
- package/dist/components/AddressSearch.vue.d.ts +6 -7
- package/dist/components/Alert.vue.d.ts.map +1 -1
- package/dist/components/Avatar.vue.d.ts.map +1 -1
- package/dist/components/Badge.vue.d.ts.map +1 -1
- package/dist/components/Btn.vue.d.ts +1 -1
- package/dist/components/Btn.vue.d.ts.map +1 -1
- package/dist/components/Card.vue.d.ts.map +1 -1
- package/dist/components/Carousel.vue.d.ts +0 -11
- package/dist/components/Dropdown.vue.d.ts +0 -2
- package/dist/components/Dropdown.vue.d.ts.map +1 -1
- package/dist/components/Filter.vue.d.ts +30 -0
- package/dist/components/Filter.vue.d.ts.map +1 -0
- package/dist/components/FilterQuery.vue.d.ts +8 -3
- package/dist/components/Image.vue.d.ts.map +1 -1
- package/dist/components/ImportData.vue.d.ts.map +1 -1
- package/dist/components/ListItem.vue.d.ts.map +1 -1
- package/dist/components/MapEmbed/Index.vue.d.ts.map +1 -1
- package/dist/components/Modal.vue.d.ts +0 -1
- package/dist/components/Pagination.vue.d.ts.map +1 -1
- package/dist/components/Pill.vue.d.ts.map +1 -1
- package/dist/components/QueryFilter.vue.d.ts +30 -0
- package/dist/components/QueryFilter.vue.d.ts.map +1 -0
- package/dist/components/Swiper.vue.d.ts +6 -12
- package/dist/components/Swiper.vue.d.ts.map +1 -1
- package/dist/components/Toast.vue.d.ts.map +1 -1
- package/dist/components/analytics/PieChart.vue.d.ts +2 -2
- package/dist/components/calendar/CalendarPopover.vue.d.ts +8 -4
- package/dist/components/calendar/CalendarPopover.vue.d.ts.map +1 -1
- package/dist/components/calendar/CalendarTypes.d.ts +0 -10
- package/dist/components/calendar/Index.vue.d.ts +4 -20
- package/dist/components/calendar/views/WeekView.vue.d.ts +1 -9
- package/dist/components/dataTable/DataTable.vue.d.ts.map +1 -1
- package/dist/components/form/index.d.ts.map +1 -1
- package/dist/components/form/inputs/ArrayInput.vue.d.ts +2 -4
- package/dist/components/form/inputs/CheckInput.vue.d.ts +1 -2
- package/dist/components/form/inputs/Checkbox.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/CodeEditor/Index.vue.d.ts +0 -54
- package/dist/components/form/inputs/ColorInput.vue.d.ts +1 -3
- package/dist/components/form/inputs/DateInput.vue.d.ts +1 -2
- package/dist/components/form/inputs/DatePicker.vue.d.ts +0 -1
- package/dist/components/form/inputs/EmailInput.vue.d.ts +2 -5
- package/dist/components/form/inputs/JSONInput.vue.d.ts +1 -2
- package/dist/components/form/inputs/MarkdownEditor.vue.d.ts +2 -7
- package/dist/components/form/inputs/NumberInput.vue.d.ts +1 -2
- package/dist/components/form/inputs/OTP.vue.d.ts +1 -2
- package/dist/components/form/inputs/PasswordInput.vue.d.ts +10 -16
- package/dist/components/form/inputs/RadioGroup.vue.d.ts +1 -3
- package/dist/components/form/inputs/RangeInput.vue.d.ts +1 -6
- package/dist/components/form/inputs/RichText/index.vue.d.ts +1 -2
- package/dist/components/form/inputs/RichText/index.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/utils/media.d.ts.map +1 -1
- package/dist/components/form/inputs/SelectBtn.vue.d.ts +2 -2
- package/dist/components/form/inputs/SelectInput.vue.d.ts +13 -20
- package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/SignaturePad.vue.d.ts +1 -6
- package/dist/components/form/inputs/TableField.vue.d.ts +1 -2
- package/dist/components/form/inputs/TelInput.vue.d.ts +1 -2
- package/dist/components/form/inputs/TextInput.vue.d.ts +2 -3
- package/dist/components/form/inputs/ToggleInput.vue.d.ts +1 -2
- package/dist/components/form/inputs/Upload/UploadInput.vue.d.ts +6 -27
- package/dist/components/form/inputs/Upload/upload.d.ts +1 -1
- package/dist/components/form/inputs/index.d.ts +0 -1
- package/dist/components/index.d.ts +1 -3
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/layout/AppContent.vue.d.ts +1 -1
- package/dist/components/layout/AppContent.vue.d.ts.map +1 -1
- package/dist/components/layout/AppLayout.vue.d.ts +0 -2
- package/dist/components/layout/AppLayout.vue.d.ts.map +1 -1
- package/dist/components/layout/AppSidebar.vue.d.ts +1 -5
- package/dist/components/layout/AppSidebar.vue.d.ts.map +1 -1
- package/dist/components/layout/Panel.vue.d.ts.map +1 -1
- package/dist/components/layout/Resizable.vue.d.ts.map +1 -1
- package/dist/components/layout/Skeleton.vue.d.ts.map +1 -1
- package/dist/components/layout/TabsNav.vue.d.ts +1 -12
- package/dist/components/layout/TabsNav.vue.d.ts.map +1 -1
- package/dist/components/layout/appLayoutContext.d.ts +24 -0
- package/dist/components/layout/appLayoutContext.d.ts.map +1 -0
- package/dist/components/layout/index.d.ts.map +1 -1
- package/dist/components/lightbox/Lightbox.vue.d.ts.map +1 -1
- package/dist/composables/index.d.ts.map +1 -1
- package/dist/composables/useDevice.d.ts.map +1 -1
- package/dist/composables/useEscapeKey.d.ts +12 -0
- package/dist/composables/useEscapeKey.d.ts.map +1 -0
- package/dist/composables/useSchemaField.d.ts.map +1 -1
- package/dist/composables/useTheme.d.ts.map +1 -1
- package/dist/dialog/Dialog.vue.d.ts.map +1 -1
- package/dist/dialog/DialogConfirm.vue.d.ts.map +1 -1
- package/dist/form-flow/FormFlow.vue.d.ts.map +1 -1
- package/dist/form-flow/MultiStepForm.vue.d.ts +1 -6
- package/dist/form-flow/form-flow.d.ts +1 -24
- package/dist/form-flow/form-flow.d.ts.map +1 -1
- package/dist/i18n/index.d.ts +0 -838
- package/dist/index.cjs +245 -222
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +42201 -51162
- package/dist/plugins/bagel.d.ts.map +1 -1
- package/dist/style.css +1 -2
- package/dist/types/BagelForm.d.ts +1 -10
- package/dist/types/BagelForm.d.ts.map +1 -1
- package/dist/types/BtnOptions.d.ts.map +1 -1
- package/dist/types/NavLink.d.ts +1 -2
- package/dist/types/TableSchema.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/BagelFormUtils.d.ts +0 -1
- package/dist/utils/calendar/dateUtils.d.ts +2 -2
- package/dist/utils/calendar/dateUtils.d.ts.map +1 -1
- package/dist/utils/constants.d.ts.map +1 -1
- package/dist/utils/date.d.ts +116 -0
- package/dist/utils/date.d.ts.map +1 -0
- package/dist/utils/fetch.d.ts +29 -0
- package/dist/utils/fetch.d.ts.map +1 -0
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/string.d.ts +7 -0
- package/dist/utils/string.d.ts.map +1 -0
- package/dist/utils/useSearch.d.ts +1 -1
- package/package.json +3 -10
- package/src/components/AccordionItem.vue +5 -5
- package/src/components/Alert.vue +37 -16
- package/src/components/Avatar.vue +2 -1
- package/src/components/Badge.vue +145 -22
- package/src/components/BglVideo.vue +4 -4
- package/src/components/Btn.vue +81 -69
- package/src/components/Card.vue +7 -6
- package/src/components/Dropdown.vue +7 -14
- package/src/components/FieldSetVue.vue +2 -2
- package/src/components/FilterQuery.vue +3 -3
- package/src/components/Image.vue +5 -3
- package/src/components/JSONSchema.vue +4 -4
- package/src/components/JsonBuilder.vue +3 -3
- package/src/components/ListItem.vue +2 -4
- package/src/components/MapEmbed/Index.vue +18 -17
- package/src/components/NavBar.vue +2 -2
- package/src/components/Spreadsheet/Index.vue +4 -4
- package/src/components/Spreadsheet/SpreadsheetTable.vue +10 -10
- package/src/components/Swiper.vue +3 -1
- package/src/components/Toast.vue +57 -36
- package/src/components/calendar/CalendarPopover.vue +1 -1
- package/src/components/calendar/Index.vue +5 -5
- package/src/components/calendar/views/AgendaView.vue +2 -2
- package/src/components/calendar/views/DayView.vue +1 -1
- package/src/components/calendar/views/MonthView.vue +8 -8
- package/src/components/dataTable/DataTable.vue +68 -10
- package/src/components/form/index.ts +0 -4
- package/src/components/form/inputs/ArrayInput.vue +1 -1
- package/src/components/form/inputs/CheckInput.vue +6 -6
- package/src/components/form/inputs/Checkbox.vue +5 -4
- package/src/components/form/inputs/CodeEditor/Index.vue +1 -1
- package/src/components/form/inputs/ColorInput.vue +5 -5
- package/src/components/form/inputs/DatePicker.vue +3 -3
- package/src/components/form/inputs/EmailInput.vue +15 -15
- package/src/components/form/inputs/NumberInput.vue +11 -11
- package/src/components/form/inputs/OTP.vue +4 -4
- package/src/components/form/inputs/PasswordInput.vue +3 -3
- package/src/components/form/inputs/RadioGroup.vue +1 -1
- package/src/components/form/inputs/RichText/editor.css +4 -4
- package/src/components/form/inputs/RichText/index.vue +39 -39
- package/src/components/form/inputs/RichText/utils/media.ts +1 -92
- package/src/components/form/inputs/RichText/utils/table.ts +4 -4
- package/src/components/form/inputs/SelectBtn.vue +1 -1
- package/src/components/form/inputs/SelectInput.vue +16 -16
- package/src/components/form/inputs/SignaturePad.vue +6 -6
- package/src/components/form/inputs/TableField.vue +7 -7
- package/src/components/form/inputs/TelInput.vue +12 -12
- package/src/components/form/inputs/TextInput.vue +11 -11
- package/src/components/form/inputs/ToggleInput.vue +11 -11
- package/src/components/form/inputs/Upload/upload.css +16 -16
- package/src/components/index.ts +2 -9
- package/src/components/layout/AppContent.vue +5 -19
- package/src/components/layout/AppLayout.vue +47 -18
- package/src/components/layout/AppSidebar.vue +19 -36
- package/src/components/layout/BottomMenu.vue +1 -1
- package/src/components/layout/Resizable.vue +5 -2
- package/src/components/layout/Skeleton.vue +5 -4
- package/src/components/layout/TabsNav.vue +23 -23
- package/src/components/layout/appLayoutContext.ts +44 -0
- package/src/components/layout/index.ts +2 -0
- package/src/components/lightbox/Lightbox.vue +3 -9
- package/src/composables/index.ts +1 -0
- package/src/composables/useDevice.ts +2 -1
- package/src/composables/useEscapeKey.ts +56 -0
- package/src/composables/useSchemaField.ts +2 -17
- package/src/composables/useTheme.ts +23 -19
- package/src/form-flow/FormFlow.vue +2 -0
- package/src/form-flow/form-flow.ts +7 -0
- package/src/index.ts +0 -3
- package/src/plugins/bagel.ts +0 -15
- package/src/styles/app-layout.css +231 -0
- package/src/styles/appearance.css +179 -21
- package/src/styles/bagel.css +103 -97
- package/src/styles/buttons.css +8 -8
- package/src/styles/colors.css +0 -103
- package/src/styles/dark.css +25 -26
- package/src/styles/input-variants.css +11 -11
- package/src/styles/inputs.css +44 -61
- package/src/styles/layout.css +445 -1258
- package/src/styles/loginCard.css +1 -1
- package/src/styles/mobilLayout.css +153 -28
- package/src/styles/text.css +500 -1508
- package/src/styles/theme.css +199 -435
- package/src/styles/transitions.css +4 -4
- package/src/types/BagelForm.ts +46 -151
- package/src/types/BtnOptions.ts +5 -3
- package/src/types/TableSchema.ts +1 -0
- package/src/types/index.ts +0 -5
- package/src/utils/calendar/dateUtils.ts +2 -3
- package/src/utils/constants.ts +7 -0
- package/src/utils/date.ts +482 -0
- package/src/utils/fetch.ts +128 -0
- package/src/utils/index.ts +54 -3
- package/src/utils/sizeParsing.ts +5 -5
- package/src/utils/string.ts +56 -0
- package/vite.config.ts +5 -1
- package/bin/generateFormSchema.ts +0 -1035
- package/bin/utils.ts +0 -223
- package/src/components/Carousel.vue +0 -724
- package/src/components/ImportData.vue +0 -1749
- package/src/components/Modal.vue +0 -184
- package/src/components/ModalConfirm.vue +0 -42
- package/src/components/ModalForm.vue +0 -102
- package/src/components/Pill.vue +0 -149
- package/src/components/Slider.vue +0 -1446
- package/src/components/Title.vue +0 -23
- package/src/components/ToolBar.vue +0 -9
- package/src/components/form/BagelForm.vue +0 -219
- package/src/components/form/BglFieldSet.vue +0 -14
- package/src/components/form/BglMultiStepForm.vue +0 -469
- package/src/components/form/FieldArray.vue +0 -422
- package/src/components/form/useBagelFormState.ts +0 -76
- package/src/composables/useFormField.ts +0 -38
- package/src/dialog/DialogOLD.vue +0 -358
- package/src/plugins/modalTypes.ts +0 -61
- package/src/plugins/useModal.ts +0 -225
- package/src/styles/modal.css +0 -120
- package/src/styles/pillColors.css +0 -0
- package/src/utils/BagelFormUtils.ts +0 -684
|
@@ -17,7 +17,7 @@ const props = defineProps<{
|
|
|
17
17
|
iconSize?: number | string
|
|
18
18
|
iconMobileSize?: number | string
|
|
19
19
|
thin?: boolean
|
|
20
|
-
size?: 'xs' | '
|
|
20
|
+
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'
|
|
21
21
|
fullWidth?: boolean
|
|
22
22
|
fullWidthMobile?: boolean
|
|
23
23
|
alignTxt?: 'center' | 'start' | 'end'
|
|
@@ -146,10 +146,10 @@ onBeforeUnmount(() => {
|
|
|
146
146
|
{ active: isActive(tab) },
|
|
147
147
|
{
|
|
148
148
|
'bgl_tab-thin': thin,
|
|
149
|
-
'bgl_tab-xs': size === 'xs'
|
|
150
|
-
'bgl_tab-s': size === '
|
|
151
|
-
'bgl_tab-l': size === '
|
|
152
|
-
'bgl_tab-xl': size === 'xl'
|
|
149
|
+
'bgl_tab-xs': size === 'xs',
|
|
150
|
+
'bgl_tab-s': size === 'sm',
|
|
151
|
+
'bgl_tab-l': size === 'lg',
|
|
152
|
+
'bgl_tab-xl': size === 'xl',
|
|
153
153
|
'w-100p justify-center': fullWidth,
|
|
154
154
|
'w-auto m_w-100p': fullWidthMobile,
|
|
155
155
|
'bgl_tab-align-center': alignTxt === 'center',
|
|
@@ -171,17 +171,17 @@ onBeforeUnmount(() => {
|
|
|
171
171
|
|
|
172
172
|
<style>
|
|
173
173
|
:root {
|
|
174
|
-
--bgl_tabs-background: var(--input-bg);
|
|
175
|
-
--bgl_tabs-border-radius: var(--input-border-radius);
|
|
176
|
-
--bgl_tabs-inline-padding: calc(var(--btn-padding) / 8);
|
|
177
|
-
--bgl_tabs-block-padding: calc(var(--btn-padding) / 8);
|
|
174
|
+
--bgl_tabs-background: var(--bgl-input-bg);
|
|
175
|
+
--bgl_tabs-border-radius: var(--bgl-input-border-radius);
|
|
176
|
+
--bgl_tabs-inline-padding: calc(var(--bgl-btn-padding) / 8);
|
|
177
|
+
--bgl_tabs-block-padding: calc(var(--bgl-btn-padding) / 8);
|
|
178
178
|
--bgl_tabs-shadow: inset 0 0 10px #00000012;
|
|
179
179
|
--bgl_tabs-gap: 0.25rem;
|
|
180
|
-
--bgl_tabs-font-size: var(--input-font-size);
|
|
181
|
-
--bgl_tab-inline-padding: calc(var(--btn-padding) / 2);
|
|
182
|
-
--bgl_tab-block-padding: calc(var(--btn-padding) / 8);
|
|
180
|
+
--bgl_tabs-font-size: var(--bgl-input-font-size);
|
|
181
|
+
--bgl_tab-inline-padding: calc(var(--bgl-btn-padding) / 2);
|
|
182
|
+
--bgl_tab-block-padding: calc(var(--bgl-btn-padding) / 8);
|
|
183
183
|
--bgl_tab-gap: 0.5rem;
|
|
184
|
-
--bgl_tabs-border-radius: var(--input-border-radius);
|
|
184
|
+
--bgl_tabs-border-radius: var(--bgl-input-border-radius);
|
|
185
185
|
--bgl-tab-hover-bg: rgba(255, 255, 255, .4);
|
|
186
186
|
--bgl_tabs-indicator-color: var(--bgl-popup-bg);
|
|
187
187
|
--bgl-tabs-flat-indicator-color: var(--bgl-primary);
|
|
@@ -204,7 +204,7 @@ onBeforeUnmount(() => {
|
|
|
204
204
|
cursor: pointer;
|
|
205
205
|
font-size: inherit;
|
|
206
206
|
font-family: inherit;
|
|
207
|
-
height: calc(var(--btn-height) - var(--bgl_tabs-block-padding) * 2);
|
|
207
|
+
height: calc(var(--bgl-btn-height) - var(--bgl_tabs-block-padding) * 2);
|
|
208
208
|
padding-inline: var(--bgl_tab-inline-padding);
|
|
209
209
|
padding-block: 0;
|
|
210
210
|
border-radius: var(--bgl_tab-border-radius);
|
|
@@ -242,7 +242,7 @@ onBeforeUnmount(() => {
|
|
|
242
242
|
background: transparent;
|
|
243
243
|
border-bottom: 1px solid var(--bgl-tabs-flat-indicator-color);
|
|
244
244
|
border-radius: 0;
|
|
245
|
-
top: calc(var(--btn-padding) * 1.25);
|
|
245
|
+
top: calc(var(--bgl-btn-padding) * 1.25);
|
|
246
246
|
bottom: unset;
|
|
247
247
|
|
|
248
248
|
}
|
|
@@ -255,30 +255,30 @@ onBeforeUnmount(() => {
|
|
|
255
255
|
}
|
|
256
256
|
.bgl_tab-thin {
|
|
257
257
|
padding-inline: calc(var(--bgl_tab-inline-padding) / 2);
|
|
258
|
-
height: calc(var(--btn-height) * 0.7 - var(--bgl_tabs-block-padding) * 2);
|
|
258
|
+
height: calc(var(--bgl-btn-height) * 0.7 - var(--bgl_tabs-block-padding) * 2);
|
|
259
259
|
}
|
|
260
260
|
|
|
261
261
|
.bgl_tab-xs {
|
|
262
262
|
padding-inline: calc(var(--bgl_tab-inline-padding) / 3);
|
|
263
|
-
font-size: calc(var(--input-font-size) * 0.6);
|
|
264
|
-
height: calc(var(--btn-height) * 0.5 - var(--bgl_tabs-block-padding) * 2);
|
|
263
|
+
font-size: calc(var(--bgl-input-font-size) * 0.6);
|
|
264
|
+
height: calc(var(--bgl-btn-height) * 0.5 - var(--bgl_tabs-block-padding) * 2);
|
|
265
265
|
}
|
|
266
266
|
|
|
267
267
|
.bgl_tab-s {
|
|
268
268
|
padding-inline: calc(var(--bgl_tab-inline-padding) / 1.5);
|
|
269
|
-
height: calc(var(--btn-height) * 0.7 - var(--bgl_tabs-block-padding) * 2);
|
|
269
|
+
height: calc(var(--bgl-btn-height) * 0.7 - var(--bgl_tabs-block-padding) * 2);
|
|
270
270
|
}
|
|
271
271
|
|
|
272
272
|
.bgl_tab-l {
|
|
273
273
|
padding-inline: calc(var(--bgl_tab-inline-padding) * 1.3);
|
|
274
|
-
font-size: calc(var(--input-font-size) * 1.1);
|
|
275
|
-
height: calc(var(--btn-height) * 1.2 - var(--bgl_tabs-block-padding) * 2);
|
|
274
|
+
font-size: calc(var(--bgl-input-font-size) * 1.1);
|
|
275
|
+
height: calc(var(--bgl-btn-height) * 1.2 - var(--bgl_tabs-block-padding) * 2);
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
.bgl_tab-xl {
|
|
279
279
|
padding-inline: calc(var(--bgl_tab-inline-padding) * 1.6);
|
|
280
|
-
font-size: calc(var(--input-font-size) * 1.3);
|
|
281
|
-
height: calc(var(--btn-height) * 1.5 - var(--bgl_tabs-block-padding) * 2);
|
|
280
|
+
font-size: calc(var(--bgl-input-font-size) * 1.3);
|
|
281
|
+
height: calc(var(--bgl-btn-height) * 1.5 - var(--bgl_tabs-block-padding) * 2);
|
|
282
282
|
}
|
|
283
283
|
|
|
284
284
|
.bgl_tab-align-start {
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { InjectionKey, Ref } from 'vue'
|
|
2
|
+
import { inject, ref } from 'vue'
|
|
3
|
+
|
|
4
|
+
export const SIDEBAR_COLLAPSED_WIDTH = '66px'
|
|
5
|
+
export const SIDEBAR_COLLAPSED_WIDTH_CARD = '82px'
|
|
6
|
+
|
|
7
|
+
export interface AppLayoutContext {
|
|
8
|
+
/** Sidebar open (expanded) state */
|
|
9
|
+
isOpen: Ref<boolean>
|
|
10
|
+
/** Viewport is below MOBILE_BREAKPOINT */
|
|
11
|
+
isMobile: Ref<boolean>
|
|
12
|
+
toggleMenu: () => void
|
|
13
|
+
/** Close the sidebar when on mobile (e.g. after navigating) */
|
|
14
|
+
closeOnMobile: () => void
|
|
15
|
+
sidebarWidth: string
|
|
16
|
+
sidebarCollapsedWidth: string
|
|
17
|
+
/** Sidebar rendered as a floating card */
|
|
18
|
+
sidebarCardStyle: boolean
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const AppLayoutKey: InjectionKey<AppLayoutContext> = Symbol('AppLayout')
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Access the AppLayout context (sidebar open state, mobile flag, toggle).
|
|
25
|
+
* Works inside AppLayout's slots — including custom header buttons.
|
|
26
|
+
* Outside an AppLayout it warns (dev) and returns an inert fallback.
|
|
27
|
+
*/
|
|
28
|
+
export function useAppLayout(): AppLayoutContext {
|
|
29
|
+
const ctx = inject(AppLayoutKey, null)
|
|
30
|
+
if (ctx) { return ctx }
|
|
31
|
+
|
|
32
|
+
if (import.meta.env?.DEV) {
|
|
33
|
+
console.warn('[bagelink] useAppLayout() called outside <AppLayout>. AppSidebar/AppContent are designed to be used inside it.')
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
isOpen: ref(true),
|
|
37
|
+
isMobile: ref(false),
|
|
38
|
+
toggleMenu: () => {},
|
|
39
|
+
closeOnMobile: () => {},
|
|
40
|
+
sidebarWidth: '260px',
|
|
41
|
+
sidebarCollapsedWidth: SIDEBAR_COLLAPSED_WIDTH,
|
|
42
|
+
sidebarCardStyle: false,
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { default as AppContent } from './AppContent.vue'
|
|
2
2
|
export { default as AppLayout } from './AppLayout.vue'
|
|
3
3
|
export { default as AppSidebar } from './AppSidebar.vue'
|
|
4
|
+
export { useAppLayout } from './appLayoutContext'
|
|
5
|
+
export type { AppLayoutContext } from './appLayoutContext'
|
|
4
6
|
export { default as BottomMenu } from './BottomMenu.vue'
|
|
5
7
|
export { default as Layout } from './Layout.vue'
|
|
6
8
|
export { default as Panel } from './Panel.vue'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { LightboxItem } from './lightbox.types'
|
|
3
3
|
|
|
4
|
-
import { BglVideo, Btn, Icon, Zoomer, Image, normalizeURL, Swiper, downloadFile } from '@bagelink/vue'
|
|
4
|
+
import { BglVideo, Btn, Icon, Zoomer, Image, normalizeURL, Swiper, downloadFile, useEscapeKey } from '@bagelink/vue'
|
|
5
5
|
import { computed, ref, watch } from 'vue'
|
|
6
6
|
|
|
7
7
|
const isOpen = ref(false)
|
|
@@ -31,14 +31,14 @@ function open(item: LightboxItem, groupItems?: LightboxItem[]) {
|
|
|
31
31
|
})
|
|
32
32
|
if (currentIndex.value === -1) currentIndex.value = 0
|
|
33
33
|
zoom.value = 1
|
|
34
|
-
document.addEventListener('keydown', handleKeydown)
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
function close() {
|
|
38
37
|
isOpen.value = false
|
|
39
|
-
document.removeEventListener('keydown', handleKeydown)
|
|
40
38
|
}
|
|
41
39
|
|
|
40
|
+
useEscapeKey(close, isOpen)
|
|
41
|
+
|
|
42
42
|
function selectItem(index: number) {
|
|
43
43
|
currentIndex.value = index
|
|
44
44
|
zoom.value = 1
|
|
@@ -58,12 +58,6 @@ watch(() => currentIndex.value, () => {
|
|
|
58
58
|
zoom.value = 1
|
|
59
59
|
})
|
|
60
60
|
|
|
61
|
-
function handleKeydown(event: KeyboardEvent) {
|
|
62
|
-
if (event.key === 'Escape') {
|
|
63
|
-
close()
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
61
|
defineExpose({ open, close })
|
|
68
62
|
</script>
|
|
69
63
|
|
package/src/composables/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { computed, toValue } from 'vue'
|
|
|
6
6
|
|
|
7
7
|
export { useAddToCalendar } from './useAddToCalendar'
|
|
8
8
|
export { useDevice } from './useDevice'
|
|
9
|
+
export { useEscapeKey } from './useEscapeKey'
|
|
9
10
|
export { useExcel } from './useExcel'
|
|
10
11
|
export { useLocalStore } from './useLocalStore'
|
|
11
12
|
export { usePolling } from './usePolling'
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { onMounted, onUnmounted, ref } from 'vue'
|
|
2
|
+
import { MOBILE_BREAKPOINT } from '../utils/constants'
|
|
2
3
|
|
|
3
4
|
export function useDevice() {
|
|
4
5
|
const innerWidth = ref(0)
|
|
@@ -20,7 +21,7 @@ export function useDevice() {
|
|
|
20
21
|
|
|
21
22
|
// Update current values
|
|
22
23
|
innerWidth.value = window.innerWidth
|
|
23
|
-
isMobile.value = window.innerWidth
|
|
24
|
+
isMobile.value = window.innerWidth <= MOBILE_BREAKPOINT
|
|
24
25
|
scrollY.value = window.scrollY
|
|
25
26
|
scrollX.value = window.scrollX
|
|
26
27
|
innerHeight.value = window.innerHeight
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { MaybeRefOrGetter } from 'vue'
|
|
2
|
+
import { onBeforeUnmount, onMounted, toValue } from 'vue'
|
|
3
|
+
|
|
4
|
+
interface EscapeEntry {
|
|
5
|
+
handler: (e: KeyboardEvent) => void
|
|
6
|
+
enabled: () => boolean
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const stack: EscapeEntry[] = []
|
|
10
|
+
let listening = false
|
|
11
|
+
|
|
12
|
+
function onDocumentKeydown(e: KeyboardEvent) {
|
|
13
|
+
if (e.key !== 'Escape') { return }
|
|
14
|
+
// LIFO: the most recently mounted (topmost) active layer handles Escape
|
|
15
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
16
|
+
if (stack[i].enabled()) {
|
|
17
|
+
stack[i].handler(e)
|
|
18
|
+
return
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function syncListener() {
|
|
24
|
+
if (typeof document === 'undefined') { return }
|
|
25
|
+
if (stack.length > 0 && !listening) {
|
|
26
|
+
document.addEventListener('keydown', onDocumentKeydown)
|
|
27
|
+
listening = true
|
|
28
|
+
} else if (stack.length === 0 && listening) {
|
|
29
|
+
document.removeEventListener('keydown', onDocumentKeydown)
|
|
30
|
+
listening = false
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Run a handler when Escape is pressed, while `enabled` is truthy.
|
|
36
|
+
* - One shared document listener for the whole app
|
|
37
|
+
* - LIFO: the most recently mounted active layer wins (dropdown inside a lightbox closes first)
|
|
38
|
+
* - Automatically cleaned up on unmount
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* useEscapeKey(() => close(), () => isOpen.value)
|
|
42
|
+
*/
|
|
43
|
+
export function useEscapeKey(handler: (e: KeyboardEvent) => void, enabled: MaybeRefOrGetter<boolean> = true) {
|
|
44
|
+
const entry: EscapeEntry = { handler, enabled: () => !!toValue(enabled) }
|
|
45
|
+
|
|
46
|
+
onMounted(() => {
|
|
47
|
+
stack.push(entry)
|
|
48
|
+
syncListener()
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
onBeforeUnmount(() => {
|
|
52
|
+
const i = stack.indexOf(entry)
|
|
53
|
+
if (i !== -1) { stack.splice(i, 1) }
|
|
54
|
+
syncListener()
|
|
55
|
+
})
|
|
56
|
+
}
|
|
@@ -4,7 +4,6 @@ import type { Field, Attributes, Path, SchemaChild, BaseBagelField, VNodeFn } fr
|
|
|
4
4
|
import {
|
|
5
5
|
TextInput,
|
|
6
6
|
NumberInput,
|
|
7
|
-
FieldArray,
|
|
8
7
|
SelectInput,
|
|
9
8
|
ToggleInput,
|
|
10
9
|
CheckInput,
|
|
@@ -12,7 +11,6 @@ import {
|
|
|
12
11
|
UploadInput,
|
|
13
12
|
DateInput,
|
|
14
13
|
TabsNav,
|
|
15
|
-
BglForm,
|
|
16
14
|
bindAttrs,
|
|
17
15
|
classify,
|
|
18
16
|
keyToLabel,
|
|
@@ -74,7 +72,7 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
|
|
|
74
72
|
text: TextInput,
|
|
75
73
|
textarea: TextInput,
|
|
76
74
|
number: NumberInput,
|
|
77
|
-
array:
|
|
75
|
+
array: 'div',
|
|
78
76
|
color: ColorInput,
|
|
79
77
|
tel: TelInput,
|
|
80
78
|
select: SelectInput,
|
|
@@ -85,7 +83,7 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
|
|
|
85
83
|
file: UploadInput,
|
|
86
84
|
date: DateInput,
|
|
87
85
|
tabs: TabsNav,
|
|
88
|
-
form:
|
|
86
|
+
form: 'div',
|
|
89
87
|
range: RangeInput,
|
|
90
88
|
email: EmailInput
|
|
91
89
|
}
|
|
@@ -195,19 +193,6 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
|
|
|
195
193
|
defaultValue,
|
|
196
194
|
}
|
|
197
195
|
|
|
198
|
-
// Special handling for FieldArray component to pass attrs.schema as schema prop
|
|
199
|
-
if (Component === FieldArray && field.attrs?.schema) {
|
|
200
|
-
props.schema = field.attrs.schema
|
|
201
|
-
}
|
|
202
|
-
// Special handling for FieldArray component to pass attrs.type as type prop
|
|
203
|
-
if (Component === FieldArray && field.attrs?.type) {
|
|
204
|
-
props.type = field.attrs.type
|
|
205
|
-
}
|
|
206
|
-
// Special handling for FieldArray component to pass collapsed prop
|
|
207
|
-
if (Component === FieldArray && 'collapsed' in field) {
|
|
208
|
-
props.collapsed = (field as any).collapsed
|
|
209
|
-
}
|
|
210
|
-
|
|
211
196
|
// Wire top-level onClick with conditional args
|
|
212
197
|
if (typeof (field as any).onClick === 'function') {
|
|
213
198
|
const original = (field as any).onClick as (val?: any, row?: T) => void
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// composables/useTheme.ts
|
|
2
|
-
import { ref, computed,
|
|
2
|
+
import { ref, computed, watch } from 'vue'
|
|
3
3
|
|
|
4
4
|
export interface ThemeOption {
|
|
5
5
|
value: string
|
|
@@ -118,33 +118,37 @@ function addTheme(theme: ThemeOption) {
|
|
|
118
118
|
* setTheme('ocean')
|
|
119
119
|
*/
|
|
120
120
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const validTheme = themeOptions.value.find(t => t.value === saved)
|
|
121
|
+
// Module-level one-time init: a single matchMedia listener and a single
|
|
122
|
+
// colorMode watcher, no matter how many components call useTheme().
|
|
123
|
+
let initialized = false
|
|
125
124
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
function initTheme() {
|
|
126
|
+
if (initialized || !isBrowser) { return }
|
|
127
|
+
initialized = true
|
|
128
|
+
|
|
129
|
+
const saved = window.localStorage.getItem(STORAGE_KEY)
|
|
130
|
+
if (themeOptions.value.some(t => t.value === saved)) {
|
|
131
|
+
colorMode.value = saved!
|
|
132
|
+
}
|
|
129
133
|
|
|
130
|
-
|
|
131
|
-
applyTheme(colorMode.value)
|
|
134
|
+
applyTheme(colorMode.value)
|
|
132
135
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
applyTheme('system')
|
|
138
|
-
}
|
|
136
|
+
// React to system changes when in "system" mode
|
|
137
|
+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
|
|
138
|
+
if (colorMode.value === 'system') {
|
|
139
|
+
applyTheme('system')
|
|
139
140
|
}
|
|
140
|
-
mq.addEventListener('change', handler)
|
|
141
141
|
})
|
|
142
142
|
|
|
143
|
-
//
|
|
143
|
+
// Persist + apply on mode changes
|
|
144
144
|
watch(colorMode, (newMode) => {
|
|
145
|
-
|
|
145
|
+
localStorage.setItem(STORAGE_KEY, newMode)
|
|
146
146
|
applyTheme(newMode)
|
|
147
147
|
})
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function useTheme() {
|
|
151
|
+
initTheme()
|
|
148
152
|
|
|
149
153
|
const theme = computed(() => colorMode.value)
|
|
150
154
|
|
|
@@ -10,6 +10,7 @@ import EmailInput from '../components/form/inputs/EmailInput.vue'
|
|
|
10
10
|
import NumberInput from '../components/form/inputs/NumberInput.vue'
|
|
11
11
|
import PasswordInput from '../components/form/inputs/PasswordInput.vue'
|
|
12
12
|
import RadioGroup from '../components/form/inputs/RadioGroup.vue'
|
|
13
|
+
import RangeInput from '../components/form/inputs/RangeInput.vue'
|
|
13
14
|
import RichText from '../components/form/inputs/RichText/index.vue'
|
|
14
15
|
import SelectBtn from '../components/form/inputs/SelectBtn.vue'
|
|
15
16
|
import SelectInput from '../components/form/inputs/SelectInput.vue'
|
|
@@ -223,6 +224,7 @@ function getFieldComponent(fieldOrType: FieldBuilder | string) {
|
|
|
223
224
|
array: ArrayInput,
|
|
224
225
|
upload: UploadInput,
|
|
225
226
|
color: ColorInput,
|
|
227
|
+
range: RangeInput,
|
|
226
228
|
}
|
|
227
229
|
|
|
228
230
|
return (componentMap[type] as typeof TextInput | undefined) ?? TextInput
|
|
@@ -358,6 +358,13 @@ export const $ = {
|
|
|
358
358
|
return new Field('color', parseArgs(labelOrConfig, config))
|
|
359
359
|
},
|
|
360
360
|
|
|
361
|
+
range(
|
|
362
|
+
labelOrConfig?: string | (BaseFieldConfig & { min?: number, max?: number, step?: number, multiRange?: boolean }),
|
|
363
|
+
config?: BaseFieldConfig & { min?: number, max?: number, step?: number, multiRange?: boolean }
|
|
364
|
+
): FieldBuilder<number | [number, number]> {
|
|
365
|
+
return new Field('range', parseArgs(labelOrConfig, config))
|
|
366
|
+
},
|
|
367
|
+
|
|
361
368
|
upload(
|
|
362
369
|
labelOrConfig?: string | (BaseFieldConfig & {
|
|
363
370
|
multiple?: boolean
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import './styles/bagel.css'
|
|
2
2
|
|
|
3
3
|
export * from './components'
|
|
4
|
-
export * from './components/form/useBagelFormState'
|
|
5
4
|
export * from './composables'
|
|
6
5
|
// Dialog (native <dialog> based)
|
|
7
6
|
export * from './dialog'
|
|
@@ -23,14 +22,12 @@ export {
|
|
|
23
22
|
useI18n,
|
|
24
23
|
} from './i18n'
|
|
25
24
|
export { type BagelOptions, BagelVue, getI18n } from './plugins/bagel'
|
|
26
|
-
export { ModalPlugin, useModal } from './plugins/useModal'
|
|
27
25
|
|
|
28
26
|
export { type BagelToastOptions, type ToastApi, ToastPlugin, useToast } from './plugins/useToast'
|
|
29
27
|
|
|
30
28
|
export * from './types'
|
|
31
29
|
export * from './utils'
|
|
32
30
|
export * from './utils/allCountries'
|
|
33
|
-
export * from './utils/BagelFormUtils'
|
|
34
31
|
export * from './utils/calendar/dateUtils'
|
|
35
32
|
|
|
36
33
|
export * from './utils/constants'
|
package/src/plugins/bagel.ts
CHANGED
|
@@ -2,14 +2,12 @@ import type { Plugin } from 'vue'
|
|
|
2
2
|
import type { CreateBagelI18nOptions } from '../i18n'
|
|
3
3
|
|
|
4
4
|
import type { BagelToastOptions } from './useToast'
|
|
5
|
-
import { configure } from '@bagelink/utils'
|
|
6
5
|
import FloatingVue from 'floating-vue'
|
|
7
6
|
import lightboxPlugin from '../components/lightbox/index'
|
|
8
7
|
import { DialogPlugin } from '../dialog/useDialog'
|
|
9
8
|
import { ripple, pattern } from '../directives'
|
|
10
9
|
import { createI18n, getI18n } from '../i18n'
|
|
11
10
|
import clickOutside from '../utils/clickOutside'
|
|
12
|
-
import { ModalPlugin } from './useModal'
|
|
13
11
|
import { ToastPlugin } from './useToast'
|
|
14
12
|
import '@oddbird/popover-polyfill'
|
|
15
13
|
|
|
@@ -29,7 +27,6 @@ export const BagelVue: Plugin<BagelOptions> = {
|
|
|
29
27
|
// Install UI plugins
|
|
30
28
|
app.use(lightboxPlugin)
|
|
31
29
|
app.use(DialogPlugin)
|
|
32
|
-
app.use(ModalPlugin)
|
|
33
30
|
app.use(ToastPlugin, options.toast || {})
|
|
34
31
|
|
|
35
32
|
// Install FloatingVue for tooltips/popovers
|
|
@@ -46,18 +43,6 @@ export const BagelVue: Plugin<BagelOptions> = {
|
|
|
46
43
|
// Setup i18n
|
|
47
44
|
const i18n = createI18n(options.i18n || {})
|
|
48
45
|
app.use(i18n as any)
|
|
49
|
-
|
|
50
|
-
// Bridge locale into @bagelink/utils
|
|
51
|
-
configure({
|
|
52
|
-
locale: () => {
|
|
53
|
-
try {
|
|
54
|
-
const { locale } = getI18n().global
|
|
55
|
-
return typeof locale === 'string' ? locale : locale.value
|
|
56
|
-
} catch {
|
|
57
|
-
return 'en'
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
})
|
|
61
46
|
},
|
|
62
47
|
}
|
|
63
48
|
|