@bagelink/vue 1.4.73 → 1.4.77

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bagelink/vue",
3
3
  "type": "module",
4
- "version": "1.4.73",
4
+ "version": "1.4.77",
5
5
  "description": "Bagel core sdk packages",
6
6
  "author": {
7
7
  "name": "Neveh Allon",
@@ -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
- ? originalCount + (2 * perPage.value)
356
- : originalCount
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 - perPage.value; i < originalCount; i++) {
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 (already clones of the slot content)
400
- for (let i = 0; i < originalCount; i++) {
401
- const element = innerElements.value[i]
402
- const wrapped = buildSliderFrameItem(element.cloneNode(true) as Element)
403
- docFragment.appendChild(wrapped)
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 < perPage.value; 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 / (innerElements.value.length + (2 * perPage.value))
510
- : 100 / innerElements.value.length
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 + perPage.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
- = `translate3d(${(config.value.rtl ? 1 : -1) * offset}px, 0, 0)`
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
- = `translate3d(${(config.value.rtl ? 1 : -1) * offset}px, 0, 0)`
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
- :key="i"
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
- position: relative;
1394
- width: 100%;
1414
+ position: relative;
1415
+ width: 100%;
1395
1416
  }
1396
1417
 
1397
1418
  .carousel-container {
1398
- margin: 0 auto;
1399
- overflow: hidden;
1419
+ margin: 0 auto;
1420
+ overflow: hidden;
1400
1421
  }
1401
1422
 
1402
1423
  .carousel-dots {
1403
- display: flex;
1404
- justify-content: center;
1405
- gap: 8px;
1406
- margin-top: 16px;
1424
+ display: flex;
1425
+ justify-content: center;
1426
+ gap: 8px;
1427
+ margin-top: 16px;
1407
1428
  }
1408
1429
 
1409
1430
  .carousel-dot {
1410
- width: 12px;
1411
- height: 12px;
1412
- border-radius: 50px;
1413
- background-color: var(--bgl-gray-light);
1414
- border: none;
1415
- padding: 0;
1416
- cursor: pointer;
1417
- transition: all 0.3s ease-in-out;
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
- background-color: var(--bgl-primary);
1422
- width: 26px;
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 date = new Date(year, month - 1, day)
66
- if (date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day) {
67
- return date
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.toISOString()
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.toISOString()
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
- iconStart="calendar"
167
- :min="formatDisplayDate(min)"
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
- :min="min"
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>