@stfrigerio/sito-template 0.1.52 → 0.1.54

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.
@@ -9,8 +9,12 @@ export interface CalendarEvent {
9
9
  title: string;
10
10
  /** Event date */
11
11
  date: Date | string;
12
- /** Optional time string (e.g., "14:30") */
12
+ /** Optional start time string (e.g., "14:30") */
13
13
  time?: string;
14
+ /** Optional end time string (e.g., "15:30") — used for duration-based height in day view */
15
+ endTime?: string;
16
+ /** If true, event is rendered in the all-day strip above the timeline */
17
+ allDay?: boolean;
14
18
  /** Event type/category for styling and icons */
15
19
  type?: string;
16
20
  /** Event status (affects opacity and styling) */
@@ -39,6 +43,14 @@ export interface CalendarConfig {
39
43
  mondayStart?: boolean;
40
44
  /** Show week numbers */
41
45
  showWeekNumbers?: boolean;
46
+ /** Day view: first hour to show (default 0) */
47
+ startHour?: number;
48
+ /** Day view: last hour to show, exclusive (default 24) */
49
+ endHour?: number;
50
+ /** Day view: pixel height per hour slot (default 60) */
51
+ hourHeight?: number;
52
+ /** Day view: split hour slots into two clickable halves with 30-minute precision (default false) */
53
+ halfHourSlots?: boolean;
42
54
  /** Custom date format */
43
55
  dateFormat?: Intl.DateTimeFormatOptions;
44
56
  /** Custom locale */
@@ -73,6 +85,8 @@ export interface CalendarProps {
73
85
  };
74
86
  /** Callback when a time slot is clicked in day view */
75
87
  onTimeSlotClick?: (date: Date, hour: number, time: string) => void;
88
+ /** Callback when an event is dropped (drag-rescheduled) in day view */
89
+ onEventDrop?: (event: CalendarEvent, newDate: Date) => void;
76
90
  /** Initial view mode */
77
91
  viewMode?: 'month' | 'week' | 'day';
78
92
  /** Initial date to display */
@@ -123,5 +137,5 @@ export interface CalendarProps {
123
137
  * onEventClick={handleEventClick}
124
138
  * />
125
139
  */
126
- export declare function Calendar({ events, onEventClick, onDateClick, onEventClickByView, onDateClickByView, onTimeSlotClick, viewMode, initialDate, config, className, style, loading, emptyState, hideHeader, compact, selectedDate }: CalendarProps): import("react/jsx-runtime").JSX.Element;
140
+ export declare function Calendar({ events, onEventClick, onDateClick, onEventClickByView, onDateClickByView, onTimeSlotClick, onEventDrop, viewMode, initialDate, config, className, style, loading, emptyState, hideHeader, compact, selectedDate }: CalendarProps): import("react/jsx-runtime").JSX.Element;
127
141
  //# sourceMappingURL=Calendar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Calendar.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/Calendar/Calendar.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Calendar.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/Calendar/Calendar.tsx"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC1B,sCAAsC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB;IACjB,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC;IACpB,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4FAA4F;IAC5F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,MAAM,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,MAAM,CAAC;IACxD,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IAC9C,gCAAgC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC3B,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,2CAA2C;IAC3C,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,KAAK,CAAC,SAAS,CAAC;IACzD,6DAA6D;IAC7D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qDAAqD;IACrD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,wBAAwB;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oGAAoG;IACpG,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,yBAAyB;IACzB,UAAU,CAAC,EAAE,IAAI,CAAC,qBAAqB,CAAC;IACxC,oBAAoB;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,yBAAyB;IACzB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC1B,iCAAiC;IACjC,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,wCAAwC;IACxC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC9C,sCAAsC;IACtC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACnC,yCAAyC;IACzC,kBAAkB,CAAC,EAAE;QACjB,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;QACvC,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;QACtC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;KACxC,CAAC;IACF,wCAAwC;IACxC,iBAAiB,CAAC,EAAE;QAChB,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;QAC7B,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;QAC5B,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;KAC9B,CAAC;IACF,uDAAuD;IACvD,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACnE,uEAAuE;IACvE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,IAAI,KAAK,IAAI,CAAC;IAC5D,wBAAwB;IACxB,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;IACpC,8BAA8B;IAC9B,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,4BAA4B;IAC5B,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,oBAAoB;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mCAAmC;IACnC,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,kEAAkE;IAClE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gFAAgF;IAChF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0GAA0G;IAC1G,YAAY,CAAC,EAAE,IAAI,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,QAAQ,CAAC,EACrB,MAAM,EACN,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,QAAkB,EAClB,WAAwB,EACxB,MAAW,EACX,SAAc,EACd,KAAU,EACV,OAAe,EACf,UAAU,EACV,UAAkB,EAClB,OAAe,EACf,YAAY,EACf,EAAE,aAAa,2CA+lBf"}
package/dist/index.esm.js CHANGED
@@ -2954,7 +2954,7 @@ const LiquidButton = ({ actions, icon: Icon = Plus, className = '', }) => {
2954
2954
  }, onClick: () => handleAction(action), children: [jsx(action.icon, { size: 18, color: action.color }), jsx("span", { className: styles$a.actionLabel, children: action.label })] }, action.key))) })) }), jsx(motion.button, { type: "button", className: styles$a.button, onClick: handleToggle, animate: { rotate: expanded ? 45 : 0 }, transition: { duration: 0.2 }, "aria-label": expanded ? 'Close actions' : 'Open actions', children: jsx(Icon, { size: 24, strokeWidth: 2.5 }) })] })] }));
