@bagelink/vue 1.2.33 → 1.2.41

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.
Files changed (46) hide show
  1. package/dist/components/calendar/CalendarPopover.vue.d.ts +179 -0
  2. package/dist/components/calendar/CalendarPopover.vue.d.ts.map +1 -0
  3. package/dist/components/calendar/CalendarTypes.d.ts +15 -0
  4. package/dist/components/calendar/CalendarTypes.d.ts.map +1 -1
  5. package/dist/components/calendar/Index.vue.d.ts +21 -12
  6. package/dist/components/calendar/Index.vue.d.ts.map +1 -1
  7. package/dist/components/calendar/views/AgendaView.vue.d.ts +8 -0
  8. package/dist/components/calendar/views/AgendaView.vue.d.ts.map +1 -1
  9. package/dist/components/calendar/views/CalendarPopover.vue.d.ts +175 -0
  10. package/dist/components/calendar/views/CalendarPopover.vue.d.ts.map +1 -0
  11. package/dist/components/calendar/views/DayView.vue.d.ts +10 -32
  12. package/dist/components/calendar/views/DayView.vue.d.ts.map +1 -1
  13. package/dist/components/calendar/views/MonthView.vue.d.ts +10 -170
  14. package/dist/components/calendar/views/MonthView.vue.d.ts.map +1 -1
  15. package/dist/components/calendar/views/WeekView.vue.d.ts +12 -168
  16. package/dist/components/calendar/views/WeekView.vue.d.ts.map +1 -1
  17. package/dist/components/form/inputs/DateInput.vue.d.ts.map +1 -1
  18. package/dist/components/form/inputs/DatePicker.vue.d.ts.map +1 -1
  19. package/dist/composables/useDevice.d.ts +3 -0
  20. package/dist/composables/useDevice.d.ts.map +1 -1
  21. package/dist/index.cjs +446 -309
  22. package/dist/index.mjs +446 -309
  23. package/dist/style.css +231 -179
  24. package/dist/types/BagelForm.d.ts +14 -11
  25. package/dist/types/BagelForm.d.ts.map +1 -1
  26. package/dist/utils/BagelFormUtils.d.ts +10 -10
  27. package/dist/utils/BagelFormUtils.d.ts.map +1 -1
  28. package/dist/utils/calendar/dateUtils.d.ts +10 -10
  29. package/dist/utils/calendar/dateUtils.d.ts.map +1 -1
  30. package/package.json +1 -1
  31. package/src/components/calendar/CalendarPopover.vue +102 -0
  32. package/src/components/calendar/CalendarTypes.ts +14 -0
  33. package/src/components/calendar/Index.vue +77 -35
  34. package/src/components/calendar/views/AgendaView.vue +26 -2
  35. package/src/components/calendar/views/DayView.vue +83 -104
  36. package/src/components/calendar/views/MonthView.vue +39 -67
  37. package/src/components/calendar/views/WeekView.vue +229 -136
  38. package/src/components/form/inputs/DateInput.vue +14 -3
  39. package/src/components/form/inputs/DatePicker.vue +7 -0
  40. package/src/composables/useDevice.ts +13 -2
  41. package/src/styles/layout.css +14 -0
  42. package/src/styles/mobilLayout.css +12 -0
  43. package/src/types/BagelForm.ts +30 -53
  44. package/src/utils/BagelFormUtils.ts +11 -10
  45. package/src/utils/calendar/dateUtils.ts +42 -45
  46. package/src/components/calendar/utils.ts +0 -70
@@ -1,13 +1,8 @@
1
1
  <script setup lang="ts">
2
- import type { SetupContext } from 'vue'
2
+ import type { SetupContext, ComponentPublicInstance } from 'vue'
3
3
  import type { CalendarEvent, WeekStart } from '../CalendarTypes'
4
- import type { PopoverState } from '../utils'
5
- import { Card, fmtDate } from '@bagelink/vue'
4
+ import { formatDate } from '@bagelink/vue'
6
5
  import { ref, computed, onMounted, onUnmounted, useSlots } from 'vue'
