@ahrowe/ui 0.39.1 → 0.41.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/README.md +15 -14
- package/dist/cjs-types/common/ahroweProvider/ahroweProvider.d.ts +4 -0
- package/dist/cjs-types/common/ahroweProvider/ahroweProvider.types.d.ts +12 -0
- package/dist/cjs-types/common/ahroweProvider/index.d.ts +2 -0
- package/dist/cjs-types/common/bodyEnd/portalHostContext.d.ts +6 -0
- package/dist/cjs-types/common/calendar/calendar.d.ts +4 -0
- package/dist/cjs-types/common/calendar/calendar.types.d.ts +141 -0
- package/dist/cjs-types/common/calendar/components/agendaList/agendaList.d.ts +5 -0
- package/dist/cjs-types/common/calendar/components/agendaList/agendaList.types.d.ts +23 -0
- package/dist/cjs-types/common/calendar/components/agendaList/index.d.ts +1 -0
- package/dist/cjs-types/common/calendar/components/calendarHeader/calendarHeader.d.ts +4 -0
- package/dist/cjs-types/common/calendar/components/calendarHeader/calendarHeader.types.d.ts +17 -0
- package/dist/cjs-types/common/calendar/components/calendarHeader/index.d.ts +1 -0
- package/dist/cjs-types/common/calendar/components/compactMonth/compactMonth.d.ts +9 -0
- package/dist/cjs-types/common/calendar/components/compactMonth/compactMonth.types.d.ts +1 -0
- package/dist/cjs-types/common/calendar/components/compactMonth/index.d.ts +1 -0
- package/dist/cjs-types/common/calendar/components/monthView/index.d.ts +1 -0
- package/dist/cjs-types/common/calendar/components/monthView/monthView.d.ts +5 -0
- package/dist/cjs-types/common/calendar/components/monthView/monthView.types.d.ts +10 -0
- package/dist/cjs-types/common/calendar/components/timeGrid/index.d.ts +1 -0
- package/dist/cjs-types/common/calendar/components/timeGrid/timeGrid.d.ts +5 -0
- package/dist/cjs-types/common/calendar/components/timeGrid/timeGrid.types.d.ts +40 -0
- package/dist/cjs-types/common/calendar/dates.d.ts +50 -0
- package/dist/cjs-types/common/calendar/format.d.ts +32 -0
- package/dist/cjs-types/common/calendar/gesture.d.ts +32 -0
- package/dist/cjs-types/common/calendar/index.d.ts +2 -0
- package/dist/cjs-types/common/calendar/layout.d.ts +74 -0
- package/dist/cjs-types/common/calendar/useGestures.d.ts +37 -0
- package/dist/cjs-types/common/calendar/usePager.d.ts +20 -0
- package/dist/cjs-types/common/calendar/view.types.d.ts +26 -0
- package/dist/cjs-types/common/configProvider/configProvider.types.d.ts +3 -0
- package/dist/cjs-types/common/confirmModal/confirmModal.types.d.ts +1 -1
- package/dist/cjs-types/common/datePicker/index.d.ts +1 -1
- package/dist/cjs-types/common/errorBoundary/errorBoundary.types.d.ts +2 -2
- package/dist/cjs-types/common/modal/modal.types.d.ts +4 -3
- package/dist/cjs-types/common/themeProvider/index.d.ts +1 -1
- package/dist/cjs-types/common/themeProvider/theme.types.d.ts +16 -0
- package/dist/cjs-types/common/themeProvider/themeProvider.d.ts +7 -9
- package/dist/cjs-types/common/themeProvider/themeVariablesContext.d.ts +2 -2
- package/dist/cjs-types/common/toast/index.d.ts +1 -2
- package/dist/cjs-types/common/toast/toast.types.d.ts +4 -4
- package/dist/cjs-types/common/toast/toastHost.d.ts +4 -0
- package/dist/cjs-types/common/toast/toastService.d.ts +1 -1
- package/dist/cjs-types/common/utils/day.d.ts +8 -0
- package/dist/cjs-types/common/virtualList/useColumns.d.ts +3 -1
- package/dist/cjs-types/index.d.ts +4 -1
- package/dist/esm/common/ahroweProvider/ahroweProvider.mjs +2 -0
- package/dist/esm/common/ahroweProvider/ahroweProvider.mjs.map +1 -0
- package/dist/esm/common/bodyEnd/bodyEnd.mjs +1 -1
- package/dist/esm/common/bodyEnd/bodyEnd.mjs.map +1 -1
- package/dist/esm/common/bodyEnd/portalHostContext.mjs +2 -0
- package/dist/esm/common/bodyEnd/portalHostContext.mjs.map +1 -0
- package/dist/esm/common/calendar/calendar.mjs +2 -0
- package/dist/esm/common/calendar/calendar.mjs.map +1 -0
- package/dist/esm/common/calendar/calendar.module.mjs +2 -0
- package/dist/esm/common/calendar/calendar.module.mjs.map +1 -0
- package/dist/esm/common/calendar/calendar.types.mjs +2 -0
- package/dist/esm/common/calendar/calendar.types.mjs.map +1 -0
- package/dist/esm/common/calendar/components/agendaList/agendaList.mjs +2 -0
- package/dist/esm/common/calendar/components/agendaList/agendaList.mjs.map +1 -0
- package/dist/esm/common/calendar/components/agendaList/agendaList.module.mjs +2 -0
- package/dist/esm/common/calendar/components/agendaList/agendaList.module.mjs.map +1 -0
- package/dist/esm/common/calendar/components/calendarHeader/calendarHeader.mjs +2 -0
- package/dist/esm/common/calendar/components/calendarHeader/calendarHeader.mjs.map +1 -0
- package/dist/esm/common/calendar/components/calendarHeader/calendarHeader.module.mjs +2 -0
- package/dist/esm/common/calendar/components/calendarHeader/calendarHeader.module.mjs.map +1 -0
- package/dist/esm/common/calendar/components/compactMonth/compactMonth.mjs +2 -0
- package/dist/esm/common/calendar/components/compactMonth/compactMonth.mjs.map +1 -0
- package/dist/esm/common/calendar/components/compactMonth/compactMonth.module.mjs +2 -0
- package/dist/esm/common/calendar/components/compactMonth/compactMonth.module.mjs.map +1 -0
- package/dist/esm/common/calendar/components/monthView/monthView.mjs +2 -0
- package/dist/esm/common/calendar/components/monthView/monthView.mjs.map +1 -0
- package/dist/esm/common/calendar/components/monthView/monthView.module.mjs +2 -0
- package/dist/esm/common/calendar/components/monthView/monthView.module.mjs.map +1 -0
- package/dist/esm/common/calendar/components/timeGrid/timeGrid.mjs +2 -0
- package/dist/esm/common/calendar/components/timeGrid/timeGrid.mjs.map +1 -0
- package/dist/esm/common/calendar/components/timeGrid/timeGrid.module.mjs +2 -0
- package/dist/esm/common/calendar/components/timeGrid/timeGrid.module.mjs.map +1 -0
- package/dist/esm/common/calendar/dates.mjs +2 -0
- package/dist/esm/common/calendar/dates.mjs.map +1 -0
- package/dist/esm/common/calendar/format.mjs +2 -0
- package/dist/esm/common/calendar/format.mjs.map +1 -0
- package/dist/esm/common/calendar/gesture.mjs +2 -0
- package/dist/esm/common/calendar/gesture.mjs.map +1 -0
- package/dist/esm/common/calendar/layout.mjs +2 -0
- package/dist/esm/common/calendar/layout.mjs.map +1 -0
- package/dist/esm/common/calendar/pager.module.mjs +2 -0
- package/dist/esm/common/calendar/pager.module.mjs.map +1 -0
- package/dist/esm/common/calendar/useGestures.mjs +2 -0
- package/dist/esm/common/calendar/useGestures.mjs.map +1 -0
- package/dist/esm/common/calendar/usePager.mjs +2 -0
- package/dist/esm/common/calendar/usePager.mjs.map +1 -0
- package/dist/esm/common/carousel/carousel.module.mjs.map +1 -1
- package/dist/esm/common/confirmModal/confirmModal.mjs +1 -1
- package/dist/esm/common/confirmModal/confirmModal.mjs.map +1 -1
- package/dist/esm/common/datePicker/components/datePickerMonth/datePickerMonth.mjs +1 -1
- package/dist/esm/common/datePicker/dateFunctions.mjs +1 -1
- package/dist/esm/common/datePicker/datePicker.mjs +1 -1
- package/dist/esm/common/errorBoundary/errorBoundary.mjs +2 -2
- package/dist/esm/common/hooks/useAnchorTracking.mjs.map +1 -1
- package/dist/esm/common/input/input.mjs +1 -1
- package/dist/esm/common/input/input.mjs.map +1 -1
- package/dist/esm/common/modal/modal.mjs +1 -1
- package/dist/esm/common/modal/modal.mjs.map +1 -1
- package/dist/esm/common/popover/popover.mjs +1 -1
- package/dist/esm/common/popover/popover.mjs.map +1 -1
- package/dist/esm/common/scrollFade/scrollFade.mjs +1 -1
- package/dist/esm/common/scrollbarProvider/scrollbarProvider.module.mjs.map +1 -1
- package/dist/esm/common/tabHeader/tabHeader.module.mjs.map +1 -1
- package/dist/esm/common/themeProvider/themeProvider.mjs +1 -1
- package/dist/esm/common/themeProvider/themeProvider.mjs.map +1 -1
- package/dist/esm/common/themeProvider/themeVariablesContext.mjs.map +1 -1
- package/dist/esm/common/toast/toastHost.mjs +2 -0
- package/dist/esm/common/toast/toastHost.mjs.map +1 -0
- package/dist/esm/common/toast/toastService.mjs +1 -1
- package/dist/esm/common/toast/toastService.mjs.map +1 -1
- package/dist/esm/common/tooltip/tooltip.module.mjs.map +1 -1
- package/dist/esm/common/utils/day.mjs +1 -1
- package/dist/esm/common/utils/day.mjs.map +1 -1
- package/dist/esm/common/virtualList/useColumns.mjs +1 -1
- package/dist/esm/common/virtualList/useColumns.mjs.map +1 -1
- package/dist/esm/common/virtualList/virtualList.mjs +1 -1
- package/dist/esm/common/virtualList/virtualList.mjs.map +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/mcp.js +2 -2
- package/dist/style.css +1 -1
- package/dist/types/common/ahroweProvider/ahroweProvider.d.ts +4 -0
- package/dist/types/common/ahroweProvider/ahroweProvider.types.d.ts +12 -0
- package/dist/types/common/ahroweProvider/index.d.ts +2 -0
- package/dist/types/common/bodyEnd/portalHostContext.d.ts +6 -0
- package/dist/types/common/calendar/calendar.d.ts +4 -0
- package/dist/types/common/calendar/calendar.types.d.ts +141 -0
- package/dist/types/common/calendar/components/agendaList/agendaList.d.ts +5 -0
- package/dist/types/common/calendar/components/agendaList/agendaList.types.d.ts +23 -0
- package/dist/types/common/calendar/components/agendaList/index.d.ts +1 -0
- package/dist/types/common/calendar/components/calendarHeader/calendarHeader.d.ts +4 -0
- package/dist/types/common/calendar/components/calendarHeader/calendarHeader.types.d.ts +17 -0
- package/dist/types/common/calendar/components/calendarHeader/index.d.ts +1 -0
- package/dist/types/common/calendar/components/compactMonth/compactMonth.d.ts +9 -0
- package/dist/types/common/calendar/components/compactMonth/compactMonth.types.d.ts +1 -0
- package/dist/types/common/calendar/components/compactMonth/index.d.ts +1 -0
- package/dist/types/common/calendar/components/monthView/index.d.ts +1 -0
- package/dist/types/common/calendar/components/monthView/monthView.d.ts +5 -0
- package/dist/types/common/calendar/components/monthView/monthView.types.d.ts +10 -0
- package/dist/types/common/calendar/components/timeGrid/index.d.ts +1 -0
- package/dist/types/common/calendar/components/timeGrid/timeGrid.d.ts +5 -0
- package/dist/types/common/calendar/components/timeGrid/timeGrid.types.d.ts +40 -0
- package/dist/types/common/calendar/dates.d.ts +50 -0
- package/dist/types/common/calendar/format.d.ts +32 -0
- package/dist/types/common/calendar/gesture.d.ts +32 -0
- package/dist/types/common/calendar/index.d.ts +2 -0
- package/dist/types/common/calendar/layout.d.ts +74 -0
- package/dist/types/common/calendar/useGestures.d.ts +37 -0
- package/dist/types/common/calendar/usePager.d.ts +20 -0
- package/dist/types/common/calendar/view.types.d.ts +26 -0
- package/dist/types/common/configProvider/configProvider.types.d.ts +3 -0
- package/dist/types/common/confirmModal/confirmModal.types.d.ts +1 -1
- package/dist/types/common/datePicker/index.d.ts +1 -1
- package/dist/types/common/errorBoundary/errorBoundary.types.d.ts +2 -2
- package/dist/types/common/modal/modal.types.d.ts +4 -3
- package/dist/types/common/themeProvider/index.d.ts +1 -1
- package/dist/types/common/themeProvider/theme.types.d.ts +16 -0
- package/dist/types/common/themeProvider/themeProvider.d.ts +7 -9
- package/dist/types/common/themeProvider/themeVariablesContext.d.ts +2 -2
- package/dist/types/common/toast/index.d.ts +1 -2
- package/dist/types/common/toast/toast.types.d.ts +4 -4
- package/dist/types/common/toast/toastHost.d.ts +4 -0
- package/dist/types/common/toast/toastService.d.ts +1 -1
- package/dist/types/common/utils/day.d.ts +8 -0
- package/dist/types/common/virtualList/useColumns.d.ts +3 -1
- package/dist/types/index.d.ts +4 -1
- package/docs/AhroweProvider.md +90 -0
- package/docs/BodyEnd.md +5 -12
- package/docs/Breadcrumb.md +0 -2
- package/docs/CLAUDE.md +21 -16
- package/docs/Calendar.md +184 -0
- package/docs/CommandPalette.md +0 -2
- package/docs/ConfigProvider.md +12 -8
- package/docs/ConfirmModal.md +1 -3
- package/docs/DatePicker.md +9 -2
- package/docs/ErrorBoundary.md +5 -3
- package/docs/FormValidatorGroup.md +1 -1
- package/docs/KlipyPicker.md +1 -1
- package/docs/Menu.md +0 -2
- package/docs/Modal.md +2 -4
- package/docs/MultiSelect.md +0 -2
- package/docs/OtpInput.md +0 -2
- package/docs/Popover.md +0 -2
- package/docs/RadioGroup.md +1 -1
- package/docs/ScrollbarProvider.md +4 -0
- package/docs/SplitButton.md +0 -2
- package/docs/ThemeProvider.md +13 -10
- package/docs/TimeInput.md +2 -0
- package/docs/Toast.md +18 -17
- package/docs/Tooltip.md +1 -1
- package/docs/VirtualList.md +0 -2
- package/package.json +1 -1
- package/dist/cjs-types/common/toast/toastProvider.d.ts +0 -8
- package/dist/esm/common/toast/toastProvider.mjs +0 -2
- package/dist/esm/common/toast/toastProvider.mjs.map +0 -1
- package/dist/types/common/toast/toastProvider.d.ts +0 -8
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compactMonth.mjs","names":[],"sources":["../../../../../../package/common/calendar/components/compactMonth/compactMonth.tsx"],"sourcesContent":["import { useLayoutEffect, useRef, useState, type CSSProperties, type KeyboardEvent, type ReactElement } from 'react';\nimport cx from 'classnames';\n\nimport Button from 'components/common/button';\nimport { ButtonSize } from 'components/common/button/button.types';\nimport { useMediaQuery } from 'components/common/hooks/useMediaQuery';\nimport { CalendarView, type CalendarEvent } from '../../calendar.types';\nimport {\n addDays,\n addMonths,\n dayDiff,\n dateToDay,\n gridKeyTarget,\n isSameDay,\n periodRange,\n shownDays,\n startOfMonth,\n startOfWeek,\n} from '../../dates';\nimport { formatDayNumber, formatLongDate, formatMonthTitle, formatWeekday } from '../../format';\nimport { pageStep } from '../../gesture';\nimport { eventsByDay } from '../../layout';\nimport { useGestures } from '../../useGestures';\nimport { usePager } from '../../usePager';\nimport AgendaList from '../agendaList';\nimport type { CompactMonthProps } from './compactMonth.types';\n\nimport pagerStyles from '../../pager.module.pcss';\nimport styles from './compactMonth.module.pcss';\n\nconst STEPS = [-1, 0, 1] as const;\nconst MAX_DOTS = 3;\n/** Quiet time after the last scroll before a half-collapsed month settles open or shut. */\nconst SETTLE_DELAY_MS = 150;\n\n/**\n * The month view of a narrow calendar: a grid of days with event dots over the selected day's\n * events. Scrolling that list folds the month up into the selected week, iOS-style.\n */\nfunction CompactMonth<E extends CalendarEvent>({\n events,\n date,\n locale,\n weekStartsOn,\n hidden,\n text,\n onDateChange,\n onEventClick,\n onSlotCreate,\n renderEvent,\n classNames,\n slotStyles,\n}: CompactMonthProps<E>): ReactElement {\n const scrollerRef = useRef<HTMLDivElement>(null);\n const monthRef = useRef<HTMLDivElement>(null);\n const viewportRef = useRef<HTMLDivElement>(null);\n const currentRef = useRef<HTMLDivElement>(null);\n const pendingFocus = useRef<string | null>(null);\n const progress = useRef(0);\n const [collapsed, setCollapsed] = useState(false);\n const reducedMotion = useMediaQuery('(prefers-reduced-motion: reduce)');\n\n const today = new Date();\n const month = startOfMonth(date);\n const week = startOfWeek(date, weekStartsOn);\n const weekdays = shownDays(startOfWeek(today, weekStartsOn), 7, hidden);\n\n const pager = usePager(\n dateToDay(collapsed ? week : month),\n (step) => onDateChange(collapsed ? addDays(date, 7 * step) : addMonths(date, step)),\n () => currentRef.current?.querySelector<HTMLElement>('[tabindex=\"0\"]') ?? null,\n );\n\n // The fold follows the scroll position rather than animating, so it is written straight to a\n // custom property on every scroll event and never re-renders. Only reaching or leaving fully\n // folded re-renders, to swap the month panes for week strips that look identical at that point.\n useLayoutEffect(() => {\n const scroller = scrollerRef.current;\n if (!scroller) return;\n let settleTimer: ReturnType<typeof setTimeout> | undefined;\n let touching = false;\n\n function foldDistance() {\n // Five of the six rows fold away.\n return ((viewportRef.current?.clientHeight ?? 0) * 5) / 6;\n }\n\n function update() {\n const distance = foldDistance();\n let next = distance > 0 ? Math.min(scroller!.scrollTop / distance, 1) : 0;\n // Following the scroll, the rows move at a rate of their own, as parallax does. Under\n // reduced motion the month stays whole until it is scrolled all the way, then folds at once.\n if (reducedMotion) next = next > 0.99 ? 1 : 0;\n progress.current = next;\n scroller!.style.setProperty('--collapse', String(next));\n setCollapsed(next >= 1);\n }\n\n function settle() {\n if (touching) return;\n const distance = foldDistance();\n const top = scroller!.scrollTop;\n if (top <= 0 || top >= distance) return;\n scroller!.scrollTo({ top: top < distance / 2 ? 0 : distance, behavior: reducedMotion ? 'auto' : 'smooth' });\n }\n\n function scheduleSettle() {\n clearTimeout(settleTimer);\n settleTimer = setTimeout(settle, SETTLE_DELAY_MS);\n }\n\n function onScroll() {\n update();\n scheduleSettle();\n }\n function onTouchStart() {\n touching = true;\n }\n function onTouchEnd() {\n touching = false;\n scheduleSettle();\n }\n\n update();\n scroller.addEventListener('scroll', onScroll, { passive: true });\n scroller.addEventListener('touchstart', onTouchStart, { passive: true });\n scroller.addEventListener('touchend', onTouchEnd, { passive: true });\n scroller.addEventListener('touchcancel', onTouchEnd, { passive: true });\n return () => {\n clearTimeout(settleTimer);\n scroller.removeEventListener('scroll', onScroll);\n scroller.removeEventListener('touchstart', onTouchStart);\n scroller.removeEventListener('touchend', onTouchEnd);\n scroller.removeEventListener('touchcancel', onTouchEnd);\n };\n }, [reducedMotion]);\n\n useLayoutEffect(() => {\n const key = pendingFocus.current;\n if (key === null) return;\n pendingFocus.current = null;\n currentRef.current?.querySelector<HTMLElement>(`[data-cal-day=\"${key}\"]`)?.focus();\n });\n\n useGestures(monthRef, {\n onPress: pager.finish,\n // Half folded, the neighbours would not line up with the current pane.\n canSwipe: () => progress.current < 0.01 || progress.current > 0.99,\n onSwipeMove: pager.move,\n onSwipeEnd: (dx, velocity) => pager.settle(pageStep(dx, pager.width(), velocity)),\n });\n\n function handleKeyDown(keyEvent: KeyboardEvent<HTMLDivElement>, day: Date) {\n const next = gridKeyTarget(keyEvent.key, day, weekStartsOn, hidden);\n if (!next) return;\n keyEvent.preventDefault();\n pendingFocus.current = dateToDay(next);\n onDateChange(next);\n }\n\n function renderDay(day: Date, outside: boolean, isCurrent: boolean, dayEvents: readonly E[]) {\n const selected = isSameDay(day, date);\n const isToday = isSameDay(day, today);\n const name = formatLongDate(day, locale);\n return (\n <div\n key={dateToDay(day)}\n role='gridcell'\n data-cal-day={dateToDay(day)}\n tabIndex={isCurrent && selected ? 0 : -1}\n aria-selected={selected}\n aria-current={isToday ? 'date' : undefined}\n aria-label={dayEvents.length > 0 ? `${name}, ${text.eventCount(dayEvents.length)}` : name}\n className={cx(styles.compactMonthCell, outside && styles.compactMonthCellOutside, classNames?.cell)}\n style={slotStyles?.cell}\n onClick={() => onDateChange(day)}\n onKeyDown={(keyEvent) => handleKeyDown(keyEvent, day)}\n >\n <span\n aria-hidden\n className={cx(\n styles.compactMonthNumber,\n isToday && styles.compactMonthNumberToday,\n selected && styles.compactMonthNumberSelected,\n )}\n >\n {formatDayNumber(day, locale)}\n </span>\n <span aria-hidden className={styles.compactMonthDots}>\n {dayEvents.slice(0, MAX_DOTS).map((event) => (\n <span\n key={event.id}\n className={styles.compactMonthDot}\n style={{ '--event-color': event.color } as CSSProperties}\n />\n ))}\n </span>\n </div>\n );\n }\n\n function renderPane(step: (typeof STEPS)[number]) {\n const isCurrent = step === 0;\n const className = cx(\n pagerStyles.pagerPane,\n step === -1 && pagerStyles.pagerPanePrev,\n step === 1 && pagerStyles.pagerPaneNext,\n styles.compactMonthPane,\n );\n\n if (collapsed) {\n const paneWeek = addDays(week, 7 * step);\n const dates = shownDays(paneWeek, 7, hidden);\n const perDay = eventsByDay(events, dates);\n return (\n <div\n key={dateToDay(paneWeek)}\n ref={isCurrent ? currentRef : undefined}\n className={className}\n inert={!isCurrent}\n aria-hidden={!isCurrent || undefined}\n >\n <div role='row' className={styles.compactMonthWeek}>\n {dates.map((day, index) => renderDay(day, false, isCurrent, perDay[index]))}\n </div>\n </div>\n );\n }\n\n const paneMonth = addMonths(month, step);\n const gridStart = periodRange(CalendarView.Month, paneMonth, weekStartsOn).start;\n const selectedRow = isCurrent ? Math.floor(dayDiff(gridStart, date) / 7) : 0;\n return (\n <div\n key={dateToDay(paneMonth)}\n ref={isCurrent ? currentRef : undefined}\n className={className}\n inert={!isCurrent}\n aria-hidden={!isCurrent || undefined}\n style={{ '--selected-row': selectedRow } as CSSProperties}\n >\n <div className={styles.compactMonthRows}>\n {Array.from({ length: 6 }, (_, row) => {\n const weekStart = addDays(gridStart, row * 7);\n const dates = shownDays(weekStart, 7, hidden);\n const perDay = eventsByDay(events, dates);\n return (\n <div\n key={dateToDay(weekStart)}\n role='row'\n className={cx(styles.compactMonthWeek, row !== selectedRow && styles.compactMonthWeekFolding)}\n >\n {dates.map((day, column) =>\n renderDay(day, day.getMonth() !== paneMonth.getMonth(), isCurrent, perDay[column]),\n )}\n </div>\n );\n })}\n </div>\n </div>\n );\n }\n\n return (\n <div ref={scrollerRef} className={styles.compactMonth} style={{ '--days': weekdays.length } as CSSProperties}>\n <div ref={monthRef} className={styles.compactMonthSticky}>\n <div role='grid' aria-label={formatMonthTitle(date, locale)}>\n <div role='row' className={styles.compactMonthWeekdays}>\n {weekdays.map((day) => (\n <div\n key={day.getDay()}\n role='columnheader'\n aria-label={formatWeekday(day, locale, 'long')}\n className={cx(styles.compactMonthWeekday, classNames?.dayHeader)}\n style={slotStyles?.dayHeader}\n >\n {formatWeekday(day, locale, 'narrow')}\n </div>\n ))}\n </div>\n <div ref={viewportRef} className={cx(pagerStyles.pagerViewport, styles.compactMonthViewport)}>\n <div ref={pager.trackRef} className={pagerStyles.pagerTrack}>\n {STEPS.map(renderPane)}\n </div>\n </div>\n </div>\n </div>\n <div className={styles.compactMonthList}>\n <div className={styles.compactMonthListHeader}>\n <div className={styles.compactMonthListTitle}>{formatLongDate(date, locale)}</div>\n {onSlotCreate && (\n <Button\n size={ButtonSize.Small}\n onClick={(clickEvent) =>\n onSlotCreate({ start: date, end: addDays(date, 1), allDay: true }, clickEvent.currentTarget)\n }\n >\n {text.newEvent}\n </Button>\n )}\n </div>\n <AgendaList\n className={styles.compactMonthAgenda}\n events={events}\n start={date}\n days={1}\n showDayHeaders={false}\n locale={locale}\n text={text}\n onEventClick={onEventClick}\n renderEvent={renderEvent}\n classNames={classNames}\n slotStyles={slotStyles}\n />\n </div>\n </div>\n );\n}\n\nexport default CompactMonth;\n"],"mappings":"q/BA8BA,IAAM,GAAQ,CAAC,GAAI,EAAG,CAAC,EACjB,GAAW,EAEX,GAAkB,IAMxB,SAAS,EAAsC,CAC7C,SACA,OACA,SACA,eACA,SACA,OACA,eACA,eACA,eACA,cACA,aACA,cACqC,CACrC,IAAM,EAAc,EAAuB,IAAI,EACzC,EAAW,EAAuB,IAAI,EACtC,EAAc,EAAuB,IAAI,EACzC,EAAa,EAAuB,IAAI,EACxC,EAAe,EAAsB,IAAI,EACzC,EAAW,EAAO,CAAC,EACnB,CAAC,EAAW,IAAgB,EAAS,EAAK,EAC1C,EAAgB,EAAc,kCAAkC,EAEhE,EAAQ,IAAI,KACZ,EAAQ,EAAa,CAAI,EACzB,EAAO,EAAY,EAAM,CAAY,EACrC,EAAW,EAAU,EAAY,EAAO,CAAY,EAAG,EAAG,CAAM,EAEhE,EAAQ,EACZ,EAAU,EAAY,EAAO,CAAK,EACjC,GAAS,EAAa,EAAY,EAAQ,EAAM,EAAI,CAAI,EAAI,EAAU,EAAM,CAAI,CAAC,MAC5E,EAAW,SAAS,cAA2B,gBAAgB,GAAK,IAC5E,EAKA,MAAsB,CACpB,IAAM,EAAW,EAAY,QAC7B,GAAI,CAAC,EAAU,OACf,IAAI,EACA,EAAW,GAEf,SAAS,GAAe,CAEtB,OAAS,EAAY,SAAS,cAAgB,GAAK,EAAK,CAC1D,CAEA,SAAS,GAAS,CAChB,IAAM,EAAW,EAAa,EAC1B,EAAO,EAAW,EAAI,KAAK,IAAI,EAAU,UAAY,EAAU,CAAC,EAAI,EAGpE,IAAe,EAAO,IAAO,MACjC,EAAS,QAAU,EACnB,EAAU,MAAM,YAAY,aAAc,OAAO,CAAI,CAAC,EACtD,GAAa,GAAQ,CAAC,CACxB,CAEA,SAAS,GAAS,CAChB,GAAI,EAAU,OACd,IAAM,EAAW,EAAa,EACxB,EAAM,EAAU,UAClB,GAAO,GAAK,GAAO,GACvB,EAAU,SAAS,CAAE,IAAK,EAAM,EAAW,EAAI,EAAI,EAAU,SAAU,EAAgB,OAAS,QAAS,CAAC,CAC5G,CAEA,SAAS,GAAiB,CACxB,aAAa,CAAW,EACxB,EAAc,WAAW,EAAQ,EAAe,CAClD,CAEA,SAAS,GAAW,CAClB,EAAO,EACP,EAAe,CACjB,CACA,SAAS,GAAe,CACtB,EAAW,EACb,CACA,SAAS,GAAa,CACpB,EAAW,GACX,EAAe,CACjB,CAOA,OALA,EAAO,EACP,EAAS,iBAAiB,SAAU,EAAU,CAAE,QAAS,EAAK,CAAC,EAC/D,EAAS,iBAAiB,aAAc,EAAc,CAAE,QAAS,EAAK,CAAC,EACvE,EAAS,iBAAiB,WAAY,EAAY,CAAE,QAAS,EAAK,CAAC,EACnE,EAAS,iBAAiB,cAAe,EAAY,CAAE,QAAS,EAAK,CAAC,MACzD,CACX,aAAa,CAAW,EACxB,EAAS,oBAAoB,SAAU,CAAQ,EAC/C,EAAS,oBAAoB,aAAc,CAAY,EACvD,EAAS,oBAAoB,WAAY,CAAU,EACnD,EAAS,oBAAoB,cAAe,CAAU,CACxD,CACF,EAAG,CAAC,CAAa,CAAC,EAElB,MAAsB,CACpB,IAAM,EAAM,EAAa,QACrB,IAAQ,OACZ,EAAa,QAAU,KACvB,EAAW,SAAS,cAA2B,kBAAkB,EAAI,GAAG,CAAC,EAAE,MAAM,EACnF,CAAC,EAED,GAAY,EAAU,CACpB,QAAS,EAAM,OAEf,aAAgB,EAAS,QAAU,KAAQ,EAAS,QAAU,IAC9D,YAAa,EAAM,KACnB,YAAa,EAAI,IAAa,EAAM,OAAO,GAAS,EAAI,EAAM,MAAM,EAAG,CAAQ,CAAC,CAClF,CAAC,EAED,SAAS,GAAc,EAAyC,EAAW,CACzE,IAAM,EAAO,EAAc,EAAS,IAAK,EAAK,EAAc,CAAM,EAC7D,IACL,EAAS,eAAe,EACxB,EAAa,QAAU,EAAU,CAAI,EACrC,EAAa,CAAI,EACnB,CAEA,SAAS,EAAU,EAAW,EAAkB,EAAoB,EAAyB,CAC3F,IAAM,EAAW,EAAU,EAAK,CAAI,EAC9B,EAAU,EAAU,EAAK,CAAK,EAC9B,EAAO,EAAe,EAAK,CAAM,EACvC,OACE,EAAC,MAAD,CAEE,KAAK,WACL,eAAc,EAAU,CAAG,EAC3B,SAAU,GAAa,EAAW,EAAI,GACtC,gBAAe,EACf,eAAc,EAAU,OAAS,IAAA,GACjC,aAAY,EAAU,OAAS,EAAI,GAAG,EAAK,IAAI,EAAK,WAAW,EAAU,MAAM,IAAM,EACrF,UAAW,EAAG,EAAO,iBAAkB,GAAW,EAAO,wBAAyB,GAAY,IAAI,EAClG,MAAO,GAAY,KACnB,YAAe,EAAa,CAAG,EAC/B,UAAY,GAAa,GAAc,EAAU,CAAG,EAXtD,SAAA,CAaE,EAAC,OAAD,CACE,cAAA,GACA,UAAW,EACT,EAAO,mBACP,GAAW,EAAO,wBAClB,GAAY,EAAO,0BACrB,EAEC,SAAA,GAAgB,EAAK,CAAM,CACxB,CAAA,EACN,EAAC,OAAD,CAAM,cAAA,GAAY,UAAW,EAAO,iBACjC,SAAA,EAAU,MAAM,EAAG,EAAQ,CAAC,CAAC,IAAK,GACjC,EAAC,OAAD,CAEE,UAAW,EAAO,gBAClB,MAAO,CAAE,gBAAiB,EAAM,KAAM,CACvC,EAHM,EAAM,EAGZ,CACF,CACG,CAAA,CACH,CA/BE,EAAA,EAAU,CAAG,CA+Bf,CAET,CAEA,SAAS,GAAW,EAA8B,CAChD,IAAM,EAAY,IAAS,EACrB,EAAY,EAChB,EAAY,UACZ,IAAS,IAAM,EAAY,cAC3B,IAAS,GAAK,EAAY,cAC1B,EAAO,gBACT,EAEA,GAAI,EAAW,CACb,IAAM,EAAW,EAAQ,EAAM,EAAI,CAAI,EACjC,EAAQ,EAAU,EAAU,EAAG,CAAM,EACrC,EAAS,EAAY,EAAQ,CAAK,EACxC,OACE,EAAC,MAAD,CAEE,IAAK,EAAY,EAAa,IAAA,GACnB,YACX,MAAO,CAAC,EACR,cAAa,CAAC,GAAa,IAAA,GAE3B,SAAA,EAAC,MAAD,CAAK,KAAK,MAAM,UAAW,EAAO,iBAC/B,SAAA,EAAM,KAAK,EAAK,IAAU,EAAU,EAAK,GAAO,EAAW,EAAO,EAAM,CAAC,CACvE,CAAA,CACF,EATE,EAAU,CAAQ,CASpB,CAET,CAEA,IAAM,EAAY,EAAU,EAAO,CAAI,EACjC,EAAY,EAAY,EAAa,MAAO,EAAW,CAAY,CAAC,CAAC,MACrE,EAAc,EAAY,KAAK,MAAM,EAAQ,EAAW,CAAI,EAAI,CAAC,EAAI,EAC3E,OACE,EAAC,MAAD,CAEE,IAAK,EAAY,EAAa,IAAA,GACnB,YACX,MAAO,CAAC,EACR,cAAa,CAAC,GAAa,IAAA,GAC3B,MAAO,CAAE,iBAAkB,CAAY,EAEvC,SAAA,EAAC,MAAD,CAAK,UAAW,EAAO,iBACpB,SAAA,MAAM,KAAK,CAAE,OAAQ,CAAE,GAAI,EAAG,IAAQ,CACrC,IAAM,EAAY,EAAQ,EAAW,EAAM,CAAC,EACtC,EAAQ,EAAU,EAAW,EAAG,CAAM,EACtC,EAAS,EAAY,EAAQ,CAAK,EACxC,OACE,EAAC,MAAD,CAEE,KAAK,MACL,UAAW,EAAG,EAAO,iBAAkB,IAAQ,GAAe,EAAO,uBAAuB,EAE3F,SAAA,EAAM,KAAK,EAAK,IACf,EAAU,EAAK,EAAI,SAAS,IAAM,EAAU,SAAS,EAAG,EAAW,EAAO,EAAO,CACnF,CACG,EAPE,EAAU,CAAS,CAOrB,CAET,CAAC,CACE,CAAA,CACF,EAzBE,EAAU,CAAS,CAyBrB,CAET,CAEA,OACE,EAAC,MAAD,CAAK,IAAK,EAAa,UAAW,EAAO,aAAc,MAAO,CAAE,SAAU,EAAS,MAAO,EAA1F,SAAA,CACE,EAAC,MAAD,CAAK,IAAK,EAAU,UAAW,EAAO,mBACpC,SAAA,EAAC,MAAD,CAAK,KAAK,OAAO,aAAY,EAAiB,EAAM,CAAM,EAA1D,SAAA,CACE,EAAC,MAAD,CAAK,KAAK,MAAM,UAAW,EAAO,qBAC/B,SAAA,EAAS,IAAK,GACb,EAAC,MAAD,CAEE,KAAK,eACL,aAAY,EAAc,EAAK,EAAQ,MAAM,EAC7C,UAAW,EAAG,EAAO,oBAAqB,GAAY,SAAS,EAC/D,MAAO,GAAY,UAElB,SAAA,EAAc,EAAK,EAAQ,QAAQ,CACjC,EAPE,EAAI,OAAO,CAOb,CACN,CACE,CAAA,EACL,EAAC,MAAD,CAAK,IAAK,EAAa,UAAW,EAAG,EAAY,cAAe,EAAO,oBAAoB,EACzF,SAAA,EAAC,MAAD,CAAK,IAAK,EAAM,SAAU,UAAW,EAAY,WAC9C,SAAA,GAAM,IAAI,EAAU,CAClB,CAAA,CACF,CAAA,CACF,GACF,CAAA,EACL,EAAC,MAAD,CAAK,UAAW,EAAO,iBAAvB,SAAA,CACE,EAAC,MAAD,CAAK,UAAW,EAAO,uBAAvB,SAAA,CACE,EAAC,MAAD,CAAK,UAAW,EAAO,sBAAwB,SAAA,EAAe,EAAM,CAAM,CAAO,CAAA,EAChF,GACC,EAAC,EAAD,CACE,KAAM,EAAW,MACjB,QAAU,GACR,EAAa,CAAE,MAAO,EAAM,IAAK,EAAQ,EAAM,CAAC,EAAG,OAAQ,EAAK,EAAG,EAAW,aAAa,EAG5F,SAAA,EAAK,QACA,CAAA,CAEP,CACL,CAAA,EAAA,EAAC,EAAD,CACE,UAAW,EAAO,mBACV,SACR,MAAO,EACP,KAAM,EACN,eAAgB,GACR,SACF,OACQ,eACD,cACD,aACA,YACb,CAAA,CACE,CACF,CAAA,CAAA,GAET"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";var e=`compactMonth_FqyT2`,t=`compactMonth-sticky_jvXmc`,n=`compactMonth-weekdays_Pqo-f`,r=`compactMonth-weekday_D7FA1`,i=`compactMonth-viewport_Ala2B`,a=`compactMonth-pane_MnQpH`,o=`compactMonth-rows_s7t79`,s=`compactMonth-week_aU0xC`,c=`compactMonth-week-folding_enQnk`,l=`compactMonth-cell_cerzg`,u=`compactMonth-cell-outside_90ht-`,d=`compactMonth-number_EpPAy`,f=`compactMonth-number-today_xZAeN`,p=`compactMonth-number-selected_r3RiE`,m=`compactMonth-dots_0UvHH`,h=`compactMonth-dot_-UfnO`,g=`compactMonth-list_laIa8`,_=`compactMonth-list-header_Zo7PB`,v=`compactMonth-list-title_iT4MI`,y=`compactMonth-agenda_F0LqZ`,b={compactMonth:e,"compactMonth-sticky":`compactMonth-sticky_jvXmc`,compactMonthSticky:t,"compactMonth-weekdays":`compactMonth-weekdays_Pqo-f`,compactMonthWeekdays:n,"compactMonth-weekday":`compactMonth-weekday_D7FA1`,compactMonthWeekday:r,"compactMonth-viewport":`compactMonth-viewport_Ala2B`,compactMonthViewport:i,"compactMonth-pane":`compactMonth-pane_MnQpH`,compactMonthPane:a,"compactMonth-rows":`compactMonth-rows_s7t79`,compactMonthRows:o,"compactMonth-week":`compactMonth-week_aU0xC`,compactMonthWeek:s,"compactMonth-week-folding":`compactMonth-week-folding_enQnk`,compactMonthWeekFolding:c,"compactMonth-cell":`compactMonth-cell_cerzg`,compactMonthCell:l,"compactMonth-cell-outside":`compactMonth-cell-outside_90ht-`,compactMonthCellOutside:u,"compactMonth-number":`compactMonth-number_EpPAy`,compactMonthNumber:d,"compactMonth-number-today":`compactMonth-number-today_xZAeN`,compactMonthNumberToday:f,"compactMonth-number-selected":`compactMonth-number-selected_r3RiE`,compactMonthNumberSelected:p,"compactMonth-dots":`compactMonth-dots_0UvHH`,compactMonthDots:m,"compactMonth-dot":`compactMonth-dot_-UfnO`,compactMonthDot:h,"compactMonth-list":`compactMonth-list_laIa8`,compactMonthList:g,"compactMonth-list-header":`compactMonth-list-header_Zo7PB`,compactMonthListHeader:_,"compactMonth-list-title":`compactMonth-list-title_iT4MI`,compactMonthListTitle:v,"compactMonth-agenda":`compactMonth-agenda_F0LqZ`,compactMonthAgenda:y};export{e as compactMonth,y as compactMonthAgenda,l as compactMonthCell,u as compactMonthCellOutside,h as compactMonthDot,m as compactMonthDots,g as compactMonthList,_ as compactMonthListHeader,v as compactMonthListTitle,d as compactMonthNumber,p as compactMonthNumberSelected,f as compactMonthNumberToday,a as compactMonthPane,o as compactMonthRows,t as compactMonthSticky,i as compactMonthViewport,s as compactMonthWeek,c as compactMonthWeekFolding,r as compactMonthWeekday,n as compactMonthWeekdays,b as default};
|
|
2
|
+
//# sourceMappingURL=compactMonth.module.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compactMonth.module.mjs","names":[],"sources":["../../../../../../package/common/calendar/components/compactMonth/compactMonth.module.pcss"],"sourcesContent":["/* `--collapse` runs from 0 (the whole month) to 1 (only the selected week), written by the\n component from the scroll position. Five rows fold away over five rows of scrolling, so the\n clipped edge of the month and the top of the list below it stay level the whole way. */\n.compactMonth {\n --row: 2.75em;\n --weekdays: 1.75em;\n\n position: relative;\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n overscroll-behavior-y: contain;\n\n &-sticky {\n position: sticky;\n top: 0;\n z-index: 1;\n\n /* The folded rows are clipped, not removed, so this box still spans all six: it must not\n catch the taps meant for the list showing through below the fold. */\n pointer-events: none;\n user-select: none;\n -webkit-touch-callout: none;\n }\n\n &-weekdays {\n display: grid;\n grid-template-columns: repeat(var(--days), minmax(0, 1fr));\n align-items: center;\n height: var(--weekdays);\n background: var(--background);\n pointer-events: auto;\n }\n\n &-weekday {\n font-size: 0.6875em;\n font-weight: 600;\n text-align: center;\n color: var(--text-dark);\n }\n\n &-viewport {\n height: calc(6 * var(--row));\n clip-path: inset(0 0 calc(5 * var(--row) * var(--collapse, 0)) 0);\n pointer-events: auto;\n\n /* Horizontal swipes page the month or week; vertical ones fold it. */\n touch-action: pan-y;\n }\n\n &-pane {\n background: var(--background);\n }\n\n /* Keeps the selected week in view while the rows around it fold away above and below it.\n Reduced motion is handled where `--collapse` is written, which is then only 0 or 1: freezing\n this transform instead would clip the selected week out of view mid-fold. */\n &-rows {\n transform: translateY(calc(var(--selected-row, 0) * var(--row) * var(--collapse, 0) * -1));\n }\n\n &-week {\n display: grid;\n grid-template-columns: repeat(var(--days), minmax(0, 1fr));\n height: var(--row);\n\n &-folding {\n opacity: calc(1 - var(--collapse, 0));\n }\n }\n\n &-cell {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 0.1875em;\n min-width: 0;\n outline: none;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n\n &-outside {\n color: var(--text-light);\n }\n\n &:focus-visible .compactMonth-number {\n box-shadow: 0 0 0 2px var(--focus-border-color, var(--primary-color));\n }\n }\n\n &-number {\n display: grid;\n place-items: center;\n width: 1.875em;\n height: 1.875em;\n border-radius: 50%;\n font-size: 0.9375em;\n font-variant-numeric: tabular-nums;\n transition:\n background-color 0.15s ease,\n color 0.15s ease;\n\n &-today {\n color: var(--custom-calendar-today-color);\n font-weight: 700;\n }\n\n &-selected {\n background: var(--text-color);\n color: var(--background);\n font-weight: 600;\n }\n }\n\n &-dots {\n display: flex;\n gap: 2px;\n height: 4px;\n }\n\n &-dot {\n width: 4px;\n height: 4px;\n border-radius: 50%;\n background: var(--event-color, var(--primary-color));\n }\n\n /* Tall enough that the month can always fold all the way, however few events the day has. */\n &-list {\n min-height: calc(100% - var(--weekdays) - var(--row));\n border-top: 1px solid var(--border-color);\n\n &-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.5em;\n padding: 0.75em 1em 0.125em;\n }\n\n &-title {\n font-size: 0.8125em;\n font-weight: 600;\n color: var(--text-dark);\n }\n }\n}\n\n/* Today stays marked when it is also the selected day. */\n.compactMonth-number-today.compactMonth-number-selected {\n background: var(--custom-calendar-today-color);\n color: var(--text-on-primary);\n}\n\n/* Scrolls with the page it sits in, rather than on its own. Two classes, to outrank AgendaList's\n own rule whichever stylesheet loads first. */\n.compactMonth .compactMonth-agenda {\n flex: none;\n overflow: visible;\n}\n"],"mappings":""}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{isSelfActivation as e}from"../../../utils/activationKey.mjs";import t from"../../../button/button.mjs";import{PopoverAlign as n,PopoverPlacement as r}from"../../../popover/popover.types.mjs";import i from"../../../popover/popover.mjs";import{dateToDay as a}from"../../../utils/day.mjs";import{CalendarView as o}from"../../calendar.types.mjs";import{addDays as s,addMonths as c,dayDiff as l,endAfter as u,gridKeyTarget as ee,isSameDay as d,periodRange as f,shiftDays as p,shownDays as m,startOfMonth as te,startOfWeek as ne}from"../../dates.mjs";import{formatDayNumber as re,formatLongDate as h,formatMonthTitle as ie,formatTime as ae,formatWeekday as g}from"../../format.mjs";import{eventDays as oe,eventEnd as se,eventsByDay as ce,isAllDayLike as le,limitLanes as ue,packLanes as de}from"../../layout.mjs";import fe from"../agendaList/agendaList.mjs";import{clamp as _,pageStep as pe}from"../../gesture.mjs";import{useGestures as me}from"../../useGestures.mjs";import{usePager as he}from"../../usePager.mjs";import v from"../../pager.module.mjs";import y from"./monthView.module.mjs";import{useLayoutEffect as b,useRef as x,useState as S}from"react";import C from"classnames";import{jsx as w,jsxs as T}from"react/jsx-runtime";var ge=[-1,0,1];function E({events:E,date:D,locale:O,weekStartsOn:k,hidden:A,text:j,onDateChange:M,onOpenDay:N,onEventClick:P,onEventChange:F,onSlotCreate:I,renderEvent:L,classNames:R,slotStyles:z}){let B=x(null),V=x(null),H=x(null),U=x(null),[_e,W]=S(1/0),[G,K]=S(null),[q,J]=S(null),Y=te(D),X=new Date,Z=m(ne(X,k),7,A),ve=f(o.Month,Y,k).start,ye=(e,t)=>m(s(e,t*7),7,A),Q=he(a(Y),e=>M(c(D,e)),()=>H.current?.querySelector(`[tabindex="0"]`)??null);b(()=>{let e=V.current;if(!e)return;function t(){let t=e.querySelector(`[data-cal-bars]`);if(!t||t.clientHeight===0){W(1/0);return}let n=getComputedStyle(t),r=parseFloat(n.gridAutoRows),i=parseFloat(n.rowGap)||0,a=parseFloat(n.paddingTop)||0;W(r>0?Math.max(1,Math.floor((t.clientHeight-a+i)/(r+i))):1/0)}t();let n=new ResizeObserver(t);return n.observe(e),()=>n.disconnect()},[]),b(()=>{let e=U.current;e!==null&&(U.current=null,H.current?.querySelector(`[data-cal-day="${e}"]`)?.focus())});function $(e){let t=H.current;if(!t)return null;let n=t.getBoundingClientRect();if(n.width===0||n.height===0)return null;let r=Z.length,i=_(Math.floor((e.x-n.left)/n.width*r),0,r-1),a=_(Math.floor((e.y-n.top)/n.height*6),0,5);return ye(ve,a)[i]}function be(e){return H.current?.querySelector(`[data-cal-day="${a(e)}"]`)??null}me(B,{onPress:Q.finish,canSwipe:()=>!0,onSwipeMove:Q.move,onSwipeEnd:(e,t)=>Q.settle(pe(e,Q.width(),t)),dragFrom:(e,t)=>{if(!F)return null;let n=e.closest(`[data-cal-event]`);if(!n||!H.current?.contains(n))return null;let r=E.find(e=>String(e.id)===n.dataset.calEvent),i=$(t);return!r||r.readOnly||i===null?null:{event:r,grabbed:i,offset:0}},onDragStart:J,onDragMove:e=>{let t=$(e);t!==null&&J(e=>{if(!e)return e;let n=l(e.grabbed,t);return n===e.offset?e:{...e,offset:n}})},onDragEnd:e=>{J(null);let t=$(e);if(!q||t===null)return;let n=l(q.grabbed,t);if(n===0)return;let r=p(q.event.start,n),i=(se(q.event).getTime()-q.event.start.getTime())/6e4;F?.({event:q.event,start:r,end:u(r,p(q.event.end,n),i)})},onDragCancel:()=>J(null)});function xe(e,t){let n=be(e);n&&K({day:e,anchor:n,fromKeyboard:t})}function Se(e,t){if(N&&e.target.closest(`[data-cal-day-number]`)){N(t);return}I?.({start:t,end:s(t,1),allDay:!0},e.currentTarget)}function Ce(t,n){let r=ee(t.key,n,k,A);if(!r){e(t)&&(t.preventDefault(),xe(n,!0));return}t.preventDefault(),U.current=a(r),M(r)}function we(e){let{event:t}=e,n=le(t)||e.span>1||e.continuesBefore||e.continuesAfter,r=!!P||!!F&&!t.readOnly;return T(`div`,{"data-cal-event":String(t.id),className:C(y.monthViewBar,n?y.monthViewBarFilled:y.monthViewBarTimed,e.continuesBefore&&y.monthViewBarContinuesBefore,e.continuesAfter&&y.monthViewBarContinuesAfter,r&&y.monthViewBarInteractive,q?.event===t&&y.monthViewBarDragging,R?.event),style:{"--event-color":t.color,gridColumn:`${e.start+1} / span ${e.span}`,gridRow:e.lane+1,...z?.event},onClick:e=>P?.(t,e.currentTarget),children:[!n&&w(`span`,{className:y.monthViewDot}),!n&&w(`span`,{className:y.monthViewTime,children:ae(t.start,O)}),w(`span`,{className:y.monthViewBarTitle,children:L?L(t,{singleLine:!0}):t.title})]},t.id)}function Te(e){let t=c(Y,e),n=e===0,r=f(o.Month,t,k).start,i=null;if(n&&q&&q.offset!==0){let{first:e,last:t}=oe(q.event);i={from:s(e,q.offset),to:s(t,q.offset)}}return w(`div`,{ref:n?H:void 0,className:C(v.pagerPane,e===-1&&v.pagerPanePrev,e===1&&v.pagerPaneNext,y.monthViewPane),inert:!n,"aria-hidden":!n||void 0,children:Array.from({length:6},(e,o)=>{let s=ye(r,o),c=ce(E,s),u=ue(de(E,s),s.length,_e);return T(`div`,{role:`row`,className:y.monthViewWeek,children:[s.map((e,r)=>{let o=c[r].length,s=d(e,X),u=h(e,O);return w(`div`,{role:`gridcell`,"data-cal-day":a(e),tabIndex:n&&d(e,D)?0:-1,"aria-current":s?`date`:void 0,"aria-label":o>0?`${u}, ${j.eventCount(o)}`:u,className:C(y.monthViewCell,e.getMonth()!==t.getMonth()&&y.monthViewCellOutside,I&&y.monthViewCellCreatable,i&&l(i.from,e)>=0&&l(e,i.to)>=0&&y.monthViewCellTarget,R?.cell),style:z?.cell,onClick:t=>Se(t,e),onKeyDown:t=>Ce(t,e),children:w(`span`,{"data-cal-day-number":!0,"aria-hidden":!0,className:C(y.monthViewDayNumber,s&&y.monthViewDayNumberToday,N&&y.monthViewDayNumberLink),children:re(e,O)})},a(e))}),T(`div`,{"data-cal-bars":!0,"aria-hidden":!0,className:y.monthViewBars,children:[u.visible.map(we),u.hidden.map((e,t)=>e>0&&w(`div`,{className:y.monthViewMore,style:{gridColumn:t+1,gridRow:u.moreLane+1},onClick:()=>xe(s[t],!1),children:j.more(e)},`more-${t}`))]})]},a(s[0]))})},a(t))}return T(`div`,{ref:B,className:y.monthView,style:{"--days":Z.length},children:[T(`div`,{role:`grid`,"aria-label":ie(D,O),className:y.monthViewGrid,children:[w(`div`,{role:`row`,className:y.monthViewWeekdays,children:Z.map(e=>w(`div`,{role:`columnheader`,"aria-label":g(e,O,`long`),className:C(y.monthViewWeekday,R?.dayHeader),style:z?.dayHeader,children:g(e,O,`short`)},e.getDay()))}),w(`div`,{ref:V,className:C(v.pagerViewport,y.monthViewViewport),children:w(`div`,{ref:Q.trackRef,className:v.pagerTrack,children:ge.map(Te)})})]}),w(i,{anchor:G?.anchor??null,isOpen:G!==null,onOpenChange:e=>!e&&K(null),focusOnOpen:G?.fromKeyboard??!1,placement:r.Bottom,align:n.Start,content:G&&T(`div`,{className:y.monthViewList,children:[w(`div`,{className:y.monthViewListTitle,children:h(G.day,O)}),w(fe,{className:y.monthViewListEvents,events:E,start:G.day,days:1,showDayHeaders:!1,locale:O,text:j,onEventClick:e=>{K(null),P?.(e,G.anchor)},renderEvent:L,classNames:R,slotStyles:z}),I&&w(t,{className:y.monthViewListCreate,onClick:()=>{K(null),I({start:G.day,end:s(G.day,1),allDay:!0},G.anchor)},children:j.newEvent})]})})]})}export{E as default};
|
|
2
|
+
//# sourceMappingURL=monthView.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monthView.mjs","names":[],"sources":["../../../../../../package/common/calendar/components/monthView/monthView.tsx"],"sourcesContent":["import {\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type MouseEvent,\n type ReactElement,\n} from 'react';\nimport cx from 'classnames';\n\nimport Button from 'components/common/button';\nimport Popover from 'components/common/popover';\nimport { PopoverAlign, PopoverPlacement } from 'components/common/popover/popover.types';\nimport { isSelfActivation } from 'components/common/utils/activationKey';\nimport { CalendarView, type CalendarEvent } from '../../calendar.types';\nimport {\n addDays,\n addMonths,\n dayDiff,\n dateToDay,\n endAfter,\n gridKeyTarget,\n isSameDay,\n periodRange,\n shiftDays,\n shownDays,\n startOfMonth,\n startOfWeek,\n} from '../../dates';\nimport { formatDayNumber, formatLongDate, formatMonthTitle, formatTime, formatWeekday } from '../../format';\nimport { clamp, pageStep } from '../../gesture';\nimport { eventDays, eventEnd, eventsByDay, isAllDayLike, limitLanes, packLanes, type LaneBar } from '../../layout';\nimport { useGestures, type GesturePoint } from '../../useGestures';\nimport { usePager } from '../../usePager';\nimport AgendaList from '../agendaList';\nimport type { MonthDrag, MonthViewProps } from './monthView.types';\n\nimport pagerStyles from '../../pager.module.pcss';\nimport styles from './monthView.module.pcss';\n\nconst STEPS = [-1, 0, 1] as const;\n\nfunction MonthView<E extends CalendarEvent>({\n events,\n date,\n locale,\n weekStartsOn,\n hidden,\n text,\n onDateChange,\n onOpenDay,\n onEventClick,\n onEventChange,\n onSlotCreate,\n renderEvent,\n classNames,\n slotStyles,\n}: MonthViewProps<E>): ReactElement {\n const rootRef = useRef<HTMLDivElement>(null);\n const viewportRef = useRef<HTMLDivElement>(null);\n const currentRef = useRef<HTMLDivElement>(null);\n const pendingFocus = useRef<string | null>(null);\n const [capacity, setCapacity] = useState(Infinity);\n const [list, setList] = useState<{ day: Date; anchor: HTMLElement; fromKeyboard: boolean } | null>(null);\n const [drag, setDrag] = useState<MonthDrag<E> | null>(null);\n\n const month = startOfMonth(date);\n const today = new Date();\n const weekdays = shownDays(startOfWeek(today, weekStartsOn), 7, hidden);\n const gridStart = periodRange(CalendarView.Month, month, weekStartsOn).start;\n const rowDates = (paneStart: Date, row: number) => shownDays(addDays(paneStart, row * 7), 7, hidden);\n\n const pager = usePager(\n dateToDay(month),\n (step) => onDateChange(addMonths(date, step)),\n () => currentRef.current?.querySelector<HTMLElement>('[tabindex=\"0\"]') ?? null,\n );\n\n // Lanes that fit a cell, from the real geometry, so `+N` appears exactly when bars would clip.\n // Without layout (jsdom) there is nothing to measure, and every event is shown.\n useLayoutEffect(() => {\n const viewport = viewportRef.current;\n if (!viewport) return;\n function measure() {\n const bars = viewport!.querySelector<HTMLElement>('[data-cal-bars]');\n if (!bars || bars.clientHeight === 0) {\n setCapacity(Infinity);\n return;\n }\n const style = getComputedStyle(bars);\n const lane = parseFloat(style.gridAutoRows);\n const gap = parseFloat(style.rowGap) || 0;\n const top = parseFloat(style.paddingTop) || 0;\n setCapacity(lane > 0 ? Math.max(1, Math.floor((bars.clientHeight - top + gap) / (lane + gap))) : Infinity);\n }\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(viewport);\n return () => observer.disconnect();\n }, []);\n\n // Arrowing onto a day of the next month pages first, so the cell to focus only exists after\n // the render that follows.\n useLayoutEffect(() => {\n const key = pendingFocus.current;\n if (key === null) return;\n pendingFocus.current = null;\n currentRef.current?.querySelector<HTMLElement>(`[data-cal-day=\"${key}\"]`)?.focus();\n });\n\n function dayAt(point: GesturePoint): Date | null {\n const pane = currentRef.current;\n if (!pane) return null;\n const rect = pane.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) return null;\n const count = weekdays.length;\n const column = clamp(Math.floor(((point.x - rect.left) / rect.width) * count), 0, count - 1);\n const row = clamp(Math.floor(((point.y - rect.top) / rect.height) * 6), 0, 5);\n return rowDates(gridStart, row)[column];\n }\n\n function cellFor(day: Date): HTMLElement | null {\n return currentRef.current?.querySelector<HTMLElement>(`[data-cal-day=\"${dateToDay(day)}\"]`) ?? null;\n }\n\n useGestures<MonthDrag<E>>(rootRef, {\n onPress: pager.finish,\n canSwipe: () => true,\n onSwipeMove: pager.move,\n onSwipeEnd: (dx, velocity) => pager.settle(pageStep(dx, pager.width(), velocity)),\n dragFrom: (target, point) => {\n if (!onEventChange) return null;\n const element = target.closest<HTMLElement>('[data-cal-event]');\n if (!element || !currentRef.current?.contains(element)) return null;\n const event = events.find((candidate) => String(candidate.id) === element.dataset.calEvent);\n const grabbed = dayAt(point);\n if (!event || event.readOnly || grabbed === null) return null;\n return { event, grabbed, offset: 0 };\n },\n onDragStart: setDrag,\n onDragMove: (point) => {\n const day = dayAt(point);\n if (day === null) return;\n setDrag((current) => {\n if (!current) return current;\n const offset = dayDiff(current.grabbed, day);\n return offset === current.offset ? current : { ...current, offset };\n });\n },\n onDragEnd: (point) => {\n setDrag(null);\n const day = dayAt(point);\n if (!drag || day === null) return;\n const offset = dayDiff(drag.grabbed, day);\n if (offset === 0) return;\n const start = shiftDays(drag.event.start, offset);\n const length = (eventEnd(drag.event).getTime() - drag.event.start.getTime()) / 60_000;\n onEventChange?.({\n event: drag.event,\n start,\n end: endAfter(start, shiftDays(drag.event.end, offset), length),\n });\n },\n onDragCancel: () => setDrag(null),\n });\n\n function openList(day: Date, fromKeyboard: boolean) {\n const anchor = cellFor(day);\n if (anchor) setList({ day, anchor, fromKeyboard });\n }\n\n function handleCellClick(clickEvent: MouseEvent<HTMLDivElement>, day: Date) {\n if (onOpenDay && (clickEvent.target as Element).closest('[data-cal-day-number]')) {\n onOpenDay(day);\n return;\n }\n onSlotCreate?.({ start: day, end: addDays(day, 1), allDay: true }, clickEvent.currentTarget);\n }\n\n function handleKeyDown(keyEvent: KeyboardEvent<HTMLDivElement>, day: Date) {\n const next = gridKeyTarget(keyEvent.key, day, weekStartsOn, hidden);\n if (!next) {\n if (isSelfActivation(keyEvent)) {\n keyEvent.preventDefault();\n openList(day, true);\n }\n return;\n }\n keyEvent.preventDefault();\n pendingFocus.current = dateToDay(next);\n onDateChange(next);\n }\n\n function renderBar(bar: LaneBar<E>) {\n const { event } = bar;\n const filled = isAllDayLike(event) || bar.span > 1 || bar.continuesBefore || bar.continuesAfter;\n const interactive = Boolean(onEventClick) || (Boolean(onEventChange) && !event.readOnly);\n return (\n <div\n key={event.id}\n data-cal-event={String(event.id)}\n className={cx(\n styles.monthViewBar,\n filled ? styles.monthViewBarFilled : styles.monthViewBarTimed,\n bar.continuesBefore && styles.monthViewBarContinuesBefore,\n bar.continuesAfter && styles.monthViewBarContinuesAfter,\n interactive && styles.monthViewBarInteractive,\n drag?.event === event && styles.monthViewBarDragging,\n classNames?.event,\n )}\n style={\n {\n '--event-color': event.color,\n gridColumn: `${bar.start + 1} / span ${bar.span}`,\n gridRow: bar.lane + 1,\n ...slotStyles?.event,\n } as CSSProperties\n }\n onClick={(clickEvent) => onEventClick?.(event, clickEvent.currentTarget)}\n >\n {!filled && <span className={styles.monthViewDot} />}\n {!filled && <span className={styles.monthViewTime}>{formatTime(event.start, locale)}</span>}\n <span className={styles.monthViewBarTitle}>\n {renderEvent ? renderEvent(event, { singleLine: true }) : event.title}\n </span>\n </div>\n );\n }\n\n function renderPane(step: (typeof STEPS)[number]) {\n const paneMonth = addMonths(month, step);\n const isCurrent = step === 0;\n const paneStart = periodRange(CalendarView.Month, paneMonth, weekStartsOn).start;\n\n let target: { from: Date; to: Date } | null = null;\n if (isCurrent && drag && drag.offset !== 0) {\n const { first, last } = eventDays(drag.event);\n target = { from: addDays(first, drag.offset), to: addDays(last, drag.offset) };\n }\n\n return (\n <div\n key={dateToDay(paneMonth)}\n ref={isCurrent ? currentRef : undefined}\n className={cx(\n pagerStyles.pagerPane,\n step === -1 && pagerStyles.pagerPanePrev,\n step === 1 && pagerStyles.pagerPaneNext,\n styles.monthViewPane,\n )}\n inert={!isCurrent}\n aria-hidden={!isCurrent || undefined}\n >\n {Array.from({ length: 6 }, (_, row) => {\n const dates = rowDates(paneStart, row);\n const perDay = eventsByDay(events, dates);\n const lanes = limitLanes(packLanes(events, dates), dates.length, capacity);\n return (\n <div key={dateToDay(dates[0])} role='row' className={styles.monthViewWeek}>\n {dates.map((day, column) => {\n const count = perDay[column].length;\n const isToday = isSameDay(day, today);\n const name = formatLongDate(day, locale);\n return (\n <div\n key={dateToDay(day)}\n role='gridcell'\n data-cal-day={dateToDay(day)}\n tabIndex={isCurrent && isSameDay(day, date) ? 0 : -1}\n aria-current={isToday ? 'date' : undefined}\n aria-label={count > 0 ? `${name}, ${text.eventCount(count)}` : name}\n className={cx(\n styles.monthViewCell,\n day.getMonth() !== paneMonth.getMonth() && styles.monthViewCellOutside,\n onSlotCreate && styles.monthViewCellCreatable,\n target &&\n dayDiff(target.from, day) >= 0 &&\n dayDiff(day, target.to) >= 0 &&\n styles.monthViewCellTarget,\n classNames?.cell,\n )}\n style={slotStyles?.cell}\n onClick={(clickEvent) => handleCellClick(clickEvent, day)}\n onKeyDown={(keyEvent) => handleKeyDown(keyEvent, day)}\n >\n <span\n data-cal-day-number\n aria-hidden\n className={cx(\n styles.monthViewDayNumber,\n isToday && styles.monthViewDayNumberToday,\n onOpenDay && styles.monthViewDayNumberLink,\n )}\n >\n {formatDayNumber(day, locale)}\n </span>\n </div>\n );\n })}\n {/* Pointer only: a keyboard reaches a day's events through Enter on its cell. */}\n <div data-cal-bars aria-hidden className={styles.monthViewBars}>\n {lanes.visible.map(renderBar)}\n {lanes.hidden.map(\n (count, column) =>\n count > 0 && (\n <div\n key={`more-${column}`}\n className={styles.monthViewMore}\n style={{ gridColumn: column + 1, gridRow: lanes.moreLane + 1 }}\n onClick={() => openList(dates[column], false)}\n >\n {text.more(count)}\n </div>\n ),\n )}\n </div>\n </div>\n );\n })}\n </div>\n );\n }\n\n return (\n <div ref={rootRef} className={styles.monthView} style={{ '--days': weekdays.length } as CSSProperties}>\n <div role='grid' aria-label={formatMonthTitle(date, locale)} className={styles.monthViewGrid}>\n <div role='row' className={styles.monthViewWeekdays}>\n {weekdays.map((day) => (\n <div\n key={day.getDay()}\n role='columnheader'\n aria-label={formatWeekday(day, locale, 'long')}\n className={cx(styles.monthViewWeekday, classNames?.dayHeader)}\n style={slotStyles?.dayHeader}\n >\n {formatWeekday(day, locale, 'short')}\n </div>\n ))}\n </div>\n <div ref={viewportRef} className={cx(pagerStyles.pagerViewport, styles.monthViewViewport)}>\n <div ref={pager.trackRef} className={pagerStyles.pagerTrack}>\n {STEPS.map(renderPane)}\n </div>\n </div>\n </div>\n <Popover\n anchor={list?.anchor ?? null}\n isOpen={list !== null}\n onOpenChange={(open) => !open && setList(null)}\n // Enter on a cell is a key event of ours, which Popover cannot see, so it is told.\n focusOnOpen={list?.fromKeyboard ?? false}\n placement={PopoverPlacement.Bottom}\n align={PopoverAlign.Start}\n content={\n list && (\n <div className={styles.monthViewList}>\n <div className={styles.monthViewListTitle}>{formatLongDate(list.day, locale)}</div>\n <AgendaList\n className={styles.monthViewListEvents}\n events={events}\n start={list.day}\n days={1}\n showDayHeaders={false}\n locale={locale}\n text={text}\n onEventClick={(event) => {\n setList(null);\n // The list's own row unmounts with the popover, so the day's cell anchors it.\n onEventClick?.(event, list.anchor);\n }}\n renderEvent={renderEvent}\n classNames={classNames}\n slotStyles={slotStyles}\n />\n {onSlotCreate && (\n <Button\n className={styles.monthViewListCreate}\n onClick={() => {\n setList(null);\n onSlotCreate({ start: list.day, end: addDays(list.day, 1), allDay: true }, list.anchor);\n }}\n >\n {text.newEvent}\n </Button>\n )}\n </div>\n )\n }\n />\n </div>\n );\n}\n\nexport default MonthView;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";var e=`monthView_COWAp`,t=`monthView-grid_MG0UZ`,n=`monthView-weekdays_BHTuU`,r=`monthView-weekday_ycA-L`,i=`monthView-viewport_LpCe1`,a=`monthView-pane_bHUbv`,o=`monthView-week_gnh6Y`,s=`monthView-cell_ypx-s`,c=`monthView-cell-outside_1Mr0V`,l=`monthView-cell-creatable_BxZde`,u=`monthView-cell-target_-oYgU`,d=`monthView-dayNumber_voxGS`,f=`monthView-dayNumber-today_G7coa`,p=`monthView-dayNumber-link_5k317`,m=`monthView-bars_DW4bv`,h=`monthView-bar_9zcHJ`,g=`monthView-bar-filled_Mq2Ca`,_=`monthView-bar-timed_C8Xwi`,v=`monthView-bar-continuesBefore_DBSlE`,y=`monthView-bar-continuesAfter_cEvZo`,b=`monthView-bar-interactive_FGu9C`,x=`monthView-bar-dragging_sxndr`,S=`monthView-bar-title_-X5yZ`,C=`monthView-dot_81QmI`,w=`monthView-time_W-u-E`,T=`monthView-more_m2PXd`,E=`monthView-list_4pG-Y`,D=`monthView-list-title_oM-3e`,O=`monthView-list-events_RsMQ6`,k=`monthView-list-create_e7EdY`,A={monthView:e,"monthView-grid":`monthView-grid_MG0UZ`,monthViewGrid:t,"monthView-weekdays":`monthView-weekdays_BHTuU`,monthViewWeekdays:n,"monthView-weekday":`monthView-weekday_ycA-L`,monthViewWeekday:r,"monthView-viewport":`monthView-viewport_LpCe1`,monthViewViewport:i,"monthView-pane":`monthView-pane_bHUbv`,monthViewPane:a,"monthView-week":`monthView-week_gnh6Y`,monthViewWeek:o,"monthView-cell":`monthView-cell_ypx-s`,monthViewCell:s,"monthView-cell-outside":`monthView-cell-outside_1Mr0V`,monthViewCellOutside:c,"monthView-cell-creatable":`monthView-cell-creatable_BxZde`,monthViewCellCreatable:l,"monthView-cell-target":`monthView-cell-target_-oYgU`,monthViewCellTarget:u,"monthView-dayNumber":`monthView-dayNumber_voxGS`,monthViewDayNumber:d,"monthView-dayNumber-today":`monthView-dayNumber-today_G7coa`,monthViewDayNumberToday:f,"monthView-dayNumber-link":`monthView-dayNumber-link_5k317`,monthViewDayNumberLink:p,"monthView-bars":`monthView-bars_DW4bv`,monthViewBars:m,"monthView-bar":`monthView-bar_9zcHJ`,monthViewBar:h,"monthView-bar-filled":`monthView-bar-filled_Mq2Ca`,monthViewBarFilled:g,"monthView-bar-timed":`monthView-bar-timed_C8Xwi`,monthViewBarTimed:_,"monthView-bar-continuesBefore":`monthView-bar-continuesBefore_DBSlE`,monthViewBarContinuesBefore:v,"monthView-bar-continuesAfter":`monthView-bar-continuesAfter_cEvZo`,monthViewBarContinuesAfter:y,"monthView-bar-interactive":`monthView-bar-interactive_FGu9C`,monthViewBarInteractive:b,"monthView-bar-dragging":`monthView-bar-dragging_sxndr`,monthViewBarDragging:x,"monthView-bar-title":`monthView-bar-title_-X5yZ`,monthViewBarTitle:S,"monthView-dot":`monthView-dot_81QmI`,monthViewDot:C,"monthView-time":`monthView-time_W-u-E`,monthViewTime:w,"monthView-more":`monthView-more_m2PXd`,monthViewMore:T,"monthView-list":`monthView-list_4pG-Y`,monthViewList:E,"monthView-list-title":`monthView-list-title_oM-3e`,monthViewListTitle:D,"monthView-list-events":`monthView-list-events_RsMQ6`,monthViewListEvents:O,"monthView-list-create":`monthView-list-create_e7EdY`,monthViewListCreate:k};export{A as default,e as monthView,h as monthViewBar,y as monthViewBarContinuesAfter,v as monthViewBarContinuesBefore,x as monthViewBarDragging,g as monthViewBarFilled,b as monthViewBarInteractive,_ as monthViewBarTimed,S as monthViewBarTitle,m as monthViewBars,s as monthViewCell,l as monthViewCellCreatable,c as monthViewCellOutside,u as monthViewCellTarget,d as monthViewDayNumber,p as monthViewDayNumberLink,f as monthViewDayNumberToday,C as monthViewDot,t as monthViewGrid,E as monthViewList,k as monthViewListCreate,O as monthViewListEvents,D as monthViewListTitle,T as monthViewMore,a as monthViewPane,w as monthViewTime,i as monthViewViewport,o as monthViewWeek,r as monthViewWeekday,n as monthViewWeekdays};
|
|
2
|
+
//# sourceMappingURL=monthView.module.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monthView.module.mjs","names":[],"sources":["../../../../../../package/common/calendar/components/monthView/monthView.module.pcss"],"sourcesContent":[".monthView {\n display: flex;\n flex: 1;\n flex-direction: column;\n min-height: 0;\n user-select: none;\n -webkit-touch-callout: none;\n\n /* Horizontal swipes page the month; vertical ones still scroll the page. */\n touch-action: pan-y;\n\n &-grid {\n display: flex;\n flex: 1;\n flex-direction: column;\n min-height: 0;\n }\n\n &-weekdays {\n display: grid;\n grid-template-columns: repeat(var(--days), minmax(0, 1fr));\n border-bottom: 1px solid var(--border-color);\n }\n\n &-weekday {\n padding: 0.5em 0.625em;\n overflow: hidden;\n font-size: 0.6875em;\n font-weight: 600;\n letter-spacing: 0.06em;\n text-overflow: ellipsis;\n text-transform: uppercase;\n white-space: nowrap;\n color: var(--text-dark);\n }\n\n &-viewport {\n flex: 1;\n min-height: 0;\n }\n\n /* Six equal rows whatever the month, so every pane has the same height while swiping and a\n row never grows to fit its events: that is what the `+N` buttons are for. */\n &-pane {\n display: grid;\n grid-template-rows: repeat(6, minmax(0, 1fr));\n background: var(--background);\n }\n\n &-week {\n position: relative;\n display: grid;\n grid-template-columns: repeat(var(--days), minmax(0, 1fr));\n min-height: 0;\n\n & + & {\n border-top: 1px solid var(--border-color);\n }\n }\n\n &-cell {\n min-width: 0;\n padding: 0.25em;\n outline: none;\n\n & + & {\n border-left: 1px solid var(--border-color);\n }\n\n &:focus-visible {\n box-shadow: inset 0 0 0 2px var(--focus-border-color, var(--primary-color));\n }\n\n &-outside {\n background: color-mix(in oklab, var(--background-accent) 40%, transparent);\n color: var(--text-light);\n }\n\n &-creatable {\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n\n &:hover {\n background: color-mix(in oklab, var(--primary-color) 5%, transparent);\n }\n }\n\n &-target {\n background: color-mix(in oklab, var(--primary-color) 14%, transparent);\n }\n }\n\n &-dayNumber {\n display: inline-grid;\n place-items: center;\n min-width: 1.75em;\n height: 1.75em;\n padding: 0 0.25em;\n border-radius: 0.875em;\n font-size: 0.8125em;\n font-weight: 500;\n font-variant-numeric: tabular-nums;\n transition: background-color 0.15s ease;\n\n &-today {\n background: var(--custom-calendar-today-color);\n color: var(--text-on-primary);\n font-weight: 700;\n }\n\n &-link {\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n\n &:not(.monthView-dayNumber-today):hover {\n background: var(--background-accent);\n }\n }\n }\n\n /* Laid over the week's cells and starting below the day numbers. Its `grid-auto-rows`,\n `row-gap` and `padding-top` are read back to work out how many lanes fit, so change them\n here rather than overriding them on a bar. */\n &-bars {\n position: absolute;\n inset: 0;\n display: grid;\n grid-template-columns: repeat(var(--days), minmax(0, 1fr));\n grid-auto-rows: 1.375em;\n row-gap: 2px;\n align-content: start;\n padding-top: 1.75em;\n overflow: hidden;\n pointer-events: none;\n }\n\n &-bar {\n --event: var(--event-color, var(--primary-color));\n\n display: flex;\n align-items: center;\n gap: 0.3em;\n min-width: 0;\n margin: 0 0.25em;\n padding: 0 0.4em;\n overflow: hidden;\n border-radius: var(--custom-calendar-event-radius);\n font-size: 0.75em;\n white-space: nowrap;\n pointer-events: auto;\n transition:\n background-color 0.15s ease,\n opacity 0.15s ease;\n\n &-filled {\n background: color-mix(in oklab, var(--event) 22%, var(--background));\n box-shadow: inset 3px 0 0 var(--event);\n font-weight: 500;\n\n &:hover {\n background: color-mix(in oklab, var(--event) 32%, var(--background));\n }\n }\n\n &-timed:hover {\n background: color-mix(in oklab, var(--event) 12%, transparent);\n }\n\n &-continuesBefore {\n margin-left: 0;\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n box-shadow: none;\n }\n\n &-continuesAfter {\n margin-right: 0;\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n\n &-interactive {\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n }\n\n &-dragging {\n opacity: 0.45;\n }\n\n &-title {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n }\n\n &-dot {\n flex: none;\n width: 0.5em;\n height: 0.5em;\n border-radius: 50%;\n background: var(--event);\n }\n\n &-time {\n flex: none;\n font-variant-numeric: tabular-nums;\n color: var(--text-dark);\n }\n\n &-more {\n align-self: center;\n margin: 0 0.25em;\n padding: 0 0.4em;\n border-radius: var(--custom-calendar-event-radius);\n font-size: 0.75em;\n font-weight: 600;\n white-space: nowrap;\n color: var(--text-dark);\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n pointer-events: auto;\n\n &:hover {\n background: var(--background-accent-light);\n }\n }\n\n &-list {\n display: flex;\n flex-direction: column;\n gap: 0.25em;\n width: 18em;\n max-width: 100%;\n\n &-title {\n padding: 0.25em 0.625em;\n font-size: 0.8125em;\n font-weight: 600;\n color: var(--text-dark);\n }\n\n /* Scrolls inside the popover rather than growing it past the screen. */\n &-events {\n max-height: 18em;\n }\n\n &-create {\n align-self: flex-start;\n margin: 0.25em 0.625em 0.125em;\n }\n }\n}\n"],"mappings":""}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{renderIcon as e}from"../../../utils/renderIcon.mjs";import{dateToDay as t}from"../../../utils/day.mjs";import{CalendarView as n}from"../../calendar.types.mjs";import{MINUTES_PER_DAY as r,addDays as i,atMinutes as a,dayDiff as o,endAfter as s,isSameDay as c,minutesOfDay as l,periodRange as u,shownDays as d,stepDate as ee}from"../../dates.mjs";import{formatClockRange as te,formatDayNumber as ne,formatHour as re,formatLongDate as ie,formatTimeRange as ae,formatWeekday as oe}from"../../format.mjs";import{eventEnd as f,isAllDayLike as se,limitLanes as ce,packDay as le,packLanes as ue}from"../../layout.mjs";import{clamp as p,pageStep as de,snap as fe}from"../../gesture.mjs";import{useGestures as pe}from"../../useGestures.mjs";import{usePager as me}from"../../usePager.mjs";import m from"../../pager.module.mjs";import h from"./timeGrid.module.mjs";import{useEffect as he,useLayoutEffect as ge,useRef as g,useState as _}from"react";import v from"classnames";import{faChevronDown as _e}from"@fortawesome/free-solid-svg-icons";import{Fragment as ve,jsx as y,jsxs as b}from"react/jsx-runtime";var ye=[-1,0,1],be=Array.from({length:23},(e,t)=>t+1),xe=3,Se=45,Ce=7,x=4;function we(){let[e,t]=_(()=>new Date);return he(()=>{let e;function n(){e=setTimeout(()=>{t(new Date),n()},6e4-Date.now()%6e4)}return n(),()=>clearTimeout(e)},[]),e}function Te({scroller:e,head:t,body:n},r,i,a,o){let s=r.current?.base??n.getBoundingClientRect().height/24;if(!s)return;let c=Math.max((e.clientHeight-t.offsetHeight)/24,1),l=p(i,Math.min(c,s),s*x);r.current={hour:l,base:s},e.style.setProperty(`--custom-calendar-hour-height`,`${l}px`);let u=e.getBoundingClientRect().top;e.scrollTop=n.offsetTop+a*l-(o-u)}function S({events:x,date:S,view:C,locale:w,weekStartsOn:Ee,slotMinutes:T,hidden:E,scrollToHour:De,text:D,onDateChange:Oe,onOpenDay:O,onEventClick:k,onEventChange:A,onSlotCreate:j,renderEvent:M,classNames:N,slotStyles:P,zoomRef:F}){let I=g(null),L=g(null),R=g(null),z=g(null),B=g(null),ke=g(null),V=g(x),H=g(null),[U,Ae]=_(null),[W,je]=_(!1),G=we(),K=C===n.Day?1:7,q=u(C,S,Ee).start,J=d(q,K,E),Me=U?V.current:x,Y=me(t(q),e=>Oe(ee(C,S,e,E)),()=>I.current);function X(){let e=I.current,t=L.current,n=R.current;return e&&t&&n?{scroller:e,head:t,body:n}:null}ge(()=>{let e=I.current,t=R.current;if(!e||!t)return;let n=t.offsetHeight/24;if(!n)return;let r=new Date,i=J.some(e=>c(e,r)),a=De??(i?Math.max(0,l(r)/60-1):Ce);e.scrollTop=p(a,0,24)*n},[]),he(()=>{let e=I.current;if(!e)return;function t(e){if(!e.ctrlKey)return;let t=X();if(!t)return;e.preventDefault();let n=t.body.getBoundingClientRect(),r=n.height/24;r&&Te(t,F,r*Math.exp(-e.deltaY*.01),(e.clientY-n.top)/r,e.clientY)}return e.addEventListener(`wheel`,t,{passive:!1}),()=>e.removeEventListener(`wheel`,t)},[F]);function Ne(e){let t=z.current;if(!t)return null;let n=t.getBoundingClientRect();if(!n.width||!n.height)return null;let i=p(Math.floor((e.x-n.left)/n.width*J.length),0,J.length-1);return{day:o(q,J[i]),minutes:p((e.y-n.top)/n.height*r,0,r)}}function Pe(e){return o(q,e)*r+l(e)}function Z(e,t){let n=Ne(t);if(!n)return null;let o=K*r;if(e.kind===`create`){let t=Math.floor(e.anchor/T)*T,[o,c]=n.minutes>=t?[t,Math.max(Math.ceil(n.minutes/T)*T,t+T)]:[Math.floor(n.minutes/T)*T,t+T],l=i(q,e.day),u=a(l,o);return{start:u,end:s(u,a(l,Math.min(c,r)),c-o)}}let c=n.day*r+n.minutes,l=Pe(e.event.start);if(e.kind===`move`){let t=p(fe(c-e.grab,T),Math.min(l,0),o-T),n=a(q,t),r=f(e.event).getTime()-e.event.start.getTime();return{start:n,end:new Date(n.getTime()+r)}}let u=p(fe(c,T),l+T,Math.max(o,l+T)),d=e.event.start;return{start:d,end:s(d,a(q,u),u-l)}}function Q(e){B.current=e,Ae(e)}function Fe(e){return x.find(t=>String(t.id)===e.dataset.calEvent)}pe(I,{onPress:Y.finish,canSwipe:()=>!0,onSwipeMove:Y.move,onSwipeEnd:(e,t)=>Y.settle(de(e,Y.width(),t)),dragFrom:(e,t)=>{if(!z.current?.contains(e))return null;let n=Ne(t);if(!n)return null;let a=e.closest(`[data-cal-event]`);if(a){let t=A?Fe(a):void 0;if(!t||t.readOnly)return null;let i={start:t.start,end:f(t)};return e.closest(`[data-cal-resize]`)?{kind:`resize`,event:t,...i}:{kind:`move`,event:t,grab:n.day*r+n.minutes-Pe(t.start),...i}}if(!j)return null;let o=i(q,n.day);return{kind:`create`,day:n.day,anchor:n.minutes,start:o,end:o}},onDragStart:(e,t)=>{V.current=x,Q({...e,...Z(e,t)})},onDragMove:e=>{let t=B.current,n=t&&Z(t,e);t&&n&&(n.start.getTime()!==t.start.getTime()||n.end.getTime()!==t.end.getTime())&&Q({...t,...n})},onDragEnd:e=>{let t=B.current;if(Q(null),!t)return;let{start:n,end:r}=Z(t,e)??t;if(t.kind===`create`){j?.({start:n,end:r,allDay:!1},Le(t.day,n,r));return}(n.getTime()!==t.event.start.getTime()||r.getTime()!==f(t.event).getTime())&&A?.({event:t.event,start:n,end:r})},onDragCancel:()=>Q(null),onPinchStart:(e,t)=>{let n=R.current;if(!n)return;let r=n.getBoundingClientRect(),i=r.height/24;i&&(H.current={hour:i,anchorHour:(e.y-r.top)/i,distance:t})},onPinchMove:(e,t)=>{let n=H.current,r=X();n&&r&&n.distance&&Te(r,F,n.hour*t/n.distance,n.anchorHour,e.y)},onPinchEnd:()=>{H.current=null},autoScroll:()=>{let e=I.current,t=L.current;if(!e||!t)return null;let n=e.getBoundingClientRect();return{element:e,top:n.top+t.offsetHeight,bottom:n.bottom}}});function Ie(e,t){if(!j||e.target.closest(`[data-cal-event]`))return;let n=e.currentTarget.getBoundingClientRect();if(!n.height)return;let i=(e.clientY-n.top)/n.height*r,s=p(Math.floor(i/T)*T,0,r-T),c=a(t,s),l=new Date(c.getTime()+Math.max(60,T)*6e4),u=a(t,r),d={start:c,end:l<u?l:u,allDay:!1};j(d,Le(o(q,t),d.start,d.end))}function Le(e,t,n){let a=ke.current;if(!a)return I.current;let s=i(q,e+1),c=l(t),u=n>=s?r:l(n),d=Math.max(J.findIndex(t=>o(q,t)===e),0);return a.style.left=`${d/J.length*100}%`,a.style.width=`${100/J.length}%`,a.style.top=`${c/r*100}%`,a.style.height=`${Math.max(u-c,0)/r*100}%`,a}function Re(e){let{event:t}=e;return y(`button`,{type:`button`,"data-cal-event":String(t.id),className:v(h.timeGridBar,e.continuesBefore&&h.timeGridBarContinuesBefore,e.continuesAfter&&h.timeGridBarContinuesAfter,N?.event),style:{"--event-color":t.color,gridColumn:`${e.start+1} / span ${e.span}`,gridRow:e.lane+1,...P?.event},"aria-label":`${t.title}, ${D.allDay}`,onClick:e=>k?.(t,e.currentTarget),children:y(`span`,{className:h.timeGridBarTitle,"aria-hidden":!0,children:M?M(t,{singleLine:!0}):t.title})},t.id)}function ze(e){let{event:t}=e,n=e.bottom-e.top,i=n<Se,a=ae(t.start,f(t),w),o=!!A&&!t.readOnly&&!e.continuesAfter,s=U&&U.kind!==`create`&&U.event===t;return b(`button`,{type:`button`,"data-cal-event":String(t.id),"aria-label":`${t.title}, ${a}`,className:v(h.timeGridEvent,i&&h.timeGridEventShort,n<15&&h.timeGridEventBrief,e.continuesBefore&&h.timeGridEventContinuesBefore,e.continuesAfter&&h.timeGridEventContinuesAfter,(k||o)&&h.timeGridEventInteractive,s&&h.timeGridEventDragged,N?.event),style:{"--event-color":t.color,top:`${e.top/r*100}%`,"--span":`${n/r*100}%`,left:`calc(var(--column-width) * ${e.column/e.columns})`,width:`calc(var(--column-width) * ${e.span/e.columns})`,...P?.event},onClick:e=>k?.(t,e.currentTarget),children:[y(`span`,{className:h.timeGridEventTitle,"aria-hidden":!0,children:M?M(t,{singleLine:i}):t.title}),y(`span`,{className:h.timeGridEventTime,"aria-hidden":!0,children:te(t.start,f(t),w)}),o&&y(`span`,{"data-cal-resize":!0,className:h.timeGridResize,"aria-hidden":!0})]},t.id)}function Be(e){if(!U)return null;let t=e,n=i(e,1);if(U.end<=t&&U.start<t||U.start>=n)return null;let a=U.start<t?0:l(U.start),o=U.end>=n?r:l(U.end),s=U.kind===`create`?void 0:U.event.color,c=U.kind===`create`?null:U.event.title;return b(`div`,{className:h.timeGridPreview,style:{"--event-color":s,top:`${a/r*100}%`,height:`${Math.max(o-a,15)/r*100}%`},"aria-hidden":!0,children:[c&&y(`span`,{className:h.timeGridEventTitle,children:c}),y(`span`,{className:h.timeGridPreviewTime,children:te(U.start,U.end,w)})]})}let $=ye.map(e=>{let t=u(C,ee(C,S,e,E),Ee).start,n=d(t,K,E),r=ue(Me,n,se);return{step:e,start:t,dates:n,lanes:W?{visible:r,moreLane:0,hidden:n.map(()=>0)}:ce(r,n.length,xe)}}),Ve=$[1].lanes.hidden.some(e=>e>0),He=e=>v(m.pagerPane,e===-1&&m.pagerPanePrev,e===1&&m.pagerPaneNext);return b(`div`,{ref:I,tabIndex:-1,className:h.timeGrid,style:{"--days":J.length,"--custom-calendar-hour-height":F.current?`${F.current.hour}px`:void 0},children:[b(`div`,{ref:L,className:h.timeGridHead,children:[y(`div`,{className:h.timeGridCorner,children:(Ve||W)&&y(`button`,{type:`button`,className:v(h.timeGridToggle,W&&h.timeGridToggleOpen),"aria-label":D.allDay,"aria-expanded":W,onClick:()=>je(e=>!e),children:e(_e)})}),y(`div`,{className:m.pagerViewport,children:y(`div`,{ref:Y.trackRef,className:m.pagerTrack,children:$.map(({step:e,start:n,dates:r,lanes:i})=>b(`div`,{className:v(He(e),h.timeGridHeadPane),inert:e!==0,"aria-hidden":e!==0||void 0,children:[r.map(e=>{let n=c(e,G),r=b(ve,{children:[y(`span`,{className:h.timeGridWeekday,children:oe(e,w,`short`)}),y(`span`,{className:v(h.timeGridDayNumber,n&&h.timeGridDayNumberToday),children:ne(e,w)})]}),i={className:v(h.timeGridDayHeader,N?.dayHeader),style:P?.dayHeader,"aria-current":n?`date`:void 0};return K>1&&O?y(`button`,{type:`button`,...i,className:v(i.className,h.timeGridDayHeaderLink),"aria-label":ie(e,w),onClick:()=>O(e),children:r},t(e)):y(`div`,{...i,children:r},t(e))}),b(`div`,{className:h.timeGridAllDay,"aria-label":D.allDay,role:`group`,children:[i.visible.map(Re),i.hidden.map((e,t)=>e>0&&y(`div`,{"aria-hidden":!0,className:h.timeGridMore,style:{gridColumn:t+1,gridRow:i.moreLane+1},onClick:()=>je(!0),children:D.more(e)},`more-${t}`))]})]},t(n)))})})]}),b(`div`,{ref:R,className:h.timeGridBody,children:[y(`div`,{className:h.timeGridGutter,"aria-hidden":!0,children:be.map(e=>y(`span`,{className:h.timeGridHour,style:{top:`${e/24*100}%`},children:re(e,w)},e))}),y(`div`,{className:m.pagerViewport,children:y(`div`,{ref:Y.trackRef,className:m.pagerTrack,children:$.map(({step:e,start:n,dates:r})=>b(`div`,{ref:e===0?z:void 0,className:v(He(e),h.timeGridBodyPane),inert:e!==0,"aria-hidden":e!==0||void 0,children:[r.map(n=>{let r=c(n,G);return b(`div`,{role:`group`,"aria-label":ie(n,w),"data-cal-column":t(n),className:v(h.timeGridColumn,r&&h.timeGridColumnToday,j&&h.timeGridColumnCreatable,N?.cell),style:P?.cell,onClick:e=>Ie(e,n),children:[le(Me,n).map(ze),r&&y(`div`,{className:h.timeGridNow,style:{top:`${l(G)/1440*100}%`},"aria-hidden":!0}),e===0&&Be(n)]},t(n))}),e===0&&y(`div`,{ref:ke,className:h.timeGridSlot,"aria-hidden":!0})]},t(n)))})})]})]})}export{S as default};
|
|
2
|
+
//# sourceMappingURL=timeGrid.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeGrid.mjs","names":[],"sources":["../../../../../../package/common/calendar/components/timeGrid/timeGrid.tsx"],"sourcesContent":["import {\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type MouseEvent,\n type ReactElement,\n type RefObject,\n} from 'react';\nimport cx from 'classnames';\nimport { faChevronDown } from '@fortawesome/free-solid-svg-icons';\n\nimport { renderIcon } from 'components/common/utils/renderIcon';\nimport { CalendarView, type CalendarEvent } from '../../calendar.types';\nimport {\n addDays,\n atMinutes,\n dayDiff,\n dateToDay,\n endAfter,\n isSameDay,\n MINUTES_PER_DAY,\n minutesOfDay,\n periodRange,\n shownDays,\n stepDate,\n} from '../../dates';\nimport {\n formatClockRange,\n formatDayNumber,\n formatHour,\n formatLongDate,\n formatTimeRange,\n formatWeekday,\n} from '../../format';\nimport { clamp, pageStep, snap } from '../../gesture';\nimport {\n BRIEF_EVENT_MINUTES,\n eventEnd,\n isAllDayLike,\n limitLanes,\n packDay,\n packLanes,\n type LaneBar,\n type LimitedLanes,\n type TimedBox,\n} from '../../layout';\nimport { useGestures, type GesturePoint } from '../../useGestures';\nimport { usePager } from '../../usePager';\nimport type { TimeDrag, TimeGridProps, TimeGridZoom } from './timeGrid.types';\n\nimport pagerStyles from '../../pager.module.pcss';\nimport styles from './timeGrid.module.pcss';\n\nconst STEPS = [-1, 0, 1] as const;\nconst HOURS = Array.from({ length: 23 }, (_, i) => i + 1);\nconst ALL_DAY_LANES = 3;\n/** Below this an event is drawn on one line, its time after its title. */\nconst SHORT_EVENT_MINUTES = 45;\n/** Hour first scrolled to when today is not in view. */\nconst DEFAULT_SCROLL_HOUR = 7;\n/** Deepest zoom, as a multiple of the theme's hour height. */\nconst MAX_ZOOM = 4;\n\n/** The current time, updated on each minute boundary: it also carries the now-line past midnight. */\nfunction useNow(): Date {\n const [now, setNow] = useState(() => new Date());\n useEffect(() => {\n let timer: ReturnType<typeof setTimeout>;\n function schedule() {\n timer = setTimeout(\n () => {\n setNow(new Date());\n schedule();\n },\n 60_000 - (Date.now() % 60_000),\n );\n }\n schedule();\n return () => clearTimeout(timer);\n }, []);\n return now;\n}\n\ninterface ZoomElements {\n scroller: HTMLElement;\n head: HTMLElement;\n body: HTMLElement;\n}\n\n/**\n * Sets the hour height, and scrolls so `anchorHour` stays under `clientY`: zooming pivots on the\n * fingers or the cursor instead of the top of the day.\n */\nfunction zoomTo(\n { scroller, head, body }: ZoomElements,\n zoomRef: RefObject<TimeGridZoom | null>,\n hour: number,\n anchorHour: number,\n clientY: number,\n) {\n const base = zoomRef.current?.base ?? body.getBoundingClientRect().height / 24;\n if (!base) return;\n // Zoomed out, the whole day fits exactly.\n const min = Math.max((scroller.clientHeight - head.offsetHeight) / 24, 1);\n const next = clamp(hour, Math.min(min, base), base * MAX_ZOOM);\n zoomRef.current = { hour: next, base };\n scroller.style.setProperty('--custom-calendar-hour-height', `${next}px`);\n const top = scroller.getBoundingClientRect().top;\n scroller.scrollTop = body.offsetTop + anchorHour * next - (clientY - top);\n}\n\nfunction TimeGrid<E extends CalendarEvent>({\n events,\n date,\n view,\n locale,\n weekStartsOn,\n slotMinutes,\n hidden,\n scrollToHour,\n text,\n onDateChange,\n onOpenDay,\n onEventClick,\n onEventChange,\n onSlotCreate,\n renderEvent,\n classNames,\n slotStyles,\n zoomRef,\n}: TimeGridProps<E>): ReactElement {\n const scrollerRef = useRef<HTMLDivElement>(null);\n const headRef = useRef<HTMLDivElement>(null);\n const bodyRef = useRef<HTMLDivElement>(null);\n const currentRef = useRef<HTMLDivElement>(null);\n const dragRef = useRef<TimeDrag<E> | null>(null);\n const slotRef = useRef<HTMLDivElement>(null);\n const snapshot = useRef(events);\n const pinchRef = useRef<{ hour: number; anchorHour: number; distance: number } | null>(null);\n const [drag, setDrag] = useState<TimeDrag<E> | null>(null);\n const [allDayOpen, setAllDayOpen] = useState(false);\n const now = useNow();\n\n const periodDays = view === CalendarView.Day ? 1 : 7;\n const rangeStart = periodRange(view, date, weekStartsOn).start;\n const columns = shownDays(rangeStart, periodDays, hidden);\n // While a drag runs, the grid renders the events as they were when it began: the touch that\n // started it keeps targeting the element it landed on, and iOS stops delivering its moves if\n // a re-render replaces that element.\n const shown = drag ? snapshot.current : events;\n\n const pager = usePager(\n dateToDay(rangeStart),\n (step) => onDateChange(stepDate(view, date, step, hidden)),\n () => scrollerRef.current,\n );\n\n function zoomElements(): ZoomElements | null {\n const scroller = scrollerRef.current;\n const head = headRef.current;\n const body = bodyRef.current;\n return scroller && head && body ? { scroller, head, body } : null;\n }\n\n // Once, on mount: paging keeps the scroll position, so the same hours stay under the eye.\n useLayoutEffect(() => {\n const scroller = scrollerRef.current;\n const body = bodyRef.current;\n if (!scroller || !body) return;\n const hour = body.offsetHeight / 24;\n if (!hour) return;\n const current = new Date();\n const todayShown = columns.some((day) => isSameDay(day, current));\n const target = scrollToHour ?? (todayShown ? Math.max(0, minutesOfDay(current) / 60 - 1) : DEFAULT_SCROLL_HOUR);\n scroller.scrollTop = clamp(target, 0, 24) * hour;\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n const scroller = scrollerRef.current;\n if (!scroller) return;\n // Trackpad pinches arrive as a wheel with Ctrl held (Chromium, Firefox); Safari sends\n // `gesturechange` instead, and there the trackpad zooms the page as usual.\n function onWheel(event: WheelEvent) {\n if (!event.ctrlKey) return;\n const elements = zoomElements();\n if (!elements) return;\n event.preventDefault();\n const rect = elements.body.getBoundingClientRect();\n const hour = rect.height / 24;\n if (!hour) return;\n zoomTo(\n elements,\n zoomRef,\n hour * Math.exp(-event.deltaY * 0.01),\n (event.clientY - rect.top) / hour,\n event.clientY,\n );\n }\n scroller.addEventListener('wheel', onWheel, { passive: false });\n return () => scroller.removeEventListener('wheel', onWheel);\n // zoomElements only reads refs.\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [zoomRef]);\n\n /** `day` counts from the period's first day, hidden ones included, so it adds up to a date. */\n function pointAt(point: GesturePoint): { day: number; minutes: number } | null {\n const pane = currentRef.current;\n if (!pane) return null;\n const rect = pane.getBoundingClientRect();\n if (!rect.width || !rect.height) return null;\n const column = clamp(Math.floor(((point.x - rect.left) / rect.width) * columns.length), 0, columns.length - 1);\n return {\n day: dayDiff(rangeStart, columns[column]),\n minutes: clamp(((point.y - rect.top) / rect.height) * MINUTES_PER_DAY, 0, MINUTES_PER_DAY),\n };\n }\n\n /** Wall-clock minutes from the first shown midnight: negative before it. */\n function minutesFromStart(value: Date): number {\n return dayDiff(rangeStart, value) * MINUTES_PER_DAY + minutesOfDay(value);\n }\n\n function preview(current: TimeDrag<E>, point: GesturePoint): { start: Date; end: Date } | null {\n const at = pointAt(point);\n if (!at) return null;\n const limit = periodDays * MINUTES_PER_DAY;\n\n if (current.kind === 'create') {\n const anchor = Math.floor(current.anchor / slotMinutes) * slotMinutes;\n const [from, to] =\n at.minutes >= anchor\n ? [anchor, Math.max(Math.ceil(at.minutes / slotMinutes) * slotMinutes, anchor + slotMinutes)]\n : [Math.floor(at.minutes / slotMinutes) * slotMinutes, anchor + slotMinutes];\n const day = addDays(rangeStart, current.day);\n const start = atMinutes(day, from);\n return { start, end: endAfter(start, atMinutes(day, Math.min(to, MINUTES_PER_DAY)), to - from) };\n }\n\n const pointer = at.day * MINUTES_PER_DAY + at.minutes;\n const eventStart = minutesFromStart(current.event.start);\n if (current.kind === 'move') {\n const from = clamp(snap(pointer - current.grab, slotMinutes), Math.min(eventStart, 0), limit - slotMinutes);\n const start = atMinutes(rangeStart, from);\n // The real length, not the wall-clock one, so a move across a clock change keeps it.\n const length = eventEnd(current.event).getTime() - current.event.start.getTime();\n return { start, end: new Date(start.getTime() + length) };\n }\n const to = clamp(snap(pointer, slotMinutes), eventStart + slotMinutes, Math.max(limit, eventStart + slotMinutes));\n const start = current.event.start;\n return { start, end: endAfter(start, atMinutes(rangeStart, to), to - eventStart) };\n }\n\n function setDragState(next: TimeDrag<E> | null) {\n dragRef.current = next;\n setDrag(next);\n }\n\n function findEvent(element: HTMLElement): E | undefined {\n return events.find((candidate) => String(candidate.id) === element.dataset.calEvent);\n }\n\n useGestures<TimeDrag<E>>(scrollerRef, {\n onPress: pager.finish,\n canSwipe: () => true,\n onSwipeMove: pager.move,\n onSwipeEnd: (dx, velocity) => pager.settle(pageStep(dx, pager.width(), velocity)),\n dragFrom: (target, point) => {\n if (!currentRef.current?.contains(target)) return null;\n const at = pointAt(point);\n if (!at) return null;\n const element = target.closest<HTMLElement>('[data-cal-event]');\n if (element) {\n const event = onEventChange ? findEvent(element) : undefined;\n if (!event || event.readOnly) return null;\n const current = { start: event.start, end: eventEnd(event) };\n if (target.closest('[data-cal-resize]')) return { kind: 'resize', event, ...current };\n const grab = at.day * MINUTES_PER_DAY + at.minutes - minutesFromStart(event.start);\n return { kind: 'move', event, grab, ...current };\n }\n if (!onSlotCreate) return null;\n const day = addDays(rangeStart, at.day);\n return { kind: 'create', day: at.day, anchor: at.minutes, start: day, end: day };\n },\n onDragStart: (started, point) => {\n snapshot.current = events;\n setDragState({ ...started, ...preview(started, point) });\n },\n onDragMove: (point) => {\n const current = dragRef.current;\n const next = current && preview(current, point);\n if (!current || !next) return;\n if (next.start.getTime() === current.start.getTime() && next.end.getTime() === current.end.getTime()) return;\n setDragState({ ...current, ...next });\n },\n onDragEnd: (point) => {\n const current = dragRef.current;\n setDragState(null);\n if (!current) return;\n const { start, end } = preview(current, point) ?? current;\n if (current.kind === 'create') {\n onSlotCreate?.({ start, end, allDay: false }, markSlot(current.day, start, end));\n return;\n }\n const unchanged =\n start.getTime() === current.event.start.getTime() && end.getTime() === eventEnd(current.event).getTime();\n if (!unchanged) onEventChange?.({ event: current.event, start, end });\n },\n onDragCancel: () => setDragState(null),\n onPinchStart: (center, distance) => {\n const body = bodyRef.current;\n if (!body) return;\n const rect = body.getBoundingClientRect();\n const hour = rect.height / 24;\n if (!hour) return;\n pinchRef.current = { hour, anchorHour: (center.y - rect.top) / hour, distance };\n },\n onPinchMove: (center, distance) => {\n const pinch = pinchRef.current;\n const elements = zoomElements();\n if (!pinch || !elements || !pinch.distance) return;\n zoomTo(elements, zoomRef, (pinch.hour * distance) / pinch.distance, pinch.anchorHour, center.y);\n },\n onPinchEnd: () => {\n pinchRef.current = null;\n },\n autoScroll: () => {\n const scroller = scrollerRef.current;\n const head = headRef.current;\n if (!scroller || !head) return null;\n const rect = scroller.getBoundingClientRect();\n // The sticky head covers the top of the scroller, so the zone starts below it.\n return { element: scroller, top: rect.top + head.offsetHeight, bottom: rect.bottom };\n },\n });\n\n function handleColumnClick(clickEvent: MouseEvent<HTMLDivElement>, day: Date) {\n if (!onSlotCreate || (clickEvent.target as Element).closest('[data-cal-event]')) return;\n const rect = clickEvent.currentTarget.getBoundingClientRect();\n if (!rect.height) return;\n const minutes = ((clickEvent.clientY - rect.top) / rect.height) * MINUTES_PER_DAY;\n const from = clamp(Math.floor(minutes / slotMinutes) * slotMinutes, 0, MINUTES_PER_DAY - slotMinutes);\n const start = atMinutes(day, from);\n // Real time, not the clock: across a clock change an hour on the clock is none or two.\n const end = new Date(start.getTime() + Math.max(60, slotMinutes) * 60_000);\n const midnight = atMinutes(day, MINUTES_PER_DAY);\n const slot = { start, end: end < midnight ? end : midnight, allDay: false };\n onSlotCreate(slot, markSlot(dayDiff(rangeStart, day), slot.start, slot.end));\n }\n\n /**\n * Moves the invisible box over a new slot and returns it: the anchor `onSlotCreate` hands out,\n * so the app can open its editor right next to the slot, as `onEventClick` lets it for an event.\n */\n function markSlot(dayIndex: number, start: Date, end: Date): HTMLElement {\n const marker = slotRef.current;\n if (!marker) return scrollerRef.current!;\n const next = addDays(rangeStart, dayIndex + 1);\n const top = minutesOfDay(start);\n const bottom = end >= next ? MINUTES_PER_DAY : minutesOfDay(end);\n const column = Math.max(\n columns.findIndex((day) => dayDiff(rangeStart, day) === dayIndex),\n 0,\n );\n marker.style.left = `${(column / columns.length) * 100}%`;\n marker.style.width = `${100 / columns.length}%`;\n marker.style.top = `${(top / MINUTES_PER_DAY) * 100}%`;\n // Never upside down: on the day the clocks go back, a slot can end on an earlier clock time.\n marker.style.height = `${(Math.max(bottom - top, 0) / MINUTES_PER_DAY) * 100}%`;\n return marker;\n }\n\n function renderAllDayBar(bar: LaneBar<E>) {\n const { event } = bar;\n return (\n <button\n key={event.id}\n type='button'\n data-cal-event={String(event.id)}\n className={cx(\n styles.timeGridBar,\n bar.continuesBefore && styles.timeGridBarContinuesBefore,\n bar.continuesAfter && styles.timeGridBarContinuesAfter,\n classNames?.event,\n )}\n style={\n {\n '--event-color': event.color,\n gridColumn: `${bar.start + 1} / span ${bar.span}`,\n gridRow: bar.lane + 1,\n ...slotStyles?.event,\n } as CSSProperties\n }\n aria-label={`${event.title}, ${text.allDay}`}\n onClick={(clickEvent) => onEventClick?.(event, clickEvent.currentTarget)}\n >\n <span className={styles.timeGridBarTitle} aria-hidden>\n {renderEvent ? renderEvent(event, { singleLine: true }) : event.title}\n </span>\n </button>\n );\n }\n\n function renderBox(box: TimedBox<E>) {\n const { event } = box;\n const minutes = box.bottom - box.top;\n const short = minutes < SHORT_EVENT_MINUTES;\n const when = formatTimeRange(event.start, eventEnd(event), locale);\n const resizable = Boolean(onEventChange) && !event.readOnly && !box.continuesAfter;\n const dragged = drag && drag.kind !== 'create' && drag.event === event;\n return (\n <button\n key={event.id}\n type='button'\n data-cal-event={String(event.id)}\n aria-label={`${event.title}, ${when}`}\n className={cx(\n styles.timeGridEvent,\n short && styles.timeGridEventShort,\n minutes < BRIEF_EVENT_MINUTES && styles.timeGridEventBrief,\n box.continuesBefore && styles.timeGridEventContinuesBefore,\n box.continuesAfter && styles.timeGridEventContinuesAfter,\n (onEventClick || resizable) && styles.timeGridEventInteractive,\n dragged && styles.timeGridEventDragged,\n classNames?.event,\n )}\n style={\n {\n '--event-color': event.color,\n top: `${(box.top / MINUTES_PER_DAY) * 100}%`,\n '--span': `${(minutes / MINUTES_PER_DAY) * 100}%`,\n left: `calc(var(--column-width) * ${box.column / box.columns})`,\n width: `calc(var(--column-width) * ${box.span / box.columns})`,\n ...slotStyles?.event,\n } as CSSProperties\n }\n onClick={(clickEvent) => onEventClick?.(event, clickEvent.currentTarget)}\n >\n <span className={styles.timeGridEventTitle} aria-hidden>\n {renderEvent ? renderEvent(event, { singleLine: short }) : event.title}\n </span>\n <span className={styles.timeGridEventTime} aria-hidden>\n {formatClockRange(event.start, eventEnd(event), locale)}\n </span>\n {resizable && <span data-cal-resize className={styles.timeGridResize} aria-hidden />}\n </button>\n );\n }\n\n function renderPreview(day: Date) {\n if (!drag) return null;\n const dayStart = day;\n const next = addDays(day, 1);\n if (drag.end <= dayStart && drag.start < dayStart) return null;\n if (drag.start >= next) return null;\n const top = drag.start < dayStart ? 0 : minutesOfDay(drag.start);\n const bottom = drag.end >= next ? MINUTES_PER_DAY : minutesOfDay(drag.end);\n const color = drag.kind === 'create' ? undefined : drag.event.color;\n const title = drag.kind === 'create' ? null : drag.event.title;\n return (\n <div\n className={styles.timeGridPreview}\n style={\n {\n '--event-color': color,\n top: `${(top / MINUTES_PER_DAY) * 100}%`,\n height: `${(Math.max(bottom - top, 15) / MINUTES_PER_DAY) * 100}%`,\n } as CSSProperties\n }\n aria-hidden\n >\n {title && <span className={styles.timeGridEventTitle}>{title}</span>}\n <span className={styles.timeGridPreviewTime}>{formatClockRange(drag.start, drag.end, locale)}</span>\n </div>\n );\n }\n\n const panes = STEPS.map((step) => {\n const start = periodRange(view, stepDate(view, date, step, hidden), weekStartsOn).start;\n const dates = shownDays(start, periodDays, hidden);\n const allDay = packLanes(shown, dates, isAllDayLike);\n const lanes: LimitedLanes<E> = allDayOpen\n ? { visible: allDay, moreLane: 0, hidden: dates.map(() => 0) }\n : limitLanes(allDay, dates.length, ALL_DAY_LANES);\n return { step, start, dates, lanes };\n });\n const hasHidden = panes[1].lanes.hidden.some((count) => count > 0);\n const paneClass = (step: number) =>\n cx(pagerStyles.pagerPane, step === -1 && pagerStyles.pagerPanePrev, step === 1 && pagerStyles.pagerPaneNext);\n\n return (\n <div\n ref={scrollerRef}\n tabIndex={-1}\n className={styles.timeGrid}\n style={\n {\n '--days': columns.length,\n '--custom-calendar-hour-height': zoomRef.current ? `${zoomRef.current.hour}px` : undefined,\n } as CSSProperties\n }\n >\n <div ref={headRef} className={styles.timeGridHead}>\n <div className={styles.timeGridCorner}>\n {(hasHidden || allDayOpen) && (\n <button\n type='button'\n className={cx(styles.timeGridToggle, allDayOpen && styles.timeGridToggleOpen)}\n aria-label={text.allDay}\n aria-expanded={allDayOpen}\n onClick={() => setAllDayOpen((open) => !open)}\n >\n {renderIcon(faChevronDown)}\n </button>\n )}\n </div>\n <div className={pagerStyles.pagerViewport}>\n <div ref={pager.trackRef} className={pagerStyles.pagerTrack}>\n {panes.map(({ step, start, dates, lanes }) => (\n <div\n key={dateToDay(start)}\n className={cx(paneClass(step), styles.timeGridHeadPane)}\n inert={step !== 0}\n aria-hidden={step !== 0 || undefined}\n >\n {dates.map((day) => {\n const isToday = isSameDay(day, now);\n const content = (\n <>\n <span className={styles.timeGridWeekday}>{formatWeekday(day, locale, 'short')}</span>\n <span className={cx(styles.timeGridDayNumber, isToday && styles.timeGridDayNumberToday)}>\n {formatDayNumber(day, locale)}\n </span>\n </>\n );\n const shared = {\n className: cx(styles.timeGridDayHeader, classNames?.dayHeader),\n style: slotStyles?.dayHeader,\n 'aria-current': isToday ? ('date' as const) : undefined,\n };\n return periodDays > 1 && onOpenDay ? (\n <button\n key={dateToDay(day)}\n type='button'\n {...shared}\n className={cx(shared.className, styles.timeGridDayHeaderLink)}\n aria-label={formatLongDate(day, locale)}\n onClick={() => onOpenDay(day)}\n >\n {content}\n </button>\n ) : (\n <div key={dateToDay(day)} {...shared}>\n {content}\n </div>\n );\n })}\n <div className={styles.timeGridAllDay} aria-label={text.allDay} role='group'>\n {lanes.visible.map(renderAllDayBar)}\n {lanes.hidden.map(\n (count, column) =>\n count > 0 && (\n <div\n key={`more-${column}`}\n aria-hidden\n className={styles.timeGridMore}\n style={{ gridColumn: column + 1, gridRow: lanes.moreLane + 1 }}\n onClick={() => setAllDayOpen(true)}\n >\n {text.more(count)}\n </div>\n ),\n )}\n </div>\n </div>\n ))}\n </div>\n </div>\n </div>\n\n <div ref={bodyRef} className={styles.timeGridBody}>\n <div className={styles.timeGridGutter} aria-hidden>\n {HOURS.map((hour) => (\n <span key={hour} className={styles.timeGridHour} style={{ top: `${(hour / 24) * 100}%` }}>\n {formatHour(hour, locale)}\n </span>\n ))}\n </div>\n <div className={pagerStyles.pagerViewport}>\n <div ref={pager.trackRef} className={pagerStyles.pagerTrack}>\n {panes.map(({ step, start, dates }) => (\n <div\n key={dateToDay(start)}\n ref={step === 0 ? currentRef : undefined}\n className={cx(paneClass(step), styles.timeGridBodyPane)}\n inert={step !== 0}\n aria-hidden={step !== 0 || undefined}\n >\n {dates.map((day) => {\n const isToday = isSameDay(day, now);\n return (\n <div\n key={dateToDay(day)}\n role='group'\n aria-label={formatLongDate(day, locale)}\n data-cal-column={dateToDay(day)}\n className={cx(\n styles.timeGridColumn,\n isToday && styles.timeGridColumnToday,\n onSlotCreate && styles.timeGridColumnCreatable,\n classNames?.cell,\n )}\n style={slotStyles?.cell}\n onClick={(clickEvent) => handleColumnClick(clickEvent, day)}\n >\n {packDay(shown, day).map(renderBox)}\n {isToday && (\n <div\n className={styles.timeGridNow}\n style={{ top: `${(minutesOfDay(now) / MINUTES_PER_DAY) * 100}%` }}\n aria-hidden\n />\n )}\n {step === 0 && renderPreview(day)}\n </div>\n );\n })}\n {step === 0 && <div ref={slotRef} className={styles.timeGridSlot} aria-hidden />}\n </div>\n ))}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nexport default TimeGrid;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";var e=`timeGrid_eQt1f`,t=`timeGrid-head_QeMAH`,n=`timeGrid-corner_ass6Y`,r=`timeGrid-toggle_q0Oh4`,i=`timeGrid-toggle-open_CkMZf`,a=`timeGrid-headPane_KOqbR`,o=`timeGrid-dayHeader_nyugU`,s=`timeGrid-dayHeader-link_vE861`,c=`timeGrid-dayNumber_3xDPg`,l=`timeGrid-dayNumber-today_em4ho`,u=`timeGrid-weekday_BEOk2`,d=`timeGrid-allDay_sBaRg`,f=`timeGrid-bar_bGt1p`,p=`timeGrid-bar-continuesBefore_XRW1T`,m=`timeGrid-bar-continuesAfter_BsjNh`,h=`timeGrid-bar-title_iVZsx`,g=`timeGrid-more_Fo6hf`,_=`timeGrid-body_Vzvbo`,v=`timeGrid-gutter_OuCf-`,y=`timeGrid-hour_wVF05`,b=`timeGrid-bodyPane_Ji1lF`,x=`timeGrid-column_mEJNy`,S=`timeGrid-column-today_goKa0`,C=`timeGrid-column-creatable_5MQ8P`,w=`timeGrid-event_qLWLI`,T=`timeGrid-event-short_akp1j`,E=`timeGrid-event-brief_AX4PC`,D=`timeGrid-resize_LdiRH`,O=`timeGrid-event-continuesBefore_uGyO5`,k=`timeGrid-event-continuesAfter_p-hcM`,A=`timeGrid-event-interactive_TXdJ8`,j=`timeGrid-event-dragged_UrxXL`,M=`timeGrid-event-title_uDvkI`,N=`timeGrid-event-time_O5W3b`,P=`timeGrid-preview_nfmke`,F=`timeGrid-preview-time_8hmVF`,I=`timeGrid-slot_s7iMI`,L=`timeGrid-now_Rs5aE`,R=`calendarNowPulse_DDoyI`,z={timeGrid:e,"timeGrid-head":`timeGrid-head_QeMAH`,timeGridHead:t,"timeGrid-corner":`timeGrid-corner_ass6Y`,timeGridCorner:n,"timeGrid-toggle":`timeGrid-toggle_q0Oh4`,timeGridToggle:r,"timeGrid-toggle-open":`timeGrid-toggle-open_CkMZf`,timeGridToggleOpen:i,"timeGrid-headPane":`timeGrid-headPane_KOqbR`,timeGridHeadPane:a,"timeGrid-dayHeader":`timeGrid-dayHeader_nyugU`,timeGridDayHeader:o,"timeGrid-dayHeader-link":`timeGrid-dayHeader-link_vE861`,timeGridDayHeaderLink:s,"timeGrid-dayNumber":`timeGrid-dayNumber_3xDPg`,timeGridDayNumber:c,"timeGrid-dayNumber-today":`timeGrid-dayNumber-today_em4ho`,timeGridDayNumberToday:l,"timeGrid-weekday":`timeGrid-weekday_BEOk2`,timeGridWeekday:u,"timeGrid-allDay":`timeGrid-allDay_sBaRg`,timeGridAllDay:d,"timeGrid-bar":`timeGrid-bar_bGt1p`,timeGridBar:f,"timeGrid-bar-continuesBefore":`timeGrid-bar-continuesBefore_XRW1T`,timeGridBarContinuesBefore:p,"timeGrid-bar-continuesAfter":`timeGrid-bar-continuesAfter_BsjNh`,timeGridBarContinuesAfter:m,"timeGrid-bar-title":`timeGrid-bar-title_iVZsx`,timeGridBarTitle:h,"timeGrid-more":`timeGrid-more_Fo6hf`,timeGridMore:g,"timeGrid-body":`timeGrid-body_Vzvbo`,timeGridBody:_,"timeGrid-gutter":`timeGrid-gutter_OuCf-`,timeGridGutter:v,"timeGrid-hour":`timeGrid-hour_wVF05`,timeGridHour:y,"timeGrid-bodyPane":`timeGrid-bodyPane_Ji1lF`,timeGridBodyPane:b,"timeGrid-column":`timeGrid-column_mEJNy`,timeGridColumn:x,"timeGrid-column-today":`timeGrid-column-today_goKa0`,timeGridColumnToday:S,"timeGrid-column-creatable":`timeGrid-column-creatable_5MQ8P`,timeGridColumnCreatable:C,"timeGrid-event":`timeGrid-event_qLWLI`,timeGridEvent:w,"timeGrid-event-short":`timeGrid-event-short_akp1j`,timeGridEventShort:T,"timeGrid-event-brief":`timeGrid-event-brief_AX4PC`,timeGridEventBrief:E,"timeGrid-resize":`timeGrid-resize_LdiRH`,timeGridResize:D,"timeGrid-event-continuesBefore":`timeGrid-event-continuesBefore_uGyO5`,timeGridEventContinuesBefore:O,"timeGrid-event-continuesAfter":`timeGrid-event-continuesAfter_p-hcM`,timeGridEventContinuesAfter:k,"timeGrid-event-interactive":`timeGrid-event-interactive_TXdJ8`,timeGridEventInteractive:A,"timeGrid-event-dragged":`timeGrid-event-dragged_UrxXL`,timeGridEventDragged:j,"timeGrid-event-title":`timeGrid-event-title_uDvkI`,timeGridEventTitle:M,"timeGrid-event-time":`timeGrid-event-time_O5W3b`,timeGridEventTime:N,"timeGrid-preview":`timeGrid-preview_nfmke`,timeGridPreview:P,"timeGrid-preview-time":`timeGrid-preview-time_8hmVF`,timeGridPreviewTime:F,"timeGrid-slot":`timeGrid-slot_s7iMI`,timeGridSlot:I,"timeGrid-now":`timeGrid-now_Rs5aE`,timeGridNow:L,calendarNowPulse:R};export{R as calendarNowPulse,z as default,e as timeGrid,d as timeGridAllDay,f as timeGridBar,m as timeGridBarContinuesAfter,p as timeGridBarContinuesBefore,h as timeGridBarTitle,_ as timeGridBody,b as timeGridBodyPane,x as timeGridColumn,C as timeGridColumnCreatable,S as timeGridColumnToday,n as timeGridCorner,o as timeGridDayHeader,s as timeGridDayHeaderLink,c as timeGridDayNumber,l as timeGridDayNumberToday,w as timeGridEvent,E as timeGridEventBrief,k as timeGridEventContinuesAfter,O as timeGridEventContinuesBefore,j as timeGridEventDragged,A as timeGridEventInteractive,T as timeGridEventShort,N as timeGridEventTime,M as timeGridEventTitle,v as timeGridGutter,t as timeGridHead,a as timeGridHeadPane,y as timeGridHour,g as timeGridMore,L as timeGridNow,P as timeGridPreview,F as timeGridPreviewTime,D as timeGridResize,I as timeGridSlot,r as timeGridToggle,i as timeGridToggleOpen,u as timeGridWeekday};
|
|
2
|
+
//# sourceMappingURL=timeGrid.module.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeGrid.module.mjs","names":[],"sources":["../../../../../../package/common/calendar/components/timeGrid/timeGrid.module.pcss"],"sourcesContent":["/* One vertical scroller holds the sticky head and the body, so the head's day columns line up\n with the body's by construction, scrollbar or not. Only the two tracks inside move sideways.\n Everything positioned in time uses percentages of the day, so zooming rewrites one custom\n property and nothing else. */\n.timeGrid {\n --gutter: 3.5em;\n --lane: 1.375em;\n\n position: relative;\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n overscroll-behavior: contain;\n outline: none;\n user-select: none;\n -webkit-touch-callout: none;\n\n /* Horizontal swipes page, pinches zoom, vertical drags still scroll. */\n touch-action: pan-y;\n\n &-head {\n position: sticky;\n top: 0;\n z-index: 1;\n display: grid;\n grid-template-columns: var(--gutter) minmax(0, 1fr);\n border-bottom: 1px solid var(--border-color);\n background: var(--background);\n }\n\n &-corner {\n display: flex;\n align-items: flex-end;\n justify-content: center;\n padding-bottom: 0.25em;\n }\n\n &-toggle {\n display: grid;\n place-items: center;\n width: 1.75em;\n height: 1.75em;\n padding: 0;\n border: 0;\n border-radius: 50%;\n background: transparent;\n color: var(--text-dark);\n font-size: 0.75em;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n transition: transform 0.2s ease;\n\n &:hover {\n background: var(--background-accent-light);\n }\n\n &:focus-visible {\n outline: 2px solid var(--focus-border-color, var(--primary-color));\n }\n\n &-open {\n transform: rotate(180deg);\n }\n }\n\n &-headPane {\n display: grid;\n grid-template-columns: repeat(var(--days), minmax(0, 1fr));\n align-content: start;\n background: var(--background);\n }\n\n &-dayHeader {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.125em;\n padding: 0.375em 0 0.25em;\n border: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n\n &-link {\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n\n &:hover .timeGrid-dayNumber:not(.timeGrid-dayNumber-today) {\n background: var(--background-accent-light);\n }\n\n &:focus-visible {\n outline: 2px solid var(--focus-border-color, var(--primary-color));\n outline-offset: -2px;\n border-radius: var(--default-border-radius);\n }\n }\n }\n\n &-weekday {\n font-size: 0.6875em;\n font-weight: 600;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--text-dark);\n }\n\n &-dayNumber {\n display: grid;\n place-items: center;\n width: 1.875em;\n height: 1.875em;\n border-radius: 50%;\n font-size: 1.125em;\n font-weight: 500;\n font-variant-numeric: tabular-nums;\n transition: background-color 0.15s ease;\n\n &-today {\n background: var(--custom-calendar-today-color);\n color: var(--text-on-primary);\n font-weight: 700;\n }\n }\n\n &-allDay {\n grid-column: 1 / -1;\n display: grid;\n grid-template-columns: repeat(var(--days), minmax(0, 1fr));\n grid-auto-rows: var(--lane);\n row-gap: 2px;\n min-height: 0.5em;\n padding: 2px 0 4px;\n }\n\n &-bar {\n --event: var(--event-color, var(--primary-color));\n\n min-width: 0;\n margin: 0 2px;\n padding: 0 0.5em;\n overflow: hidden;\n border: 0;\n border-radius: var(--custom-calendar-event-radius);\n background: color-mix(in oklab, var(--event) 22%, var(--background));\n box-shadow: inset 3px 0 0 var(--event);\n color: var(--text-color);\n font: inherit;\n font-size: 0.75em;\n font-weight: 500;\n text-align: left;\n white-space: nowrap;\n text-overflow: ellipsis;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n\n &:hover {\n background: color-mix(in oklab, var(--event) 32%, var(--background));\n }\n\n &:focus-visible {\n outline: 2px solid var(--focus-border-color, var(--primary-color));\n }\n\n &-continuesBefore {\n margin-left: 0;\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n box-shadow: none;\n }\n\n &-continuesAfter {\n margin-right: 0;\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n\n &-title {\n display: block;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n }\n\n &-more {\n align-self: center;\n margin: 0 2px;\n padding: 0 0.5em;\n border-radius: var(--custom-calendar-event-radius);\n font-size: 0.75em;\n font-weight: 600;\n white-space: nowrap;\n color: var(--text-dark);\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n\n &:hover {\n background: var(--background-accent-light);\n }\n }\n\n /* Its own stacking context, which keeps everything drawn in the hours under the sticky head\n above. Inside it, the now-line and the drag preview come after the events in the markup,\n and so paint over them without a z-index. */\n &-body {\n isolation: isolate;\n display: grid;\n grid-template-columns: var(--gutter) minmax(0, 1fr);\n height: calc(24 * var(--custom-calendar-hour-height));\n }\n\n &-gutter {\n position: relative;\n }\n\n &-hour {\n position: absolute;\n right: 0.625em;\n font-size: 0.6875em;\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n color: var(--text-light);\n transform: translateY(-50%);\n }\n\n &-bodyPane {\n position: relative;\n display: grid;\n grid-template-columns: repeat(var(--days), minmax(0, 1fr));\n height: 100%;\n background: var(--background);\n }\n\n /* Hour lines, and fainter half-hour lines between them. */\n &-column {\n /* Events leave a strip on the right free, so there is always somewhere to press to create. */\n --column-width: calc(100% - 0.75em);\n\n position: relative;\n min-width: 0;\n border-left: 1px solid var(--border-color);\n background-image:\n linear-gradient(var(--border-color) 1px, transparent 1px),\n linear-gradient(color-mix(in oklab, var(--border-color) 45%, transparent) 1px, transparent 1px);\n background-position:\n 0 0,\n 0 calc(var(--custom-calendar-hour-height) / 2);\n background-size: 100% var(--custom-calendar-hour-height);\n\n &-today {\n background-color: color-mix(in oklab, var(--custom-calendar-today-color) 4%, transparent);\n }\n\n &-creatable {\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n }\n }\n\n &-event {\n --event: var(--event-color, var(--primary-color));\n\n position: absolute;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n min-width: 0;\n height: var(--span);\n margin: 0;\n padding: 0.2em 0.45em 0.2em 0.6em;\n overflow: hidden;\n container-type: size;\n border: 0;\n border-radius: var(--custom-calendar-event-radius);\n background: color-mix(in oklab, var(--event) 22%, var(--background));\n\n /* The outline in the page colour keeps side-by-side events apart. */\n box-shadow:\n inset 3px 0 0 var(--event),\n 0 0 0 1px var(--background);\n color: var(--text-color);\n font: inherit;\n font-size: 0.75em;\n line-height: 1.3;\n text-align: left;\n transition:\n background-color 0.15s ease,\n opacity 0.15s ease;\n\n &:hover {\n background: color-mix(in oklab, var(--event) 32%, var(--background));\n }\n\n &:focus-visible {\n z-index: 1;\n outline: 2px solid var(--focus-border-color, var(--primary-color));\n }\n\n &-short {\n flex-direction: row;\n\n /* Not `baseline`: a 15-minute event is shorter than its line, and centring clips it evenly\n rather than cutting off the bottom. Title and time share a font size, so they still line up. */\n align-items: center;\n gap: 0.4em;\n padding-block: 0;\n }\n\n /* Too short for its label, which would be clipped to nothing: a bar of its real length, and\n the label on a line of its own beneath it, in the room packDay leaves for it. */\n &-brief {\n /* One line, with room for the descenders that a line height of 1 clips in Firefox. Keep\n BRIEF_LABEL_MINUTES in layout.ts at least this tall at the default hour height. */\n --label: 1.25em;\n\n isolation: isolate;\n height: calc(var(--span) + var(--label));\n align-items: flex-end;\n line-height: var(--label);\n background: none;\n box-shadow: none;\n\n /* Under the label, which it covers once zoomed in: see the @container rule below. */\n &::before {\n content: '';\n position: absolute;\n z-index: -1;\n top: 0;\n right: 0;\n left: 0;\n height: max(2px, 100% - var(--label));\n border-radius: inherit;\n background: var(--event);\n transition:\n background-color 0.15s ease,\n opacity 0.15s ease;\n }\n\n &:hover {\n background: none;\n\n &::before {\n opacity: 0.75;\n }\n }\n\n /* On the bar's end, which is the event's, rather than under the label. */\n .timeGrid-resize {\n bottom: calc(var(--label) - 0.3em);\n height: 0.6em;\n max-height: none;\n }\n }\n\n &-continuesBefore {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n }\n\n &-continuesAfter {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n }\n\n &-interactive {\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n }\n\n &-dragged {\n opacity: 0.4;\n }\n\n &-title {\n flex: none;\n overflow: hidden;\n font-weight: 600;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n\n &-time {\n overflow: hidden;\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n text-overflow: ellipsis;\n color: var(--text-dark);\n }\n }\n\n &-resize {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n height: 0.625em;\n\n /* Half at most, so a short event keeps a part that moves it: a finger's grip is taller. */\n max-height: 50%;\n cursor: ns-resize;\n\n /* A visible grip where a finger is the pointer, since there is no hover to reveal it. */\n @media (pointer: coarse) {\n height: 1.5em;\n\n &::after {\n content: '';\n position: absolute;\n bottom: 0.3em;\n left: 50%;\n width: 1.5em;\n height: 0.25em;\n border-radius: 0.125em;\n background: color-mix(in oklab, var(--event) 70%, var(--background));\n translate: -50% 0;\n }\n }\n }\n\n &-preview {\n --event: var(--event-color, var(--primary-color));\n\n position: absolute;\n left: 0;\n width: var(--column-width);\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n padding: 0.2em 0.45em 0.2em 0.6em;\n overflow: hidden;\n border-radius: var(--custom-calendar-event-radius);\n background: color-mix(in oklab, var(--event) 32%, var(--background));\n box-shadow:\n inset 3px 0 0 var(--event),\n 0 0.5em 1.25em color-mix(in oklab, var(--text-color) 22%, transparent);\n color: var(--text-color);\n font-size: 0.75em;\n line-height: 1.3;\n pointer-events: none;\n\n &-time {\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n }\n }\n\n /* The anchor `onSlotCreate` hands out, moved over each new slot. Transparent rather than\n hidden, so it keeps the box a popover measures and anchors to. */\n &-slot {\n position: absolute;\n opacity: 0;\n pointer-events: none;\n }\n\n &-now {\n position: absolute;\n right: 0;\n left: 0;\n height: 2px;\n margin-top: -1px;\n background: var(--custom-calendar-now-color);\n pointer-events: none;\n\n &::before {\n content: '';\n position: absolute;\n top: 50%;\n left: 0;\n width: 0.625em;\n height: 0.625em;\n border-radius: 50%;\n background: var(--custom-calendar-now-color);\n translate: -50% -50%;\n animation: calendarNowPulse 2.4s ease-in-out infinite;\n }\n }\n}\n\n/* Zoomed in until its bar holds its label, a brief event is drawn like any other, its label\n centred in the bar. 2.5em is twice the label's line: a condition cannot read `--label`. */\n@container (height >= 2.5em) {\n .timeGrid-event-brief::before {\n background: color-mix(in oklab, var(--event) 22%, var(--background));\n box-shadow: inset 3px 0 0 var(--event);\n }\n\n .timeGrid-event-brief:hover::before {\n background: color-mix(in oklab, var(--event) 32%, var(--background));\n opacity: 1;\n }\n\n .timeGrid-event-brief .timeGrid-event-title,\n .timeGrid-event-brief .timeGrid-event-time {\n align-self: flex-start;\n margin-top: calc((100cqh - 2 * var(--label)) / 2);\n }\n}\n\n/* An event shorter than its text shows its colour alone, not a slice of clipped letters. The `em`\n is the event's own font size, and zooming in brings the text back. */\n@container (height < 0.8em) {\n .timeGrid-event-title,\n .timeGrid-event-time {\n display: none;\n }\n}\n\n@keyframes calendarNowPulse {\n 50% {\n box-shadow: 0 0 0 0.3em color-mix(in oklab, var(--custom-calendar-now-color) 25%, transparent);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .timeGrid-toggle {\n transition: none;\n }\n\n .timeGrid-now::before {\n animation: none;\n }\n}\n"],"mappings":""}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{dateToDay as e}from"../utils/day.mjs";import{CalendarView as t}from"./calendar.types.mjs";var n=1440;function r(e){return new Date(e.getFullYear(),e.getMonth(),e.getDate())}function i(e,t){return new Date(e.getFullYear(),e.getMonth(),e.getDate()+t)}function a(e,t){return new Date(e.getFullYear(),e.getMonth(),e.getDate()+t,e.getHours(),e.getMinutes(),e.getSeconds(),e.getMilliseconds())}function o(e,t){return new Date(e,t+1,0).getDate()}function s(e,t){let n=new Date(e.getFullYear(),e.getMonth()+t,1),r=Math.min(e.getDate(),o(n.getFullYear(),n.getMonth()));return new Date(n.getFullYear(),n.getMonth(),r)}function c(e){return new Date(e.getFullYear(),e.getMonth(),1)}function l(e,t){return i(e,-((e.getDay()-t+7)%7))}function u(e,t){let n=Date.UTC(e.getFullYear(),e.getMonth(),e.getDate()),r=Date.UTC(t.getFullYear(),t.getMonth(),t.getDate());return Math.round((r-n)/864e5)}function d(e,t){return e.getFullYear()===t.getFullYear()&&e.getMonth()===t.getMonth()&&e.getDate()===t.getDate()}function f(e){return e.getHours()*60+e.getMinutes()}function p(e,t){return new Date(e.getFullYear(),e.getMonth(),e.getDate(),0,t)}function m(e,t,n){return t>e?t:new Date(e.getTime()+n*6e4)}function h(e,n,i){switch(e){case t.Week:return l(n,i);case t.Day:return r(n);default:return c(n)}}function g(e,n,r){let a=h(e,n,r);switch(e){case t.Month:{let e=l(a,r);return{start:e,end:i(e,42)}}case t.Week:return{start:a,end:i(a,7)};case t.Day:return{start:a,end:i(a,1)};default:return{start:a,end:s(a,1)}}}var _=new Set;function v(e){let t=new Set(e);return t.size===0||[0,1,2,3,4,5,6].every(e=>t.has(e))?_:t}function y(e,t,n=1){let a=r(e);for(;t.has(a.getDay());)a=i(a,n);return a}function b(e,n,r,a=_){switch(e){case t.Week:return i(n,7*r);case t.Day:{let e=r<0?-1:1,t=n;for(let n=0;n<Math.abs(r);n++)t=y(i(t,e),a,e);return t}default:return s(n,r)}}function x(e,t,n,r=_){return{start:g(e,b(e,t,-1,r),n).start,end:g(e,b(e,t,1,r),n).end}}function S(e,t){return Array.from({length:t},(t,n)=>i(e,n))}function C(e,t,n=_){return S(e,t).filter(e=>!n.has(e.getDay()))}var w={ArrowLeft:-1,ArrowRight:1,ArrowUp:-7,ArrowDown:7};function T(e,t,n){return e in w?i(t,w[e]):e===`Home`?l(t,n):e===`End`?i(l(t,n),6):e===`PageUp`?s(t,-1):e===`PageDown`?s(t,1):null}function E(e,t,n,r=_){let i=T(e,t,n);return i&&y(i,r,e===`ArrowLeft`||e===`End`?-1:1)}export{n as MINUTES_PER_DAY,i as addDays,s as addMonths,p as atMinutes,e as dateToDay,u as dayDiff,S as daysFrom,o as daysInMonth,m as endAfter,E as gridKeyTarget,v as hiddenDaySet,d as isSameDay,f as minutesOfDay,g as periodRange,h as periodStart,x as rangeWithNeighbours,a as shiftDays,y as shownDay,C as shownDays,r as startOfDay,c as startOfMonth,l as startOfWeek,b as stepDate};
|
|
2
|
+
//# sourceMappingURL=dates.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dates.mjs","names":[],"sources":["../../../../package/common/calendar/dates.ts"],"sourcesContent":["import { CalendarView, type CalendarRange, type CalendarWeekStart } from './calendar.types';\n\n// All arithmetic goes through the local date fields rather than milliseconds: a day with a\n// daylight-saving change is 23 or 25 hours long, so adding 86 400 000 ms lands on the wrong day.\n\nexport const MINUTES_PER_DAY = 1440;\n\nexport function startOfDay(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate());\n}\n\n/** Midnight, `days` calendar days away. */\nexport function addDays(date: Date, days: number): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate() + days);\n}\n\n/** The same wall-clock time, `days` calendar days away. */\nexport function shiftDays(date: Date, days: number): Date {\n return new Date(\n date.getFullYear(),\n date.getMonth(),\n date.getDate() + days,\n date.getHours(),\n date.getMinutes(),\n date.getSeconds(),\n date.getMilliseconds(),\n );\n}\n\nexport function daysInMonth(year: number, month: number): number {\n return new Date(year, month + 1, 0).getDate();\n}\n\n/** Midnight, `months` months away. The day is clamped, so 31 January plus one month is the end of February. */\nexport function addMonths(date: Date, months: number): Date {\n const target = new Date(date.getFullYear(), date.getMonth() + months, 1);\n const day = Math.min(date.getDate(), daysInMonth(target.getFullYear(), target.getMonth()));\n return new Date(target.getFullYear(), target.getMonth(), day);\n}\n\nexport function startOfMonth(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), 1);\n}\n\nexport function startOfWeek(date: Date, weekStartsOn: CalendarWeekStart): Date {\n return addDays(date, -((date.getDay() - weekStartsOn + 7) % 7));\n}\n\n/** Calendar days from `a` to `b`, whatever their times of day. */\nexport function dayDiff(a: Date, b: Date): number {\n const utcA = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());\n const utcB = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());\n return Math.round((utcB - utcA) / 86_400_000);\n}\n\nexport function isSameDay(a: Date, b: Date): boolean {\n return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\n}\n\n// `'2026-09-26'` is also the key for lookups and React keys. Never `getTime()`: where a clock\n// change happens at midnight (America/Santiago), the day's first moment is 01:00, and two paths to\n// the same day disagree.\nexport { dateToDay } from '../utils/day';\n\n/** Wall-clock minutes since midnight. On a 25-hour day the repeated hour maps onto itself. */\nexport function minutesOfDay(date: Date): number {\n return date.getHours() * 60 + date.getMinutes();\n}\n\n/**\n * The wall-clock time `minutes` after the start of `day`; 1440 is the next midnight. A time the\n * clock skips resolves forwards (02:30 becomes 03:30) and a repeated one to its first occurrence.\n */\nexport function atMinutes(day: Date, minutes: number): Date {\n return new Date(day.getFullYear(), day.getMonth(), day.getDate(), 0, minutes);\n}\n\n/**\n * `end`, unless a clock change turned the range around: where one end lands in the hour the\n * clocks skip, a wall-clock end can fall on or before its start. Then `minutes` of real time\n * after the start instead.\n */\nexport function endAfter(start: Date, end: Date, minutes: number): Date {\n return end > start ? end : new Date(start.getTime() + minutes * 60_000);\n}\n\n/** Midnight of the first day of the period `date` is in. */\nexport function periodStart(view: CalendarView, date: Date, weekStartsOn: CalendarWeekStart): Date {\n switch (view) {\n case CalendarView.Week:\n return startOfWeek(date, weekStartsOn);\n case CalendarView.Day:\n return startOfDay(date);\n default:\n return startOfMonth(date);\n }\n}\n\n/** The days a view shows for `date`. The month view is always six full weeks. */\nexport function periodRange(view: CalendarView, date: Date, weekStartsOn: CalendarWeekStart): CalendarRange {\n const start = periodStart(view, date, weekStartsOn);\n switch (view) {\n case CalendarView.Month: {\n const gridStart = startOfWeek(start, weekStartsOn);\n return { start: gridStart, end: addDays(gridStart, 42) };\n }\n case CalendarView.Week:\n return { start, end: addDays(start, 7) };\n case CalendarView.Day:\n return { start, end: addDays(start, 1) };\n default:\n return { start, end: addMonths(start, 1) };\n }\n}\n\nconst NO_DAYS: ReadonlySet<number> = new Set();\n\n/** `hiddenDays` as a lookup. A list that leaves no day of the week hides nothing. */\nexport function hiddenDaySet(hiddenDays: readonly number[] | undefined): ReadonlySet<number> {\n const hidden = new Set(hiddenDays);\n return hidden.size === 0 || [0, 1, 2, 3, 4, 5, 6].every((day) => hidden.has(day)) ? NO_DAYS : hidden;\n}\n\n/** `date`, or the first shown day from it on in `direction`. */\nexport function shownDay(date: Date, hidden: ReadonlySet<number>, direction: 1 | -1 = 1): Date {\n let day = startOfDay(date);\n while (hidden.has(day.getDay())) day = addDays(day, direction);\n return day;\n}\n\n/** `date` moved by `steps` periods, keeping its place in the period where it can. */\nexport function stepDate(view: CalendarView, date: Date, steps: number, hidden: ReadonlySet<number> = NO_DAYS): Date {\n switch (view) {\n case CalendarView.Week:\n return addDays(date, 7 * steps);\n case CalendarView.Day: {\n const direction = steps < 0 ? -1 : 1;\n let day = date;\n for (let i = 0; i < Math.abs(steps); i++) day = shownDay(addDays(day, direction), hidden, direction);\n return day;\n }\n default:\n return addMonths(date, steps);\n }\n}\n\n/** The shown period plus one on either side: what the swipe pager can reveal. */\nexport function rangeWithNeighbours(\n view: CalendarView,\n date: Date,\n weekStartsOn: CalendarWeekStart,\n hidden: ReadonlySet<number> = NO_DAYS,\n): CalendarRange {\n return {\n start: periodRange(view, stepDate(view, date, -1, hidden), weekStartsOn).start,\n end: periodRange(view, stepDate(view, date, 1, hidden), weekStartsOn).end,\n };\n}\n\n/** Midnight of each of `count` days from `start`. */\nexport function daysFrom(start: Date, count: number): Date[] {\n return Array.from({ length: count }, (_, i) => addDays(start, i));\n}\n\n/** The days of `count` from `start` that are not hidden: the columns a row of them draws. */\nexport function shownDays(start: Date, count: number, hidden: ReadonlySet<number> = NO_DAYS): Date[] {\n return daysFrom(start, count).filter((day) => !hidden.has(day.getDay()));\n}\n\nconst KEY_DAYS: Record<string, number> = { ArrowLeft: -1, ArrowRight: 1, ArrowUp: -7, ArrowDown: 7 };\n\nfunction keyTarget(key: string, day: Date, weekStartsOn: CalendarWeekStart): Date | null {\n if (key in KEY_DAYS) return addDays(day, KEY_DAYS[key]);\n if (key === 'Home') return startOfWeek(day, weekStartsOn);\n if (key === 'End') return addDays(startOfWeek(day, weekStartsOn), 6);\n if (key === 'PageUp') return addMonths(day, -1);\n if (key === 'PageDown') return addMonths(day, 1);\n return null;\n}\n\n/**\n * The day a month grid moves to for `key`, or `null` for a key it does not handle. A hidden day\n * gives way to the next shown one in the direction the key points, so the focus stays on a cell.\n */\nexport function gridKeyTarget(\n key: string,\n day: Date,\n weekStartsOn: CalendarWeekStart,\n hidden: ReadonlySet<number> = NO_DAYS,\n): Date | null {\n const target = keyTarget(key, day, weekStartsOn);\n return target && shownDay(target, hidden, key === 'ArrowLeft' || key === 'End' ? -1 : 1);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{CalendarView as e}from"./calendar.types.mjs";import{addDays as t}from"./dates.mjs";var n=new Map,r;function i(){return r===void 0&&(r=new Intl.DateTimeFormat().resolvedOptions().timeZone,queueMicrotask(()=>{r=void 0})),r}function a(e,t){let r=`${i()}|${e??``}|${JSON.stringify(t)}`,a=n.get(r);return a||(a=new Intl.DateTimeFormat(e,t),n.set(r,a)),a}function o(e,t,n){return e.formatRange(t,n)}var s=new Map;function c(e){let t=e??``,n=s.get(t);if(n!==void 0)return n;let r=1;try{let t=e??new Intl.DateTimeFormat().resolvedOptions().locale,n=new Intl.Locale(t),i=n.getWeekInfo?.()??n.weekInfo;i&&(r=i.firstDay%7)}catch{}return s.set(t,r),r}function l(e){let t=a(e,{hour:`numeric`}).resolvedOptions().hourCycle;return t===`h11`||t===`h12`}function u(e,t){return a(t,{hour:`numeric`,minute:`2-digit`}).format(e)}function d(e,t,n){return o(a(n,{hour:`numeric`,minute:`2-digit`}),e,t)}function f(e,t,n){let r=new Date(2e3,0,1,e.getHours(),e.getMinutes()),i=new Date(2e3,0,1,t.getHours(),t.getMinutes());try{return o(a(n,{hour:`numeric`,minute:`2-digit`}),r,i)}catch{return u(e,n)}}function p(e,t){let n=new Date(2e3,0,1,e);return l(t)?a(t,{hour:`numeric`}).format(n):a(t,{hour:`2-digit`,minute:`2-digit`}).format(n)}function m(e,t,n){return a(t,{weekday:n}).format(e)}function h(e,t){return a(t,{day:`numeric`}).format(e)}function g(e,t){return a(t,{weekday:`long`,day:`numeric`,month:`long`,year:`numeric`}).format(e)}function _(e,t){return a(t,{month:`long`,year:`numeric`}).format(e)}function v(n,r,i,s){switch(n){case e.Week:return o(a(s,{day:`numeric`,month:`short`,year:`numeric`}),i.start,t(i.end,-1));case e.Day:return g(r,s);default:return _(r,s)}}export{f as formatClockRange,h as formatDayNumber,p as formatHour,g as formatLongDate,_ as formatMonthTitle,v as formatPeriodTitle,u as formatTime,d as formatTimeRange,m as formatWeekday,a as formatter,c as localeWeekStart};
|
|
2
|
+
//# sourceMappingURL=format.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.mjs","names":[],"sources":["../../../../package/common/calendar/format.ts"],"sourcesContent":["import { CalendarView, type CalendarRange, type CalendarWeekStart } from './calendar.types';\nimport { addDays } from './dates';\n\n// `locale` is passed to Intl as given, and `undefined` means the browser's locale. Not\n// `getLocale()` from services/localization: it narrows to a few supported locales and maps\n// en-GB to en-US, which would give British users 12-hour times.\n\nconst formatters = new Map<string, Intl.DateTimeFormat>();\nlet zone: string | undefined;\n\n/**\n * Read once per task: reading the zone costs as much as building a formatter. Its name, not its\n * offsets, because Casablanca and Brazzaville share January's and July's but not March's.\n */\nfunction currentZone(): string {\n if (zone === undefined) {\n zone = new Intl.DateTimeFormat().resolvedOptions().timeZone;\n queueMicrotask(() => {\n zone = undefined;\n });\n }\n return zone;\n}\n\n/**\n * Cached, since building one costs about fifty times more than using it. A formatter keeps the\n * time zone it was built in while `Date` follows the current one, so the key carries the zone: a\n * zone change (the device's, or `process.env.TZ` between tests) then builds a new formatter\n * instead of labelling days in the old zone.\n */\nexport function formatter(locale: string | undefined, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {\n const key = `${currentZone()}|${locale ?? ''}|${JSON.stringify(options)}`;\n let cached = formatters.get(key);\n if (!cached) {\n cached = new Intl.DateTimeFormat(locale, options);\n formatters.set(key, cached);\n }\n return cached;\n}\n\n// ES2020's lib predates `formatRange`, which every supported browser has had since 2021.\nfunction formatRange(format: Intl.DateTimeFormat, start: Date, end: Date): string {\n return (format as Intl.DateTimeFormat & { formatRange(a: Date, b: Date): string }).formatRange(start, end);\n}\n\ntype WeekInfoLocale = Intl.Locale & {\n getWeekInfo?: () => { firstDay: number };\n /** The accessor form Chrome 99 to 129 and Safari 15.4 to 16 shipped before the method. */\n weekInfo?: { firstDay: number };\n};\n\nconst weekStarts = new Map<string, CalendarWeekStart>();\n\n/**\n * The locale's first day of the week, falling back to Monday where `getWeekInfo` is missing:\n * it is Baseline only since July 2026 (Chrome 130, Firefox 153, Safari 17).\n */\nexport function localeWeekStart(locale: string | undefined): CalendarWeekStart {\n const key = locale ?? '';\n const cached = weekStarts.get(key);\n if (cached !== undefined) return cached;\n\n let result: CalendarWeekStart = 1;\n try {\n const tag = locale ?? new Intl.DateTimeFormat().resolvedOptions().locale;\n const info = new Intl.Locale(tag) as WeekInfoLocale;\n const weekInfo = info.getWeekInfo?.() ?? info.weekInfo;\n // `firstDay` counts 1 (Monday) to 7 (Sunday); `getDay()` counts 0 (Sunday) to 6.\n if (weekInfo) result = (weekInfo.firstDay % 7) as CalendarWeekStart;\n } catch {\n // An invalid tag: Intl.DateTimeFormat would have thrown for it too, so keep the fallback.\n }\n weekStarts.set(key, result);\n return result;\n}\n\nfunction uses12Hour(locale: string | undefined): boolean {\n // `hourCycle` is missing from ES2020's lib typings, not from any supported browser.\n const options = formatter(locale, { hour: 'numeric' }).resolvedOptions() as { hourCycle?: string };\n const cycle = options.hourCycle;\n return cycle === 'h11' || cycle === 'h12';\n}\n\nexport function formatTime(date: Date, locale: string | undefined): string {\n return formatter(locale, { hour: 'numeric', minute: '2-digit' }).format(date);\n}\n\n/** A time span, with the dates added by Intl where the two ends fall on different days. */\nexport function formatTimeRange(start: Date, end: Date, locale: string | undefined): string {\n return formatRange(formatter(locale, { hour: 'numeric', minute: '2-digit' }), start, end);\n}\n\n/**\n * The clock times alone, `10:00 PM to 2:00 AM` as the locale writes it, where `formatTimeRange` would add both dates for\n * an event that crosses midnight. Both ends are moved onto one day for it. The first spec of\n * `formatRange` threw a RangeError for an end earlier than the start; an engine still doing that\n * gets the start time alone.\n */\nexport function formatClockRange(start: Date, end: Date, locale: string | undefined): string {\n const from = new Date(2000, 0, 1, start.getHours(), start.getMinutes());\n const to = new Date(2000, 0, 1, end.getHours(), end.getMinutes());\n try {\n return formatRange(formatter(locale, { hour: 'numeric', minute: '2-digit' }), from, to);\n } catch {\n return formatTime(start, locale);\n }\n}\n\n/** `9 AM` where the locale counts to twelve, `09:00` where it counts to 24. */\nexport function formatHour(hour: number, locale: string | undefined): string {\n const date = new Date(2000, 0, 1, hour);\n return uses12Hour(locale)\n ? formatter(locale, { hour: 'numeric' }).format(date)\n : formatter(locale, { hour: '2-digit', minute: '2-digit' }).format(date);\n}\n\nexport function formatWeekday(date: Date, locale: string | undefined, width: 'long' | 'short' | 'narrow'): string {\n return formatter(locale, { weekday: width }).format(date);\n}\n\n/** The day of the month in the locale's own digits. */\nexport function formatDayNumber(date: Date, locale: string | undefined): string {\n return formatter(locale, { day: 'numeric' }).format(date);\n}\n\nexport function formatLongDate(date: Date, locale: string | undefined): string {\n return formatter(locale, { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' }).format(date);\n}\n\nexport function formatShortDate(date: Date, locale: string | undefined): string {\n return formatter(locale, { weekday: 'short', day: 'numeric', month: 'short' }).format(date);\n}\n\nexport function formatMonthTitle(date: Date, locale: string | undefined): string {\n return formatter(locale, { month: 'long', year: 'numeric' }).format(date);\n}\n\nexport function formatPeriodTitle(\n view: CalendarView,\n date: Date,\n range: CalendarRange,\n locale: string | undefined,\n): string {\n switch (view) {\n case CalendarView.Week:\n return formatRange(\n formatter(locale, { day: 'numeric', month: 'short', year: 'numeric' }),\n range.start,\n addDays(range.end, -1),\n );\n case CalendarView.Day:\n return formatLongDate(date, locale);\n default:\n return formatMonthTitle(date, locale);\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";var e=.2,t=.5;function n(e,t,n){return e===0||!(Math.abs(e)>=t*.2)&&!(Math.abs(n)>=.5&&Math.sign(n)===Math.sign(e))?0:e<0?1:-1}function r(e,t,n){return e<t+48?-18*Math.min(1,(t+48-e)/48):e>n-48?18*Math.min(1,(e-(n-48))/48):0}function i(e,t){return Math.round(e/t)*t}function a(e,t,n){return Math.min(Math.max(e,t),n)}function o(e,t){let n=e.filter(e=>t-e.time<=100);if(n.length<2)return 0;let r=n[0],i=n[n.length-1],a=i.time-r.time;return a>0?(i.x-r.x)/a:0}export{e as COMMIT_RATIO,t as COMMIT_VELOCITY,a as clamp,r as edgeSpeed,n as pageStep,i as snap,o as velocityOf};
|
|
2
|
+
//# sourceMappingURL=gesture.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gesture.mjs","names":[],"sources":["../../../../package/common/calendar/gesture.ts"],"sourcesContent":["// Thresholds the library already settled on elsewhere, so a swipe or a long press feels the same\n// here as in Carousel, Toast and VirtualList.\n\n/** Touch movement before a press is read as a swipe or a scroll (carousel.tsx, useSwipeDismiss.ts). */\nexport const LOCK_DISTANCE = 10;\n/** Mouse movement before a press becomes a drag. */\nexport const MOUSE_DRAG_DISTANCE = 4;\n/** Hold before a touch picks something up (VirtualList's `longPressDelay`). */\nexport const LONG_PRESS_MS = 400;\n/** A touch this soon after a scroll is stopping momentum, not picking something up. */\nexport const RECENT_SCROLL_MS = 150;\n/** Share of the width a swipe must travel to page (carousel.tsx). */\nexport const COMMIT_RATIO = 0.2;\n/** px/ms a shorter flick must reach to page anyway (useSwipeDismiss.ts). */\nexport const COMMIT_VELOCITY = 0.5;\n/** How far back the flick velocity is measured. */\nexport const VELOCITY_WINDOW_MS = 100;\n/** Distance from a scroller's edge where a drag starts scrolling it (useRowDrag.ts). */\nexport const EDGE_ZONE = 48;\n/** px per frame at the very edge. */\nexport const EDGE_SPEED = 18;\n/** How long after a gesture the click it ends in is swallowed (useRowDrag.ts). */\nexport const CLICK_SUPPRESS_MS = 350;\n\n/** `1` to page forwards, `-1` back, `0` to return. A swipe to the left reveals the next period. */\nexport function pageStep(dx: number, width: number, velocity: number): -1 | 0 | 1 {\n if (dx === 0) return 0;\n const far = Math.abs(dx) >= width * COMMIT_RATIO;\n const flicked = Math.abs(velocity) >= COMMIT_VELOCITY && Math.sign(velocity) === Math.sign(dx);\n if (!far && !flicked) return 0;\n return dx < 0 ? 1 : -1;\n}\n\n/** Scroll speed for a pointer at `y` in a scroller spanning `top` to `bottom`: negative scrolls up. */\nexport function edgeSpeed(y: number, top: number, bottom: number): number {\n if (y < top + EDGE_ZONE) return -EDGE_SPEED * Math.min(1, (top + EDGE_ZONE - y) / EDGE_ZONE);\n if (y > bottom - EDGE_ZONE) return EDGE_SPEED * Math.min(1, (y - (bottom - EDGE_ZONE)) / EDGE_ZONE);\n return 0;\n}\n\nexport function snap(minutes: number, step: number): number {\n return Math.round(minutes / step) * step;\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nexport interface VelocitySample {\n time: number;\n x: number;\n}\n\n/** px/ms over the samples of the last `VELOCITY_WINDOW_MS`. */\nexport function velocityOf(samples: readonly VelocitySample[], now: number): number {\n const recent = samples.filter((sample) => now - sample.time <= VELOCITY_WINDOW_MS);\n if (recent.length < 2) return 0;\n const first = recent[0];\n const last = recent[recent.length - 1];\n const elapsed = last.time - first.time;\n return elapsed > 0 ? (last.x - first.x) / elapsed : 0;\n}\n"],"mappings":"aAYA,IAAa,EAAe,GAEf,EAAkB,GAW/B,SAAgB,EAAS,EAAY,EAAe,EAA8B,CAKhF,OAJI,IAAO,GAGP,EAFQ,KAAK,IAAI,CAAE,GAAK,EAAA,KAEhB,EADI,KAAK,IAAI,CAAQ,GAAA,IAAwB,KAAK,KAAK,CAAQ,IAAM,KAAK,KAAK,CAAE,GAChE,EACtB,EAAK,EAAI,EAAI,EACtB,CAGA,SAAgB,EAAU,EAAW,EAAa,EAAwB,CAGxE,OAFI,EAAI,EAAA,GAAwB,IAAc,KAAK,IAAI,GAAI,EAAA,GAAkB,GAAA,EAAc,EACvF,EAAI,EAAA,GAAoB,GAAoB,KAAK,IAAI,GAAI,GAAK,EAAA,KAAA,EAAgC,EAC3F,CACT,CAEA,SAAgB,EAAK,EAAiB,EAAsB,CAC1D,OAAO,KAAK,MAAM,EAAU,CAAI,EAAI,CACtC,CAEA,SAAgB,EAAM,EAAe,EAAa,EAAqB,CACrE,OAAO,KAAK,IAAI,KAAK,IAAI,EAAO,CAAG,EAAG,CAAG,CAC3C,CAQA,SAAgB,EAAW,EAAoC,EAAqB,CAClF,IAAM,EAAS,EAAQ,OAAQ,GAAW,EAAM,EAAO,MAAA,GAA0B,EACjF,GAAI,EAAO,OAAS,EAAG,MAAO,GAC9B,IAAM,EAAQ,EAAO,GACf,EAAO,EAAO,EAAO,OAAS,GAC9B,EAAU,EAAK,KAAO,EAAM,KAClC,OAAO,EAAU,GAAK,EAAK,EAAI,EAAM,GAAK,EAAU,CACtD"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{MINUTES_PER_DAY as e,addDays as t,dayDiff as n,minutesOfDay as r,startOfDay as i}from"./dates.mjs";var a=864e5,o=20;function s(e){return e.end<e.start?e.start:e.end}function c(e){return!!e.allDay||s(e).getTime()-e.start.getTime()>=a}function l(e){let r=i(e.start),a=s(e);if(e.allDay){let e=i(a);return{first:r,last:n(r,e)>=1?t(e,-1):r}}return{first:r,last:a>e.start?i(new Date(a.getTime()-1)):r}}function u(e,t){let n=Number(c(t))-Number(c(e));if(n!==0)return n;let r=e.start.getTime()-t.start.getTime();if(r!==0)return r;let i=s(t).getTime()-s(e).getTime();return i===0?e.title.localeCompare(t.title):i}function d(e,t){let r=t.map(()=>[]);for(let i of e){let{first:e,last:a}=l(i);t.forEach((t,o)=>{n(e,t)>=0&&n(t,a)>=0&&r[o].push(i)})}for(let e of r)e.sort(u);return r}function f(n,a){let l=i(a),u=t(l,1),d=[];for(let t of n){if(c(t))continue;let{start:n}=t,i=s(t);if(n>=u||i<=l&&n<l)continue;let a=n<l,f=i>u,p=a?0:r(n),m=Math.max(i>=u?e:r(i),p),h=m-p<15?Math.min(m+o,e):m;d.push({event:t,top:p,bottom:m,reach:h,column:0,columns:1,span:1,continuesBefore:a,continuesAfter:f})}d.sort((e,t)=>e.top-t.top||t.reach-e.reach);let f=[],m=-1;for(let e of d)f.length>0&&e.top>=m&&(p(f),f=[]),f.push(e),m=Math.max(m,e.reach);return f.length>0&&p(f),d}function p(e){let t=[];for(let n of e){let e=t.findIndex(e=>e<=n.top);e===-1&&(e=t.push(0)-1),n.column=e,t[e]=n.reach}let n=t.length;for(let t of e){t.columns=n;let r=1;for(let i=t.column+1;i<n&&!e.some(e=>e.column===i&&e.top<t.reach&&e.reach>t.top);i++)r++;t.span=r}}function m(e,t,r=()=>!0){let i=[];for(let a of e){if(!r(a))continue;let{first:e,last:o}=l(a),s=t.findIndex(t=>n(e,t)>=0&&n(t,o)>=0);if(s===-1)continue;let c=s;for(;c+1<t.length&&n(t[c+1],o)>=0;)c++;i.push({event:a,start:s,span:c-s+1,lane:0,continuesBefore:n(e,t[s])>0,continuesAfter:n(t[c],o)>0})}i.sort((e,t)=>e.start-t.start||t.span-e.span||u(e.event,t.event));let a=[];for(let e of i){let t=a.findIndex(t=>t<=e.start);t===-1&&(t=a.push(0)-1),e.lane=t,a[t]=e.start+e.span}return i}function h(e,t,n){let r=Math.max(n-1,0),i=Array.from({length:t},()=>0);for(let t of e)for(let e=t.start;e<t.start+t.span;e++)i[e]=Math.max(i[e],t.lane+1);let a=Array.from({length:t},()=>0),o=[];for(let t of e){let e=t.lane<r;if(!e&&t.lane===r){e=!0;for(let r=t.start;r<t.start+t.span;r++)i[r]>n&&(e=!1)}if(e){o.push(t);continue}for(let e=t.start;e<t.start+t.span;e++)a[e]++}return{visible:o,moreLane:r,hidden:a}}export{u as compareEvents,l as eventDays,s as eventEnd,d as eventsByDay,c as isAllDayLike,h as limitLanes,f as packDay,m as packLanes};
|
|
2
|
+
//# sourceMappingURL=layout.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.mjs","names":[],"sources":["../../../../package/common/calendar/layout.ts"],"sourcesContent":["import type { CalendarEvent } from './calendar.types';\nimport { addDays, dayDiff, MINUTES_PER_DAY, minutesOfDay, startOfDay } from './dates';\n\nconst DAY_MS = 86_400_000;\n\n/**\n * Below this an event has no room for a line of text at the default hour height. It is drawn as a\n * bar of its real length with its label beneath, and packed with room for that label.\n */\nexport const BRIEF_EVENT_MINUTES = 15;\n/** The label's line (`--label` in timeGrid.module.pcss) at the default 48px hour: 15px. */\nconst BRIEF_LABEL_MINUTES = 20;\n\n/** `end`, clamped so an event that ends before it starts is treated as having no length. */\nexport function eventEnd(event: CalendarEvent): Date {\n return event.end < event.start ? event.start : event.end;\n}\n\n/** Drawn in the all-day row rather than the time grid. */\nexport function isAllDayLike(event: CalendarEvent): boolean {\n return Boolean(event.allDay) || eventEnd(event).getTime() - event.start.getTime() >= DAY_MS;\n}\n\n/** First and last day (both midnight, both inclusive) the event appears on. */\nexport function eventDays(event: CalendarEvent): { first: Date; last: Date } {\n const first = startOfDay(event.start);\n const end = eventEnd(event);\n if (event.allDay) {\n // `end` is exclusive, but an all-day event ending on its own start day still takes that day.\n const endDay = startOfDay(end);\n return { first, last: dayDiff(first, endDay) >= 1 ? addDays(endDay, -1) : first };\n }\n // One millisecond back, so a timed event ending at midnight does not appear on the next day.\n const last = end > event.start ? startOfDay(new Date(end.getTime() - 1)) : first;\n return { first, last };\n}\n\n/** All-day events first, then by start, then the longer first, so a day reads the same everywhere. */\nexport function compareEvents(a: CalendarEvent, b: CalendarEvent): number {\n const allDay = Number(isAllDayLike(b)) - Number(isAllDayLike(a));\n if (allDay !== 0) return allDay;\n const start = a.start.getTime() - b.start.getTime();\n if (start !== 0) return start;\n const length = eventEnd(b).getTime() - eventEnd(a).getTime();\n if (length !== 0) return length;\n return a.title.localeCompare(b.title);\n}\n\n/** The events on each of `dates`, sorted with `compareEvents`. */\nexport function eventsByDay<E extends CalendarEvent>(events: readonly E[], dates: readonly Date[]): E[][] {\n const result: E[][] = dates.map(() => []);\n for (const event of events) {\n const { first, last } = eventDays(event);\n dates.forEach((day, i) => {\n if (dayDiff(first, day) >= 0 && dayDiff(day, last) >= 0) result[i].push(event);\n });\n }\n for (const day of result) day.sort(compareEvents);\n return result;\n}\n\nexport interface TimedBox<E extends CalendarEvent = CalendarEvent> {\n event: E;\n /** Wall-clock minutes from the column's midnight. */\n top: number;\n bottom: number;\n /** Where the next event in its column may start: below the label of a brief event. */\n reach: number;\n /** Left edge, as a column of `columns`. */\n column: number;\n columns: number;\n /** Columns it can widen into to its right without covering another event. */\n span: number;\n continuesBefore: boolean;\n continuesAfter: boolean;\n}\n\n/**\n * Lays out one day column of the time grid: events that overlap share the width in columns, and\n * each one widens right into columns that are free for its whole height.\n *\n * Positions are wall-clock minutes, never milliseconds from midnight. Drawing and packing have\n * to agree on that: on a 25-hour day two events in the repeated hour occupy the same rows, and\n * packing them by real time would put them in one column, drawn over each other.\n */\nexport function packDay<E extends CalendarEvent>(events: readonly E[], day: Date): TimedBox<E>[] {\n const dayStart = startOfDay(day);\n const next = addDays(dayStart, 1);\n\n const boxes: TimedBox<E>[] = [];\n for (const event of events) {\n if (isAllDayLike(event)) continue;\n const { start } = event;\n const end = eventEnd(event);\n if (start >= next) continue;\n // A zero-length event at midnight belongs to the day it starts on.\n if (end <= dayStart && start < dayStart) continue;\n\n const continuesBefore = start < dayStart;\n const continuesAfter = end > next;\n const top = continuesBefore ? 0 : minutesOfDay(start);\n // Never upside down: on the day the clocks go back, an event can end on an earlier clock time.\n const bottom = Math.max(end >= next ? MINUTES_PER_DAY : minutesOfDay(end), top);\n const reach = bottom - top < BRIEF_EVENT_MINUTES ? Math.min(bottom + BRIEF_LABEL_MINUTES, MINUTES_PER_DAY) : bottom;\n boxes.push({ event, top, bottom, reach, column: 0, columns: 1, span: 1, continuesBefore, continuesAfter });\n }\n\n boxes.sort((a, b) => a.top - b.top || b.reach - a.reach);\n\n let cluster: TimedBox<E>[] = [];\n let clusterEnd = -1;\n for (const box of boxes) {\n if (cluster.length > 0 && box.top >= clusterEnd) {\n packCluster(cluster);\n cluster = [];\n }\n cluster.push(box);\n clusterEnd = Math.max(clusterEnd, box.reach);\n }\n if (cluster.length > 0) packCluster(cluster);\n\n return boxes;\n}\n\nfunction packCluster(cluster: TimedBox[]): void {\n const columnBottoms: number[] = [];\n for (const box of cluster) {\n let column = columnBottoms.findIndex((bottom) => bottom <= box.top);\n if (column === -1) column = columnBottoms.push(0) - 1;\n box.column = column;\n columnBottoms[column] = box.reach;\n }\n const columns = columnBottoms.length;\n for (const box of cluster) {\n box.columns = columns;\n let span = 1;\n for (let column = box.column + 1; column < columns; column++) {\n const blocked = cluster.some(\n (other) => other.column === column && other.top < box.reach && other.reach > box.top,\n );\n if (blocked) break;\n span++;\n }\n box.span = span;\n }\n}\n\nexport interface LaneBar<E extends CalendarEvent = CalendarEvent> {\n event: E;\n /** First column of the row it covers, 0-based. */\n start: number;\n /** Columns it covers within the row. */\n span: number;\n lane: number;\n /** It starts before its first column: in an earlier row, or on a hidden day. */\n continuesBefore: boolean;\n continuesAfter: boolean;\n}\n\n/**\n * Stacks the events of one row of days into lanes, as the month view and the all-day row draw\n * them: longer bars first, so a multi-day event keeps one lane across the week. `dates` are the\n * row's columns, so a hidden day between two of them is simply not drawn.\n */\nexport function packLanes<E extends CalendarEvent>(\n events: readonly E[],\n dates: readonly Date[],\n include: (event: E) => boolean = () => true,\n): LaneBar<E>[] {\n const bars: LaneBar<E>[] = [];\n for (const event of events) {\n if (!include(event)) continue;\n const { first, last } = eventDays(event);\n const start = dates.findIndex((day) => dayDiff(first, day) >= 0 && dayDiff(day, last) >= 0);\n if (start === -1) continue;\n let end = start;\n while (end + 1 < dates.length && dayDiff(dates[end + 1], last) >= 0) end++;\n bars.push({\n event,\n start,\n span: end - start + 1,\n lane: 0,\n continuesBefore: dayDiff(first, dates[start]) > 0,\n continuesAfter: dayDiff(dates[end], last) > 0,\n });\n }\n\n bars.sort((a, b) => a.start - b.start || b.span - a.span || compareEvents(a.event, b.event));\n\n const laneEnds: number[] = [];\n for (const bar of bars) {\n let lane = laneEnds.findIndex((end) => end <= bar.start);\n if (lane === -1) lane = laneEnds.push(0) - 1;\n bar.lane = lane;\n laneEnds[lane] = bar.start + bar.span;\n }\n return bars;\n}\n\nexport interface LimitedLanes<E extends CalendarEvent = CalendarEvent> {\n visible: LaneBar<E>[];\n /** Lane the `+N` buttons go in, on the days that have one. */\n moreLane: number;\n /** Events hidden on each day of the row. */\n hidden: number[];\n}\n\n/**\n * Fits the bars into `capacity` lanes. A day that needs more gives its last lane to a `+N`\n * button; a day that does not keeps every bar. Decided per day, so one crowded day does not\n * hide events on the quiet days next to it. A bar crossing into a crowded day's `+N` lane is\n * hidden along its whole length and counted on each day it covers.\n */\nexport function limitLanes<E extends CalendarEvent>(\n bars: LaneBar<E>[],\n days: number,\n capacity: number,\n): LimitedLanes<E> {\n const moreLane = Math.max(capacity - 1, 0);\n const lanesPerDay = Array.from({ length: days }, () => 0);\n for (const bar of bars) {\n for (let day = bar.start; day < bar.start + bar.span; day++) {\n lanesPerDay[day] = Math.max(lanesPerDay[day], bar.lane + 1);\n }\n }\n\n const hidden = Array.from({ length: days }, () => 0);\n const visible: LaneBar<E>[] = [];\n for (const bar of bars) {\n let fits = bar.lane < moreLane;\n if (!fits && bar.lane === moreLane) {\n fits = true;\n for (let day = bar.start; day < bar.start + bar.span; day++) {\n if (lanesPerDay[day] > capacity) fits = false;\n }\n }\n if (fits) {\n visible.push(bar);\n continue;\n }\n for (let day = bar.start; day < bar.start + bar.span; day++) hidden[day]++;\n }\n return { visible, moreLane, hidden };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";var e=`pager-viewport_Mq7zC`,t=`pager-track_MTNN6`,n=`pager-pane_b38-h`,r=`pager-pane-prev_PEY3n`,i=`pager-pane-next_B62PQ`,a={"pager-viewport":`pager-viewport_Mq7zC`,pagerViewport:e,"pager-track":`pager-track_MTNN6`,pagerTrack:t,"pager-pane":`pager-pane_b38-h`,pagerPane:n,"pager-pane-prev":`pager-pane-prev_PEY3n`,pagerPanePrev:r,"pager-pane-next":`pager-pane-next_B62PQ`,pagerPaneNext:i};export{a as default,n as pagerPane,i as pagerPaneNext,r as pagerPanePrev,t as pagerTrack,e as pagerViewport};
|
|
2
|
+
//# sourceMappingURL=pager.module.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pager.module.mjs","names":[],"sources":["../../../../package/common/calendar/pager.module.pcss"],"sourcesContent":["/* The three panes of a pageable view share one grid cell, so the track is as tall as its\n tallest pane and does not change height mid-swipe. `clip` rather than `hidden` on the viewport:\n `hidden` makes it a scroll container, which the neighbours would then extend sideways.\n The neighbours' transforms are positions, not motion: the slide itself runs in usePager,\n which skips it under reduced motion. */\n.pager {\n &-viewport {\n position: relative;\n min-width: 0;\n overflow: clip;\n }\n\n &-track {\n display: grid;\n height: 100%;\n }\n\n &-pane {\n grid-area: 1 / 1;\n min-width: 0;\n min-height: 0;\n\n &-prev {\n transform: translateX(-100%);\n }\n\n &-next {\n transform: translateX(100%);\n }\n }\n}\n"],"mappings":""}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{edgeSpeed as e,velocityOf as t}from"./gesture.mjs";import{useEffect as n,useLayoutEffect as r,useRef as i}from"react";function a(a,o){let s=i(o);r(()=>{s.current=o}),n(()=>{let n=a.current;if(!n)return;let r=()=>s.current,i=`idle`,o=-1,c=``,l={x:0,y:0},u={x:0,y:0},d=[],f=null,p,m=0,h=-1/0,g=0,_=new Map;function v(e){try{n.setPointerCapture(e)}catch{}}function y(){clearTimeout(p),p=void 0}function b(){y(),cancelAnimationFrame(m),m=0,f=null,i=`passive`,g=performance.now()+350}function x(){let[e,t]=[..._.values()];return{center:{x:(e.x+t.x)/2,y:(e.y+t.y)/2},distance:Math.hypot(e.x-t.x,e.y-t.y)}}function S(){if(i!==`dragging`)return;let t=r().autoScroll?.();if(t){let n=e(u.y,t.top,t.bottom),i=t.element.scrollTop;n!==0&&(t.element.scrollTop+=n),t.element.scrollTop!==i&&r().onDragMove?.(u)}m=requestAnimationFrame(S)}function C(){p=void 0,f!==null&&i===`pressed`&&(i=`dragging`,v(o),c!==`mouse`&&`vibrate`in navigator&&navigator.vibrate(10),r().onDragStart?.(f,u),m=requestAnimationFrame(S))}function w(e){if(e.isPrimary&&i!==`idle`&&(i===`dragging`?r().onDragCancel?.():i===`swiping`?r().onSwipeEnd?.(0,0):i===`pinching`&&r().onPinchEnd?.(),y(),cancelAnimationFrame(m),f=null,i=`idle`),i===`idle`){if(e.pointerType===`mouse`&&e.button!==0)return;r().onPress?.(),o=e.pointerId,c=e.pointerType,l=u={x:e.clientX,y:e.clientY},_.clear(),_.set(e.pointerId,l),d=[{time:e.timeStamp,x:e.clientX}],f=e.target instanceof Element?r().dragFrom?.(e.target,l)??null:null,i=`pressed`;let t=performance.now()-h<150;f!==null&&c!==`mouse`&&!t&&(p=setTimeout(C,400));return}if(e.pointerType!==`mouse`&&(_.set(e.pointerId,{x:e.clientX,y:e.clientY}),i===`pressed`&&_.size===2&&r().onPinchStart)){y(),i=`pinching`,v(o),v(e.pointerId);let{center:t,distance:n}=x();r().onPinchStart?.(t,n)}}function T(e){if(!_.has(e.pointerId))return;let t={x:e.clientX,y:e.clientY};if(_.set(e.pointerId,t),i===`pinching`){if(_.size<2)return;let{center:e,distance:t}=x();r().onPinchMove?.(e,t);return}if(e.pointerId!==o)return;u=t;let n=t.x-l.x,a=t.y-l.y;if(i===`pressed`){let e=Math.hypot(n,a);if(c===`mouse`){if(e<=4)return;if(f===null){i=`passive`;return}C()}else{if(e<=10)return;if(y(),Math.abs(n)<=Math.abs(a)||!r().canSwipe?.()){i=`passive`;return}i=`swiping`,v(o)}}i===`swiping`?(d.push({time:e.timeStamp,x:t.x}),d.length>20&&d.shift(),r().onSwipeMove?.(n)):i===`dragging`&&r().onDragMove?.(t)}function E(e){_.delete(e),_.size===0&&(y(),f=null,i=`idle`)}function D(e){_.has(e.pointerId)&&(i===`pinching`?(r().onPinchEnd?.(),b()):e.pointerId===o&&(i===`swiping`?(d.push({time:e.timeStamp,x:e.clientX}),r().onSwipeEnd?.(e.clientX-l.x,t(d,e.timeStamp)),b()):i===`dragging`?(u={x:e.clientX,y:e.clientY},r().onDragEnd?.(u),b()):i===`pressed`&&(y(),i=`passive`)),E(e.pointerId))}function O(e){_.has(e.pointerId)&&(i===`swiping`?(r().onSwipeEnd?.(0,0),b()):i===`dragging`?(r().onDragCancel?.(),b()):i===`pinching`?(r().onPinchEnd?.(),b()):(y(),i=`passive`),E(e.pointerId))}function k(e){(i===`swiping`||i===`dragging`||i===`pinching`)&&e.cancelable&&e.preventDefault()}function A(e){(i===`dragging`||i===`pressed`&&c!==`mouse`&&f!==null)&&e.preventDefault()}function j(e){e.preventDefault()}function M(e){performance.now()<g&&(e.stopPropagation(),e.preventDefault(),g=0)}function N(){h=performance.now()}function P(e){e.key===`Escape`&&i===`dragging`&&(e.preventDefault(),r().onDragCancel?.(),b())}return n.addEventListener(`pointerdown`,w),n.addEventListener(`pointermove`,T),n.addEventListener(`pointerup`,D),n.addEventListener(`pointercancel`,O),n.addEventListener(`touchmove`,k,{passive:!1}),n.addEventListener(`contextmenu`,A),n.addEventListener(`dragstart`,j),n.addEventListener(`click`,M,!0),n.addEventListener(`scroll`,N,{capture:!0,passive:!0}),window.addEventListener(`scroll`,N,{passive:!0}),window.addEventListener(`keydown`,P),()=>{y(),cancelAnimationFrame(m),n.removeEventListener(`pointerdown`,w),n.removeEventListener(`pointermove`,T),n.removeEventListener(`pointerup`,D),n.removeEventListener(`pointercancel`,O),n.removeEventListener(`touchmove`,k),n.removeEventListener(`contextmenu`,A),n.removeEventListener(`dragstart`,j),n.removeEventListener(`click`,M,!0),n.removeEventListener(`scroll`,N,{capture:!0}),window.removeEventListener(`scroll`,N),window.removeEventListener(`keydown`,P)}},[a])}export{a as useGestures};
|
|
2
|
+
//# sourceMappingURL=useGestures.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useGestures.mjs","names":[],"sources":["../../../../package/common/calendar/useGestures.ts"],"sourcesContent":["import { useEffect, useLayoutEffect, useRef, type RefObject } from 'react';\n\nimport {\n CLICK_SUPPRESS_MS,\n edgeSpeed,\n LOCK_DISTANCE,\n LONG_PRESS_MS,\n MOUSE_DRAG_DISTANCE,\n RECENT_SCROLL_MS,\n velocityOf,\n type VelocitySample,\n} from './gesture';\n\nexport interface GesturePoint {\n x: number;\n y: number;\n}\n\nexport interface GestureHandlers<D> {\n /** Every press that starts a gesture, before anything else: where a running settle is finished. */\n onPress?: () => void;\n /** Whether a horizontal swipe may page right now. */\n canSwipe?: () => boolean;\n onSwipeMove?: (dx: number) => void;\n /** Also called with `(0, 0)` when the browser takes the gesture over. */\n onSwipeEnd?: (dx: number, velocity: number) => void;\n /** What a press on `target` would pick up, or `null` where nothing can be dragged. */\n dragFrom?: (target: Element, point: GesturePoint) => D | null;\n onDragStart?: (drag: D, point: GesturePoint) => void;\n onDragMove?: (point: GesturePoint) => void;\n onDragEnd?: (point: GesturePoint) => void;\n onDragCancel?: () => void;\n onPinchStart?: (center: GesturePoint, distance: number) => void;\n onPinchMove?: (center: GesturePoint, distance: number) => void;\n onPinchEnd?: () => void;\n /** The element a drag scrolls near its edges, and the band of the viewport that counts as its inside. */\n autoScroll?: () => { element: HTMLElement; top: number; bottom: number } | null;\n}\n\ntype Phase = 'idle' | 'pressed' | 'swiping' | 'dragging' | 'pinching' | 'passive';\n\n/**\n * One owner for every pointer gesture inside `ref`, so a swipe, a long-press drag, a pinch and\n * the browser's own scrolling can never both act on the same touch.\n *\n * Mouse or touch rules are chosen per event from `pointerType`, not once from a media query,\n * which answers wrongly on a laptop with a touch screen.\n */\nexport function useGestures<D>(ref: RefObject<HTMLElement | null>, handlers: GestureHandlers<D>): void {\n const handlersRef = useRef(handlers);\n useLayoutEffect(() => {\n handlersRef.current = handlers;\n });\n\n useEffect(() => {\n const root = ref.current;\n if (!root) return;\n const h = () => handlersRef.current;\n\n let phase: Phase = 'idle';\n let primary = -1;\n let pointerType = '';\n let origin: GesturePoint = { x: 0, y: 0 };\n let last: GesturePoint = { x: 0, y: 0 };\n let samples: VelocitySample[] = [];\n let drag: D | null = null;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let frame = 0;\n let lastScroll = -Infinity;\n let suppressUntil = 0;\n const pointers = new Map<number, GesturePoint>();\n\n function capture(pointerId: number) {\n // Only once the gesture is ours: a captured pointer sends its click to the capture target,\n // so capturing on press would swallow every click meant for an event inside the grid.\n try {\n root!.setPointerCapture(pointerId);\n } catch {\n // The pointer is already gone.\n }\n }\n\n function clearTimer() {\n clearTimeout(timer);\n timer = undefined;\n }\n\n function finishGesture() {\n clearTimer();\n cancelAnimationFrame(frame);\n frame = 0;\n drag = null;\n phase = 'passive';\n suppressUntil = performance.now() + CLICK_SUPPRESS_MS;\n }\n\n function pinchGeometry() {\n const [a, b] = [...pointers.values()];\n return {\n center: { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 },\n distance: Math.hypot(a.x - b.x, a.y - b.y),\n };\n }\n\n function scrollStep() {\n if (phase !== 'dragging') return;\n const area = h().autoScroll?.();\n if (area) {\n const speed = edgeSpeed(last.y, area.top, area.bottom);\n const before = area.element.scrollTop;\n if (speed !== 0) area.element.scrollTop += speed;\n // The content moved under a finger that did not, so the drag target did.\n if (area.element.scrollTop !== before) h().onDragMove?.(last);\n }\n frame = requestAnimationFrame(scrollStep);\n }\n\n function startDrag() {\n timer = undefined;\n if (drag === null || phase !== 'pressed') return;\n phase = 'dragging';\n capture(primary);\n if (pointerType !== 'mouse' && 'vibrate' in navigator) navigator.vibrate(10);\n h().onDragStart?.(drag, last);\n frame = requestAnimationFrame(scrollStep);\n }\n\n function onPointerDown(event: PointerEvent) {\n // A primary pointer means every earlier one is up, even where its pointerup never reached\n // us (a mouse released outside the window before the drag captured it).\n if (event.isPrimary && phase !== 'idle') {\n if (phase === 'dragging') h().onDragCancel?.();\n else if (phase === 'swiping') h().onSwipeEnd?.(0, 0);\n else if (phase === 'pinching') h().onPinchEnd?.();\n clearTimer();\n cancelAnimationFrame(frame);\n drag = null;\n phase = 'idle';\n }\n if (phase === 'idle') {\n if (event.pointerType === 'mouse' && event.button !== 0) return;\n h().onPress?.();\n primary = event.pointerId;\n pointerType = event.pointerType;\n origin = last = { x: event.clientX, y: event.clientY };\n pointers.clear();\n pointers.set(event.pointerId, origin);\n samples = [{ time: event.timeStamp, x: event.clientX }];\n drag = event.target instanceof Element ? (h().dragFrom?.(event.target, origin) ?? null) : null;\n phase = 'pressed';\n const stoppingMomentum = performance.now() - lastScroll < RECENT_SCROLL_MS;\n if (drag !== null && pointerType !== 'mouse' && !stoppingMomentum) {\n timer = setTimeout(startDrag, LONG_PRESS_MS);\n }\n return;\n }\n if (event.pointerType === 'mouse') return;\n pointers.set(event.pointerId, { x: event.clientX, y: event.clientY });\n if (phase === 'pressed' && pointers.size === 2 && h().onPinchStart) {\n clearTimer();\n phase = 'pinching';\n capture(primary);\n capture(event.pointerId);\n const { center, distance } = pinchGeometry();\n h().onPinchStart?.(center, distance);\n }\n }\n\n function onPointerMove(event: PointerEvent) {\n if (!pointers.has(event.pointerId)) return;\n const point = { x: event.clientX, y: event.clientY };\n pointers.set(event.pointerId, point);\n\n if (phase === 'pinching') {\n if (pointers.size < 2) return;\n const { center, distance } = pinchGeometry();\n h().onPinchMove?.(center, distance);\n return;\n }\n if (event.pointerId !== primary) return;\n last = point;\n const dx = point.x - origin.x;\n const dy = point.y - origin.y;\n\n if (phase === 'pressed') {\n const distance = Math.hypot(dx, dy);\n if (pointerType === 'mouse') {\n if (distance <= MOUSE_DRAG_DISTANCE) return;\n if (drag === null) {\n phase = 'passive';\n return;\n }\n startDrag();\n } else {\n if (distance <= LOCK_DISTANCE) return;\n clearTimer();\n if (Math.abs(dx) <= Math.abs(dy) || !h().canSwipe?.()) {\n phase = 'passive';\n return;\n }\n phase = 'swiping';\n capture(primary);\n }\n }\n\n if (phase === 'swiping') {\n samples.push({ time: event.timeStamp, x: point.x });\n if (samples.length > 20) samples.shift();\n h().onSwipeMove?.(dx);\n } else if (phase === 'dragging') {\n h().onDragMove?.(point);\n }\n }\n\n function release(pointerId: number) {\n pointers.delete(pointerId);\n if (pointers.size === 0) {\n clearTimer();\n drag = null;\n phase = 'idle';\n }\n }\n\n function onPointerUp(event: PointerEvent) {\n if (!pointers.has(event.pointerId)) return;\n if (phase === 'pinching') {\n h().onPinchEnd?.();\n finishGesture();\n } else if (event.pointerId === primary) {\n if (phase === 'swiping') {\n samples.push({ time: event.timeStamp, x: event.clientX });\n h().onSwipeEnd?.(event.clientX - origin.x, velocityOf(samples, event.timeStamp));\n finishGesture();\n } else if (phase === 'dragging') {\n last = { x: event.clientX, y: event.clientY };\n h().onDragEnd?.(last);\n finishGesture();\n } else if (phase === 'pressed') {\n // Left to the click that follows, so a tap, a mouse click and Enter share one path.\n clearTimer();\n phase = 'passive';\n }\n }\n release(event.pointerId);\n }\n\n // The browser took the touch over, usually to scroll: whatever was in progress is undone.\n function onPointerCancel(event: PointerEvent) {\n if (!pointers.has(event.pointerId)) return;\n if (phase === 'swiping') {\n h().onSwipeEnd?.(0, 0);\n finishGesture();\n } else if (phase === 'dragging') {\n h().onDragCancel?.();\n finishGesture();\n } else if (phase === 'pinching') {\n h().onPinchEnd?.();\n finishGesture();\n } else {\n clearTimer();\n phase = 'passive';\n }\n release(event.pointerId);\n }\n\n // The only way to keep iOS Safari from scrolling under a drag that has already begun:\n // `touch-action` is read once, when the touch starts, so changing it mid-gesture does\n // nothing. Registered here at mount rather than on touchstart, so the area is already known\n // to block scrolling before the first touch arrives.\n function onTouchMove(event: TouchEvent) {\n if ((phase === 'swiping' || phase === 'dragging' || phase === 'pinching') && event.cancelable) {\n event.preventDefault();\n }\n }\n\n // Android opens the context menu on a long press, iOS the callout, both around the time a\n // drag arms.\n function onContextMenu(event: Event) {\n if (phase === 'dragging' || (phase === 'pressed' && pointerType !== 'mouse' && drag !== null)) {\n event.preventDefault();\n }\n }\n\n function onDragStartNative(event: Event) {\n event.preventDefault();\n }\n\n function onClickCapture(event: MouseEvent) {\n if (performance.now() < suppressUntil) {\n event.stopPropagation();\n event.preventDefault();\n suppressUntil = 0;\n }\n }\n\n function onScroll() {\n lastScroll = performance.now();\n }\n\n function onKeyDown(event: KeyboardEvent) {\n if (event.key !== 'Escape' || phase !== 'dragging') return;\n event.preventDefault();\n h().onDragCancel?.();\n finishGesture();\n }\n\n root.addEventListener('pointerdown', onPointerDown);\n root.addEventListener('pointermove', onPointerMove);\n root.addEventListener('pointerup', onPointerUp);\n root.addEventListener('pointercancel', onPointerCancel);\n root.addEventListener('touchmove', onTouchMove, { passive: false });\n root.addEventListener('contextmenu', onContextMenu);\n root.addEventListener('dragstart', onDragStartNative);\n root.addEventListener('click', onClickCapture, true);\n // `scroll` does not bubble, but it does pass through capturing listeners on the way down.\n root.addEventListener('scroll', onScroll, { capture: true, passive: true });\n window.addEventListener('scroll', onScroll, { passive: true });\n window.addEventListener('keydown', onKeyDown);\n return () => {\n clearTimer();\n cancelAnimationFrame(frame);\n root.removeEventListener('pointerdown', onPointerDown);\n root.removeEventListener('pointermove', onPointerMove);\n root.removeEventListener('pointerup', onPointerUp);\n root.removeEventListener('pointercancel', onPointerCancel);\n root.removeEventListener('touchmove', onTouchMove);\n root.removeEventListener('contextmenu', onContextMenu);\n root.removeEventListener('dragstart', onDragStartNative);\n root.removeEventListener('click', onClickCapture, true);\n root.removeEventListener('scroll', onScroll, { capture: true });\n window.removeEventListener('scroll', onScroll);\n window.removeEventListener('keydown', onKeyDown);\n };\n }, [ref]);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import e from"../hooks/useMediaQuery.mjs";import{useCallback as t,useEffect as n,useLayoutEffect as r,useRef as i}from"react";import{flushSync as a}from"react-dom";var o=240;function s(s,c,l){let u=i(new Set),d=i(0),f=i([]),p=i(0),m=i(s),h=e(`(prefers-reduced-motion: reduce)`),g=i({onPage:c,focusFallback:l,reducedMotion:h});r(()=>{g.current={onPage:c,focusFallback:l,reducedMotion:h}});let _=t(e=>{d.current=e;for(let t of u.current)t.style.transform=e===0?``:`translateX(${e}px)`},[]);r(()=>{m.current=s,_(0);let e=document.activeElement;e instanceof HTMLElement&&e.closest(`[inert]`)&&[...u.current].some(t=>t.contains(e))&&g.current.focusFallback()?.focus()},[s,_]);let v=t(e=>{if(e)return u.current.add(e),()=>{u.current.delete(e)}},[]),y=t(()=>{let[e]=u.current;return e?.parentElement?.clientWidth??0},[]),b=t(e=>{if(f.current=[],e===0){_(0);return}let t=m.current;a(()=>g.current.onPage(e)),m.current===t&&_(0)},[_]),x=t(e=>{let t=y(),n=d.current,r=e===0?0:-e*t,i=[...u.current];_(r);let a=typeof i[0]?.animate==`function`;if(g.current.reducedMotion||n===r||!a){b(e);return}let s=Math.max(120,o*Math.min(1,Math.abs(r-n)/Math.max(t,1))),c=[{transform:`translateX(${n}px)`},{transform:`translateX(${r}px)`}];p.current=e,f.current=i.map(e=>e.animate(c,{duration:s,easing:`cubic-bezier(0.25, 1, 0.5, 1)`})),f.current[0].onfinish=()=>b(e)},[b,y,_]),S=t(()=>{if(f.current.length!==0){for(let e of f.current)e.onfinish=null,e.cancel();b(p.current)}},[b]);return n(()=>{let e=f;return()=>{for(let t of e.current)t.onfinish=null,t.cancel()}},[]),{trackRef:v,width:y,move:t(e=>_(e),[_]),settle:x,finish:S}}export{s as usePager};
|
|
2
|
+
//# sourceMappingURL=usePager.mjs.map
|