2955
2955
  };
2956
2956
 
2957
- var styles$9 = {"calendar":"Calendar-module_calendar__3mIJS","loading":"Calendar-module_loading__59Z9-","loadingSpinner":"Calendar-module_loadingSpinner__7MXqV","header":"Calendar-module_header__cZHNA","navigation":"Calendar-module_navigation__PGkpY","navButton":"Calendar-module_navButton__kOe-w","title":"Calendar-module_title__oJZ7m","controls":"Calendar-module_controls__i1Z38","todayButton":"Calendar-module_todayButton__Ac9zc","viewToggle":"Calendar-module_viewToggle__Fhg2t","viewButton":"Calendar-module_viewButton__J2WY6","active":"Calendar-module_active__lIqH-","weekDays":"Calendar-module_weekDays__4J-8f","weekNumberHeader":"Calendar-module_weekNumberHeader__xhKbB","weekDay":"Calendar-module_weekDay__cg8Gr","daysGrid":"Calendar-module_daysGrid__ER0GM","weekView":"Calendar-module_weekView__bdtGs","dayCell":"Calendar-module_dayCell__TV-HR","dayNumber":"Calendar-module_dayNumber__ICH-X","today":"Calendar-module_today__eGuUU","events":"Calendar-module_events__qdbs7","event":"Calendar-module_event__Q1Zq3","eventTitle":"Calendar-module_eventTitle__XU7Wd","eventTime":"Calendar-module_eventTime__pMGEB","otherMonth":"Calendar-module_otherMonth__r6VJK","selected":"Calendar-module_selected__5e6h0","compact":"Calendar-module_compact__i0SF3","dots":"Calendar-module_dots__1Q7QR","dot":"Calendar-module_dot__tsCR1","dotMore":"Calendar-module_dotMore__emasD","weekNumber":"Calendar-module_weekNumber__nlo50","completed":"Calendar-module_completed__B-SHI","completedIcon":"Calendar-module_completedIcon__-oDZ9","moreEvents":"Calendar-module_moreEvents__TIKaT","emptyState":"Calendar-module_emptyState__2fcj7","dayView":"Calendar-module_dayView__PCIos","dayViewHeader":"Calendar-module_dayViewHeader__Gvxx2","timeColumnHeader":"Calendar-module_timeColumnHeader__B0btR","dayColumnHeader":"Calendar-module_dayColumnHeader__Rjqwg","dayViewScrollContainer":"Calendar-module_dayViewScrollContainer__84Byq","dayViewContent":"Calendar-module_dayViewContent__VU9JI","timeColumn":"Calendar-module_timeColumn__Sce-X","dayColumn":"Calendar-module_dayColumn__-j2oT","timeSlot":"Calendar-module_timeSlot__jldHq","timeLabel":"Calendar-module_timeLabel__9xLiK","hourSlot":"Calendar-module_hourSlot__z-80Q","hourLine":"Calendar-module_hourLine__fofdD","dayEvent":"Calendar-module_dayEvent__tSPFa","dayEventTitle":"Calendar-module_dayEventTitle__er03k","dayEventTime":"Calendar-module_dayEventTime__TlkeQ","currentTimeIndicator":"Calendar-module_currentTimeIndicator__GntOZ"};
2957
+ var styles$9 = {"calendar":"Calendar-module_calendar__3mIJS","loading":"Calendar-module_loading__59Z9-","loadingSpinner":"Calendar-module_loadingSpinner__7MXqV","header":"Calendar-module_header__cZHNA","navigation":"Calendar-module_navigation__PGkpY","navButton":"Calendar-module_navButton__kOe-w","title":"Calendar-module_title__oJZ7m","controls":"Calendar-module_controls__i1Z38","todayButton":"Calendar-module_todayButton__Ac9zc","viewToggle":"Calendar-module_viewToggle__Fhg2t","viewButton":"Calendar-module_viewButton__J2WY6","active":"Calendar-module_active__lIqH-","weekDays":"Calendar-module_weekDays__4J-8f","weekNumberHeader":"Calendar-module_weekNumberHeader__xhKbB","weekDay":"Calendar-module_weekDay__cg8Gr","daysGrid":"Calendar-module_daysGrid__ER0GM","weekView":"Calendar-module_weekView__bdtGs","dayCell":"Calendar-module_dayCell__TV-HR","dayNumber":"Calendar-module_dayNumber__ICH-X","today":"Calendar-module_today__eGuUU","events":"Calendar-module_events__qdbs7","event":"Calendar-module_event__Q1Zq3","eventTitle":"Calendar-module_eventTitle__XU7Wd","eventTime":"Calendar-module_eventTime__pMGEB","otherMonth":"Calendar-module_otherMonth__r6VJK","selected":"Calendar-module_selected__5e6h0","compact":"Calendar-module_compact__i0SF3","dots":"Calendar-module_dots__1Q7QR","dot":"Calendar-module_dot__tsCR1","dotMore":"Calendar-module_dotMore__emasD","weekNumber":"Calendar-module_weekNumber__nlo50","completed":"Calendar-module_completed__B-SHI","completedIcon":"Calendar-module_completedIcon__-oDZ9","moreEvents":"Calendar-module_moreEvents__TIKaT","emptyState":"Calendar-module_emptyState__2fcj7","dayView":"Calendar-module_dayView__PCIos","dayViewHeader":"Calendar-module_dayViewHeader__Gvxx2","timeColumnHeader":"Calendar-module_timeColumnHeader__B0btR","dayColumnHeader":"Calendar-module_dayColumnHeader__Rjqwg","allDayStrip":"Calendar-module_allDayStrip__VOqbV","allDayLabel":"Calendar-module_allDayLabel__2AmyT","allDayList":"Calendar-module_allDayList__6hFSb","allDayEvent":"Calendar-module_allDayEvent__SYkCs","dayViewScrollContainer":"Calendar-module_dayViewScrollContainer__84Byq","dayTimelineGrid":"Calendar-module_dayTimelineGrid__r1BNI","hourRow":"Calendar-module_hourRow__U-YN-","hourLabel":"Calendar-module_hourLabel__im84k","hourSlots":"Calendar-module_hourSlots__vbtYy","halfHourSlot":"Calendar-module_halfHourSlot__UWIri","halfHourSlotBottom":"Calendar-module_halfHourSlotBottom__aE5Mo","dayEvent":"Calendar-module_dayEvent__tSPFa","dayEventTitle":"Calendar-module_dayEventTitle__er03k","dayEventTime":"Calendar-module_dayEventTime__TlkeQ","currentTimeIndicator":"Calendar-module_currentTimeIndicator__GntOZ"};
2958
2958
 
