@calchemy/date-react 0.1.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.
Files changed (78) hide show
  1. package/LICENSE +21 -0
  2. package/dist/calendar-scroll.d.ts +2 -0
  3. package/dist/calendar-scroll.d.ts.map +1 -0
  4. package/dist/calendar-scroll.js +225 -0
  5. package/dist/calendar-scroll.js.map +1 -0
  6. package/dist/chunk-KI7GMSS3.js +451 -0
  7. package/dist/chunk-KI7GMSS3.js.map +1 -0
  8. package/dist/chunk-NGJGJXY4.js +34 -0
  9. package/dist/chunk-NGJGJXY4.js.map +1 -0
  10. package/dist/components/Calchemy.d.ts +50 -0
  11. package/dist/components/Calchemy.d.ts.map +1 -0
  12. package/dist/components/Calchemy.js +57 -0
  13. package/dist/components/Calchemy.js.map +1 -0
  14. package/dist/components/calendar/Calendar.d.ts +19 -0
  15. package/dist/components/calendar/Calendar.d.ts.map +1 -0
  16. package/dist/components/calendar/Calendar.js +218 -0
  17. package/dist/components/calendar/Calendar.js.map +1 -0
  18. package/dist/components/calendar/CalendarGrid.d.ts +12 -0
  19. package/dist/components/calendar/CalendarGrid.d.ts.map +1 -0
  20. package/dist/components/calendar/CalendarGrid.js +93 -0
  21. package/dist/components/calendar/CalendarGrid.js.map +1 -0
  22. package/dist/components/calendar/CalendarPeriod.d.ts +6 -0
  23. package/dist/components/calendar/CalendarPeriod.d.ts.map +1 -0
  24. package/dist/components/calendar/CalendarPeriod.js +42 -0
  25. package/dist/components/calendar/CalendarPeriod.js.map +1 -0
  26. package/dist/components/calendar/CalendarPeriodHeading.d.ts +4 -0
  27. package/dist/components/calendar/CalendarPeriodHeading.d.ts.map +1 -0
  28. package/dist/components/calendar/CalendarPeriodHeading.js +9 -0
  29. package/dist/components/calendar/CalendarPeriodHeading.js.map +1 -0
  30. package/dist/components/calendar/CalendarPeriodList.d.ts +6 -0
  31. package/dist/components/calendar/CalendarPeriodList.d.ts.map +1 -0
  32. package/dist/components/calendar/CalendarPeriodList.js +93 -0
  33. package/dist/components/calendar/CalendarPeriodList.js.map +1 -0
  34. package/dist/components/calendar/CalendarScroll.d.ts +8 -0
  35. package/dist/components/calendar/CalendarScroll.d.ts.map +1 -0
  36. package/dist/components/calendar/CalendarScroll.js +115 -0
  37. package/dist/components/calendar/CalendarScroll.js.map +1 -0
  38. package/dist/components/calendar/CalendarSelects.d.ts +12 -0
  39. package/dist/components/calendar/CalendarSelects.d.ts.map +1 -0
  40. package/dist/components/calendar/CalendarSelects.js +31 -0
  41. package/dist/components/calendar/CalendarSelects.js.map +1 -0
  42. package/dist/components/calendar/calendar-period-drag.d.ts +74 -0
  43. package/dist/components/calendar/calendar-period-drag.d.ts.map +1 -0
  44. package/dist/components/calendar/calendar-period-drag.js +374 -0
  45. package/dist/components/calendar/calendar-period-drag.js.map +1 -0
  46. package/dist/components/calendar/context.d.ts +10 -0
  47. package/dist/components/calendar/context.d.ts.map +1 -0
  48. package/dist/components/calendar/context.js +23 -0
  49. package/dist/components/calendar/context.js.map +1 -0
  50. package/dist/components/calendar/date-model.d.ts +36 -0
  51. package/dist/components/calendar/date-model.d.ts.map +1 -0
  52. package/dist/components/calendar/date-model.js +257 -0
  53. package/dist/components/calendar/date-model.js.map +1 -0
  54. package/dist/components/calendar/scroll-preload.d.ts +10 -0
  55. package/dist/components/calendar/scroll-preload.d.ts.map +1 -0
  56. package/dist/components/calendar/scroll-preload.js +80 -0
  57. package/dist/components/calendar/scroll-preload.js.map +1 -0
  58. package/dist/components/calendar/types.d.ts +68 -0
  59. package/dist/components/calendar/types.d.ts.map +1 -0
  60. package/dist/components/calendar/types.js +2 -0
  61. package/dist/components/calendar/types.js.map +1 -0
  62. package/dist/hooks/useCalchemy.d.ts +52 -0
  63. package/dist/hooks/useCalchemy.d.ts.map +1 -0
  64. package/dist/hooks/useCalchemy.js +161 -0
  65. package/dist/hooks/useCalchemy.js.map +1 -0
  66. package/dist/hooks/useDebouncedValue.d.ts +3 -0
  67. package/dist/hooks/useDebouncedValue.d.ts.map +1 -0
  68. package/dist/hooks/useDebouncedValue.js +15 -0
  69. package/dist/hooks/useDebouncedValue.js.map +1 -0
  70. package/dist/index.d.ts +6 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/dist/index.js +3 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/inline-completion.d.ts +4 -0
  75. package/dist/inline-completion.d.ts.map +1 -0
  76. package/dist/inline-completion.js +7 -0
  77. package/dist/inline-completion.js.map +1 -0
  78. package/package.json +55 -0
