@bagelink/vue 1.4.73 → 1.4.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Card.vue.d.ts +1 -0
- package/dist/components/Card.vue.d.ts.map +1 -1
- package/dist/components/Slider.vue.d.ts.map +1 -1
- package/dist/components/calendar/CalendarPopover.vue.d.ts +6 -0
- package/dist/components/calendar/CalendarPopover.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/DateInput.vue.d.ts.map +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.mjs +3 -3
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/Card.vue +18 -7
- package/src/components/Slider.vue +60 -39
- package/src/components/form/inputs/DateInput.vue +31 -34
package/package.json
CHANGED
package/src/components/Card.vue
CHANGED
|
@@ -5,6 +5,7 @@ const props = defineProps<{
|
|
|
5
5
|
outline?: boolean
|
|
6
6
|
h100?: boolean
|
|
7
7
|
to?: string
|
|
8
|
+
href?: string
|
|
8
9
|
overflowX?: boolean
|
|
9
10
|
overflowY?: boolean
|
|
10
11
|
bg?:
|
|
@@ -21,16 +22,23 @@ const props = defineProps<{
|
|
|
21
22
|
| 'transparent'
|
|
22
23
|
}>()
|
|
23
24
|
|
|
24
|
-
const
|
|
25
|
+
const bind = $computed(() => {
|
|
26
|
+
const obj: { [key: string]: any } = {}
|
|
27
|
+
if (props.href) obj.href = props.href
|
|
28
|
+
else if (props.to) obj.to = props.to
|
|
29
|
+
return obj
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const is = $computed(() => {
|
|
33
|
+
if (props.href) return 'a'
|
|
34
|
+
if (props.to) return 'router-link'
|
|
35
|
+
return 'div'
|
|
36
|
+
})
|
|
25
37
|
</script>
|
|
26
38
|
|
|
27
39
|
<template>
|
|
28
40
|
<component
|
|
29
|
-
:is="is"
|
|
30
|
-
v-ripple="!!to"
|
|
31
|
-
:to="to"
|
|
32
|
-
class="bgl_card"
|
|
33
|
-
:class="{
|
|
41
|
+
:is="is" v-ripple="!!to" v-bind="bind" class="bgl_card" :class="{
|
|
34
42
|
thin,
|
|
35
43
|
'border': outline,
|
|
36
44
|
'h-100': h100,
|
|
@@ -56,10 +64,11 @@ const is = $computed(() => (props.to ? 'router-link' : 'div'))
|
|
|
56
64
|
border-bottom: 1px solid var(--border-color);
|
|
57
65
|
margin-bottom: 1rem;
|
|
58
66
|
}
|
|
67
|
+
|
|
59
68
|
.border .card_label {
|
|
60
69
|
font-size: 0.7rem;
|
|
61
70
|
font-weight: 300;
|
|
62
|
-
background:var(--bgl-box-bg);
|
|
71
|
+
background: var(--bgl-box-bg);
|
|
63
72
|
padding: 0 0.75rem;
|
|
64
73
|
position: absolute;
|
|
65
74
|
top: -0.5rem;
|
|
@@ -89,11 +98,13 @@ const is = $computed(() => (props.to ? 'router-link' : 'div'))
|
|
|
89
98
|
.bgl_card.thin {
|
|
90
99
|
padding: 1rem 1rem;
|
|
91
100
|
}
|
|
101
|
+
|
|
92
102
|
.bgl_card.BagelTable {
|
|
93
103
|
height: 100%;
|
|
94
104
|
overflow: auto;
|
|
95
105
|
padding-top: 0;
|
|
96
106
|
}
|
|
107
|
+
|
|
97
108
|
.bgl_card.thin .tabs {
|
|
98
109
|
margin-bottom: 1rem;
|
|
99
110
|
}
|
|
@@ -351,9 +351,17 @@ function buildSliderFrame(): void {
|
|
|
351
351
|
|
|
352
352
|
const originalCount = innerElements.value.length
|
|
353
353
|
const widthItem = selectorWidth.value / perPage.value
|
|
354
|
+
|
|
355
|
+
// Calculate how many times to repeat items to fill big screens
|
|
356
|
+
const minItemsNeeded = Math.max(perPage.value * 3, 20) // Ensure we have enough content for big screens
|
|
357
|
+
const repetitions = Math.max(1, Math.ceil(minItemsNeeded / originalCount))
|
|
358
|
+
const totalMainItems = originalCount * repetitions
|
|
359
|
+
|
|
360
|
+
// Ultra-aggressive buffer size for really big screens
|
|
361
|
+
const bufferSize = Math.max(perPage.value * 8, 20) // Even more buffer for huge screens
|
|
354
362
|
const itemsToBuild = config.value.loop
|
|
355
|
-
?
|
|
356
|
-
:
|
|
363
|
+
? totalMainItems + (2 * bufferSize)
|
|
364
|
+
: totalMainItems
|
|
357
365
|
|
|
358
366
|
// Create a clean slate for the slider
|
|
359
367
|
carouselRef.value.innerHTML = ''
|
|
@@ -380,7 +388,7 @@ function buildSliderFrame(): void {
|
|
|
380
388
|
|
|
381
389
|
// Add clones before original items (for loop mode)
|
|
382
390
|
if (config.value.loop && innerElements.value.length > 0) {
|
|
383
|
-
for (let i = originalCount -
|
|
391
|
+
for (let i = originalCount - bufferSize; i < originalCount; i++) {
|
|
384
392
|
if (i >= 0 && i < originalCount) {
|
|
385
393
|
const original = innerElements.value[i]
|
|
386
394
|
const clone = original.cloneNode(true) as Element
|
|
@@ -396,16 +404,24 @@ function buildSliderFrame(): void {
|
|
|
396
404
|
}
|
|
397
405
|
}
|
|
398
406
|
|
|
399
|
-
// Add main items
|
|
400
|
-
for (let
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
407
|
+
// Add main items repeated multiple times to fill big screens
|
|
408
|
+
for (let rep = 0; rep < repetitions; rep++) {
|
|
409
|
+
for (let i = 0; i < originalCount; i++) {
|
|
410
|
+
const element = innerElements.value[i]
|
|
411
|
+
const clone = element.cloneNode(true) as Element
|
|
412
|
+
|
|
413
|
+
if (clone instanceof HTMLElement) {
|
|
414
|
+
clone.setAttribute('data-repetition', rep.toString())
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
const wrapped = buildSliderFrameItem(clone)
|
|
418
|
+
docFragment.appendChild(wrapped)
|
|
419
|
+
}
|
|
404
420
|
}
|
|
405
421
|
|
|
406
422
|
// Add clones after original items (for loop mode)
|
|
407
423
|
if (config.value.loop && innerElements.value.length > 0) {
|
|
408
|
-
for (let i = 0; i <
|
|
424
|
+
for (let i = 0; i < bufferSize; i++) {
|
|
409
425
|
if (i >= 0 && i < originalCount) {
|
|
410
426
|
const original = innerElements.value[i]
|
|
411
427
|
const clone = original.cloneNode(true) as Element
|
|
@@ -505,9 +521,17 @@ function buildSliderFrameItem(elm: Element): HTMLElement {
|
|
|
505
521
|
elementContainer.style.float = config.value.rtl ? 'right' : 'left'
|
|
506
522
|
elementContainer.style.padding = config.value.slideGap ? `${config.value.slideGap / 2}rem` : '0'
|
|
507
523
|
|
|
524
|
+
// Calculate total items including repetitions for big screens
|
|
525
|
+
const originalCount = innerElements.value.length
|
|
526
|
+
const minItemsNeeded = Math.max(perPage.value * 3, 20)
|
|
527
|
+
const repetitions = Math.max(1, Math.ceil(minItemsNeeded / originalCount))
|
|
528
|
+
const totalMainItems = originalCount * repetitions
|
|
529
|
+
|
|
530
|
+
// Ultra-aggressive buffer size - must match buildSliderFrame buffer size
|
|
531
|
+
const itemBufferSize = Math.max(perPage.value * 8, 20) // Even more buffer for huge screens
|
|
508
532
|
const percentage = config.value.loop
|
|
509
|
-
? 100 / (
|
|
510
|
-
: 100 /
|
|
533
|
+
? 100 / (totalMainItems + (2 * itemBufferSize))
|
|
534
|
+
: 100 / totalMainItems
|
|
511
535
|
|
|
512
536
|
elementContainer.style.width = `${percentage}%`
|
|
513
537
|
elementContainer.appendChild(elm)
|
|
@@ -519,8 +543,10 @@ function slideToCurrent(enableTransitionFlag?: boolean): void {
|
|
|
519
543
|
// Ensure component is still mounted
|
|
520
544
|
if (!isMounted.value || !innerElements.value.length || !sliderFrame.value) return
|
|
521
545
|
|
|
546
|
+
// Ultra-aggressive buffer size - must match buildSliderFrame buffer size
|
|
547
|
+
const slideBufferSize = Math.max(perPage.value * 8, 20) // Even more buffer for huge screens
|
|
522
548
|
const currentSlideValue = config.value.loop
|
|
523
|
-
? currentSlide.value +
|
|
549
|
+
? currentSlide.value + slideBufferSize
|
|
524
550
|
: currentSlide.value
|
|
525
551
|
|
|
526
552
|
const offset = (config.value.rtl ? 1 : -1) * currentSlideValue * (selectorWidth.value / perPage.value)
|
|
@@ -834,7 +860,7 @@ function touchmoveHandler(e: TouchEvent): void {
|
|
|
834
860
|
: currentOffset - dragOffset
|
|
835
861
|
|
|
836
862
|
sliderFrame.value.style[transformProperty.value as any]
|
|
837
|
-
|
|
863
|
+
= `translate3d(${(config.value.rtl ? 1 : -1) * offset}px, 0, 0)`
|
|
838
864
|
}
|
|
839
865
|
}
|
|
840
866
|
}
|
|
@@ -972,7 +998,7 @@ function mousemoveHandler(e: MouseEvent): void {
|
|
|
972
998
|
: currentOffset - dragOffset
|
|
973
999
|
|
|
974
1000
|
sliderFrame.value.style[transformProperty.value as any]
|
|
975
|
-
|
|
1001
|
+
= `translate3d(${(config.value.rtl ? 1 : -1) * offset}px, 0, 0)`
|
|
976
1002
|
}
|
|
977
1003
|
}
|
|
978
1004
|
}
|
|
@@ -1373,16 +1399,11 @@ defineExpose({
|
|
|
1373
1399
|
<div ref="carouselRef" class="carousel-container">
|
|
1374
1400
|
<!-- We'll populate this with cloned content programmatically -->
|
|
1375
1401
|
</div>
|
|
1376
|
-
|
|
1377
1402
|
<!-- Dots navigation (Vue-managed) -->
|
|
1378
1403
|
<div v-if="props.dots && totalDots > 1" class="carousel-dots">
|
|
1379
1404
|
<button
|
|
1380
|
-
v-for="i in totalDots"
|
|
1381
|
-
:
|
|
1382
|
-
type="button"
|
|
1383
|
-
class="carousel-dot" :class="[{ active: (i - 1) === currentSlide }]"
|
|
1384
|
-
:aria-label="`Go to slide ${i}`"
|
|
1385
|
-
@click="goTo(i - 1)"
|
|
1405
|
+
v-for="i in totalDots" :key="i" type="button" class="carousel-dot"
|
|
1406
|
+
:class="[{ active: (i - 1) === currentSlide }]" :aria-label="`Go to slide ${i}`" @click="goTo(i - 1)"
|
|
1386
1407
|
/>
|
|
1387
1408
|
</div>
|
|
1388
1409
|
</div>
|
|
@@ -1390,35 +1411,35 @@ defineExpose({
|
|
|
1390
1411
|
|
|
1391
1412
|
<style scoped>
|
|
1392
1413
|
.carousel-wrapper {
|
|
1393
|
-
|
|
1394
|
-
|
|
1414
|
+
position: relative;
|
|
1415
|
+
width: 100%;
|
|
1395
1416
|
}
|
|
1396
1417
|
|
|
1397
1418
|
.carousel-container {
|
|
1398
|
-
|
|
1399
|
-
|
|
1419
|
+
margin: 0 auto;
|
|
1420
|
+
overflow: hidden;
|
|
1400
1421
|
}
|
|
1401
1422
|
|
|
1402
1423
|
.carousel-dots {
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1424
|
+
display: flex;
|
|
1425
|
+
justify-content: center;
|
|
1426
|
+
gap: 8px;
|
|
1427
|
+
margin-top: 16px;
|
|
1407
1428
|
}
|
|
1408
1429
|
|
|
1409
1430
|
.carousel-dot {
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1431
|
+
width: 12px;
|
|
1432
|
+
height: 12px;
|
|
1433
|
+
border-radius: 50px;
|
|
1434
|
+
background-color: var(--bgl-gray-light);
|
|
1435
|
+
border: none;
|
|
1436
|
+
padding: 0;
|
|
1437
|
+
cursor: pointer;
|
|
1438
|
+
transition: all 0.3s ease-in-out;
|
|
1418
1439
|
}
|
|
1419
1440
|
|
|
1420
1441
|
.carousel-dot.active {
|
|
1421
|
-
|
|
1422
|
-
|
|
1442
|
+
background-color: var(--bgl-primary);
|
|
1443
|
+
width: 26px;
|
|
1423
1444
|
}
|
|
1424
1445
|
</style>
|
|
@@ -62,9 +62,13 @@ function useFormatting() {
|
|
|
62
62
|
if (parts.length === 3) {
|
|
63
63
|
const [day, month, year] = parts.map(p => Number.parseInt(p, 10))
|
|
64
64
|
if (!Number.isNaN(day) && !Number.isNaN(month) && !Number.isNaN(year)) {
|
|
65
|
-
const
|
|
66
|
-
if (
|
|
67
|
-
|
|
65
|
+
const parsedDate = new Date(year, month - 1, day)
|
|
66
|
+
if (
|
|
67
|
+
parsedDate.getFullYear() === year
|
|
68
|
+
&& parsedDate.getMonth() === month - 1
|
|
69
|
+
&& parsedDate.getDate() === day
|
|
70
|
+
) {
|
|
71
|
+
return parsedDate
|
|
68
72
|
}
|
|
69
73
|
}
|
|
70
74
|
}
|
|
@@ -72,14 +76,27 @@ function useFormatting() {
|
|
|
72
76
|
return null
|
|
73
77
|
}
|
|
74
78
|
|
|
79
|
+
const normalizeDate = (date: Date): string => {
|
|
80
|
+
if (props.enableTime) {
|
|
81
|
+
// Keep the time when time is enabled
|
|
82
|
+
return date.toISOString()
|
|
83
|
+
} else {
|
|
84
|
+
// Normalize to midnight to emit exact date without time for server compatibility
|
|
85
|
+
const normalizedDate = new Date(date)
|
|
86
|
+
normalizedDate.setHours(0, 0, 0, 0)
|
|
87
|
+
return normalizedDate.toISOString().split('T')[0]
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
75
91
|
return {
|
|
76
92
|
formatDisplayDate,
|
|
77
|
-
parseUserInput
|
|
93
|
+
parseUserInput,
|
|
94
|
+
normalizeDate
|
|
78
95
|
}
|
|
79
96
|
}
|
|
80
97
|
|
|
81
98
|
// Initialize formatting
|
|
82
|
-
const { formatDisplayDate, parseUserInput } = useFormatting()
|
|
99
|
+
const { formatDisplayDate, parseUserInput, normalizeDate } = useFormatting()
|
|
83
100
|
|
|
84
101
|
// Input handling composable
|
|
85
102
|
function useInputHandling() {
|
|
@@ -91,7 +108,7 @@ function useInputHandling() {
|
|
|
91
108
|
|
|
92
109
|
const date = parseUserInput(input.value)
|
|
93
110
|
if (date) {
|
|
94
|
-
selectedDate.value = date
|
|
111
|
+
selectedDate.value = normalizeDate(date)
|
|
95
112
|
}
|
|
96
113
|
}
|
|
97
114
|
|
|
@@ -112,7 +129,7 @@ function useInputHandling() {
|
|
|
112
129
|
} else if (event.key === 'Enter' && inputValue.value) {
|
|
113
130
|
const date = parseUserInput(inputValue.value)
|
|
114
131
|
if (date) {
|
|
115
|
-
selectedDate.value = date
|
|
132
|
+
selectedDate.value = normalizeDate(date)
|
|
116
133
|
isOpen.value = false
|
|
117
134
|
}
|
|
118
135
|
}
|
|
@@ -153,43 +170,23 @@ onMounted(() => {
|
|
|
153
170
|
{{ label }}
|
|
154
171
|
<span v-if="required" class="required">*</span>
|
|
155
172
|
</label>
|
|
156
|
-
<Dropdown
|
|
157
|
-
:shown="isOpen"
|
|
158
|
-
placement="bottom-start"
|
|
159
|
-
:autoHide="false"
|
|
160
|
-
:triggers="['click']"
|
|
161
|
-
>
|
|
173
|
+
<Dropdown :shown="isOpen" placement="bottom-start" :autoHide="false" :triggers="['click']">
|
|
162
174
|
<template #trigger>
|
|
163
175
|
<div ref="datePickerRef" class="date-picker-container" @mousedown.stop @click.stop>
|
|
164
176
|
<TextInput
|
|
165
|
-
:modelValue="formatDisplayDate(selectedDate)"
|
|
166
|
-
|
|
167
|
-
:
|
|
168
|
-
:max="formatDisplayDate(max)"
|
|
169
|
-
:required="required"
|
|
170
|
-
:disabled="!editMode"
|
|
171
|
-
class="date-input m-0"
|
|
172
|
-
:class="{
|
|
177
|
+
:modelValue="formatDisplayDate(selectedDate)" iconStart="calendar"
|
|
178
|
+
:min="formatDisplayDate(min)" :max="formatDisplayDate(max)" :required="required"
|
|
179
|
+
:disabled="!editMode" class="date-input m-0" :class="{
|
|
173
180
|
'txt-center': center,
|
|
174
|
-
}"
|
|
175
|
-
:readonly="false"
|
|
176
|
-
@input="handleInput"
|
|
177
|
-
@focus="handleFocus"
|
|
178
|
-
@click="handleClick"
|
|
179
|
-
@keydown="handleKeydown"
|
|
181
|
+
}" :readonly="false" @input="handleInput" @focus="handleFocus" @click="handleClick" @keydown="handleKeydown"
|
|
180
182
|
/>
|
|
181
183
|
</div>
|
|
182
184
|
</template>
|
|
183
185
|
|
|
184
186
|
<div ref="calendarRef" @click.stop>
|
|
185
187
|
<DatePicker
|
|
186
|
-
v-model="selectedDate"
|
|
187
|
-
:
|
|
188
|
-
:max="max"
|
|
189
|
-
:mode="mode"
|
|
190
|
-
:firstDayOfWeek="firstDayOfWeek"
|
|
191
|
-
:locale="locale"
|
|
192
|
-
:enableTime="enableTime"
|
|
188
|
+
v-model="selectedDate" :min="min" :max="max" :mode="mode" :firstDayOfWeek="firstDayOfWeek"
|
|
189
|
+
:locale="locale" :enableTime="enableTime"
|
|
193
190
|
/>
|
|
194
191
|
</div>
|
|
195
192
|
</Dropdown>
|