2959
2959
  /**
2960
2960
  * Calendar component - A flexible, reusable calendar for displaying events
@@ -2985,30 +2985,25 @@ var styles$9 = {"calendar":"Calendar-module_calendar__3mIJS","loading":"Calendar
2985
2985
  * onEventClick={handleEventClick}
2986
2986
  * />
2987
2987
  */
2988
- function Calendar({ events, onEventClick, onDateClick, onEventClickByView, onDateClickByView, onTimeSlotClick, viewMode = 'month', initialDate = new Date(), config = {}, className = '', style = {}, loading = false, emptyState, hideHeader = false, compact = false, selectedDate }) {
2988
+ function Calendar({ events, onEventClick, onDateClick, onEventClickByView, onDateClickByView, onTimeSlotClick, onEventDrop, viewMode = 'month', initialDate = new Date(), config = {}, className = '', style = {}, loading = false, emptyState, hideHeader = false, compact = false, selectedDate }) {
2989
2989
  const [currentDate, setCurrentDate] = useState(initialDate);
2990
2990
  const [currentViewMode, setCurrentViewMode] = useState(viewMode);
2991
2991
  const dayViewScrollRef = useRef(null);
2992
- const { eventColors = {}, iconRenderer, maxEventsPerDay = 3, mondayStart = false, showWeekNumbers = false, dateFormat = { month: 'long', year: 'numeric' }, locale = 'en-US', dayLabels, monthNames } = config;
2992
+ const { eventColors = {}, iconRenderer, maxEventsPerDay = 3, mondayStart = false, showWeekNumbers = false, dateFormat = { month: 'long', year: 'numeric' }, locale = 'en-US', dayLabels, monthNames, startHour = 0, endHour = 24, hourHeight = 60, halfHourSlots = false } = config;
2993
2993
  const defaultDayLabels = mondayStart
2994
2994
  ? ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
2995
2995
  : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
2996
2996
  const finalDayLabels = dayLabels || defaultDayLabels;
2997
- // Auto-scroll to current time in day view
2997
+ // Auto-scroll to current time in day view (respects startHour/hourHeight config)
2998
+ const dayViewHourHeight = config?.hourHeight ?? 60;
2999
+ const dayViewStartHour = config?.startHour ?? 0;
2998
3000
  useEffect(() => {
2999
3001
  if (currentViewMode === 'day' && dayViewScrollRef.current) {
3000
- // Check if viewing today
3001
3002
  const now = new Date();
3002
3003
  const isToday = currentDate.toDateString() === now.toDateString();
3003
3004
  if (isToday) {
3004
- // Calculate scroll position based on current time
3005
- const currentHour = now.getHours();
3006
- const currentMinute = now.getMinutes();
3007
- const minutesSinceMidnight = currentHour * 60 + currentMinute;
3008
- // Each hour is 60px, so calculate pixel position
3009
- // Scroll to put current time in the upper third of the view
3010
- const scrollPosition = (minutesSinceMidnight / 60) * 60 - 100; // Subtract 100 to show some context above
3011
- // Use setTimeout to ensure DOM is ready
3005
+ const minutesFromStart = (now.getHours() - dayViewStartHour) * 60 + now.getMinutes();
3006
+ const scrollPosition = (minutesFromStart / 60) * dayViewHourHeight - 100;
3012
3007
  setTimeout(() => {
3013
3008
  if (dayViewScrollRef.current) {
3014
3009
  dayViewScrollRef.current.scrollTop = Math.max(0, scrollPosition);
@@ -3016,7 +3011,7 @@ function Calendar({ events, onEventClick, onDateClick, onEventClickByView, onDat
3016
3011
  }, 0);
3017
3012
  }
3018
3013
  }
3019
- }, [currentViewMode, currentDate]);
3014
+ }, [currentViewMode, currentDate, dayViewStartHour, dayViewHourHeight]);
3020
3015
  const calendarData = useMemo(() => {
3021
3016
  const year = currentDate.getFullYear();
3022
3017
  const month = currentDate.getMonth();
@@ -3178,16 +3173,6 @@ function Calendar({ events, onEventClick, onDateClick, onEventClickByView, onDat
3178
3173
  onDateClick(date);
3179
3174
  }
3180
3175
  };
3181
- const handleTimeSlotClick = (hour) => {
3182
- if (onTimeSlotClick) {
3183
- // Create a date object with the current date and the clicked hour
3184
- const slotDate = new Date(currentDate);
3185
- slotDate.setHours(hour, 0, 0, 0);
3186
- // Format time as HH:00
3187
- const timeString = `${hour.toString().padStart(2, '0')}:00`;
3188
- onTimeSlotClick(slotDate, hour, timeString);
3189
- }
3190
- };
3191
3176
  const isToday = (date) => {
3192
3177
  const today = new Date();
3193
3178
  return date.toDateString() === today.toDateString();
@@ -3205,49 +3190,75 @@ function Calendar({ events, onEventClick, onDateClick, onEventClickByView, onDat
3205
3190
  return (jsx("div", { className: `${styles$9.calendar} ${styles$9.loading} ${className}`, style: style, children: jsx("div", { className: styles$9.loadingSpinner, children: "Loading..." }) }));
3206
3191
  }
3207
3192
  return (jsxs("div", { className: `${styles$9.calendar} ${compact ? styles$9.compact : ''} ${className}`, style: style, children: [!hideHeader && (jsxs("div", { className: styles$9.header, children: [jsxs("div", { className: styles$9.navigation, children: [jsx("button", { onClick: handlePrevious, className: styles$9.navButton, "aria-label": "Previous", children: jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", children: jsx("polyline", { points: "15,18 9,12 15,6" }) }) }), jsx("h3", { className: styles$9.title, children: calendarData.displayTitle }), jsx("button", { onClick: handleNext, className: styles$9.navButton, "aria-label": "Next", children: jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", children: jsx("polyline", { points: "9,6 15,12 9,18" }) }) })] }), jsxs("div", { className: styles$9.controls, children: [jsx("button", { onClick: handleToday, className: styles$9.todayButton, children: "Today" }), jsxs("div", { className: styles$9.viewToggle, children: [jsx("button", { className: `${styles$9.viewButton} ${currentViewMode === 'month' ? styles$9.active : ''}`, onClick: () => setCurrentViewMode('month'), children: "Month" }), jsx("button", { className: `${styles$9.viewButton} ${currentViewMode === 'week' ? styles$9.active : ''}`, onClick: () => setCurrentViewMode('week'), children: "Week" }), jsx("button", { className: `${styles$9.viewButton} ${currentViewMode === 'day' ? styles$9.active : ''}`, onClick: () => setCurrentViewMode('day'), children: "Day" })] })] })] })), currentViewMode !== 'day' && (jsxs("div", { className: styles$9.weekDays, children: [showWeekNumbers && jsx("div", { className: styles$9.weekNumberHeader, children: "Week" }), finalDayLabels.map((day) => (jsx("div", { className: styles$9.weekDay, children: day }, day)))] })), currentViewMode === 'day' ? (
3208
- // Day view layout
3209
- jsxs("div", { className: styles$9.dayView, children: [jsxs("div", { className: styles$9.dayViewHeader, children: [jsx("div", { className: styles$9.timeColumnHeader }), jsx("div", { className: styles$9.dayColumnHeader, children: currentDate.toLocaleDateString(locale, { weekday: 'short', day: 'numeric' }) })] }), jsx("div", { className: styles$9.dayViewScrollContainer, ref: dayViewScrollRef, children: jsxs("div", { className: styles$9.dayViewContent, children: [(() => {
3210
- const now = new Date();
3211
- const currentHour = now.getHours();
3212
- const currentMinute = now.getMinutes();
3213
- const minutesSinceMidnight = currentHour * 60 + currentMinute;
3214
- const topPosition = (minutesSinceMidnight / 1440) * (24 * 60); // 24 hours * 60px per hour
3215
- // Only show if viewing today
3216
- const isToday = currentDate.toDateString() === now.toDateString();
3217
- return isToday ? (jsx("div", { className: styles$9.currentTimeIndicator, style: { top: `${topPosition}px` } })) : null;
3218
- })(), jsx("div", { className: styles$9.timeColumn, children: Array.from({ length: 24 }, (_, hour) => (jsx("div", { className: styles$9.timeSlot, children: jsxs("span", { className: styles$9.timeLabel, children: [hour.toString().padStart(2, '0'), ":00"] }) }, hour))) }), jsx("div", { className: styles$9.dayColumn, children: Array.from({ length: 24 }, (_, hour) => {
3219
- const hourEvents = getDayEvents(currentDate).filter(event => {
3220
- if (!event.time)
3221
- return false;
3222
- const eventHour = parseInt(event.time.split(':')[0]);
3223
- return eventHour === hour;
3224
- });
3225
- return (jsxs("div", { className: styles$9.hourSlot, onClick: (e) => {
3226
- // Only trigger if clicking on the slot itself, not on an event
3227
- if (e.target === e.currentTarget ||
3228
- e.target.classList.contains(styles$9.hourLine)) {
3229
- handleTimeSlotClick(hour);
3230
- }
3231
- }, style: { cursor: 'pointer' }, children: [jsx("div", { className: styles$9.hourLine }), hourEvents.map((event, eventIndex) => (jsxs(motion.div, { className: `${styles$9.dayEvent} ${event.status === 'completed' ? styles$9.completed : ''}`, style: {
3232
- backgroundColor: getEventColor(event),
3233
- color: getEventTextColor(event),
3234
- opacity: event.status === 'completed' ? 0.7 : 1
3235
- }, onClick: (e) => {
3236
- e.stopPropagation();
3237
- handleEventClick(event);
3238
- }, initial: { opacity: 0, x: -10 }, animate: { opacity: 1, x: 0 }, transition: {
3239
- duration: 0.2,
3240
- delay: eventIndex * 0.05,
3241
- ease: "easeOut"
3242
- }, whileHover: {
3243
- scale: 1.02,
3244
- y: -1,
3245
- transition: { duration: 0.1 }
3246
- }, whileTap: {
3247
- scale: 0.98,
3248
- transition: { duration: 0.1 }
3249
- }, children: [iconRenderer && iconRenderer(event), jsxs("span", { className: styles$9.dayEventTitle, children: [jsx("span", { className: styles$9.dayEventTime, children: event.time }), event.title] }), event.status === 'completed' && (jsx("svg", { className: styles$9.completedIcon, width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", children: jsx("polyline", { points: "20,6 9,17 4,12" }) }))] }, event.id)))] }, hour));
3250
- }) })] }) })] })) : (jsx("div", { className: `${styles$9.daysGrid} ${currentViewMode === 'week' ? styles$9.weekView : ''}`, children: calendarData.days.map((day, index) => {
3193
+ // Day view layout — positioned events with duration, all-day strip, now-line
3194
+ (() => {
3195
+ const dayEvents = getDayEvents(currentDate);
3196
+ const scheduled = dayEvents.filter(e => !e.allDay && e.time);
3197
+ const allDayEvents = dayEvents.filter(e => e.allDay || !e.time);
3198
+ const hours = Array.from({ length: endHour - startHour }, (_, i) => startHour + i);
3199
+ const timelineHeight = hours.length * hourHeight;
3200
+ const now = new Date();
3201
+ const dayIsToday = currentDate.toDateString() === now.toDateString();
3202
+ const nowMinutesFromStart = (now.getHours() - startHour) * 60 + now.getMinutes();
3203
+ const nowOffset = (nowMinutesFromStart / 60) * hourHeight;
3204
+ const showNow = dayIsToday && nowOffset >= 0 && nowOffset <= timelineHeight;
3205
+ const eventMinutes = (time) => {
3206
+ const [h, m] = time.split(':').map(Number);
3207
+ return h * 60 + m;
3208
+ };
3209
+ const eventDuration = (event) => {
3210
+ if (!event.time || !event.endTime)
3211
+ return 30;
3212
+ const d = eventMinutes(event.endTime) - eventMinutes(event.time);
3213
+ return d > 0 ? d : 30;
3214
+ };
3215
+ const handleSlotClick = (hour, minute) => {
3216
+ if (onTimeSlotClick) {
3217
+ const slotDate = new Date(currentDate);
3218
+ slotDate.setHours(hour, minute, 0, 0);
3219
+ const timeString = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`;
3220
+ onTimeSlotClick(slotDate, hour, timeString);
3221
+ }
3222
+ };
3223
+ const handleEventDragEnd = (event, info) => {
3224
+ if (!onEventDrop)
3225
+ return;
3226
+ const gridEl = dayViewScrollRef.current?.querySelector(`.${styles$9.dayTimelineGrid}`);
3227
+ if (!gridEl)
3228
+ return;
3229
+ const rect = gridEl.getBoundingClientRect();
3230
+ const relativeY = info.point.y - rect.top;
3231
+ const slotSize = halfHourSlots ? hourHeight / 2 : hourHeight;
3232
+ const slotIndex = Math.max(0, Math.floor(relativeY / slotSize));
3233
+ const totalSlots = halfHourSlots ? hours.length * 2 : hours.length;
3234
+ const clamped = Math.min(totalSlots - 1, slotIndex);
3235
+ const newHour = startHour + Math.floor(halfHourSlots ? clamped / 2 : clamped);
3236
+ const newMinute = halfHourSlots && clamped % 2 === 1 ? 30 : 0;
3237
+ const newDate = new Date(currentDate);
3238
+ newDate.setHours(newHour, newMinute, 0, 0);
3239
+ onEventDrop(event, newDate);
3240
+ };
3241
+ return (jsxs("div", { className: styles$9.dayView, children: [jsxs("div", { className: styles$9.dayViewHeader, children: [jsx("div", { className: styles$9.timeColumnHeader }), jsx("div", { className: styles$9.dayColumnHeader, children: currentDate.toLocaleDateString(locale, { weekday: 'short', day: 'numeric' }) })] }), allDayEvents.length > 0 && (jsxs("div", { className: styles$9.allDayStrip, children: [jsx("span", { className: styles$9.allDayLabel, children: "All day" }), jsx("div", { className: styles$9.allDayList, children: allDayEvents.map(event => (jsxs(motion.div, { className: `${styles$9.allDayEvent} ${event.status === 'completed' ? styles$9.completed : ''}`, style: {
3242
+ backgroundColor: getEventColor(event),
3243
+ color: getEventTextColor(event),
3244
+ opacity: event.status === 'completed' ? 0.7 : 1
3245
+ }, onClick: () => handleEventClick(event), whileHover: { scale: 1.02 }, whileTap: { scale: 0.98 }, children: [iconRenderer && iconRenderer(event), jsx("span", { children: event.title })] }, event.id))) })] })), jsx("div", { className: styles$9.dayViewScrollContainer, ref: dayViewScrollRef, children: jsxs("div", { className: styles$9.dayTimelineGrid, style: { height: timelineHeight }, children: [hours.map(hour => (jsxs("div", { className: styles$9.hourRow, style: { height: hourHeight }, children: [jsxs("span", { className: styles$9.hourLabel, children: [hour.toString().padStart(2, '0'), ":00"] }), jsx("div", { className: styles$9.hourSlots, children: halfHourSlots ? (jsxs(Fragment, { children: [jsx("div", { className: styles$9.halfHourSlot, onClick: () => handleSlotClick(hour, 0) }), jsx("div", { className: `${styles$9.halfHourSlot} ${styles$9.halfHourSlotBottom}`, onClick: () => handleSlotClick(hour, 30) })] })) : (jsx("div", { className: styles$9.halfHourSlot, onClick: () => handleSlotClick(hour, 0) })) })] }, hour))), scheduled.map((event, eventIndex) => {
3246
+ const [h, m] = event.time.split(':').map(Number);
3247
+ const top = (h - startHour) * hourHeight + (m / 60) * hourHeight;
3248
+ const duration = eventDuration(event);
3249
+ const height = Math.max(24, (duration / 60) * hourHeight - 2);
3250
+ return (jsxs(motion.div, { className: `${styles$9.dayEvent} ${event.status === 'completed' ? styles$9.completed : ''}`, style: {
3251
+ top,
3252
+ height,
3253
+ backgroundColor: getEventColor(event),
3254
+ color: getEventTextColor(event),
3255
+ opacity: event.status === 'completed' ? 0.7 : 1
3256
+ }, onClick: (e) => {
3257
+ e.stopPropagation();
3258
+ handleEventClick(event);
3259
+ }, initial: { opacity: 0, x: -10 }, animate: { opacity: 1, x: 0 }, transition: { duration: 0.2, delay: eventIndex * 0.03, ease: 'easeOut' }, whileHover: { scale: 1.01, transition: { duration: 0.1 } }, whileTap: { scale: 0.98, transition: { duration: 0.1 } }, drag: onEventDrop ? 'y' : false, dragMomentum: false, onDragEnd: (_, info) => handleEventDragEnd(event, info), children: [iconRenderer && iconRenderer(event), jsxs("span", { className: styles$9.dayEventTitle, children: [jsx("span", { className: styles$9.dayEventTime, children: event.time }), event.title] }), event.status === 'completed' && (jsx("svg", { className: styles$9.completedIcon, width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", children: jsx("polyline", { points: "20,6 9,17 4,12" }) }))] }, event.id));
3260
+ }), showNow && (jsx("div", { className: styles$9.currentTimeIndicator, style: { top: `${nowOffset}px` } }))] }) })] }));
3261
+ })()) : (jsx("div", { className: `${styles$9.daysGrid} ${currentViewMode === 'week' ? styles$9.weekView : ''}`, children: calendarData.days.map((day, index) => {
3251
3262
  const dayEvents = getDayEvents(day);
3252
3263
  const dayIsToday = isToday(day);
3253
3264
  const isInCurrentMonth = currentViewMode === 'week' || isCurrentMonth(day);