@@ -0,0 +1,115 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useLayoutEffect, useRef, useState } from "react";
3
+ import { flushSync } from "react-dom";
4
+ import { CalendarScrollContext, useCalchemyCalendar } from "./context";
5
+ import { getCalendarPeriodWindowSize, getClientSize, getLoadedPeriodRunway, getScrollAnchorPeriod, getScrollPosition, getScrollSize, scrollPeriodIntoView, setScrollPosition, } from "./scroll-preload";
6
+ const preloadWindowCount = 2;
7
+ export function CalendarScroll({ direction = "vertical", onScroll, ...props }) {
8
+ const calendar = useCalchemyCalendar();
9
+ const scrollRef = useRef(null);
10
+ const [leadingSpacer, setLeadingSpacer] = useState({
11
+ periodCount: 0,
12
+ pixelSize: 0,
13
+ });
14
+ const positionedPeriodAnchor = useRef(null);
15
+ const suppressPreloadEvaluation = useRef(false);
16
+ const pendingPrependStabilization = useRef(null);
17
+ useLayoutEffect(() => {
18
+ const anchorKey = calendar.periodAnchor.toString();
19
+ if (positionedPeriodAnchor.current === anchorKey) {
20
+ return;
21
+ }
22
+ const element = scrollRef.current;
23
+ const currentPeriod = element?.querySelector("[calchemy-period][calchemy-period-index='0']");
24
+ if (!element || !currentPeriod) {
25
+ return;
26
+ }
27
+ positionedPeriodAnchor.current = anchorKey;
28
+ scrollPeriodIntoView(element, currentPeriod, direction);
29
+ }, [direction, calendar.periodAnchor, calendar.periods]);
30
+ function startBeforePreloadTransaction(element, preloadDirection, periodWindowSize) {
31
+ suppressPreloadEvaluation.current = true;
32
+ const extendPeriodCount = calendar.period.count * preloadWindowCount;
33
+ const previousScrollSize = getScrollSize(element, preloadDirection);
34
+ const previousScrollPosition = getScrollPosition(element, preloadDirection);
35
+ flushSync(() => {
36
+ setLeadingSpacer({
37
+ periodCount: extendPeriodCount,
38
+ pixelSize: periodWindowSize * preloadWindowCount,
39
+ });
40
+ });
41
+ setScrollPosition(element, preloadDirection, previousScrollPosition +
42
+ getScrollSize(element, preloadDirection) -
43
+ previousScrollSize);
44
+ flushSync(() => {
45
+ calendar.extendPeriods("before", preloadWindowCount);
46
+ setLeadingSpacer({ periodCount: 0, pixelSize: 0 });
47
+ });
48
+ const insertedDelta = getScrollSize(element, preloadDirection) - previousScrollSize;
49
+ const targetPosition = previousScrollPosition + insertedDelta;
50
+ setScrollPosition(element, preloadDirection, targetPosition);
51
+ pendingPrependStabilization.current = {
52
+ direction: preloadDirection,
53
+ insertedDelta,
54
+ targetPosition,
55
+ };
56
+ }
57
+ function stabilizePrependScrollEvent(element) {
58
+ const stabilization = pendingPrependStabilization.current;
59
+ if (!stabilization) {
60
+ suppressPreloadEvaluation.current = false;
61
+ return;
62
+ }
63
+ const observedPosition = getScrollPosition(element, stabilization.direction);
64
+ const targetDistance = observedPosition - stabilization.targetPosition;
65
+ const staleCoordinate = Math.abs(observedPosition +
66
+ stabilization.insertedDelta -
67
+ stabilization.targetPosition) < Math.abs(targetDistance);
68
+ if (staleCoordinate) {
69
+ setScrollPosition(element, stabilization.direction, observedPosition + stabilization.insertedDelta);
70
+ }
71
+ pendingPrependStabilization.current = null;
72
+ suppressPreloadEvaluation.current = false;
73
+ }
74
+ function handleScroll(event) {
75
+ onScroll?.(event);
76
+ if (event.defaultPrevented) {
77
+ return;
78
+ }
79
+ const element = event.currentTarget;
80
+ if (suppressPreloadEvaluation.current) {
81
+ stabilizePrependScrollEvent(element);
82
+ return;
83
+ }
84
+ if (getScrollSize(element, direction) <= getClientSize(element, direction)) {
85
+ return;
86
+ }
87
+ const anchor = getScrollAnchorPeriod(element, direction);
88
+ const anchorIndex = anchor?.getAttribute("calchemy-period-index")
89
+ ? Number(anchor.getAttribute("calchemy-period-index"))
90
+ : NaN;
91
+ if (Number.isFinite(anchorIndex)) {
92
+ calendar.setVisiblePeriodIndex(anchorIndex);
93
+ }
94
+ const periodWindowSize = getCalendarPeriodWindowSize(element, direction, calendar.period.count);
95
+ const startRunway = getLoadedPeriodRunway(calendar, anchor, "before");
96
+ const runwayThreshold = calendar.period.count * preloadWindowCount;
97
+ const endRunway = getLoadedPeriodRunway(calendar, anchor, "after");
98
+ if (startRunway !== null &&
99
+ startRunway <= runwayThreshold &&
100
+ calendar.canExtendPeriods("before", preloadWindowCount)) {
101
+ startBeforePreloadTransaction(element, direction, periodWindowSize);
102
+ }
103
+ if (endRunway !== null &&
104
+ endRunway <= runwayThreshold &&
105
+ calendar.canExtendPeriods("after", preloadWindowCount)) {
106
+ calendar.extendPeriods("after", preloadWindowCount);
107
+ }
108
+ }
109
+ return (_jsx(CalendarScrollContext.Provider, { value: {
110
+ direction,
111
+ leadingSpacerPeriodCount: leadingSpacer.periodCount,
112
+ leadingSpacerPixelSize: leadingSpacer.pixelSize,
113
+ }, children: _jsx("div", { ...props, ref: scrollRef, "calchemy-scroll": "", "calchemy-direction": direction, onScroll: handleScroll }) }));
114
+ }
115
+ //# sourceMappingURL=CalendarScroll.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalendarScroll.js","sourceRoot":"","sources":["../../../src/components/calendar/CalendarScroll.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { ComponentPropsWithoutRef } from "react";
2
+ export type CalchemyCalendarMonthSelectProps = Omit<ComponentPropsWithoutRef<"select">, "value" | "onChange"> & {
3
+ onChange?: ComponentPropsWithoutRef<"select">["onChange"];
4
+ };
5
+ export declare function CalendarMonthSelect({ onChange, ...props }: CalchemyCalendarMonthSelectProps): import("react/jsx-runtime").JSX.Element;
6
+ export type CalchemyCalendarYearSelectProps = Omit<ComponentPropsWithoutRef<"select">, "value" | "onChange"> & {
7
+ startYear?: number;
8
+ endYear?: number;
9
+ onChange?: ComponentPropsWithoutRef<"select">["onChange"];
10
+ };
11
+ export declare function CalendarYearSelect({ startYear, endYear, onChange, ...props }: CalchemyCalendarYearSelectProps): import("react/jsx-runtime").JSX.Element;
12
+ //# sourceMappingURL=CalendarSelects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalendarSelects.d.ts","sourceRoot":"","sources":["../../../src/components/calendar/CalendarSelects.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAe,MAAM,OAAO,CAAC;AAInE,MAAM,MAAM,gCAAgC,GAAG,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC,GAAG;IAC9G,QAAQ,CAAC,EAAE,wBAAwB,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC;CAC3D,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,gCAAgC,2CA2B3F;AAED,MAAM,MAAM,+BAA+B,GAAG,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC,GAAG;IAC7G,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,wBAAwB,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC;CAC3D,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,+BAA+B,2CAwB7G"}
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useCalchemyCalendar } from "./context";
3
+ import { formatMonthLabel, isAfter, isBefore } from "./date-model";
4
+ export function CalendarMonthSelect({ onChange, ...props }) {
5
+ const calendar = useCalchemyCalendar();
6
+ const months = Array.from({ length: 12 }, (_, index) => index + 1).filter((month) => isMonthWithinBounds(calendar.visiblePeriodAnchor.with({ month, day: 1 }), calendar));
7
+ return (_jsx("select", { ...props, "calchemy-month-select": "", value: String(calendar.visiblePeriodAnchor.month), onChange: (event) => handleCalendarSelectChange(event, onChange, (value) => calendar.setPeriodAnchor(calendar.visiblePeriodAnchor.with({ month: value, day: 1 }))), children: months.map((month) => {
8
+ const date = calendar.visiblePeriodAnchor.with({ month, day: 1 });
9
+ return (_jsx("option", { value: String(month), children: formatMonthLabel(date, calendar.locale) }, month));
10
+ }) }));
11
+ }
12
+ export function CalendarYearSelect({ startYear, endYear, onChange, ...props }) {
13
+ const calendar = useCalchemyCalendar();
14
+ const visibleYear = calendar.visiblePeriodAnchor.year;
15
+ const firstYear = Math.min(calendar.bounds?.start?.year ?? startYear ?? visibleYear - 100, visibleYear);
16
+ const lastYear = Math.max(calendar.bounds?.end?.year ?? endYear ?? visibleYear + 100, visibleYear);
17
+ return (_jsx("select", { ...props, "calchemy-year-select": "", value: String(visibleYear), onChange: (event) => handleCalendarSelectChange(event, onChange, (value) => calendar.setPeriodAnchor(calendar.visiblePeriodAnchor.with({ year: value, day: 1 }))), children: Array.from({ length: lastYear - firstYear + 1 }, (_, index) => firstYear + index).map((year) => (_jsx("option", { value: String(year), children: year }, year))) }));
18
+ }
19
+ function handleCalendarSelectChange(event, onChange, updatePeriodAnchor) {
20
+ onChange?.(event);
21
+ if (event.defaultPrevented) {
22
+ return;
23
+ }
24
+ updatePeriodAnchor(Number(event.currentTarget.value));
25
+ }
26
+ function isMonthWithinBounds(monthStart, calendar) {
27
+ const monthEnd = monthStart.add({ months: 1 }).subtract({ days: 1 });
28
+ return ((!calendar.bounds?.start || !isBefore(monthEnd, calendar.bounds.start)) &&
29
+ (!calendar.bounds?.end || !isAfter(monthStart, calendar.bounds.end)));
30
+ }
31
+ //# sourceMappingURL=CalendarSelects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalendarSelects.js","sourceRoot":"","sources":["../../../src/components/calendar/CalendarSelects.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ import { type PointerEvent, type RefObject } from "react";
2
+ import type { DateValue, PlainDate } from "@calchemy/date-core";
3
+ type Point = {
4
+ x: number;
5
+ y: number;
6
+ };
7
+ type CellBounds = {
8
+ left: number;
9
+ right: number;
10
+ top: number;
11
+ bottom: number;
12
+ };
13
+ type DragState = {
14
+ pointerId: number;
15
+ start: Point;
16
+ current: Point;
17
+ baseDates: PlainDate[];
18
+ previewKeys: string[];
19
+ hasMoved: boolean;
20
+ startDayCell: DayCell | null;
21
+ cellBounds: ReadonlyMap<string, CellBounds>;
22
+ };
23
+ type DayCell = {
24
+ date: PlainDate;
25
+ disabled: boolean;
26
+ element: HTMLButtonElement;
27
+ };
28
+ type DragRectangle = {
29
+ start: Point;
30
+ current: Point;
31
+ };
32
+ export type CalendarPeriodDragContextValue = {
33
+ multipleSelection: boolean;
34
+ dragState: DragState | null;
35
+ dragRectangle: DragRectangle | null;
36
+ previewSelectedKeys: ReadonlySet<string>;
37
+ suppressClickRef: RefObject<boolean>;
38
+ surfaceRef: RefObject<HTMLElement | null>;
39
+ registerDay(element: HTMLButtonElement | null, date: PlainDate, disabled: boolean): void;
40
+ handlePointerDownCapture(event: PointerEvent<HTMLElement>): void;
41
+ handlePointerMove(event: PointerEvent<HTMLElement>): void;
42
+ handlePointerUp(event: PointerEvent<HTMLElement>): void;
43
+ handlePointerCancel(event: PointerEvent<HTMLElement>): void;
44
+ };
45
+ export declare const multipleDragSurfaceStyle: {
46
+ readonly position: "relative";
47
+ readonly userSelect: "none";
48
+ readonly WebkitUserSelect: "none";
49
+ readonly touchAction: "none";
50
+ };
51
+ export declare const multiplePeriodListDragSurfaceStyle: {
52
+ readonly position: "relative";
53
+ readonly background: "transparent";
54
+ readonly userSelect: "none";
55
+ readonly WebkitUserSelect: "none";
56
+ readonly touchAction: "none";
57
+ };
58
+ export declare function useOptionalCalendarPeriodDrag(): CalendarPeriodDragContextValue | null;
59
+ export declare function useCalendarPeriodDragSurface(dragSelection?: boolean, surfaceElementRef?: RefObject<HTMLElement | null>): CalendarPeriodDragContextValue | null;
60
+ export type CalendarDragRectangleOverlayProps = {
61
+ dragRectangle?: DragRectangle | null;
62
+ surfaceRef?: RefObject<HTMLElement | null>;
63
+ };
64
+ export declare function CalendarDragRectangleOverlay({ dragRectangle: dragRectangleProp, surfaceRef: surfaceRefProp, }?: CalendarDragRectangleOverlayProps): import("react/jsx-runtime").JSX.Element | null;
65
+ export type CalendarPeriodDragProviderProps = {
66
+ value: CalendarPeriodDragContextValue;
67
+ children: React.ReactNode;
68
+ };
69
+ export declare function CalendarPeriodDragProvider({ value, children }: CalendarPeriodDragProviderProps): import("react/jsx-runtime").JSX.Element;
70
+ export declare function getMultipleDates(value: DateValue | null): PlainDate[];
71
+ export declare function getSelectedDateKeys(value: DateValue | null): string[];
72
+ export declare function toggleDateKeys(baseKeys: readonly string[], toggledKeys: readonly string[]): string[];
73
+ export {};
74
+ //# sourceMappingURL=calendar-period-drag.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-period-drag.d.ts","sourceRoot":"","sources":["../../../src/components/calendar/calendar-period-drag.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGhE,KAAK,KAAK,GAAG;IACX,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,KAAK,SAAS,GAAG;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,KAAK,CAAC;IACf,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CAC7C,CAAC;AAEF,KAAK,OAAO,GAAG;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,iBAAiB,CAAC;CAC5B,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,KAAK,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG;IAC3C,iBAAiB,EAAE,OAAO,CAAC;IAC3B,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IACpC,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACzC,gBAAgB,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IACrC,UAAU,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC1C,WAAW,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IACzF,wBAAwB,CAAC,KAAK,EAAE,YAAY,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;IACjE,iBAAiB,CAAC,KAAK,EAAE,YAAY,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;IAC1D,eAAe,CAAC,KAAK,EAAE,YAAY,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;IACxD,mBAAmB,CAAC,KAAK,EAAE,YAAY,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;CAC7D,CAAC;AAIF,eAAO,MAAM,wBAAwB;;;;;CAK3B,CAAC;AAEX,eAAO,MAAM,kCAAkC;;;;;;CAIrC,CAAC;AAEX,wBAAgB,6BAA6B,IAAI,8BAA8B,GAAG,IAAI,CAErF;AAED,wBAAgB,4BAA4B,CAC1C,aAAa,UAAO,EACpB,iBAAiB,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,GAChD,8BAA8B,GAAG,IAAI,CAwRvC;AAED,MAAM,MAAM,iCAAiC,GAAG;IAC9C,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,UAAU,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CAC5C,CAAC;AAEF,wBAAgB,4BAA4B,CAAC,EAC3C,aAAa,EAAE,iBAAiB,EAChC,UAAU,EAAE,cAAc,GAC3B,GAAE,iCAAsC,kDAmCxC;AAED,MAAM,MAAM,+BAA+B,GAAG;IAC5C,KAAK,EAAE,8BAA8B,CAAC;IACtC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF,wBAAgB,0BAA0B,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,+BAA+B,2CAI9F;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,EAAE,CAErE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,MAAM,EAAE,CAErE;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAAE,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAWpG"}
@@ -0,0 +1,374 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useCallback, useContext, useMemo, useRef, useState, } from "react";
3
+ import { useCalchemyCalendar } from "./context";
4
+ const CalendarPeriodDragContext = createContext(null);
5
+ export const multipleDragSurfaceStyle = {
6
+ position: "relative",
7
+ userSelect: "none",
8
+ WebkitUserSelect: "none",
9
+ touchAction: "none",
10
+ };
11
+ export const multiplePeriodListDragSurfaceStyle = {
12
+ ...multipleDragSurfaceStyle,
13
+ position: "relative",
14
+ background: "transparent",
15
+ };
16
+ export function useOptionalCalendarPeriodDrag() {
17
+ return useContext(CalendarPeriodDragContext);
18
+ }
19
+ export function useCalendarPeriodDragSurface(dragSelection = true, surfaceElementRef) {
20
+ const calendar = useCalchemyCalendar();
21
+ const multipleSelection = dragSelection && calendar.calchemy.expectedValue === "multiple";
22
+ const surfaceRef = useRef(null);
23
+ const dayCells = useRef(new Map());
24
+ const suppressClickRef = useRef(false);
25
+ const dragStateRef = useRef(null);
26
+ const dragPreviewFrameRef = useRef(null);
27
+ const dragGestureCleanupRef = useRef(null);
28
+ const [dragState, setDragState] = useState(null);
29
+ const [dragRectangle, setDragRectangle] = useState(null);
30
+ const previewSelectedKeys = useMemo(() => new Set(dragState?.previewKeys ?? []), [dragState]);
31
+ const acquireDragGestureLock = useCallback(() => {
32
+ if (dragGestureCleanupRef.current || typeof document === "undefined") {
33
+ return;
34
+ }
35
+ const preventGestureDefault = (event) => {
36
+ event.preventDefault();
37
+ };
38
+ const clearDocumentSelection = () => {
39
+ document.getSelection()?.removeAllRanges();
40
+ };
41
+ const previousBodyUserSelect = document.body.style.userSelect;
42
+ const previousDocumentUserSelect = document.documentElement.style.userSelect;
43
+ document.body.style.userSelect = "none";
44
+ document.documentElement.style.userSelect = "none";
45
+ document.addEventListener("pointermove", preventGestureDefault, { capture: true, passive: false });
46
+ document.addEventListener("touchmove", preventGestureDefault, { capture: true, passive: false });
47
+ document.addEventListener("wheel", preventGestureDefault, { capture: true, passive: false });
48
+ document.addEventListener("selectstart", preventGestureDefault, { capture: true });
49
+ document.addEventListener("dragstart", preventGestureDefault, { capture: true });
50
+ clearDocumentSelection();
51
+ dragGestureCleanupRef.current = () => {
52
+ document.removeEventListener("pointermove", preventGestureDefault, { capture: true });
53
+ document.removeEventListener("touchmove", preventGestureDefault, { capture: true });
54
+ document.removeEventListener("wheel", preventGestureDefault, { capture: true });
55
+ document.removeEventListener("selectstart", preventGestureDefault, { capture: true });
56
+ document.removeEventListener("dragstart", preventGestureDefault, { capture: true });
57
+ document.body.style.userSelect = previousBodyUserSelect;
58
+ document.documentElement.style.userSelect = previousDocumentUserSelect;
59
+ clearDocumentSelection();
60
+ dragGestureCleanupRef.current = null;
61
+ };
62
+ }, []);
63
+ const releaseDragGestureLock = useCallback(() => {
64
+ dragGestureCleanupRef.current?.();
65
+ if (dragPreviewFrameRef.current !== null) {
66
+ cancelAnimationFrame(dragPreviewFrameRef.current);
67
+ dragPreviewFrameRef.current = null;
68
+ }
69
+ }, []);
70
+ const scheduleDragPreviewUpdate = useCallback((nextDragState) => {
71
+ dragStateRef.current = nextDragState;
72
+ if (dragPreviewFrameRef.current !== null) {
73
+ return;
74
+ }
75
+ dragPreviewFrameRef.current = requestAnimationFrame(() => {
76
+ setDragState(dragStateRef.current);
77
+ dragPreviewFrameRef.current = null;
78
+ });
79
+ }, []);
80
+ const registerDay = useCallback((element, date, disabled) => {
81
+ const key = date.toString();
82
+ if (element) {
83
+ dayCells.current.set(key, { date, disabled, element });
84
+ return;
85
+ }
86
+ dayCells.current.delete(key);
87
+ }, []);
88
+ const getDayCellFromTarget = useCallback((target) => {
89
+ if (!(target instanceof Element)) {
90
+ return null;
91
+ }
92
+ const button = target.closest("[calchemy-date]");
93
+ if (!(button instanceof HTMLButtonElement)) {
94
+ return null;
95
+ }
96
+ for (const cell of dayCells.current.values()) {
97
+ if (cell.element === button) {
98
+ return cell;
99
+ }
100
+ }
101
+ return null;
102
+ }, []);
103
+ const commitMultipleSelection = useCallback((keys, fallbackDates = []) => {
104
+ const dates = resolveDateKeys(keys, dayCells.current, fallbackDates);
105
+ calendar.selectValue({
106
+ kind: "multiple",
107
+ dates,
108
+ });
109
+ }, [calendar]);
110
+ const endDragGesture = useCallback((pointerId) => {
111
+ if (pointerId !== undefined) {
112
+ surfaceRef.current?.releasePointerCapture?.(pointerId);
113
+ }
114
+ releaseDragGestureLock();
115
+ dragStateRef.current = null;
116
+ setDragState(null);
117
+ setDragRectangle(null);
118
+ }, [releaseDragGestureLock]);
119
+ const handlePointerMove = useCallback((event) => {
120
+ const activeDrag = dragStateRef.current;
121
+ if (!multipleSelection || !activeDrag || event.pointerId !== activeDrag.pointerId) {
122
+ return;
123
+ }
124
+ event.preventDefault();
125
+ const current = getPointerPoint(event);
126
+ setDragRectangle({ start: activeDrag.start, current });
127
+ const dragRect = getDragRect(activeDrag.start, current);
128
+ const clipRect = getDragClipRect(surfaceRef.current);
129
+ const gestureKeys = getIntersectingDateKeys(dayCells.current, dragRect, activeDrag.cellBounds, clipRect);
130
+ const baseKeys = activeDrag.baseDates.map((date) => date.toString());
131
+ const previewKeys = toggleDateKeys(baseKeys, gestureKeys);
132
+ const hasMoved = activeDrag.hasMoved || hasPointerMoved(activeDrag.start, current);
133
+ scheduleDragPreviewUpdate({
134
+ ...activeDrag,
135
+ current,
136
+ previewKeys,
137
+ hasMoved,
138
+ });
139
+ }, [multipleSelection, scheduleDragPreviewUpdate]);
140
+ const handlePointerDownCapture = useCallback((event) => {
141
+ if (!multipleSelection || event.button !== 0 || !event.isPrimary) {
142
+ return;
143
+ }
144
+ const baseDates = getMultipleDates(calendar.selected);
145
+ event.preventDefault();
146
+ if (typeof document !== "undefined") {
147
+ document.getSelection()?.removeAllRanges();
148
+ }
149
+ surfaceRef.current = surfaceElementRef?.current ?? event.currentTarget;
150
+ surfaceRef.current?.setPointerCapture?.(event.pointerId);
151
+ acquireDragGestureLock();
152
+ const nextDragState = {
153
+ pointerId: event.pointerId,
154
+ start: getPointerPoint(event),
155
+ current: getPointerPoint(event),
156
+ baseDates,
157
+ previewKeys: baseDates.map((selectedDate) => selectedDate.toString()),
158
+ hasMoved: false,
159
+ startDayCell: getDayCellFromTarget(event.target),
160
+ cellBounds: snapshotCellBounds(dayCells.current),
161
+ };
162
+ dragStateRef.current = nextDragState;
163
+ setDragState(nextDragState);
164
+ setDragRectangle({
165
+ start: nextDragState.start,
166
+ current: nextDragState.current,
167
+ });
168
+ }, [acquireDragGestureLock, calendar.selected, getDayCellFromTarget, multipleSelection, surfaceElementRef]);
169
+ const handlePointerUp = useCallback((event) => {
170
+ const activeDrag = dragStateRef.current;
171
+ if (!multipleSelection || !activeDrag || event.pointerId !== activeDrag.pointerId) {
172
+ return;
173
+ }
174
+ if (dragPreviewFrameRef.current !== null) {
175
+ cancelAnimationFrame(dragPreviewFrameRef.current);
176
+ dragPreviewFrameRef.current = null;
177
+ setDragState(activeDrag);
178
+ }
179
+ event.preventDefault();
180
+ suppressClickRef.current = true;
181
+ setTimeout(() => {
182
+ suppressClickRef.current = false;
183
+ }, 0);
184
+ if (activeDrag.hasMoved) {
185
+ commitMultipleSelection(activeDrag.previewKeys, activeDrag.baseDates);
186
+ }
187
+ else {
188
+ const dayCell = activeDrag.startDayCell;
189
+ if (dayCell && !dayCell.disabled) {
190
+ const selectedDates = getMultipleDates(calendar.selected);
191
+ const nextKeys = toggleDateKeys(selectedDates.map((selectedDate) => selectedDate.toString()), [dayCell.date.toString()]);
192
+ commitMultipleSelection(nextKeys, selectedDates.concat(dayCell.date));
193
+ }
194
+ }
195
+ endDragGesture(event.pointerId);
196
+ const focused = document.activeElement;
197
+ if (focused instanceof HTMLElement && event.currentTarget.contains(focused)) {
198
+ focused.blur();
199
+ }
200
+ }, [calendar.selected, commitMultipleSelection, endDragGesture, getDayCellFromTarget, multipleSelection]);
201
+ const handlePointerCancel = useCallback((event) => {
202
+ const activeDrag = dragStateRef.current;
203
+ if (!activeDrag || event.pointerId !== activeDrag.pointerId) {
204
+ return;
205
+ }
206
+ endDragGesture(event.pointerId);
207
+ }, [endDragGesture]);
208
+ return useMemo(() => {
209
+ if (!multipleSelection) {
210
+ return null;
211
+ }
212
+ return {
213
+ multipleSelection,
214
+ dragState,
215
+ dragRectangle,
216
+ previewSelectedKeys,
217
+ suppressClickRef,
218
+ surfaceRef,
219
+ registerDay,
220
+ handlePointerDownCapture,
221
+ handlePointerMove,
222
+ handlePointerUp,
223
+ handlePointerCancel,
224
+ };
225
+ }, [
226
+ dragRectangle,
227
+ dragState,
228
+ handlePointerCancel,
229
+ handlePointerDownCapture,
230
+ handlePointerMove,
231
+ handlePointerUp,
232
+ multipleSelection,
233
+ previewSelectedKeys,
234
+ registerDay,
235
+ ]);
236
+ }
237
+ export function CalendarDragRectangleOverlay({ dragRectangle: dragRectangleProp, surfaceRef: surfaceRefProp, } = {}) {
238
+ const drag = useOptionalCalendarPeriodDrag();
239
+ const dragRectangle = dragRectangleProp ?? drag?.dragRectangle ?? null;
240
+ const surfaceRef = surfaceRefProp ?? drag?.surfaceRef;
241
+ if (!dragRectangle) {
242
+ return null;
243
+ }
244
+ const surface = surfaceRef?.current;
245
+ if (!surface) {
246
+ return null;
247
+ }
248
+ const surfaceRect = surface.getBoundingClientRect();
249
+ const left = Math.min(dragRectangle.start.x, dragRectangle.current.x) - surfaceRect.left;
250
+ const top = Math.min(dragRectangle.start.y, dragRectangle.current.y) - surfaceRect.top;
251
+ const width = Math.abs(dragRectangle.current.x - dragRectangle.start.x);
252
+ const height = Math.abs(dragRectangle.current.y - dragRectangle.start.y);
253
+ return (_jsx("div", { "aria-hidden": "true", "calchemy-drag-rect": "", style: {
254
+ position: "absolute",
255
+ left,
256
+ top,
257
+ width,
258
+ height,
259
+ pointerEvents: "none",
260
+ boxSizing: "border-box",
261
+ } }));
262
+ }
263
+ export function CalendarPeriodDragProvider({ value, children }) {
264
+ return (_jsx(CalendarPeriodDragContext.Provider, { value: value, children: children }));
265
+ }
266
+ export function getMultipleDates(value) {
267
+ return value?.kind === "multiple" ? value.dates : [];
268
+ }
269
+ export function getSelectedDateKeys(value) {
270
+ return getMultipleDates(value).map((date) => date.toString());
271
+ }
272
+ export function toggleDateKeys(baseKeys, toggledKeys) {
273
+ const next = new Set(baseKeys);
274
+ for (const key of toggledKeys) {
275
+ if (next.has(key)) {
276
+ next.delete(key);
277
+ }
278
+ else {
279
+ next.add(key);
280
+ }
281
+ }
282
+ return Array.from(next).sort();
283
+ }
284
+ function getPointerPoint(event) {
285
+ return { x: event.clientX, y: event.clientY };
286
+ }
287
+ function hasPointerMoved(start, current) {
288
+ return Math.abs(start.x - current.x) > 2 || Math.abs(start.y - current.y) > 2;
289
+ }
290
+ function getDragRect(start, current) {
291
+ const left = Math.min(start.x, current.x);
292
+ const right = Math.max(start.x, current.x);
293
+ const top = Math.min(start.y, current.y);
294
+ const bottom = Math.max(start.y, current.y);
295
+ return {
296
+ left,
297
+ right,
298
+ top,
299
+ bottom,
300
+ x: left,
301
+ y: top,
302
+ width: right - left,
303
+ height: bottom - top,
304
+ toJSON: () => ({}),
305
+ };
306
+ }
307
+ function snapshotCellBounds(cells) {
308
+ const bounds = new Map();
309
+ for (const [key, cell] of cells) {
310
+ const rect = cell.element.getBoundingClientRect();
311
+ bounds.set(key, {
312
+ left: rect.left,
313
+ right: rect.right,
314
+ top: rect.top,
315
+ bottom: rect.bottom,
316
+ });
317
+ }
318
+ return bounds;
319
+ }
320
+ function getDragClipRect(surface) {
321
+ if (!surface) {
322
+ return null;
323
+ }
324
+ const scrollContainer = surface.closest("[calchemy-scroll]");
325
+ if (!(scrollContainer instanceof HTMLElement)) {
326
+ return null;
327
+ }
328
+ const rect = scrollContainer.getBoundingClientRect();
329
+ return {
330
+ left: rect.left,
331
+ right: rect.right,
332
+ top: rect.top,
333
+ bottom: rect.bottom,
334
+ };
335
+ }
336
+ function clipBoundsToRect(bounds, clip) {
337
+ const left = Math.max(bounds.left, clip.left);
338
+ const right = Math.min(bounds.right, clip.right);
339
+ const top = Math.max(bounds.top, clip.top);
340
+ const bottom = Math.min(bounds.bottom, clip.bottom);
341
+ if (left > right || top > bottom) {
342
+ return null;
343
+ }
344
+ return { left, right, top, bottom };
345
+ }
346
+ function getIntersectingDateKeys(cells, dragRect, cellBounds, clipRect = null) {
347
+ const clippedDragRect = clipRect ? clipBoundsToRect(dragRect, clipRect) : dragRect;
348
+ if (!clippedDragRect) {
349
+ return [];
350
+ }
351
+ return Array.from(cells.entries())
352
+ .filter(([key, cell]) => {
353
+ const bounds = cellBounds.get(key);
354
+ if (!bounds || cell.disabled) {
355
+ return false;
356
+ }
357
+ const visibleBounds = clipRect ? clipBoundsToRect(bounds, clipRect) : bounds;
358
+ return visibleBounds && rectsIntersect(clippedDragRect, visibleBounds);
359
+ })
360
+ .map(([key]) => key);
361
+ }
362
+ function rectsIntersect(left, right) {
363
+ return left.left <= right.right && left.right >= right.left && left.top <= right.bottom && left.bottom >= right.top;
364
+ }
365
+ function resolveDateKeys(keys, cells, fallbackDates) {
366
+ const fallbackByKey = new Map(fallbackDates.map((date) => [date.toString(), date]));
367
+ return Array.from(keys)
368
+ .sort()
369
+ .flatMap((key) => {
370
+ const date = cells.get(key)?.date ?? fallbackByKey.get(key);
371
+ return date ? [date] : [];
372
+ });
373
+ }
374
+ //# sourceMappingURL=calendar-period-drag.js.map