@bagelink/vue 1.6.43 → 1.6.49
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/Swiper.vue.d.ts +12 -4
- package/dist/components/Swiper.vue.d.ts.map +1 -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/AppContent.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/components/lightbox/Lightbox.vue.d.ts.map +1 -1
- package/dist/index.cjs +24 -15
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +1530 -1404
- package/dist/plugins/modalTypes.d.ts +1 -8
- package/dist/plugins/modalTypes.d.ts.map +1 -1
- package/dist/plugins/useModal.d.ts.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -2
- package/src/components/AccordionItem.vue +13 -13
- 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 +12 -11
- 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 +15 -11
- 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/Swiper.vue +4 -4
- package/src/components/Zoomer.vue +282 -182
- 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/media.ts +7 -7
- 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/AppContent.vue +6 -3
- package/src/components/layout/AppLayout.vue +2 -2
- package/src/components/layout/AppSidebar.vue +83 -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 +276 -126
- 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/modalTypes.ts +1 -8
- package/src/plugins/useModal.ts +43 -18
- 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
|
@@ -1,127 +1,123 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { LightboxItem } from './lightbox.types'
|
|
3
3
|
|
|
4
|
-
import { BglVideo, Btn, Icon, Zoomer, Image, normalizeURL,
|
|
5
|
-
import { watch } from 'vue'
|
|
4
|
+
import { BglVideo, Btn, Icon, Zoomer, Image, normalizeURL, Swiper, downloadFile } from '@bagelink/vue'
|
|
5
|
+
import { computed, ref, watch } from 'vue'
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
+
|
|
13
|
+
const canSwipe = computed(() => zoom.value === 1)
|
|
14
|
+
|
|
15
|
+
// Advanced options that update reactively
|
|
16
|
+
const swiperAdvancedOptions = computed(() => ({
|
|
17
|
+
allowTouchMove: zoom.value === 1,
|
|
18
|
+
touchRatio: zoom.value === 1 ? 1 : 0,
|
|
19
|
+
simulateTouch: zoom.value === 1,
|
|
20
|
+
}))
|
|
11
21
|
|
|
12
22
|
function open(item: LightboxItem, groupItems?: LightboxItem[]) {
|
|
13
|
-
isOpen = true
|
|
14
|
-
group = groupItems || [item]
|
|
15
|
-
currentIndex = group.findIndex((
|
|
23
|
+
isOpen.value = true
|
|
24
|
+
group.value = groupItems || [item]
|
|
25
|
+
currentIndex.value = group.value.findIndex((groupItem) => {
|
|
26
|
+
const hasSrcMatch = item.src !== undefined && item.src !== null && item.src !== ''
|
|
27
|
+
&& groupItem.src === item.src
|
|
28
|
+
const hasPathMatch = item.pathKey !== undefined && item.pathKey !== null && item.pathKey !== ''
|
|
29
|
+
&& groupItem.pathKey === item.pathKey
|
|
30
|
+
return hasSrcMatch || hasPathMatch
|
|
31
|
+
})
|
|
32
|
+
if (currentIndex.value === -1) currentIndex.value = 0
|
|
33
|
+
zoom.value = 1
|
|
16
34
|
document.addEventListener('keydown', handleKeydown)
|
|
17
35
|
}
|
|
18
36
|
|
|
19
37
|
function close() {
|
|
20
|
-
isOpen = false
|
|
38
|
+
isOpen.value = false
|
|
21
39
|
document.removeEventListener('keydown', handleKeydown)
|
|
22
40
|
}
|
|
23
41
|
|
|
24
|
-
function
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
42
|
+
function selectItem(index: number) {
|
|
43
|
+
currentIndex.value = index
|
|
44
|
+
zoom.value = 1
|
|
45
|
+
// The v-model will handle updating the swiper
|
|
29
46
|
}
|
|
30
47
|
|
|
31
|
-
|
|
32
|
-
if (
|
|
33
|
-
|
|
34
|
-
|
|
48
|
+
watch(() => isOpen.value, (val) => {
|
|
49
|
+
if (val) {
|
|
50
|
+
document.body.style.overflow = 'hidden'
|
|
51
|
+
} else {
|
|
52
|
+
document.body.style.overflow = ''
|
|
35
53
|
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function selectItem(index: number) {
|
|
39
|
-
currentIndex = index
|
|
40
|
-
currentItem = group[index]
|
|
41
|
-
}
|
|
54
|
+
})
|
|
42
55
|
|
|
43
|
-
watch(() =>
|
|
44
|
-
|
|
45
|
-
|
|
56
|
+
watch(() => currentIndex.value, () => {
|
|
57
|
+
// Reset zoom when changing slides
|
|
58
|
+
zoom.value = 1
|
|
46
59
|
})
|
|
47
60
|
|
|
48
61
|
function handleKeydown(event: KeyboardEvent) {
|
|
49
62
|
if (event.key === 'Escape') {
|
|
50
63
|
close()
|
|
51
|
-
} else if (event.key === 'ArrowLeft') {
|
|
52
|
-
prev()
|
|
53
|
-
} else if (event.key === 'ArrowRight') {
|
|
54
|
-
next()
|
|
55
64
|
}
|
|
56
65
|
}
|
|
57
66
|
|
|
58
|
-
const zoom = $ref(1)
|
|
59
|
-
|
|
60
|
-
function clickOutside() {
|
|
61
|
-
if (zoom === 1) { close() }
|
|
62
|
-
}
|
|
63
|
-
|
|
64
67
|
defineExpose({ open, close })
|
|
65
68
|
</script>
|
|
66
69
|
|
|
67
70
|
<template>
|
|
68
71
|
<transition name="fade">
|
|
69
|
-
<div
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
class="navigation flex space-between px-3 w-100 absolute m_px-1 m_none z-9"
|
|
77
|
-
>
|
|
78
|
-
<Btn class="oval opacity-8" icon="arrow_back" color="black" @click="prev" />
|
|
79
|
-
|
|
80
|
-
<Btn class="oval opacity-8" icon="arrow_forward" color="black" @click="next" />
|
|
81
|
-
</div>
|
|
82
|
-
<div class="bgl-lightbox relative txt-center" @click.stop>
|
|
83
|
-
<div class="flex start fixed top-1 w-100 space-between px-1 z-9">
|
|
84
|
-
<Btn flat class="color-white" icon="close" @click="close" />
|
|
85
|
-
<div v-if="currentItem?.enableZoom && currentItem?.type === 'image'" class="center">
|
|
86
|
-
<Btn flat class="color-white" icon="remove" :disabled="zoom === 1" @click="zoom--" />
|
|
87
|
-
<Btn flat class="color-white" icon="zoom_in" :disabled="zoom === 1" @click="zoom = 1" />
|
|
88
|
-
<Btn flat class="color-white" icon="add" :disabled="zoom === 3" @click="zoom++" />
|
|
89
|
-
</div>
|
|
90
|
-
<Btn
|
|
91
|
-
v-if="currentItem?.openFile && currentItem?.src" class="color-white" round thin flat
|
|
92
|
-
iconEnd="arrow_outward" value="Open File" :href="currentItem?.src" target="_blank"
|
|
93
|
-
/>
|
|
94
|
-
<Btn
|
|
95
|
-
v-if="currentItem?.download && currentItem?.src" class="color-white" round thin flat
|
|
96
|
-
icon="download" value="Download File" @click="downloadFile(currentItem?.src)"
|
|
97
|
-
/>
|
|
98
|
-
<div v-if="!currentItem?.openFile && !currentItem?.download" />
|
|
72
|
+
<div v-if="isOpen" class="bgl-lightbox-overlay" @keydown.esc="close">
|
|
73
|
+
<div class="flex start w-100 space-between p-025 z-9" @click="close">
|
|
74
|
+
<Btn flat class="color-white" icon="close" @click="close" />
|
|
75
|
+
<div v-if="currentItem?.enableZoom && currentItem?.type === 'image'" class="center">
|
|
76
|
+
<Btn flat class="color-white" icon="remove" :disabled="zoom === 1" @click="zoom--" />
|
|
77
|
+
<Btn flat class="color-white" icon="zoom_in" :disabled="zoom === 1" @click="zoom = 1" />
|
|
78
|
+
<Btn flat class="color-white" icon="add" :disabled="zoom === 3" @click="zoom++" />
|
|
99
79
|
</div>
|
|
80
|
+
<Btn
|
|
81
|
+
v-if="currentItem?.openFile && currentItem?.src" class="color-white" round thin flat
|
|
82
|
+
iconEnd="arrow_outward" value="Open File" :href="currentItem?.src" target="_blank"
|
|
83
|
+
/>
|
|
84
|
+
<Btn
|
|
85
|
+
v-if="currentItem?.download && currentItem?.src" class="color-white" round thin flat
|
|
86
|
+
icon="download" value="Download File" @click="downloadFile(currentItem?.src)"
|
|
87
|
+
/>
|
|
88
|
+
<div v-if="!currentItem?.openFile && !currentItem?.download" />
|
|
89
|
+
</div>
|
|
100
90
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
>
|
|
105
|
-
|
|
91
|
+
<Swiper
|
|
92
|
+
v-if="group && group.length > 0" v-model:index="currentIndex" :items="group"
|
|
93
|
+
:initial-slide="currentIndex" class="bgl-lightbox-swiper" :class="{ zoomed: zoom > 1 }"
|
|
94
|
+
:navigation="group.length > 1" :grab-cursor="canSwipe" :keyboard="true" :loop="false" :speed="400"
|
|
95
|
+
:slides-per-view="1" :space-between="0" effect="slide" :advanced-options="swiperAdvancedOptions"
|
|
96
|
+
@click.stop
|
|
97
|
+
>
|
|
98
|
+
<template #default="{ item }">
|
|
99
|
+
<div class="bgl-lightbox-item">
|
|
106
100
|
<Zoomer
|
|
107
101
|
v-if="item.type === 'image'" v-model:zoom="zoom" :disabled="!item?.enableZoom"
|
|
108
|
-
:mouse-wheel-to-zoom="false"
|
|
102
|
+
:mouse-wheel-to-zoom="false" :double-click-to-zoom="true" :max-scale="5" :min-scale="1"
|
|
103
|
+
:aspect-ratio="0" :limit-translation="true" @click.stop
|
|
109
104
|
>
|
|
110
|
-
<Image :draggable="false" :src="item?.src" alt="Preview" class="
|
|
105
|
+
<Image :draggable="false" :src="item?.src" alt="Preview" class="lightbox-image" />
|
|
111
106
|
</Zoomer>
|
|
112
107
|
|
|
113
108
|
<BglVideo
|
|
114
109
|
v-else-if="item?.type === 'video' && item?.src" :src="item?.src" autoplay controls
|
|
115
|
-
class="
|
|
110
|
+
class="lightbox-video"
|
|
116
111
|
/>
|
|
117
112
|
|
|
118
|
-
<div v-else-if="item?.type === 'pdf' && item?.src" class="
|
|
113
|
+
<div v-else-if="item?.type === 'pdf' && item?.src" class="lightbox-pdf">
|
|
119
114
|
<embed
|
|
120
115
|
:src="normalizeURL(item?.src)" type="application/pdf" width="100%" height="1080"
|
|
121
|
-
:title="item?.name"
|
|
116
|
+
:title="item?.name"
|
|
122
117
|
>
|
|
123
118
|
</div>
|
|
124
|
-
|
|
119
|
+
|
|
120
|
+
<div v-else class="lightbox-file">
|
|
125
121
|
<div class="file-info txt-white flex m_block align-items-start gap-025">
|
|
126
122
|
<Icon class="m-0 m_none" icon="draft" :size="10" weight="12" />
|
|
127
123
|
<Icon class="m-0 none m_block m_-mb-1" icon="draft" :size="4" weight="2" />
|
|
@@ -129,40 +125,39 @@ defineExpose({ open, close })
|
|
|
129
125
|
<div class="txt-start">
|
|
130
126
|
<p class="mx-0 light">
|
|
131
127
|
File:
|
|
132
|
-
<span class="semi word-break-all
|
|
133
|
-
{{ item?.name }}
|
|
134
|
-
</span>
|
|
128
|
+
<span class="semi word-break-all">{{ item?.name }}</span>
|
|
135
129
|
</p>
|
|
136
|
-
<p class="mx-0
|
|
130
|
+
<p class="mx-0">
|
|
137
131
|
Type:
|
|
138
|
-
<span class="semi">
|
|
139
|
-
{{ item?.type }}
|
|
140
|
-
</span>
|
|
132
|
+
<span class="semi">{{ item?.type }}</span>
|
|
141
133
|
</p>
|
|
142
134
|
<Btn :href="item?.src" target="_blank" round thin class="mt-1" value="Open file" />
|
|
143
|
-
<!-- <a :href="currentItem?.src" target="_blank">Open file</a> -->
|
|
144
135
|
</div>
|
|
145
136
|
</div>
|
|
146
137
|
</div>
|
|
147
|
-
</
|
|
148
|
-
</
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
>
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
138
|
+
</div>
|
|
139
|
+
</template>
|
|
140
|
+
|
|
141
|
+
<template #prev-button="{ prev }">
|
|
142
|
+
<Btn icon="arrow_back" color="black" @click="prev" />
|
|
143
|
+
</template>
|
|
144
|
+
|
|
145
|
+
<template #next-button="{ next }">
|
|
146
|
+
<Btn icon="arrow_forward" color="black" @click="next" />
|
|
147
|
+
</template>
|
|
148
|
+
</Swiper>
|
|
149
|
+
|
|
150
|
+
<div v-if="group && group.length > 1" class="lightbox-thumbnails" @click.stop>
|
|
151
|
+
<template v-for="(item, index) in group" :key="index">
|
|
152
|
+
<Image
|
|
153
|
+
v-if="item.type === 'image'" class="thumbnail" :src="item.src" alt=""
|
|
154
|
+
:class="{ active: currentIndex === index }" @click.stop="selectItem(index)"
|
|
155
|
+
/>
|
|
156
|
+
<Icon
|
|
157
|
+
v-else class="thumbnail thumbnail-icon" icon="description"
|
|
158
|
+
:class="{ active: currentIndex === index }" @click.stop="selectItem(index)"
|
|
159
|
+
/>
|
|
160
|
+
</template>
|
|
166
161
|
</div>
|
|
167
162
|
</div>
|
|
168
163
|
</transition>
|
|
@@ -189,70 +184,225 @@ defineExpose({ open, close })
|
|
|
189
184
|
}
|
|
190
185
|
|
|
191
186
|
.bgl-lightbox-overlay {
|
|
187
|
+
position: fixed;
|
|
188
|
+
width: 100vw;
|
|
189
|
+
height: 100vh;
|
|
190
|
+
display: grid;
|
|
191
|
+
grid-template-rows: 50px 1fr 100px;
|
|
192
|
+
z-index: 9999;
|
|
193
|
+
inset: 0;
|
|
192
194
|
background: rgba(0, 0, 0, 0.8);
|
|
195
|
+
overflow: hidden;
|
|
193
196
|
}
|
|
194
197
|
|
|
195
|
-
|
|
196
|
-
|
|
198
|
+
/* Top controls row */
|
|
199
|
+
.bgl-lightbox-overlay>.flex:first-child {
|
|
200
|
+
grid-row: 1;
|
|
201
|
+
align-self: start;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/* Main content row - Swiper */
|
|
205
|
+
.bgl-lightbox-swiper {
|
|
206
|
+
grid-row: 2;
|
|
207
|
+
width: 100vw;
|
|
208
|
+
height: 100%;
|
|
209
|
+
overflow: hidden;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/* Bottom thumbnails row */
|
|
213
|
+
.lightbox-thumbnails {
|
|
214
|
+
grid-row: 3;
|
|
215
|
+
align-self: end;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.bgl-lightbox-swiper .swiper {
|
|
219
|
+
width: 100%;
|
|
220
|
+
height: 100%;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.bgl-lightbox-swiper .swiper-wrapper {
|
|
224
|
+
align-items: center;
|
|
197
225
|
}
|
|
198
226
|
|
|
199
227
|
.bgl-lightbox-item {
|
|
200
|
-
|
|
228
|
+
display: flex;
|
|
229
|
+
align-items: center;
|
|
230
|
+
justify-content: center;
|
|
231
|
+
width: 100%;
|
|
232
|
+
height: 100%;
|
|
233
|
+
animation: 200ms ease bgl-lightbox-load;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/* Navigation button styling */
|
|
237
|
+
.lightbox-nav-btn {
|
|
238
|
+
background: rgba(0, 0, 0, 0.6);
|
|
239
|
+
backdrop-filter: blur(8px);
|
|
240
|
+
border-radius: 50%;
|
|
241
|
+
width: 48px;
|
|
242
|
+
height: 48px;
|
|
243
|
+
display: flex;
|
|
244
|
+
align-items: center;
|
|
245
|
+
justify-content: center;
|
|
246
|
+
color: white;
|
|
247
|
+
cursor: pointer;
|
|
248
|
+
transition: all 0.2s ease;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.lightbox-nav-btn:hover {
|
|
252
|
+
background: rgba(0, 0, 0, 0.8);
|
|
253
|
+
transform: scale(1.05);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.lightbox-nav-btn:active {
|
|
257
|
+
transform: scale(0.95);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/* Adjust swiper navigation positioning */
|
|
261
|
+
.bgl-lightbox-swiper :deep(.swi-ctrl) {
|
|
262
|
+
padding: 0 1.5rem !important;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
@media screen and (max-width: 900px) {
|
|
266
|
+
.bgl-lightbox-swiper :deep(.swi-ctrl) {
|
|
267
|
+
padding: 0 1rem !important;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.lightbox-nav-btn {
|
|
271
|
+
width: 40px;
|
|
272
|
+
height: 40px;
|
|
273
|
+
}
|
|
201
274
|
}
|
|
202
275
|
|
|
203
276
|
@keyframes bgl-lightbox-load {
|
|
204
277
|
from {
|
|
205
|
-
|
|
278
|
+
opacity: 0;
|
|
279
|
+
transform: scale(0.95);
|
|
206
280
|
}
|
|
207
281
|
|
|
208
282
|
to {
|
|
209
|
-
|
|
210
|
-
|
|
283
|
+
opacity: 1;
|
|
284
|
+
transform: scale(1);
|
|
211
285
|
}
|
|
212
286
|
}
|
|
213
287
|
|
|
214
|
-
.
|
|
215
|
-
|
|
288
|
+
.lightbox-image,
|
|
289
|
+
.lightbox-video,
|
|
290
|
+
.lightbox-pdf,
|
|
291
|
+
.lightbox-file {
|
|
292
|
+
max-width: 90vw;
|
|
293
|
+
max-height: calc(100vh - 140px);
|
|
294
|
+
object-fit: contain;
|
|
216
295
|
border-radius: 3px;
|
|
217
296
|
margin: auto;
|
|
218
|
-
animation: 200ms ease bgl-lightbox-load;
|
|
219
|
-
transition: max-height 200ms ease;
|
|
220
297
|
}
|
|
221
298
|
|
|
222
|
-
.
|
|
299
|
+
.lightbox-image {
|
|
300
|
+
width: auto;
|
|
301
|
+
height: auto;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/* When zoomed, make image full width */
|
|
305
|
+
.bgl-lightbox-swiper.zoomed .lightbox-image {
|
|
306
|
+
max-width: 100vw;
|
|
307
|
+
width: 100vw;
|
|
308
|
+
max-height: 100vh;
|
|
309
|
+
height: 100vh;
|
|
310
|
+
object-fit: contain;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.bgl-lightbox-swiper.zoomed .vue-zoomer {
|
|
314
|
+
width: 100vw;
|
|
315
|
+
height: 100vh;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.bgl-lightbox-swiper.zoomed .bgl-lightbox-item * {
|
|
223
319
|
max-height: calc(100vh - 90px);
|
|
224
320
|
height: calc(100vh - 90px);
|
|
225
321
|
}
|
|
226
322
|
|
|
227
|
-
.bgl-lightbox-
|
|
323
|
+
.bgl-lightbox-swiper.zoomed {
|
|
228
324
|
pointer-events: none;
|
|
229
325
|
}
|
|
230
326
|
|
|
231
|
-
.bgl-lightbox-
|
|
327
|
+
.bgl-lightbox-swiper.zoomed .vue-zoomer {
|
|
232
328
|
pointer-events: auto;
|
|
233
329
|
}
|
|
234
330
|
|
|
235
|
-
.
|
|
236
|
-
|
|
237
|
-
|
|
331
|
+
.lightbox-thumbnails {
|
|
332
|
+
display: flex;
|
|
333
|
+
justify-content: center;
|
|
334
|
+
align-items: center;
|
|
335
|
+
gap: 0.75rem;
|
|
336
|
+
padding: 1rem;
|
|
337
|
+
overflow-x: auto;
|
|
338
|
+
overflow-y: hidden;
|
|
339
|
+
background: linear-gradient(to top, rgba(0, 0, 0, 0.4) 0%, transparent 100%);
|
|
340
|
+
width: 100%;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.lightbox-thumbnails::-webkit-scrollbar {
|
|
344
|
+
height: 4px;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
.lightbox-thumbnails::-webkit-scrollbar-track {
|
|
348
|
+
background: transparent;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
.lightbox-thumbnails::-webkit-scrollbar-thumb {
|
|
352
|
+
background: rgba(255, 255, 255, 0.3);
|
|
353
|
+
border-radius: 2px;
|
|
238
354
|
}
|
|
239
355
|
|
|
240
356
|
.thumbnail {
|
|
241
|
-
height:
|
|
242
|
-
width:
|
|
357
|
+
height: 60px;
|
|
358
|
+
width: 60px;
|
|
359
|
+
min-width: 60px;
|
|
360
|
+
object-fit: cover;
|
|
361
|
+
border-radius: 6px;
|
|
362
|
+
cursor: pointer;
|
|
363
|
+
opacity: 0.6;
|
|
364
|
+
transition: all 0.2s ease;
|
|
365
|
+
flex-shrink: 0;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
.thumbnail-icon {
|
|
369
|
+
display: flex;
|
|
370
|
+
align-items: center;
|
|
371
|
+
justify-content: center;
|
|
372
|
+
background: rgba(255, 255, 255, 0.1);
|
|
243
373
|
}
|
|
244
374
|
|
|
245
375
|
.thumbnail:hover {
|
|
246
376
|
opacity: 1;
|
|
377
|
+
transform: scale(1.05);
|
|
247
378
|
}
|
|
248
379
|
|
|
249
380
|
.thumbnail:active {
|
|
250
|
-
|
|
381
|
+
transform: scale(0.95);
|
|
251
382
|
}
|
|
252
383
|
|
|
253
384
|
.thumbnail.active {
|
|
254
385
|
opacity: 1;
|
|
255
|
-
outline:
|
|
386
|
+
outline: 3px solid white;
|
|
387
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
@media screen and (max-width: 910px) {
|
|
391
|
+
.bgl-lightbox-overlay {
|
|
392
|
+
grid-template-rows: 50px 1fr 70px;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
.lightbox-thumbnails {
|
|
396
|
+
justify-content: flex-start;
|
|
397
|
+
gap: 0.5rem;
|
|
398
|
+
padding: 0.75rem 1rem;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
.thumbnail {
|
|
402
|
+
height: 50px;
|
|
403
|
+
width: 50px;
|
|
404
|
+
min-width: 50px;
|
|
405
|
+
}
|
|
256
406
|
}
|
|
257
407
|
|
|
258
408
|
.file-info {
|
|
@@ -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>(
|