@omidrahmati/react-slot-scheduler 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/LICENSE +21 -0
- package/README.md +717 -0
- package/dist/index.cjs +1197 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.css +469 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.cts +217 -0
- package/dist/index.d.ts +217 -0
- package/dist/index.js +1154 -0
- package/dist/index.js.map +1 -0
- package/package.json +88 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/BookingCalendar.tsx","../src/utils/date.ts","../src/styles/defaultTheme.ts","../src/components/GanttScheduler.tsx","../src/adapters.ts"],"sourcesContent":["import React, { useEffect, useMemo, useState } from 'react';\nimport type { BookingCalendarProps, CalendarTheme, CalendarSlot, GanttDataAdapter, SlotMovePayload } from '../types';\nimport { addDays, generateTimeSlots, getHourBounds, getWeekDays, rangesOverlap, toIsoDate } from '../utils/date';\nimport { defaultTheme } from '../styles/defaultTheme';\nimport { GanttScheduler } from './GanttScheduler';\nimport '../styles/calendar.css';\n\nfunction toMinutes(t: string): number {\n const [h, m] = t.split(':').map(Number);\n return h * 60 + m;\n}\n\nfunction slotClass(status: CalendarSlot['status']): string {\n return `rbc-slot ${status}`;\n}\n\nfunction minutesToTime(total: number): string {\n const h = Math.floor(total / 60);\n const m = total % 60;\n return `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}`;\n}\n\nfunction compressSelectionKeys(\n keys: Iterable<string>,\n slotGranularity: number\n): Array<{ date: string; startTime: string; endTime: string }> {\n const byDate = new Map<string, number[]>();\n for (const k of keys) {\n const [date, startTime] = k.split('__');\n const minute = toMinutes(startTime);\n const arr = byDate.get(date) ?? [];\n arr.push(minute);\n byDate.set(date, arr);\n }\n\n const merged: Array<{ date: string; startTime: string; endTime: string }> = [];\n for (const [date, mins] of byDate.entries()) {\n mins.sort((a, b) => a - b);\n let rangeStart = mins[0];\n let prev = mins[0];\n for (let i = 1; i < mins.length; i += 1) {\n const current = mins[i];\n if (current === prev + slotGranularity) {\n prev = current;\n continue;\n }\n merged.push({ date, startTime: minutesToTime(rangeStart), endTime: minutesToTime(prev + slotGranularity) });\n rangeStart = current;\n prev = current;\n }\n merged.push({ date, startTime: minutesToTime(rangeStart), endTime: minutesToTime(prev + slotGranularity) });\n }\n\n return merged.sort((a, b) => (a.date === b.date ? toMinutes(a.startTime) - toMinutes(b.startTime) : a.date.localeCompare(b.date)));\n}\n\nexport function BookingCalendar({\n value,\n onChange,\n schedules,\n mode: schedulerMode = 'time-grid',\n dataAdapter,\n dataSource,\n ganttTimeUnit,\n ganttScale,\n viewMode,\n onViewModeChange,\n onSlotClick,\n onItemClick,\n onBookingClick,\n onSlotMove,\n onGanttItemMove,\n onGanttItemResize,\n onGanttItemCreate,\n onBeforeSlotMove,\n onSlotConflict,\n draggableSlots = false,\n selectionMode = false,\n selectedSlots,\n onSelectionChange,\n onSlotDragSelectStart,\n onSlotDragSelectMove,\n onSlotDragSelectEnd,\n isSlotSelected,\n slotGranularity = 30,\n locale = 'fa-IR',\n weekStartsOn = 6,\n direction = 'auto',\n translations,\n theme,\n hideTimeColumn = false,\n className\n}: BookingCalendarProps) {\n const [internalMode, setInternalMode] = useState<'day' | 'week'>('week');\n const [dragOverKey, setDragOverKey] = useState<string | null>(null);\n const [internalSelectedKeys, setInternalSelectedKeys] = useState<Set<string>>(new Set());\n const liveSelectionRef = React.useRef<Set<string>>(new Set());\n const isSelectingRef = React.useRef(false);\n const [isSelecting, setIsSelecting] = useState(false);\n useEffect(() => {\n if (typeof window === 'undefined') return;\n setInternalMode(window.innerWidth < 768 ? 'day' : 'week');\n }, []);\n useEffect(() => {\n if (typeof window === 'undefined') return;\n const onUp = () => { isSelectingRef.current = false; setIsSelecting(false); };\n window.addEventListener('mouseup', onUp);\n return () => window.removeEventListener('mouseup', onUp);\n }, []);\n const calendarMode = viewMode ?? internalMode;\n const setCalendarMode = (m: 'day' | 'week') => {\n setInternalMode(m);\n onViewModeChange?.(m);\n };\n const isRtlLocale = /^fa|^ar|^he/.test(locale.toLowerCase());\n const resolvedDirection = direction === 'auto' ? (isRtlLocale ? 'rtl' : 'ltr') : direction;\n const t = {\n previous: isRtlLocale ? 'قبلی' : 'Previous',\n today: isRtlLocale ? 'امروز' : 'Today',\n next: isRtlLocale ? 'بعدی' : 'Next',\n day: isRtlLocale ? 'روز' : 'Day',\n week: isRtlLocale ? 'هفته' : 'Week',\n ...translations\n };\n const ganttTranslations = useMemo(() => {\n const map: Partial<{ previous: string; today: string; next: string }> = {};\n if (t.previous) map.previous = t.previous;\n if (t.today) map.today = t.today;\n if (t.next) map.next = t.next;\n return map;\n }, [t.previous, t.today, t.next]);\n\n const mergedTheme: CalendarTheme = { ...defaultTheme, ...theme };\n const cssVars = {\n ['--rbc-primary' as string]: mergedTheme.primary,\n ['--rbc-bg' as string]: mergedTheme.bg,\n ['--rbc-panel' as string]: mergedTheme.panel,\n ['--rbc-border' as string]: mergedTheme.border,\n ['--rbc-text' as string]: mergedTheme.text,\n ['--rbc-muted' as string]: mergedTheme.mutedText,\n ['--rbc-available' as string]: mergedTheme.availableBg,\n ['--rbc-booked' as string]: mergedTheme.bookedBg,\n ['--rbc-blocked' as string]: mergedTheme.blockedBg,\n ['--rbc-custom' as string]: mergedTheme.customBg\n } as React.CSSProperties;\n\n // ── Gantt mode: delegate to GanttScheduler ──────────────────────────────\n const isGanttMode = schedulerMode === 'task-timeline' || schedulerMode === 'resource-planner';\n\n const ganttData = useMemo(() => {\n if (!isGanttMode || !dataAdapter || dataSource === undefined) return null;\n const adapter = dataAdapter as GanttDataAdapter<unknown>;\n if (typeof adapter.toGantt !== 'function') return null;\n return adapter.toGantt(dataSource, { date: value, locale });\n }, [isGanttMode, dataAdapter, dataSource, value, locale]);\n\n if (isGanttMode && ganttData) {\n return (\n <GanttScheduler\n schedulerMode={schedulerMode}\n rows={ganttData.rows}\n items={ganttData.items}\n date={value}\n timeStart={ganttData.timeStart}\n timeEnd={ganttData.timeEnd}\n granularity={ganttData.granularity}\n timeUnit={ganttTimeUnit ?? ganttData.timeUnit}\n scale={ganttScale ?? ganttData.scale ?? (ganttData.timeUnit === 'day' ? 'week' : undefined)}\n weekStartsOn={weekStartsOn}\n locale={locale}\n direction={direction === 'auto' ? (/^fa|^ar|^he/.test(locale.toLowerCase()) ? 'rtl' : 'ltr') : direction as 'rtl' | 'ltr'}\n theme={theme}\n onItemClick={onItemClick}\n onItemMove={onGanttItemMove}\n onItemResize={onGanttItemResize}\n onItemCreate={onGanttItemCreate}\n translations={ganttTranslations}\n onDateChange={onChange}\n />\n );\n }\n\n const normalizedSchedules = useMemo(() => {\n if (dataAdapter && dataSource !== undefined && !isGanttMode) {\n const adapter = dataAdapter as { toSchedules?: (d: unknown) => typeof schedules };\n if (typeof adapter.toSchedules === 'function') return adapter.toSchedules(dataSource);\n }\n return schedules;\n }, [dataAdapter, dataSource, schedules, isGanttMode]);\n\n const days = useMemo(() => (calendarMode === 'week' ? getWeekDays(value, weekStartsOn) : [value]), [calendarMode, value, weekStartsOn]);\n const byDate = useMemo(() => new Map(normalizedSchedules.map((d) => [d.date, d])), [normalizedSchedules]);\n const bounds = useMemo(() => getHourBounds(normalizedSchedules), [normalizedSchedules]);\n const times = useMemo(() => generateTimeSlots(bounds.start, bounds.end, slotGranularity), [bounds, slotGranularity]);\n\n const title = calendarMode === 'week'\n ? `${days[0].toLocaleDateString(locale)} - ${days[days.length - 1].toLocaleDateString(locale)}`\n : value.toLocaleDateString(locale, { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });\n\n const rowsHeight = 30;\n const totalMinutes = (bounds.end - bounds.start) * 60;\n const currentSelectionKeys = useMemo(() => {\n if (selectedSlots) {\n const keys = new Set<string>();\n for (const s of selectedSlots) {\n const start = toMinutes(s.startTime);\n const end = toMinutes(s.endTime);\n for (let m = start; m < end; m += slotGranularity) {\n keys.add(`${s.date}__${minutesToTime(m)}`);\n }\n }\n return keys;\n }\n return internalSelectedKeys;\n }, [selectedSlots, internalSelectedKeys, slotGranularity]);\n\n const emitSelection = (keys: Set<string>) => {\n const values = compressSelectionKeys(keys, slotGranularity);\n onSelectionChange?.(values);\n return values;\n };\n\n const addSelection = (date: string, startTime: string) => {\n const key = `${date}__${startTime}`;\n if (liveSelectionRef.current.has(key)) return;\n liveSelectionRef.current = new Set(liveSelectionRef.current);\n liveSelectionRef.current.add(key);\n\n const endTime = minutesToTime(toMinutes(startTime) + slotGranularity);\n onSlotDragSelectMove?.({ date, startTime, endTime });\n\n if (selectedSlots) {\n emitSelection(liveSelectionRef.current);\n return;\n }\n const nextKeys = new Set(liveSelectionRef.current);\n setInternalSelectedKeys(nextKeys);\n setTimeout(() => emitSelection(nextKeys), 0);\n };\n\n const findConflict = (payload: SlotMovePayload): CalendarSlot | undefined => {\n const targetStart = toMinutes(payload.to.startTime);\n const targetEnd = toMinutes(payload.to.endTime);\n const sameSlotMove =\n payload.from.date === payload.to.date &&\n payload.from.startTime === payload.to.startTime &&\n payload.from.endTime === payload.to.endTime;\n if (sameSlotMove) return undefined;\n const targetDay = byDate.get(payload.to.date);\n if (!targetDay) return undefined;\n\n return targetDay.slots.find((s) => {\n if (\n payload.from.date === payload.to.date &&\n s.startTime === payload.from.startTime &&\n s.endTime === payload.from.endTime &&\n (s.itemId ?? s.bookingId) === (payload.slot.itemId ?? payload.slot.bookingId)\n ) {\n return false;\n }\n const sStart = toMinutes(s.startTime);\n const sEnd = toMinutes(s.endTime);\n return rangesOverlap(targetStart, targetEnd, sStart, sEnd);\n });\n };\n\n return (\n <div\n className={`rbc-root rbc-model-${schedulerMode} ${className ?? ''} ${resolvedDirection === 'rtl' ? 'rbc-rtl' : 'rbc-ltr'}`}\n style={cssVars}\n dir={resolvedDirection}\n data-scheduler-mode={schedulerMode}\n >\n <div className=\"rbc-toolbar\">\n <div style={{ display: 'flex', gap: 8 }}>\n <button className=\"rbc-btn\" onClick={() => onChange(addDays(value, calendarMode === 'week' ? -7 : -1))}>{t.previous}</button>\n <button className=\"rbc-btn\" onClick={() => onChange(new Date())}>{t.today}</button>\n <button className=\"rbc-btn\" onClick={() => onChange(addDays(value, calendarMode === 'week' ? 7 : 1))}>{t.next}</button>\n </div>\n <strong>{title}</strong>\n <div style={{ display: 'flex', gap: 6 }}>\n <button className={`rbc-btn ${calendarMode === 'day' ? 'active' : ''}`} onClick={() => setCalendarMode('day')}>{t.day}</button>\n <button className={`rbc-btn ${calendarMode === 'week' ? 'active' : ''}`} onClick={() => setCalendarMode('week')}>{t.week}</button>\n </div>\n </div>\n\n <div className=\"rbc-grid\" style={{\n ['--rbc-days' as string]: String(days.length),\n ['--rbc-rows' as string]: String(times.length),\n gridTemplateRows: `auto repeat(${times.length}, ${rowsHeight}px)`\n } as React.CSSProperties}>\n {!hideTimeColumn && <div className=\"rbc-day-head\" />}\n {days.map((d) => {\n const isToday = toIsoDate(d) === toIsoDate(new Date());\n return <div key={d.toISOString()} className={`rbc-day-head ${isToday ? 'today' : ''}`}>{d.toLocaleDateString(locale, { weekday: 'short', month: 'short', day: 'numeric' })}</div>;\n })}\n\n {times.map((t, rowIdx) => (\n <React.Fragment key={t}>\n {!hideTimeColumn && (\n <div\n className=\"rbc-time\"\n style={{ gridRow: rowIdx + 2, gridColumn: 1 } as React.CSSProperties}\n >\n {t}\n </div>\n )}\n {days.map((d, colIdx) => {\n const dayIso = toIsoDate(d);\n const cellKey = `${dayIso}-${t}`;\n const tMin = toMinutes(t);\n const cellHasSlot = byDate.get(dayIso)?.slots.some(\n s => toMinutes(s.startTime) <= tMin && tMin < toMinutes(s.endTime)\n ) ?? false;\n return (\n <div\n key={`${t}-${d.toISOString()}`}\n data-slot-cell=\"true\"\n data-date={dayIso}\n data-start-time={t}\n className={`rbc-cell ${dragOverKey === cellKey ? 'rbc-drop-target' : ''} ${selectionMode && !cellHasSlot && (isSlotSelected?.({ date: dayIso, startTime: t, endTime: minutesToTime(tMin + slotGranularity) }) || currentSelectionKeys.has(`${dayIso}__${t}`)) ? 'rbc-cell-selected' : ''}`}\n style={{ height: rowsHeight, gridRow: rowIdx + 2, gridColumn: (hideTimeColumn ? 1 : 2) + colIdx } as React.CSSProperties}\n onMouseDown={(e) => {\n if (!selectionMode || e.button !== 0 || cellHasSlot) return;\n liveSelectionRef.current = new Set();\n setInternalSelectedKeys(new Set());\n isSelectingRef.current = true;\n setIsSelecting(true);\n const endTime = minutesToTime(tMin + slotGranularity);\n onSlotDragSelectStart?.({ date: dayIso, startTime: t, endTime });\n addSelection(dayIso, t);\n }}\n onMouseEnter={() => {\n if (!selectionMode || !isSelectingRef.current || cellHasSlot) return;\n addSelection(dayIso, t);\n }}\n onMouseUp={() => {\n if (!selectionMode || !isSelectingRef.current) return;\n isSelectingRef.current = false;\n setIsSelecting(false);\n const keys = liveSelectionRef.current;\n const final = compressSelectionKeys(keys, slotGranularity);\n liveSelectionRef.current = new Set();\n onSlotDragSelectEnd?.(final);\n }}\n />\n );\n })}\n </React.Fragment>\n ))}\n\n {!hideTimeColumn && (\n <div\n className=\"rbc-empty-col\"\n style={{ gridRow: `2 / span ${times.length}`, gridColumn: 1 } as React.CSSProperties}\n />\n )}\n {days.map((d, i) => {\n const dayIso = toIsoDate(d);\n const day = byDate.get(dayIso);\n\n const calcTimeFromY = (e: React.DragEvent<HTMLDivElement>): string => {\n const rect = e.currentTarget.getBoundingClientRect();\n const fraction = Math.max(0, Math.min(1, (e.clientY - rect.top) / rect.height));\n const mins = Math.floor((fraction * totalMinutes) / slotGranularity) * slotGranularity;\n return minutesToTime(bounds.start * 60 + mins);\n };\n\n return (\n <div\n key={`slots-${dayIso}`}\n className=\"rbc-empty-col\"\n style={{\n gridRow: `2 / span ${times.length}`,\n gridColumn: (hideTimeColumn ? 1 : 2) + i,\n pointerEvents: draggableSlots ? 'auto' : 'none',\n } as React.CSSProperties}\n onDragOver={(e) => {\n if (!draggableSlots) return;\n e.preventDefault();\n const t = calcTimeFromY(e);\n setDragOverKey(`${dayIso}-${t}`);\n }}\n onDragLeave={() => setDragOverKey(null)}\n onDrop={(e) => {\n if (!draggableSlots || !onSlotMove) return;\n e.preventDefault();\n setDragOverKey(null);\n const raw = e.dataTransfer.getData('application/x-rbc-slot');\n if (!raw) return;\n const payload = JSON.parse(raw) as { slot: CalendarSlot; date: string };\n const targetStart = calcTimeFromY(e);\n const duration = toMinutes(payload.slot.endTime) - toMinutes(payload.slot.startTime);\n if (duration <= 0) return;\n const movePayload: SlotMovePayload = {\n slot: payload.slot,\n from: { date: payload.date, startTime: payload.slot.startTime, endTime: payload.slot.endTime },\n to: { date: dayIso, startTime: targetStart, endTime: minutesToTime(toMinutes(targetStart) + duration) }\n };\n\n const conflict = findConflict(movePayload);\n if (conflict) {\n onSlotConflict?.({ ...movePayload, reason: 'overlap', conflictingSlot: conflict });\n return;\n }\n\n Promise.resolve(onBeforeSlotMove?.(movePayload) ?? true).then((allowed) => {\n if (!allowed) {\n onSlotConflict?.({ ...movePayload, reason: 'blocked-by-policy' });\n return;\n }\n onSlotMove(movePayload);\n });\n }}\n >\n {(day?.slots ?? []).map((slot, i) => {\n const start = toMinutes(slot.startTime);\n const end = toMinutes(slot.endTime);\n const top = ((start - bounds.start * 60) / totalMinutes) * 100;\n const height = ((end - start) / totalMinutes) * 100;\n return (\n <div\n key={`${slot.startTime}-${slot.endTime}-${i}`}\n data-slot-item=\"true\"\n data-date={dayIso}\n data-start-time={slot.startTime}\n data-end-time={slot.endTime}\n className={slotClass(slot.status)}\n style={{ top: `${top}%`, height: `${height}%` }}\n draggable={draggableSlots}\n onDragStart={(e) => {\n if (!draggableSlots) return;\n e.stopPropagation();\n e.dataTransfer.effectAllowed = 'move';\n e.dataTransfer.setData('application/x-rbc-slot', JSON.stringify({ slot, date: dayIso }));\n }}\n onClick={() => {\n const id = slot.itemId ?? slot.bookingId;\n if (id) {\n onItemClick?.(id);\n onBookingClick?.(id);\n return;\n }\n onSlotClick?.(dayIso, slot);\n }}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key !== 'Enter' && e.key !== ' ') return;\n e.preventDefault();\n const id = slot.itemId ?? slot.bookingId;\n if (id) {\n onItemClick?.(id);\n onBookingClick?.(id);\n return;\n }\n onSlotClick?.(dayIso, slot);\n }}\n >\n <div className=\"rbc-label\">{slot.title ?? `${slot.startTime} - ${slot.endTime}`}</div>\n <div className=\"rbc-sub\">{slot.description ?? slot.status}</div>\n </div>\n );\n })}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\nexport default BookingCalendar;\n","export function toIsoDate(date: Date): string {\n return date.toISOString().slice(0, 10);\n}\n\nexport function getWeekDays(anchor: Date, weekStartsOn: 0 | 1 | 6 = 6): Date[] {\n const current = new Date(anchor);\n current.setHours(12, 0, 0, 0);\n\n const day = current.getDay();\n const offset = (day - weekStartsOn + 7) % 7;\n current.setDate(current.getDate() - offset);\n\n return Array.from({ length: 7 }, (_, i) => {\n const d = new Date(current);\n d.setDate(current.getDate() + i);\n return d;\n });\n}\n\nexport function addDays(date: Date, amount: number): Date {\n const d = new Date(date);\n d.setDate(d.getDate() + amount);\n return d;\n}\n\nexport function generateTimeSlots(startHour: number, endHour: number, granularity: number): string[] {\n const items: string[] = [];\n const startMinutes = startHour * 60;\n const endMinutes = endHour * 60;\n for (let m = startMinutes; m < endMinutes; m += granularity) {\n const h = Math.floor(m / 60);\n const mm = m % 60;\n items.push(`${h.toString().padStart(2, '0')}:${mm.toString().padStart(2, '0')}`);\n }\n return items;\n}\n\nexport function getHourBounds(work: { workStartTime?: string; workEndTime?: string }[]): { start: number; end: number } {\n let start = 8;\n let end = 20;\n const starts: number[] = [];\n const ends: number[] = [];\n\n for (const d of work) {\n if (d.workStartTime && d.workEndTime) {\n starts.push(Number(d.workStartTime.split(':')[0]));\n const [eh, em] = d.workEndTime.split(':').map(Number);\n ends.push(eh + (em > 0 ? 1 : 0));\n }\n }\n\n if (starts.length && ends.length) {\n start = Math.min(...starts);\n end = Math.max(...ends);\n }\n\n return { start, end };\n}\n\nexport function rangesOverlap(startA: number, endA: number, startB: number, endB: number): boolean {\n return startA < endB && endA > startB;\n}\n","import type { CalendarTheme } from '../types';\n\nexport const defaultTheme: CalendarTheme = {\n primary: '#0f766e',\n bg: '#f4f7f7',\n panel: '#ffffff',\n border: '#d6e0df',\n text: '#102725',\n mutedText: '#5c7270',\n availableBg: '#dcfce7',\n bookedBg: '#fee2e2',\n blockedBg: '#e5e7eb',\n customBg: '#e0f2fe'\n};\n","import React, { useCallback, useMemo, useRef, useState } from 'react';\nimport type { CalendarTheme, GanttCreatePayload, GanttItem, GanttMovePayload, GanttResizePayload, GanttRow } from '../types';\nimport { defaultTheme } from '../styles/defaultTheme';\nimport '../styles/gantt.css';\n\n// ─── Helpers ────────────────────────────────────────────────────────────────\n\nfunction toMin(t: string): number {\n const [h, m] = t.split(':').map(Number);\n return h * 60 + m;\n}\nfunction toTime(mins: number): string {\n const clamped = Math.max(0, Math.min(23 * 60 + 59, mins));\n return `${String(Math.floor(clamped / 60)).padStart(2, '0')}:${String(clamped % 60).padStart(2, '0')}`;\n}\nfunction snapToGrid(mins: number, gran: number): number {\n return Math.round(mins / gran) * gran;\n}\nfunction isoStr(d: Date): string {\n return d.toISOString().slice(0, 10);\n}\nfunction addDays(d: Date, n: number): Date {\n const dd = new Date(d);\n dd.setDate(dd.getDate() + n);\n return dd;\n}\n\n// ─── Overlap lane assignment ─────────────────────────────────────────────────\n\ninterface LanedItem extends GanttItem {\n lane: number;\n totalLanes: number;\n}\n\nfunction assignLanesSequential(items: GanttItem[]): LanedItem[] {\n const n = items.length || 1;\n return items.map((item, i) => ({ ...item, lane: i, totalLanes: n }));\n}\n\nfunction daysBetween(a: string, b: string): number {\n return Math.round((new Date(b).getTime() - new Date(a).getTime()) / 86400000);\n}\n\nfunction addDaysToIso(iso: string, n: number): string {\n const d = new Date(iso);\n d.setDate(d.getDate() + n);\n return isoStr(d);\n}\n\nfunction assignLanes(items: GanttItem[]): LanedItem[] {\n const sorted = [...items].sort((a, b) => toMin(a.startTime) - toMin(b.startTime));\n const laneEnds: number[] = [];\n const result: LanedItem[] = [];\n for (const item of sorted) {\n const s = toMin(item.startTime);\n const e = toMin(item.endTime);\n let assigned = laneEnds.findIndex(end => end <= s);\n if (assigned === -1) { assigned = laneEnds.length; laneEnds.push(0); }\n laneEnds[assigned] = e;\n result.push({ ...item, lane: assigned, totalLanes: 0 });\n }\n const n = laneEnds.length || 1;\n return result.map(r => ({ ...r, totalLanes: n }));\n}\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport type GanttScale = 'day' | 'week' | 'month';\n\nexport interface GanttSchedulerProps {\n schedulerMode?: 'task-timeline' | 'resource-planner';\n rows: GanttRow[];\n items: GanttItem[];\n date: Date;\n // Hour mode props\n timeStart?: number;\n timeEnd?: number;\n granularity?: number;\n // View mode\n timeUnit?: 'hour' | 'day'; // 'hour' = hourly columns, 'day' = date columns\n scale?: GanttScale; // for day mode: 'week' (7 cols) or 'month' (30 cols)\n weekStartsOn?: 0 | 1 | 6;\n // Common\n locale?: string;\n direction?: 'rtl' | 'ltr';\n theme?: Partial<CalendarTheme>;\n onItemClick?: (id: string) => void;\n onItemMove?: (payload: GanttMovePayload) => void;\n onItemResize?: (payload: GanttResizePayload) => void;\n onItemCreate?: (payload: GanttCreatePayload) => void;\n translations?: Partial<{ previous: string; today: string; next: string; week: string; month: string }>;\n onDateChange?: (d: Date) => void;\n}\n\nconst ROW_MIN_H = 60;\nconst LANE_H = 44;\nconst LANE_GAP = 4;\nconst LABEL_W = 144;\n\n// ─── Component ───────────────────────────────────────────────────────────────\n\nexport function GanttScheduler({\n schedulerMode,\n rows,\n items,\n date,\n timeUnit = 'hour',\n scale = 'week',\n weekStartsOn = 1,\n timeStart = 8,\n timeEnd = 20,\n granularity = 30,\n locale = 'en-US',\n direction = 'ltr',\n theme,\n onItemClick,\n onItemMove,\n onItemResize,\n onItemCreate,\n translations,\n onDateChange,\n}: GanttSchedulerProps) {\n const merged = { ...defaultTheme, ...theme };\n const isRtl = direction === 'rtl';\n const todayStr = (() => { const d = new Date(); d.setHours(12, 0, 0, 0); return isoStr(d); })();\n const totalMins = (timeEnd - timeStart) * 60;\n\n const t = { previous: 'Previous', today: 'Today', next: 'Next', week: 'Week', month: 'Month', ...translations };\n\n const cssVars = {\n '--gantt-primary': merged.primary,\n '--gantt-bg': merged.bg,\n '--gantt-panel': merged.panel,\n '--gantt-border': merged.border,\n '--gantt-text': merged.text,\n '--gantt-muted': merged.mutedText,\n '--gantt-booked': merged.bookedBg,\n '--gantt-blocked': merged.blockedBg,\n '--gantt-custom': merged.customBg,\n } as React.CSSProperties;\n\n // ── HOUR MODE columns ────────────────────────────────────────────────────\n const hourCols = useMemo(() => {\n if (timeUnit !== 'hour') return [];\n return Array.from({ length: timeEnd - timeStart }, (_, i) =>\n `${String(timeStart + i).padStart(2, '0')}:00`\n );\n }, [timeUnit, timeStart, timeEnd]);\n\n // ── DAY MODE: compute visible date columns ───────────────────────────────\n const dayColumns = useMemo((): Date[] => {\n if (timeUnit !== 'day') return [];\n const anchor = new Date(date);\n anchor.setHours(12, 0, 0, 0);\n if (scale === 'week') {\n const dow = anchor.getDay();\n const offset = (dow - weekStartsOn + 7) % 7;\n anchor.setDate(anchor.getDate() - offset);\n return Array.from({ length: 7 }, (_, i) => addDays(anchor, i));\n }\n if (scale === 'month') {\n const first = new Date(anchor.getFullYear(), anchor.getMonth(), 1, 12);\n const daysInMonth = new Date(anchor.getFullYear(), anchor.getMonth() + 1, 0).getDate();\n return Array.from({ length: daysInMonth }, (_, i) => addDays(first, i));\n }\n // day = single day\n return [new Date(anchor)];\n }, [timeUnit, date, scale, weekStartsOn]);\n\n const dayColStrs = useMemo(() => dayColumns.map(isoStr), [dayColumns]);\n\n // ── Items grouped by row for HOUR mode ──────────────────────────────────\n const itemsByRowHour = useMemo(() => {\n if (timeUnit !== 'hour') return new Map<string, GanttItem[]>();\n const dateStr = isoStr(date);\n const map = new Map<string, GanttItem[]>();\n for (const item of items) {\n if (item.date !== dateStr) continue;\n const list = map.get(item.rowId) ?? [];\n list.push(item);\n map.set(item.rowId, list);\n }\n return map;\n }, [items, date, timeUnit]);\n\n // ── Items grouped by row+date for DAY mode ───────────────────────────────\n const itemsByRowDate = useMemo(() => {\n if (timeUnit !== 'day') return new Map<string, GanttItem[]>();\n const dateSet = new Set(dayColStrs);\n const map = new Map<string, GanttItem[]>();\n for (const item of items) {\n if (!dateSet.has(item.date)) continue;\n const key = `${item.rowId}__${item.date}`;\n const list = map.get(key) ?? [];\n list.push(item);\n map.set(key, list);\n }\n return map;\n }, [items, timeUnit, dayColStrs]);\n\n // ── Drag state ────────────────────────────────────────────────────────────\n const gridRef = useRef<HTMLDivElement>(null);\n const [dragging, setDragging] = useState<{\n type: 'move' | 'resize-left' | 'resize-right';\n item: GanttItem;\n origStart: number; origEnd: number;\n curStart: number; curEnd: number;\n curRowId: string; curDate: string;\n } | null>(null);\n\n // ── Create state (hour mode: drag on empty cell) ──────────────────────────\n const [creating, setCreating] = useState<{\n rowId: string;\n date: string; // hour-mode: single date; day-mode: start date\n startMin: number; // hour-mode only (0 for day-mode)\n endMin: number; // hour-mode only (0 for day-mode)\n endDate?: string; // day-mode only: current end date of ghost span\n } | null>(null);\n\n const getTimeFromX = useCallback((clientX: number, grid: HTMLDivElement): number => {\n const rect = grid.getBoundingClientRect();\n const contentW = rect.width - LABEL_W;\n const contentLeft = isRtl ? rect.left : rect.left + LABEL_W;\n const contentRight = isRtl ? rect.right - LABEL_W : rect.right;\n let frac = isRtl\n ? (contentRight - clientX) / contentW\n : (clientX - contentLeft) / contentW;\n frac = Math.max(0, Math.min(1, frac));\n return timeStart * 60 + frac * totalMins;\n }, [isRtl, timeStart, totalMins]);\n\n // For day-mode: get which date column the cursor is in\n const getDateFromX = useCallback((clientX: number, grid: HTMLDivElement): string | null => {\n if (!dayColumns.length) return null;\n const rect = grid.getBoundingClientRect();\n const contentW = rect.width - LABEL_W;\n const contentLeft = isRtl ? rect.left : rect.left + LABEL_W;\n const contentRight = isRtl ? rect.right - LABEL_W : rect.right;\n let frac = isRtl\n ? (contentRight - clientX) / contentW\n : (clientX - contentLeft) / contentW;\n frac = Math.max(0, Math.min(0.9999, frac));\n const colIdx = Math.floor(frac * dayColumns.length);\n return isoStr(dayColumns[Math.min(colIdx, dayColumns.length - 1)]);\n }, [dayColumns, isRtl]);\n\n const getRowFromY = useCallback((clientY: number, grid: HTMLDivElement): string | null => {\n const scrollTop = grid.scrollTop ?? 0;\n const rect = grid.getBoundingClientRect();\n const relY = clientY - rect.top + scrollTop - 40;\n let acc = 0;\n for (const row of rows) {\n const h = ROW_MIN_H;\n if (relY >= acc && relY < acc + h) return row.id;\n acc += h;\n }\n return null;\n }, [rows]);\n\n const onMouseMove = useCallback((e: React.MouseEvent<HTMLDivElement>) => {\n // Handle create drag in hour mode\n if (creating && gridRef.current && timeUnit === 'hour') {\n const rawMin = getTimeFromX(e.clientX, gridRef.current);\n const snapped = snapToGrid(rawMin, granularity);\n const endMin = Math.max(snapped, creating.startMin + granularity);\n setCreating(c => c ? { ...c, endMin } : null);\n return;\n }\n // Handle create drag in day mode\n if (creating && gridRef.current && timeUnit === 'day') {\n const hovered = getDateFromX(e.clientX, gridRef.current);\n if (hovered) setCreating(c => c ? { ...c, endDate: hovered } : null);\n return;\n }\n\n if (!dragging || !gridRef.current) return;\n\n if (timeUnit === 'hour') {\n const rawMin = getTimeFromX(e.clientX, gridRef.current);\n const duration = dragging.origEnd - dragging.origStart;\n if (dragging.type === 'move') {\n const snapped = snapToGrid(rawMin - duration / 2, granularity);\n const newStart = Math.max(timeStart * 60, snapped);\n const newRowId = getRowFromY(e.clientY, gridRef.current) ?? dragging.curRowId;\n setDragging(d => d ? { ...d, curStart: newStart, curEnd: newStart + duration, curRowId: newRowId } : null);\n } else if (dragging.type === 'resize-left') {\n const snapped = snapToGrid(rawMin, granularity);\n setDragging(d => d ? { ...d, curStart: Math.min(snapped, dragging.curEnd - granularity) } : null);\n } else {\n const snapped = snapToGrid(rawMin, granularity);\n setDragging(d => d ? { ...d, curEnd: Math.max(snapped, dragging.curStart + granularity) } : null);\n }\n } else if (timeUnit === 'day' && dragging.type === 'move') {\n const newDate = getDateFromX(e.clientX, gridRef.current) ?? dragging.curDate;\n const newRowId = getRowFromY(e.clientY, gridRef.current) ?? dragging.curRowId;\n setDragging(d => d ? { ...d, curDate: newDate, curRowId: newRowId } : null);\n }\n }, [creating, dragging, getTimeFromX, getDateFromX, getRowFromY, granularity, timeStart, timeUnit]);\n\n const onMouseUp = useCallback(() => {\n // Finish create\n if (creating) {\n if (timeUnit === 'hour') {\n const dur = creating.endMin - creating.startMin;\n if (dur >= granularity) {\n onItemCreate?.({\n rowId: creating.rowId,\n date: creating.date,\n startTime: toTime(creating.startMin),\n endTime: toTime(creating.endMin),\n });\n }\n } else {\n // day-mode create: span from date to endDate\n const endDate = creating.endDate ?? creating.date;\n const [startDate, finalEnd] = creating.date <= endDate\n ? [creating.date, endDate]\n : [endDate, creating.date];\n onItemCreate?.({\n rowId: creating.rowId,\n date: startDate,\n endDate: finalEnd !== startDate ? finalEnd : undefined,\n startTime: '09:00',\n endTime: '18:00',\n });\n }\n setCreating(null);\n return;\n }\n if (!dragging) return;\n const { item, type, curStart, curEnd, curRowId, curDate } = dragging;\n if (type === 'move') {\n let newEndDate: string | undefined;\n if (item.endDate) {\n const span = daysBetween(item.date, item.endDate);\n newEndDate = addDaysToIso(curDate, span);\n }\n onItemMove?.({\n item,\n newRowId: curRowId,\n newDate: curDate,\n newEndDate,\n newStartTime: toTime(curStart),\n newEndTime: toTime(curEnd),\n });\n } else {\n onItemResize?.({ item, newStartTime: toTime(curStart), newEndTime: toTime(curEnd) });\n }\n setDragging(null);\n }, [creating, dragging, granularity, onItemCreate, onItemMove, onItemResize, timeUnit]);\n\n // ── Navigation ────────────────────────────────────────────────────────────\n const navDelta = timeUnit === 'day'\n ? (scale === 'month' ? 30 : scale === 'week' ? 7 : 1)\n : 1;\n\n const navigate = (delta: number) => {\n if (!onDateChange) return;\n onDateChange(addDays(date, delta * navDelta));\n };\n\n const titleLabel = useMemo(() => {\n if (timeUnit === 'day' && dayColumns.length > 1) {\n const first = dayColumns[0].toLocaleDateString(locale, { month: 'short', day: 'numeric' });\n const last = dayColumns[dayColumns.length - 1].toLocaleDateString(locale, { month: 'short', day: 'numeric', year: 'numeric' });\n return `${first} – ${last}`;\n }\n return date.toLocaleDateString(locale, { weekday: 'long', year: 'numeric', month: 'short', day: 'numeric' });\n }, [timeUnit, dayColumns, date, locale]);\n\n // ─────────────────────────────────────────────────────────────────────────\n // RENDER\n // ─────────────────────────────────────────────────────────────────────────\n\n return (\n <div\n className={`gantt-root ${isRtl ? 'gantt-rtl' : 'gantt-ltr'}`}\n data-scheduler-mode={schedulerMode}\n style={{ ...cssVars, direction: isRtl ? 'rtl' : 'ltr' }}\n onMouseMove={dragging || creating ? onMouseMove : undefined}\n onMouseUp={dragging || creating ? onMouseUp : undefined}\n onMouseLeave={dragging || creating ? onMouseUp : undefined}\n >\n {/* Toolbar */}\n <div className=\"gantt-toolbar\">\n <div style={{ display: 'flex', gap: 6 }}>\n <button className=\"gantt-btn\" onClick={() => navigate(-1)}>{t.previous}</button>\n <button className=\"gantt-btn\" onClick={() => onDateChange?.(new Date())}>{t.today}</button>\n <button className=\"gantt-btn\" onClick={() => navigate(1)}>{t.next}</button>\n </div>\n <strong className=\"gantt-title\">{titleLabel}</strong>\n <div style={{ display: 'flex', gap: 4 }}>\n <span className=\"gantt-badge\">\n {timeUnit === 'hour' ? '⏱ Hour' : scale === 'month' ? '📅 Month' : scale === 'week' ? '📅 Week' : '📅 Day'}\n </span>\n </div>\n </div>\n\n {/* Main grid */}\n <div className=\"gantt-scroll-wrap\" ref={gridRef}>\n\n {/* ── HOUR MODE ────────────────────────────────────────────────────── */}\n {timeUnit === 'hour' && (\n <>\n <div className=\"gantt-header\">\n <div className=\"gantt-label-col gantt-header-label\" />\n <div className=\"gantt-time-header\">\n {hourCols.map(slot => (\n <div key={slot} className=\"gantt-time-cell\">{slot}</div>\n ))}\n </div>\n </div>\n\n {rows.map(row => {\n // When dragging, show item in its TARGET row (not original)\n const baseItems = itemsByRowHour.get(row.id) ?? [];\n const dragItem = dragging?.item;\n const isDragTargetRow = dragging?.type === 'move' && dragging.curRowId === row.id && dragItem?.rowId !== row.id;\n const isDragSourceRow = dragging?.type === 'move' && dragItem?.rowId === row.id && dragging.curRowId !== row.id;\n // For source row: hide the dragged item; for target row: add ghost\n const visibleItems = isDragSourceRow\n ? baseItems.filter(i => i.id !== dragItem!.id)\n : baseItems;\n const ghostItems: GanttItem[] = isDragTargetRow && dragItem\n ? [{ ...dragItem, rowId: row.id, startTime: toTime(dragging!.curStart), endTime: toTime(dragging!.curEnd) }]\n : [];\n\n const allVisible = [...visibleItems, ...ghostItems];\n const laned = assignLanes(allVisible);\n const maxLanes = Math.max(1, laned.length > 0 ? Math.max(...laned.map(l => l.totalLanes)) : 1);\n const rowH = Math.max(ROW_MIN_H, maxLanes * (LANE_H + LANE_GAP) + LANE_GAP * 2);\n\n return (\n <div key={row.id} className=\"gantt-row\" style={{ minHeight: rowH }}>\n <div className=\"gantt-label-col\">\n <div className=\"gantt-row-label-text\">{row.label}</div>\n {row.subLabel && <div className=\"gantt-row-sublabel\">{row.subLabel}</div>}\n </div>\n <div\n className=\"gantt-row-content\"\n style={{ '--gantt-cols': hourCols.length, cursor: onItemCreate ? 'cell' : 'default' } as React.CSSProperties}\n onMouseDown={(ev) => {\n if (ev.button !== 0 || !onItemCreate || !gridRef.current) return;\n if ((ev.target as HTMLElement).closest('.gantt-item')) return;\n ev.preventDefault();\n const rawMin = getTimeFromX(ev.clientX, gridRef.current);\n const snapped = snapToGrid(rawMin, granularity);\n setCreating({ rowId: row.id, date: isoStr(date), startMin: snapped, endMin: snapped });\n }}\n >\n {hourCols.map((_, i) => (\n <div\n key={i}\n className=\"gantt-grid-line\"\n style={\n isRtl\n ? { right: `${(i / hourCols.length) * 100}%` }\n : { left: `${(i / hourCols.length) * 100}%` }\n }\n />\n ))}\n\n {/* Create ghost */}\n {creating?.rowId === row.id && (\n <div\n className=\"gantt-selection-ghost\"\n style={{\n ...(isRtl\n ? { right: `${Math.max(0, ((creating.startMin - timeStart * 60) / totalMins) * 100)}%` }\n : { left: `${Math.max(0, ((creating.startMin - timeStart * 60) / totalMins) * 100)}%` }),\n width: `${Math.max(0.5, ((creating.endMin - creating.startMin) / totalMins) * 100)}%`,\n top: LANE_GAP, height: LANE_H,\n }}\n >\n <div className=\"gantt-item-inner\">\n <div className=\"gantt-item-title\">{toTime(creating.startMin)} – {toTime(creating.endMin)}</div>\n </div>\n </div>\n )}\n\n {laned.map(item => {\n const isOrigDrg = dragging?.item.id === item.id && dragging.curRowId === row.id;\n const isGhost = ghostItems.some(g => g.id === item.id);\n const s = isOrigDrg || isGhost ? dragging!.curStart : toMin(item.startTime);\n const e = isOrigDrg || isGhost ? dragging!.curEnd : toMin(item.endTime);\n const leftPct = ((s - timeStart * 60) / totalMins) * 100;\n const widthPct = ((e - s) / totalMins) * 100;\n const topPx = LANE_GAP + item.lane * (LANE_H + LANE_GAP);\n const cls = `gantt-item gantt-item-${item.status} ${isOrigDrg || isGhost ? 'gantt-item-dragging' : ''}`;\n\n return (\n <div\n key={`${item.id}-${row.id}`}\n className={cls}\n style={{\n ...(isRtl\n ? { right: `${Math.max(0, leftPct)}%` }\n : { left: `${Math.max(0, leftPct)}%` }),\n width: `${Math.max(0.5, widthPct)}%`,\n top: topPx,\n height: LANE_H,\n cursor: isGhost ? 'grabbing' : 'grab'\n }}\n onClick={(ev) => { ev.stopPropagation(); if (!dragging) onItemClick?.(item.id); }}\n onKeyDown={(ev) => {\n if (ev.key !== 'Enter' && ev.key !== ' ') return;\n ev.preventDefault();\n ev.stopPropagation();\n if (!dragging) onItemClick?.(item.id);\n }}\n role=\"button\"\n tabIndex={0}\n onMouseDown={(ev) => {\n if (ev.button !== 0 || isGhost) return; ev.preventDefault();\n setDragging({ type: 'move', item, origStart: toMin(item.startTime), origEnd: toMin(item.endTime), curStart: toMin(item.startTime), curEnd: toMin(item.endTime), curRowId: row.id, curDate: item.date });\n }}\n >\n <div className=\"gantt-handle gantt-handle-left\" onMouseDown={(ev) => { if (isGhost) return; ev.preventDefault(); ev.stopPropagation(); setDragging({ type: isRtl ? 'resize-right' : 'resize-left', item, origStart: toMin(item.startTime), origEnd: toMin(item.endTime), curStart: toMin(item.startTime), curEnd: toMin(item.endTime), curRowId: row.id, curDate: item.date }); }} />\n <div className=\"gantt-item-inner\">\n <div className=\"gantt-item-title\">{item.title}</div>\n {item.subTitle && <div className=\"gantt-item-sub\">{item.subTitle}</div>}\n </div>\n <div className=\"gantt-handle gantt-handle-right\" onMouseDown={(ev) => { if (isGhost) return; ev.preventDefault(); ev.stopPropagation(); setDragging({ type: isRtl ? 'resize-left' : 'resize-right', item, origStart: toMin(item.startTime), origEnd: toMin(item.endTime), curStart: toMin(item.startTime), curEnd: toMin(item.endTime), curRowId: row.id, curDate: item.date }); }} />\n </div>\n );\n })}\n </div>\n </div>\n );\n })}\n </>\n )}\n\n {/* ── DAY MODE ─────────────────────────────────────────────────────── */}\n {timeUnit === 'day' && (\n <>\n <div className=\"gantt-header\">\n <div className=\"gantt-label-col gantt-header-label\" />\n <div className=\"gantt-time-header\">\n {dayColumns.map((d) => {\n const ds = isoStr(d);\n const isToday = ds === todayStr;\n const label = scale === 'month'\n ? d.toLocaleDateString(locale, { day: 'numeric' })\n : d.toLocaleDateString(locale, { weekday: 'short', month: 'short', day: 'numeric' });\n return (\n <div key={ds} className={`gantt-time-cell ${isToday ? 'gantt-today-col' : ''}`}>\n {label}\n </div>\n );\n })}\n </div>\n </div>\n\n {rows.map(row => {\n // Collect all items for this row with sequential lane assignment per start-date cell\n const rowItems = dayColStrs.flatMap(ds =>\n assignLanesSequential(itemsByRowDate.get(`${row.id}__${ds}`) ?? [])\n );\n\n // Row height: max items starting on any single day\n const maxPerCol = Math.max(1, ...dayColStrs.map(ds =>\n (itemsByRowDate.get(`${row.id}__${ds}`) ?? []).length\n ));\n const rowH = Math.max(ROW_MIN_H, maxPerCol * (LANE_H + LANE_GAP) + LANE_GAP * 2);\n\n // Create ghost column span\n const creatingThisRow = creating?.rowId === row.id && creating.endDate !== undefined;\n let ghostColStart = -1, ghostColEnd = -1;\n if (creatingThisRow && creating) {\n const a = dayColStrs.indexOf(creating.date);\n const b = dayColStrs.indexOf(creating.endDate!);\n const ai = a < 0 ? 0 : a;\n const bi = b < 0 ? 0 : b;\n ghostColStart = Math.min(ai, bi);\n ghostColEnd = Math.max(ai, bi);\n }\n\n return (\n <div key={row.id} className=\"gantt-row\" style={{ minHeight: rowH }}>\n <div className=\"gantt-label-col\">\n <div className=\"gantt-row-label-text\">{row.label}</div>\n {row.subLabel && <div className=\"gantt-row-sublabel\">{row.subLabel}</div>}\n </div>\n\n <div className=\"gantt-row-day-content\" style={{ position: 'relative' }}>\n {/* Background cells — click/drag-create zones */}\n {dayColumns.map((d) => {\n const ds = isoStr(d);\n const isToday = ds === todayStr;\n const isDragTarget = dragging?.type === 'move'\n && dragging.curRowId === row.id\n && dragging.curDate === ds\n && (dragging.curDate !== dragging.item.date || dragging.curRowId !== dragging.item.rowId);\n return (\n <div\n key={ds}\n className={`gantt-day-cell ${isToday ? 'gantt-today-col' : ''} ${isDragTarget ? 'gantt-day-cell-target' : ''}`}\n style={{ minHeight: rowH, cursor: onItemCreate ? 'cell' : 'default' }}\n onMouseDown={(ev) => {\n if (ev.button !== 0 || !onItemCreate || !gridRef.current) return;\n if ((ev.target as HTMLElement).closest('.gantt-item')) return;\n ev.preventDefault();\n setCreating({ rowId: row.id, date: ds, startMin: 0, endMin: 0, endDate: ds });\n }}\n />\n );\n })}\n\n {/* Create ghost */}\n {creatingThisRow && ghostColStart >= 0 && (\n <div\n className=\"gantt-selection-ghost\"\n style={{\n position: 'absolute',\n top: LANE_GAP,\n height: LANE_H,\n ...(isRtl\n ? { right: `${(ghostColStart / dayColumns.length) * 100}%` }\n : { left: `${(ghostColStart / dayColumns.length) * 100}%` }),\n width: `${((ghostColEnd - ghostColStart + 1) / dayColumns.length) * 100}%`,\n }}\n >\n <div className=\"gantt-item-inner\">\n <div className=\"gantt-item-title\">\n {dayColumns[ghostColStart]?.toLocaleDateString(locale, { month: 'short', day: 'numeric' })}\n {ghostColEnd !== ghostColStart && ` – ${dayColumns[ghostColEnd]?.toLocaleDateString(locale, { month: 'short', day: 'numeric' })}`}\n </div>\n </div>\n </div>\n )}\n\n {/* Items overlay — positioned absolutely over the cell grid */}\n {rowItems.map(item => {\n const colStart = dayColStrs.indexOf(item.date);\n if (colStart < 0) return null;\n const rawColEnd = item.endDate ? dayColStrs.indexOf(item.endDate) : colStart;\n const colEnd = rawColEnd < 0 ? dayColStrs.length - 1 : Math.max(colStart, rawColEnd);\n const spanCols = colEnd - colStart + 1;\n\n const isDraggingThis = dragging?.item.id === item.id && dragging.type === 'move';\n const rawEffectiveColStart = isDraggingThis ? dayColStrs.indexOf(dragging!.curDate) : colStart;\n if (rawEffectiveColStart < 0) return null; // dragged outside visible range\n const effectiveColStart = rawEffectiveColStart;\n const effectiveSpan = spanCols; // preserve span on drag\n\n const leftPct = (effectiveColStart / dayColumns.length) * 100;\n const widthPct = (effectiveSpan / dayColumns.length) * 100;\n const topPx = LANE_GAP + item.lane * (LANE_H + LANE_GAP);\n\n const cls = `gantt-item gantt-item-${item.status} gantt-day-item-overlay${isDraggingThis ? ' gantt-item-dragging' : ''}`;\n\n return (\n <div\n key={`${item.id}-${row.id}`}\n className={cls}\n style={{\n position: 'absolute',\n top: topPx,\n height: LANE_H,\n ...(isRtl\n ? { right: `${Math.max(0, leftPct)}%` }\n : { left: `${Math.max(0, leftPct)}%` }),\n width: `${Math.max(0.5, widthPct)}%`,\n cursor: isDraggingThis ? 'grabbing' : 'grab',\n boxSizing: 'border-box' as const,\n paddingLeft: 4,\n paddingRight: 4,\n }}\n onClick={(ev) => { ev.stopPropagation(); if (!dragging) onItemClick?.(item.id); }}\n onKeyDown={(ev) => {\n if (ev.key !== 'Enter' && ev.key !== ' ') return;\n ev.preventDefault(); ev.stopPropagation();\n if (!dragging) onItemClick?.(item.id);\n }}\n role=\"button\"\n tabIndex={0}\n onMouseDown={(ev) => {\n if (ev.button !== 0) return;\n ev.preventDefault(); ev.stopPropagation();\n setDragging({\n type: 'move', item,\n origStart: toMin(item.startTime), origEnd: toMin(item.endTime),\n curStart: toMin(item.startTime), curEnd: toMin(item.endTime),\n curRowId: row.id, curDate: item.date,\n });\n }}\n >\n <div className=\"gantt-item-inner\">\n <div className=\"gantt-item-title\">{item.title}</div>\n <div className=\"gantt-item-sub\">\n {item.endDate\n ? `${item.date} – ${item.endDate}`\n : `${item.startTime}–${item.endTime}`}\n {item.subTitle ? ` · ${item.subTitle}` : ''}\n </div>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n })}\n </>\n )}\n </div>\n </div>\n );\n}\n","import type {\n GanttDataAdapter, GanttItem, GanttRow,\n ResourceDefinition, ResourcePlannerItem,\n SchedulerDataAdapter, SlotStatus,\n TaskTimelineItem\n} from './types';\n\nfunction defStatus(s?: SlotStatus): SlotStatus {\n return s ?? 'custom';\n}\n\n// ─── Legacy time-grid adapters (kept for backward compat) ──────────────────\n\nexport function createTaskTimelineAdapter(): GanttDataAdapter<TaskTimelineItem[]> {\n return {\n toGantt(items, { date }) {\n // Extract unique assignees → rows\n const assigneeOrder: string[] = [];\n const seen = new Set<string>();\n for (const item of items) {\n const key = item.assignee ?? item.title;\n if (!seen.has(key)) { seen.add(key); assigneeOrder.push(key); }\n }\n\n const rows: GanttRow[] = assigneeOrder.map(a => ({ id: a, label: a }));\n\n const ganttItems: GanttItem[] = items.map(item => ({\n id: item.id,\n rowId: item.assignee ?? item.title,\n date: item.date,\n endDate: item.endDate,\n startTime: item.startTime,\n endTime: item.endTime,\n title: item.title,\n subTitle: item.progress != null ? `${item.progress}%` : item.assignee,\n status: defStatus(item.status),\n }));\n\n // Compute visible time bounds from items on the current day\n const todayStr = date.toISOString().slice(0, 10);\n const todayItems = ganttItems.filter(i => i.date === todayStr);\n const allItems = ganttItems;\n const starts = allItems.map(i => toMin(i.startTime));\n const ends = allItems.map(i => toMin(i.endTime));\n const timeStart = starts.length ? Math.max(0, Math.floor(Math.min(...starts) / 60) - 1) : 8;\n const timeEnd = ends.length ? Math.min(24, Math.ceil(Math.max(...ends) / 60) + 1) : 20;\n\n return { rows, items: ganttItems, timeStart, timeEnd, granularity: 30, timeUnit: 'hour' as const };\n },\n };\n}\n\nexport function createResourcePlannerAdapter(\n resources: ResourceDefinition[]\n): GanttDataAdapter<ResourcePlannerItem[]> {\n return {\n toGantt(items) {\n const rows: GanttRow[] = resources.map(r => ({\n id: r.id,\n label: r.title,\n subLabel: r.meta?.type as string | undefined,\n }));\n\n const ganttItems: GanttItem[] = items.map(item => ({\n id: item.id,\n rowId: item.resourceId,\n date: item.date,\n startTime: item.startTime,\n endTime: item.endTime,\n title: item.title,\n subTitle: item.description,\n status: defStatus(item.status),\n }));\n\n const starts = ganttItems.map(i => toMin(i.startTime));\n const ends = ganttItems.map(i => toMin(i.endTime));\n const timeStart = starts.length ? Math.max(0, Math.floor(Math.min(...starts) / 60) - 1) : 8;\n const timeEnd = ends.length ? Math.min(24, Math.ceil(Math.max(...ends) / 60) + 1) : 20;\n\n return { rows, items: ganttItems, timeStart, timeEnd, granularity: 30, timeUnit: 'day' as const };\n },\n };\n}\n\nfunction toMin(t: string): number {\n const [h, m] = t.split(':').map(Number);\n return h * 60 + m;\n}\n"],"mappings":"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","names":["React","useMemo","useState","addDays","jsx","jsxs","useState","React","useMemo","t","i","toMin"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@omidrahmati/react-slot-scheduler",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Production-ready React scheduler with time-grid, task timeline (Gantt), and resource planning modes",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"react",
|
|
7
|
+
"calendar",
|
|
8
|
+
"scheduler",
|
|
9
|
+
"booking",
|
|
10
|
+
"slot",
|
|
11
|
+
"appointment",
|
|
12
|
+
"rtl",
|
|
13
|
+
"persian",
|
|
14
|
+
"farsi",
|
|
15
|
+
"arabic",
|
|
16
|
+
"jalali",
|
|
17
|
+
"weekly-calendar",
|
|
18
|
+
"daily-calendar",
|
|
19
|
+
"gantt",
|
|
20
|
+
"timeline",
|
|
21
|
+
"resource-planning",
|
|
22
|
+
"drag-drop",
|
|
23
|
+
"dark-mode",
|
|
24
|
+
"typescript",
|
|
25
|
+
"next.js",
|
|
26
|
+
"zero-deps",
|
|
27
|
+
"booking-calendar",
|
|
28
|
+
"react-scheduler",
|
|
29
|
+
"time-slots",
|
|
30
|
+
"slot-picker"
|
|
31
|
+
],
|
|
32
|
+
"homepage": "https://github.com/omidrahmati2000/react-slot-scheduler",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/omidrahmati2000/react-slot-scheduler.git"
|
|
36
|
+
},
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/omidrahmati2000/react-slot-scheduler/issues"
|
|
39
|
+
},
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"author": "Omid Rahmati <omidrahmati2000@gmail.com> (https://github.com/omidrahmati2000)",
|
|
42
|
+
"type": "module",
|
|
43
|
+
"main": "dist/index.cjs",
|
|
44
|
+
"module": "dist/index.js",
|
|
45
|
+
"types": "dist/index.d.ts",
|
|
46
|
+
"files": [
|
|
47
|
+
"dist",
|
|
48
|
+
"README.md",
|
|
49
|
+
"CHANGELOG.md",
|
|
50
|
+
"LICENSE"
|
|
51
|
+
],
|
|
52
|
+
"exports": {
|
|
53
|
+
".": {
|
|
54
|
+
"types": "./dist/index.d.ts",
|
|
55
|
+
"import": "./dist/index.js",
|
|
56
|
+
"require": "./dist/index.cjs"
|
|
57
|
+
},
|
|
58
|
+
"./dist/index.css": "./dist/index.css"
|
|
59
|
+
},
|
|
60
|
+
"sideEffects": [
|
|
61
|
+
"**/*.css"
|
|
62
|
+
],
|
|
63
|
+
"peerDependencies": {
|
|
64
|
+
"react": ">=18",
|
|
65
|
+
"react-dom": ">=18"
|
|
66
|
+
},
|
|
67
|
+
"devDependencies": {
|
|
68
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
69
|
+
"@testing-library/react": "^16.3.2",
|
|
70
|
+
"@testing-library/user-event": "^14.6.1",
|
|
71
|
+
"@types/react": "^18.3.12",
|
|
72
|
+
"@types/react-dom": "^18.3.1",
|
|
73
|
+
"@vitest/coverage-v8": "^4.1.7",
|
|
74
|
+
"jsdom": "^29.1.1",
|
|
75
|
+
"tsup": "^8.3.0",
|
|
76
|
+
"typescript": "^5.6.3",
|
|
77
|
+
"vitest": "^4.1.7"
|
|
78
|
+
},
|
|
79
|
+
"scripts": {
|
|
80
|
+
"build": "tsup src/index.ts --format esm,cjs --dts --sourcemap --clean",
|
|
81
|
+
"typecheck": "tsc --noEmit",
|
|
82
|
+
"test": "vitest run",
|
|
83
|
+
"test:watch": "vitest",
|
|
84
|
+
"test:coverage": "vitest run --coverage",
|
|
85
|
+
"pack:check": "npm pack --dry-run",
|
|
86
|
+
"prepublishOnly": "npm run build && npm run typecheck"
|
|
87
|
+
}
|
|
88
|
+
}
|