@mantine/schedule 9.6.1 → 9.6.2

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 (60) hide show
  1. package/cjs/components/DayView/DayView.cjs +37 -16
  2. package/cjs/components/DayView/DayView.cjs.map +1 -1
  3. package/cjs/components/DayView/DayView.module.cjs +1 -0
  4. package/cjs/components/DayView/DayView.module.cjs.map +1 -1
  5. package/cjs/components/MobileMonthView/MobileMonthView.cjs +1 -1
  6. package/cjs/components/MobileMonthView/MobileMonthView.cjs.map +1 -1
  7. package/cjs/components/ResourcesDayView/ResourcesDayView.cjs +39 -14
  8. package/cjs/components/ResourcesDayView/ResourcesDayView.cjs.map +1 -1
  9. package/cjs/components/ResourcesDayView/ResourcesDayView.module.cjs.map +1 -1
  10. package/cjs/components/ResourcesSchedule/ResourcesSchedule.cjs.map +1 -1
  11. package/cjs/components/ResourcesWeekView/ResourcesWeekView.cjs +45 -15
  12. package/cjs/components/ResourcesWeekView/ResourcesWeekView.cjs.map +1 -1
  13. package/cjs/components/ResourcesWeekView/ResourcesWeekView.module.cjs.map +1 -1
  14. package/cjs/components/Schedule/Schedule.cjs.map +1 -1
  15. package/cjs/components/ScheduleBackgroundEvent/ScheduleBackgroundEvent.cjs +18 -3
  16. package/cjs/components/ScheduleBackgroundEvent/ScheduleBackgroundEvent.cjs.map +1 -1
  17. package/cjs/components/WeekView/WeekView.cjs +36 -13
  18. package/cjs/components/WeekView/WeekView.cjs.map +1 -1
  19. package/cjs/components/WeekView/WeekView.module.cjs +1 -0
  20. package/cjs/components/WeekView/WeekView.module.cjs.map +1 -1
  21. package/cjs/hooks/use-event-resize.cjs +7 -4
  22. package/cjs/hooks/use-event-resize.cjs.map +1 -1
  23. package/cjs/hooks/use-horizontal-event-resize.cjs +7 -4
  24. package/cjs/hooks/use-horizontal-event-resize.cjs.map +1 -1
  25. package/esm/components/DayView/DayView.mjs +37 -16
  26. package/esm/components/DayView/DayView.mjs.map +1 -1
  27. package/esm/components/DayView/DayView.module.mjs +1 -0
  28. package/esm/components/DayView/DayView.module.mjs.map +1 -1
  29. package/esm/components/MobileMonthView/MobileMonthView.mjs +1 -1
  30. package/esm/components/MobileMonthView/MobileMonthView.mjs.map +1 -1
  31. package/esm/components/ResourcesDayView/ResourcesDayView.mjs +39 -14
  32. package/esm/components/ResourcesDayView/ResourcesDayView.mjs.map +1 -1
  33. package/esm/components/ResourcesDayView/ResourcesDayView.module.mjs.map +1 -1
  34. package/esm/components/ResourcesSchedule/ResourcesSchedule.mjs.map +1 -1
  35. package/esm/components/ResourcesWeekView/ResourcesWeekView.mjs +45 -15
  36. package/esm/components/ResourcesWeekView/ResourcesWeekView.mjs.map +1 -1
  37. package/esm/components/ResourcesWeekView/ResourcesWeekView.module.mjs.map +1 -1
  38. package/esm/components/Schedule/Schedule.mjs.map +1 -1
  39. package/esm/components/ScheduleBackgroundEvent/ScheduleBackgroundEvent.mjs +19 -4
  40. package/esm/components/ScheduleBackgroundEvent/ScheduleBackgroundEvent.mjs.map +1 -1
  41. package/esm/components/WeekView/WeekView.mjs +36 -13
  42. package/esm/components/WeekView/WeekView.mjs.map +1 -1
  43. package/esm/components/WeekView/WeekView.module.mjs +1 -0
  44. package/esm/components/WeekView/WeekView.module.mjs.map +1 -1
  45. package/esm/hooks/use-event-resize.mjs +7 -4
  46. package/esm/hooks/use-event-resize.mjs.map +1 -1
  47. package/esm/hooks/use-horizontal-event-resize.mjs +7 -4
  48. package/esm/hooks/use-horizontal-event-resize.mjs.map +1 -1
  49. package/lib/components/DayView/DayView.d.ts +2 -2
  50. package/lib/components/ResourcesDayView/ResourcesDayView.d.ts +1 -1
  51. package/lib/components/ResourcesSchedule/ResourcesSchedule.d.ts +1 -1
  52. package/lib/components/ResourcesWeekView/ResourcesWeekView.d.ts +1 -1
  53. package/lib/components/Schedule/Schedule.d.ts +1 -1
  54. package/lib/components/ScheduleBackgroundEvent/ScheduleBackgroundEvent.d.ts +15 -2
  55. package/lib/components/WeekView/WeekView.d.ts +2 -2
  56. package/lib/hooks/use-event-resize.d.ts +3 -2
  57. package/lib/hooks/use-horizontal-event-resize.d.ts +3 -2
  58. package/package.json +4 -4
  59. package/styles.css +254 -6
  60. package/styles.layer.css +254 -6