7
- import {
8
- openPopover as openPopoverUtil,
9
- closePopover as closePopoverUtil,
10
- } from '../utils'
11
6
 
12
7
  interface WeekViewEvent extends CalendarEvent {
13
8
  top: number
@@ -31,6 +26,7 @@ const props = withDefaults(defineProps<{
31
26
  const emit = defineEmits<{
32
27
  (e: 'eventClick', event: CalendarEvent): void
33
28
  (e: 'eventCreate', event: { start_time: Date, end_time: Date }): void
29
+ (e: 'openPopover', event: CalendarEvent, position?: { top: number, left: number }): void
34
30
  }>()
35
31
 
36
32
  const slots: SetupContext['slots'] = useSlots()
@@ -43,29 +39,23 @@ const timeRange = { start: 0, end: 24 }
43
39
  // Drag state
44
40
  const dragState = ref({
45
41
  isDragging: false,
46
- start: null as { x: number, y: number } | null,
47
- end: null as { x: number, y: number } | null,
48
- startTime: null as Date | null,
49
- endTime: null as Date | null
42
+ startDay: -1, // Index of the starting day
43
+ endDay: -1, // Index of the ending day
44
+ start: undefined as { x: number, y: number } | undefined,
45
+ end: undefined as { x: number, y: number } | undefined,
46
+ startTime: undefined as Date | undefined,
47
+ endTime: undefined as Date | undefined
50
48
  })
51
49
 
52
- // Popover state
53
- const activeEvent = ref<CalendarEvent | null>(null)
54
- const showPopover = ref(false)
55
- const popoverPosition = ref({ top: 0, left: 0, width: 0, height: 0 })
56
- const popoverRef = ref<HTMLElement | null>(null)
57
-
58
- const popoverState: PopoverState = {
59
- activeEvent,
60
- showPopover,
61
- popoverPosition,
62
- popoverRef
63
- }
64
-
65
50
  // Time indicators
66
51
  const currentTimeTop = ref(0)
67
52
  const isToday = ref(false)
68
- const currentTimeInterval = ref(null as any)
53
+ const currentTimeInterval = ref<any>()
54
+
55
+ const timeSlotsContainer = ref<HTMLElement>()
56
+ const calendarGrid = ref<HTMLElement>()
57
+ const dayColumns = ref<HTMLElement[]>([])
58
+ const dayColumnsContainer = ref<HTMLElement>()
69
59
 
70
60
  // Calculate week days based on start date and week start preference
71
61
  const weekDays = computed(() => {
@@ -76,6 +66,7 @@ const weekDays = computed(() => {
76
66
  // Adjust to start of week
77
67
  const dayOfWeek = start.getDay()
78
68
  start.setDate(start.getDate() - dayOfWeek + weekStartOffset)
69
+ start.setHours(0, 0, 0, 0) // Set time to start of day
79
70
 
80
71
  // Create array of 7 day dates
81
72
  for (let i = 0; i < 7; i++) {
@@ -118,18 +109,18 @@ const processedEvents = computed(() => {
118
109
 
119
110
  if (dayIndex === -1) return
120
111
 
121
- // Calculate vertical positioning
112
+ // Calculate vertical positioning - make sure to use the same formula everywhere
122
113
  const startMinutes = startDate.getHours() * 60 + startDate.getMinutes()
123
114
  const endMinutes = endDate.getHours() * 60 + endDate.getMinutes()
124
- const top = (startMinutes / slotDuration) * (slotHeight / 2)
125
- const height = Math.max(((endMinutes - startMinutes) / slotDuration) * (slotHeight / 2), 30)
115
+ const top = (startMinutes / slotDuration) * slotHeight
116
+ const height = Math.max(((endMinutes - startMinutes) / slotDuration) * slotHeight, 30)
126
117
 
127
118
  const weekEvent: WeekViewEvent = {
128
119
  ...event,
129
120
  top,
130
121
  height,
131
122
  left: 0,
132
- width: 95,
123
+ width: 100,
133
124
  overlappingEvents: 0,
134
125
  position: 0
135
126
  }
@@ -160,23 +151,103 @@ const processedEvents = computed(() => {
160
151
  })
161
152
 
162
153
  // Mouse event handlers for drag-to-create functionality
163
- function handleMouseDown(e: MouseEvent) {
164
- const target = e.target as HTMLElement
165
- if (!target.closest('.time-slot')) return
154
+ function handleMouseDown(e: MouseEvent, day: Date) {
155
+ if (!calendarGrid.value || !dayColumnsContainer.value) return
156
+
157
+ // Find the clicked day column
158
+ let clickedDayIndex = -1
159
+ for (let i = 0; i < dayColumns.value.length; i++) {
160
+ const columnEl = dayColumns.value[i]
161
+ if (!columnEl) continue
162
+
163
+ const rect = columnEl.getBoundingClientRect()
164
+ if (e.clientX >= rect.left && e.clientX <= rect.right) {
165
+ clickedDayIndex = i
166
+ break
167
+ }
168
+ }
169
+
170
+ if (clickedDayIndex === -1) return
171
+
172
+ // Get the clicked day column's position and dimensions
173
+ const dayColumnRect = dayColumns.value[clickedDayIndex].getBoundingClientRect()
174
+ const dayColumnsRect = dayColumnsContainer.value.getBoundingClientRect()
166
175
 
167
176
  dragState.value.isDragging = true
168
- dragState.value.start = { x: e.clientX, y: e.clientY }
169
- dragState.value.startTime = getTimeFromPosition(e.clientX, e.clientY)
177
+ dragState.value.startDay = clickedDayIndex
178
+ dragState.value.endDay = clickedDayIndex
179
+ dragState.value.start = {
180
+ x: dayColumnRect.left - dayColumnsRect.left, // Left edge of the day column
181
+ y: e.clientY - dayColumnsRect.top
182
+ }
183
+ dragState.value.end = {
184
+ x: dayColumnRect.right - dayColumnsRect.left, // Right edge of the day column
185
+ y: e.clientY - dayColumnsRect.top
186
+ }
187
+
188
+ // Create a clean copy of the day
189
+ const cleanDay = new Date(day)
190
+ cleanDay.setHours(0, 0, 0, 0)
191
+
192
+ const startTime = getTimeFromPosition(e.clientY, cleanDay)
193
+ dragState.value.startTime = startTime
170
194
 
171
195
  document.addEventListener('mousemove', handleMouseMove)
172
196
  document.addEventListener('mouseup', handleMouseUp)
173
197
  }
174
198
 
175
199
  function handleMouseMove(e: MouseEvent) {
176
- if (!dragState.value.isDragging) return
200
+ if (!dragState.value.isDragging || !dragState.value.start || !dayColumns.value.length || !calendarGrid.value || !dayColumnsContainer.value) return
201
+
202
+ // Find which day column we're hovering over
203
+ let targetDayIndex = -1
204
+ for (let i = 0; i < dayColumns.value.length; i++) {
205
+ const columnEl = dayColumns.value[i]
206
+ if (!columnEl) continue
207
+
208
+ const rect = columnEl.getBoundingClientRect()
209
+ if (e.clientX >= rect.left && e.clientX <= rect.right) {
210
+ targetDayIndex = i
211
+ break
212
+ }
213
+ }
214
+
215
+ if (targetDayIndex === -1) return
216
+
217
+ // Update which days are selected
218
+ const dayColumnsRect = dayColumnsContainer.value.getBoundingClientRect()
219
+ const minDayIndex = Math.min(dragState.value.startDay, targetDayIndex)
220
+ const maxDayIndex = Math.max(dragState.value.startDay, targetDayIndex)
221
+
222
+ // Get the left edge of the leftmost selected day
223
+ const leftDayEl = dayColumns.value[minDayIndex]
224
+ if (!leftDayEl) return
225
+ const leftDayRect = leftDayEl.getBoundingClientRect()
226
+ const leftEdge = leftDayRect.left - dayColumnsRect.left
227
+
228
+ // Get the right edge of the rightmost selected day
229
+ const rightDayEl = dayColumns.value[maxDayIndex]
230
+ if (!rightDayEl) return
231
+ const rightDayRect = rightDayEl.getBoundingClientRect()
232
+ const rightEdge = rightDayRect.right - dayColumnsRect.left
233
+
234
+ dragState.value.endDay = targetDayIndex
235
+ dragState.value.end = {
236
+ x: rightEdge,
237
+ y: e.clientY - dayColumnsRect.top
238
+ }
239
+
240
+ // Ensure the selection spans the full width of all selected days
241
+ dragState.value.start.x = leftEdge
177
242
 
178
- dragState.value.end = { x: e.clientX, y: e.clientY }
179
- dragState.value.endTime = getTimeFromPosition(e.clientX, e.clientY)
243
+ if (targetDayIndex >= 0 && targetDayIndex < weekDays.value.length) {
244
+ // Create a clean copy of the day
245
+ const targetDay = new Date(weekDays.value[targetDayIndex])
246
+ targetDay.setHours(0, 0, 0, 0)
247
+
248
+ const endTime = getTimeFromPosition(e.clientY, targetDay)
249
+ dragState.value.endTime = endTime
250
+ }
180
251
  }
181
252
 
182
253
  function handleMouseUp() {
@@ -185,39 +256,53 @@ function handleMouseUp() {
185
256
  let start = new Date(dragState.value.startTime)
186
257
  let end = new Date(dragState.value.endTime)
187
258
 
188
- // Ensure end time is after start time
189
- if (end < start) [start, end] = [end, start]
259
+ // Ensure end time is after start time - handle multi-day and reversed selections
260
+ if (dragState.value.startDay > dragState.value.endDay
261
+ || (dragState.value.startDay === dragState.value.endDay && end < start)) {
262
+ [start, end] = [end, start]
263
+ }
190
264
 
191
265
  emit('eventCreate', { start_time: start, end_time: end })
192
266
 
193
267
  // Reset drag state
194
268
  dragState.value = {
195
269
  isDragging: false,
196
- start: null,
197
- end: null,
198
- startTime: null,
199
- endTime: null
270
+ startDay: -1,
271
+ endDay: -1,
272
+ start: undefined,
273
+ end: undefined,
274
+ startTime: undefined,
275
+ endTime: undefined
200
276
  }
201
277
 
202
278
  document.removeEventListener('mousemove', handleMouseMove)
203
279
  document.removeEventListener('mouseup', handleMouseUp)
204
280
  }
205
281
 
206
- function getTimeFromPosition(x: number, y: number): Date {
207
- const rect = document.querySelector('.time-slots')?.getBoundingClientRect()
208
- if (!rect) return new Date()
282
+ function getTimeFromPosition(y: number, day: Date): Date {
283
+ if (!calendarGrid.value || !timeSlotsContainer.value) return new Date(day)
284
+
285
+ const gridRect = calendarGrid.value.getBoundingClientRect()
286
+
287
+ // Calculate relative Y position
288
+ const relativeY = y - gridRect.top
209
289
 
210
- const dayIndex = Math.floor((x - rect.left) / (rect.width / 7))
211
- const minutes = Math.floor((y - rect.top) / (slotHeight / 2)) * slotDuration
290
+ // Use the same formula as for events
291
+ const minutesPerSlot = slotDuration
292
+ const slotsFromTop = relativeY / slotHeight
293
+ const minutes = Math.floor(slotsFromTop * minutesPerSlot)
212
294
 
213
- const date = new Date(weekDays.value[dayIndex])
214
- date.setHours(Math.floor(minutes / 60))
215
- date.setMinutes(minutes % 60)
295
+ const date = new Date(day)
296
+ date.setHours(Math.floor(minutes / 60) - 1)
297
+ const roundedMinutes = Math.round((minutes % 60) / 5) * 5
298
+ date.setMinutes(roundedMinutes)
299
+ date.setSeconds(0)
300
+ date.setMilliseconds(0)
216
301
 
217
302
  return date
218
303
  }
219
304
 
220
- // Update the current time indicator position
305
+ // Update the current time indicator to use the same calculation as events
221
306
  function updateCurrentTimeIndicator() {
222
307
  const now = new Date()
223
308
 
@@ -227,37 +312,52 @@ function updateCurrentTimeIndicator() {
227
312
  && day.getFullYear() === now.getFullYear()
228
313
  )
229
314
 
230
- // Calculate position for the current time line
315
+ // Calculate position for the current time line - use same formula as events
231
316
  const minutes = now.getHours() * 60 + now.getMinutes()
232
- currentTimeTop.value = (minutes / slotDuration) * (slotHeight / 2)
317
+ currentTimeTop.value = (minutes / slotDuration) * slotHeight
233
318
  }
234
319
 
235
- // Wrapper functions for popover utilities
236
- function openPopover(event: CalendarEvent, e: MouseEvent) {
237
- openPopoverUtil(
238
- event,
239
- e,
240
- popoverState,
241
- !!slots.eventContent,
242
- (evt) => { emit('eventClick', evt) }
243
- )
320
+ // Update the event handling to emit the openPopover event
321
+ function handleEventSelection(event: CalendarEvent, domEvent?: MouseEvent) {
322
+ if (!slots.eventContent) {
323
+ emit('eventClick', event)
324
+ return
325
+ }
326
+
327
+ // Calculate position from DOM event if available
328
+ if (domEvent) {
329
+ const rect = (domEvent.currentTarget as HTMLElement).getBoundingClientRect()
330
+ const position = {
331
+ top: rect.top + window.scrollY + (rect.height / 2),
332
+ left: rect.left + window.scrollX + rect.width + 10
333
+ }
334
+ emit('openPopover', event, position)
335
+ } else {
336
+ emit('openPopover', event)
337
+ }
244
338
  }
245
339
 
246
- function closePopover() {
247
- closePopoverUtil(popoverState)
340
+ function setDayColumnRef(el: Element | ComponentPublicInstance | null | undefined, index: number) {
341
+ // Ensure the array is the right size
342
+ while (dayColumns.value.length <= index) {
343
+ dayColumns.value.push(null as unknown as HTMLElement)
344
+ }
345
+
346
+ if (el) {
347
+ dayColumns.value[index] = el instanceof Element ? el as HTMLElement : (el.$el as HTMLElement)
348
+ } else {
349
+ // If el is undefined or null, we might still want to keep track of this slot
350
+ dayColumns.value[index] = null as unknown as HTMLElement
351
+ }
248
352
  }
249
353
 
250
354
  // Lifecycle hooks
251
355
  onMounted(() => {
252
- document.addEventListener('mousedown', handleMouseDown)
253
-
254
- // Initialize current time indicator and set up interval to update it
255
356
  updateCurrentTimeIndicator()
256
357
  currentTimeInterval.value = setInterval(updateCurrentTimeIndicator, 60000)
257
358
  })
258
359
 
259
360
  onUnmounted(() => {
260
- document.removeEventListener('mousedown', handleMouseDown)
261
361
  document.removeEventListener('mousemove', handleMouseMove)
262
362
  document.removeEventListener('mouseup', handleMouseUp)
263
363
 
@@ -269,13 +369,13 @@ onUnmounted(() => {
269
369
 
270
370
  <template>
271
371
  <div class="w-100p overflow-hidden m_overflow h-100p grid">
272
- <div class="weekGrid border-bottom me-1">
372
+ <div ref="calendarGrid" class="weekGrid border-bottom me-1">
273
373
  <div />
274
374
  <div
275
375
  v-for="day in weekDays" :key="day.toISOString()"
276
376
  class="day-header p-05 txt-center"
277
377
  >
278
- {{ fmtDate(day, { fmt: 'DDD' }) }}
378
+ {{ formatDate(day, { fmt: 'DDD' }) }}
279
379
  <span
280
380
  class="txt-12 round p-025"
281
381
  :class="{
@@ -283,24 +383,31 @@ onUnmounted(() => {
283
383
  'bg-primary color-white': day.toDateString() === new Date().toDateString(),
284
384
  }"
285
385
  >
286
- {{ fmtDate(day, { fmt: 'DD' }) }}
386
+ {{ formatDate(day, { fmt: 'DD' }) }}
287
387
  </span>
288
388
  </div>
289
389
  </div>
290
390
  <div class="overflow h-100p pe-05">
291
- <div class="weekGrid border-end relative" @mousedown="handleMouseDown">
292
- <div>
391
+ <div ref="dayColumnsContainer" class="weekGrid border-end relative">
392
+ <div ref="timeSlotsContainer">
293
393
  <div v-for="slot in timeSlots" :key="slot.time" class="txt-light txt-12 color-gray flex justify-content-center bg-gray-light border-start" :style="{ height: `${slotHeight}px` }">
294
394
  {{ slot.time }}
295
395
  </div>
296
396
  </div>
297
397
 
298
- <div v-if="isToday" class=" absolute end w-100p z-2 flex pointer-events-none ps-4-5" :style="{ top: `${currentTimeTop}px` }">
398
+ <!-- Current time indicator - ensure it aligns with the time slots and events -->
399
+ <div v-if="isToday" class="absolute end w-100p z-2 flex pointer-events-none ps-4-5" :style="{ top: `${currentTimeTop}px` }">
299
400
  <div class="current-time-dot h-10px aspect-ratio-1 round bg-primary" />
300
401
  <div class="current-time-line w-100p bg-primary" />
301
402
  </div>
302
403
 
303
- <div v-for="day in weekDays" :key="day.toISOString()" class="day-column top bottom border-start relative">
404
+ <div
405
+ v-for="(day, index) in weekDays"
406
+ :key="day.toISOString()"
407
+ :ref="el => setDayColumnRef(el, index)"
408
+ class="day-column top bottom border-start relative"
409
+ @mousedown="handleMouseDown($event, day)"
410
+ >
304
411
  <template
305
412
  v-for="event in processedEvents.filter(e =>
306
413
  new Date(e.start_time).toDateString() === day.toDateString())"
@@ -315,118 +422,104 @@ onUnmounted(() => {
315
422
  width: `${event.width}%`,
316
423
  backgroundColor: event.color || 'var(--bgl-primary)',
317
424
  }"
318
- @click.stop="slots.eventContent ? openPopover(event, $event) : emit('eventClick', event)"
425
+ @mousedown.stop
426
+ @click.stop="handleEventSelection(event, $event)"
319
427
  >
320
- <div class="overflow-hidden color-text-light p-025 txt12 h-100p">
428
+ <div class="overflow-hidden color-white p-025 txt12 h-100p">
321
429
  <div class="white-space ellipsis-1">
322
430
  {{ event.title }}
323
431
  </div>
324
432
  <div class="txt10 opacity-8">
325
- {{ fmtDate(event.start_time, { fmt: 'HH:mm' }) }}
433
+ {{ formatDate(event.start_time, { fmt: 'HH:mm' }) }} - {{ formatDate(event.end_time, { fmt: 'HH:mm' }) }}
326
434
  </div>
327
435
  </div>
328
436
  </div>
329
437
  </template>
330
438
  </div>
331
439
 
332
- <!-- Drag selection preview -->
440
+ <!-- Drag selection preview - ensure it aligns with time slots and events -->
333
441
  <div
334
442
  v-if="dragState.isDragging && dragState.start && dragState.end"
335
- class="drag-preview absolute bg-primary pointer-events-none"
443
+ class="drag-preview absolute bg-primary-tint pointer-events-none overflow-hidden opacity-7 z-1"
336
444
  :style="{
337
445
  left: `${Math.min(dragState.start.x, dragState.end.x)}px`,
338
446
  top: `${Math.min(dragState.start.y, dragState.end.y)}px`,
339
447
  width: `${Math.abs(dragState.end.x - dragState.start.x)}px`,
340
448
  height: `${Math.abs(dragState.end.y - dragState.start.y)}px`,
341
449
  }"
342
- />
450
+ >
451
+ <div class="color-primary txt-12 p-025">
452
+ {{ dragState.startTime ? formatDate(dragState.startTime, { fmt: 'HH:mm' }) : '' }} - {{ dragState.endTime ? formatDate(dragState.endTime, { fmt: 'HH:mm' }) : '' }}
453
+ </div>
454
+ </div>
343
455
  </div>
344
456
  </div>
345
-
346
- <!-- Custom Popover -->
347
- <Card
348
- v-if="showPopover && activeEvent"
349
- ref="popoverRef"
350
- v-click-outside="closePopover"
351
- thin
352
- class="custom-popover fixed z-999 radius-05 bg-white w350"
353
- :style="{
354
- top: `${popoverPosition.top}px`,
355
- left: `${popoverPosition.left}px`,
356
- maxWidth: `${popoverPosition.width}px`,
357
- }"
358
- >
359
- <slot name="eventContent" :event="activeEvent" />
360
- </Card>
361
457
  <div class="border-bottom me-1" />
362
458
  </div>
363
459
  </template>
364
460
 
365
461
  <style scoped>
366
- .weekGrid{
462
+ .weekGrid {
367
463
  display: grid;
368
464
  grid-template-columns: 5rem repeat(7, 1fr);
369
465
  }
370
466
 
371
467
  .days-column {
372
- flex-grow: 1;
373
- display: flex;
374
-
375
- }
376
-
377
- .time-slot {
378
- height: 30px;
379
- display: flex;
380
- align-items: center;
381
- justify-content: center;
382
- color: var(--text-muted);
468
+ flex-grow: 1;
469
+ display: flex;
383
470
  }
384
471
 
385
- .time-slots {
386
- flex-grow: 1;
387
- display: flex;
388
- overflow: auto;
389
- position: relative;
472
+ .day-column {
473
+ flex: 1;
474
+ position: relative; /* Ensure absolute positioning works properly */
475
+ min-height: 100%; /* Ensure column fills the full height */
390
476
  }
391
477
 
392
- .day-column {
393
- flex: 1;
478
+ /* Add consistent styling for the time slots */
479
+ .txt-light {
480
+ padding: 0.5rem 0;
481
+ box-sizing: border-box;
482
+ display: flex;
483
+ align-items: flex-start;
484
+ justify-content: center;
394
485
  }
395
486
 
396
487
  .event {
397
- margin-right: 2px;
488
+ margin-right: 2px;
489
+ box-sizing: border-box;
398
490
  }
399
491
 
400
492
  .event:hover {
401
- z-index: 1;
493
+ z-index: 2;
402
494
  }
403
495
 
404
496
  .drag-preview {
405
- border: 2px solid var(--bgl-primary);
497
+ border: 1px solid var(--bgl-primary);
498
+ background-color: rgba(var(--bgl-primary-rgb), 0.1);
499
+ box-sizing: border-box; /* Ensure consistent sizing */
406
500
  }
407
501
 
408
502
  .current-time-line {
409
- height: 2px;
503
+ height: 2px;
504
+ background-color: var(--bgl-primary);
410
505
  }
411
506
 
412
- .custom-popover {
413
- min-width: 250px;
414
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
415
- animation: fadeIn 0.2s ease;
416
- transform-origin: center left;
507
+ .current-time-dot {
508
+ background-color: var(--bgl-primary);
509
+ margin-right: -5px; /* Adjust dot position */
417
510
  }
418
511
 
419
- @keyframes fadeIn {
420
- from {
421
- opacity: 0;
422
- transform: scale(0.95);
423
- }
424
- to {
425
- opacity: 1;
426
- transform: scale(1);
427
- }
512
+ /* This ensures all grid content aligns properly */
513
+ .overflow {
514
+ position: relative;
428
515
  }
429
- @media screen and (max-width: 910px) {
430
516
 
517
+ /* Time column headers should be aligned with their content */
518
+ .day-header {
519
+ box-sizing: border-box;
520
+ height: 100%;
521
+ display: flex;
522
+ flex-direction: column;
523
+ justify-content: center;
431
524
  }
432
525
  </style>
@@ -150,7 +150,7 @@ onMounted(() => {
150
150
  <template>
151
151
  <div class="bagel-input" :class="{ small }" :title="label" @focusin="handleFocus">
152
152
  <label v-if="label">
153
- {{ label }}
153
+ <!-- {{ label }} -->
154
154
  <span v-if="required" class="required">*</span>
155
155
  </label>
156
156
  <Dropdown
@@ -163,7 +163,7 @@ onMounted(() => {
163
163
  <div ref="datePickerRef" class="date-picker-container" @mousedown.stop @click.stop>
164
164
  <TextInput
165
165
  :modelValue="formatDisplayDate(selectedDate)"
166
- icon="calendar"
166
+ iconStart="calendar"
167
167
  :min="formatDisplayDate(min)"
168
168
  :max="formatDisplayDate(max)"
169
169
  :required="required"
@@ -196,8 +196,19 @@ onMounted(() => {
196
196
  </div>
197
197
  </template>
198
198
 
199
- <style scoped>
199
+ <style>
200
200
  .date-picker-container {
201
201
  width: 100%;
202
202
  }
203
+ .date-picker-container .date-input{
204
+ --input-bg: transparent;
205
+ --input-font-size: 12px;
206
+ opacity: 0.6;
207
+ --input-height: 20px;
208
+ width: 75px;
209
+ }
210
+ .date-picker-container .txtInputIconStart input{
211
+ padding: 0 !important;
212
+ padding-inline-start: 1.25rem !important;
213
+ }
203
214
  </style>
@@ -437,6 +437,13 @@ function selectDate(date: Date | null) {
437
437
 
438
438
  .day:hover:not(.disabled) {
439
439
  background-color: var(--input-bg);
440
+ color: var(--bgl-text-color);
441
+ outline: 1px solid var(--border-color);
442
+ }
443
+ .day:hover:not(.disabled).selected {
444
+ filter: var(--bgl-hover-filter);
445
+ background-color: var(--bgl-primary);
446
+ color: var(--bgl-white);
440
447
  }
441
448
 
442
449
  .day.selected {
@@ -1,24 +1,35 @@
1
- import { ref, onMounted, onUnmounted } from 'vue'
1
+ import { onMounted, onUnmounted, ref } from 'vue'
2
2
 
3
3
  export function useDevice() {
4
4
  const innerWidth = ref(window.innerWidth)
5
5
  const isMobile = ref(window.innerWidth < 768)
6
+ const scrollY = ref(window.scrollY)
7
+ const scrollX = ref(window.scrollX)
8
+ const innerHeight = ref(window.innerHeight)
6
9
 
7
10
  function updateDeviceInfo() {
8
11
  innerWidth.value = window.innerWidth
9
12
  isMobile.value = window.innerWidth < 768
13
+ scrollY.value = window.scrollY
14
+ scrollX.value = window.scrollX
15
+ innerHeight.value = window.innerHeight
10
16
  }
11
17
 
12
18
  onMounted(() => {
13
19
  window.addEventListener('resize', updateDeviceInfo)
20
+ window.addEventListener('scroll', updateDeviceInfo)
14
21
  })
15
22
 
16
23
  onUnmounted(() => {
17
24
  window.removeEventListener('resize', updateDeviceInfo)
25
+ window.removeEventListener('scroll', updateDeviceInfo)
18
26
  })
19
27
 
20
28
  return {
21
29
  innerWidth,
22
- isMobile
30
+ isMobile,
31
+ scrollY,
32
+ scrollX,
33
+ innerHeight,
23
34
  }
24
35
  }
@@ -986,6 +986,20 @@
986
986
  min-height: 100%;
987
987
  }
988
988
 
989
+
990
+ .vh-min-100,
991
+ .min100vh,
992
+ .min-100vh,
993
+ .h-min100vh {
994
+ min-height: 100vh !important;
995
+ }
996
+ .h-min-unset,
997
+ .min-h-unset {
998
+ min-height: 100%;
999
+ }
1000
+
1001
+
1002
+
989
1003
  .min-0,
990
1004
  .min0,
991
1005
  .wmin0p,