@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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { LatLngExpression, Map, Marker } from 'leaflet'
|
|
3
3
|
import { appendScript, sleep } from '@bagelink/vue'
|
|
4
|
-
import { onMounted, watch } from 'vue'
|
|
4
|
+
import { onMounted, ref, watch } from 'vue'
|
|
5
5
|
import './leaflet.css'
|
|
6
6
|
|
|
7
7
|
type MapMarker = {
|
|
@@ -32,56 +32,56 @@ const props = withDefaults(
|
|
|
32
32
|
)
|
|
33
33
|
|
|
34
34
|
const emit = defineEmits(['select'])
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const _markers =
|
|
38
|
-
const id =
|
|
35
|
+
const L = ref<any>()
|
|
36
|
+
const map = ref<Map>()
|
|
37
|
+
const _markers = ref<Marker[]>([])
|
|
38
|
+
const id = ref(Math.random().toString(36).slice(2, 10))
|
|
39
39
|
|
|
40
40
|
const defaultMarkerSVG = '<svg width="28" height="38" viewBox="0 0 28 38" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M14.2263 37.7955C17.0897 37.7955 19.4109 37.0138 19.4109 36.0496C19.4109 35.0854 17.0897 34.3037 14.2263 34.3037C11.363 34.3037 9.04175 35.0854 9.04175 36.0496C9.04175 37.0138 11.363 37.7955 14.2263 37.7955Z" fill="black" fill-opacity="0.1"/><path d="M14.2265 0.549591C21.2842 0.549591 27.0131 6.23786 27.0787 13.28V13.4024C27.0787 19.3328 24.4759 24.4306 21.5627 28.2764C18.6511 32.12 15.4577 34.6754 14.3457 35.5097C14.2748 35.5629 14.1778 35.5629 14.1068 35.5097C12.9947 34.675 9.80135 32.1197 6.88984 28.2762C3.97665 24.4304 1.37378 19.3328 1.37378 13.4024C1.37378 6.30387 7.12806 0.549591 14.2265 0.549591Z" fill="#ED1b3E" stroke="#ED6C6F"/><path d="M14.2263 21.6185C18.7639 21.6185 22.4424 17.94 22.4424 13.4024C22.4424 8.86477 18.7639 5.18631 14.2263 5.18631C9.68872 5.18631 6.01025 8.86477 6.01025 13.4024C6.01025 17.94 9.68872 21.6185 14.2263 21.6185Z" fill="white"/></svg>'
|
|
41
41
|
const leafletScriptUrl = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js'
|
|
42
42
|
|
|
43
43
|
async function loadGlobalL() {
|
|
44
|
-
while (!window.L) {await sleep(100)}
|
|
44
|
+
while (!window.L) { await sleep(100) }
|
|
45
45
|
return window.L
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
async function initializeMap() {
|
|
49
49
|
await appendScript(leafletScriptUrl)
|
|
50
|
-
L = await loadGlobalL()
|
|
51
|
-
if (!map) {
|
|
52
|
-
map = L.map(id, {
|
|
50
|
+
L.value = await loadGlobalL()
|
|
51
|
+
if (!map.value) {
|
|
52
|
+
map.value = L.value.map(id.value, {
|
|
53
53
|
center: props.center,
|
|
54
54
|
zoom: props.zoom,
|
|
55
55
|
zoomControl: props.zoomControl,
|
|
56
56
|
})
|
|
57
57
|
|
|
58
|
-
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18, }).addTo(map)
|
|
58
|
+
L.value.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18, }).addTo(map.value)
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
async function addMarker(marker: MapMarker) {
|
|
63
63
|
const iconSVG = props.markerIcon || defaultMarkerSVG
|
|
64
|
-
const icon = L?.icon({
|
|
64
|
+
const icon = L.value?.icon({
|
|
65
65
|
iconUrl: `data:image/svg+xml;utf8,${encodeURIComponent(iconSVG)}`,
|
|
66
66
|
iconSize: [32, 32],
|
|
67
67
|
})
|
|
68
68
|
const latlng = latLangFromMarker(marker)
|
|
69
69
|
const title = Array.isArray(marker) ? marker[2] : marker.title ?? marker.tooltip
|
|
70
70
|
const tooltip = Array.isArray(marker) ? marker[2] : marker.tooltip
|
|
71
|
-
const m = L?.marker(latlng, { title, icon, interactive: true }).addTo(map as Map) as Marker
|
|
72
|
-
if (tooltip) {m.bindTooltip(tooltip, { direction: 'top' })} // Use `bindPopup` if you want a click-to-show label
|
|
71
|
+
const m = L.value?.marker(latlng, { title, icon, interactive: true }).addTo(map.value as Map) as Marker
|
|
72
|
+
if (tooltip) { m.bindTooltip(tooltip, { direction: 'top' }) } // Use `bindPopup` if you want a click-to-show label
|
|
73
73
|
m.on('click', () => { emit('select', marker) })
|
|
74
74
|
|
|
75
|
-
_markers.push(m)
|
|
75
|
+
_markers.value.push(m)
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
function fitMarkers(L: any) {
|
|
79
|
-
if (
|
|
80
|
-
const latLngs = _markers.map(marker => marker.getLatLng())
|
|
79
|
+
if (_markers.value.length > 0) {
|
|
80
|
+
const latLngs = _markers.value.map(marker => marker.getLatLng())
|
|
81
81
|
const bounds = L.latLngBounds(latLngs)
|
|
82
82
|
const center = bounds.getCenter()
|
|
83
|
-
map?.setView(center, props.zoom)
|
|
84
|
-
map?.fitBounds(bounds, {
|
|
83
|
+
map.value?.setView(center, props.zoom)
|
|
84
|
+
map.value?.fitBounds(bounds, {
|
|
85
85
|
animate: true,
|
|
86
86
|
padding: [20, 20], // Adjust padding as needed
|
|
87
87
|
})
|
|
@@ -96,19 +96,19 @@ function latLangFromMarker(marker: MapMarker): LatLngExpression {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
async function watchMarkers(markers?: MapMarker[]) {
|
|
99
|
-
if (!L) {L = await loadGlobalL()}
|
|
100
|
-
_markers.forEach(marker => marker.remove())
|
|
101
|
-
if (!markers) {return}
|
|
99
|
+
if (!L.value) { L.value = await loadGlobalL() }
|
|
100
|
+
_markers.value.forEach(marker => marker.remove())
|
|
101
|
+
if (!markers) { return }
|
|
102
102
|
|
|
103
103
|
for (const marker of markers) {
|
|
104
|
-
if (!map) {await initializeMap()}
|
|
104
|
+
if (!map.value) { await initializeMap() }
|
|
105
105
|
addMarker(marker)
|
|
106
106
|
}
|
|
107
|
-
fitMarkers(L)
|
|
107
|
+
fitMarkers(L.value)
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
watch(() => props.markers, watchMarkers, { immediate: true })
|
|
111
|
-
watch(() => props.center, center => map?.setView(center, props.zoom), { immediate: true })
|
|
111
|
+
watch(() => props.center, center => map.value?.setView(center, props.zoom), { immediate: true })
|
|
112
112
|
|
|
113
113
|
onMounted(initializeMap)
|
|
114
114
|
</script>
|
package/src/components/Modal.vue
CHANGED
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
Title
|
|
8
8
|
} from '@bagelink/vue'
|
|
9
9
|
import {
|
|
10
|
+
computed,
|
|
11
|
+
ref,
|
|
10
12
|
useSlots,
|
|
11
13
|
watch
|
|
12
14
|
} from 'vue'
|
|
@@ -36,19 +38,19 @@ const emit = defineEmits(['update:visible'])
|
|
|
36
38
|
|
|
37
39
|
const slots: SetupContext['slots'] = useSlots()
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
const isVisible = ref<boolean>(false)
|
|
40
42
|
|
|
41
43
|
watch(
|
|
42
44
|
() => props.visible,
|
|
43
45
|
(val) => {
|
|
44
|
-
if (val === isVisible || val === undefined) { return }
|
|
46
|
+
if (val === isVisible.value || val === undefined) { return }
|
|
45
47
|
if (val) { openModal() }
|
|
46
48
|
else { closeModal() }
|
|
47
49
|
},
|
|
48
50
|
{ immediate: true },
|
|
49
51
|
)
|
|
50
52
|
|
|
51
|
-
const maxWidth =
|
|
53
|
+
const maxWidth = computed(() => {
|
|
52
54
|
const { width } = props
|
|
53
55
|
if (width?.match(/px|em|rem|vw|vh|%/)) { return { 'max-width': width } }
|
|
54
56
|
if (width?.match(/\d+/)) { return { 'max-width': `${width}px` } }
|
|
@@ -56,24 +58,24 @@ const maxWidth = $computed(() => {
|
|
|
56
58
|
})
|
|
57
59
|
|
|
58
60
|
// Computed properties for close button placement
|
|
59
|
-
const isOverlay =
|
|
60
|
-
const isHeader =
|
|
61
|
-
const isFooter =
|
|
61
|
+
const isOverlay = computed(() => props.closePlacement === 'overlay' || props.closePlacement === 'overlay-end')
|
|
62
|
+
const isHeader = computed(() => props.closePlacement === 'header' || props.closePlacement === 'header-end')
|
|
63
|
+
const isFooter = computed(() => props.closePlacement === 'footer')
|
|
62
64
|
|
|
63
|
-
const overlayCloseClass =
|
|
65
|
+
const overlayCloseClass = computed(() => {
|
|
64
66
|
if (props.closePlacement === 'overlay-end') { return 'top-1 end-1' }
|
|
65
67
|
return 'top-1 start-1'
|
|
66
68
|
})
|
|
67
69
|
|
|
68
70
|
function closeModal() {
|
|
69
|
-
isVisible = false
|
|
71
|
+
isVisible.value = false
|
|
70
72
|
setTimeout(() => { emit('update:visible', false) }, 200)
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
defineExpose({ closeModal })
|
|
74
76
|
|
|
75
77
|
function openModal() {
|
|
76
|
-
setTimeout(() => (isVisible = true), 1)
|
|
78
|
+
setTimeout(() => (isVisible.value = true), 1)
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
// Note: ESC key handling is now done centrally in ModalPlugin for proper stacking behavior
|
|
@@ -3,6 +3,7 @@ import type { Path } from '@bagelink/vue'
|
|
|
3
3
|
import type { ComponentExposed } from 'vue-component-type-helpers'
|
|
4
4
|
import type { ModalFormOptions } from '../plugins/modalTypes'
|
|
5
5
|
import { Btn, Modal, useBagel, BagelForm } from '@bagelink/vue'
|
|
6
|
+
import { ref } from 'vue'
|
|
6
7
|
|
|
7
8
|
// eslint-disable-next-line vue/prop-name-casing
|
|
8
9
|
const props = withDefaults(defineProps<ModalFormOptions<T>>(), {
|
|
@@ -17,7 +18,7 @@ const emit = defineEmits<{
|
|
|
17
18
|
|
|
18
19
|
const bagel = useBagel()
|
|
19
20
|
|
|
20
|
-
const modal =
|
|
21
|
+
const modal = ref<ComponentExposed<typeof Modal>>()
|
|
21
22
|
|
|
22
23
|
const formData = defineModel<T>('modelValue', {
|
|
23
24
|
default: {} as Partial<T>,
|
|
@@ -25,20 +26,20 @@ const formData = defineModel<T>('modelValue', {
|
|
|
25
26
|
|
|
26
27
|
type BagelFormT = ComponentExposed<typeof BagelForm<T, P>>
|
|
27
28
|
|
|
28
|
-
const form =
|
|
29
|
-
const closeModal = () => modal?.closeModal()
|
|
29
|
+
const form = ref<BagelFormT>()
|
|
30
|
+
const closeModal = () => modal.value?.closeModal()
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
const submitting = ref(false)
|
|
32
33
|
|
|
33
34
|
async function runSubmit() {
|
|
34
|
-
if (submitting) { return }
|
|
35
|
-
if (form?.validateForm() === false) { return }
|
|
36
|
-
submitting = true
|
|
35
|
+
if (submitting.value) { return }
|
|
36
|
+
if (form.value?.validateForm() === false) { return }
|
|
37
|
+
submitting.value = true
|
|
37
38
|
try {
|
|
38
39
|
await props.onSubmit?.(formData.value)
|
|
39
40
|
closeModal()
|
|
40
41
|
} catch (err: any) {
|
|
41
|
-
submitting = false
|
|
42
|
+
submitting.value = false
|
|
42
43
|
if (props.onError) { props.onError(err) }
|
|
43
44
|
else { bagel.onError?.(err) }
|
|
44
45
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import type { IconType, NavLink } from '@bagelink/vue'
|
|
3
3
|
import { Icon } from '@bagelink/vue'
|
|
4
|
-
import { onMounted } from 'vue'
|
|
4
|
+
import { onMounted, ref } from 'vue'
|
|
5
5
|
|
|
6
6
|
withDefaults(
|
|
7
7
|
defineProps<{
|
|
@@ -20,18 +20,18 @@ withDefaults(
|
|
|
20
20
|
}
|
|
21
21
|
)
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
const isOpen = ref(true)
|
|
24
24
|
|
|
25
25
|
function calcIsOpen() {
|
|
26
|
-
isOpen =
|
|
26
|
+
isOpen.value = window.innerWidth < 1100
|
|
27
27
|
|
|
28
28
|
const storedNavOpenVal = localStorage.getItem('navOpen')
|
|
29
|
-
if ('true'
|
|
29
|
+
if (storedNavOpenVal === 'true' || storedNavOpenVal === null) { isOpen.value = true }
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
function toggleMenu() {
|
|
33
|
-
isOpen = !isOpen
|
|
34
|
-
localStorage.setItem('navOpen', `${isOpen}`)
|
|
33
|
+
isOpen.value = !isOpen.value
|
|
34
|
+
localStorage.setItem('navOpen', `${isOpen.value}`)
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
onMounted(calcIsOpen)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { Btn } from '@bagelink/vue'
|
|
3
|
-
import { watch, nextTick } from 'vue'
|
|
3
|
+
import { computed, ref, watch, nextTick } from 'vue'
|
|
4
4
|
|
|
5
5
|
interface Range {
|
|
6
6
|
start: number
|
|
@@ -28,13 +28,13 @@ const props = withDefaults(defineProps<PaginationProps>(), {
|
|
|
28
28
|
const page = defineModel<number>('page', { default: 1 })
|
|
29
29
|
const range = defineModel<Range>('range')
|
|
30
30
|
|
|
31
|
-
const paginationContainer =
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
const paginationContainer = ref<HTMLElement>()
|
|
32
|
+
const indicatorPosition = ref(0)
|
|
33
|
+
const indicatorWidth = ref(0)
|
|
34
34
|
|
|
35
35
|
// Calculate totalPages from totalItems and perPage if not provided directly
|
|
36
|
-
const computedTotalPages =
|
|
37
|
-
if (props.totalPages !== undefined) {return props.totalPages}
|
|
36
|
+
const computedTotalPages = computed(() => {
|
|
37
|
+
if (props.totalPages !== undefined) { return props.totalPages }
|
|
38
38
|
const { perPage } = props
|
|
39
39
|
return Math.max(1, Math.ceil(props.totalItems / perPage))
|
|
40
40
|
})
|
|
@@ -59,12 +59,12 @@ watch(
|
|
|
59
59
|
watch(() => props.rtl, updateIndicatorPosition)
|
|
60
60
|
|
|
61
61
|
// Calculate which page numbers to show
|
|
62
|
-
const visiblePages =
|
|
62
|
+
const visiblePages = computed(() => {
|
|
63
63
|
const { maxVisiblePages } = props
|
|
64
64
|
|
|
65
65
|
// If we have few enough pages, show all of them
|
|
66
|
-
if (computedTotalPages <= maxVisiblePages * 2) {
|
|
67
|
-
return Array.from({ length: computedTotalPages }, (_, i) => i + 1)
|
|
66
|
+
if (computedTotalPages.value <= maxVisiblePages * 2) {
|
|
67
|
+
return Array.from({ length: computedTotalPages.value }, (_, i) => i + 1)
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
// Always include current page and adjacent pages for navigation
|
|
@@ -74,12 +74,12 @@ const visiblePages = $computed(() => {
|
|
|
74
74
|
mustInclude.add(page.value)
|
|
75
75
|
|
|
76
76
|
// Ensure adjacent pages are included for navigation
|
|
77
|
-
if (
|
|
78
|
-
if (page.value < computedTotalPages) {mustInclude.add(page.value + 1)}
|
|
77
|
+
if (page.value > 1) { mustInclude.add(page.value - 1) }
|
|
78
|
+
if (page.value < computedTotalPages.value) { mustInclude.add(page.value + 1) }
|
|
79
79
|
|
|
80
80
|
// Always include first and last pages
|
|
81
81
|
mustInclude.add(1)
|
|
82
|
-
mustInclude.add(computedTotalPages)
|
|
82
|
+
mustInclude.add(computedTotalPages.value)
|
|
83
83
|
|
|
84
84
|
// Start with explicitly required pages
|
|
85
85
|
const pageArray = Array.from(mustInclude).sort((a, b) => a - b)
|
|
@@ -91,7 +91,7 @@ const visiblePages = $computed(() => {
|
|
|
91
91
|
const current = pageArray[i]
|
|
92
92
|
const next = pageArray[i + 1]
|
|
93
93
|
|
|
94
|
-
if (
|
|
94
|
+
if (next - current > 1) {
|
|
95
95
|
// There's a gap - fill in additional pages
|
|
96
96
|
const pagesToAdd = Math.min(next - current - 1, maxVisiblePages + 2 - pageArray.length)
|
|
97
97
|
|
|
@@ -110,30 +110,30 @@ const visiblePages = $computed(() => {
|
|
|
110
110
|
})
|
|
111
111
|
|
|
112
112
|
function updateIndicatorPosition() {
|
|
113
|
-
if (!paginationContainer) {return}
|
|
113
|
+
if (!paginationContainer.value) { return }
|
|
114
114
|
|
|
115
|
-
const selectedButton = paginationContainer.querySelector('.selected')
|
|
116
|
-
if (!selectedButton) {return}
|
|
115
|
+
const selectedButton = paginationContainer.value.querySelector('.selected')
|
|
116
|
+
if (!selectedButton) { return }
|
|
117
117
|
|
|
118
|
-
const containerRect = paginationContainer.getBoundingClientRect()
|
|
118
|
+
const containerRect = paginationContainer.value.getBoundingClientRect()
|
|
119
119
|
const buttonRect = selectedButton.getBoundingClientRect()
|
|
120
120
|
|
|
121
121
|
// Get position and dimensions
|
|
122
|
-
indicatorWidth = buttonRect.width
|
|
122
|
+
indicatorWidth.value = buttonRect.width
|
|
123
123
|
|
|
124
124
|
if (props.rtl) {
|
|
125
125
|
// RTL positioning - align to right edge
|
|
126
126
|
const rightOffset = containerRect.right - buttonRect.right
|
|
127
|
-
indicatorPosition = rightOffset
|
|
127
|
+
indicatorPosition.value = rightOffset
|
|
128
128
|
} else {
|
|
129
129
|
// LTR positioning - align to left edge
|
|
130
130
|
const leftOffset = buttonRect.left - containerRect.left
|
|
131
|
-
indicatorPosition = leftOffset
|
|
131
|
+
indicatorPosition.value = leftOffset
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
function handleClick(p: number) {
|
|
136
|
-
if (
|
|
136
|
+
if (p < 1 || p > computedTotalPages.value) { return }
|
|
137
137
|
page.value = p
|
|
138
138
|
}
|
|
139
139
|
|
|
@@ -157,16 +157,16 @@ interface PageItem {
|
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
// Enhanced rendering - creates UI with ellipses in the right positions
|
|
160
|
-
const renderPageButtons =
|
|
160
|
+
const renderPageButtons = computed(() => {
|
|
161
161
|
const items: PageItem[] = []
|
|
162
162
|
|
|
163
|
-
for (let i = 0; i < visiblePages.length; i++) {
|
|
164
|
-
const pageNum = visiblePages[i]
|
|
163
|
+
for (let i = 0; i < visiblePages.value.length; i++) {
|
|
164
|
+
const pageNum = visiblePages.value[i]
|
|
165
165
|
|
|
166
166
|
// Insert ellipsis before this page if needed
|
|
167
|
-
if (
|
|
168
|
-
const prevPage = visiblePages[i - 1]
|
|
169
|
-
if (
|
|
167
|
+
if (i > 0) {
|
|
168
|
+
const prevPage = visiblePages.value[i - 1]
|
|
169
|
+
if (pageNum - prevPage > 1) {
|
|
170
170
|
items.push({
|
|
171
171
|
type: 'ellipsis',
|
|
172
172
|
key: `ellipsis-${i}`
|
package/src/components/Pill.vue
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import type { IconType, ThemeType } from '@bagelink/vue'
|
|
3
3
|
import type { SetupContext } from 'vue'
|
|
4
4
|
import { Btn, Icon } from '@bagelink/vue'
|
|
5
|
-
import { useSlots } from 'vue'
|
|
5
|
+
import { computed, useSlots } from 'vue'
|
|
6
6
|
|
|
7
7
|
interface BtnProp {
|
|
8
8
|
icon?: IconType
|
|
@@ -31,23 +31,23 @@ const props = defineProps<{
|
|
|
31
31
|
|
|
32
32
|
const slots: SetupContext['slots'] = useSlots()
|
|
33
33
|
|
|
34
|
-
const computedTheme =
|
|
34
|
+
const computedTheme = computed(
|
|
35
35
|
() => {
|
|
36
|
-
if (props.disabled) {return 'gray-light'}
|
|
36
|
+
if (props.disabled) { return 'gray-light' }
|
|
37
37
|
return (props.color || props.theme) as ThemeType
|
|
38
38
|
},
|
|
39
39
|
)
|
|
40
40
|
|
|
41
|
-
const computedDefaultColors =
|
|
41
|
+
const computedDefaultColors = computed(
|
|
42
42
|
() => ({
|
|
43
43
|
backgroundColor: 'var(--bgl-primary)',
|
|
44
44
|
color: props.flat ? 'var(--bgl-text-color)' : 'var(--bgl-light-text)',
|
|
45
45
|
}),
|
|
46
46
|
)
|
|
47
47
|
|
|
48
|
-
function getThemeColors(theme: Partial<typeof computedDefaultColors>): typeof computedDefaultColors {
|
|
48
|
+
function getThemeColors(theme: Partial<typeof computedDefaultColors.value>): typeof computedDefaultColors.value {
|
|
49
49
|
return {
|
|
50
|
-
...computedDefaultColors,
|
|
50
|
+
...computedDefaultColors.value,
|
|
51
51
|
...theme,
|
|
52
52
|
color: props.flat
|
|
53
53
|
? theme.backgroundColor as string
|
|
@@ -55,7 +55,7 @@ function getThemeColors(theme: Partial<typeof computedDefaultColors>): typeof co
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
const themes: Partial<Record<string, typeof computedDefaultColors>> = {
|
|
58
|
+
const themes: Partial<Record<string, typeof computedDefaultColors.value>> = {
|
|
59
59
|
// Base Colors
|
|
60
60
|
'blue': getThemeColors({ backgroundColor: 'var(--bgl-blue)', color: 'var(--bgl-white)' }),
|
|
61
61
|
'green': getThemeColors({ backgroundColor: 'var(--bgl-green)', color: 'var(--bgl-white)' }),
|
|
@@ -238,7 +238,6 @@ const themes: Partial<Record<string, typeof computedDefaultColors>> = {
|
|
|
238
238
|
'black-130': getThemeColors({ backgroundColor: 'var(--bgl-black-130)', color: 'var(--bgl-white)' }),
|
|
239
239
|
'pink-130': getThemeColors({ backgroundColor: 'var(--bgl-pink-130)', color: 'var(--bgl-white)' }),
|
|
240
240
|
|
|
241
|
-
|
|
242
241
|
// Legacy light variants (mapped to 20% tints)
|
|
243
242
|
'blue-light': getThemeColors({ backgroundColor: 'var(--bgl-blue-light)', color: 'var(--bgl-blue)' }),
|
|
244
243
|
'green-light': getThemeColors({ backgroundColor: 'var(--bgl-green-light)', color: 'var(--bgl-green)' }),
|
|
@@ -263,12 +262,12 @@ const themes: Partial<Record<string, typeof computedDefaultColors>> = {
|
|
|
263
262
|
'light': getThemeColors({ backgroundColor: 'var(--bgl-primary-light)', color: 'var(--bgl-primary)' }),
|
|
264
263
|
}
|
|
265
264
|
|
|
266
|
-
const cumputedTextColor =
|
|
267
|
-
() => (themes[computedTheme as ThemeType]?.color ?? computedDefaultColors.color),
|
|
265
|
+
const cumputedTextColor = computed(
|
|
266
|
+
() => (themes[computedTheme.value as ThemeType]?.color ?? computedDefaultColors.value.color),
|
|
268
267
|
)
|
|
269
268
|
|
|
270
|
-
const computedBackgroundColor =
|
|
271
|
-
() => (themes[computedTheme as ThemeType]?.backgroundColor ?? computedDefaultColors.backgroundColor),
|
|
269
|
+
const computedBackgroundColor = computed(
|
|
270
|
+
() => (themes[computedTheme.value as ThemeType]?.backgroundColor ?? computedDefaultColors.value.backgroundColor),
|
|
272
271
|
)
|
|
273
272
|
</script>
|
|
274
273
|
|
|
@@ -12,10 +12,10 @@ const { rating, totalStars = 5, iconType = 'star', fillColor = '#fabf05', emptyC
|
|
|
12
12
|
}>()
|
|
13
13
|
|
|
14
14
|
function getFillWidth(n: number): string {
|
|
15
|
-
const ratingNumber = 'string'
|
|
15
|
+
const ratingNumber = typeof rating === 'string' ? Number.parseFloat(rating.replace(',', '.')) : rating
|
|
16
16
|
if (n <= Math.floor(ratingNumber)) {
|
|
17
17
|
return '100%'
|
|
18
|
-
}if (n > Math.ceil(ratingNumber)) {
|
|
18
|
+
} if (n > Math.ceil(ratingNumber)) {
|
|
19
19
|
return '0%'
|
|
20
20
|
} else {
|
|
21
21
|
return `${(ratingNumber % 1) * 100}%`
|