@@ -1 +1 @@
1
- {"version":3,"file":"WeekView.mjs","names":["classes"],"sources":["../../../src/components/WeekView/WeekView.tsx"],"sourcesContent":["import dayjs from 'dayjs';\nimport { useCallback, useMemo, useRef, useState } from 'react';\nimport {\n Box,\n BoxProps,\n createVarsResolver,\n DataAttributes,\n ElementProps,\n factory,\n Factory,\n getRadius,\n MantineRadius,\n rem,\n ScrollArea,\n ScrollAreaAutosizeProps,\n StylesApiProps,\n UnstyledButton,\n useProps,\n useResolvedStylesApi,\n useStyles,\n} from '@mantine/core';\nimport { useDatesContext } from '@mantine/dates';\nimport { useIsomorphicEffect, useMergedRef } from '@mantine/hooks';\nimport { useAutoScrollOnDrag } from '../../hooks/use-auto-scroll-on-drag';\nimport { useDragDropHandlers } from '../../hooks/use-drag-drop-handlers';\nimport { useEventResize } from '../../hooks/use-event-resize';\nimport { useSlotDragSelect } from '../../hooks/use-slot-drag-select';\nimport { getLabel, ScheduleLabelsOverride } from '../../labels';\nimport {\n AnyDateValue,\n DateLabelFormat,\n DateStringValue,\n DateTimeStringValue,\n DayOfWeek,\n ScheduleEventData,\n ScheduleEventOverlapMode,\n ScheduleMode,\n ScheduleViewLevel,\n} from '../../types';\nimport {\n BusinessHoursValue,\n calculateDropTime,\n expandRecurringEvents,\n formatDate,\n getBusinessHoursMod,\n getDayPosition,\n getDayTimeIntervals,\n getTimeAxisEventStyle,\n getWeekDays,\n getWeekNumber,\n isAllDayEvent,\n nextWeek,\n previousWeek,\n toDateString,\n} from '../../utils';\nimport { AgendaView, AgendaViewStylesNames } from '../AgendaView/AgendaView';\nimport {\n CurrentTimeIndicator,\n CurrentTimeIndicatorStylesNames,\n} from '../CurrentTimeIndicator/CurrentTimeIndicator';\nimport { DragContext, DragContextValue } from '../DragContext/DragContext';\nimport { ScheduleBackgroundEvent } from '../ScheduleBackgroundEvent';\nimport { RenderEvent, RenderEventBody, ScheduleEvent } from '../ScheduleEvent/ScheduleEvent';\nimport { CombinedScheduleHeaderStylesNames } from '../ScheduleHeader/ScheduleHeader';\nimport { ScheduleHeaderBase } from '../ScheduleHeader/ScheduleHeaderBase';\nimport { ViewSelectProps } from '../ScheduleHeader/ViewSelect/ViewSelect';\nimport { getWeekLabel } from './get-week-label/get-week-label';\nimport { getWeekViewEvents } from './get-week-view-events/get-week-view-events';\nimport { handleWeekViewKeyDown, WeekViewControlsRef } from './handle-week-view-key-down';\nimport { WeekViewDay } from './WeekViewDay';\nimport classes from './WeekView.module.css';\n\nexport type WeekViewStylesNames =\n | 'weekView'\n | 'weekViewRoot'\n | 'weekViewHeader'\n | 'weekViewInner'\n | 'weekViewAllDaySlotsEvents'\n | 'weekViewAllDaySlots'\n | 'weekViewAllDaySlotsList'\n | 'weekViewAllDaySlot'\n | 'weekViewAllDaySlotsLabel'\n | 'weekViewScrollArea'\n | 'weekViewCorner'\n | 'weekViewSlotLabels'\n | 'weekViewSlotLabel'\n | 'weekViewDayLabel'\n | 'weekViewDayWeekday'\n | 'weekViewDay'\n | 'weekViewDayNumber'\n | 'weekViewDaySlot'\n | 'weekViewDaySlots'\n | 'weekViewWeekLabel'\n | 'weekViewWeekNumber'\n | 'weekViewBackgroundEvent'\n | 'weekViewDragPreview'\n | CurrentTimeIndicatorStylesNames\n | CombinedScheduleHeaderStylesNames\n | AgendaViewStylesNames;\n\nexport type WeekViewCssVariables = {\n weekView: '--week-view-radius' | '--week-view-slot-height' | '--week-view-all-day-slots-height';\n};\n\nexport interface WeekViewProps\n extends BoxProps, StylesApiProps<WeekViewFactory>, ElementProps<'div'> {\n __staticSelector?: string;\n\n /** Week to display, Date object or date string in `YYYY-MM-DD` format */\n date: Date | string;\n\n /** Called with the new date value when a date is selected */\n onDateChange?: (value: DateStringValue) => void;\n\n /** Start time for the day view, in `HH:mm:ss` format @default 00:00:00 */\n startTime?: string;\n\n /** End time for the day view, in `HH:mm:ss` format @default 23:59:59 */\n endTime?: string;\n\n /** Number of minutes for each interval in the day view. Must divide evenly into an hour (e.g. `15`, `30`) or be a whole number of hours (e.g. `120`, `240`) @default 60 */\n intervalMinutes?: number;\n\n /** If set, grid lines are displayed for intervals smaller than one hour, for example 15 and 30 minutes intervals @default true */\n withSubHourGridLines?: boolean;\n\n /** Dayjs format for slot labels or a callback function that returns formatted value @default HH:mm */\n slotLabelFormat?: DateLabelFormat;\n\n /** Number 0-6, where 0 – Sunday and 6 – Saturday. @default 1 – Monday */\n firstDayOfWeek?: DayOfWeek;\n\n /** `dayjs` format for weekdays names. @default 'ddd' */\n weekdayFormat?: DateLabelFormat;\n\n /** Indices of weekend days, 0-6, where 0 is Sunday and 6 is Saturday. The default value is defined by `DatesProvider`. */\n weekendDays?: DayOfWeek[];\n\n /** If set to false, weekend days are hidden @default true */\n withWeekendDays?: boolean;\n\n /** Determines how events that overlap in time are laid out: `columns` splits the available width between them, `cascade` indents each event and stacks it over the previous one @default 'columns' */\n eventOverlapMode?: ScheduleEventOverlapMode;\n\n /** Time in ms the pointer must rest on an event before it is raised above the events covering it, only used with `eventOverlapMode=\"cascade\"` @default 600 */\n eventOverlapRaiseDelay?: number;\n\n /** If set to true, highlights today in the weekday row @default false */\n highlightToday?: boolean;\n\n /** Key of `theme.radius` or any valid CSS value to set `border-radius` @default theme.defaultRadius */\n radius?: MantineRadius;\n\n /** Props passed down to the `ScrollArea.Autosize` component */\n scrollAreaProps?: ScrollAreaAutosizeProps & DataAttributes;\n\n /** Locale passed down to dayjs, overrides value defined on `DatesProvider` */\n locale?: string;\n\n /** If set, the week number is displayed at the top left corner @default true */\n withWeekNumber?: boolean;\n\n /** If set, displays a line indicating the current time @default true */\n withCurrentTimeIndicator?: boolean;\n\n /** If set, the time indicator displays the current time in the bubble @default true */\n withCurrentTimeBubble?: boolean;\n\n /** If set, displays the current time indicator on the same day of week even when viewing a different week @default false */\n forceCurrentTimeIndicator?: boolean;\n\n /** A function to get the current time, called on every tick. Can be used to display the current time indicator in a different timezone. @default () => dayjs() */\n getCurrentTime?: () => AnyDateValue;\n\n /** If set, displays all-day slots at the top of the view @default true */\n withAllDaySlots?: boolean;\n\n /** If set, the header is displayed @default true */\n withHeader?: boolean;\n\n /** Called when view level select button is clicked */\n onViewChange?: (view: ScheduleViewLevel) => void;\n\n /** Props passed to previous month control */\n previousControlProps?: React.ComponentProps<'button'> & DataAttributes;\n\n /** Props passed to next month control */\n nextControlProps?: React.ComponentProps<'button'> & DataAttributes;\n\n /** Props passed to today control */\n todayControlProps?: React.ComponentProps<'button'> & DataAttributes;\n\n /** Props passed to view level select */\n viewSelectProps?: Partial<ViewSelectProps> & DataAttributes;\n\n /** Format for week label @default 'MMM DD' */\n weekLabelFormat?: DateLabelFormat;\n\n /** List of events to display in the week view */\n events?: ScheduleEventData[];\n\n /** Height of 1hr slot @default 64px */\n slotHeight?: React.CSSProperties['height'];\n\n /** Height of all-day slot @default 48px */\n allDaySlotHeight?: React.CSSProperties['height'];\n\n /** Labels override */\n labels?: ScheduleLabelsOverride;\n\n /** If set to true, highlights business hours with white background @default false */\n highlightBusinessHours?: boolean;\n\n /** Business hours range in `HH:mm:ss` format shared across all days, or a per-day record keyed by day of the week (`0` – Sunday, `6` – Saturday) for day-specific ranges. Set a day to `null` to mark it as fully outside business hours. @default ['09:00:00', '17:00:00'] */\n businessHours?: BusinessHoursValue;\n\n /** Function to customize event body, `event` object is passed as first argument */\n renderEventBody?: RenderEventBody;\n\n /** Function to fully customize event rendering, receives all props that would be passed to the root element including children */\n renderEvent?: RenderEvent;\n\n /** If true, events can be dragged and dropped @default false */\n withEventsDragAndDrop?: boolean;\n\n /** Called when event is dropped at new time */\n onEventDrop?: (data: {\n eventId: string | number;\n newStart: DateTimeStringValue;\n newEnd: DateTimeStringValue;\n event: ScheduleEventData;\n }) => void;\n\n /** Function to determine if event can be dragged */\n canDragEvent?: (event: ScheduleEventData) => boolean;\n\n /** Snap step for moving events by drag and drop, in minutes. Must divide evenly into an hour (e.g. `15`, `30`) or be a whole number of hours. When not set, `intervalMinutes` is used. @default intervalMinutes */\n eventDragInterval?: number;\n\n /** Called when any event drag starts */\n onEventDragStart?: (event: ScheduleEventData) => void;\n\n /** Called when any event drag ends */\n onEventDragEnd?: () => void;\n\n /** Called when time slot is clicked */\n onTimeSlotClick?: (data: {\n slotStart: DateTimeStringValue;\n slotEnd: DateTimeStringValue;\n nativeEvent: React.MouseEvent<HTMLButtonElement>;\n }) => void;\n\n /** Called when all-day slot is clicked */\n onAllDaySlotClick?: (day: DateStringValue, event: React.MouseEvent<HTMLButtonElement>) => void;\n\n /** Called when event is clicked */\n onEventClick?: (event: ScheduleEventData, e: React.MouseEvent<HTMLButtonElement>) => void;\n\n /** If set, background events (`display: 'background'`) can be clicked and trigger `onEventClick` @default false */\n withInteractiveBackgroundEvents?: boolean;\n\n /** If set, enables drag-to-select time slot ranges @default false */\n withDragSlotSelect?: boolean;\n\n /** Called when a time slot range is selected by dragging */\n onSlotDragEnd?: (rangeStart: DateTimeStringValue, rangeEnd: DateTimeStringValue) => void;\n\n /** Interaction mode: 'default' allows all interactions, 'static' disables event interactions @default default */\n mode?: ScheduleMode;\n\n /** Time to scroll to on initial render, in `HH:mm:ss` format */\n startScrollTime?: string;\n\n /** Function to customize week label in the header */\n renderWeekLabel?: (params: {\n weekStart: DateStringValue;\n weekEnd: DateStringValue;\n }) => React.ReactNode;\n\n /** Called when an external item is dropped onto the schedule. Receives the `DataTransfer` object and the drop target datetime. */\n onExternalEventDrop?: (dataTransfer: DataTransfer, dropDateTime: DateTimeStringValue) => void;\n\n /** If true, events can be resized by dragging their edges @default false */\n withEventResize?: boolean;\n\n /** Called when event is resized */\n onEventResize?: (data: {\n eventId: string | number;\n newStart: DateTimeStringValue;\n newEnd: DateTimeStringValue;\n event: ScheduleEventData;\n }) => void;\n\n /** Function to determine if event can be resized */\n canResizeEvent?: (event: ScheduleEventData) => boolean;\n\n /** Snap step for resizing events, in minutes. Must divide evenly into an hour (e.g. `15`, `30`) or be a whole number of hours. When not set, `intervalMinutes` is used. @default intervalMinutes */\n eventResizeInterval?: number;\n\n /** Max number of generated recurring instances per recurring series @default 2000 */\n recurrenceExpansionLimit?: number;\n\n /** Function to get additional props for each time slot. Receives slot start and end datetime strings. Returned props are spread onto the slot element. Event handlers returned by this function are composed with internal handlers (e.g. onClick) rather than overriding them. */\n getTimeSlotProps?: (data: {\n start: DateTimeStringValue;\n end: DateTimeStringValue;\n }) => Record<string, any> | undefined;\n\n /** If set, displays an Agenda button in the header that opens an agenda list view @default false */\n withAgenda?: boolean;\n}\n\nexport type WeekViewFactory = Factory<{\n props: WeekViewProps;\n ref: HTMLDivElement;\n stylesNames: WeekViewStylesNames;\n vars: WeekViewCssVariables;\n}>;\n\nconst defaultProps = {\n __staticSelector: 'WeekView',\n withWeekendDays: true,\n withCurrentTimeIndicator: true,\n startTime: '00:00:00',\n endTime: '23:59:59',\n slotLabelFormat: 'HH:mm',\n intervalMinutes: 60,\n withSubHourGridLines: true,\n weekdayFormat: 'ddd',\n withWeekNumber: true,\n withCurrentTimeBubble: true,\n withAllDaySlots: true,\n withHeader: true,\n weekLabelFormat: 'MMM DD',\n highlightBusinessHours: false,\n businessHours: ['09:00:00', '17:00:00'],\n withEventsDragAndDrop: false,\n withDragSlotSelect: false,\n withEventResize: false,\n mode: 'default',\n withInteractiveBackgroundEvents: false,\n eventOverlapMode: 'columns',\n eventOverlapRaiseDelay: 600,\n} satisfies Partial<WeekViewProps>;\n\nconst varsResolver = createVarsResolver<WeekViewFactory>(\n (_theme, { radius, allDaySlotHeight, slotHeight }) => ({\n weekView: {\n '--week-view-radius': radius !== undefined ? getRadius(radius) : undefined,\n '--week-view-all-day-slots-height': rem(allDaySlotHeight),\n '--week-view-slot-height': rem(slotHeight),\n },\n })\n);\n\nexport const WeekView = factory<WeekViewFactory>((_props) => {\n const props = useProps('WeekView', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n attributes,\n vars,\n startTime,\n endTime,\n date,\n onDateChange,\n intervalMinutes,\n withSubHourGridLines,\n slotLabelFormat,\n withWeekendDays,\n eventOverlapMode,\n eventOverlapRaiseDelay,\n weekendDays,\n firstDayOfWeek,\n weekdayFormat,\n radius,\n highlightToday,\n withCurrentTimeIndicator,\n forceCurrentTimeIndicator,\n getCurrentTime,\n scrollAreaProps,\n locale,\n withWeekNumber,\n withCurrentTimeBubble,\n withAllDaySlots,\n __staticSelector,\n withHeader,\n onViewChange,\n previousControlProps,\n nextControlProps,\n todayControlProps,\n viewSelectProps,\n weekLabelFormat,\n events,\n allDaySlotHeight,\n slotHeight,\n labels,\n highlightBusinessHours,\n businessHours,\n renderEventBody,\n renderEvent,\n withEventsDragAndDrop,\n onEventDrop,\n canDragEvent,\n eventDragInterval,\n onEventDragStart,\n onEventDragEnd,\n onTimeSlotClick,\n onAllDaySlotClick,\n onEventClick,\n withInteractiveBackgroundEvents,\n withDragSlotSelect,\n onSlotDragEnd,\n mode,\n startScrollTime,\n renderWeekLabel,\n onExternalEventDrop,\n withEventResize,\n onEventResize,\n canResizeEvent,\n eventResizeInterval,\n recurrenceExpansionLimit,\n getTimeSlotProps,\n withAgenda,\n ...others\n } = props;\n\n const [agendaOpen, setAgendaOpen] = useState(false);\n\n const getStyles = useStyles<WeekViewFactory>({\n name: __staticSelector,\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n vars,\n varsResolver,\n attributes,\n rootSelector: 'weekView',\n });\n\n const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi<WeekViewFactory>({\n classNames,\n styles,\n props,\n });\n\n const stylesApiProps = {\n classNames: resolvedClassNames,\n styles: resolvedStyles,\n attributes,\n __staticSelector,\n radius,\n };\n\n const [scrolled, setScrolled] = useState(false);\n const ctx = useDatesContext();\n const slots = getDayTimeIntervals({ startTime, endTime, intervalMinutes });\n const viewportRef = useRef<HTMLDivElement>(null);\n\n useAutoScrollOnDrag({\n viewportRef,\n enabled: (withEventsDragAndDrop || !!onExternalEventDrop) && mode !== 'static',\n });\n\n type DropTargetSlot = { day: string; slotIndex: number };\n\n const dragOffsetRef = useRef<{ offset: number; size: number }>({ offset: 0, size: 0 });\n\n const getDropTimeForSlot = (target: DropTargetSlot, draggedEvent: ScheduleEventData) => {\n const slotTime = slots[target.slotIndex].startTime;\n return calculateDropTime({\n draggedEvent,\n targetDate: target.day,\n targetSlotTime: slotTime,\n intervalMinutes,\n dragIntervalMinutes: eventDragInterval,\n slotOffset: eventDragInterval == null ? undefined : dragOffsetRef.current.offset,\n slotSize: eventDragInterval == null ? undefined : dragOffsetRef.current.size,\n startTime,\n endTime,\n });\n };\n\n const handleExternalDrop = useCallback(\n (e: React.DragEvent, target: DropTargetSlot) => {\n if (!onExternalEventDrop) {\n return;\n }\n const slotDate = dayjs(target.day).format('YYYY-MM-DD');\n const slotTime = slots[target.slotIndex].startTime;\n\n if (eventDragInterval == null) {\n onExternalEventDrop(e.dataTransfer, `${slotDate} ${slotTime}`);\n return;\n }\n\n const slotStart = `${slotDate} ${slotTime}`;\n const { start } = calculateDropTime({\n draggedEvent: { start: slotStart, end: slotStart } as ScheduleEventData,\n targetDate: target.day,\n targetSlotTime: slotTime,\n intervalMinutes,\n dragIntervalMinutes: eventDragInterval,\n slotOffset: dragOffsetRef.current.offset,\n slotSize: dragOffsetRef.current.size,\n startTime,\n endTime,\n });\n onExternalEventDrop(e.dataTransfer, dayjs(start).format('YYYY-MM-DD HH:mm:ss'));\n },\n [onExternalEventDrop, slots, eventDragInterval, intervalMinutes, startTime, endTime]\n );\n\n const handleExternalAllDayDrop = useCallback(\n (e: React.DragEvent, day: string) => {\n if (!onExternalEventDrop) {\n return;\n }\n onExternalEventDrop(e.dataTransfer, `${dayjs(day).format('YYYY-MM-DD')} 00:00:00`);\n },\n [onExternalEventDrop]\n );\n\n const dragDrop = useDragDropHandlers<DropTargetSlot>({\n enabled: withEventsDragAndDrop,\n mode,\n onEventDrop,\n canDragEvent,\n onEventDragStart,\n onEventDragEnd,\n calculateDropTarget: getDropTimeForSlot,\n onExternalDrop: onExternalEventDrop ? handleExternalDrop : undefined,\n });\n\n const updateDragPreview = (target: DropTargetSlot) => {\n const draggedEvent = dragDrop.dragContextValue.draggedEvent;\n if (eventDragInterval == null || !draggedEvent) {\n return;\n }\n const { start, end } = getDropTimeForSlot(target, draggedEvent);\n const newStart = dayjs(start).format('YYYY-MM-DD HH:mm:ss');\n if (\n dragDrop.dragPreview?.start !== newStart ||\n dragDrop.dragPreview?.target.day !== target.day\n ) {\n dragDrop.setDragPreview({\n start: newStart,\n end: dayjs(end).format('YYYY-MM-DD HH:mm:ss'),\n target,\n });\n }\n };\n\n const suppressDropHighlight = eventDragInterval != null && dragDrop.dragContextValue.isDragging;\n\n const allDayDragDrop = useDragDropHandlers<string>({\n enabled: withEventsDragAndDrop,\n mode,\n onEventDrop,\n canDragEvent,\n onEventDragStart,\n onEventDragEnd,\n calculateDropTarget: (targetDay: string, draggedEvent: ScheduleEventData) => {\n const eventDuration = dayjs(draggedEvent.end).diff(dayjs(draggedEvent.start), 'millisecond');\n const newStart = dayjs(targetDay).startOf('day');\n return { start: newStart.toDate(), end: newStart.add(eventDuration, 'millisecond').toDate() };\n },\n onExternalDrop: onExternalEventDrop ? handleExternalAllDayDrop : undefined,\n });\n\n const slotDragSelect = useSlotDragSelect({\n enabled: withDragSlotSelect && mode !== 'static',\n onDragEnd: (startIndex, endIndex, group) => {\n if (!onSlotDragEnd) {\n return;\n }\n const slotDate = dayjs(group).format('YYYY-MM-DD');\n onSlotDragEnd(\n `${slotDate} ${slots[startIndex].startTime}`,\n `${slotDate} ${slots[endIndex].endTime}`\n );\n },\n });\n\n const eventResize = useEventResize({\n enabled: withEventResize,\n mode,\n startTime,\n endTime,\n intervalMinutes,\n resizeIntervalMinutes: eventResizeInterval,\n onEventResize,\n canResizeEvent,\n });\n\n const withDragHandlers = (withEventsDragAndDrop || !!onExternalEventDrop) && mode !== 'static';\n\n const handleTimeSlotClick = (\n day: string,\n slotTime: string,\n e: React.MouseEvent<HTMLButtonElement>\n ) => {\n if (!onTimeSlotClick) {\n return;\n }\n\n const slotDate = dayjs(day).format('YYYY-MM-DD');\n const slotIndex = slots.findIndex((s) => s.startTime === slotTime);\n if (slotIndex === -1) {\n return;\n }\n\n const slot = slots[slotIndex];\n onTimeSlotClick({\n slotStart: `${slotDate} ${slot.startTime}`,\n slotEnd: `${slotDate} ${slot.endTime}`,\n nativeEvent: e,\n });\n };\n\n const weekdays = getWeekDays({\n week: date,\n withWeekendDays,\n weekendDays: ctx.getWeekendDays(weekendDays),\n firstDayOfWeek: ctx.getFirstDayOfWeek(firstDayOfWeek),\n });\n\n const expandedEvents = expandRecurringEvents({\n events,\n rangeStart: dayjs(weekdays[0]).startOf('day').toDate(),\n rangeEnd: dayjs(weekdays[weekdays.length - 1])\n .endOf('day')\n .toDate(),\n expansionLimit: recurrenceExpansionLimit,\n });\n\n const weekEvents = getWeekViewEvents({\n date,\n events: expandedEvents,\n startTime,\n endTime,\n intervalMinutes,\n firstDayOfWeek: ctx.getFirstDayOfWeek(firstDayOfWeek),\n weekendDays: ctx.getWeekendDays(weekendDays),\n withWeekendDays,\n eventOverlapMode,\n });\n\n const timeValues = slots.reduce<React.ReactNode[]>((acc, interval) => {\n if (!interval.isHourStart) {\n return acc;\n }\n\n const intervalTime = dayjs(`${dayjs(date).format('YYYY-MM-DD')} ${interval.startTime}`);\n const label = formatDate({\n date: intervalTime,\n locale: ctx.getLocale(locale),\n format: slotLabelFormat,\n });\n\n acc.push(\n <Box\n {...getStyles('weekViewSlotLabel')}\n key={interval.startTime}\n mod={{\n 'hour-start': interval.isHourStart,\n ...getBusinessHoursMod({\n time: interval.startTime,\n businessHours,\n highlightBusinessHours,\n }),\n }}\n >\n {label}\n </Box>\n );\n\n return acc;\n }, []);\n\n const slotsRef: WeekViewControlsRef = useRef<HTMLButtonElement[][]>([]);\n const allDaySlotsRef = useRef<HTMLButtonElement[]>([]);\n const weekdaysRef = useRef<HTMLButtonElement[]>([]);\n const daySlotsContainersRef = useRef<(HTMLDivElement | null)[]>([]);\n const mergedViewportRef = useMergedRef(viewportRef, scrollAreaProps?.viewportRef);\n\n const firstSlotIndex = { dayIndex: 0, slotIndex: 0 };\n\n useIsomorphicEffect(() => {\n if (!startScrollTime || !viewportRef.current) {\n return;\n }\n\n const firstDaySlots = slotsRef.current[0];\n if (!firstDaySlots || firstDaySlots.length === 0) {\n return;\n }\n\n const targetIndex = slots.findIndex((s) => s.startTime >= startScrollTime);\n if (targetIndex < 0) {\n return;\n }\n\n const targetSlot = firstDaySlots[targetIndex];\n if (!targetSlot) {\n return;\n }\n\n const slotRect = targetSlot.getBoundingClientRect();\n const viewportRect = viewportRef.current.getBoundingClientRect();\n viewportRef.current.scrollTo({ left: 0, top: slotRect.top - viewportRect.top });\n }, []);\n\n const getSlotIndexFromDragPoint = useCallback((event: React.DragEvent, dayIndex: number) => {\n const daySlots = slotsRef.current[dayIndex] ?? [];\n const slotIndex = daySlots.findIndex((slotNode) => {\n if (!slotNode) {\n return false;\n }\n\n const rect = slotNode.getBoundingClientRect();\n return event.clientY >= rect.top && event.clientY <= rect.bottom;\n });\n\n if (slotIndex >= 0) {\n const rect = daySlots[slotIndex]!.getBoundingClientRect();\n dragOffsetRef.current = { offset: event.clientY - rect.top, size: rect.height };\n return slotIndex;\n }\n\n const firstSlot = daySlots[0];\n const lastSlot = daySlots[daySlots.length - 1];\n\n if (!firstSlot || !lastSlot) {\n return null;\n }\n\n const firstRect = firstSlot.getBoundingClientRect();\n const lastRect = lastSlot.getBoundingClientRect();\n\n if (event.clientY < firstRect.top) {\n dragOffsetRef.current = { offset: 0, size: firstRect.height };\n return 0;\n }\n\n if (event.clientY > lastRect.bottom) {\n dragOffsetRef.current = { offset: lastRect.height, size: lastRect.height };\n return daySlots.length - 1;\n }\n\n return null;\n }, []);\n\n const handleSlotKeyDown = (\n event: React.KeyboardEvent<HTMLButtonElement>,\n dayIndex: number,\n slotIndex: number\n ) => {\n handleWeekViewKeyDown({\n controlsRef: slotsRef,\n dayIndex,\n slotIndex,\n event,\n });\n };\n\n const handleAllDaySlotKeyDown = (\n event: React.KeyboardEvent<HTMLButtonElement>,\n dayIndex: number\n ) => {\n const direction = event.key;\n if (direction === 'ArrowRight' && dayIndex < weekdays.length - 1) {\n event.preventDefault();\n allDaySlotsRef.current[dayIndex + 1]?.focus();\n } else if (direction === 'ArrowLeft' && dayIndex > 0) {\n event.preventDefault();\n allDaySlotsRef.current[dayIndex - 1]?.focus();\n } else if (direction === 'ArrowDown') {\n event.preventDefault();\n slotsRef.current?.[dayIndex]?.[0]?.focus();\n }\n };\n\n const handleWeekdayKeyDown = (\n event: React.KeyboardEvent<HTMLButtonElement>,\n dayIndex: number\n ) => {\n const direction = event.key;\n if (direction === 'ArrowRight' && dayIndex < weekdays.length - 1) {\n event.preventDefault();\n weekdaysRef.current[dayIndex + 1]?.focus();\n } else if (direction === 'ArrowLeft' && dayIndex > 0) {\n event.preventDefault();\n weekdaysRef.current[dayIndex - 1]?.focus();\n }\n };\n\n const resolveNow = () => (getCurrentTime ? dayjs(getCurrentTime()) : dayjs());\n const now = resolveNow();\n\n const currentWeekdayIndex = withCurrentTimeIndicator\n ? forceCurrentTimeIndicator\n ? weekdays.findIndex((day) => dayjs(day).day() === now.day())\n : weekdays.findIndex((day) => dayjs(day).isSame(now, 'date'))\n : -1;\n\n const weekdaysLabels = weekdays.map((day, dayIndex) => (\n <UnstyledButton\n {...getStyles('weekViewDayLabel')}\n key={day}\n ref={(node) => {\n weekdaysRef.current[dayIndex] = node!;\n }}\n aria-label={`${getLabel('weekday', labels)} ${dayjs(day).format('YYYY-MM-DD')}`}\n mod={{\n today: dayjs(day).isSame(now, 'day') && !!highlightToday,\n weekend: ctx.getWeekendDays(weekendDays).includes(dayjs(day).day() as DayOfWeek),\n static: mode === 'static',\n }}\n tabIndex={mode === 'static' ? -1 : dayIndex === 0 ? 0 : -1}\n onKeyDown={mode === 'static' ? undefined : (event) => handleWeekdayKeyDown(event, dayIndex)}\n onClick={\n mode === 'static'\n ? undefined\n : () => {\n onViewChange?.('day');\n onDateChange?.(toDateString(day));\n }\n }\n >\n <Box {...getStyles('weekViewDayWeekday')} key=\"weekday\">\n {formatDate({ locale: ctx.getLocale(locale), date: day, format: weekdayFormat })}\n </Box>\n <div {...getStyles('weekViewDayNumber')} key=\"date\">\n {dayjs(day).date()}\n </div>\n </UnstyledButton>\n ));\n\n const interactiveBackgroundEvents = withInteractiveBackgroundEvents && mode !== 'static';\n\n const days = weekdays.map((day, dayIndex) => {\n const allBgEvents = weekEvents.backgroundEvents[day] || [];\n\n const backgroundEventNodes = allBgEvents\n .filter((event) => !event.position.allDay)\n .map((event) => (\n <ScheduleBackgroundEvent\n key={`bg-${event.id}`}\n event={event}\n renderEvent={renderEvent}\n renderEventBody={renderEventBody}\n interactive={interactiveBackgroundEvents}\n onEventClick={onEventClick}\n {...getStyles('weekViewBackgroundEvent', {\n style: {\n top: `${event.position.top}%`,\n height: `${event.position.height}%`,\n width: '100%',\n },\n })}\n />\n ));\n\n const dayEvents = (weekEvents.regularEvents[day] || []).map((event) => {\n const eventIsAllDay = isAllDayEvent({ event, date: day });\n const isDraggable = !eventIsAllDay && dragDrop.isDraggableEvent(event);\n const isResizable = !eventIsAllDay && eventResize.isResizableEvent(event);\n const resizePosition = eventResize.getResizePosition(event.id);\n const eventTop = resizePosition ? resizePosition.top : event.position.top;\n const eventHeight = resizePosition ? resizePosition.height : event.position.height;\n\n return (\n <ScheduleEvent\n key={event.id}\n event={event}\n autoSize\n hanging={event.position.hanging}\n draggable={isDraggable}\n withResize={isResizable}\n isResizing={resizePosition !== null}\n onResizeStart={\n isResizable\n ? (edge, e) => {\n const container = daySlotsContainersRef.current[dayIndex];\n if (container) {\n eventResize.handleResizeStart({\n event,\n edge,\n container,\n originalTop: event.position.top,\n originalHeight: event.position.height,\n eventDate: dayjs(day).format('YYYY-MM-DD'),\n pointerEvent: e,\n });\n }\n }\n : undefined\n }\n renderEventBody={renderEventBody}\n renderEvent={renderEvent}\n radius={radius}\n mode={mode}\n onClick={\n onEventClick\n ? (e) => {\n if (!eventResize.wasResizing()) {\n onEventClick(event, e);\n }\n }\n : undefined\n }\n mod={{ cascade: eventOverlapMode === 'cascade' }}\n style={{\n position: 'absolute',\n ...getTimeAxisEventStyle({\n start: eventTop,\n span: eventHeight,\n axis: 'vertical',\n }),\n left: `${event.position.offset}%`,\n width: `${event.position.width}%`,\n '--event-z-index': event.position.column + 3,\n '--event-z-index-raised': event.position.overlaps + 3,\n }}\n />\n );\n });\n\n return (\n <WeekViewDay\n key={day}\n day={day}\n dayIndex={dayIndex}\n slots={slots}\n intervalMinutes={intervalMinutes}\n getStyles={getStyles}\n weekendDays={weekendDays}\n highlightBusinessHours={highlightBusinessHours}\n businessHours={businessHours}\n labels={labels}\n withEventsDragAndDrop={withDragHandlers}\n mode={mode}\n slotsRef={slotsRef}\n firstSlotIndex={firstSlotIndex}\n onSlotKeyDown={handleSlotKeyDown}\n onSlotClick={handleTimeSlotClick}\n onFirstSlotArrowUp={\n withAllDaySlots\n ? (dayIdx) => {\n allDaySlotsRef.current[dayIdx]?.focus();\n }\n : undefined\n }\n onDaySlotsDragOver={(event, dayStr, dayIdx) => {\n const slotIndex = getSlotIndexFromDragPoint(event, dayIdx);\n if (slotIndex !== null) {\n dragDrop.handleDragOver(event, { day: dayStr, slotIndex });\n updateDragPreview({ day: dayStr, slotIndex });\n }\n }}\n onDaySlotsDragLeave={dragDrop.handleDragLeave}\n onDaySlotsDrop={(event, dayStr, dayIdx) => {\n const slotIndex = getSlotIndexFromDragPoint(event, dayIdx);\n if (slotIndex !== null) {\n dragDrop.handleDrop(event, { day: dayStr, slotIndex });\n }\n }}\n dropTargetSlotIndex={\n !suppressDropHighlight && dragDrop.dropTarget?.day === day\n ? dragDrop.dropTarget.slotIndex\n : undefined\n }\n withDragSlotSelect={withDragSlotSelect}\n onSlotPointerDown={slotDragSelect.handleSlotPointerDown}\n isSlotDragSelected={slotDragSelect.isSlotSelected}\n daySlotsContainerRef={(node) => {\n daySlotsContainersRef.current[dayIndex] = node;\n }}\n getTimeSlotProps={getTimeSlotProps}\n >\n {backgroundEventNodes}\n {dayEvents}\n {dragDrop.dragPreview?.target.day === day && dragDrop.dragContextValue.draggedEvent && (\n <Box\n {...getStyles('weekViewDragPreview', {\n style: (() => {\n const { top, height } = getDayPosition({\n event: {\n ...dragDrop.dragContextValue.draggedEvent,\n start: dragDrop.dragPreview.start,\n end: dragDrop.dragPreview.end,\n },\n startTime,\n endTime,\n intervalMinutes,\n });\n return {\n position: 'absolute',\n insetInlineStart: 0,\n insetInlineEnd: 0,\n top: `${top}%`,\n height: `${height}%`,\n };\n })(),\n })}\n />\n )}\n </WeekViewDay>\n );\n });\n\n const allDaySlots = weekdays.map((day, dayIndex) => (\n <UnstyledButton\n aria-label={`${getLabel('allDay', labels)} ${dayjs(day).format('YYYY-MM-DD')}`}\n key={day}\n ref={(node) => {\n allDaySlotsRef.current[dayIndex] = node!;\n }}\n tabIndex={dayIndex === 0 ? 0 : -1}\n onKeyDown={(event) => handleAllDaySlotKeyDown(event, dayIndex)}\n onClick={\n mode === 'static' || !onAllDaySlotClick\n ? undefined\n : (e) => onAllDaySlotClick(dayjs(day).format('YYYY-MM-DD'), e)\n }\n onDragOver={withDragHandlers ? (e) => allDayDragDrop.handleDragOver(e, day) : undefined}\n onDragLeave={withDragHandlers ? allDayDragDrop.handleDragLeave : undefined}\n onDrop={withDragHandlers ? (e) => allDayDragDrop.handleDrop(e, day) : undefined}\n {...getStyles('weekViewDaySlot')}\n mod={{ 'drop-target': allDayDragDrop.isDropTarget(day) }}\n />\n ));\n\n const allDayEventIds = useMemo(\n () => new Set(weekEvents.allDayEvents.map((e) => e.id)),\n [weekEvents.allDayEvents]\n );\n\n const allDayEvents = weekEvents.allDayEvents.map((event) => (\n <ScheduleEvent\n key={event.id}\n event={event}\n autoSize\n nowrap\n hanging={event.position.hanging}\n draggable={allDayDragDrop.isDraggableEvent(event)}\n renderEvent={renderEvent}\n mode={mode}\n onClick={onEventClick ? (e) => onEventClick(event, e) : undefined}\n style={{\n position: 'absolute',\n zIndex: 2,\n top: `calc(${event.position.row * 50}% + 1px)`,\n left: `calc(${event.position.offset}% + 1px)`,\n width: `calc(${event.position.width}% - 1px)`,\n height: 'calc(50% - 2px)',\n maxHeight: 'calc(50% - 2px)',\n }}\n />\n ));\n\n const allDayBackgroundEventNodes = weekdays.flatMap((day, dayIndex) => {\n const allDayBgEvents = (weekEvents.backgroundEvents[day] || []).filter(\n (event) => event.position.allDay\n );\n const dayWidth = 100 / weekdays.length;\n const dayOffset = dayIndex * dayWidth;\n\n return allDayBgEvents.map((event) => (\n <ScheduleBackgroundEvent\n key={`bg-allday-${event.id}-${day}`}\n event={event}\n renderEvent={renderEvent}\n renderEventBody={renderEventBody}\n interactive={interactiveBackgroundEvents}\n onEventClick={onEventClick}\n {...getStyles('weekViewBackgroundEvent', {\n style: {\n top: 0,\n height: '100%',\n left: `${dayOffset}%`,\n width: `${dayWidth}%`,\n },\n })}\n />\n ));\n });\n\n // Extra rows show on hover = total rows - 2 visible rows (starts from 0, so -1)\n const extraRows = Math.max(...weekEvents.allDayEvents.map((event) => event.position.row), 1) - 1;\n\n const content = (\n <Box\n {...getStyles('weekView')}\n mod={{ static: mode === 'static', 'slot-dragging': slotDragSelect.isDragging }}\n {...others}\n >\n {withHeader && (\n <ScheduleHeaderBase\n view=\"week\"\n navigationHandlers={{\n previous: () => previousWeek(date, ctx.getFirstDayOfWeek(firstDayOfWeek)),\n next: () => nextWeek(date, ctx.getFirstDayOfWeek(firstDayOfWeek)),\n today: () => toDateString(resolveNow()),\n }}\n control={{\n miw: 140,\n title: getWeekLabel({\n weekdays,\n locale: ctx.getLocale(locale),\n weekLabelFormat,\n renderWeekLabel,\n }),\n }}\n labels={labels}\n onDateChange={onDateChange}\n onViewChange={onViewChange}\n previousControlProps={previousControlProps}\n nextControlProps={nextControlProps}\n todayControlProps={todayControlProps}\n viewSelectProps={viewSelectProps}\n stylesApiProps={stylesApiProps}\n onAgendaClick={withAgenda ? () => setAgendaOpen((v) => !v) : undefined}\n agendaActive={agendaOpen}\n />\n )}\n\n {agendaOpen && (\n <AgendaView\n rangeStart={dayjs(weekdays[0]).format('YYYY-MM-DD')}\n rangeEnd={dayjs(weekdays[weekdays.length - 1]).format('YYYY-MM-DD')}\n events={events}\n locale={locale}\n labels={labels}\n mode={mode}\n onEventClick={onEventClick}\n recurrenceExpansionLimit={recurrenceExpansionLimit}\n {...stylesApiProps}\n />\n )}\n\n {!agendaOpen && (\n <Box\n {...getStyles('weekViewRoot')}\n __vars={{\n '--event-raise-delay': `${eventOverlapRaiseDelay}ms`,\n '--indicator-offset-index':\n currentWeekdayIndex === -1 ? undefined : `${currentWeekdayIndex + 1}`,\n '--number-of-days': withWeekendDays\n ? '7'\n : `${7 - ctx.getWeekendDays(weekendDays).length}`,\n }}\n mod={{\n 'with-weekends': withWeekendDays,\n 'hide-sub-hour-grid-lines': !withSubHourGridLines,\n 'event-interaction': eventResize.isResizing || dragDrop.dragContextValue.isDragging,\n 'all-day-dragging': allDayDragDrop.dragContextValue.isDragging,\n }}\n >\n <ScrollArea.Autosize\n scrollbarSize={4}\n {...scrollAreaProps}\n {...getStyles('weekViewScrollArea', {\n className: scrollAreaProps?.className,\n style: scrollAreaProps?.style,\n })}\n onScrollPositionChange={(position) => {\n scrollAreaProps?.onScrollPositionChange?.(position);\n setScrolled(position.y !== 0);\n }}\n viewportRef={mergedViewportRef}\n >\n <Box {...getStyles('weekViewHeader')} mod={{ scrolled }}>\n <div {...getStyles('weekViewCorner')} key=\"corner\">\n {withWeekNumber && (\n <>\n <div {...getStyles('weekViewWeekLabel')}>{getLabel('week', labels)}</div>\n <div {...getStyles('weekViewWeekNumber')}>{getWeekNumber(date)}</div>\n </>\n )}\n </div>\n\n {weekdaysLabels}\n </Box>\n\n {withAllDaySlots && (\n <div {...getStyles('weekViewAllDaySlots')}>\n <div {...getStyles('weekViewAllDaySlotsLabel')}>{getLabel('allDay', labels)}</div>\n <div {...getStyles('weekViewAllDaySlotsList')}>\n {allDayBackgroundEventNodes}\n <Box\n {...getStyles('weekViewAllDaySlotsEvents')}\n __vars={{ '--extra-rows': `${extraRows}` }}\n >\n {allDayEvents}\n </Box>\n {allDaySlots}\n </div>\n </div>\n )}\n\n <div {...getStyles('weekViewInner')}>\n <div {...getStyles('weekViewSlotLabels')}>{timeValues}</div>\n\n {withCurrentTimeIndicator && currentWeekdayIndex !== -1 && (\n <CurrentTimeIndicator\n startOffset=\"calc(100% - (100% / var(--number-of-days)) * (var(--number-of-days) - var(--indicator-offset-index) + 1) + ((var(--number-of-days) - var(--indicator-offset-index) + 1) * var(--indicator-labels-offset)))\"\n endOffset=\"calc((100% / var(--number-of-days)) * (var(--number-of-days) - var(--indicator-offset-index)) - (var(--number-of-days) - var(--indicator-offset-index)) * var(--indicator-labels-offset))\"\n timeBubbleStartOffset=\"calc(var(--week-view-slots-label-width) - var(--time-bubble-width))\"\n currentTimeFormat={slotLabelFormat}\n withTimeBubble={withCurrentTimeBubble}\n withThumb={withCurrentTimeBubble ? currentWeekdayIndex !== 0 : true}\n locale={locale}\n startTime={startTime}\n endTime={endTime}\n intervalMinutes={intervalMinutes}\n getCurrentTime={getCurrentTime}\n {...stylesApiProps}\n />\n )}\n {days}\n </div>\n </ScrollArea.Autosize>\n </Box>\n )}\n </Box>\n );\n\n const mergedDragContextValue = useMemo<DragContextValue>(\n () => ({\n isDragging:\n dragDrop.dragContextValue.isDragging || allDayDragDrop.dragContextValue.isDragging,\n draggedEventId:\n dragDrop.dragContextValue.draggedEventId ?? allDayDragDrop.dragContextValue.draggedEventId,\n draggedEvent:\n dragDrop.dragContextValue.draggedEvent ?? allDayDragDrop.dragContextValue.draggedEvent,\n dropTarget:\n dragDrop.dragContextValue.dropTarget ?? allDayDragDrop.dragContextValue.dropTarget,\n onDragStart: (event: ScheduleEventData) => {\n if (allDayEventIds.has(event.id)) {\n allDayDragDrop.handleDragStart(event);\n } else {\n dragDrop.handleDragStart(event);\n }\n },\n onDragEnd: () => {\n dragDrop.handleDragEnd();\n allDayDragDrop.handleDragEnd();\n },\n setDropTarget: dragDrop.dragContextValue.setDropTarget,\n }),\n [dragDrop.dragContextValue, allDayDragDrop.dragContextValue, allDayEventIds]\n );\n\n if (withEventsDragAndDrop) {\n return <DragContext.Provider value={mergedDragContextValue}>{content}</DragContext.Provider>;\n }\n\n return content;\n});\n\nWeekView.displayName = '@mantine/schedule/WeekView';\nWeekView.classes = classes;\nWeekView.varsResolver = varsResolver;\n\nexport namespace WeekView {\n export type Props = WeekViewProps;\n export type Factory = WeekViewFactory;\n export type StylesNames = WeekViewStylesNames;\n export type CssVariables = WeekViewCssVariables;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+TA,MAAM,eAAe;CACnB,kBAAkB;CAClB,iBAAiB;CACjB,0BAA0B;CAC1B,WAAW;CACX,SAAS;CACT,iBAAiB;CACjB,iBAAiB;CACjB,sBAAsB;CACtB,eAAe;CACf,gBAAgB;CAChB,uBAAuB;CACvB,iBAAiB;CACjB,YAAY;CACZ,iBAAiB;CACjB,wBAAwB;CACxB,eAAe,CAAC,YAAY,UAAU;CACtC,uBAAuB;CACvB,oBAAoB;CACpB,iBAAiB;CACjB,MAAM;CACN,iCAAiC;CACjC,kBAAkB;CAClB,wBAAwB;AAC1B;AAEA,MAAM,eAAe,oBAClB,QAAQ,EAAE,QAAQ,kBAAkB,kBAAkB,EACrD,UAAU;CACR,sBAAsB,WAAW,KAAA,IAAY,UAAU,MAAM,IAAI,KAAA;CACjE,oCAAoC,IAAI,gBAAgB;CACxD,2BAA2B,IAAI,UAAU;AAC3C,EACF,EACF;AAEA,MAAa,WAAW,SAA0B,WAAW;CAC3D,MAAM,QAAQ,SAAS,YAAY,cAAc,MAAM;CACvD,MAAM,EACJ,YACA,WACA,OACA,QACA,UACA,YACA,MACA,WACA,SACA,MACA,cACA,iBACA,sBACA,iBACA,iBACA,kBACA,wBACA,aACA,gBACA,eACA,QACA,gBACA,0BACA,2BACA,gBACA,iBACA,QACA,gBACA,uBACA,iBACA,kBACA,YACA,cACA,sBACA,kBACA,mBACA,iBACA,iBACA,QACA,kBACA,YACA,QACA,wBACA,eACA,iBACA,aACA,uBACA,aACA,cACA,mBACA,kBACA,gBACA,iBACA,mBACA,cACA,iCACA,oBACA,eACA,MACA,iBACA,iBACA,qBACA,iBACA,eACA,gBACA,qBACA,0BACA,kBACA,YACA,GAAG,WACD;CAEJ,MAAM,CAAC,YAAY,iBAAiB,SAAS,KAAK;CAElD,MAAM,YAAY,UAA2B;EAC3C,MAAM;EACN,SAAA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,cAAc;CAChB,CAAC;CAED,MAAM,EAAE,oBAAoB,mBAAmB,qBAAsC;EACnF;EACA;EACA;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"}
1
+ {"version":3,"file":"WeekView.mjs","names":["classes"],"sources":["../../../src/components/WeekView/WeekView.tsx"],"sourcesContent":["import dayjs from 'dayjs';\nimport { useCallback, useMemo, useRef, useState } from 'react';\nimport {\n Box,\n BoxProps,\n createVarsResolver,\n DataAttributes,\n ElementProps,\n factory,\n Factory,\n getRadius,\n MantineRadius,\n rem,\n ScrollArea,\n ScrollAreaAutosizeProps,\n StylesApiProps,\n UnstyledButton,\n useProps,\n useResolvedStylesApi,\n useStyles,\n} from '@mantine/core';\nimport { useDatesContext } from '@mantine/dates';\nimport { useIsomorphicEffect, useMergedRef } from '@mantine/hooks';\nimport { useAutoScrollOnDrag } from '../../hooks/use-auto-scroll-on-drag';\nimport { useDragDropHandlers } from '../../hooks/use-drag-drop-handlers';\nimport { useEventResize } from '../../hooks/use-event-resize';\nimport { useSlotDragSelect } from '../../hooks/use-slot-drag-select';\nimport { getLabel, ScheduleLabelsOverride } from '../../labels';\nimport {\n AnyDateValue,\n DateLabelFormat,\n DateStringValue,\n DateTimeStringValue,\n DayOfWeek,\n ScheduleEventData,\n ScheduleEventOverlapMode,\n ScheduleMode,\n ScheduleViewLevel,\n} from '../../types';\nimport {\n BusinessHoursValue,\n calculateDropTime,\n expandRecurringEvents,\n formatDate,\n getBusinessHoursMod,\n getDayPosition,\n getDayTimeIntervals,\n getTimeAxisEventStyle,\n getWeekDays,\n getWeekNumber,\n isAllDayEvent,\n nextWeek,\n previousWeek,\n toDateString,\n} from '../../utils';\nimport { AgendaView, AgendaViewStylesNames } from '../AgendaView/AgendaView';\nimport {\n CurrentTimeIndicator,\n CurrentTimeIndicatorStylesNames,\n} from '../CurrentTimeIndicator/CurrentTimeIndicator';\nimport { DragContext, DragContextValue } from '../DragContext/DragContext';\nimport { ScheduleBackgroundEvent } from '../ScheduleBackgroundEvent';\nimport { RenderEvent, RenderEventBody, ScheduleEvent } from '../ScheduleEvent/ScheduleEvent';\nimport { CombinedScheduleHeaderStylesNames } from '../ScheduleHeader/ScheduleHeader';\nimport { ScheduleHeaderBase } from '../ScheduleHeader/ScheduleHeaderBase';\nimport { ViewSelectProps } from '../ScheduleHeader/ViewSelect/ViewSelect';\nimport { getWeekLabel } from './get-week-label/get-week-label';\nimport { getWeekViewEvents } from './get-week-view-events/get-week-view-events';\nimport { handleWeekViewKeyDown, WeekViewControlsRef } from './handle-week-view-key-down';\nimport { WeekViewDay } from './WeekViewDay';\nimport classes from './WeekView.module.css';\n\nexport type WeekViewStylesNames =\n | 'weekView'\n | 'weekViewRoot'\n | 'weekViewHeader'\n | 'weekViewInner'\n | 'weekViewAllDaySlotsEvents'\n | 'weekViewAllDaySlots'\n | 'weekViewAllDaySlotsList'\n | 'weekViewAllDaySlot'\n | 'weekViewAllDaySlotsLabel'\n | 'weekViewScrollArea'\n | 'weekViewCorner'\n | 'weekViewSlotLabels'\n | 'weekViewSlotLabel'\n | 'weekViewDayLabel'\n | 'weekViewDayWeekday'\n | 'weekViewDay'\n | 'weekViewDayNumber'\n | 'weekViewDaySlot'\n | 'weekViewDaySlots'\n | 'weekViewWeekLabel'\n | 'weekViewWeekNumber'\n | 'weekViewBackgroundEvent'\n | 'weekViewBackgroundEventResizeHandle'\n | 'weekViewDragPreview'\n | CurrentTimeIndicatorStylesNames\n | CombinedScheduleHeaderStylesNames\n | AgendaViewStylesNames;\n\nexport type WeekViewCssVariables = {\n weekView: '--week-view-radius' | '--week-view-slot-height' | '--week-view-all-day-slots-height';\n};\n\nexport interface WeekViewProps\n extends BoxProps, StylesApiProps<WeekViewFactory>, ElementProps<'div'> {\n __staticSelector?: string;\n\n /** Week to display, Date object or date string in `YYYY-MM-DD` format */\n date: Date | string;\n\n /** Called with the new date value when a date is selected */\n onDateChange?: (value: DateStringValue) => void;\n\n /** Start time for the day view, in `HH:mm:ss` format @default 00:00:00 */\n startTime?: string;\n\n /** End time for the day view, in `HH:mm:ss` format @default 23:59:59 */\n endTime?: string;\n\n /** Number of minutes for each interval in the day view. Must divide evenly into an hour (e.g. `15`, `30`) or be a whole number of hours (e.g. `120`, `240`) @default 60 */\n intervalMinutes?: number;\n\n /** If set, grid lines are displayed for intervals smaller than one hour, for example 15 and 30 minutes intervals @default true */\n withSubHourGridLines?: boolean;\n\n /** Dayjs format for slot labels or a callback function that returns formatted value @default HH:mm */\n slotLabelFormat?: DateLabelFormat;\n\n /** Number 0-6, where 0 – Sunday and 6 – Saturday. @default 1 – Monday */\n firstDayOfWeek?: DayOfWeek;\n\n /** `dayjs` format for weekdays names. @default 'ddd' */\n weekdayFormat?: DateLabelFormat;\n\n /** Indices of weekend days, 0-6, where 0 is Sunday and 6 is Saturday. The default value is defined by `DatesProvider`. */\n weekendDays?: DayOfWeek[];\n\n /** If set to false, weekend days are hidden @default true */\n withWeekendDays?: boolean;\n\n /** Determines how events that overlap in time are laid out: `columns` splits the available width between them, `cascade` indents each event and stacks it over the previous one @default 'columns' */\n eventOverlapMode?: ScheduleEventOverlapMode;\n\n /** Time in ms the pointer must rest on an event before it is raised above the events covering it, only used with `eventOverlapMode=\"cascade\"` @default 600 */\n eventOverlapRaiseDelay?: number;\n\n /** If set to true, highlights today in the weekday row @default false */\n highlightToday?: boolean;\n\n /** Key of `theme.radius` or any valid CSS value to set `border-radius` @default theme.defaultRadius */\n radius?: MantineRadius;\n\n /** Props passed down to the `ScrollArea.Autosize` component */\n scrollAreaProps?: ScrollAreaAutosizeProps & DataAttributes;\n\n /** Locale passed down to dayjs, overrides value defined on `DatesProvider` */\n locale?: string;\n\n /** If set, the week number is displayed at the top left corner @default true */\n withWeekNumber?: boolean;\n\n /** If set, displays a line indicating the current time @default true */\n withCurrentTimeIndicator?: boolean;\n\n /** If set, the time indicator displays the current time in the bubble @default true */\n withCurrentTimeBubble?: boolean;\n\n /** If set, displays the current time indicator on the same day of week even when viewing a different week @default false */\n forceCurrentTimeIndicator?: boolean;\n\n /** A function to get the current time, called on every tick. Can be used to display the current time indicator in a different timezone. @default () => dayjs() */\n getCurrentTime?: () => AnyDateValue;\n\n /** If set, displays all-day slots at the top of the view @default true */\n withAllDaySlots?: boolean;\n\n /** If set, the header is displayed @default true */\n withHeader?: boolean;\n\n /** Called when view level select button is clicked */\n onViewChange?: (view: ScheduleViewLevel) => void;\n\n /** Props passed to previous month control */\n previousControlProps?: React.ComponentProps<'button'> & DataAttributes;\n\n /** Props passed to next month control */\n nextControlProps?: React.ComponentProps<'button'> & DataAttributes;\n\n /** Props passed to today control */\n todayControlProps?: React.ComponentProps<'button'> & DataAttributes;\n\n /** Props passed to view level select */\n viewSelectProps?: Partial<ViewSelectProps> & DataAttributes;\n\n /** Format for week label @default 'MMM DD' */\n weekLabelFormat?: DateLabelFormat;\n\n /** List of events to display in the week view */\n events?: ScheduleEventData[];\n\n /** Height of 1hr slot @default 64px */\n slotHeight?: React.CSSProperties['height'];\n\n /** Height of all-day slot @default 48px */\n allDaySlotHeight?: React.CSSProperties['height'];\n\n /** Labels override */\n labels?: ScheduleLabelsOverride;\n\n /** If set to true, highlights business hours with white background @default false */\n highlightBusinessHours?: boolean;\n\n /** Business hours range in `HH:mm:ss` format shared across all days, or a per-day record keyed by day of the week (`0` – Sunday, `6` – Saturday) for day-specific ranges. Set a day to `null` to mark it as fully outside business hours. @default ['09:00:00', '17:00:00'] */\n businessHours?: BusinessHoursValue;\n\n /** Function to customize event body, `event` object is passed as first argument */\n renderEventBody?: RenderEventBody;\n\n /** Function to fully customize event rendering, receives all props that would be passed to the root element including children */\n renderEvent?: RenderEvent;\n\n /** If true, events can be dragged and dropped @default false */\n withEventsDragAndDrop?: boolean;\n\n /** Called when event is dropped at new time */\n onEventDrop?: (data: {\n eventId: string | number;\n newStart: DateTimeStringValue;\n newEnd: DateTimeStringValue;\n event: ScheduleEventData;\n }) => void;\n\n /** Function to determine if event can be dragged */\n canDragEvent?: (event: ScheduleEventData) => boolean;\n\n /** Snap step for moving events by drag and drop, in minutes. Must divide evenly into an hour (e.g. `15`, `30`) or be a whole number of hours. When not set, `intervalMinutes` is used. @default intervalMinutes */\n eventDragInterval?: number;\n\n /** Called when any event drag starts */\n onEventDragStart?: (event: ScheduleEventData) => void;\n\n /** Called when any event drag ends */\n onEventDragEnd?: () => void;\n\n /** Called when time slot is clicked */\n onTimeSlotClick?: (data: {\n slotStart: DateTimeStringValue;\n slotEnd: DateTimeStringValue;\n nativeEvent: React.MouseEvent<HTMLButtonElement>;\n }) => void;\n\n /** Called when all-day slot is clicked */\n onAllDaySlotClick?: (day: DateStringValue, event: React.MouseEvent<HTMLButtonElement>) => void;\n\n /** Called when event is clicked */\n onEventClick?: (event: ScheduleEventData, e: React.MouseEvent<HTMLButtonElement>) => void;\n\n /** If set, background events (`display: 'background'`) can be clicked and trigger `onEventClick`. Combined with `withEventResize`, timed background events can also be resized by dragging their edges. @default false */\n withInteractiveBackgroundEvents?: boolean;\n\n /** If set, enables drag-to-select time slot ranges @default false */\n withDragSlotSelect?: boolean;\n\n /** Called when a time slot range is selected by dragging */\n onSlotDragEnd?: (rangeStart: DateTimeStringValue, rangeEnd: DateTimeStringValue) => void;\n\n /** Interaction mode: 'default' allows all interactions, 'static' disables event interactions @default default */\n mode?: ScheduleMode;\n\n /** Time to scroll to on initial render, in `HH:mm:ss` format */\n startScrollTime?: string;\n\n /** Function to customize week label in the header */\n renderWeekLabel?: (params: {\n weekStart: DateStringValue;\n weekEnd: DateStringValue;\n }) => React.ReactNode;\n\n /** Called when an external item is dropped onto the schedule. Receives the `DataTransfer` object and the drop target datetime. */\n onExternalEventDrop?: (dataTransfer: DataTransfer, dropDateTime: DateTimeStringValue) => void;\n\n /** If true, events can be resized by dragging their edges @default false */\n withEventResize?: boolean;\n\n /** Called when event is resized */\n onEventResize?: (data: {\n eventId: string | number;\n newStart: DateTimeStringValue;\n newEnd: DateTimeStringValue;\n event: ScheduleEventData;\n }) => void;\n\n /** Function to determine if event can be resized */\n canResizeEvent?: (event: ScheduleEventData) => boolean;\n\n /** Snap step for resizing events, in minutes. Must divide evenly into an hour (e.g. `15`, `30`) or be a whole number of hours. When not set, `intervalMinutes` is used. @default intervalMinutes */\n eventResizeInterval?: number;\n\n /** Max number of generated recurring instances per recurring series @default 2000 */\n recurrenceExpansionLimit?: number;\n\n /** Function to get additional props for each time slot. Receives slot start and end datetime strings. Returned props are spread onto the slot element. Event handlers returned by this function are composed with internal handlers (e.g. onClick) rather than overriding them. */\n getTimeSlotProps?: (data: {\n start: DateTimeStringValue;\n end: DateTimeStringValue;\n }) => Record<string, any> | undefined;\n\n /** If set, displays an Agenda button in the header that opens an agenda list view @default false */\n withAgenda?: boolean;\n}\n\nexport type WeekViewFactory = Factory<{\n props: WeekViewProps;\n ref: HTMLDivElement;\n stylesNames: WeekViewStylesNames;\n vars: WeekViewCssVariables;\n}>;\n\nconst defaultProps = {\n __staticSelector: 'WeekView',\n withWeekendDays: true,\n withCurrentTimeIndicator: true,\n startTime: '00:00:00',\n endTime: '23:59:59',\n slotLabelFormat: 'HH:mm',\n intervalMinutes: 60,\n withSubHourGridLines: true,\n weekdayFormat: 'ddd',\n withWeekNumber: true,\n withCurrentTimeBubble: true,\n withAllDaySlots: true,\n withHeader: true,\n weekLabelFormat: 'MMM DD',\n highlightBusinessHours: false,\n businessHours: ['09:00:00', '17:00:00'],\n withEventsDragAndDrop: false,\n withDragSlotSelect: false,\n withEventResize: false,\n mode: 'default',\n withInteractiveBackgroundEvents: false,\n eventOverlapMode: 'columns',\n eventOverlapRaiseDelay: 600,\n} satisfies Partial<WeekViewProps>;\n\nconst varsResolver = createVarsResolver<WeekViewFactory>(\n (_theme, { radius, allDaySlotHeight, slotHeight }) => ({\n weekView: {\n '--week-view-radius': radius !== undefined ? getRadius(radius) : undefined,\n '--week-view-all-day-slots-height': rem(allDaySlotHeight),\n '--week-view-slot-height': rem(slotHeight),\n },\n })\n);\n\nexport const WeekView = factory<WeekViewFactory>((_props) => {\n const props = useProps('WeekView', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n attributes,\n vars,\n startTime,\n endTime,\n date,\n onDateChange,\n intervalMinutes,\n withSubHourGridLines,\n slotLabelFormat,\n withWeekendDays,\n eventOverlapMode,\n eventOverlapRaiseDelay,\n weekendDays,\n firstDayOfWeek,\n weekdayFormat,\n radius,\n highlightToday,\n withCurrentTimeIndicator,\n forceCurrentTimeIndicator,\n getCurrentTime,\n scrollAreaProps,\n locale,\n withWeekNumber,\n withCurrentTimeBubble,\n withAllDaySlots,\n __staticSelector,\n withHeader,\n onViewChange,\n previousControlProps,\n nextControlProps,\n todayControlProps,\n viewSelectProps,\n weekLabelFormat,\n events,\n allDaySlotHeight,\n slotHeight,\n labels,\n highlightBusinessHours,\n businessHours,\n renderEventBody,\n renderEvent,\n withEventsDragAndDrop,\n onEventDrop,\n canDragEvent,\n eventDragInterval,\n onEventDragStart,\n onEventDragEnd,\n onTimeSlotClick,\n onAllDaySlotClick,\n onEventClick,\n withInteractiveBackgroundEvents,\n withDragSlotSelect,\n onSlotDragEnd,\n mode,\n startScrollTime,\n renderWeekLabel,\n onExternalEventDrop,\n withEventResize,\n onEventResize,\n canResizeEvent,\n eventResizeInterval,\n recurrenceExpansionLimit,\n getTimeSlotProps,\n withAgenda,\n ...others\n } = props;\n\n const [agendaOpen, setAgendaOpen] = useState(false);\n\n const getStyles = useStyles<WeekViewFactory>({\n name: __staticSelector,\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n vars,\n varsResolver,\n attributes,\n rootSelector: 'weekView',\n });\n\n const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi<WeekViewFactory>({\n classNames,\n styles,\n props,\n });\n\n const stylesApiProps = {\n classNames: resolvedClassNames,\n styles: resolvedStyles,\n attributes,\n __staticSelector,\n radius,\n };\n\n const [scrolled, setScrolled] = useState(false);\n const ctx = useDatesContext();\n const slots = getDayTimeIntervals({ startTime, endTime, intervalMinutes });\n const viewportRef = useRef<HTMLDivElement>(null);\n\n useAutoScrollOnDrag({\n viewportRef,\n enabled: (withEventsDragAndDrop || !!onExternalEventDrop) && mode !== 'static',\n });\n\n type DropTargetSlot = { day: string; slotIndex: number };\n\n const dragOffsetRef = useRef<{ offset: number; size: number }>({ offset: 0, size: 0 });\n\n const getDropTimeForSlot = (target: DropTargetSlot, draggedEvent: ScheduleEventData) => {\n const slotTime = slots[target.slotIndex].startTime;\n return calculateDropTime({\n draggedEvent,\n targetDate: target.day,\n targetSlotTime: slotTime,\n intervalMinutes,\n dragIntervalMinutes: eventDragInterval,\n slotOffset: eventDragInterval == null ? undefined : dragOffsetRef.current.offset,\n slotSize: eventDragInterval == null ? undefined : dragOffsetRef.current.size,\n startTime,\n endTime,\n });\n };\n\n const handleExternalDrop = useCallback(\n (e: React.DragEvent, target: DropTargetSlot) => {\n if (!onExternalEventDrop) {\n return;\n }\n const slotDate = dayjs(target.day).format('YYYY-MM-DD');\n const slotTime = slots[target.slotIndex].startTime;\n\n if (eventDragInterval == null) {\n onExternalEventDrop(e.dataTransfer, `${slotDate} ${slotTime}`);\n return;\n }\n\n const slotStart = `${slotDate} ${slotTime}`;\n const { start } = calculateDropTime({\n draggedEvent: { start: slotStart, end: slotStart } as ScheduleEventData,\n targetDate: target.day,\n targetSlotTime: slotTime,\n intervalMinutes,\n dragIntervalMinutes: eventDragInterval,\n slotOffset: dragOffsetRef.current.offset,\n slotSize: dragOffsetRef.current.size,\n startTime,\n endTime,\n });\n onExternalEventDrop(e.dataTransfer, dayjs(start).format('YYYY-MM-DD HH:mm:ss'));\n },\n [onExternalEventDrop, slots, eventDragInterval, intervalMinutes, startTime, endTime]\n );\n\n const handleExternalAllDayDrop = useCallback(\n (e: React.DragEvent, day: string) => {\n if (!onExternalEventDrop) {\n return;\n }\n onExternalEventDrop(e.dataTransfer, `${dayjs(day).format('YYYY-MM-DD')} 00:00:00`);\n },\n [onExternalEventDrop]\n );\n\n const dragDrop = useDragDropHandlers<DropTargetSlot>({\n enabled: withEventsDragAndDrop,\n mode,\n onEventDrop,\n canDragEvent,\n onEventDragStart,\n onEventDragEnd,\n calculateDropTarget: getDropTimeForSlot,\n onExternalDrop: onExternalEventDrop ? handleExternalDrop : undefined,\n });\n\n const updateDragPreview = (target: DropTargetSlot) => {\n const draggedEvent = dragDrop.dragContextValue.draggedEvent;\n if (eventDragInterval == null || !draggedEvent) {\n return;\n }\n const { start, end } = getDropTimeForSlot(target, draggedEvent);\n const newStart = dayjs(start).format('YYYY-MM-DD HH:mm:ss');\n if (\n dragDrop.dragPreview?.start !== newStart ||\n dragDrop.dragPreview?.target.day !== target.day\n ) {\n dragDrop.setDragPreview({\n start: newStart,\n end: dayjs(end).format('YYYY-MM-DD HH:mm:ss'),\n target,\n });\n }\n };\n\n const suppressDropHighlight = eventDragInterval != null && dragDrop.dragContextValue.isDragging;\n\n const allDayDragDrop = useDragDropHandlers<string>({\n enabled: withEventsDragAndDrop,\n mode,\n onEventDrop,\n canDragEvent,\n onEventDragStart,\n onEventDragEnd,\n calculateDropTarget: (targetDay: string, draggedEvent: ScheduleEventData) => {\n const eventDuration = dayjs(draggedEvent.end).diff(dayjs(draggedEvent.start), 'millisecond');\n const newStart = dayjs(targetDay).startOf('day');\n return { start: newStart.toDate(), end: newStart.add(eventDuration, 'millisecond').toDate() };\n },\n onExternalDrop: onExternalEventDrop ? handleExternalAllDayDrop : undefined,\n });\n\n const slotDragSelect = useSlotDragSelect({\n enabled: withDragSlotSelect && mode !== 'static',\n onDragEnd: (startIndex, endIndex, group) => {\n if (!onSlotDragEnd) {\n return;\n }\n const slotDate = dayjs(group).format('YYYY-MM-DD');\n onSlotDragEnd(\n `${slotDate} ${slots[startIndex].startTime}`,\n `${slotDate} ${slots[endIndex].endTime}`\n );\n },\n });\n\n const eventResize = useEventResize({\n enabled: withEventResize,\n mode,\n startTime,\n endTime,\n intervalMinutes,\n resizeIntervalMinutes: eventResizeInterval,\n onEventResize,\n canResizeEvent,\n withBackgroundEvents: withInteractiveBackgroundEvents,\n });\n\n const withDragHandlers = (withEventsDragAndDrop || !!onExternalEventDrop) && mode !== 'static';\n\n const handleTimeSlotClick = (\n day: string,\n slotTime: string,\n e: React.MouseEvent<HTMLButtonElement>\n ) => {\n if (!onTimeSlotClick) {\n return;\n }\n\n const slotDate = dayjs(day).format('YYYY-MM-DD');\n const slotIndex = slots.findIndex((s) => s.startTime === slotTime);\n if (slotIndex === -1) {\n return;\n }\n\n const slot = slots[slotIndex];\n onTimeSlotClick({\n slotStart: `${slotDate} ${slot.startTime}`,\n slotEnd: `${slotDate} ${slot.endTime}`,\n nativeEvent: e,\n });\n };\n\n const weekdays = getWeekDays({\n week: date,\n withWeekendDays,\n weekendDays: ctx.getWeekendDays(weekendDays),\n firstDayOfWeek: ctx.getFirstDayOfWeek(firstDayOfWeek),\n });\n\n const expandedEvents = expandRecurringEvents({\n events,\n rangeStart: dayjs(weekdays[0]).startOf('day').toDate(),\n rangeEnd: dayjs(weekdays[weekdays.length - 1])\n .endOf('day')\n .toDate(),\n expansionLimit: recurrenceExpansionLimit,\n });\n\n const weekEvents = getWeekViewEvents({\n date,\n events: expandedEvents,\n startTime,\n endTime,\n intervalMinutes,\n firstDayOfWeek: ctx.getFirstDayOfWeek(firstDayOfWeek),\n weekendDays: ctx.getWeekendDays(weekendDays),\n withWeekendDays,\n eventOverlapMode,\n });\n\n const timeValues = slots.reduce<React.ReactNode[]>((acc, interval) => {\n if (!interval.isHourStart) {\n return acc;\n }\n\n const intervalTime = dayjs(`${dayjs(date).format('YYYY-MM-DD')} ${interval.startTime}`);\n const label = formatDate({\n date: intervalTime,\n locale: ctx.getLocale(locale),\n format: slotLabelFormat,\n });\n\n acc.push(\n <Box\n {...getStyles('weekViewSlotLabel')}\n key={interval.startTime}\n mod={{\n 'hour-start': interval.isHourStart,\n ...getBusinessHoursMod({\n time: interval.startTime,\n businessHours,\n highlightBusinessHours,\n }),\n }}\n >\n {label}\n </Box>\n );\n\n return acc;\n }, []);\n\n const slotsRef: WeekViewControlsRef = useRef<HTMLButtonElement[][]>([]);\n const allDaySlotsRef = useRef<HTMLButtonElement[]>([]);\n const weekdaysRef = useRef<HTMLButtonElement[]>([]);\n const daySlotsContainersRef = useRef<(HTMLDivElement | null)[]>([]);\n const mergedViewportRef = useMergedRef(viewportRef, scrollAreaProps?.viewportRef);\n\n const firstSlotIndex = { dayIndex: 0, slotIndex: 0 };\n\n useIsomorphicEffect(() => {\n if (!startScrollTime || !viewportRef.current) {\n return;\n }\n\n const firstDaySlots = slotsRef.current[0];\n if (!firstDaySlots || firstDaySlots.length === 0) {\n return;\n }\n\n const targetIndex = slots.findIndex((s) => s.startTime >= startScrollTime);\n if (targetIndex < 0) {\n return;\n }\n\n const targetSlot = firstDaySlots[targetIndex];\n if (!targetSlot) {\n return;\n }\n\n const slotRect = targetSlot.getBoundingClientRect();\n const viewportRect = viewportRef.current.getBoundingClientRect();\n viewportRef.current.scrollTo({ left: 0, top: slotRect.top - viewportRect.top });\n }, []);\n\n const getSlotIndexFromDragPoint = useCallback((event: React.DragEvent, dayIndex: number) => {\n const daySlots = slotsRef.current[dayIndex] ?? [];\n const slotIndex = daySlots.findIndex((slotNode) => {\n if (!slotNode) {\n return false;\n }\n\n const rect = slotNode.getBoundingClientRect();\n return event.clientY >= rect.top && event.clientY <= rect.bottom;\n });\n\n if (slotIndex >= 0) {\n const rect = daySlots[slotIndex]!.getBoundingClientRect();\n dragOffsetRef.current = { offset: event.clientY - rect.top, size: rect.height };\n return slotIndex;\n }\n\n const firstSlot = daySlots[0];\n const lastSlot = daySlots[daySlots.length - 1];\n\n if (!firstSlot || !lastSlot) {\n return null;\n }\n\n const firstRect = firstSlot.getBoundingClientRect();\n const lastRect = lastSlot.getBoundingClientRect();\n\n if (event.clientY < firstRect.top) {\n dragOffsetRef.current = { offset: 0, size: firstRect.height };\n return 0;\n }\n\n if (event.clientY > lastRect.bottom) {\n dragOffsetRef.current = { offset: lastRect.height, size: lastRect.height };\n return daySlots.length - 1;\n }\n\n return null;\n }, []);\n\n const handleSlotKeyDown = (\n event: React.KeyboardEvent<HTMLButtonElement>,\n dayIndex: number,\n slotIndex: number\n ) => {\n handleWeekViewKeyDown({\n controlsRef: slotsRef,\n dayIndex,\n slotIndex,\n event,\n });\n };\n\n const handleAllDaySlotKeyDown = (\n event: React.KeyboardEvent<HTMLButtonElement>,\n dayIndex: number\n ) => {\n const direction = event.key;\n if (direction === 'ArrowRight' && dayIndex < weekdays.length - 1) {\n event.preventDefault();\n allDaySlotsRef.current[dayIndex + 1]?.focus();\n } else if (direction === 'ArrowLeft' && dayIndex > 0) {\n event.preventDefault();\n allDaySlotsRef.current[dayIndex - 1]?.focus();\n } else if (direction === 'ArrowDown') {\n event.preventDefault();\n slotsRef.current?.[dayIndex]?.[0]?.focus();\n }\n };\n\n const handleWeekdayKeyDown = (\n event: React.KeyboardEvent<HTMLButtonElement>,\n dayIndex: number\n ) => {\n const direction = event.key;\n if (direction === 'ArrowRight' && dayIndex < weekdays.length - 1) {\n event.preventDefault();\n weekdaysRef.current[dayIndex + 1]?.focus();\n } else if (direction === 'ArrowLeft' && dayIndex > 0) {\n event.preventDefault();\n weekdaysRef.current[dayIndex - 1]?.focus();\n }\n };\n\n const resolveNow = () => (getCurrentTime ? dayjs(getCurrentTime()) : dayjs());\n const now = resolveNow();\n\n const currentWeekdayIndex = withCurrentTimeIndicator\n ? forceCurrentTimeIndicator\n ? weekdays.findIndex((day) => dayjs(day).day() === now.day())\n : weekdays.findIndex((day) => dayjs(day).isSame(now, 'date'))\n : -1;\n\n const weekdaysLabels = weekdays.map((day, dayIndex) => (\n <UnstyledButton\n {...getStyles('weekViewDayLabel')}\n key={day}\n ref={(node) => {\n weekdaysRef.current[dayIndex] = node!;\n }}\n aria-label={`${getLabel('weekday', labels)} ${dayjs(day).format('YYYY-MM-DD')}`}\n mod={{\n today: dayjs(day).isSame(now, 'day') && !!highlightToday,\n weekend: ctx.getWeekendDays(weekendDays).includes(dayjs(day).day() as DayOfWeek),\n static: mode === 'static',\n }}\n tabIndex={mode === 'static' ? -1 : dayIndex === 0 ? 0 : -1}\n onKeyDown={mode === 'static' ? undefined : (event) => handleWeekdayKeyDown(event, dayIndex)}\n onClick={\n mode === 'static'\n ? undefined\n : () => {\n onViewChange?.('day');\n onDateChange?.(toDateString(day));\n }\n }\n >\n <Box {...getStyles('weekViewDayWeekday')} key=\"weekday\">\n {formatDate({ locale: ctx.getLocale(locale), date: day, format: weekdayFormat })}\n </Box>\n <div {...getStyles('weekViewDayNumber')} key=\"date\">\n {dayjs(day).date()}\n </div>\n </UnstyledButton>\n ));\n\n const interactiveBackgroundEvents = withInteractiveBackgroundEvents && mode !== 'static';\n\n const days = weekdays.map((day, dayIndex) => {\n const allBgEvents = weekEvents.backgroundEvents[day] || [];\n\n const backgroundEventNodes = allBgEvents\n .filter((event) => !event.position.allDay)\n .map((event) => {\n const eventDate = dayjs(day).format('YYYY-MM-DD');\n const isResizable = eventResize.isResizableEvent(event);\n const resizePosition = eventResize.getResizePosition(event.id, eventDate);\n\n return (\n <ScheduleBackgroundEvent<'top' | 'bottom'>\n key={`bg-${event.id}`}\n event={event}\n renderEvent={renderEvent}\n renderEventBody={renderEventBody}\n interactive={interactiveBackgroundEvents}\n onEventClick={\n onEventClick\n ? (clickedEvent, e) => {\n if (!eventResize.wasResizing()) {\n onEventClick(clickedEvent, e);\n }\n }\n : undefined\n }\n withResize={isResizable}\n isResizing={resizePosition !== null}\n resizeHandleProps={getStyles('weekViewBackgroundEventResizeHandle')}\n onResizeStart={\n isResizable\n ? (edge, e) => {\n const container = daySlotsContainersRef.current[dayIndex];\n if (container) {\n eventResize.handleResizeStart({\n event,\n edge,\n container,\n originalTop: event.position.top,\n originalHeight: event.position.height,\n eventDate,\n pointerEvent: e,\n });\n }\n }\n : undefined\n }\n {...getStyles('weekViewBackgroundEvent', {\n style: {\n top: `${resizePosition ? resizePosition.top : event.position.top}%`,\n height: `${resizePosition ? resizePosition.height : event.position.height}%`,\n width: '100%',\n },\n })}\n />\n );\n });\n\n const dayEvents = (weekEvents.regularEvents[day] || []).map((event) => {\n const eventIsAllDay = isAllDayEvent({ event, date: day });\n const isDraggable = !eventIsAllDay && dragDrop.isDraggableEvent(event);\n const isResizable = !eventIsAllDay && eventResize.isResizableEvent(event);\n const resizePosition = eventResize.getResizePosition(event.id);\n const eventTop = resizePosition ? resizePosition.top : event.position.top;\n const eventHeight = resizePosition ? resizePosition.height : event.position.height;\n\n return (\n <ScheduleEvent\n key={event.id}\n event={event}\n autoSize\n hanging={event.position.hanging}\n draggable={isDraggable}\n withResize={isResizable}\n isResizing={resizePosition !== null}\n onResizeStart={\n isResizable\n ? (edge, e) => {\n const container = daySlotsContainersRef.current[dayIndex];\n if (container) {\n eventResize.handleResizeStart({\n event,\n edge,\n container,\n originalTop: event.position.top,\n originalHeight: event.position.height,\n eventDate: dayjs(day).format('YYYY-MM-DD'),\n pointerEvent: e,\n });\n }\n }\n : undefined\n }\n renderEventBody={renderEventBody}\n renderEvent={renderEvent}\n radius={radius}\n mode={mode}\n onClick={\n onEventClick\n ? (e) => {\n if (!eventResize.wasResizing()) {\n onEventClick(event, e);\n }\n }\n : undefined\n }\n mod={{ cascade: eventOverlapMode === 'cascade' }}\n style={{\n position: 'absolute',\n ...getTimeAxisEventStyle({\n start: eventTop,\n span: eventHeight,\n axis: 'vertical',\n }),\n left: `${event.position.offset}%`,\n width: `${event.position.width}%`,\n '--event-z-index': event.position.column + 3,\n '--event-z-index-raised': event.position.overlaps + 3,\n }}\n />\n );\n });\n\n return (\n <WeekViewDay\n key={day}\n day={day}\n dayIndex={dayIndex}\n slots={slots}\n intervalMinutes={intervalMinutes}\n getStyles={getStyles}\n weekendDays={weekendDays}\n highlightBusinessHours={highlightBusinessHours}\n businessHours={businessHours}\n labels={labels}\n withEventsDragAndDrop={withDragHandlers}\n mode={mode}\n slotsRef={slotsRef}\n firstSlotIndex={firstSlotIndex}\n onSlotKeyDown={handleSlotKeyDown}\n onSlotClick={handleTimeSlotClick}\n onFirstSlotArrowUp={\n withAllDaySlots\n ? (dayIdx) => {\n allDaySlotsRef.current[dayIdx]?.focus();\n }\n : undefined\n }\n onDaySlotsDragOver={(event, dayStr, dayIdx) => {\n const slotIndex = getSlotIndexFromDragPoint(event, dayIdx);\n if (slotIndex !== null) {\n dragDrop.handleDragOver(event, { day: dayStr, slotIndex });\n updateDragPreview({ day: dayStr, slotIndex });\n }\n }}\n onDaySlotsDragLeave={dragDrop.handleDragLeave}\n onDaySlotsDrop={(event, dayStr, dayIdx) => {\n const slotIndex = getSlotIndexFromDragPoint(event, dayIdx);\n if (slotIndex !== null) {\n dragDrop.handleDrop(event, { day: dayStr, slotIndex });\n }\n }}\n dropTargetSlotIndex={\n !suppressDropHighlight && dragDrop.dropTarget?.day === day\n ? dragDrop.dropTarget.slotIndex\n : undefined\n }\n withDragSlotSelect={withDragSlotSelect}\n onSlotPointerDown={slotDragSelect.handleSlotPointerDown}\n isSlotDragSelected={slotDragSelect.isSlotSelected}\n daySlotsContainerRef={(node) => {\n daySlotsContainersRef.current[dayIndex] = node;\n }}\n getTimeSlotProps={getTimeSlotProps}\n >\n {backgroundEventNodes}\n {dayEvents}\n {dragDrop.dragPreview?.target.day === day && dragDrop.dragContextValue.draggedEvent && (\n <Box\n {...getStyles('weekViewDragPreview', {\n style: (() => {\n const { top, height } = getDayPosition({\n event: {\n ...dragDrop.dragContextValue.draggedEvent,\n start: dragDrop.dragPreview.start,\n end: dragDrop.dragPreview.end,\n },\n startTime,\n endTime,\n intervalMinutes,\n });\n return {\n position: 'absolute',\n insetInlineStart: 0,\n insetInlineEnd: 0,\n top: `${top}%`,\n height: `${height}%`,\n };\n })(),\n })}\n />\n )}\n </WeekViewDay>\n );\n });\n\n const allDaySlots = weekdays.map((day, dayIndex) => (\n <UnstyledButton\n aria-label={`${getLabel('allDay', labels)} ${dayjs(day).format('YYYY-MM-DD')}`}\n key={day}\n ref={(node) => {\n allDaySlotsRef.current[dayIndex] = node!;\n }}\n tabIndex={dayIndex === 0 ? 0 : -1}\n onKeyDown={(event) => handleAllDaySlotKeyDown(event, dayIndex)}\n onClick={\n mode === 'static' || !onAllDaySlotClick\n ? undefined\n : (e) => onAllDaySlotClick(dayjs(day).format('YYYY-MM-DD'), e)\n }\n onDragOver={withDragHandlers ? (e) => allDayDragDrop.handleDragOver(e, day) : undefined}\n onDragLeave={withDragHandlers ? allDayDragDrop.handleDragLeave : undefined}\n onDrop={withDragHandlers ? (e) => allDayDragDrop.handleDrop(e, day) : undefined}\n {...getStyles('weekViewDaySlot')}\n mod={{ 'drop-target': allDayDragDrop.isDropTarget(day) }}\n />\n ));\n\n const allDayEventIds = useMemo(\n () => new Set(weekEvents.allDayEvents.map((e) => e.id)),\n [weekEvents.allDayEvents]\n );\n\n const allDayEvents = weekEvents.allDayEvents.map((event) => (\n <ScheduleEvent\n key={event.id}\n event={event}\n autoSize\n nowrap\n hanging={event.position.hanging}\n draggable={allDayDragDrop.isDraggableEvent(event)}\n renderEvent={renderEvent}\n mode={mode}\n onClick={onEventClick ? (e) => onEventClick(event, e) : undefined}\n style={{\n position: 'absolute',\n zIndex: 2,\n top: `calc(${event.position.row * 50}% + 1px)`,\n left: `calc(${event.position.offset}% + 1px)`,\n width: `calc(${event.position.width}% - 1px)`,\n height: 'calc(50% - 2px)',\n maxHeight: 'calc(50% - 2px)',\n }}\n />\n ));\n\n const allDayBackgroundEventNodes = weekdays.flatMap((day, dayIndex) => {\n const allDayBgEvents = (weekEvents.backgroundEvents[day] || []).filter(\n (event) => event.position.allDay\n );\n const dayWidth = 100 / weekdays.length;\n const dayOffset = dayIndex * dayWidth;\n\n return allDayBgEvents.map((event) => (\n <ScheduleBackgroundEvent\n key={`bg-allday-${event.id}-${day}`}\n event={event}\n renderEvent={renderEvent}\n renderEventBody={renderEventBody}\n interactive={interactiveBackgroundEvents}\n onEventClick={onEventClick}\n {...getStyles('weekViewBackgroundEvent', {\n style: {\n top: 0,\n height: '100%',\n left: `${dayOffset}%`,\n width: `${dayWidth}%`,\n },\n })}\n />\n ));\n });\n\n // Extra rows show on hover = total rows - 2 visible rows (starts from 0, so -1)\n const extraRows = Math.max(...weekEvents.allDayEvents.map((event) => event.position.row), 1) - 1;\n\n const content = (\n <Box\n {...getStyles('weekView')}\n mod={{ static: mode === 'static', 'slot-dragging': slotDragSelect.isDragging }}\n {...others}\n >\n {withHeader && (\n <ScheduleHeaderBase\n view=\"week\"\n navigationHandlers={{\n previous: () => previousWeek(date, ctx.getFirstDayOfWeek(firstDayOfWeek)),\n next: () => nextWeek(date, ctx.getFirstDayOfWeek(firstDayOfWeek)),\n today: () => toDateString(resolveNow()),\n }}\n control={{\n miw: 140,\n title: getWeekLabel({\n weekdays,\n locale: ctx.getLocale(locale),\n weekLabelFormat,\n renderWeekLabel,\n }),\n }}\n labels={labels}\n onDateChange={onDateChange}\n onViewChange={onViewChange}\n previousControlProps={previousControlProps}\n nextControlProps={nextControlProps}\n todayControlProps={todayControlProps}\n viewSelectProps={viewSelectProps}\n stylesApiProps={stylesApiProps}\n onAgendaClick={withAgenda ? () => setAgendaOpen((v) => !v) : undefined}\n agendaActive={agendaOpen}\n />\n )}\n\n {agendaOpen && (\n <AgendaView\n rangeStart={dayjs(weekdays[0]).format('YYYY-MM-DD')}\n rangeEnd={dayjs(weekdays[weekdays.length - 1]).format('YYYY-MM-DD')}\n events={events}\n locale={locale}\n labels={labels}\n mode={mode}\n onEventClick={onEventClick}\n recurrenceExpansionLimit={recurrenceExpansionLimit}\n {...stylesApiProps}\n />\n )}\n\n {!agendaOpen && (\n <Box\n {...getStyles('weekViewRoot')}\n __vars={{\n '--event-raise-delay': `${eventOverlapRaiseDelay}ms`,\n '--indicator-offset-index':\n currentWeekdayIndex === -1 ? undefined : `${currentWeekdayIndex + 1}`,\n '--number-of-days': withWeekendDays\n ? '7'\n : `${7 - ctx.getWeekendDays(weekendDays).length}`,\n }}\n mod={{\n 'with-weekends': withWeekendDays,\n 'hide-sub-hour-grid-lines': !withSubHourGridLines,\n 'event-interaction': eventResize.isResizing || dragDrop.dragContextValue.isDragging,\n 'all-day-dragging': allDayDragDrop.dragContextValue.isDragging,\n }}\n >\n <ScrollArea.Autosize\n scrollbarSize={4}\n {...scrollAreaProps}\n {...getStyles('weekViewScrollArea', {\n className: scrollAreaProps?.className,\n style: scrollAreaProps?.style,\n })}\n onScrollPositionChange={(position) => {\n scrollAreaProps?.onScrollPositionChange?.(position);\n setScrolled(position.y !== 0);\n }}\n viewportRef={mergedViewportRef}\n >\n <Box {...getStyles('weekViewHeader')} mod={{ scrolled }}>\n <div {...getStyles('weekViewCorner')} key=\"corner\">\n {withWeekNumber && (\n <>\n <div {...getStyles('weekViewWeekLabel')}>{getLabel('week', labels)}</div>\n <div {...getStyles('weekViewWeekNumber')}>{getWeekNumber(date)}</div>\n </>\n )}\n </div>\n\n {weekdaysLabels}\n </Box>\n\n {withAllDaySlots && (\n <div {...getStyles('weekViewAllDaySlots')}>\n <div {...getStyles('weekViewAllDaySlotsLabel')}>{getLabel('allDay', labels)}</div>\n <div {...getStyles('weekViewAllDaySlotsList')}>\n {allDayBackgroundEventNodes}\n <Box\n {...getStyles('weekViewAllDaySlotsEvents')}\n __vars={{ '--extra-rows': `${extraRows}` }}\n >\n {allDayEvents}\n </Box>\n {allDaySlots}\n </div>\n </div>\n )}\n\n <div {...getStyles('weekViewInner')}>\n <div {...getStyles('weekViewSlotLabels')}>{timeValues}</div>\n\n {withCurrentTimeIndicator && currentWeekdayIndex !== -1 && (\n <CurrentTimeIndicator\n startOffset=\"calc(100% - (100% / var(--number-of-days)) * (var(--number-of-days) - var(--indicator-offset-index) + 1) + ((var(--number-of-days) - var(--indicator-offset-index) + 1) * var(--indicator-labels-offset)))\"\n endOffset=\"calc((100% / var(--number-of-days)) * (var(--number-of-days) - var(--indicator-offset-index)) - (var(--number-of-days) - var(--indicator-offset-index)) * var(--indicator-labels-offset))\"\n timeBubbleStartOffset=\"calc(var(--week-view-slots-label-width) - var(--time-bubble-width))\"\n currentTimeFormat={slotLabelFormat}\n withTimeBubble={withCurrentTimeBubble}\n withThumb={withCurrentTimeBubble ? currentWeekdayIndex !== 0 : true}\n locale={locale}\n startTime={startTime}\n endTime={endTime}\n intervalMinutes={intervalMinutes}\n getCurrentTime={getCurrentTime}\n {...stylesApiProps}\n />\n )}\n {days}\n </div>\n </ScrollArea.Autosize>\n </Box>\n )}\n </Box>\n );\n\n const mergedDragContextValue = useMemo<DragContextValue>(\n () => ({\n isDragging:\n dragDrop.dragContextValue.isDragging || allDayDragDrop.dragContextValue.isDragging,\n draggedEventId:\n dragDrop.dragContextValue.draggedEventId ?? allDayDragDrop.dragContextValue.draggedEventId,\n draggedEvent:\n dragDrop.dragContextValue.draggedEvent ?? allDayDragDrop.dragContextValue.draggedEvent,\n dropTarget:\n dragDrop.dragContextValue.dropTarget ?? allDayDragDrop.dragContextValue.dropTarget,\n onDragStart: (event: ScheduleEventData) => {\n if (allDayEventIds.has(event.id)) {\n allDayDragDrop.handleDragStart(event);\n } else {\n dragDrop.handleDragStart(event);\n }\n },\n onDragEnd: () => {\n dragDrop.handleDragEnd();\n allDayDragDrop.handleDragEnd();\n },\n setDropTarget: dragDrop.dragContextValue.setDropTarget,\n }),\n [dragDrop.dragContextValue, allDayDragDrop.dragContextValue, allDayEventIds]\n );\n\n if (withEventsDragAndDrop) {\n return <DragContext.Provider value={mergedDragContextValue}>{content}</DragContext.Provider>;\n }\n\n return content;\n});\n\nWeekView.displayName = '@mantine/schedule/WeekView';\nWeekView.classes = classes;\nWeekView.varsResolver = varsResolver;\n\nexport namespace WeekView {\n export type Props = WeekViewProps;\n export type Factory = WeekViewFactory;\n export type StylesNames = WeekViewStylesNames;\n export type CssVariables = WeekViewCssVariables;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgUA,MAAM,eAAe;CACnB,kBAAkB;CAClB,iBAAiB;CACjB,0BAA0B;CAC1B,WAAW;CACX,SAAS;CACT,iBAAiB;CACjB,iBAAiB;CACjB,sBAAsB;CACtB,eAAe;CACf,gBAAgB;CAChB,uBAAuB;CACvB,iBAAiB;CACjB,YAAY;CACZ,iBAAiB;CACjB,wBAAwB;CACxB,eAAe,CAAC,YAAY,UAAU;CACtC,uBAAuB;CACvB,oBAAoB;CACpB,iBAAiB;CACjB,MAAM;CACN,iCAAiC;CACjC,kBAAkB;CAClB,wBAAwB;AAC1B;AAEA,MAAM,eAAe,oBAClB,QAAQ,EAAE,QAAQ,kBAAkB,kBAAkB,EACrD,UAAU;CACR,sBAAsB,WAAW,KAAA,IAAY,UAAU,MAAM,IAAI,KAAA;CACjE,oCAAoC,IAAI,gBAAgB;CACxD,2BAA2B,IAAI,UAAU;AAC3C,EACF,EACF;AAEA,MAAa,WAAW,SAA0B,WAAW;CAC3D,MAAM,QAAQ,SAAS,YAAY,cAAc,MAAM;CACvD,MAAM,EACJ,YACA,WACA,OACA,QACA,UACA,YACA,MACA,WACA,SACA,MACA,cACA,iBACA,sBACA,iBACA,iBACA,kBACA,wBACA,aACA,gBACA,eACA,QACA,gBACA,0BACA,2BACA,gBACA,iBACA,QACA,gBACA,uBACA,iBACA,kBACA,YACA,cACA,sBACA,kBACA,mBACA,iBACA,iBACA,QACA,kBACA,YACA,QACA,wBACA,eACA,iBACA,aACA,uBACA,aACA,cACA,mBACA,kBACA,gBACA,iBACA,mBACA,cACA,iCACA,oBACA,eACA,MACA,iBACA,iBACA,qBACA,iBACA,eACA,gBACA,qBACA,0BACA,kBACA,YACA,GAAG,WACD;CAEJ,MAAM,CAAC,YAAY,iBAAiB,SAAS,KAAK;CAElD,MAAM,YAAY,UAA2B;EAC3C,MAAM;EACN,SAAA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,cAAc;CAChB,CAAC;CAED,MAAM,EAAE,oBAAoB,mBAAmB,qBAAsC;EACnF;EACA;EACA;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"}
@@ -14,6 +14,7 @@ var WeekView_module_default = {
14
14
  "weekViewDayNumber": "m_d5b28558",
15
15
  "weekViewDayWeekday": "m_a0fc06f9",
16
16
  "weekViewBackgroundEvent": "m_41ce8f1f",
17
+ "weekViewBackgroundEventResizeHandle": "m_b20accbb",
17
18
  "weekViewDaySlots": "m_cd58ae46",
18
19
  "weekViewDragPreview": "m_e0da287",
19
20
  "weekViewDaySlot": "m_8ac0cbcd",
@@ -1 +1 @@
1
- {"version":3,"file":"WeekView.module.mjs","names":[],"sources":["../../../src/components/WeekView/WeekView.module.css"],"sourcesContent":[".weekView {\n --week-view-week-day-height: 58px;\n --week-view-all-day-slots-height: 48px;\n --week-view-radius: var(--schedule-radius, var(--mantine-radius-default));\n --week-view-slots-label-width: 80px;\n --week-view-min-slot-width: 80px;\n --week-view-slot-height: 64px;\n\n @mixin where-light {\n --week-view-border-color: var(--mantine-color-gray-3);\n --week-view-business-hours-bg: var(--mantine-color-white);\n --week-view-non-business-hours-bg: var(--mantine-color-gray-0);\n }\n\n @mixin where-dark {\n --week-view-border-color: var(--mantine-color-dark-4);\n --week-view-business-hours-bg: var(--mantine-color-dark-7);\n --week-view-non-business-hours-bg: var(--mantine-color-dark-6);\n }\n}\n\n.weekViewRoot {\n --indicator-labels-offset: calc(var(--week-view-slots-label-width) / var(--number-of-days));\n\n border: 1px solid var(--week-view-border-color);\n border-radius: var(--week-view-radius);\n overflow: hidden;\n}\n\n.weekViewInner {\n display: flex;\n position: relative;\n overflow: hidden;\n}\n\n.weekViewScrollArea {\n :where(:global(.mantine-ScrollArea-scrollbar)) {\n z-index: 4;\n }\n}\n\n.weekViewHeader {\n display: flex;\n position: sticky;\n top: 0;\n z-index: 4;\n background-color: var(--mantine-color-body);\n border-bottom: 1px solid var(--week-view-border-color);\n margin-bottom: -1px;\n transition: box-shadow 100ms ease;\n\n &:where([data-scrolled]) {\n box-shadow: var(--mantine-shadow-sm);\n }\n}\n\n.weekViewCorner {\n height: var(--week-view-week-day-height);\n flex: 0 0 var(--week-view-slots-label-width);\n min-width: var(--week-view-slots-label-width);\n line-height: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n}\n\n.weekViewSlotLabels {\n flex: 0 0 var(--week-view-slots-label-width);\n min-width: var(--week-view-slots-label-width);\n background-color: var(--mantine-color-body);\n}\n\n.weekViewSlotLabel {\n border-top: 1px solid var(--week-view-border-color);\n text-align: right;\n height: var(--week-view-slot-height);\n padding: 4px;\n padding-inline-end: 8px;\n font-size: var(--mantine-font-size-sm);\n user-select: none;\n cursor: default;\n font-variant-numeric: tabular-nums;\n text-transform: uppercase;\n\n &:where([data-business-hours]) {\n background-color: var(--week-view-business-hours-bg);\n }\n\n &:where([data-non-business-hours]) {\n background-color: var(--week-view-non-business-hours-bg);\n }\n}\n\n.weekViewDay {\n flex: 1;\n border-inline-start: 1px solid var(--week-view-border-color);\n}\n\n.weekViewDayLabel {\n height: var(--week-view-week-day-height);\n min-width: var(--week-view-min-slot-width);\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n font-weight: var(--mantine-font-weight-medium);\n user-select: none;\n cursor: pointer;\n flex: 1;\n border-inline-start: 1px solid var(--week-view-border-color);\n padding-inline-start: 5px;\n\n &:where([data-weekend]) {\n color: var(--mantine-color-error);\n }\n\n &:where([data-today]) {\n gap: 6px;\n }\n\n @mixin hover {\n @mixin where-light {\n background-color: var(--mantine-color-gray-0);\n }\n\n @mixin where-dark {\n background-color: var(--mantine-color-dark-6);\n }\n }\n\n &:where([data-static]) {\n cursor: default;\n pointer-events: none;\n }\n}\n\n.weekViewDayNumber {\n text-align: center;\n width: 26px;\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 100%;\n font-size: var(--mantine-font-size-sm);\n\n :where(.weekViewDayLabel[data-today]) & {\n background-color: var(--mantine-primary-color-filled);\n color: var(--mantine-primary-color-contrast);\n }\n}\n\n.weekViewDayWeekday {\n text-align: center;\n font-size: var(--mantine-font-size-sm);\n text-transform: capitalize;\n}\n\n.weekViewBackgroundEvent {\n position: absolute;\n pointer-events: none;\n z-index: 2;\n border-radius: var(--week-view-radius);\n background-color: var(--bg-event-bg);\n overflow: hidden;\n font-size: 12px;\n font-weight: var(--mantine-font-weight-medium);\n padding: 3px 4px;\n color: var(--bg-event-color);\n\n &:where([data-interactive]) {\n pointer-events: auto;\n cursor: pointer;\n user-select: none;\n\n @mixin hover {\n background-color: var(--bg-event-hover);\n }\n }\n}\n\n.weekView:where([data-slot-dragging]) .weekViewBackgroundEvent,\n.weekViewRoot:where([data-event-interaction]) .weekViewBackgroundEvent,\n.weekViewRoot:where([data-all-day-dragging]) .weekViewBackgroundEvent {\n pointer-events: none;\n}\n\n.weekViewDaySlots {\n position: relative;\n\n /* Cascade events stack with an unbounded z-index, keep them out of the sticky header's layer */\n &:where(:has([data-cascade])) {\n isolation: isolate;\n\n /* Drag and resize feedback must stay above every cascade column */\n --event-cascade-interaction-z-index: 999;\n\n .weekViewDragPreview {\n z-index: var(--event-cascade-interaction-z-index);\n }\n }\n}\n\n.weekViewDaySlot {\n display: block;\n width: 100%;\n border-top: 1px solid var(--week-view-border-color);\n height: calc(var(--week-view-slot-height) * var(--slot-size, 1));\n min-width: var(--week-view-min-slot-width);\n padding: 4px;\n cursor: pointer;\n position: relative;\n\n &:where(:focus) {\n z-index: 1;\n }\n\n @mixin hover {\n @mixin where-light {\n background-color: var(--mantine-color-gray-1);\n }\n\n @mixin where-dark {\n background-color: var(--mantine-color-dark-5);\n }\n }\n\n &:where([data-business-hours]) {\n background-color: var(--week-view-business-hours-bg);\n }\n\n &:where([data-non-business-hours]) {\n background-color: var(--week-view-non-business-hours-bg);\n }\n\n &:where([data-drop-target]) {\n @mixin where-light {\n background-color: var(--mantine-color-blue-1);\n }\n\n @mixin where-dark {\n background-color: var(--mantine-color-dark-5);\n }\n\n &::before {\n content: '';\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 2;\n border: 1px solid;\n border-radius: 2px;\n\n @mixin where-light {\n border-color: var(--mantine-color-blue-4);\n }\n\n @mixin where-dark {\n border-color: var(--mantine-color-blue-6);\n }\n }\n }\n\n &:where([data-drag-selected]) {\n &,\n &:hover {\n background-color: var(--mantine-primary-color-light);\n }\n\n &::before {\n content: '';\n position: absolute;\n inset: -1px;\n pointer-events: none;\n z-index: 2;\n border: 1px solid;\n\n @mixin where-light {\n border-color: var(--mantine-primary-color-2);\n }\n\n @mixin where-dark {\n border-color: var(--mantine-primary-color-9);\n }\n }\n }\n\n &:where([data-drag-slot-index]) {\n touch-action: none;\n }\n\n &:where([data-static]) {\n cursor: default;\n pointer-events: none;\n }\n}\n\n.weekViewDaySlots .weekViewDaySlot {\n border-top-style: dotted;\n\n &:where([data-hour-start]) {\n border-top-style: solid;\n }\n}\n\n.weekViewRoot:where([data-hide-sub-hour-grid-lines])\n .weekViewDaySlots\n .weekViewDaySlot:not([data-hour-start]) {\n border-top-color: transparent;\n}\n\n.weekViewRoot:where([data-event-interaction]) .weekViewDaySlots .weekViewDaySlot {\n pointer-events: none;\n}\n\n.weekViewWeekLabel {\n text-align: center;\n margin-bottom: 4px;\n font-size: var(--mantine-font-size-sm);\n}\n\n.weekViewWeekNumber {\n font-weight: var(--mantine-font-weight-medium);\n text-align: center;\n font-size: var(--mantine-font-size-lg);\n}\n\n.weekViewAllDaySlots {\n display: flex;\n height: var(--week-view-all-day-slots-height);\n}\n\n.weekViewAllDaySlotsLabel {\n flex: 0 0 var(--week-view-slots-label-width);\n text-align: right;\n padding: 4px 8px;\n font-size: var(--mantine-font-size-sm);\n}\n\n.weekViewAllDaySlotsEvents {\n position: absolute;\n inset: 0;\n overflow: hidden;\n pointer-events: none;\n}\n\n.weekViewAllDaySlotsList {\n position: relative;\n width: 100%;\n height: 100%;\n display: flex;\n\n & > .weekViewDaySlot {\n flex: 1;\n border-inline-start: 1px solid var(--week-view-border-color);\n height: 100%;\n }\n\n &:hover,\n &:focus-within {\n .weekViewAllDaySlotsEvents {\n overflow: visible;\n\n &::before {\n content: '';\n position: absolute;\n top: 100%;\n height: calc(var(--week-view-all-day-slots-height) / 2 * var(--extra-rows));\n inset-inline: 0;\n z-index: 1;\n pointer-events: all;\n }\n }\n }\n}\n\n.weekViewDragPreview {\n pointer-events: none;\n z-index: 3;\n border-radius: var(--week-view-radius);\n border: 1px dashed var(--mantine-color-blue-filled);\n background-color: var(--mantine-color-blue-light);\n opacity: 0.6;\n}\n"],"mappings":""}
1
+ {"version":3,"file":"WeekView.module.mjs","names":[],"sources":["../../../src/components/WeekView/WeekView.module.css"],"sourcesContent":[".weekView {\n --week-view-week-day-height: 58px;\n --week-view-all-day-slots-height: 48px;\n --week-view-radius: var(--schedule-radius, var(--mantine-radius-default));\n --week-view-slots-label-width: 80px;\n --week-view-min-slot-width: 80px;\n --week-view-slot-height: 64px;\n\n @mixin where-light {\n --week-view-border-color: var(--mantine-color-gray-3);\n --week-view-business-hours-bg: var(--mantine-color-white);\n --week-view-non-business-hours-bg: var(--mantine-color-gray-0);\n }\n\n @mixin where-dark {\n --week-view-border-color: var(--mantine-color-dark-4);\n --week-view-business-hours-bg: var(--mantine-color-dark-7);\n --week-view-non-business-hours-bg: var(--mantine-color-dark-6);\n }\n}\n\n.weekViewRoot {\n --indicator-labels-offset: calc(var(--week-view-slots-label-width) / var(--number-of-days));\n\n border: 1px solid var(--week-view-border-color);\n border-radius: var(--week-view-radius);\n overflow: hidden;\n}\n\n.weekViewInner {\n display: flex;\n position: relative;\n overflow: hidden;\n}\n\n.weekViewScrollArea {\n :where(:global(.mantine-ScrollArea-scrollbar)) {\n z-index: 4;\n }\n}\n\n.weekViewHeader {\n display: flex;\n position: sticky;\n top: 0;\n z-index: 4;\n background-color: var(--mantine-color-body);\n border-bottom: 1px solid var(--week-view-border-color);\n margin-bottom: -1px;\n transition: box-shadow 100ms ease;\n\n &:where([data-scrolled]) {\n box-shadow: var(--mantine-shadow-sm);\n }\n}\n\n.weekViewCorner {\n height: var(--week-view-week-day-height);\n flex: 0 0 var(--week-view-slots-label-width);\n min-width: var(--week-view-slots-label-width);\n line-height: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n}\n\n.weekViewSlotLabels {\n flex: 0 0 var(--week-view-slots-label-width);\n min-width: var(--week-view-slots-label-width);\n background-color: var(--mantine-color-body);\n}\n\n.weekViewSlotLabel {\n border-top: 1px solid var(--week-view-border-color);\n text-align: right;\n height: var(--week-view-slot-height);\n padding: 4px;\n padding-inline-end: 8px;\n font-size: var(--mantine-font-size-sm);\n user-select: none;\n cursor: default;\n font-variant-numeric: tabular-nums;\n text-transform: uppercase;\n\n &:where([data-business-hours]) {\n background-color: var(--week-view-business-hours-bg);\n }\n\n &:where([data-non-business-hours]) {\n background-color: var(--week-view-non-business-hours-bg);\n }\n}\n\n.weekViewDay {\n flex: 1;\n border-inline-start: 1px solid var(--week-view-border-color);\n}\n\n.weekViewDayLabel {\n height: var(--week-view-week-day-height);\n min-width: var(--week-view-min-slot-width);\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n font-weight: var(--mantine-font-weight-medium);\n user-select: none;\n cursor: pointer;\n flex: 1;\n border-inline-start: 1px solid var(--week-view-border-color);\n padding-inline-start: 5px;\n\n &:where([data-weekend]) {\n color: var(--mantine-color-error);\n }\n\n &:where([data-today]) {\n gap: 6px;\n }\n\n @mixin hover {\n @mixin where-light {\n background-color: var(--mantine-color-gray-0);\n }\n\n @mixin where-dark {\n background-color: var(--mantine-color-dark-6);\n }\n }\n\n &:where([data-static]) {\n cursor: default;\n pointer-events: none;\n }\n}\n\n.weekViewDayNumber {\n text-align: center;\n width: 26px;\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 100%;\n font-size: var(--mantine-font-size-sm);\n\n :where(.weekViewDayLabel[data-today]) & {\n background-color: var(--mantine-primary-color-filled);\n color: var(--mantine-primary-color-contrast);\n }\n}\n\n.weekViewDayWeekday {\n text-align: center;\n font-size: var(--mantine-font-size-sm);\n text-transform: capitalize;\n}\n\n.weekViewBackgroundEvent {\n position: absolute;\n pointer-events: none;\n z-index: 2;\n border-radius: var(--week-view-radius);\n background-color: var(--bg-event-bg);\n overflow: hidden;\n font-size: 12px;\n font-weight: var(--mantine-font-weight-medium);\n padding: 3px 4px;\n color: var(--bg-event-color);\n\n &:where([data-interactive]) {\n pointer-events: auto;\n cursor: pointer;\n user-select: none;\n\n @mixin hover {\n background-color: var(--bg-event-hover);\n }\n }\n\n /* The resized edge repeatedly crosses the pointer, so hover feedback would flicker */\n &:where([data-resizing]) {\n @mixin hover {\n background-color: var(--bg-event-bg);\n }\n }\n}\n\n.weekViewBackgroundEventResizeHandle {\n position: absolute;\n left: 50%;\n transform: translateX(-50%);\n width: 40%;\n max-width: 40px;\n height: 4px;\n border-radius: 2px;\n cursor: ns-resize;\n pointer-events: all;\n z-index: 4;\n touch-action: none;\n background-color: var(--bg-event-color);\n opacity: 0;\n transition: opacity 100ms ease;\n\n &::before {\n content: '';\n position: absolute;\n inset: -4px -6px;\n }\n\n &:where([data-edge='top']) {\n top: 0;\n }\n\n &:where([data-edge='bottom']) {\n bottom: 0;\n }\n\n .weekViewBackgroundEvent:where(:hover, [data-resizing]) & {\n opacity: 0.5;\n }\n\n @mixin hover {\n opacity: 0.8;\n }\n}\n\n/* The resizing background event is the one that set `data-event-interaction`, so it must\n keep capturing pointer events. */\n.weekView:where([data-slot-dragging]) .weekViewBackgroundEvent:not([data-resizing]),\n.weekViewRoot:where([data-event-interaction]) .weekViewBackgroundEvent:not([data-resizing]),\n.weekViewRoot:where([data-all-day-dragging]) .weekViewBackgroundEvent:not([data-resizing]) {\n pointer-events: none;\n\n & .weekViewBackgroundEventResizeHandle {\n pointer-events: none;\n opacity: 0;\n }\n}\n\n.weekViewDaySlots {\n position: relative;\n\n /* Cascade events stack with an unbounded z-index, keep them out of the sticky header's layer */\n &:where(:has([data-cascade])) {\n isolation: isolate;\n\n /* Drag and resize feedback must stay above every cascade column */\n --event-cascade-interaction-z-index: 999;\n\n .weekViewDragPreview {\n z-index: var(--event-cascade-interaction-z-index);\n }\n }\n}\n\n.weekViewDaySlot {\n display: block;\n width: 100%;\n border-top: 1px solid var(--week-view-border-color);\n height: calc(var(--week-view-slot-height) * var(--slot-size, 1));\n min-width: var(--week-view-min-slot-width);\n padding: 4px;\n cursor: pointer;\n position: relative;\n\n &:where(:focus) {\n z-index: 1;\n }\n\n @mixin hover {\n @mixin where-light {\n background-color: var(--mantine-color-gray-1);\n }\n\n @mixin where-dark {\n background-color: var(--mantine-color-dark-5);\n }\n }\n\n &:where([data-business-hours]) {\n background-color: var(--week-view-business-hours-bg);\n }\n\n &:where([data-non-business-hours]) {\n background-color: var(--week-view-non-business-hours-bg);\n }\n\n &:where([data-drop-target]) {\n @mixin where-light {\n background-color: var(--mantine-color-blue-1);\n }\n\n @mixin where-dark {\n background-color: var(--mantine-color-dark-5);\n }\n\n &::before {\n content: '';\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 2;\n border: 1px solid;\n border-radius: 2px;\n\n @mixin where-light {\n border-color: var(--mantine-color-blue-4);\n }\n\n @mixin where-dark {\n border-color: var(--mantine-color-blue-6);\n }\n }\n }\n\n &:where([data-drag-selected]) {\n &,\n &:hover {\n background-color: var(--mantine-primary-color-light);\n }\n\n &::before {\n content: '';\n position: absolute;\n inset: -1px;\n pointer-events: none;\n z-index: 2;\n border: 1px solid;\n\n @mixin where-light {\n border-color: var(--mantine-primary-color-2);\n }\n\n @mixin where-dark {\n border-color: var(--mantine-primary-color-9);\n }\n }\n }\n\n &:where([data-drag-slot-index]) {\n touch-action: none;\n }\n\n &:where([data-static]) {\n cursor: default;\n pointer-events: none;\n }\n}\n\n.weekViewDaySlots .weekViewDaySlot {\n border-top-style: dotted;\n\n &:where([data-hour-start]) {\n border-top-style: solid;\n }\n}\n\n.weekViewRoot:where([data-hide-sub-hour-grid-lines])\n .weekViewDaySlots\n .weekViewDaySlot:not([data-hour-start]) {\n border-top-color: transparent;\n}\n\n.weekViewRoot:where([data-event-interaction]) .weekViewDaySlots .weekViewDaySlot {\n pointer-events: none;\n}\n\n.weekViewWeekLabel {\n text-align: center;\n margin-bottom: 4px;\n font-size: var(--mantine-font-size-sm);\n}\n\n.weekViewWeekNumber {\n font-weight: var(--mantine-font-weight-medium);\n text-align: center;\n font-size: var(--mantine-font-size-lg);\n}\n\n.weekViewAllDaySlots {\n display: flex;\n height: var(--week-view-all-day-slots-height);\n}\n\n.weekViewAllDaySlotsLabel {\n flex: 0 0 var(--week-view-slots-label-width);\n text-align: right;\n padding: 4px 8px;\n font-size: var(--mantine-font-size-sm);\n}\n\n.weekViewAllDaySlotsEvents {\n position: absolute;\n inset: 0;\n overflow: hidden;\n pointer-events: none;\n}\n\n.weekViewAllDaySlotsList {\n position: relative;\n width: 100%;\n height: 100%;\n display: flex;\n\n & > .weekViewDaySlot {\n flex: 1;\n border-inline-start: 1px solid var(--week-view-border-color);\n height: 100%;\n }\n\n &:hover,\n &:focus-within {\n .weekViewAllDaySlotsEvents {\n overflow: visible;\n\n &::before {\n content: '';\n position: absolute;\n top: 100%;\n height: calc(var(--week-view-all-day-slots-height) / 2 * var(--extra-rows));\n inset-inline: 0;\n z-index: 1;\n pointer-events: all;\n }\n }\n }\n}\n\n.weekViewDragPreview {\n pointer-events: none;\n z-index: 3;\n border-radius: var(--week-view-radius);\n border: 1px dashed var(--mantine-color-blue-filled);\n background-color: var(--mantine-color-blue-light);\n opacity: 0.6;\n}\n"],"mappings":""}
@@ -4,7 +4,7 @@ import { parseTimeString } from "../utils/parse-time-string/parse-time-string.mj
4
4
  import dayjs from "dayjs";
5
5
  import { useCallback, useEffect, useEffectEvent, useRef, useState } from "react";
6
6
  //#region packages/@mantine/schedule/src/hooks/use-event-resize.ts
7
- function useEventResize({ enabled = false, mode = "default", startTime, endTime, intervalMinutes, resizeIntervalMinutes, onEventResize, canResizeEvent }) {
7
+ function useEventResize({ enabled = false, mode = "default", startTime, endTime, intervalMinutes, resizeIntervalMinutes, onEventResize, canResizeEvent, withBackgroundEvents = false }) {
8
8
  const [resizeState, setResizeState] = useState(null);
9
9
  const resizeRef = useRef(null);
10
10
  const justResizedRef = useRef(false);
@@ -135,20 +135,23 @@ function useEventResize({ enabled = false, mode = "default", startTime, endTime,
135
135
  document.removeEventListener("pointerup", handlePointerUp);
136
136
  };
137
137
  }, [isResizing]);
138
- const getResizePosition = useCallback((eventId) => {
138
+ const getResizePosition = useCallback((eventId, eventDate) => {
139
139
  if (!resizeState || resizeState.eventId !== eventId) return null;
140
+ if (eventDate !== void 0 && resizeState.eventDate !== eventDate) return null;
140
141
  return {
141
142
  top: resizeState.currentTop,
142
143
  height: resizeState.currentHeight
143
144
  };
144
145
  }, [resizeState]);
145
146
  const isResizableEvent = useCallback((event) => {
146
- if (!enabled || mode === "static" || event.display === "background") return false;
147
+ if (!enabled || mode === "static") return false;
148
+ if (event.display === "background" && !withBackgroundEvents) return false;
147
149
  return canResizeEvent ? canResizeEvent(event) : true;
148
150
  }, [
149
151
  enabled,
150
152
  mode,
151
- canResizeEvent
153
+ canResizeEvent,
154
+ withBackgroundEvents
152
155
  ]);
153
156
  const wasResizing = useCallback(() => justResizedRef.current, []);
154
157
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"use-event-resize.mjs","names":[],"sources":["../../src/hooks/use-event-resize.ts"],"sourcesContent":["import dayjs from 'dayjs';\nimport { useCallback, useEffect, useEffectEvent, useRef, useState } from 'react';\nimport { DateTimeStringValue, ScheduleEventData, ScheduleMode } from '../types';\nimport { clampIntervalMinutes } from '../utils/clamp-interval-minutes/clamp-interval-minutes';\nimport { parseTimeString } from '../utils/parse-time-string/parse-time-string';\n\ntype ResizeEdge = 'top' | 'bottom';\n\ninterface ResizeState {\n eventId: string | number;\n event: ScheduleEventData;\n edge: ResizeEdge;\n container: HTMLElement;\n originalTop: number;\n originalHeight: number;\n currentTop: number;\n currentHeight: number;\n eventDate: string;\n originalStart: DateTimeStringValue;\n originalEnd: DateTimeStringValue;\n}\n\nexport interface UseEventResizeInput {\n enabled?: boolean;\n mode?: ScheduleMode;\n startTime: string;\n endTime: string;\n intervalMinutes: number;\n resizeIntervalMinutes?: number;\n onEventResize?: (data: {\n eventId: string | number;\n newStart: DateTimeStringValue;\n newEnd: DateTimeStringValue;\n event: ScheduleEventData;\n }) => void;\n canResizeEvent?: (event: ScheduleEventData) => boolean;\n}\n\nexport function useEventResize({\n enabled = false,\n mode = 'default',\n startTime,\n endTime,\n intervalMinutes,\n resizeIntervalMinutes,\n onEventResize,\n canResizeEvent,\n}: UseEventResizeInput) {\n const [resizeState, setResizeState] = useState<ResizeState | null>(null);\n const resizeRef = useRef<ResizeState | null>(null);\n const justResizedRef = useRef(false);\n const stableOnEventResize = useEffectEvent(onEventResize || (() => {}));\n\n const parsedStartTime = parseTimeString(startTime);\n const parsedEndTime = parseTimeString(endTime);\n const startMinutes = parsedStartTime.hours * 60 + parsedStartTime.minutes;\n const endMinutes = parsedEndTime.hours * 60 + parsedEndTime.minutes;\n const clampedInterval = clampIntervalMinutes(intervalMinutes);\n const clampedResizeInterval = clampIntervalMinutes(resizeIntervalMinutes ?? intervalMinutes);\n const literalRange = endMinutes - startMinutes;\n const totalMinutes = Math.ceil(literalRange / clampedInterval) * clampedInterval;\n\n // Snapping happens in absolute minutes from midnight – the same grid `calculateDropTime`\n // uses for drag and drop. Snapping relative to `startTime` would put resized edges on a\n // different grid than dragged events whenever `startTime` is not a multiple of the interval\n // (with `startTime=\"08:10\"` and a 30 minute step, drops land on :00/:30 but resizes on\n // :10/:40, so the two operations could never align an event).\n const clampAndSnap = useCallback(\n (minutes: number): number => {\n const snapped =\n Math.round((startMinutes + minutes) / clampedResizeInterval) * clampedResizeInterval;\n return Math.max(0, Math.min(literalRange, snapped - startMinutes));\n },\n [literalRange, clampedResizeInterval, startMinutes]\n );\n\n const percentToDateTime = useCallback(\n (percent: number, eventDate: string): DateTimeStringValue => {\n const minutes = (percent / 100) * totalMinutes;\n const snappedMinutes = clampAndSnap(minutes);\n const totalMins = startMinutes + snappedMinutes;\n const hours = Math.floor(totalMins / 60);\n const mins = totalMins % 60;\n return `${eventDate} ${String(hours).padStart(2, '0')}:${String(mins).padStart(2, '0')}:00`;\n },\n [totalMinutes, startMinutes, clampAndSnap]\n );\n\n const snapEdgeMinutes = useCallback(\n (minutes: number, direction: 'up' | 'down'): number => {\n const absolute = startMinutes + minutes;\n const snapped =\n direction === 'up'\n ? Math.ceil(absolute / clampedResizeInterval) * clampedResizeInterval\n : Math.floor(absolute / clampedResizeInterval) * clampedResizeInterval;\n return Math.max(0, Math.min(literalRange, snapped - startMinutes));\n },\n [literalRange, clampedResizeInterval, startMinutes]\n );\n\n const percentToMinutes = useCallback(\n (percent: number): number => (percent / 100) * totalMinutes,\n [totalMinutes]\n );\n\n const minutesToPercent = useCallback(\n (minutes: number): number => (minutes / totalMinutes) * 100,\n [totalMinutes]\n );\n\n const handleResizeStart = useCallback(\n ({\n event,\n edge,\n container,\n originalTop,\n originalHeight,\n eventDate,\n pointerEvent,\n }: {\n event: ScheduleEventData;\n edge: ResizeEdge;\n container: HTMLElement;\n originalTop: number;\n originalHeight: number;\n eventDate: string;\n pointerEvent: React.PointerEvent;\n }) => {\n if (!enabled || mode === 'static') {\n return;\n }\n\n pointerEvent.preventDefault();\n pointerEvent.stopPropagation();\n\n const state: ResizeState = {\n eventId: event.id,\n event,\n edge,\n container,\n originalTop,\n originalHeight,\n currentTop: originalTop,\n currentHeight: originalHeight,\n eventDate,\n originalStart: dayjs(event.start).format('YYYY-MM-DD HH:mm:ss'),\n originalEnd: dayjs(event.end).format('YYYY-MM-DD HH:mm:ss'),\n };\n\n resizeRef.current = state;\n setResizeState(state);\n },\n [enabled, mode]\n );\n\n const isResizing = resizeState !== null;\n\n useEffect(() => {\n if (!isResizing) {\n return undefined;\n }\n\n const savedUserSelect = document.body.style.userSelect;\n document.body.style.userSelect = 'none';\n\n const handlePointerMove = (e: PointerEvent) => {\n const state = resizeRef.current;\n if (!state) {\n return;\n }\n\n const containerRect = state.container.getBoundingClientRect();\n const relativeY = e.clientY - containerRect.top;\n const rawPercent = Math.max(0, Math.min(100, (relativeY / containerRect.height) * 100));\n const draggedMinutes = clampAndSnap(percentToMinutes(rawPercent));\n\n let newTop = state.originalTop;\n let newHeight = state.originalHeight;\n\n if (state.edge === 'bottom') {\n const topMinutes = percentToMinutes(state.originalTop);\n const minEndMinutes = snapEdgeMinutes(topMinutes + clampedResizeInterval, 'up');\n const endMinutes = Math.max(draggedMinutes, minEndMinutes);\n newHeight = Math.max(0, minutesToPercent(endMinutes) - state.originalTop);\n } else {\n const bottomMinutes = percentToMinutes(state.originalTop + state.originalHeight);\n const maxStartMinutes = snapEdgeMinutes(bottomMinutes - clampedResizeInterval, 'down');\n const startMinutesValue = Math.min(draggedMinutes, maxStartMinutes);\n newTop = minutesToPercent(startMinutesValue);\n newHeight = Math.max(0, state.originalTop + state.originalHeight - newTop);\n }\n\n resizeRef.current = { ...state, currentTop: newTop, currentHeight: newHeight };\n setResizeState(resizeRef.current);\n };\n\n const handlePointerUp = () => {\n const state = resizeRef.current;\n if (state) {\n if (\n state.currentTop !== state.originalTop ||\n state.currentHeight !== state.originalHeight\n ) {\n let newStart: DateTimeStringValue;\n let newEnd: DateTimeStringValue;\n\n if (state.edge === 'top') {\n newStart = percentToDateTime(state.currentTop, state.eventDate);\n newEnd = state.originalEnd;\n } else {\n newStart = state.originalStart;\n newEnd = percentToDateTime(state.currentTop + state.currentHeight, state.eventDate);\n }\n\n stableOnEventResize({\n eventId: state.eventId,\n newStart,\n newEnd,\n event: state.event,\n });\n }\n }\n resizeRef.current = null;\n setResizeState(null);\n justResizedRef.current = true;\n requestAnimationFrame(() => {\n justResizedRef.current = false;\n });\n };\n\n document.addEventListener('pointermove', handlePointerMove);\n document.addEventListener('pointerup', handlePointerUp);\n\n return () => {\n document.body.style.userSelect = savedUserSelect;\n document.removeEventListener('pointermove', handlePointerMove);\n document.removeEventListener('pointerup', handlePointerUp);\n };\n }, [isResizing]);\n\n const getResizePosition = useCallback(\n (eventId: string | number) => {\n if (!resizeState || resizeState.eventId !== eventId) {\n return null;\n }\n return { top: resizeState.currentTop, height: resizeState.currentHeight };\n },\n [resizeState]\n );\n\n const isResizableEvent = useCallback(\n (event: ScheduleEventData) => {\n if (!enabled || mode === 'static' || event.display === 'background') {\n return false;\n }\n return canResizeEvent ? canResizeEvent(event) : true;\n },\n [enabled, mode, canResizeEvent]\n );\n\n const wasResizing = useCallback(() => justResizedRef.current, []);\n\n return {\n handleResizeStart,\n isResizing,\n resizingEventId: resizeState?.eventId ?? null,\n getResizePosition,\n isResizableEvent,\n wasResizing,\n };\n}\n"],"mappings":";;;;;;AAsCA,SAAgB,eAAe,EAC7B,UAAU,OACV,OAAO,WACP,WACA,SACA,iBACA,uBACA,eACA,kBACsB;CACtB,MAAM,CAAC,aAAa,kBAAkB,SAA6B,IAAI;CACvE,MAAM,YAAY,OAA2B,IAAI;CACjD,MAAM,iBAAiB,OAAO,KAAK;CACnC,MAAM,sBAAsB,eAAe,wBAAwB,CAAC,EAAE;CAEtE,MAAM,kBAAkB,gBAAgB,SAAS;CACjD,MAAM,gBAAgB,gBAAgB,OAAO;CAC7C,MAAM,eAAe,gBAAgB,QAAQ,KAAK,gBAAgB;CAClE,MAAM,aAAa,cAAc,QAAQ,KAAK,cAAc;CAC5D,MAAM,kBAAkB,qBAAqB,eAAe;CAC5D,MAAM,wBAAwB,qBAAqB,yBAAyB,eAAe;CAC3F,MAAM,eAAe,aAAa;CAClC,MAAM,eAAe,KAAK,KAAK,eAAe,eAAe,IAAI;CAOjE,MAAM,eAAe,aAClB,YAA4B;EAC3B,MAAM,UACJ,KAAK,OAAO,eAAe,WAAW,qBAAqB,IAAI;EACjE,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,cAAc,UAAU,YAAY,CAAC;CACnE,GACA;EAAC;EAAc;EAAuB;CAAY,CACpD;CAEA,MAAM,oBAAoB,aACvB,SAAiB,cAA2C;EAC3D,MAAM,UAAW,UAAU,MAAO;EAClC,MAAM,iBAAiB,aAAa,OAAO;EAC3C,MAAM,YAAY,eAAe;EACjC,MAAM,QAAQ,KAAK,MAAM,YAAY,EAAE;EACvC,MAAM,OAAO,YAAY;EACzB,OAAO,GAAG,UAAU,GAAG,OAAO,KAAK,CAAC,CAAC,SAAS,GAAG,GAAG,EAAE,GAAG,OAAO,IAAI,CAAC,CAAC,SAAS,GAAG,GAAG,EAAE;CACzF,GACA;EAAC;EAAc;EAAc;CAAY,CAC3C;CAEA,MAAM,kBAAkB,aACrB,SAAiB,cAAqC;EACrD,MAAM,WAAW,eAAe;EAChC,MAAM,UACJ,cAAc,OACV,KAAK,KAAK,WAAW,qBAAqB,IAAI,wBAC9C,KAAK,MAAM,WAAW,qBAAqB,IAAI;EACrD,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,cAAc,UAAU,YAAY,CAAC;CACnE,GACA;EAAC;EAAc;EAAuB;CAAY,CACpD;CAEA,MAAM,mBAAmB,aACtB,YAA6B,UAAU,MAAO,cAC/C,CAAC,YAAY,CACf;CAEA,MAAM,mBAAmB,aACtB,YAA6B,UAAU,eAAgB,KACxD,CAAC,YAAY,CACf;CAEA,MAAM,oBAAoB,aACvB,EACC,OACA,MACA,WACA,aACA,gBACA,WACA,mBASI;EACJ,IAAI,CAAC,WAAW,SAAS,UACvB;EAGF,aAAa,eAAe;EAC5B,aAAa,gBAAgB;EAE7B,MAAM,QAAqB;GACzB,SAAS,MAAM;GACf;GACA;GACA;GACA;GACA;GACA,YAAY;GACZ,eAAe;GACf;GACA,eAAe,MAAM,MAAM,KAAK,CAAC,CAAC,OAAO,qBAAqB;GAC9D,aAAa,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,qBAAqB;EAC5D;EAEA,UAAU,UAAU;EACpB,eAAe,KAAK;CACtB,GACA,CAAC,SAAS,IAAI,CAChB;CAEA,MAAM,aAAa,gBAAgB;CAEnC,gBAAgB;EACd,IAAI,CAAC,YACH;EAGF,MAAM,kBAAkB,SAAS,KAAK,MAAM;EAC5C,SAAS,KAAK,MAAM,aAAa;EAEjC,MAAM,qBAAqB,MAAoB;GAC7C,MAAM,QAAQ,UAAU;GACxB,IAAI,CAAC,OACH;GAGF,MAAM,gBAAgB,MAAM,UAAU,sBAAsB;GAC5D,MAAM,YAAY,EAAE,UAAU,cAAc;GAC5C,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,IAAI,KAAM,YAAY,cAAc,SAAU,GAAG,CAAC;GACtF,MAAM,iBAAiB,aAAa,iBAAiB,UAAU,CAAC;GAEhE,IAAI,SAAS,MAAM;GACnB,IAAI,YAAY,MAAM;GAEtB,IAAI,MAAM,SAAS,UAAU;IAC3B,MAAM,aAAa,iBAAiB,MAAM,WAAW;IACrD,MAAM,gBAAgB,gBAAgB,aAAa,uBAAuB,IAAI;IAE9E,YAAY,KAAK,IAAI,GAAG,iBADL,KAAK,IAAI,gBAAgB,aACM,CAAC,IAAI,MAAM,WAAW;GAC1E,OAAO;IACL,MAAM,gBAAgB,iBAAiB,MAAM,cAAc,MAAM,cAAc;IAC/E,MAAM,kBAAkB,gBAAgB,gBAAgB,uBAAuB,MAAM;IAErF,SAAS,iBADiB,KAAK,IAAI,gBAAgB,eACT,CAAC;IAC3C,YAAY,KAAK,IAAI,GAAG,MAAM,cAAc,MAAM,iBAAiB,MAAM;GAC3E;GAEA,UAAU,UAAU;IAAE,GAAG;IAAO,YAAY;IAAQ,eAAe;GAAU;GAC7E,eAAe,UAAU,OAAO;EAClC;EAEA,MAAM,wBAAwB;GAC5B,MAAM,QAAQ,UAAU;GACxB,IAAI,OAEA;QAAA,MAAM,eAAe,MAAM,eAC3B,MAAM,kBAAkB,MAAM,gBAC9B;KACA,IAAI;KACJ,IAAI;KAEJ,IAAI,MAAM,SAAS,OAAO;MACxB,WAAW,kBAAkB,MAAM,YAAY,MAAM,SAAS;MAC9D,SAAS,MAAM;KACjB,OAAO;MACL,WAAW,MAAM;MACjB,SAAS,kBAAkB,MAAM,aAAa,MAAM,eAAe,MAAM,SAAS;KACpF;KAEA,oBAAoB;MAClB,SAAS,MAAM;MACf;MACA;MACA,OAAO,MAAM;KACf,CAAC;IACH;;GAEF,UAAU,UAAU;GACpB,eAAe,IAAI;GACnB,eAAe,UAAU;GACzB,4BAA4B;IAC1B,eAAe,UAAU;GAC3B,CAAC;EACH;EAEA,SAAS,iBAAiB,eAAe,iBAAiB;EAC1D,SAAS,iBAAiB,aAAa,eAAe;EAEtD,aAAa;GACX,SAAS,KAAK,MAAM,aAAa;GACjC,SAAS,oBAAoB,eAAe,iBAAiB;GAC7D,SAAS,oBAAoB,aAAa,eAAe;EAC3D;CACF,GAAG,CAAC,UAAU,CAAC;CAEf,MAAM,oBAAoB,aACvB,YAA6B;EAC5B,IAAI,CAAC,eAAe,YAAY,YAAY,SAC1C,OAAO;EAET,OAAO;GAAE,KAAK,YAAY;GAAY,QAAQ,YAAY;EAAc;CAC1E,GACA,CAAC,WAAW,CACd;CAEA,MAAM,mBAAmB,aACtB,UAA6B;EAC5B,IAAI,CAAC,WAAW,SAAS,YAAY,MAAM,YAAY,cACrD,OAAO;EAET,OAAO,iBAAiB,eAAe,KAAK,IAAI;CAClD,GACA;EAAC;EAAS;EAAM;CAAc,CAChC;CAEA,MAAM,cAAc,kBAAkB,eAAe,SAAS,CAAC,CAAC;CAEhE,OAAO;EACL;EACA;EACA,iBAAiB,aAAa,WAAW;EACzC;EACA;EACA;CACF;AACF"}
1
+ {"version":3,"file":"use-event-resize.mjs","names":[],"sources":["../../src/hooks/use-event-resize.ts"],"sourcesContent":["import dayjs from 'dayjs';\nimport { useCallback, useEffect, useEffectEvent, useRef, useState } from 'react';\nimport { DateTimeStringValue, ScheduleEventData, ScheduleMode } from '../types';\nimport { clampIntervalMinutes } from '../utils/clamp-interval-minutes/clamp-interval-minutes';\nimport { parseTimeString } from '../utils/parse-time-string/parse-time-string';\n\ntype ResizeEdge = 'top' | 'bottom';\n\ninterface ResizeState {\n eventId: string | number;\n event: ScheduleEventData;\n edge: ResizeEdge;\n container: HTMLElement;\n originalTop: number;\n originalHeight: number;\n currentTop: number;\n currentHeight: number;\n eventDate: string;\n originalStart: DateTimeStringValue;\n originalEnd: DateTimeStringValue;\n}\n\nexport interface UseEventResizeInput {\n enabled?: boolean;\n mode?: ScheduleMode;\n startTime: string;\n endTime: string;\n intervalMinutes: number;\n resizeIntervalMinutes?: number;\n onEventResize?: (data: {\n eventId: string | number;\n newStart: DateTimeStringValue;\n newEnd: DateTimeStringValue;\n event: ScheduleEventData;\n }) => void;\n canResizeEvent?: (event: ScheduleEventData) => boolean;\n withBackgroundEvents?: boolean;\n}\n\nexport function useEventResize({\n enabled = false,\n mode = 'default',\n startTime,\n endTime,\n intervalMinutes,\n resizeIntervalMinutes,\n onEventResize,\n canResizeEvent,\n withBackgroundEvents = false,\n}: UseEventResizeInput) {\n const [resizeState, setResizeState] = useState<ResizeState | null>(null);\n const resizeRef = useRef<ResizeState | null>(null);\n const justResizedRef = useRef(false);\n const stableOnEventResize = useEffectEvent(onEventResize || (() => {}));\n\n const parsedStartTime = parseTimeString(startTime);\n const parsedEndTime = parseTimeString(endTime);\n const startMinutes = parsedStartTime.hours * 60 + parsedStartTime.minutes;\n const endMinutes = parsedEndTime.hours * 60 + parsedEndTime.minutes;\n const clampedInterval = clampIntervalMinutes(intervalMinutes);\n const clampedResizeInterval = clampIntervalMinutes(resizeIntervalMinutes ?? intervalMinutes);\n const literalRange = endMinutes - startMinutes;\n const totalMinutes = Math.ceil(literalRange / clampedInterval) * clampedInterval;\n\n // Snapping happens in absolute minutes from midnight – the same grid `calculateDropTime`\n // uses for drag and drop. Snapping relative to `startTime` would put resized edges on a\n // different grid than dragged events whenever `startTime` is not a multiple of the interval\n // (with `startTime=\"08:10\"` and a 30 minute step, drops land on :00/:30 but resizes on\n // :10/:40, so the two operations could never align an event).\n const clampAndSnap = useCallback(\n (minutes: number): number => {\n const snapped =\n Math.round((startMinutes + minutes) / clampedResizeInterval) * clampedResizeInterval;\n return Math.max(0, Math.min(literalRange, snapped - startMinutes));\n },\n [literalRange, clampedResizeInterval, startMinutes]\n );\n\n const percentToDateTime = useCallback(\n (percent: number, eventDate: string): DateTimeStringValue => {\n const minutes = (percent / 100) * totalMinutes;\n const snappedMinutes = clampAndSnap(minutes);\n const totalMins = startMinutes + snappedMinutes;\n const hours = Math.floor(totalMins / 60);\n const mins = totalMins % 60;\n return `${eventDate} ${String(hours).padStart(2, '0')}:${String(mins).padStart(2, '0')}:00`;\n },\n [totalMinutes, startMinutes, clampAndSnap]\n );\n\n const snapEdgeMinutes = useCallback(\n (minutes: number, direction: 'up' | 'down'): number => {\n const absolute = startMinutes + minutes;\n const snapped =\n direction === 'up'\n ? Math.ceil(absolute / clampedResizeInterval) * clampedResizeInterval\n : Math.floor(absolute / clampedResizeInterval) * clampedResizeInterval;\n return Math.max(0, Math.min(literalRange, snapped - startMinutes));\n },\n [literalRange, clampedResizeInterval, startMinutes]\n );\n\n const percentToMinutes = useCallback(\n (percent: number): number => (percent / 100) * totalMinutes,\n [totalMinutes]\n );\n\n const minutesToPercent = useCallback(\n (minutes: number): number => (minutes / totalMinutes) * 100,\n [totalMinutes]\n );\n\n const handleResizeStart = useCallback(\n ({\n event,\n edge,\n container,\n originalTop,\n originalHeight,\n eventDate,\n pointerEvent,\n }: {\n event: ScheduleEventData;\n edge: ResizeEdge;\n container: HTMLElement;\n originalTop: number;\n originalHeight: number;\n eventDate: string;\n pointerEvent: React.PointerEvent;\n }) => {\n if (!enabled || mode === 'static') {\n return;\n }\n\n pointerEvent.preventDefault();\n pointerEvent.stopPropagation();\n\n const state: ResizeState = {\n eventId: event.id,\n event,\n edge,\n container,\n originalTop,\n originalHeight,\n currentTop: originalTop,\n currentHeight: originalHeight,\n eventDate,\n originalStart: dayjs(event.start).format('YYYY-MM-DD HH:mm:ss'),\n originalEnd: dayjs(event.end).format('YYYY-MM-DD HH:mm:ss'),\n };\n\n resizeRef.current = state;\n setResizeState(state);\n },\n [enabled, mode]\n );\n\n const isResizing = resizeState !== null;\n\n useEffect(() => {\n if (!isResizing) {\n return undefined;\n }\n\n const savedUserSelect = document.body.style.userSelect;\n document.body.style.userSelect = 'none';\n\n const handlePointerMove = (e: PointerEvent) => {\n const state = resizeRef.current;\n if (!state) {\n return;\n }\n\n const containerRect = state.container.getBoundingClientRect();\n const relativeY = e.clientY - containerRect.top;\n const rawPercent = Math.max(0, Math.min(100, (relativeY / containerRect.height) * 100));\n const draggedMinutes = clampAndSnap(percentToMinutes(rawPercent));\n\n let newTop = state.originalTop;\n let newHeight = state.originalHeight;\n\n if (state.edge === 'bottom') {\n const topMinutes = percentToMinutes(state.originalTop);\n const minEndMinutes = snapEdgeMinutes(topMinutes + clampedResizeInterval, 'up');\n const endMinutes = Math.max(draggedMinutes, minEndMinutes);\n newHeight = Math.max(0, minutesToPercent(endMinutes) - state.originalTop);\n } else {\n const bottomMinutes = percentToMinutes(state.originalTop + state.originalHeight);\n const maxStartMinutes = snapEdgeMinutes(bottomMinutes - clampedResizeInterval, 'down');\n const startMinutesValue = Math.min(draggedMinutes, maxStartMinutes);\n newTop = minutesToPercent(startMinutesValue);\n newHeight = Math.max(0, state.originalTop + state.originalHeight - newTop);\n }\n\n resizeRef.current = { ...state, currentTop: newTop, currentHeight: newHeight };\n setResizeState(resizeRef.current);\n };\n\n const handlePointerUp = () => {\n const state = resizeRef.current;\n if (state) {\n if (\n state.currentTop !== state.originalTop ||\n state.currentHeight !== state.originalHeight\n ) {\n let newStart: DateTimeStringValue;\n let newEnd: DateTimeStringValue;\n\n if (state.edge === 'top') {\n newStart = percentToDateTime(state.currentTop, state.eventDate);\n newEnd = state.originalEnd;\n } else {\n newStart = state.originalStart;\n newEnd = percentToDateTime(state.currentTop + state.currentHeight, state.eventDate);\n }\n\n stableOnEventResize({\n eventId: state.eventId,\n newStart,\n newEnd,\n event: state.event,\n });\n }\n }\n resizeRef.current = null;\n setResizeState(null);\n justResizedRef.current = true;\n requestAnimationFrame(() => {\n justResizedRef.current = false;\n });\n };\n\n document.addEventListener('pointermove', handlePointerMove);\n document.addEventListener('pointerup', handlePointerUp);\n\n return () => {\n document.body.style.userSelect = savedUserSelect;\n document.removeEventListener('pointermove', handlePointerMove);\n document.removeEventListener('pointerup', handlePointerUp);\n };\n }, [isResizing]);\n\n const getResizePosition = useCallback(\n (eventId: string | number, eventDate?: string) => {\n if (!resizeState || resizeState.eventId !== eventId) {\n return null;\n }\n if (eventDate !== undefined && resizeState.eventDate !== eventDate) {\n return null;\n }\n return { top: resizeState.currentTop, height: resizeState.currentHeight };\n },\n [resizeState]\n );\n\n const isResizableEvent = useCallback(\n (event: ScheduleEventData) => {\n if (!enabled || mode === 'static') {\n return false;\n }\n if (event.display === 'background' && !withBackgroundEvents) {\n return false;\n }\n return canResizeEvent ? canResizeEvent(event) : true;\n },\n [enabled, mode, canResizeEvent, withBackgroundEvents]\n );\n\n const wasResizing = useCallback(() => justResizedRef.current, []);\n\n return {\n handleResizeStart,\n isResizing,\n resizingEventId: resizeState?.eventId ?? null,\n getResizePosition,\n isResizableEvent,\n wasResizing,\n };\n}\n"],"mappings":"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"}
@@ -5,7 +5,7 @@ import { getDayRelativePercent } from "../utils/get-day-relative-percent/get-day
5
5
  import dayjs from "dayjs";
6
6
  import { useCallback, useEffect, useEffectEvent, useRef, useState } from "react";
7
7
  //#region packages/@mantine/schedule/src/hooks/use-horizontal-event-resize.ts
8
- function useHorizontalEventResize({ enabled = false, mode = "default", startTime, endTime, intervalMinutes, resizeIntervalMinutes, onEventResize, canResizeEvent }) {
8
+ function useHorizontalEventResize({ enabled = false, mode = "default", startTime, endTime, intervalMinutes, resizeIntervalMinutes, onEventResize, canResizeEvent, withBackgroundEvents = false }) {
9
9
  const [resizeState, setResizeState] = useState(null);
10
10
  const resizeRef = useRef(null);
11
11
  const justResizedRef = useRef(false);
@@ -146,20 +146,23 @@ function useHorizontalEventResize({ enabled = false, mode = "default", startTime
146
146
  document.removeEventListener("pointerup", handlePointerUp);
147
147
  };
148
148
  }, [isResizing]);
149
- const getResizePosition = useCallback((eventId) => {
149
+ const getResizePosition = useCallback((eventId, eventDate) => {
150
150
  if (!resizeState || resizeState.eventId !== eventId) return null;
151
+ if (eventDate !== void 0 && resizeState.eventDate !== eventDate) return null;
151
152
  return {
152
153
  left: resizeState.currentLeft,
153
154
  width: resizeState.currentWidth
154
155
  };
155
156
  }, [resizeState]);
156
157
  const isResizableEvent = useCallback((event) => {
157
- if (!enabled || mode === "static" || event.display === "background") return false;
158
+ if (!enabled || mode === "static") return false;
159
+ if (event.display === "background" && !withBackgroundEvents) return false;
158
160
  return canResizeEvent ? canResizeEvent(event) : true;
159
161
  }, [
160
162
  enabled,
161
163
  mode,
162
- canResizeEvent
164
+ canResizeEvent,
165
+ withBackgroundEvents
163
166
  ]);
164
167
  const wasResizing = useCallback(() => justResizedRef.current, []);
165
168
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"use-horizontal-event-resize.mjs","names":[],"sources":["../../src/hooks/use-horizontal-event-resize.ts"],"sourcesContent":["import dayjs from 'dayjs';\nimport { useCallback, useEffect, useEffectEvent, useRef, useState } from 'react';\nimport { DateTimeStringValue, ScheduleEventData, ScheduleMode } from '../types';\nimport { clampIntervalMinutes } from '../utils/clamp-interval-minutes/clamp-interval-minutes';\nimport { getDayRelativePercent } from '../utils/get-day-relative-percent/get-day-relative-percent';\nimport { parseTimeString } from '../utils/parse-time-string/parse-time-string';\n\ntype ResizeEdge = 'start' | 'end';\n\ninterface ResizeState {\n eventId: string | number;\n event: ScheduleEventData;\n edge: ResizeEdge;\n container: HTMLElement;\n originalLeft: number;\n originalWidth: number;\n currentLeft: number;\n currentWidth: number;\n eventDate: string;\n originalStart: DateTimeStringValue;\n originalEnd: DateTimeStringValue;\n dayIndex: number;\n dayCount: number;\n}\n\nexport interface UseHorizontalEventResizeInput {\n enabled?: boolean;\n mode?: ScheduleMode;\n startTime: string;\n endTime: string;\n intervalMinutes: number;\n resizeIntervalMinutes?: number;\n onEventResize?: (data: {\n eventId: string | number;\n newStart: DateTimeStringValue;\n newEnd: DateTimeStringValue;\n event: ScheduleEventData;\n }) => void;\n canResizeEvent?: (event: ScheduleEventData) => boolean;\n}\n\nexport function useHorizontalEventResize({\n enabled = false,\n mode = 'default',\n startTime,\n endTime,\n intervalMinutes,\n resizeIntervalMinutes,\n onEventResize,\n canResizeEvent,\n}: UseHorizontalEventResizeInput) {\n const [resizeState, setResizeState] = useState<ResizeState | null>(null);\n const resizeRef = useRef<ResizeState | null>(null);\n const justResizedRef = useRef(false);\n const stableOnEventResize = useEffectEvent(onEventResize || (() => {}));\n\n const parsedStartTime = parseTimeString(startTime);\n const parsedEndTime = parseTimeString(endTime);\n const startMinutes = parsedStartTime.hours * 60 + parsedStartTime.minutes;\n const endMinutes = parsedEndTime.hours * 60 + parsedEndTime.minutes;\n const clampedInterval = clampIntervalMinutes(intervalMinutes);\n const clampedResizeInterval = clampIntervalMinutes(resizeIntervalMinutes ?? intervalMinutes);\n const literalRange = endMinutes - startMinutes;\n const totalMinutes = Math.ceil(literalRange / clampedInterval) * clampedInterval;\n\n // Snapped in absolute minutes from midnight so resized edges land on the same grid as\n // dragged events – see the matching comment in `use-event-resize`.\n const clampAndSnap = useCallback(\n (minutes: number): number => {\n const snapped =\n Math.round((startMinutes + minutes) / clampedResizeInterval) * clampedResizeInterval;\n return Math.max(0, Math.min(literalRange, snapped - startMinutes));\n },\n [literalRange, clampedResizeInterval, startMinutes]\n );\n\n const percentToDateTime = useCallback(\n (percent: number, eventDate: string): DateTimeStringValue => {\n const minutes = (percent / 100) * totalMinutes;\n const snappedMinutes = clampAndSnap(minutes);\n const totalMins = startMinutes + snappedMinutes;\n const hours = Math.floor(totalMins / 60);\n const mins = totalMins % 60;\n return `${eventDate} ${String(hours).padStart(2, '0')}:${String(mins).padStart(2, '0')}:00`;\n },\n [totalMinutes, startMinutes, clampAndSnap]\n );\n\n const snapEdgeMinutes = useCallback(\n (minutes: number, direction: 'up' | 'down'): number => {\n const absolute = startMinutes + minutes;\n const snapped =\n direction === 'up'\n ? Math.ceil(absolute / clampedResizeInterval) * clampedResizeInterval\n : Math.floor(absolute / clampedResizeInterval) * clampedResizeInterval;\n return Math.max(0, Math.min(literalRange, snapped - startMinutes));\n },\n [literalRange, clampedResizeInterval, startMinutes]\n );\n\n const percentToMinutes = useCallback(\n (percent: number): number => (percent / 100) * totalMinutes,\n [totalMinutes]\n );\n\n const minutesToPercent = useCallback(\n (minutes: number): number => (minutes / totalMinutes) * 100,\n [totalMinutes]\n );\n\n const handleResizeStart = useCallback(\n ({\n event,\n edge,\n container,\n originalLeft,\n originalWidth,\n eventDate,\n dayIndex = 0,\n dayCount = 1,\n pointerEvent,\n }: {\n event: ScheduleEventData;\n edge: ResizeEdge;\n container: HTMLElement;\n originalLeft: number;\n originalWidth: number;\n eventDate: string;\n dayIndex?: number;\n dayCount?: number;\n pointerEvent: React.PointerEvent;\n }) => {\n if (!enabled || mode === 'static') {\n return;\n }\n\n pointerEvent.preventDefault();\n pointerEvent.stopPropagation();\n\n const state: ResizeState = {\n eventId: event.id,\n event,\n edge,\n container,\n originalLeft,\n originalWidth,\n currentLeft: originalLeft,\n currentWidth: originalWidth,\n eventDate,\n originalStart: dayjs(event.start).format('YYYY-MM-DD HH:mm:ss'),\n originalEnd: dayjs(event.end).format('YYYY-MM-DD HH:mm:ss'),\n dayIndex,\n dayCount,\n };\n\n resizeRef.current = state;\n setResizeState(state);\n },\n [enabled, mode]\n );\n\n const isResizing = resizeState !== null;\n\n useEffect(() => {\n if (!isResizing) {\n return undefined;\n }\n\n const savedUserSelect = document.body.style.userSelect;\n const savedCursor = document.body.style.cursor;\n document.body.style.userSelect = 'none';\n document.body.style.cursor = 'ew-resize';\n\n const handlePointerMove = (e: PointerEvent) => {\n const state = resizeRef.current;\n if (!state) {\n return;\n }\n\n const containerRect = state.container.getBoundingClientRect();\n const rawPercent = getDayRelativePercent({\n clientX: e.clientX,\n containerLeft: containerRect.left,\n containerWidth: containerRect.width,\n dayIndex: state.dayIndex,\n dayCount: state.dayCount,\n });\n const draggedMinutes = clampAndSnap(percentToMinutes(rawPercent));\n\n let newLeft = state.originalLeft;\n let newWidth = state.originalWidth;\n\n if (state.edge === 'end') {\n const leftMinutes = percentToMinutes(state.originalLeft);\n const minEndMinutes = snapEdgeMinutes(leftMinutes + clampedResizeInterval, 'up');\n const endMinutes = Math.max(draggedMinutes, minEndMinutes);\n newWidth = Math.max(0, minutesToPercent(endMinutes) - state.originalLeft);\n } else {\n const rightMinutes = percentToMinutes(state.originalLeft + state.originalWidth);\n const maxStartMinutes = snapEdgeMinutes(rightMinutes - clampedResizeInterval, 'down');\n const startMinutesValue = Math.min(draggedMinutes, maxStartMinutes);\n newLeft = minutesToPercent(startMinutesValue);\n newWidth = Math.max(0, state.originalLeft + state.originalWidth - newLeft);\n }\n\n resizeRef.current = { ...state, currentLeft: newLeft, currentWidth: newWidth };\n setResizeState(resizeRef.current);\n };\n\n const handlePointerUp = () => {\n const state = resizeRef.current;\n if (state) {\n if (\n state.currentLeft !== state.originalLeft ||\n state.currentWidth !== state.originalWidth\n ) {\n let newStart: DateTimeStringValue;\n let newEnd: DateTimeStringValue;\n\n if (state.edge === 'start') {\n newStart = percentToDateTime(state.currentLeft, state.eventDate);\n newEnd = state.originalEnd;\n } else {\n newStart = state.originalStart;\n newEnd = percentToDateTime(state.currentLeft + state.currentWidth, state.eventDate);\n }\n\n stableOnEventResize({\n eventId: state.eventId,\n newStart,\n newEnd,\n event: state.event,\n });\n }\n }\n resizeRef.current = null;\n setResizeState(null);\n justResizedRef.current = true;\n requestAnimationFrame(() => {\n justResizedRef.current = false;\n });\n };\n\n document.addEventListener('pointermove', handlePointerMove);\n document.addEventListener('pointerup', handlePointerUp);\n\n return () => {\n document.body.style.userSelect = savedUserSelect;\n document.body.style.cursor = savedCursor;\n document.removeEventListener('pointermove', handlePointerMove);\n document.removeEventListener('pointerup', handlePointerUp);\n };\n }, [isResizing]);\n\n const getResizePosition = useCallback(\n (eventId: string | number) => {\n if (!resizeState || resizeState.eventId !== eventId) {\n return null;\n }\n return { left: resizeState.currentLeft, width: resizeState.currentWidth };\n },\n [resizeState]\n );\n\n const isResizableEvent = useCallback(\n (event: ScheduleEventData) => {\n if (!enabled || mode === 'static' || event.display === 'background') {\n return false;\n }\n return canResizeEvent ? canResizeEvent(event) : true;\n },\n [enabled, mode, canResizeEvent]\n );\n\n const wasResizing = useCallback(() => justResizedRef.current, []);\n\n return {\n handleResizeStart,\n isResizing,\n resizingEventId: resizeState?.eventId ?? null,\n resizingEdge: resizeState?.edge ?? null,\n getResizePosition,\n isResizableEvent,\n wasResizing,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-horizontal-event-resize.mjs","names":[],"sources":["../../src/hooks/use-horizontal-event-resize.ts"],"sourcesContent":["import dayjs from 'dayjs';\nimport { useCallback, useEffect, useEffectEvent, useRef, useState } from 'react';\nimport { DateTimeStringValue, ScheduleEventData, ScheduleMode } from '../types';\nimport { clampIntervalMinutes } from '../utils/clamp-interval-minutes/clamp-interval-minutes';\nimport { getDayRelativePercent } from '../utils/get-day-relative-percent/get-day-relative-percent';\nimport { parseTimeString } from '../utils/parse-time-string/parse-time-string';\n\ntype ResizeEdge = 'start' | 'end';\n\ninterface ResizeState {\n eventId: string | number;\n event: ScheduleEventData;\n edge: ResizeEdge;\n container: HTMLElement;\n originalLeft: number;\n originalWidth: number;\n currentLeft: number;\n currentWidth: number;\n eventDate: string;\n originalStart: DateTimeStringValue;\n originalEnd: DateTimeStringValue;\n dayIndex: number;\n dayCount: number;\n}\n\nexport interface UseHorizontalEventResizeInput {\n enabled?: boolean;\n mode?: ScheduleMode;\n startTime: string;\n endTime: string;\n intervalMinutes: number;\n resizeIntervalMinutes?: number;\n onEventResize?: (data: {\n eventId: string | number;\n newStart: DateTimeStringValue;\n newEnd: DateTimeStringValue;\n event: ScheduleEventData;\n }) => void;\n canResizeEvent?: (event: ScheduleEventData) => boolean;\n withBackgroundEvents?: boolean;\n}\n\nexport function useHorizontalEventResize({\n enabled = false,\n mode = 'default',\n startTime,\n endTime,\n intervalMinutes,\n resizeIntervalMinutes,\n onEventResize,\n canResizeEvent,\n withBackgroundEvents = false,\n}: UseHorizontalEventResizeInput) {\n const [resizeState, setResizeState] = useState<ResizeState | null>(null);\n const resizeRef = useRef<ResizeState | null>(null);\n const justResizedRef = useRef(false);\n const stableOnEventResize = useEffectEvent(onEventResize || (() => {}));\n\n const parsedStartTime = parseTimeString(startTime);\n const parsedEndTime = parseTimeString(endTime);\n const startMinutes = parsedStartTime.hours * 60 + parsedStartTime.minutes;\n const endMinutes = parsedEndTime.hours * 60 + parsedEndTime.minutes;\n const clampedInterval = clampIntervalMinutes(intervalMinutes);\n const clampedResizeInterval = clampIntervalMinutes(resizeIntervalMinutes ?? intervalMinutes);\n const literalRange = endMinutes - startMinutes;\n const totalMinutes = Math.ceil(literalRange / clampedInterval) * clampedInterval;\n\n // Snapped in absolute minutes from midnight so resized edges land on the same grid as\n // dragged events – see the matching comment in `use-event-resize`.\n const clampAndSnap = useCallback(\n (minutes: number): number => {\n const snapped =\n Math.round((startMinutes + minutes) / clampedResizeInterval) * clampedResizeInterval;\n return Math.max(0, Math.min(literalRange, snapped - startMinutes));\n },\n [literalRange, clampedResizeInterval, startMinutes]\n );\n\n const percentToDateTime = useCallback(\n (percent: number, eventDate: string): DateTimeStringValue => {\n const minutes = (percent / 100) * totalMinutes;\n const snappedMinutes = clampAndSnap(minutes);\n const totalMins = startMinutes + snappedMinutes;\n const hours = Math.floor(totalMins / 60);\n const mins = totalMins % 60;\n return `${eventDate} ${String(hours).padStart(2, '0')}:${String(mins).padStart(2, '0')}:00`;\n },\n [totalMinutes, startMinutes, clampAndSnap]\n );\n\n const snapEdgeMinutes = useCallback(\n (minutes: number, direction: 'up' | 'down'): number => {\n const absolute = startMinutes + minutes;\n const snapped =\n direction === 'up'\n ? Math.ceil(absolute / clampedResizeInterval) * clampedResizeInterval\n : Math.floor(absolute / clampedResizeInterval) * clampedResizeInterval;\n return Math.max(0, Math.min(literalRange, snapped - startMinutes));\n },\n [literalRange, clampedResizeInterval, startMinutes]\n );\n\n const percentToMinutes = useCallback(\n (percent: number): number => (percent / 100) * totalMinutes,\n [totalMinutes]\n );\n\n const minutesToPercent = useCallback(\n (minutes: number): number => (minutes / totalMinutes) * 100,\n [totalMinutes]\n );\n\n const handleResizeStart = useCallback(\n ({\n event,\n edge,\n container,\n originalLeft,\n originalWidth,\n eventDate,\n dayIndex = 0,\n dayCount = 1,\n pointerEvent,\n }: {\n event: ScheduleEventData;\n edge: ResizeEdge;\n container: HTMLElement;\n originalLeft: number;\n originalWidth: number;\n eventDate: string;\n dayIndex?: number;\n dayCount?: number;\n pointerEvent: React.PointerEvent;\n }) => {\n if (!enabled || mode === 'static') {\n return;\n }\n\n pointerEvent.preventDefault();\n pointerEvent.stopPropagation();\n\n const state: ResizeState = {\n eventId: event.id,\n event,\n edge,\n container,\n originalLeft,\n originalWidth,\n currentLeft: originalLeft,\n currentWidth: originalWidth,\n eventDate,\n originalStart: dayjs(event.start).format('YYYY-MM-DD HH:mm:ss'),\n originalEnd: dayjs(event.end).format('YYYY-MM-DD HH:mm:ss'),\n dayIndex,\n dayCount,\n };\n\n resizeRef.current = state;\n setResizeState(state);\n },\n [enabled, mode]\n );\n\n const isResizing = resizeState !== null;\n\n useEffect(() => {\n if (!isResizing) {\n return undefined;\n }\n\n const savedUserSelect = document.body.style.userSelect;\n const savedCursor = document.body.style.cursor;\n document.body.style.userSelect = 'none';\n document.body.style.cursor = 'ew-resize';\n\n const handlePointerMove = (e: PointerEvent) => {\n const state = resizeRef.current;\n if (!state) {\n return;\n }\n\n const containerRect = state.container.getBoundingClientRect();\n const rawPercent = getDayRelativePercent({\n clientX: e.clientX,\n containerLeft: containerRect.left,\n containerWidth: containerRect.width,\n dayIndex: state.dayIndex,\n dayCount: state.dayCount,\n });\n const draggedMinutes = clampAndSnap(percentToMinutes(rawPercent));\n\n let newLeft = state.originalLeft;\n let newWidth = state.originalWidth;\n\n if (state.edge === 'end') {\n const leftMinutes = percentToMinutes(state.originalLeft);\n const minEndMinutes = snapEdgeMinutes(leftMinutes + clampedResizeInterval, 'up');\n const endMinutes = Math.max(draggedMinutes, minEndMinutes);\n newWidth = Math.max(0, minutesToPercent(endMinutes) - state.originalLeft);\n } else {\n const rightMinutes = percentToMinutes(state.originalLeft + state.originalWidth);\n const maxStartMinutes = snapEdgeMinutes(rightMinutes - clampedResizeInterval, 'down');\n const startMinutesValue = Math.min(draggedMinutes, maxStartMinutes);\n newLeft = minutesToPercent(startMinutesValue);\n newWidth = Math.max(0, state.originalLeft + state.originalWidth - newLeft);\n }\n\n resizeRef.current = { ...state, currentLeft: newLeft, currentWidth: newWidth };\n setResizeState(resizeRef.current);\n };\n\n const handlePointerUp = () => {\n const state = resizeRef.current;\n if (state) {\n if (\n state.currentLeft !== state.originalLeft ||\n state.currentWidth !== state.originalWidth\n ) {\n let newStart: DateTimeStringValue;\n let newEnd: DateTimeStringValue;\n\n if (state.edge === 'start') {\n newStart = percentToDateTime(state.currentLeft, state.eventDate);\n newEnd = state.originalEnd;\n } else {\n newStart = state.originalStart;\n newEnd = percentToDateTime(state.currentLeft + state.currentWidth, state.eventDate);\n }\n\n stableOnEventResize({\n eventId: state.eventId,\n newStart,\n newEnd,\n event: state.event,\n });\n }\n }\n resizeRef.current = null;\n setResizeState(null);\n justResizedRef.current = true;\n requestAnimationFrame(() => {\n justResizedRef.current = false;\n });\n };\n\n document.addEventListener('pointermove', handlePointerMove);\n document.addEventListener('pointerup', handlePointerUp);\n\n return () => {\n document.body.style.userSelect = savedUserSelect;\n document.body.style.cursor = savedCursor;\n document.removeEventListener('pointermove', handlePointerMove);\n document.removeEventListener('pointerup', handlePointerUp);\n };\n }, [isResizing]);\n\n const getResizePosition = useCallback(\n (eventId: string | number, eventDate?: string) => {\n if (!resizeState || resizeState.eventId !== eventId) {\n return null;\n }\n if (eventDate !== undefined && resizeState.eventDate !== eventDate) {\n return null;\n }\n return { left: resizeState.currentLeft, width: resizeState.currentWidth };\n },\n [resizeState]\n );\n\n const isResizableEvent = useCallback(\n (event: ScheduleEventData) => {\n if (!enabled || mode === 'static') {\n return false;\n }\n if (event.display === 'background' && !withBackgroundEvents) {\n return false;\n }\n return canResizeEvent ? canResizeEvent(event) : true;\n },\n [enabled, mode, canResizeEvent, withBackgroundEvents]\n );\n\n const wasResizing = useCallback(() => justResizedRef.current, []);\n\n return {\n handleResizeStart,\n isResizing,\n resizingEventId: resizeState?.eventId ?? null,\n resizingEdge: resizeState?.edge ?? null,\n getResizePosition,\n isResizableEvent,\n wasResizing,\n };\n}\n"],"mappings":"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"}
@@ -8,7 +8,7 @@ import { RenderEvent, RenderEventBody, ScheduleEventStylesNames } from '../Sched
8
8
  import { MonthYearSelectStylesNames } from '../ScheduleHeader/MonthYearSelect/MonthYearSelect';
9
9
  import { CombinedScheduleHeaderStylesNames } from '../ScheduleHeader/ScheduleHeader';
10
10
  import { ViewSelectProps } from '../ScheduleHeader/ViewSelect/ViewSelect';
11
- export type DayViewStylesNames = 'dayView' | 'dayViewInner' | 'dayViewScrollArea' | 'dayViewAllDay' | 'dayViewAllDayEvents' | 'dayViewSlot' | 'dayViewSlots' | 'dayViewTimeSlots' | 'dayViewSlotLabel' | 'dayViewSlotLabels' | 'dayViewBackgroundEvent' | 'dayViewDragPreview' | MoreEventsStylesNames | ScheduleEventStylesNames | Exclude<CombinedScheduleHeaderStylesNames, MonthYearSelectStylesNames> | CurrentTimeIndicatorStylesNames | AgendaViewStylesNames;
11
+ export type DayViewStylesNames = 'dayView' | 'dayViewInner' | 'dayViewScrollArea' | 'dayViewAllDay' | 'dayViewAllDayEvents' | 'dayViewSlot' | 'dayViewSlots' | 'dayViewTimeSlots' | 'dayViewSlotLabel' | 'dayViewSlotLabels' | 'dayViewBackgroundEvent' | 'dayViewBackgroundEventResizeHandle' | 'dayViewDragPreview' | MoreEventsStylesNames | ScheduleEventStylesNames | Exclude<CombinedScheduleHeaderStylesNames, MonthYearSelectStylesNames> | CurrentTimeIndicatorStylesNames | AgendaViewStylesNames;
12
12
  export type DayViewCssVariables = {
13
13
  dayView: '--day-view-radius' | '--day-view-slot-height' | '--day-view-all-day-slot-height';
14
14
  };
@@ -105,7 +105,7 @@ export interface DayViewProps extends BoxProps, StylesApiProps<DayViewFactory>,
105
105
  onAllDaySlotClick?: (date: DateStringValue, event: React.MouseEvent<HTMLButtonElement>) => void;
106
106
  /** Called when event is clicked */
107
107
  onEventClick?: (event: ScheduleEventData, e: React.MouseEvent<HTMLButtonElement>) => void;
108
- /** If set, background events (`display: 'background'`) can be clicked and trigger `onEventClick` @default false */
108
+ /** If set, background events (`display: 'background'`) can be clicked and trigger `onEventClick`. Combined with `withEventResize`, timed background events can also be resized by dragging their edges. @default false */
109
109
  withInteractiveBackgroundEvents?: boolean;
110
110
  /** If set, enables drag-to-select time slot ranges @default false */
111
111
  withDragSlotSelect?: boolean;
@@ -106,7 +106,7 @@ export interface ResourcesDayViewProps extends BoxProps, StylesApiProps<Resource
106
106
  }) => void;
107
107
  /** Called when event is clicked */
108
108
  onEventClick?: (event: ScheduleEventData, e: React.MouseEvent<HTMLButtonElement>) => void;
109
- /** If set, background events (`display: 'background'`) can be clicked and trigger `onEventClick` @default false */
109
+ /** If set, background events (`display: 'background'`) can be clicked and trigger `onEventClick`. Combined with `withEventResize`, timed background events can also be resized by dragging their edges. @default false */
110
110
  withInteractiveBackgroundEvents?: boolean;
111
111
  /** If set, enables drag-to-select time slot ranges @default false */
112
112
  withDragSlotSelect?: boolean;