@innosolutions/inno-calendar 1.0.47 → 1.0.49

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 (54) hide show
  1. package/dist/agenda-widget-B-AVTnqM.cjs +2 -0
  2. package/dist/agenda-widget-B-AVTnqM.cjs.map +1 -0
  3. package/dist/{agenda-widget-BiuoHkpP.js → agenda-widget-DhCPt2vI.js} +941 -929
  4. package/dist/agenda-widget-DhCPt2vI.js.map +1 -0
  5. package/dist/components/event/event-card.d.ts.map +1 -1
  6. package/dist/components/index.cjs +1 -1
  7. package/dist/components/index.mjs +2 -2
  8. package/dist/components/inno-calendar.d.ts +11 -0
  9. package/dist/components/inno-calendar.d.ts.map +1 -1
  10. package/dist/core/context/inno-calendar-provider.d.ts +15 -1
  11. package/dist/core/context/inno-calendar-provider.d.ts.map +1 -1
  12. package/dist/core/index.cjs +1 -1
  13. package/dist/core/index.mjs +43 -43
  14. package/dist/core/types.d.ts +12 -0
  15. package/dist/core/types.d.ts.map +1 -1
  16. package/dist/index.cjs +1 -1
  17. package/dist/index.mjs +62 -62
  18. package/dist/presets/index.cjs +1 -1
  19. package/dist/presets/index.mjs +1 -1
  20. package/dist/slot-selection-context-BCsC7WT7.cjs +2 -0
  21. package/dist/slot-selection-context-BCsC7WT7.cjs.map +1 -0
  22. package/dist/slot-selection-context-D1495hEJ.js +595 -0
  23. package/dist/slot-selection-context-D1495hEJ.js.map +1 -0
  24. package/dist/{tailwind-calendar-7wDEMPEi.js → tailwind-calendar-BmJa4HhQ.js} +2 -2
  25. package/dist/{tailwind-calendar-7wDEMPEi.js.map → tailwind-calendar-BmJa4HhQ.js.map} +1 -1
  26. package/dist/{tailwind-calendar-QMXCp1an.cjs → tailwind-calendar-CJmOutn1.cjs} +2 -2
  27. package/dist/{tailwind-calendar-QMXCp1an.cjs.map → tailwind-calendar-CJmOutn1.cjs.map} +1 -1
  28. package/dist/use-calendar-BEuelmSu.cjs +2 -0
  29. package/dist/use-calendar-BEuelmSu.cjs.map +1 -0
  30. package/dist/use-calendar-Clo9DFK4.js +175 -0
  31. package/dist/use-calendar-Clo9DFK4.js.map +1 -0
  32. package/dist/{use-slot-selection-BJHlyfxL.js → use-slot-selection-BCZKnZSM.js} +2 -2
  33. package/dist/{use-slot-selection-BJHlyfxL.js.map → use-slot-selection-BCZKnZSM.js.map} +1 -1
  34. package/dist/{use-slot-selection-CTFC2-xS.cjs → use-slot-selection-Bwqwjiaq.cjs} +2 -2
  35. package/dist/{use-slot-selection-CTFC2-xS.cjs.map → use-slot-selection-Bwqwjiaq.cjs.map} +1 -1
  36. package/dist/week-view-D19YRBQC.cjs +11 -0
  37. package/dist/week-view-D19YRBQC.cjs.map +1 -0
  38. package/dist/{week-view-C4YFlrPS.js → week-view-aRPB2cjn.js} +922 -904
  39. package/dist/week-view-aRPB2cjn.js.map +1 -0
  40. package/package.json +1 -1
  41. package/dist/agenda-widget-BREvI5ia.cjs +0 -2
  42. package/dist/agenda-widget-BREvI5ia.cjs.map +0 -1
  43. package/dist/agenda-widget-BiuoHkpP.js.map +0 -1
  44. package/dist/slot-selection-context-Bx3FKJfR.cjs +0 -2
  45. package/dist/slot-selection-context-Bx3FKJfR.cjs.map +0 -1
  46. package/dist/slot-selection-context-D2eu2o-7.js +0 -203
  47. package/dist/slot-selection-context-D2eu2o-7.js.map +0 -1
  48. package/dist/use-calendar-DR2emWYC.js +0 -555
  49. package/dist/use-calendar-DR2emWYC.js.map +0 -1
  50. package/dist/use-calendar-DR89bZu5.cjs +0 -2
  51. package/dist/use-calendar-DR89bZu5.cjs.map +0 -1
  52. package/dist/week-view-C4YFlrPS.js.map +0 -1
  53. package/dist/week-view-DWLMtGVt.cjs +0 -11
  54. package/dist/week-view-DWLMtGVt.cjs.map +0 -1
