@bagelink/vue 1.6.47 → 1.6.51
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/bin/experimentalGenTypedRoutes.ts +18 -19
- package/bin/utils.ts +4 -4
- package/dist/components/AddressSearch.vue.d.ts.map +1 -1
- package/dist/components/Alert.vue.d.ts.map +1 -1
- package/dist/components/BglVideo.vue.d.ts.map +1 -1
- package/dist/components/Card.vue.d.ts.map +1 -1
- package/dist/components/Carousel.vue.d.ts +2 -2
- package/dist/components/Carousel.vue.d.ts.map +1 -1
- package/dist/components/Dropdown.vue.d.ts.map +1 -1
- package/dist/components/Flag.vue.d.ts.map +1 -1
- package/dist/components/IframeVue.vue.d.ts.map +1 -1
- package/dist/components/ListItem.vue.d.ts.map +1 -1
- package/dist/components/Loading.vue.d.ts.map +1 -1
- package/dist/components/Modal.vue.d.ts.map +1 -1
- package/dist/components/ModalForm.vue.d.ts.map +1 -1
- package/dist/components/NavBar.vue.d.ts +1 -1
- package/dist/components/Pill.vue.d.ts.map +1 -1
- package/dist/components/Zoomer.vue.d.ts +0 -1
- package/dist/components/Zoomer.vue.d.ts.map +1 -1
- package/dist/components/analytics/LineChart.vue.d.ts.map +1 -1
- package/dist/components/analytics/PieChart.vue.d.ts +2 -1
- package/dist/components/analytics/PieChart.vue.d.ts.map +1 -1
- package/dist/components/analytics/index.d.ts +1 -1
- package/dist/components/analytics/index.d.ts.map +1 -1
- package/dist/components/calendar/CalendarPopover.vue.d.ts.map +1 -1
- package/dist/components/form/BglMultiStepForm.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/ColorInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/DateInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/PasswordInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RadioGroup.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RangeInput.vue.d.ts +11 -11
- package/dist/components/form/inputs/RichText/components/EditorToolbar.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/components/TableGridSelector.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/utils/commands.d.ts.map +1 -1
- package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/TelInput.vue.d.ts.map +1 -1
- package/dist/components/layout/AppSidebar.vue.d.ts +1 -0
- package/dist/components/layout/AppSidebar.vue.d.ts.map +1 -1
- package/dist/components/layout/Layout.vue.d.ts.map +1 -1
- package/dist/components/layout/Tabs.vue.d.ts.map +1 -1
- package/dist/components/layout/index.d.ts +3 -3
- package/dist/components/layout/index.d.ts.map +1 -1
- package/dist/index.cjs +34 -25
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +6668 -5883
- package/dist/plugins/useToast.d.ts.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +5 -10
- package/src/components/AccordionItem.vue +11 -11
- package/src/components/AddToCalendar.vue +1 -1
- package/src/components/AddressSearch.vue +9 -8
- package/src/components/Alert.vue +2 -1
- package/src/components/Badge.vue +5 -5
- package/src/components/BglVideo.vue +44 -45
- package/src/components/Btn.vue +15 -15
- package/src/components/Card.vue +10 -8
- package/src/components/Carousel.vue +159 -162
- package/src/components/DataPreview.vue +1 -1
- package/src/components/DragOver.vue +6 -6
- package/src/components/Dropdown.vue +39 -38
- package/src/components/Flag.vue +7 -6
- package/src/components/Icon/Icon.vue +22 -22
- package/src/components/IframeVue.vue +5 -5
- package/src/components/Image.vue +17 -17
- package/src/components/ImportData.vue +79 -79
- package/src/components/ListItem.vue +20 -13
- package/src/components/Loading.vue +10 -9
- package/src/components/MapEmbed/Index.vue +24 -24
- package/src/components/Modal.vue +11 -9
- package/src/components/ModalForm.vue +9 -8
- package/src/components/NavBar.vue +6 -6
- package/src/components/Pagination.vue +27 -27
- package/src/components/Pill.vue +11 -12
- package/src/components/Rating.vue +2 -2
- package/src/components/Slider.vue +75 -75
- package/src/components/Spreadsheet/Index.vue +34 -34
- package/src/components/Spreadsheet/SpreadsheetTable.vue +3 -3
- package/src/components/Zoomer.vue +165 -170
- package/src/components/analytics/BarChart.vue +6 -6
- package/src/components/analytics/KpiCard.vue +2 -2
- package/src/components/analytics/LineChart.vue +63 -61
- package/src/components/analytics/PieChart.vue +104 -90
- package/src/components/analytics/index.ts +2 -2
- package/src/components/calendar/CalendarPopover.vue +1 -1
- package/src/components/calendar/Index.vue +1 -1
- package/src/components/calendar/views/AgendaView.vue +3 -3
- package/src/components/calendar/views/DayView.vue +6 -6
- package/src/components/calendar/views/MonthView.vue +2 -2
- package/src/components/calendar/views/WeekView.vue +18 -18
- package/src/components/dataTable/DataTable.vue +4 -4
- package/src/components/dataTable/useSorting.ts +1 -1
- package/src/components/dataTable/useTableData.ts +15 -15
- package/src/components/dataTable/useTableSelection.ts +15 -15
- package/src/components/dataTable/useTableVirtualization.ts +1 -1
- package/src/components/draggable/useDraggable.ts +42 -42
- package/src/components/form/BagelForm.vue +15 -15
- package/src/components/form/BglFieldSet.vue +5 -3
- package/src/components/form/BglMultiStepForm.vue +20 -21
- package/src/components/form/inputs/CheckInput.vue +2 -2
- package/src/components/form/inputs/CodeEditor/format.ts +7 -7
- package/src/components/form/inputs/CodeEditor/useHighlight.ts +6 -6
- package/src/components/form/inputs/ColorInput.vue +5 -4
- package/src/components/form/inputs/DateInput.vue +8 -9
- package/src/components/form/inputs/DatePicker.vue +24 -24
- package/src/components/form/inputs/EmailInput.vue +24 -24
- package/src/components/form/inputs/NumberInput.vue +26 -26
- package/src/components/form/inputs/OTP.vue +7 -7
- package/src/components/form/inputs/PasswordInput.vue +3 -2
- package/src/components/form/inputs/RadioGroup.vue +28 -25
- package/src/components/form/inputs/RadioPillsInput.vue +12 -12
- package/src/components/form/inputs/RangeInput.vue +21 -21
- package/src/components/form/inputs/RichText/components/EditorToolbar.vue +107 -92
- package/src/components/form/inputs/RichText/components/TableGridSelector.vue +64 -64
- package/src/components/form/inputs/RichText/components/gridBox.vue +10 -8
- package/src/components/form/inputs/RichText/composables/useCommands.ts +1 -1
- package/src/components/form/inputs/RichText/composables/useEditor.ts +12 -12
- package/src/components/form/inputs/RichText/composables/useEditorKeyboard.ts +1 -1
- package/src/components/form/inputs/RichText/index.vue +138 -138
- package/src/components/form/inputs/RichText/utils/commands.ts +84 -85
- package/src/components/form/inputs/RichText/utils/debug.ts +1 -1
- package/src/components/form/inputs/RichText/utils/formatting.ts +39 -39
- package/src/components/form/inputs/RichText/utils/selection.ts +28 -28
- package/src/components/form/inputs/RichText/utils/table.ts +19 -19
- package/src/components/form/inputs/SelectBtn.vue +1 -1
- package/src/components/form/inputs/SelectInput.vue +54 -54
- package/src/components/form/inputs/SignaturePad.vue +40 -40
- package/src/components/form/inputs/TableField.vue +1 -1
- package/src/components/form/inputs/TelInput.vue +54 -53
- package/src/components/form/inputs/TextInput.vue +19 -19
- package/src/components/form/inputs/ToggleInput.vue +2 -2
- package/src/components/form/inputs/Upload/useFileUpload.ts +6 -6
- package/src/components/form/useBagelFormState.ts +5 -5
- package/src/components/layout/AppLayout.vue +2 -2
- package/src/components/layout/AppSidebar.vue +77 -16
- package/src/components/layout/Layout.vue +12 -10
- package/src/components/layout/SidebarMenu.vue +4 -4
- package/src/components/layout/TabbedLayout.vue +17 -17
- package/src/components/layout/Tabs.vue +4 -5
- package/src/components/layout/TabsNav.vue +14 -14
- package/src/components/layout/index.ts +3 -5
- package/src/components/lightbox/Lightbox.vue +22 -22
- package/src/components/lightbox/index.ts +8 -8
- package/src/composables/index.ts +8 -8
- package/src/composables/useAddToCalendar.ts +13 -13
- package/src/composables/useDevice.ts +2 -2
- package/src/composables/useFormField.ts +4 -4
- package/src/composables/usePolling.ts +8 -8
- package/src/composables/useSchemaField.ts +38 -38
- package/src/composables/useTheme.ts +9 -9
- package/src/composables/useValidateFieldValue.ts +2 -2
- package/src/directives/pattern.ts +25 -25
- package/src/directives/ripple.ts +4 -4
- package/src/directives/vResize.ts +6 -6
- package/src/index.ts +1 -0
- package/src/plugins/bagel.ts +4 -4
- package/src/plugins/useToast.ts +56 -51
- package/src/styles/layout.css +1 -1
- package/src/types/index.ts +1 -1
- package/src/utils/BagelFormUtils.ts +7 -7
- package/src/utils/calendar/Helpers.ts +8 -8
- package/src/utils/calendar/dateUtils.ts +22 -22
- package/src/utils/calendar/time.ts +25 -25
- package/src/utils/calendar/week.ts +25 -25
- package/src/utils/elementUtils.ts +27 -27
- package/src/utils/sizeParsing.ts +2 -2
- package/src/utils/strings.ts +5 -5
- package/src/utils/tapDetector.ts +11 -11
- package/src/utils/useSearch.ts +29 -29
- package/vite.config.ts +0 -2
|
@@ -2,50 +2,50 @@
|
|
|
2
2
|
import type { LightboxItem } from './lightbox.types'
|
|
3
3
|
|
|
4
4
|
import { BglVideo, Btn, Icon, Zoomer, Image, normalizeURL, Swiper, downloadFile } from '@bagelink/vue'
|
|
5
|
-
import {
|
|
5
|
+
import { computed, ref, watch } from 'vue'
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const currentItem =
|
|
11
|
-
|
|
7
|
+
const isOpen = ref(false)
|
|
8
|
+
const group = ref<LightboxItem[]>([])
|
|
9
|
+
const currentIndex = ref(0)
|
|
10
|
+
const currentItem = computed<LightboxItem>(() => group.value[currentIndex.value])
|
|
11
|
+
const zoom = ref(1)
|
|
12
12
|
|
|
13
|
-
const canSwipe =
|
|
13
|
+
const canSwipe = computed(() => zoom.value === 1)
|
|
14
14
|
|
|
15
15
|
// Advanced options that update reactively
|
|
16
|
-
const swiperAdvancedOptions =
|
|
17
|
-
allowTouchMove: zoom === 1,
|
|
18
|
-
touchRatio: zoom === 1 ? 1 : 0,
|
|
19
|
-
simulateTouch: zoom === 1,
|
|
16
|
+
const swiperAdvancedOptions = computed(() => ({
|
|
17
|
+
allowTouchMove: zoom.value === 1,
|
|
18
|
+
touchRatio: zoom.value === 1 ? 1 : 0,
|
|
19
|
+
simulateTouch: zoom.value === 1,
|
|
20
20
|
}))
|
|
21
21
|
|
|
22
22
|
function open(item: LightboxItem, groupItems?: LightboxItem[]) {
|
|
23
|
-
isOpen = true
|
|
24
|
-
group = groupItems || [item]
|
|
25
|
-
currentIndex = group.findIndex((groupItem) => {
|
|
23
|
+
isOpen.value = true
|
|
24
|
+
group.value = groupItems || [item]
|
|
25
|
+
currentIndex.value = group.value.findIndex((groupItem) => {
|
|
26
26
|
const hasSrcMatch = item.src !== undefined && item.src !== null && item.src !== ''
|
|
27
27
|
&& groupItem.src === item.src
|
|
28
28
|
const hasPathMatch = item.pathKey !== undefined && item.pathKey !== null && item.pathKey !== ''
|
|
29
29
|
&& groupItem.pathKey === item.pathKey
|
|
30
30
|
return hasSrcMatch || hasPathMatch
|
|
31
31
|
})
|
|
32
|
-
if (currentIndex === -1) currentIndex = 0
|
|
33
|
-
zoom = 1
|
|
32
|
+
if (currentIndex.value === -1) currentIndex.value = 0
|
|
33
|
+
zoom.value = 1
|
|
34
34
|
document.addEventListener('keydown', handleKeydown)
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
function close() {
|
|
38
|
-
isOpen = false
|
|
38
|
+
isOpen.value = false
|
|
39
39
|
document.removeEventListener('keydown', handleKeydown)
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
function selectItem(index: number) {
|
|
43
|
-
currentIndex = index
|
|
44
|
-
zoom = 1
|
|
43
|
+
currentIndex.value = index
|
|
44
|
+
zoom.value = 1
|
|
45
45
|
// The v-model will handle updating the swiper
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
watch(() => isOpen.value, (val) => {
|
|
49
49
|
if (val) {
|
|
50
50
|
document.body.style.overflow = 'hidden'
|
|
51
51
|
} else {
|
|
@@ -53,9 +53,9 @@ vueWatch(() => isOpen, (val) => {
|
|
|
53
53
|
}
|
|
54
54
|
})
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
watch(() => currentIndex.value, () => {
|
|
57
57
|
// Reset zoom when changing slides
|
|
58
|
-
zoom = 1
|
|
58
|
+
zoom.value = 1
|
|
59
59
|
})
|
|
60
60
|
|
|
61
61
|
function handleKeydown(event: KeyboardEvent) {
|
|
@@ -32,9 +32,9 @@ const lightboxDirective: Directive = {
|
|
|
32
32
|
|
|
33
33
|
function groupHandler(item: LightboxItem) {
|
|
34
34
|
if (item.group) {
|
|
35
|
-
if (!groups[item.group]) {groups[item.group] = []}
|
|
35
|
+
if (!groups[item.group]) { groups[item.group] = [] }
|
|
36
36
|
const currentIndex = groups[item.group].findIndex(i => i.src === item.src)
|
|
37
|
-
if (
|
|
37
|
+
if (currentIndex === -1) { groups[item.group].push(item) }
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -42,7 +42,7 @@ function openClickHandler(e: MouseEvent, el: HTMLElement, binding: DirectiveBind
|
|
|
42
42
|
e.stopPropagation()
|
|
43
43
|
const item = bindingToItem(binding, el)
|
|
44
44
|
const lightboxInstance = getLightboxInstance()
|
|
45
|
-
if (!lightboxInstance || !lightboxInstance.open) {return}
|
|
45
|
+
if (!lightboxInstance || !lightboxInstance.open) { return }
|
|
46
46
|
const open = lightboxInstance.open as OpenFunction
|
|
47
47
|
const group = item && item.group ? groups[item.group] : undefined
|
|
48
48
|
open(item, group)
|
|
@@ -60,18 +60,18 @@ const youtubeRegex = /youtube\.com|youtu\.be/
|
|
|
60
60
|
const vimeoRegex = /vimeo\.com/
|
|
61
61
|
|
|
62
62
|
function urlToName(url: string): string {
|
|
63
|
-
if (!url || 'string'
|
|
63
|
+
if (!url || typeof url !== 'string') { return '' }
|
|
64
64
|
const name = url.split('/').pop() || ''
|
|
65
65
|
return name.replace(/\.[^/.]+$/, '')
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
function determineFileType(url: any): string {
|
|
69
|
-
if ('string'
|
|
69
|
+
if (typeof url !== 'string' || !url) { return 'unknown' }
|
|
70
70
|
const extension = (url.split('.').pop() || '').toLowerCase()
|
|
71
71
|
const altExtension = url.split('?')[0].split('.').pop()?.toLowerCase() || ''
|
|
72
|
-
if (IMAGE_FORMATS_REGEXP.test(extension) || IMAGE_FORMATS_REGEXP.test(altExtension)) {return 'image'}
|
|
73
|
-
if (VIDEO_FORMATS_REGEXP.test(extension) || youtubeRegex.test(url) || vimeoRegex.test(url)) {return 'video'}
|
|
74
|
-
if (['pdf'].includes(extension)) {return 'pdf'}
|
|
72
|
+
if (IMAGE_FORMATS_REGEXP.test(extension) || IMAGE_FORMATS_REGEXP.test(altExtension)) { return 'image' }
|
|
73
|
+
if (VIDEO_FORMATS_REGEXP.test(extension) || youtubeRegex.test(url) || vimeoRegex.test(url)) { return 'video' }
|
|
74
|
+
if (['pdf'].includes(extension)) { return 'pdf' }
|
|
75
75
|
return extension ?? 'unknown'
|
|
76
76
|
}
|
|
77
77
|
|
package/src/composables/index.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { BglFormSchemaT, IfAny } from '@bagelink/vue'
|
|
|
2
2
|
|
|
3
3
|
import type { MaybeRefOrGetter, Ref, UnwrapRef } from 'vue'
|
|
4
4
|
import { getFallbackSchema } from '@bagelink/vue'
|
|
5
|
-
import { ref, toValue, watch } from 'vue'
|
|
5
|
+
import { computed, ref, toValue, watch } from 'vue'
|
|
6
6
|
|
|
7
7
|
export { useAddToCalendar } from './useAddToCalendar'
|
|
8
8
|
export { getBagelInstance, setBagelInstance, useBagel } from './useBagel'
|
|
@@ -19,17 +19,17 @@ interface UseBglSchemaParamsT<T> {
|
|
|
19
19
|
export function useBglSchema<T = { [key: string]: unknown }>(
|
|
20
20
|
{ schema, columns, data }: UseBglSchemaParamsT<T> = {}
|
|
21
21
|
): BglFormSchemaT<T> {
|
|
22
|
-
const _schema =
|
|
23
|
-
const _columns =
|
|
22
|
+
const _schema = computed(() => toValue(schema))
|
|
23
|
+
const _columns = computed(() => toValue(columns))
|
|
24
24
|
|
|
25
|
-
if (_schema) {
|
|
25
|
+
if (_schema.value) {
|
|
26
26
|
return (
|
|
27
|
-
_columns && _columns.length > 0
|
|
28
|
-
? _schema.filter(f => _columns.includes(f.id as string))
|
|
29
|
-
: _schema
|
|
27
|
+
_columns.value && _columns.value.length > 0
|
|
28
|
+
? _schema.value.filter(f => _columns.value?.includes(f.id as string))
|
|
29
|
+
: _schema.value
|
|
30
30
|
) as BglFormSchemaT<T>
|
|
31
31
|
}
|
|
32
|
-
return getFallbackSchema(data, _columns)
|
|
32
|
+
return getFallbackSchema(data, _columns.value)
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export function localRef<T>(
|
|
@@ -14,7 +14,7 @@ export type CalendarProvider = 'google' | 'apple' | 'outlook' | 'outlookcom' | '
|
|
|
14
14
|
export function useAddToCalendar(event: CalendarEvent) {
|
|
15
15
|
// Parse dates if they're strings
|
|
16
16
|
const parseDate = (date: Date | string): Date => {
|
|
17
|
-
return 'string'
|
|
17
|
+
return typeof date === 'string' ? new Date(date) : date
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
const eventStartDate = parseDate(event.startDate)
|
|
@@ -33,7 +33,7 @@ export function useAddToCalendar(event: CalendarEvent) {
|
|
|
33
33
|
|
|
34
34
|
// Check if location is a URL
|
|
35
35
|
const isUrl = (text?: string): boolean => {
|
|
36
|
-
if (!text ||
|
|
36
|
+
if (!text || text.length === 0) {
|
|
37
37
|
return false
|
|
38
38
|
}
|
|
39
39
|
return /^https?:\/\/.+/.test(text.trim())
|
|
@@ -77,13 +77,13 @@ export function useAddToCalendar(event: CalendarEvent) {
|
|
|
77
77
|
`SUMMARY:${event.title}`,
|
|
78
78
|
]
|
|
79
79
|
|
|
80
|
-
if (event.description &&
|
|
80
|
+
if (event.description && event.description.length > 0) {
|
|
81
81
|
// ICS descriptions need special handling of newlines and character limits
|
|
82
82
|
const description = event.description.replace(/\n/g, '\\n')
|
|
83
83
|
icsContent.push(`DESCRIPTION:${description}`)
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
if (event.location &&
|
|
86
|
+
if (event.location && event.location.length > 0) {
|
|
87
87
|
icsContent.push(`LOCATION:${event.location}`)
|
|
88
88
|
// If location is a URL, also add it as the URL field
|
|
89
89
|
if (locationIsUrl) {
|
|
@@ -104,11 +104,11 @@ export function useAddToCalendar(event: CalendarEvent) {
|
|
|
104
104
|
dates: `${formatDateISO(eventStartDate)}/${formatDateISO(eventEndDate)}`,
|
|
105
105
|
})
|
|
106
106
|
|
|
107
|
-
if (event.description &&
|
|
107
|
+
if (event.description && event.description.length > 0) {
|
|
108
108
|
params.append('details', event.description)
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
if (event.location &&
|
|
111
|
+
if (event.location && event.location.length > 0) {
|
|
112
112
|
params.append('location', event.location)
|
|
113
113
|
}
|
|
114
114
|
|
|
@@ -125,11 +125,11 @@ export function useAddToCalendar(event: CalendarEvent) {
|
|
|
125
125
|
enddt: eventEndDate.toISOString(),
|
|
126
126
|
})
|
|
127
127
|
|
|
128
|
-
if (event.description &&
|
|
128
|
+
if (event.description && event.description.length > 0) {
|
|
129
129
|
params.append('body', event.description)
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
if (event.location &&
|
|
132
|
+
if (event.location && event.location.length > 0) {
|
|
133
133
|
params.append('location', event.location)
|
|
134
134
|
}
|
|
135
135
|
|
|
@@ -146,11 +146,11 @@ export function useAddToCalendar(event: CalendarEvent) {
|
|
|
146
146
|
enddt: eventEndDate.toISOString(),
|
|
147
147
|
})
|
|
148
148
|
|
|
149
|
-
if (event.description &&
|
|
149
|
+
if (event.description && event.description.length > 0) {
|
|
150
150
|
params.append('body', event.description)
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
if (event.location &&
|
|
153
|
+
if (event.location && event.location.length > 0) {
|
|
154
154
|
params.append('location', event.location)
|
|
155
155
|
}
|
|
156
156
|
|
|
@@ -168,11 +168,11 @@ export function useAddToCalendar(event: CalendarEvent) {
|
|
|
168
168
|
dur: duration.toString(),
|
|
169
169
|
})
|
|
170
170
|
|
|
171
|
-
if (event.description &&
|
|
171
|
+
if (event.description && event.description.length > 0) {
|
|
172
172
|
params.append('desc', event.description)
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
if (event.location &&
|
|
175
|
+
if (event.location && event.location.length > 0) {
|
|
176
176
|
params.append('in_loc', event.location)
|
|
177
177
|
}
|
|
178
178
|
|
|
@@ -214,7 +214,7 @@ export function useAddToCalendar(event: CalendarEvent) {
|
|
|
214
214
|
|
|
215
215
|
// Add to calendar action
|
|
216
216
|
const addToCalendar = (provider: CalendarProvider) => {
|
|
217
|
-
if ('apple'
|
|
217
|
+
if (provider === 'apple' || provider === 'ics') {
|
|
218
218
|
downloadICS()
|
|
219
219
|
} else {
|
|
220
220
|
const url = getCalendarUrl(provider)
|
|
@@ -2,7 +2,7 @@ import { onMounted, onUnmounted, ref } from 'vue'
|
|
|
2
2
|
|
|
3
3
|
export function useDevice() {
|
|
4
4
|
const innerWidth = ref(window.innerWidth)
|
|
5
|
-
const isMobile = ref(
|
|
5
|
+
const isMobile = ref(window.innerWidth < 768)
|
|
6
6
|
const scrollY = ref(window.scrollY)
|
|
7
7
|
const scrollX = ref(window.scrollX)
|
|
8
8
|
const innerHeight = ref(window.innerHeight)
|
|
@@ -20,7 +20,7 @@ export function useDevice() {
|
|
|
20
20
|
|
|
21
21
|
// Update current values
|
|
22
22
|
innerWidth.value = window.innerWidth
|
|
23
|
-
isMobile.value =
|
|
23
|
+
isMobile.value = window.innerWidth < 768
|
|
24
24
|
scrollY.value = window.scrollY
|
|
25
25
|
scrollX.value = window.scrollX
|
|
26
26
|
innerHeight.value = window.innerHeight
|
|
@@ -12,17 +12,17 @@ export function useFormField<T>(props: {
|
|
|
12
12
|
|
|
13
13
|
const fieldData = computed({
|
|
14
14
|
get: () => {
|
|
15
|
-
if (!props.fieldID || !formState) {return props.modelValue ?? props.field.defaultValue ?? ''}
|
|
15
|
+
if (!props.fieldID || !formState) { return props.modelValue ?? props.field.defaultValue ?? '' }
|
|
16
16
|
const value = formState.getFieldData(props.fieldID)
|
|
17
17
|
// For nested form containers, default to empty object
|
|
18
|
-
if (
|
|
18
|
+
if (props.field.$el === 'form' && !value) { return {} }
|
|
19
19
|
// Don't auto-restore defaultValue - let user control their content
|
|
20
20
|
return value ?? ''
|
|
21
21
|
},
|
|
22
22
|
set: (val: any) => {
|
|
23
|
-
if (!props.fieldID || !formState) {return}
|
|
23
|
+
if (!props.fieldID || !formState) { return }
|
|
24
24
|
const currentValue = formState.getFieldData(props.fieldID)
|
|
25
|
-
if (JSON.stringify(val) === JSON.stringify(currentValue)) {return}
|
|
25
|
+
if (JSON.stringify(val) === JSON.stringify(currentValue)) { return }
|
|
26
26
|
|
|
27
27
|
if (props.field.onUpdate) {
|
|
28
28
|
props.field.onUpdate(val, currentValue)
|
|
@@ -25,13 +25,13 @@ export function usePolling(
|
|
|
25
25
|
const pollingId = ref<number | null>(null)
|
|
26
26
|
|
|
27
27
|
const isTabActive = () => {
|
|
28
|
-
return !pauseInBackground || 'visible'
|
|
28
|
+
return !pauseInBackground || document.visibilityState === 'visible'
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
// Stop polling permanently - cannot be resumed
|
|
32
32
|
const stopPolling = () => {
|
|
33
33
|
isPolling.value = false // Permanently set to false
|
|
34
|
-
if (
|
|
34
|
+
if (pollingId.value !== null) {
|
|
35
35
|
clearTimeout(pollingId.value)
|
|
36
36
|
pollingId.value = null
|
|
37
37
|
}
|
|
@@ -39,7 +39,7 @@ export function usePolling(
|
|
|
39
39
|
|
|
40
40
|
// Pause polling temporarily - can be resumed
|
|
41
41
|
const pausePolling = () => {
|
|
42
|
-
if (
|
|
42
|
+
if (pollingId.value !== null) {
|
|
43
43
|
clearTimeout(pollingId.value)
|
|
44
44
|
pollingId.value = null
|
|
45
45
|
}
|
|
@@ -49,7 +49,7 @@ export function usePolling(
|
|
|
49
49
|
// Start polling with intelligent checks
|
|
50
50
|
const startPolling = () => {
|
|
51
51
|
// Clear any existing polling timeout
|
|
52
|
-
if (
|
|
52
|
+
if (pollingId.value !== null) {
|
|
53
53
|
clearTimeout(pollingId.value)
|
|
54
54
|
pollingId.value = null
|
|
55
55
|
}
|
|
@@ -70,13 +70,13 @@ export function usePolling(
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
const resumePolling = () => {
|
|
73
|
-
if (isPolling.value) {startPolling()}
|
|
74
|
-
else {console.warn('Cannot resume polling that was stopped')}
|
|
73
|
+
if (isPolling.value) { startPolling() }
|
|
74
|
+
else { console.warn('Cannot resume polling that was stopped') }
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
function updateVisibility() {
|
|
78
|
-
if ('visible'
|
|
79
|
-
if (isPolling.value) {startPolling()}
|
|
78
|
+
if (document.visibilityState === 'visible') {
|
|
79
|
+
if (isPolling.value) { startPolling() }
|
|
80
80
|
} else if (pauseInBackground) {
|
|
81
81
|
pausePolling()
|
|
82
82
|
}
|
|
@@ -40,19 +40,19 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
|
|
|
40
40
|
|
|
41
41
|
// Helper function to render objects recursively
|
|
42
42
|
function renderObject(obj: T, depth = 0): string {
|
|
43
|
-
if (
|
|
44
|
-
if ('object'
|
|
45
|
-
if (Array.isArray(obj)) {return obj.map(item => renderObject(item, depth + 1)).join(', ')}
|
|
43
|
+
if (obj === null || obj === undefined) { return '' }
|
|
44
|
+
if (typeof obj !== 'object') { return String(obj) }
|
|
45
|
+
if (Array.isArray(obj)) { return obj.map(item => renderObject(item, depth + 1)).join(', ') }
|
|
46
46
|
|
|
47
47
|
// For objects, format as key: value pairs
|
|
48
|
-
const indent =
|
|
48
|
+
const indent = depth > 0 ? ' '.repeat(depth) : ''
|
|
49
49
|
const nextIndent = ' '.repeat(depth + 1)
|
|
50
50
|
|
|
51
51
|
const entries = Object.entries(obj)
|
|
52
|
-
if (
|
|
52
|
+
if (entries.length === 0) { return '{}' }
|
|
53
53
|
|
|
54
54
|
// For nested objects, format with newlines and indentation
|
|
55
|
-
if (
|
|
55
|
+
if (depth > 0) {
|
|
56
56
|
return `{\n${entries
|
|
57
57
|
.map(([key, value]) => `${nextIndent}${key}: ${renderObject(value, depth + 1)}`)
|
|
58
58
|
.join(',\n')}\n${indent}}`
|
|
@@ -61,7 +61,7 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
|
|
|
61
61
|
// For top-level objects, format as a flat list
|
|
62
62
|
return entries
|
|
63
63
|
.map(([key, value]) => {
|
|
64
|
-
const valueStr = 'object'
|
|
64
|
+
const valueStr = typeof value === 'object' && value !== null
|
|
65
65
|
? renderObject(value, depth + 1)
|
|
66
66
|
: String(value)
|
|
67
67
|
return `${key}: ${valueStr}`
|
|
@@ -90,18 +90,18 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
|
|
|
90
90
|
email: EmailInput
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
if ('textarea'
|
|
93
|
+
if (field.$el === 'textarea' && !field.attrs?.multiline) {
|
|
94
94
|
field.attrs = { ...field.attrs, multiline: true }
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
return
|
|
97
|
+
return typeof field.$el === 'object'
|
|
98
98
|
? field.$el
|
|
99
99
|
: (componentMap[field.$el as keyof typeof componentMap] ?? field.$el ?? 'div')
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
function renderChild(child: SchemaChild<T, Path<T>>, slots?: BaseBagelField<T, Path<T>>['slots']) {
|
|
103
|
-
if ('string'
|
|
104
|
-
if (isVNode(child)) {return child}
|
|
103
|
+
if (typeof child === 'string') { return child }
|
|
104
|
+
if (isVNode(child)) { return child }
|
|
105
105
|
return renderField(
|
|
106
106
|
child as BaseBagelField<T, Path<T>>,
|
|
107
107
|
slots
|
|
@@ -113,14 +113,14 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
|
|
|
113
113
|
slots?: BaseBagelField<T, Path<T>>['slots']
|
|
114
114
|
): VNode | undefined {
|
|
115
115
|
const Component = getComponent(field as Field<T>)
|
|
116
|
-
if (!Component) {return}
|
|
116
|
+
if (!Component) { return }
|
|
117
117
|
|
|
118
118
|
const rowData = (getFormData?.() || {}) as T | undefined
|
|
119
119
|
|
|
120
120
|
// Check vIf condition first
|
|
121
121
|
const condition = field.vIf ?? field['v-if']
|
|
122
122
|
if (condition !== undefined) {
|
|
123
|
-
if ('function'
|
|
123
|
+
if (typeof condition === 'function') {
|
|
124
124
|
// Compute currentValue for the vIf check
|
|
125
125
|
const vIfCurrentValue = field.id
|
|
126
126
|
? ('get' in (rowData || {})
|
|
@@ -134,7 +134,7 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
|
|
|
134
134
|
if (!vIfResult) {
|
|
135
135
|
return
|
|
136
136
|
}
|
|
137
|
-
} else if ('string'
|
|
137
|
+
} else if (typeof condition === 'string') {
|
|
138
138
|
if (!getNestedValue(rowData, condition)) {
|
|
139
139
|
return
|
|
140
140
|
}
|
|
@@ -178,9 +178,9 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
|
|
|
178
178
|
const boundFieldProps = bindAttrs(fieldProps as Attributes<T, Path<T>> | undefined, currentValue, rowData)
|
|
179
179
|
|
|
180
180
|
// Check if this component should receive value as slot
|
|
181
|
-
const isSlotValueComponent = 'string'
|
|
181
|
+
const isSlotValueComponent = typeof Component === 'string' && SLOT_VALUE_COMPONENTS.has(Component)
|
|
182
182
|
// Check if this component should receive value as src
|
|
183
|
-
const isSrcValueComponent = 'string'
|
|
183
|
+
const isSrcValueComponent = typeof Component === 'string' && SRC_VALUE_COMPONENTS.has(Component)
|
|
184
184
|
|
|
185
185
|
const props: { [key: string]: any } = {
|
|
186
186
|
...boundFieldProps,
|
|
@@ -209,7 +209,7 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
|
|
|
209
209
|
}
|
|
210
210
|
|
|
211
211
|
// Wire top-level onClick with conditional args
|
|
212
|
-
if (
|
|
212
|
+
if (typeof (field as any).onClick === 'function') {
|
|
213
213
|
const original = (field as any).onClick as (val?: any, row?: T) => void
|
|
214
214
|
props.onClick = () => {
|
|
215
215
|
if (id) {
|
|
@@ -221,7 +221,7 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
|
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
// For form mode, always use the original value for modelValue
|
|
224
|
-
if ('form'
|
|
224
|
+
if (mode === 'form') {
|
|
225
225
|
props.modelValue = currentValue
|
|
226
226
|
props['onUpdate:modelValue'] = (value: any) => {
|
|
227
227
|
onUpdateModelValue?.(field, value)
|
|
@@ -248,7 +248,7 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
|
|
|
248
248
|
if (field.options) {
|
|
249
249
|
if (Array.isArray(field.options)) {
|
|
250
250
|
props.options = field.options
|
|
251
|
-
} else if (
|
|
251
|
+
} else if (typeof field.options === 'function') {
|
|
252
252
|
const fn = field.options as any
|
|
253
253
|
// Component-aware mapping
|
|
254
254
|
if (Component === SelectInput) {
|
|
@@ -256,18 +256,18 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
|
|
|
256
256
|
const row = getFormData?.()
|
|
257
257
|
const val = currentValue
|
|
258
258
|
// If author expects (query) only, call directly
|
|
259
|
-
if (
|
|
259
|
+
if (typeof fn === 'function' && fn.length === 1) {
|
|
260
260
|
return fn(query)
|
|
261
261
|
}
|
|
262
262
|
// If author expects (query, val, row), pass it directly
|
|
263
|
-
if (
|
|
263
|
+
if (typeof fn === 'function' && fn.length >= 3) {
|
|
264
264
|
return fn(query, val, row)
|
|
265
265
|
}
|
|
266
266
|
// Otherwise evaluate (val,row) → array | (query)=>Promise | Promise
|
|
267
267
|
const out = fn(val, row)
|
|
268
|
-
if (Array.isArray(out)) {return out}
|
|
269
|
-
if ('function'
|
|
270
|
-
if (out &&
|
|
268
|
+
if (Array.isArray(out)) { return out }
|
|
269
|
+
if (typeof out === 'function') { return out(query) }
|
|
270
|
+
if (out && typeof out.then === 'function') { return out }
|
|
271
271
|
return []
|
|
272
272
|
}
|
|
273
273
|
} else {
|
|
@@ -276,10 +276,10 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
|
|
|
276
276
|
const row = getFormData?.()
|
|
277
277
|
const val = currentValue
|
|
278
278
|
const out = fn(val, row)
|
|
279
|
-
if (Array.isArray(out)) {return out}
|
|
280
|
-
if ('function'
|
|
281
|
-
if (out &&
|
|
282
|
-
if (
|
|
279
|
+
if (Array.isArray(out)) { return out }
|
|
280
|
+
if (typeof out === 'function') { return await out('') }
|
|
281
|
+
if (out && typeof out.then === 'function') { return await out }
|
|
282
|
+
if (fn.length >= 3) { return await fn('', val, row) }
|
|
283
283
|
return []
|
|
284
284
|
}
|
|
285
285
|
}
|
|
@@ -293,10 +293,10 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
|
|
|
293
293
|
const boundAttrs = bindAttrs(field.attrs, currentValue, rowData)
|
|
294
294
|
Object.entries(boundAttrs).forEach(([key, value]) => {
|
|
295
295
|
// Skip $el as it's not a DOM attribute
|
|
296
|
-
if ('$el'
|
|
296
|
+
if (key === '$el') { return }
|
|
297
297
|
|
|
298
|
-
if ('function'
|
|
299
|
-
if ('onClick'
|
|
298
|
+
if (typeof value === 'function') {
|
|
299
|
+
if (key === 'onClick') {
|
|
300
300
|
const original = value as (val?: any, row?: T) => void
|
|
301
301
|
props.onClick = () => {
|
|
302
302
|
if (id) {
|
|
@@ -324,7 +324,7 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
|
|
|
324
324
|
const componentSlots: Parameters<typeof h>[1] = {}
|
|
325
325
|
|
|
326
326
|
// Add default slot if there are children
|
|
327
|
-
if (children &&
|
|
327
|
+
if (children && children.length > 0) {
|
|
328
328
|
componentSlots.default = () => children
|
|
329
329
|
.map(child => renderChild(child, slots))
|
|
330
330
|
.filter(Boolean) // Filter out null results from vIf
|
|
@@ -342,7 +342,7 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
|
|
|
342
342
|
if (Array.isArray(slot)) {
|
|
343
343
|
// Handle BglFormSchemaT array
|
|
344
344
|
return slot.map((schemaField) => {
|
|
345
|
-
if ('function'
|
|
345
|
+
if (typeof schemaField === 'function') {
|
|
346
346
|
// Handle function slot
|
|
347
347
|
const slotFn = schemaField
|
|
348
348
|
return slotFn({ row: rowData, field })
|
|
@@ -369,19 +369,19 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
|
|
|
369
369
|
// ? (slots[field.id])({ row: rowData, field })
|
|
370
370
|
// : undefined
|
|
371
371
|
|
|
372
|
-
if ('preview'
|
|
372
|
+
if (mode === 'preview') {
|
|
373
373
|
// Skip rendering if value is unset and includeUnset is false
|
|
374
|
-
if (!includeUnset && (transformedValue === undefined ||
|
|
375
|
-
|| (
|
|
374
|
+
if (!includeUnset && (transformedValue === undefined || transformedValue === null
|
|
375
|
+
|| (typeof transformedValue === 'string' && transformedValue.length === 0))) {
|
|
376
376
|
return
|
|
377
377
|
}
|
|
378
378
|
|
|
379
379
|
return h('div', { class: 'preview-field' }, [
|
|
380
380
|
h('div', { class: 'field-label' }, `${field.label || keyToLabel(field.id || '')}:`),
|
|
381
381
|
h('div', { class: 'field-value' }, [
|
|
382
|
-
slotContent || (
|
|
382
|
+
slotContent || (typeof field.$el === 'object'
|
|
383
383
|
? h(Component as any, props, componentSlots)
|
|
384
|
-
: 'object'
|
|
384
|
+
: typeof transformedValue === 'object' && transformedValue !== null
|
|
385
385
|
? h('pre', {
|
|
386
386
|
style: 'margin: 0; white-space: pre-wrap; font-family: inherit; font-size: inherit;'
|
|
387
387
|
}, renderObject(transformedValue))
|
|
@@ -50,17 +50,17 @@ function applyTheme(themeValue: string) {
|
|
|
50
50
|
|
|
51
51
|
// Remove all theme classes
|
|
52
52
|
themeOptions.value.forEach((t) => {
|
|
53
|
-
if ('system'
|
|
53
|
+
if (t.class !== 'system') {
|
|
54
54
|
root.classList.remove(t.class)
|
|
55
55
|
}
|
|
56
56
|
})
|
|
57
57
|
|
|
58
58
|
// Handle system theme
|
|
59
|
-
if ('system'
|
|
59
|
+
if (themeValue === 'system') {
|
|
60
60
|
const systemIsDark = getSystemPrefersDark()
|
|
61
61
|
isDark.value = systemIsDark
|
|
62
|
-
const darkTheme = themeOptions.value.find(t => 'dark'
|
|
63
|
-
const lightTheme = themeOptions.value.find(t => 'light'
|
|
62
|
+
const darkTheme = themeOptions.value.find(t => t.value === 'dark')
|
|
63
|
+
const lightTheme = themeOptions.value.find(t => t.value === 'light')
|
|
64
64
|
const themeToApply = systemIsDark ? darkTheme : lightTheme
|
|
65
65
|
if (themeToApply) {
|
|
66
66
|
root.classList.add(themeToApply.class)
|
|
@@ -77,9 +77,9 @@ function applyTheme(themeValue: string) {
|
|
|
77
77
|
|
|
78
78
|
function toggleTheme() {
|
|
79
79
|
// Get all non-system themes
|
|
80
|
-
const cyclableThemes = themeOptions.value.filter(t => 'system'
|
|
80
|
+
const cyclableThemes = themeOptions.value.filter(t => t.value !== 'system')
|
|
81
81
|
|
|
82
|
-
if (
|
|
82
|
+
if (cyclableThemes.length === 0) { return }
|
|
83
83
|
|
|
84
84
|
const currentIndex = cyclableThemes.findIndex(t => t.value === colorMode.value)
|
|
85
85
|
const nextIndex = (currentIndex + 1) % cyclableThemes.length
|
|
@@ -91,8 +91,8 @@ function addTheme(theme: ThemeOption) {
|
|
|
91
91
|
const exists = themeOptions.value.some(t => t.value === theme.value)
|
|
92
92
|
if (!exists) {
|
|
93
93
|
// Add before 'system' option
|
|
94
|
-
const systemIndex = themeOptions.value.findIndex(t => 'system'
|
|
95
|
-
if (-1
|
|
94
|
+
const systemIndex = themeOptions.value.findIndex(t => t.value === 'system')
|
|
95
|
+
if (systemIndex > -1) {
|
|
96
96
|
themeOptions.value.splice(systemIndex, 0, theme)
|
|
97
97
|
} else {
|
|
98
98
|
themeOptions.value.push(theme)
|
|
@@ -130,7 +130,7 @@ export function useTheme() {
|
|
|
130
130
|
// React to system changes when in "system" mode
|
|
131
131
|
const mq = window.matchMedia('(prefers-color-scheme: dark)')
|
|
132
132
|
const handler = (e: MediaQueryListEvent) => {
|
|
133
|
-
if ('system'
|
|
133
|
+
if (colorMode.value === 'system') {
|
|
134
134
|
applyTheme('system')
|
|
135
135
|
}
|
|
136
136
|
}
|
|
@@ -12,9 +12,9 @@ export function useValidateFieldValue(
|
|
|
12
12
|
inputVal,
|
|
13
13
|
(newVal, oldVal) => {
|
|
14
14
|
getInput?.()?.setCustomValidity('')
|
|
15
|
-
if (!validateFn || newVal === oldVal || !newVal) {return}
|
|
15
|
+
if (!validateFn || newVal === oldVal || !newVal) { return }
|
|
16
16
|
const isValid = validateFn(newVal, getFormData?.())
|
|
17
|
-
if ('string'
|
|
17
|
+
if (typeof isValid === 'string') { getInput?.()?.setCustomValidity(isValid) }
|
|
18
18
|
},
|
|
19
19
|
{ debounce: 500 },
|
|
20
20
|
)
|