@@ -1,2 +0,0 @@
1
- "use strict";const T=require("react/jsx-runtime"),s=require("react"),H=s.createContext(void 0);function h({children:n,onEventDrop:t}){const[c,u]=s.useState(null),S=s.useCallback(e=>{const a=typeof e.startDate=="string"?new Date(e.startDate):e.startDate,i=typeof e.endDate=="string"?new Date(e.endDate):e.endDate;u({event:e,originalStartDate:a,originalEndDate:i})},[]),l=s.useCallback((e,a,i)=>{u(D=>D?{...D,previewDate:e,previewHour:a,previewMinute:i}:null)},[]),r=s.useCallback(()=>{if(!c)return null;const{event:e,originalStartDate:a,originalEndDate:i,previewDate:D,previewHour:w,previewMinute:p}=c,x=i.getTime()-a.getTime();let f;D?(f=new Date(D),typeof w=="number"?f.setHours(w,p??0,0,0):f.setHours(a.getHours(),a.getMinutes(),a.getSeconds(),0)):f=a;const g=new Date(f.getTime()+x),d={event:e,newStartDate:f,newEndDate:g};return u(null),t?.(d),d},[c,t]),o=s.useCallback(()=>{u(null)},[]);return T.jsx(H.Provider,{value:{dragState:c,isDragging:c!==null,startDrag:S,updateDragPreview:l,endDrag:r,cancelDrag:o},children:n})}function k(){const n=s.useContext(H);if(!n)throw new Error("useDragDrop must be used within a DragDropProvider");return n}function y(){return s.useContext(H)??null}const m=s.createContext(void 0);function C(n){const t=new Date(n.date);return typeof n.hour=="number"&&t.setHours(n.hour,n.minute??0,0,0),t}function M(n){const t=new Date(n),c=t.getMinutes(),u=Math.floor(c/30)*30;return t.setMinutes(u,0,0),t}function P(n,t){return n.getFullYear()===t.getFullYear()&&n.getMonth()===t.getMonth()&&n.getDate()===t.getDate()}function b(n,t,c,u,S=30){const l=C(n),r=C(t);let o=l,e=r;if(r<l&&(o=r,e=l),c==="day")if(P(o,e)){const i=M(new Date);o=new Date(o),o.setHours(i.getHours(),i.getMinutes(),0,0),e=new Date(o.getTime()+u*60*1e3)}else o.setHours(0,0,0,0),e.setHours(23,59,59,999);else{const a=S*60*1e3;e=new Date(e.getTime()+a);const i=e.getTime()-o.getTime(),D=u*60*1e3;i<D&&(e=new Date(o.getTime()+D))}return{startDate:o,endDate:e}}function v(n,t,c,u){const S=C(n),l=C(t),r=C(c),o=l<=r?l:r,e=l<=r?r:l;if(u==="day"){const a=new Date(S);a.setHours(0,0,0,0);const i=new Date(o);i.setHours(0,0,0,0);const D=new Date(e);return D.setHours(0,0,0,0),a>=i&&a<=D}return S>=o&&S<=e}function E({children:n,mode:t="time",onSelect:c,minDurationMinutes:u=30,slotDurationMinutes:S=30,enabled:l=!0}){const[r,o]=s.useState(null),e=s.useRef(!1),a=s.useCallback(g=>{l&&(e.current=!0,o({start:g,end:g,isSelecting:!0}))},[l]),i=s.useCallback(g=>{l&&e.current&&o(d=>d?{...d,end:g}:null)},[l]),D=s.useCallback(()=>{e.current&&(e.current=!1,o(g=>{if(!g)return null;const d=b(g.start,g.end,t,u,S);return c?.(d),{...g,isSelecting:!1}}),setTimeout(()=>{o(null)},100))},[t,u,S,c]),w=s.useCallback(()=>{e.current=!1,o(null)},[]),p=s.useCallback(g=>r?v(g,r.start,r.end,t):!1,[r,t]),x=s.useCallback(()=>r?b(r.start,r.end,t,u,S):null,[r,t,u,S]),f=s.useMemo(()=>({isSelecting:r?.isSelecting??!1,startSelection:a,updateSelection:i,endSelection:D,cancelSelection:w,isSlotSelected:p,getSelectionResult:x,mode:t}),[r?.isSelecting,a,i,D,w,p,x,t]);return T.jsx(m.Provider,{value:f,children:n})}function R(){const n=s.useContext(m);if(!n)throw new Error("useSlotSelectionContext must be used within a SlotSelectionProvider");return n}function O(){return s.useContext(m)}exports.DragDropProvider=h;exports.SlotSelectionProvider=E;exports.useDragDrop=k;exports.useOptionalDragDrop=y;exports.useOptionalSlotSelection=O;exports.useSlotSelectionContext=R;
2
- //# sourceMappingURL=slot-selection-context-Bx3FKJfR.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"slot-selection-context-Bx3FKJfR.cjs","sources":["../src/core/context/drag-drop-context.tsx","../src/core/context/slot-selection-context.tsx"],"sourcesContent":["/**\n * DragDropContext - Drag & Drop State Management for Calendar Events\n *\n * Provides drag & drop state management for calendar events.\n * Enables dragging events between time slots and days.\n *\n * Features:\n * - Generic event type support via CalendarEvent<TData>\n * - Preview position tracking during drag\n * - Duration preservation when dropping\n * - Optional provider pattern (components can work without drag-drop)\n */\n\nimport { createContext, type ReactNode, useCallback, useContext, useState } from 'react';\nimport type { CalendarEvent } from '../types';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\nexport interface IDragState<TData = Record<string, unknown>> {\n\t/** The event being dragged */\n\tevent: CalendarEvent<TData>;\n\t/** Original start date of the event */\n\toriginalStartDate: Date;\n\t/** Original end date of the event */\n\toriginalEndDate: Date;\n\t/** Current preview position (during drag) */\n\tpreviewDate?: Date | undefined;\n\t/** Current preview hour (for time-based views) */\n\tpreviewHour?: number | undefined;\n\t/** Current preview minute */\n\tpreviewMinute?: number | undefined;\n}\n\nexport interface IDropResult<TData = Record<string, unknown>> {\n\t/** The event that was dropped */\n\tevent: CalendarEvent<TData>;\n\t/** New start date after drop */\n\tnewStartDate: Date;\n\t/** New end date after drop (maintains original duration) */\n\tnewEndDate: Date;\n}\n\nexport interface IDragDropContext<TData = Record<string, unknown>> {\n\t/** Current drag state, null when not dragging */\n\tdragState: IDragState<TData> | null;\n\t/** Whether a drag operation is in progress */\n\tisDragging: boolean;\n\t/** Start dragging an event */\n\t// biome-ignore lint/suspicious/noExplicitAny: Accept any event type for flexibility\n\tstartDrag: (event: CalendarEvent<any>) => void;\n\t/** Update drag preview position */\n\tupdateDragPreview: (date: Date, hour?: number, minute?: number) => void;\n\t/** End drag operation and return drop result */\n\tendDrag: () => IDropResult<TData> | null;\n\t/** Cancel drag operation */\n\tcancelDrag: () => void;\n}\n\n// ============================================================================\n// CONTEXT\n// ============================================================================\n\n// biome-ignore lint/suspicious/noExplicitAny: Context needs to be flexible for different event types\nconst DragDropContext = createContext<IDragDropContext<any> | undefined>(undefined);\n\n// ============================================================================\n// PROVIDER PROPS\n// ============================================================================\n\nexport interface DragDropProviderProps<TData = Record<string, unknown>> {\n\tchildren: ReactNode;\n\t/** Callback when an event is dropped at a new location */\n\tonEventDrop?: (result: IDropResult<TData>) => void;\n}\n\n// ============================================================================\n// PROVIDER\n// ============================================================================\n\nexport function DragDropProvider<TData = Record<string, unknown>>({\n\tchildren,\n\tonEventDrop,\n}: DragDropProviderProps<TData>) {\n\tconst [dragState, setDragState] = useState<IDragState<TData> | null>(null);\n\n\t// biome-ignore lint/suspicious/noExplicitAny: Accept any event type for flexibility\n\tconst startDrag = useCallback((event: CalendarEvent<any>) => {\n\t\tconst startDate =\n\t\t\ttypeof event.startDate === 'string' ? new Date(event.startDate) : event.startDate;\n\t\tconst endDate = typeof event.endDate === 'string' ? new Date(event.endDate) : event.endDate;\n\n\t\tsetDragState({\n\t\t\tevent: event as CalendarEvent<TData>,\n\t\t\toriginalStartDate: startDate,\n\t\t\toriginalEndDate: endDate,\n\t\t});\n\t}, []);\n\n\tconst updateDragPreview = useCallback((date: Date, hour?: number, minute?: number) => {\n\t\tsetDragState((prev) => {\n\t\t\tif (!prev) return null;\n\t\t\treturn {\n\t\t\t\t...prev,\n\t\t\t\tpreviewDate: date,\n\t\t\t\tpreviewHour: hour,\n\t\t\t\tpreviewMinute: minute,\n\t\t\t};\n\t\t});\n\t}, []);\n\n\tconst endDrag = useCallback(() => {\n\t\tif (!dragState) return null;\n\n\t\tconst { event, originalStartDate, originalEndDate, previewDate, previewHour, previewMinute } =\n\t\t\tdragState;\n\n\t\t// Calculate duration of original event\n\t\tconst durationMs = originalEndDate.getTime() - originalStartDate.getTime();\n\n\t\t// Calculate new start date\n\t\tlet newStartDate: Date;\n\n\t\tif (previewDate) {\n\t\t\tnewStartDate = new Date(previewDate);\n\n\t\t\tif (typeof previewHour === 'number') {\n\t\t\t\t// Time-based drop (day/week view)\n\t\t\t\tnewStartDate.setHours(previewHour, previewMinute ?? 0, 0, 0);\n\t\t\t} else {\n\t\t\t\t// Day-based drop (month view) - keep original time\n\t\t\t\tnewStartDate.setHours(\n\t\t\t\t\toriginalStartDate.getHours(),\n\t\t\t\t\toriginalStartDate.getMinutes(),\n\t\t\t\t\toriginalStartDate.getSeconds(),\n\t\t\t\t\t0\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\t// No preview, return to original position\n\t\t\tnewStartDate = originalStartDate;\n\t\t}\n\n\t\t// Calculate new end date maintaining duration\n\t\tconst newEndDate = new Date(newStartDate.getTime() + durationMs);\n\n\t\tconst result: IDropResult<TData> = {\n\t\t\tevent,\n\t\t\tnewStartDate,\n\t\t\tnewEndDate,\n\t\t};\n\n\t\t// Clear drag state\n\t\tsetDragState(null);\n\n\t\t// Notify parent\n\t\tonEventDrop?.(result);\n\n\t\treturn result;\n\t}, [dragState, onEventDrop]);\n\n\tconst cancelDrag = useCallback(() => {\n\t\tsetDragState(null);\n\t}, []);\n\n\treturn (\n\t\t<DragDropContext.Provider\n\t\t\tvalue={{\n\t\t\t\tdragState,\n\t\t\t\tisDragging: dragState !== null,\n\t\t\t\tstartDrag,\n\t\t\t\tupdateDragPreview,\n\t\t\t\tendDrag,\n\t\t\t\tcancelDrag,\n\t\t\t}}\n\t\t>\n\t\t\t{children}\n\t\t</DragDropContext.Provider>\n\t);\n}\n\n// ============================================================================\n// HOOKS\n// ============================================================================\n\n/**\n * Access drag & drop context (required)\n *\n * @throws Error if used outside of DragDropProvider\n */\nexport function useDragDrop<TData = Record<string, unknown>>(): IDragDropContext<TData> {\n\tconst context = useContext(DragDropContext);\n\tif (!context) {\n\t\tthrow new Error('useDragDrop must be used within a DragDropProvider');\n\t}\n\treturn context as IDragDropContext<TData>;\n}\n\n/**\n * Access drag & drop context (optional)\n *\n * Use this for components that may be rendered outside of DragDropProvider.\n * Returns null when drag-drop is not available.\n */\nexport function useOptionalDragDrop<\n\tTData = Record<string, unknown>,\n>(): IDragDropContext<TData> | null {\n\tconst context = useContext(DragDropContext);\n\treturn (context as IDragDropContext<TData>) ?? null;\n}\n","/**\n * Slot Selection Context\n *\n * Provides centralized selection state management across all calendar views.\n * This context handles:\n * - Drag-to-select functionality\n * - Selection visualization\n * - Callback integration with parent components\n *\n * Usage:\n * 1. Wrap calendar views with SlotSelectionProvider\n * 2. Use useSlotSelectionContext in child components\n * 3. Connect onSelect callback to event creation dialog\n */\n\nimport {\n\tcreateContext,\n\ttype ReactNode,\n\tuseCallback,\n\tuseContext,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport type {\n\tISelectionResult,\n\tISlotSelectionState,\n\tITimeSlot,\n\tTOnSlotSelect,\n\tTSelectionMode,\n} from '../types';\n\n// ============================================================================\n// CONTEXT TYPES\n// ============================================================================\n\ninterface ISlotSelectionContext {\n\t/** Current selection state */\n\tisSelecting: boolean;\n\t/** Start selection at a slot */\n\tstartSelection: (slot: ITimeSlot) => void;\n\t/** Update selection end point */\n\tupdateSelection: (slot: ITimeSlot) => void;\n\t/** Complete the selection */\n\tendSelection: () => void;\n\t/** Cancel the selection */\n\tcancelSelection: () => void;\n\t/** Check if a slot is within the current selection */\n\tisSlotSelected: (slot: ITimeSlot) => boolean;\n\t/** Get the normalized selection result */\n\tgetSelectionResult: () => ISelectionResult | null;\n\t/** Current selection mode */\n\tmode: TSelectionMode;\n}\n\n// ============================================================================\n// CONTEXT\n// ============================================================================\n\nconst SlotSelectionContext = createContext<ISlotSelectionContext | undefined>(undefined);\n\n// ============================================================================\n// PROVIDER PROPS\n// ============================================================================\n\ninterface SlotSelectionProviderProps {\n\tchildren: ReactNode;\n\t/** Selection mode based on view */\n\tmode?: TSelectionMode;\n\t/** Callback when selection completes */\n\tonSelect?: TOnSlotSelect;\n\t/** Minimum duration in minutes (for time mode) */\n\tminDurationMinutes?: number;\n\t/** Slot duration in minutes (default: 30) */\n\tslotDurationMinutes?: number;\n\t/** Whether selection is enabled */\n\tenabled?: boolean;\n}\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\n/**\n * Convert a time slot to a Date object\n */\nfunction slotToDate(slot: ITimeSlot): Date {\n\tconst date = new Date(slot.date);\n\tif (typeof slot.hour === 'number') {\n\t\tdate.setHours(slot.hour, slot.minute ?? 0, 0, 0);\n\t}\n\treturn date;\n}\n\n/**\n * Round time to nearest 30-minute interval\n */\nfunction roundToNearest30Minutes(date: Date): Date {\n\tconst result = new Date(date);\n\tconst minutes = result.getMinutes();\n\tconst roundedMinutes = Math.floor(minutes / 30) * 30;\n\tresult.setMinutes(roundedMinutes, 0, 0);\n\treturn result;\n}\n\n/**\n * Check if two dates are the same calendar day\n */\nfunction isSameDay(date1: Date, date2: Date): boolean {\n\treturn (\n\t\tdate1.getFullYear() === date2.getFullYear() &&\n\t\tdate1.getMonth() === date2.getMonth() &&\n\t\tdate1.getDate() === date2.getDate()\n\t);\n}\n\n/**\n * Normalize selection so start is always before end\n */\nfunction normalizeSelection(\n\tstart: ITimeSlot,\n\tend: ITimeSlot,\n\tmode: TSelectionMode,\n\tminDurationMinutes: number,\n\tslotDurationMinutes = 30\n): ISelectionResult {\n\tconst startDate = slotToDate(start);\n\tconst endDate = slotToDate(end);\n\n\t// Swap if end is before start\n\tlet normalizedStart = startDate;\n\tlet normalizedEnd = endDate;\n\n\tif (endDate < startDate) {\n\t\tnormalizedStart = endDate;\n\t\tnormalizedEnd = startDate;\n\t}\n\n\t// Apply mode-specific logic\n\tif (mode === 'day') {\n\t\t// Check if single day selection (same day click)\n\t\tif (isSameDay(normalizedStart, normalizedEnd)) {\n\t\t\t// Single day: use current time rounded to nearest 30 min + default duration\n\t\t\tconst now = new Date();\n\t\t\tconst roundedNow = roundToNearest30Minutes(now);\n\n\t\t\t// Set the date portion from the selected day\n\t\t\tnormalizedStart = new Date(normalizedStart);\n\t\t\tnormalizedStart.setHours(roundedNow.getHours(), roundedNow.getMinutes(), 0, 0);\n\n\t\t\t// End time = start + minimum duration (default 30 min)\n\t\t\tnormalizedEnd = new Date(normalizedStart.getTime() + minDurationMinutes * 60 * 1000);\n\t\t} else {\n\t\t\t// Multi-day selection: full days\n\t\t\tnormalizedStart.setHours(0, 0, 0, 0);\n\t\t\tnormalizedEnd.setHours(23, 59, 59, 999);\n\t\t}\n\t} else {\n\t\t// Time mode: The end slot represents the START of that slot block,\n\t\t// so we need to add slot duration to get the actual end time\n\t\tconst slotDurationMs = slotDurationMinutes * 60 * 1000;\n\t\tnormalizedEnd = new Date(normalizedEnd.getTime() + slotDurationMs);\n\n\t\t// Ensure minimum duration\n\t\tconst durationMs = normalizedEnd.getTime() - normalizedStart.getTime();\n\t\tconst minDurationMs = minDurationMinutes * 60 * 1000;\n\n\t\tif (durationMs < minDurationMs) {\n\t\t\tnormalizedEnd = new Date(normalizedStart.getTime() + minDurationMs);\n\t\t}\n\t}\n\n\treturn {\n\t\tstartDate: normalizedStart,\n\t\tendDate: normalizedEnd,\n\t};\n}\n\n/**\n * Check if a slot is within a selection range\n */\nfunction isSlotWithinRange(\n\tslot: ITimeSlot,\n\tstart: ITimeSlot,\n\tend: ITimeSlot,\n\tmode: TSelectionMode\n): boolean {\n\tconst slotDate = slotToDate(slot);\n\tconst startDate = slotToDate(start);\n\tconst endDate = slotToDate(end);\n\n\t// Normalize the range\n\tconst rangeStart = startDate <= endDate ? startDate : endDate;\n\tconst rangeEnd = startDate <= endDate ? endDate : startDate;\n\n\tif (mode === 'day') {\n\t\t// Day mode: check if slot's date is within range (ignore time)\n\t\tconst slotDay = new Date(slotDate);\n\t\tslotDay.setHours(0, 0, 0, 0);\n\t\tconst startDay = new Date(rangeStart);\n\t\tstartDay.setHours(0, 0, 0, 0);\n\t\tconst endDay = new Date(rangeEnd);\n\t\tendDay.setHours(0, 0, 0, 0);\n\t\treturn slotDay >= startDay && slotDay <= endDay;\n\t}\n\n\t// Time mode: precise check\n\treturn slotDate >= rangeStart && slotDate <= rangeEnd;\n}\n\n// ============================================================================\n// PROVIDER\n// ============================================================================\n\nexport function SlotSelectionProvider({\n\tchildren,\n\tmode = 'time',\n\tonSelect,\n\tminDurationMinutes = 30,\n\tslotDurationMinutes = 30,\n\tenabled = true,\n}: SlotSelectionProviderProps) {\n\tconst [selection, setSelection] = useState<ISlotSelectionState | null>(null);\n\tconst isSelectingRef = useRef(false);\n\n\t// Start selection\n\tconst startSelection = useCallback(\n\t\t(slot: ITimeSlot) => {\n\t\t\tif (!enabled) return;\n\n\t\t\tisSelectingRef.current = true;\n\t\t\tsetSelection({\n\t\t\t\tstart: slot,\n\t\t\t\tend: slot,\n\t\t\t\tisSelecting: true,\n\t\t\t});\n\t\t},\n\t\t[enabled]\n\t);\n\n\t// Update selection end point\n\tconst updateSelection = useCallback(\n\t\t(slot: ITimeSlot) => {\n\t\t\tif (!(enabled && isSelectingRef.current)) return;\n\n\t\t\tsetSelection((prev) => {\n\t\t\t\tif (!prev) return null;\n\t\t\t\treturn {\n\t\t\t\t\t...prev,\n\t\t\t\t\tend: slot,\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\t\t[enabled]\n\t);\n\n\t// Complete selection and fire callback\n\tconst endSelection = useCallback(() => {\n\t\tif (!isSelectingRef.current) return;\n\n\t\tisSelectingRef.current = false;\n\n\t\tsetSelection((prev) => {\n\t\t\tif (!prev) return null;\n\n\t\t\t// Calculate final result\n\t\t\tconst result = normalizeSelection(\n\t\t\t\tprev.start,\n\t\t\t\tprev.end,\n\t\t\t\tmode,\n\t\t\t\tminDurationMinutes,\n\t\t\t\tslotDurationMinutes\n\t\t\t);\n\n\t\t\t// Fire callback\n\t\t\tonSelect?.(result);\n\n\t\t\t// Clear selection after a brief delay for visual feedback\n\t\t\treturn {\n\t\t\t\t...prev,\n\t\t\t\tisSelecting: false,\n\t\t\t};\n\t\t});\n\n\t\t// Clear selection after callback\n\t\tsetTimeout(() => {\n\t\t\tsetSelection(null);\n\t\t}, 100);\n\t}, [mode, minDurationMinutes, slotDurationMinutes, onSelect]);\n\n\t// Cancel selection without firing callback\n\tconst cancelSelection = useCallback(() => {\n\t\tisSelectingRef.current = false;\n\t\tsetSelection(null);\n\t}, []);\n\n\t// Check if a slot is in the current selection\n\tconst isSlotInSelection = useCallback(\n\t\t(slot: ITimeSlot): boolean => {\n\t\t\tif (!selection) return false;\n\t\t\treturn isSlotWithinRange(slot, selection.start, selection.end, mode);\n\t\t},\n\t\t[selection, mode]\n\t);\n\n\t// Get the normalized selection result\n\tconst getSelectionResult = useCallback((): ISelectionResult | null => {\n\t\tif (!selection) return null;\n\t\treturn normalizeSelection(\n\t\t\tselection.start,\n\t\t\tselection.end,\n\t\t\tmode,\n\t\t\tminDurationMinutes,\n\t\t\tslotDurationMinutes\n\t\t);\n\t}, [selection, mode, minDurationMinutes, slotDurationMinutes]);\n\n\t// Memoize context value\n\tconst value = useMemo<ISlotSelectionContext>(\n\t\t() => ({\n\t\t\tisSelecting: selection?.isSelecting ?? false,\n\t\t\tstartSelection,\n\t\t\tupdateSelection,\n\t\t\tendSelection,\n\t\t\tcancelSelection,\n\t\t\tisSlotSelected: isSlotInSelection,\n\t\t\tgetSelectionResult,\n\t\t\tmode,\n\t\t}),\n\t\t[\n\t\t\tselection?.isSelecting,\n\t\t\tstartSelection,\n\t\t\tupdateSelection,\n\t\t\tendSelection,\n\t\t\tcancelSelection,\n\t\t\tisSlotInSelection,\n\t\t\tgetSelectionResult,\n\t\t\tmode,\n\t\t]\n\t);\n\n\treturn <SlotSelectionContext.Provider value={value}>{children}</SlotSelectionContext.Provider>;\n}\n\n// ============================================================================\n// HOOKS\n// ============================================================================\n\nexport function useSlotSelectionContext(): ISlotSelectionContext {\n\tconst context = useContext(SlotSelectionContext);\n\tif (!context) {\n\t\tthrow new Error('useSlotSelectionContext must be used within a SlotSelectionProvider');\n\t}\n\treturn context;\n}\n\n/**\n * Optional hook that returns undefined if not in provider\n * Useful for components that can work with or without selection\n */\nexport function useOptionalSlotSelection(): ISlotSelectionContext | undefined {\n\treturn useContext(SlotSelectionContext);\n}\n\n// ============================================================================\n// TYPE EXPORTS\n// ============================================================================\n\nexport type { ISlotSelectionContext, SlotSelectionProviderProps };\n"],"names":["DragDropContext","createContext","DragDropProvider","children","onEventDrop","dragState","setDragState","useState","startDrag","useCallback","event","startDate","endDate","updateDragPreview","date","hour","minute","prev","endDrag","originalStartDate","originalEndDate","previewDate","previewHour","previewMinute","durationMs","newStartDate","newEndDate","result","cancelDrag","jsx","useDragDrop","context","useContext","useOptionalDragDrop","SlotSelectionContext","slotToDate","slot","roundToNearest30Minutes","minutes","roundedMinutes","isSameDay","date1","date2","normalizeSelection","start","end","mode","minDurationMinutes","slotDurationMinutes","normalizedStart","normalizedEnd","roundedNow","slotDurationMs","minDurationMs","isSlotWithinRange","slotDate","rangeStart","rangeEnd","slotDay","startDay","endDay","SlotSelectionProvider","onSelect","enabled","selection","setSelection","isSelectingRef","useRef","startSelection","updateSelection","endSelection","cancelSelection","isSlotInSelection","getSelectionResult","value","useMemo","useSlotSelectionContext","useOptionalSlotSelection"],"mappings":"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"}
@@ -1,203 +0,0 @@
1
- import { jsx as M } from "react/jsx-runtime";
2
- import { useState as C, useCallback as f, useContext as x, createContext as P, useRef as v, useMemo as E } from "react";
3
- const T = P(void 0);
4
- function O({
5
- children: n,
6
- onEventDrop: e
7
- }) {
8
- const [c, a] = C(null), g = f((t) => {
9
- const s = typeof t.startDate == "string" ? new Date(t.startDate) : t.startDate, i = typeof t.endDate == "string" ? new Date(t.endDate) : t.endDate;
10
- a({
11
- event: t,
12
- originalStartDate: s,
13
- originalEndDate: i
14
- });
15
- }, []), u = f((t, s, i) => {
16
- a((l) => l ? {
17
- ...l,
18
- previewDate: t,
19
- previewHour: s,
20
- previewMinute: i
21
- } : null);
22
- }, []), r = f(() => {
23
- if (!c) return null;
24
- const { event: t, originalStartDate: s, originalEndDate: i, previewDate: l, previewHour: w, previewMinute: m } = c, H = i.getTime() - s.getTime();
25
- let S;
26
- l ? (S = new Date(l), typeof w == "number" ? S.setHours(w, m ?? 0, 0, 0) : S.setHours(
27
- s.getHours(),
28
- s.getMinutes(),
29
- s.getSeconds(),
30
- 0
31
- )) : S = s;
32
- const D = new Date(S.getTime() + H), d = {
33
- event: t,
34
- newStartDate: S,
35
- newEndDate: D
36
- };
37
- return a(null), e?.(d), d;
38
- }, [c, e]), o = f(() => {
39
- a(null);
40
- }, []);
41
- return /* @__PURE__ */ M(
42
- T.Provider,
43
- {
44
- value: {
45
- dragState: c,
46
- isDragging: c !== null,
47
- startDrag: g,
48
- updateDragPreview: u,
49
- endDrag: r,
50
- cancelDrag: o
51
- },
52
- children: n
53
- }
54
- );
55
- }
56
- function Y() {
57
- const n = x(T);
58
- if (!n)
59
- throw new Error("useDragDrop must be used within a DragDropProvider");
60
- return n;
61
- }
62
- function j() {
63
- return x(T) ?? null;
64
- }
65
- const h = P(void 0);
66
- function p(n) {
67
- const e = new Date(n.date);
68
- return typeof n.hour == "number" && e.setHours(n.hour, n.minute ?? 0, 0, 0), e;
69
- }
70
- function R(n) {
71
- const e = new Date(n), c = e.getMinutes(), a = Math.floor(c / 30) * 30;
72
- return e.setMinutes(a, 0, 0), e;
73
- }
74
- function b(n, e) {
75
- return n.getFullYear() === e.getFullYear() && n.getMonth() === e.getMonth() && n.getDate() === e.getDate();
76
- }
77
- function y(n, e, c, a, g = 30) {
78
- const u = p(n), r = p(e);
79
- let o = u, t = r;
80
- if (r < u && (o = r, t = u), c === "day")
81
- if (b(o, t)) {
82
- const i = R(/* @__PURE__ */ new Date());
83
- o = new Date(o), o.setHours(i.getHours(), i.getMinutes(), 0, 0), t = new Date(o.getTime() + a * 60 * 1e3);
84
- } else
85
- o.setHours(0, 0, 0, 0), t.setHours(23, 59, 59, 999);
86
- else {
87
- const s = g * 60 * 1e3;
88
- t = new Date(t.getTime() + s);
89
- const i = t.getTime() - o.getTime(), l = a * 60 * 1e3;
90
- i < l && (t = new Date(o.getTime() + l));
91
- }
92
- return {
93
- startDate: o,
94
- endDate: t
95
- };
96
- }
97
- function z(n, e, c, a) {
98
- const g = p(n), u = p(e), r = p(c), o = u <= r ? u : r, t = u <= r ? r : u;
99
- if (a === "day") {
100
- const s = new Date(g);
101
- s.setHours(0, 0, 0, 0);
102
- const i = new Date(o);
103
- i.setHours(0, 0, 0, 0);
104
- const l = new Date(t);
105
- return l.setHours(0, 0, 0, 0), s >= i && s <= l;
106
- }
107
- return g >= o && g <= t;
108
- }
109
- function k({
110
- children: n,
111
- mode: e = "time",
112
- onSelect: c,
113
- minDurationMinutes: a = 30,
114
- slotDurationMinutes: g = 30,
115
- enabled: u = !0
116
- }) {
117
- const [r, o] = C(null), t = v(!1), s = f(
118
- (D) => {
119
- u && (t.current = !0, o({
120
- start: D,
121
- end: D,
122
- isSelecting: !0
123
- }));
124
- },
125
- [u]
126
- ), i = f(
127
- (D) => {
128
- u && t.current && o((d) => d ? {
129
- ...d,
130
- end: D
131
- } : null);
132
- },
133
- [u]
134
- ), l = f(() => {
135
- t.current && (t.current = !1, o((D) => {
136
- if (!D) return null;
137
- const d = y(
138
- D.start,
139
- D.end,
140
- e,
141
- a,
142
- g
143
- );
144
- return c?.(d), {
145
- ...D,
146
- isSelecting: !1
147
- };
148
- }), setTimeout(() => {
149
- o(null);
150
- }, 100));
151
- }, [e, a, g, c]), w = f(() => {
152
- t.current = !1, o(null);
153
- }, []), m = f(
154
- (D) => r ? z(D, r.start, r.end, e) : !1,
155
- [r, e]
156
- ), H = f(() => r ? y(
157
- r.start,
158
- r.end,
159
- e,
160
- a,
161
- g
162
- ) : null, [r, e, a, g]), S = E(
163
- () => ({
164
- isSelecting: r?.isSelecting ?? !1,
165
- startSelection: s,
166
- updateSelection: i,
167
- endSelection: l,
168
- cancelSelection: w,
169
- isSlotSelected: m,
170
- getSelectionResult: H,
171
- mode: e
172
- }),
173
- [
174
- r?.isSelecting,
175
- s,
176
- i,
177
- l,
178
- w,
179
- m,
180
- H,
181
- e
182
- ]
183
- );
184
- return /* @__PURE__ */ M(h.Provider, { value: S, children: n });
185
- }
186
- function I() {
187
- const n = x(h);
188
- if (!n)
189
- throw new Error("useSlotSelectionContext must be used within a SlotSelectionProvider");
190
- return n;
191
- }
192
- function W() {
193
- return x(h);
194
- }
195
- export {
196
- O as D,
197
- k as S,
198
- j as a,
199
- W as b,
200
- I as c,
201
- Y as u
202
- };
203
- //# sourceMappingURL=slot-selection-context-D2eu2o-7.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"slot-selection-context-D2eu2o-7.js","sources":["../src/core/context/drag-drop-context.tsx","../src/core/context/slot-selection-context.tsx"],"sourcesContent":["/**\n * DragDropContext - Drag & Drop State Management for Calendar Events\n *\n * Provides drag & drop state management for calendar events.\n * Enables dragging events between time slots and days.\n *\n * Features:\n * - Generic event type support via CalendarEvent<TData>\n * - Preview position tracking during drag\n * - Duration preservation when dropping\n * - Optional provider pattern (components can work without drag-drop)\n */\n\nimport { createContext, type ReactNode, useCallback, useContext, useState } from 'react';\nimport type { CalendarEvent } from '../types';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\nexport interface IDragState<TData = Record<string, unknown>> {\n\t/** The event being dragged */\n\tevent: CalendarEvent<TData>;\n\t/** Original start date of the event */\n\toriginalStartDate: Date;\n\t/** Original end date of the event */\n\toriginalEndDate: Date;\n\t/** Current preview position (during drag) */\n\tpreviewDate?: Date | undefined;\n\t/** Current preview hour (for time-based views) */\n\tpreviewHour?: number | undefined;\n\t/** Current preview minute */\n\tpreviewMinute?: number | undefined;\n}\n\nexport interface IDropResult<TData = Record<string, unknown>> {\n\t/** The event that was dropped */\n\tevent: CalendarEvent<TData>;\n\t/** New start date after drop */\n\tnewStartDate: Date;\n\t/** New end date after drop (maintains original duration) */\n\tnewEndDate: Date;\n}\n\nexport interface IDragDropContext<TData = Record<string, unknown>> {\n\t/** Current drag state, null when not dragging */\n\tdragState: IDragState<TData> | null;\n\t/** Whether a drag operation is in progress */\n\tisDragging: boolean;\n\t/** Start dragging an event */\n\t// biome-ignore lint/suspicious/noExplicitAny: Accept any event type for flexibility\n\tstartDrag: (event: CalendarEvent<any>) => void;\n\t/** Update drag preview position */\n\tupdateDragPreview: (date: Date, hour?: number, minute?: number) => void;\n\t/** End drag operation and return drop result */\n\tendDrag: () => IDropResult<TData> | null;\n\t/** Cancel drag operation */\n\tcancelDrag: () => void;\n}\n\n// ============================================================================\n// CONTEXT\n// ============================================================================\n\n// biome-ignore lint/suspicious/noExplicitAny: Context needs to be flexible for different event types\nconst DragDropContext = createContext<IDragDropContext<any> | undefined>(undefined);\n\n// ============================================================================\n// PROVIDER PROPS\n// ============================================================================\n\nexport interface DragDropProviderProps<TData = Record<string, unknown>> {\n\tchildren: ReactNode;\n\t/** Callback when an event is dropped at a new location */\n\tonEventDrop?: (result: IDropResult<TData>) => void;\n}\n\n// ============================================================================\n// PROVIDER\n// ============================================================================\n\nexport function DragDropProvider<TData = Record<string, unknown>>({\n\tchildren,\n\tonEventDrop,\n}: DragDropProviderProps<TData>) {\n\tconst [dragState, setDragState] = useState<IDragState<TData> | null>(null);\n\n\t// biome-ignore lint/suspicious/noExplicitAny: Accept any event type for flexibility\n\tconst startDrag = useCallback((event: CalendarEvent<any>) => {\n\t\tconst startDate =\n\t\t\ttypeof event.startDate === 'string' ? new Date(event.startDate) : event.startDate;\n\t\tconst endDate = typeof event.endDate === 'string' ? new Date(event.endDate) : event.endDate;\n\n\t\tsetDragState({\n\t\t\tevent: event as CalendarEvent<TData>,\n\t\t\toriginalStartDate: startDate,\n\t\t\toriginalEndDate: endDate,\n\t\t});\n\t}, []);\n\n\tconst updateDragPreview = useCallback((date: Date, hour?: number, minute?: number) => {\n\t\tsetDragState((prev) => {\n\t\t\tif (!prev) return null;\n\t\t\treturn {\n\t\t\t\t...prev,\n\t\t\t\tpreviewDate: date,\n\t\t\t\tpreviewHour: hour,\n\t\t\t\tpreviewMinute: minute,\n\t\t\t};\n\t\t});\n\t}, []);\n\n\tconst endDrag = useCallback(() => {\n\t\tif (!dragState) return null;\n\n\t\tconst { event, originalStartDate, originalEndDate, previewDate, previewHour, previewMinute } =\n\t\t\tdragState;\n\n\t\t// Calculate duration of original event\n\t\tconst durationMs = originalEndDate.getTime() - originalStartDate.getTime();\n\n\t\t// Calculate new start date\n\t\tlet newStartDate: Date;\n\n\t\tif (previewDate) {\n\t\t\tnewStartDate = new Date(previewDate);\n\n\t\t\tif (typeof previewHour === 'number') {\n\t\t\t\t// Time-based drop (day/week view)\n\t\t\t\tnewStartDate.setHours(previewHour, previewMinute ?? 0, 0, 0);\n\t\t\t} else {\n\t\t\t\t// Day-based drop (month view) - keep original time\n\t\t\t\tnewStartDate.setHours(\n\t\t\t\t\toriginalStartDate.getHours(),\n\t\t\t\t\toriginalStartDate.getMinutes(),\n\t\t\t\t\toriginalStartDate.getSeconds(),\n\t\t\t\t\t0\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\t// No preview, return to original position\n\t\t\tnewStartDate = originalStartDate;\n\t\t}\n\n\t\t// Calculate new end date maintaining duration\n\t\tconst newEndDate = new Date(newStartDate.getTime() + durationMs);\n\n\t\tconst result: IDropResult<TData> = {\n\t\t\tevent,\n\t\t\tnewStartDate,\n\t\t\tnewEndDate,\n\t\t};\n\n\t\t// Clear drag state\n\t\tsetDragState(null);\n\n\t\t// Notify parent\n\t\tonEventDrop?.(result);\n\n\t\treturn result;\n\t}, [dragState, onEventDrop]);\n\n\tconst cancelDrag = useCallback(() => {\n\t\tsetDragState(null);\n\t}, []);\n\n\treturn (\n\t\t<DragDropContext.Provider\n\t\t\tvalue={{\n\t\t\t\tdragState,\n\t\t\t\tisDragging: dragState !== null,\n\t\t\t\tstartDrag,\n\t\t\t\tupdateDragPreview,\n\t\t\t\tendDrag,\n\t\t\t\tcancelDrag,\n\t\t\t}}\n\t\t>\n\t\t\t{children}\n\t\t</DragDropContext.Provider>\n\t);\n}\n\n// ============================================================================\n// HOOKS\n// ============================================================================\n\n/**\n * Access drag & drop context (required)\n *\n * @throws Error if used outside of DragDropProvider\n */\nexport function useDragDrop<TData = Record<string, unknown>>(): IDragDropContext<TData> {\n\tconst context = useContext(DragDropContext);\n\tif (!context) {\n\t\tthrow new Error('useDragDrop must be used within a DragDropProvider');\n\t}\n\treturn context as IDragDropContext<TData>;\n}\n\n/**\n * Access drag & drop context (optional)\n *\n * Use this for components that may be rendered outside of DragDropProvider.\n * Returns null when drag-drop is not available.\n */\nexport function useOptionalDragDrop<\n\tTData = Record<string, unknown>,\n>(): IDragDropContext<TData> | null {\n\tconst context = useContext(DragDropContext);\n\treturn (context as IDragDropContext<TData>) ?? null;\n}\n","/**\n * Slot Selection Context\n *\n * Provides centralized selection state management across all calendar views.\n * This context handles:\n * - Drag-to-select functionality\n * - Selection visualization\n * - Callback integration with parent components\n *\n * Usage:\n * 1. Wrap calendar views with SlotSelectionProvider\n * 2. Use useSlotSelectionContext in child components\n * 3. Connect onSelect callback to event creation dialog\n */\n\nimport {\n\tcreateContext,\n\ttype ReactNode,\n\tuseCallback,\n\tuseContext,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport type {\n\tISelectionResult,\n\tISlotSelectionState,\n\tITimeSlot,\n\tTOnSlotSelect,\n\tTSelectionMode,\n} from '../types';\n\n// ============================================================================\n// CONTEXT TYPES\n// ============================================================================\n\ninterface ISlotSelectionContext {\n\t/** Current selection state */\n\tisSelecting: boolean;\n\t/** Start selection at a slot */\n\tstartSelection: (slot: ITimeSlot) => void;\n\t/** Update selection end point */\n\tupdateSelection: (slot: ITimeSlot) => void;\n\t/** Complete the selection */\n\tendSelection: () => void;\n\t/** Cancel the selection */\n\tcancelSelection: () => void;\n\t/** Check if a slot is within the current selection */\n\tisSlotSelected: (slot: ITimeSlot) => boolean;\n\t/** Get the normalized selection result */\n\tgetSelectionResult: () => ISelectionResult | null;\n\t/** Current selection mode */\n\tmode: TSelectionMode;\n}\n\n// ============================================================================\n// CONTEXT\n// ============================================================================\n\nconst SlotSelectionContext = createContext<ISlotSelectionContext | undefined>(undefined);\n\n// ============================================================================\n// PROVIDER PROPS\n// ============================================================================\n\ninterface SlotSelectionProviderProps {\n\tchildren: ReactNode;\n\t/** Selection mode based on view */\n\tmode?: TSelectionMode;\n\t/** Callback when selection completes */\n\tonSelect?: TOnSlotSelect;\n\t/** Minimum duration in minutes (for time mode) */\n\tminDurationMinutes?: number;\n\t/** Slot duration in minutes (default: 30) */\n\tslotDurationMinutes?: number;\n\t/** Whether selection is enabled */\n\tenabled?: boolean;\n}\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\n/**\n * Convert a time slot to a Date object\n */\nfunction slotToDate(slot: ITimeSlot): Date {\n\tconst date = new Date(slot.date);\n\tif (typeof slot.hour === 'number') {\n\t\tdate.setHours(slot.hour, slot.minute ?? 0, 0, 0);\n\t}\n\treturn date;\n}\n\n/**\n * Round time to nearest 30-minute interval\n */\nfunction roundToNearest30Minutes(date: Date): Date {\n\tconst result = new Date(date);\n\tconst minutes = result.getMinutes();\n\tconst roundedMinutes = Math.floor(minutes / 30) * 30;\n\tresult.setMinutes(roundedMinutes, 0, 0);\n\treturn result;\n}\n\n/**\n * Check if two dates are the same calendar day\n */\nfunction isSameDay(date1: Date, date2: Date): boolean {\n\treturn (\n\t\tdate1.getFullYear() === date2.getFullYear() &&\n\t\tdate1.getMonth() === date2.getMonth() &&\n\t\tdate1.getDate() === date2.getDate()\n\t);\n}\n\n/**\n * Normalize selection so start is always before end\n */\nfunction normalizeSelection(\n\tstart: ITimeSlot,\n\tend: ITimeSlot,\n\tmode: TSelectionMode,\n\tminDurationMinutes: number,\n\tslotDurationMinutes = 30\n): ISelectionResult {\n\tconst startDate = slotToDate(start);\n\tconst endDate = slotToDate(end);\n\n\t// Swap if end is before start\n\tlet normalizedStart = startDate;\n\tlet normalizedEnd = endDate;\n\n\tif (endDate < startDate) {\n\t\tnormalizedStart = endDate;\n\t\tnormalizedEnd = startDate;\n\t}\n\n\t// Apply mode-specific logic\n\tif (mode === 'day') {\n\t\t// Check if single day selection (same day click)\n\t\tif (isSameDay(normalizedStart, normalizedEnd)) {\n\t\t\t// Single day: use current time rounded to nearest 30 min + default duration\n\t\t\tconst now = new Date();\n\t\t\tconst roundedNow = roundToNearest30Minutes(now);\n\n\t\t\t// Set the date portion from the selected day\n\t\t\tnormalizedStart = new Date(normalizedStart);\n\t\t\tnormalizedStart.setHours(roundedNow.getHours(), roundedNow.getMinutes(), 0, 0);\n\n\t\t\t// End time = start + minimum duration (default 30 min)\n\t\t\tnormalizedEnd = new Date(normalizedStart.getTime() + minDurationMinutes * 60 * 1000);\n\t\t} else {\n\t\t\t// Multi-day selection: full days\n\t\t\tnormalizedStart.setHours(0, 0, 0, 0);\n\t\t\tnormalizedEnd.setHours(23, 59, 59, 999);\n\t\t}\n\t} else {\n\t\t// Time mode: The end slot represents the START of that slot block,\n\t\t// so we need to add slot duration to get the actual end time\n\t\tconst slotDurationMs = slotDurationMinutes * 60 * 1000;\n\t\tnormalizedEnd = new Date(normalizedEnd.getTime() + slotDurationMs);\n\n\t\t// Ensure minimum duration\n\t\tconst durationMs = normalizedEnd.getTime() - normalizedStart.getTime();\n\t\tconst minDurationMs = minDurationMinutes * 60 * 1000;\n\n\t\tif (durationMs < minDurationMs) {\n\t\t\tnormalizedEnd = new Date(normalizedStart.getTime() + minDurationMs);\n\t\t}\n\t}\n\n\treturn {\n\t\tstartDate: normalizedStart,\n\t\tendDate: normalizedEnd,\n\t};\n}\n\n/**\n * Check if a slot is within a selection range\n */\nfunction isSlotWithinRange(\n\tslot: ITimeSlot,\n\tstart: ITimeSlot,\n\tend: ITimeSlot,\n\tmode: TSelectionMode\n): boolean {\n\tconst slotDate = slotToDate(slot);\n\tconst startDate = slotToDate(start);\n\tconst endDate = slotToDate(end);\n\n\t// Normalize the range\n\tconst rangeStart = startDate <= endDate ? startDate : endDate;\n\tconst rangeEnd = startDate <= endDate ? endDate : startDate;\n\n\tif (mode === 'day') {\n\t\t// Day mode: check if slot's date is within range (ignore time)\n\t\tconst slotDay = new Date(slotDate);\n\t\tslotDay.setHours(0, 0, 0, 0);\n\t\tconst startDay = new Date(rangeStart);\n\t\tstartDay.setHours(0, 0, 0, 0);\n\t\tconst endDay = new Date(rangeEnd);\n\t\tendDay.setHours(0, 0, 0, 0);\n\t\treturn slotDay >= startDay && slotDay <= endDay;\n\t}\n\n\t// Time mode: precise check\n\treturn slotDate >= rangeStart && slotDate <= rangeEnd;\n}\n\n// ============================================================================\n// PROVIDER\n// ============================================================================\n\nexport function SlotSelectionProvider({\n\tchildren,\n\tmode = 'time',\n\tonSelect,\n\tminDurationMinutes = 30,\n\tslotDurationMinutes = 30,\n\tenabled = true,\n}: SlotSelectionProviderProps) {\n\tconst [selection, setSelection] = useState<ISlotSelectionState | null>(null);\n\tconst isSelectingRef = useRef(false);\n\n\t// Start selection\n\tconst startSelection = useCallback(\n\t\t(slot: ITimeSlot) => {\n\t\t\tif (!enabled) return;\n\n\t\t\tisSelectingRef.current = true;\n\t\t\tsetSelection({\n\t\t\t\tstart: slot,\n\t\t\t\tend: slot,\n\t\t\t\tisSelecting: true,\n\t\t\t});\n\t\t},\n\t\t[enabled]\n\t);\n\n\t// Update selection end point\n\tconst updateSelection = useCallback(\n\t\t(slot: ITimeSlot) => {\n\t\t\tif (!(enabled && isSelectingRef.current)) return;\n\n\t\t\tsetSelection((prev) => {\n\t\t\t\tif (!prev) return null;\n\t\t\t\treturn {\n\t\t\t\t\t...prev,\n\t\t\t\t\tend: slot,\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\t\t[enabled]\n\t);\n\n\t// Complete selection and fire callback\n\tconst endSelection = useCallback(() => {\n\t\tif (!isSelectingRef.current) return;\n\n\t\tisSelectingRef.current = false;\n\n\t\tsetSelection((prev) => {\n\t\t\tif (!prev) return null;\n\n\t\t\t// Calculate final result\n\t\t\tconst result = normalizeSelection(\n\t\t\t\tprev.start,\n\t\t\t\tprev.end,\n\t\t\t\tmode,\n\t\t\t\tminDurationMinutes,\n\t\t\t\tslotDurationMinutes\n\t\t\t);\n\n\t\t\t// Fire callback\n\t\t\tonSelect?.(result);\n\n\t\t\t// Clear selection after a brief delay for visual feedback\n\t\t\treturn {\n\t\t\t\t...prev,\n\t\t\t\tisSelecting: false,\n\t\t\t};\n\t\t});\n\n\t\t// Clear selection after callback\n\t\tsetTimeout(() => {\n\t\t\tsetSelection(null);\n\t\t}, 100);\n\t}, [mode, minDurationMinutes, slotDurationMinutes, onSelect]);\n\n\t// Cancel selection without firing callback\n\tconst cancelSelection = useCallback(() => {\n\t\tisSelectingRef.current = false;\n\t\tsetSelection(null);\n\t}, []);\n\n\t// Check if a slot is in the current selection\n\tconst isSlotInSelection = useCallback(\n\t\t(slot: ITimeSlot): boolean => {\n\t\t\tif (!selection) return false;\n\t\t\treturn isSlotWithinRange(slot, selection.start, selection.end, mode);\n\t\t},\n\t\t[selection, mode]\n\t);\n\n\t// Get the normalized selection result\n\tconst getSelectionResult = useCallback((): ISelectionResult | null => {\n\t\tif (!selection) return null;\n\t\treturn normalizeSelection(\n\t\t\tselection.start,\n\t\t\tselection.end,\n\t\t\tmode,\n\t\t\tminDurationMinutes,\n\t\t\tslotDurationMinutes\n\t\t);\n\t}, [selection, mode, minDurationMinutes, slotDurationMinutes]);\n\n\t// Memoize context value\n\tconst value = useMemo<ISlotSelectionContext>(\n\t\t() => ({\n\t\t\tisSelecting: selection?.isSelecting ?? false,\n\t\t\tstartSelection,\n\t\t\tupdateSelection,\n\t\t\tendSelection,\n\t\t\tcancelSelection,\n\t\t\tisSlotSelected: isSlotInSelection,\n\t\t\tgetSelectionResult,\n\t\t\tmode,\n\t\t}),\n\t\t[\n\t\t\tselection?.isSelecting,\n\t\t\tstartSelection,\n\t\t\tupdateSelection,\n\t\t\tendSelection,\n\t\t\tcancelSelection,\n\t\t\tisSlotInSelection,\n\t\t\tgetSelectionResult,\n\t\t\tmode,\n\t\t]\n\t);\n\n\treturn <SlotSelectionContext.Provider value={value}>{children}</SlotSelectionContext.Provider>;\n}\n\n// ============================================================================\n// HOOKS\n// ============================================================================\n\nexport function useSlotSelectionContext(): ISlotSelectionContext {\n\tconst context = useContext(SlotSelectionContext);\n\tif (!context) {\n\t\tthrow new Error('useSlotSelectionContext must be used within a SlotSelectionProvider');\n\t}\n\treturn context;\n}\n\n/**\n * Optional hook that returns undefined if not in provider\n * Useful for components that can work with or without selection\n */\nexport function useOptionalSlotSelection(): ISlotSelectionContext | undefined {\n\treturn useContext(SlotSelectionContext);\n}\n\n// ============================================================================\n// TYPE EXPORTS\n// ============================================================================\n\nexport type { ISlotSelectionContext, SlotSelectionProviderProps };\n"],"names":["DragDropContext","createContext","DragDropProvider","children","onEventDrop","dragState","setDragState","useState","startDrag","useCallback","event","startDate","endDate","updateDragPreview","date","hour","minute","prev","endDrag","originalStartDate","originalEndDate","previewDate","previewHour","previewMinute","durationMs","newStartDate","newEndDate","result","cancelDrag","jsx","useDragDrop","context","useContext","useOptionalDragDrop","SlotSelectionContext","slotToDate","slot","roundToNearest30Minutes","minutes","roundedMinutes","isSameDay","date1","date2","normalizeSelection","start","end","mode","minDurationMinutes","slotDurationMinutes","normalizedStart","normalizedEnd","roundedNow","slotDurationMs","minDurationMs","isSlotWithinRange","slotDate","rangeStart","rangeEnd","slotDay","startDay","endDay","SlotSelectionProvider","onSelect","enabled","selection","setSelection","isSelectingRef","useRef","startSelection","updateSelection","endSelection","cancelSelection","isSlotInSelection","getSelectionResult","value","useMemo","useSlotSelectionContext","useOptionalSlotSelection"],"mappings":"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"}