@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,37 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
export interface GesturePoint {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
}
|
|
6
|
+
export interface GestureHandlers<D> {
|
|
7
|
+
/** Every press that starts a gesture, before anything else: where a running settle is finished. */
|
|
8
|
+
onPress?: () => void;
|
|
9
|
+
/** Whether a horizontal swipe may page right now. */
|
|
10
|
+
canSwipe?: () => boolean;
|
|
11
|
+
onSwipeMove?: (dx: number) => void;
|
|
12
|
+
/** Also called with `(0, 0)` when the browser takes the gesture over. */
|
|
13
|
+
onSwipeEnd?: (dx: number, velocity: number) => void;
|
|
14
|
+
/** What a press on `target` would pick up, or `null` where nothing can be dragged. */
|
|
15
|
+
dragFrom?: (target: Element, point: GesturePoint) => D | null;
|
|
16
|
+
onDragStart?: (drag: D, point: GesturePoint) => void;
|
|
17
|
+
onDragMove?: (point: GesturePoint) => void;
|
|
18
|
+
onDragEnd?: (point: GesturePoint) => void;
|
|
19
|
+
onDragCancel?: () => void;
|
|
20
|
+
onPinchStart?: (center: GesturePoint, distance: number) => void;
|
|
21
|
+
onPinchMove?: (center: GesturePoint, distance: number) => void;
|
|
22
|
+
onPinchEnd?: () => void;
|
|
23
|
+
/** The element a drag scrolls near its edges, and the band of the viewport that counts as its inside. */
|
|
24
|
+
autoScroll?: () => {
|
|
25
|
+
element: HTMLElement;
|
|
26
|
+
top: number;
|
|
27
|
+
bottom: number;
|
|
28
|
+
} | null;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* One owner for every pointer gesture inside `ref`, so a swipe, a long-press drag, a pinch and
|
|
32
|
+
* the browser's own scrolling can never both act on the same touch.
|
|
33
|
+
*
|
|
34
|
+
* Mouse or touch rules are chosen per event from `pointerType`, not once from a media query,
|
|
35
|
+
* which answers wrongly on a laptop with a touch screen.
|
|
36
|
+
*/
|
|
37
|
+
export declare function useGestures<D>(ref: RefObject<HTMLElement | null>, handlers: GestureHandlers<D>): void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface Pager {
|
|
2
|
+
/** Ref for each element that slides. The time grid has two, its head and its body. */
|
|
3
|
+
trackRef: (element: HTMLElement | null) => void;
|
|
4
|
+
/** Width of one pane. */
|
|
5
|
+
width: () => number;
|
|
6
|
+
/** Offset every track by `dx` px, following the finger. */
|
|
7
|
+
move: (dx: number) => void;
|
|
8
|
+
/** Animate to the next (`1`) or previous (`-1`) pane and page, or back (`0`). */
|
|
9
|
+
settle: (step: -1 | 0 | 1) => void;
|
|
10
|
+
/** Jump to the end of a running settle: a new press arrived before it finished. */
|
|
11
|
+
finish: () => void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Drives the three panes a pageable view renders: previous, current and next, keyed by period, so
|
|
15
|
+
* after paging the pane that slid in is the same DOM node as the one now current. The track is
|
|
16
|
+
* reset in the same commit that swaps them, which is why nothing flashes.
|
|
17
|
+
*
|
|
18
|
+
* `focusFallback` receives focus when it would otherwise be left inside a pane that just went inert.
|
|
19
|
+
*/
|
|
20
|
+
export declare function usePager(periodKey: string, onPage: (step: 1 | -1) => void, focusFallback: () => HTMLElement | null): Pager;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { SlotClassNames, SlotStyles } from '../types/slots.types.js';
|
|
3
|
+
import { CalendarEvent, CalendarEventChange, CalendarEventContext, CalendarLabels, CalendarSlot, CalendarSlots, CalendarView, CalendarWeekStart } from './calendar.types.js';
|
|
4
|
+
/** What Calendar hands each of its views. Internal, so it stays out of the published types. */
|
|
5
|
+
export interface CalendarViewProps<E extends CalendarEvent = CalendarEvent> {
|
|
6
|
+
events: readonly E[];
|
|
7
|
+
/** Local midnight of the selected day. */
|
|
8
|
+
date: Date;
|
|
9
|
+
view: CalendarView;
|
|
10
|
+
locale: string | undefined;
|
|
11
|
+
weekStartsOn: CalendarWeekStart;
|
|
12
|
+
slotMinutes: number;
|
|
13
|
+
/** Weekdays left out, as `Date#getDay()` counts. `date` is never one of them. */
|
|
14
|
+
hidden: ReadonlySet<number>;
|
|
15
|
+
scrollToHour: number | undefined;
|
|
16
|
+
text: Required<CalendarLabels>;
|
|
17
|
+
onDateChange: (date: Date) => void;
|
|
18
|
+
/** Opens a day in the Day view, or `undefined` where the Day view is not offered. */
|
|
19
|
+
onOpenDay: ((date: Date) => void) | undefined;
|
|
20
|
+
onEventClick: ((event: E, anchor: HTMLElement) => void) | undefined;
|
|
21
|
+
onEventChange: ((change: CalendarEventChange<E>) => void) | undefined;
|
|
22
|
+
onSlotCreate: ((slot: CalendarSlot, anchor: HTMLElement) => void) | undefined;
|
|
23
|
+
renderEvent: ((event: E, context: CalendarEventContext) => ReactNode) | undefined;
|
|
24
|
+
classNames: SlotClassNames<CalendarSlots> | undefined;
|
|
25
|
+
slotStyles: SlotStyles<CalendarSlots> | undefined;
|
|
26
|
+
}
|
|
@@ -15,6 +15,7 @@ import { SearchInputLabels } from '../searchInput/searchInput.types.js';
|
|
|
15
15
|
import { TooltipLabels } from '../tooltip/tooltip.types.js';
|
|
16
16
|
import { VirtualListLabels } from '../virtualList/virtualList.types.js';
|
|
17
17
|
import { ButtonProps } from '../button/button.types.js';
|
|
18
|
+
import { CalendarDefaults } from '../calendar/calendar.types.js';
|
|
18
19
|
import { CopyButtonProps } from '../copyButton/copyButton.types.js';
|
|
19
20
|
import { CommandPaletteProps } from '../commandPalette/commandPalette.types.js';
|
|
20
21
|
import { WeatherIconProps } from '../weatherIcon/weatherIcon.types.js';
|
|
@@ -84,6 +85,8 @@ export interface ComponentDefaults {
|
|
|
84
85
|
VirtualList?: {
|
|
85
86
|
labels?: VirtualListLabels;
|
|
86
87
|
};
|
|
88
|
+
/** Not `Partial<CalendarProps>`: the rest of its props depend on the event type. */
|
|
89
|
+
Calendar?: CalendarDefaults;
|
|
87
90
|
Input?: Partial<InputProps>;
|
|
88
91
|
Textarea?: Partial<TextareaProps>;
|
|
89
92
|
NumberInput?: Partial<NumberInputProps>;
|
|
@@ -14,7 +14,7 @@ export interface ConfirmModalProps extends Omit<HtmlProps<HTMLDivElement>, 'onCl
|
|
|
14
14
|
style?: CSSProperties;
|
|
15
15
|
onClose?: (didSubmit: boolean) => void;
|
|
16
16
|
onConfirm?: () => void | Promise<void>;
|
|
17
|
-
title?:
|
|
17
|
+
title?: ReactNode;
|
|
18
18
|
content?: ReactNode;
|
|
19
19
|
isOpen?: boolean;
|
|
20
20
|
isDelete?: boolean;
|
|
@@ -19,9 +19,9 @@ export interface ErrorBoundaryLabels {
|
|
|
19
19
|
copied?: string;
|
|
20
20
|
/** Reset button label. Default: "Try again". */
|
|
21
21
|
reset?: string;
|
|
22
|
-
/** Toast shown after a successful copy
|
|
22
|
+
/** Toast shown after a successful copy, when the boundary is inside an `AhroweProvider`. */
|
|
23
23
|
copySuccessToast?: string;
|
|
24
|
-
/** Toast shown if the copy fails
|
|
24
|
+
/** Toast shown if the copy fails, when the boundary is inside an `AhroweProvider`. */
|
|
25
25
|
copyErrorToast?: string;
|
|
26
26
|
}
|
|
27
27
|
export interface ErrorBoundaryProps extends Omit<HtmlProps, 'title' | 'onError'> {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CSSProperties } from 'react';
|
|
1
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
2
2
|
import { SlotClassNames, SlotStyles, HtmlProps } from '../types/slots.types.js';
|
|
3
3
|
import { Presentation } from '../configProvider/presentation.types.js';
|
|
4
4
|
export type ModalSlots = 'container' | 'backdrop' | 'modal' | 'header' | 'title' | 'closeButton' | 'body' | 'footer';
|
|
@@ -7,9 +7,10 @@ export interface ModalLabels {
|
|
|
7
7
|
/** Close button, read out by screen readers. */
|
|
8
8
|
close?: string;
|
|
9
9
|
}
|
|
10
|
-
export interface ModalProps extends HtmlProps<HTMLDivElement> {
|
|
10
|
+
export interface ModalProps extends Omit<HtmlProps<HTMLDivElement>, 'title'> {
|
|
11
11
|
children?: React.ReactNode;
|
|
12
|
-
|
|
12
|
+
/** Heading in the header. Its text becomes the dialog's accessible name, unless `aria-label` is passed. */
|
|
13
|
+
title?: ReactNode;
|
|
13
14
|
isOpen?: boolean;
|
|
14
15
|
onClose?: () => void;
|
|
15
16
|
/** Applied to the modal panel itself */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { default } from './themeProvider.js';
|
|
2
2
|
export { defaultTheme } from './defaultTheme.js';
|
|
3
3
|
export { lightTheme } from './lightTheme.js';
|
|
4
|
-
export type { Theme, ThemeVariables } from './theme.types.js';
|
|
4
|
+
export type { Theme, ThemeProviderProps, ThemeVariables } from './theme.types.js';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
1
2
|
/**
|
|
2
3
|
* All CSS custom properties used by the component library.
|
|
3
4
|
* Every key is optional so a theme only needs to declare the variables it overrides.
|
|
@@ -205,6 +206,14 @@ export interface ThemeVariables {
|
|
|
205
206
|
'--tree-selected-background'?: string;
|
|
206
207
|
/** Selected row text. Falls back to --text-on-primary. */
|
|
207
208
|
'--tree-selected-color'?: string;
|
|
209
|
+
/** Height of one hour in the week and day views. Pinching zooms from it. Falls back to 3em. */
|
|
210
|
+
'--calendar-hour-height'?: string;
|
|
211
|
+
/** Today's date marker. Falls back to --primary-color. */
|
|
212
|
+
'--calendar-today-color'?: string;
|
|
213
|
+
/** The current-time line. Falls back to --error-color. */
|
|
214
|
+
'--calendar-now-color'?: string;
|
|
215
|
+
/** Corner radius of an event. Falls back to 6px. */
|
|
216
|
+
'--calendar-event-radius'?: string;
|
|
208
217
|
/** Page button size. Falls back to 36px. */
|
|
209
218
|
'--pagination-size'?: string;
|
|
210
219
|
/** Gap between page buttons. Falls back to 4px. */
|
|
@@ -270,3 +279,10 @@ export interface Theme {
|
|
|
270
279
|
baseThemeId?: string;
|
|
271
280
|
variables: ThemeVariables;
|
|
272
281
|
}
|
|
282
|
+
export interface ThemeProviderProps {
|
|
283
|
+
children: ReactNode;
|
|
284
|
+
/** The themes to choose from. Defaults to `[defaultTheme]`. */
|
|
285
|
+
themes?: Theme[];
|
|
286
|
+
/** The `id` of the theme to apply, from `themes`. */
|
|
287
|
+
currentThemeId?: string;
|
|
288
|
+
}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { default as React, Component } from 'react';
|
|
2
|
-
import { Theme } from './theme.types.js';
|
|
3
|
-
|
|
4
|
-
children: React.ReactNode;
|
|
5
|
-
themes?: Theme[];
|
|
6
|
-
currentThemeId?: string;
|
|
7
|
-
}
|
|
2
|
+
import { Theme, ThemeProviderProps } from './theme.types.js';
|
|
3
|
+
import { ThemeVariablesContext } from './themeVariablesContext.js';
|
|
8
4
|
interface State {
|
|
9
5
|
resolvedVariables: Record<string, string>;
|
|
10
6
|
colorFadeActive: boolean;
|
|
@@ -15,15 +11,17 @@ interface State {
|
|
|
15
11
|
currentThemeId: string | undefined;
|
|
16
12
|
};
|
|
17
13
|
}
|
|
18
|
-
declare class ThemeProvider extends Component<
|
|
14
|
+
declare class ThemeProvider extends Component<ThemeProviderProps, State> {
|
|
15
|
+
static contextType: React.Context<Record<string, string> | null>;
|
|
16
|
+
context: React.ContextType<typeof ThemeVariablesContext>;
|
|
19
17
|
state: State;
|
|
20
18
|
private colorFadeTimeout;
|
|
21
19
|
private wrapperRef;
|
|
22
20
|
private themeColorMeta;
|
|
23
21
|
private createdThemeColorMeta;
|
|
24
|
-
static getDerivedStateFromProps(props:
|
|
22
|
+
static getDerivedStateFromProps(props: ThemeProviderProps, state: State): Partial<State> | null;
|
|
25
23
|
componentDidMount(): void;
|
|
26
|
-
componentDidUpdate(prevProps:
|
|
24
|
+
componentDidUpdate(prevProps: ThemeProviderProps, prevState: State): void;
|
|
27
25
|
componentWillUnmount(): void;
|
|
28
26
|
/**
|
|
29
27
|
* Replaces the former react-helmet usage: keep a single
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The nearest ThemeProvider's resolved variables, for content that renders outside its DOM
|
|
3
3
|
* subtree. Theme variables reach a component by CSS inheritance, which a portal breaks: a
|
|
4
|
-
* `BodyEnd` child lands wherever
|
|
5
|
-
*
|
|
4
|
+
* `BodyEnd` child lands wherever the portal target is, so it picks up whatever provider wraps
|
|
5
|
+
* *that* node rather than the one it was written under.
|
|
6
6
|
*
|
|
7
7
|
* Deliberately its own module rather than a member of `themeProvider.tsx`: BodyEnd needs the
|
|
8
8
|
* context and nothing else, and importing the component for it would pull the whole
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
export { default } from './toastProvider.js';
|
|
2
1
|
export { showToast } from './toastService.js';
|
|
3
|
-
export type {
|
|
2
|
+
export type { ToastContextConfig, ToastLabels, ToastOptions, ToastType, ToastPosition, ToastSlots, } from './toast.types.js';
|
|
@@ -19,17 +19,17 @@ export interface ToastContextConfig {
|
|
|
19
19
|
/** Pause the auto-dismiss timer while the toast is hovered or focused. */
|
|
20
20
|
pauseOnHover?: boolean;
|
|
21
21
|
/**
|
|
22
|
-
* Overrides the text a toast renders of its own. Set
|
|
23
|
-
* the whole app, or per toast through `showToast` options.
|
|
22
|
+
* Overrides the text a toast renders of its own. Set in `AhroweProvider`'s
|
|
23
|
+
* `toast` for the whole app, or per toast through `showToast` options.
|
|
24
24
|
*/
|
|
25
25
|
labels?: ToastLabels;
|
|
26
26
|
}
|
|
27
|
-
export interface ToastOptions extends ToastContextConfig {
|
|
27
|
+
export interface ToastOptions extends Omit<ToastContextConfig, 'allowStacking'> {
|
|
28
28
|
type?: ToastType;
|
|
29
29
|
classNames?: SlotClassNames<ToastSlots>;
|
|
30
30
|
styles?: SlotStyles<ToastSlots>;
|
|
31
31
|
}
|
|
32
|
-
export interface
|
|
32
|
+
export interface ToastHostProps extends ToastContextConfig {
|
|
33
33
|
children: ReactNode;
|
|
34
34
|
}
|
|
35
35
|
export interface ToastItem extends Pick<ToastOptions, 'labels'> {
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { ToastHostProps } from './toast.types.js';
|
|
3
|
+
declare function ToastHost({ children, position, duration, showRemainingTime, showCloseButton, allowStacking, pauseOnHover, labels, }: ToastHostProps): React.JSX.Element;
|
|
4
|
+
export default ToastHost;
|
|
@@ -2,6 +2,6 @@ import { ReactNode } from 'react';
|
|
|
2
2
|
import { ToastOptions } from './toast.types.js';
|
|
3
3
|
type ShowToastFn = (content: ReactNode, options?: ToastOptions) => void;
|
|
4
4
|
export declare function _registerToastHandler(fn: ShowToastFn): void;
|
|
5
|
-
export declare function _unregisterToastHandler(): void;
|
|
5
|
+
export declare function _unregisterToastHandler(fn: ShowToastFn): void;
|
|
6
6
|
export declare function showToast(content: ReactNode, options?: ToastOptions): void;
|
|
7
7
|
export {};
|
|
@@ -14,3 +14,11 @@ export declare function formatDay({ year, month, day }: DayParts): string;
|
|
|
14
14
|
export declare function dateToDay(date: Date): string;
|
|
15
15
|
/** The first moment of a `'YYYY-MM-DD'` day in the browser's time zone. An Invalid Date for anything else. */
|
|
16
16
|
export declare function dayToDate(day: string): Date;
|
|
17
|
+
/** The `'HH:MM'` of `date` in the browser's time zone, the value a TimeInput holds; `''` for an Invalid Date. */
|
|
18
|
+
export declare function dateToTime(date: Date): string;
|
|
19
|
+
/**
|
|
20
|
+
* The moment a `'YYYY-MM-DD'` day and an `'HH:MM'` time stand for in the browser's time zone,
|
|
21
|
+
* DatePicker's and TimeInput's values together. A time the clock skips that day resolves forwards
|
|
22
|
+
* (02:30 becomes 03:30), a repeated one to its first occurrence. An Invalid Date for anything else.
|
|
23
|
+
*/
|
|
24
|
+
export declare function dayTimeToDate(day: string, time: string): Date;
|
|
@@ -19,6 +19,8 @@ interface UseColumnsArgs<T> {
|
|
|
19
19
|
containerHeight: number;
|
|
20
20
|
/** Re-measure `fit` columns when the container width settles (e.g. after a route transition). */
|
|
21
21
|
containerWidth: number;
|
|
22
|
+
/** Re-measure `fit` columns when rows replace the spinner under the same `items`. */
|
|
23
|
+
isLoading: boolean;
|
|
22
24
|
}
|
|
23
25
|
export interface UseColumnsResult<T> {
|
|
24
26
|
hasColumns: boolean;
|
|
@@ -48,5 +50,5 @@ export interface UseColumnsResult<T> {
|
|
|
48
50
|
* `fit`-column width measurement that pins one shared px track across the header
|
|
49
51
|
* and every row grid so they stay aligned.
|
|
50
52
|
*/
|
|
51
|
-
export declare function useColumns<T>({ columns, items, multiSelect, visibleColumnKeys, onVisibleColumnsChange, persistColumnsKey, showColumnToggle, userWidths, isFrozen, rootRef, startIndex, endIndex, containerHeight, containerWidth, }: UseColumnsArgs<T>): UseColumnsResult<T>;
|
|
53
|
+
export declare function useColumns<T>({ columns, items, multiSelect, visibleColumnKeys, onVisibleColumnsChange, persistColumnsKey, showColumnToggle, userWidths, isFrozen, rootRef, startIndex, endIndex, containerHeight, containerWidth, isLoading, }: UseColumnsArgs<T>): UseColumnsResult<T>;
|
|
52
54
|
export {};
|
|
@@ -3,6 +3,8 @@ export * from './common/accordion/index.js';
|
|
|
3
3
|
export * from './common/actionButtons/index.js';
|
|
4
4
|
export { default as ActionIcon } from './common/actionIcon/index.js';
|
|
5
5
|
export * from './common/actionIcon/index.js';
|
|
6
|
+
export { default as AhroweProvider } from './common/ahroweProvider/index.js';
|
|
7
|
+
export * from './common/ahroweProvider/index.js';
|
|
6
8
|
export { default as Alert } from './common/alert/index.js';
|
|
7
9
|
export * from './common/alert/index.js';
|
|
8
10
|
export { default as AnimatedLogo } from './common/animatedLogo/index.js';
|
|
@@ -21,6 +23,8 @@ export { default as Button } from './common/button/index.js';
|
|
|
21
23
|
export * from './common/button/index.js';
|
|
22
24
|
export { default as ButtonGroup } from './common/buttonGroup/index.js';
|
|
23
25
|
export * from './common/buttonGroup/index.js';
|
|
26
|
+
export { default as Calendar } from './common/calendar/index.js';
|
|
27
|
+
export * from './common/calendar/index.js';
|
|
24
28
|
export { default as Card } from './common/card/index.js';
|
|
25
29
|
export * from './common/card/index.js';
|
|
26
30
|
export { default as Carousel } from './common/carousel/index.js';
|
|
@@ -142,7 +146,6 @@ export { default as Timeline } from './common/timeline/index.js';
|
|
|
142
146
|
export * from './common/timeline/index.js';
|
|
143
147
|
export { default as Timer } from './common/timer/index.js';
|
|
144
148
|
export * from './common/timer/index.js';
|
|
145
|
-
export { default as ToastProvider } from './common/toast/index.js';
|
|
146
149
|
export * from './common/toast/index.js';
|
|
147
150
|
export { default as Tooltip } from './common/tooltip/index.js';
|
|
148
151
|
export * from './common/tooltip/index.js';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import e from"../configProvider/configProvider.mjs";import t from"../scrollbarProvider/index.mjs";import n from"../themeProvider/themeProvider.mjs";import{PortalHostContext as r}from"../bodyEnd/portalHostContext.mjs";import i from"../toast/toastHost.mjs";import{useCallback as a,useContext as o,useEffect as s,useLayoutEffect as c,useState as l,useSyncExternalStore as u}from"react";import{jsx as d,jsxs as f}from"react/jsx-runtime";var p=()=>()=>{};function m({children:m,themes:h,currentThemeId:g,defaultProps:_,presentation:v,toast:y,scrollbars:b}){let x=o(r)!==void 0,S=u(p,()=>!0,()=>!1),[C]=l(()=>typeof document>`u`?null:document.createElement(`div`)),w=a(e=>{let t=e?.parentElement?.lastElementChild;if(t&&C)return t.appendChild(C),()=>C.remove()},[C]),T=!x&&b!==!1;c(()=>{if(!T||!C)return;let e=getComputedStyle(C).getPropertyValue(`--background-accent-light`).trim(),t=document.documentElement.style;return t.setProperty(`--ahrowe-page-scrollbar-thumb`,e),()=>{t.removeProperty(`--ahrowe-page-scrollbar-thumb`)}},[T,C,h,g]);let E=x&&(y!==void 0||b!==void 0);s(()=>{E&&console.warn("[AhroweProvider] `toast` and `scrollbars` are read by the outermost AhroweProvider only. Set them there.")},[E]);let D=f(r.Provider,{value:S?C:null,children:[d(`template`,{ref:w}),d(i,{...y,children:m}),d(`div`,{})]});return d(e,{defaultProps:_,presentation:v,children:d(n,{themes:h,currentThemeId:g,children:x?m:b===!1?D:d(t,{children:D})})})}export{m as default};
|
|
2
|
+
//# sourceMappingURL=ahroweProvider.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ahroweProvider.mjs","names":[],"sources":["../../../../package/common/ahroweProvider/ahroweProvider.tsx"],"sourcesContent":["import {\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useState,\n useSyncExternalStore,\n type ReactElement,\n} from 'react';\n\nimport ConfigProvider from 'components/common/configProvider';\nimport ScrollbarProvider from 'components/common/scrollbarProvider';\nimport ThemeProvider from 'components/common/themeProvider';\nimport ToastHost from '../toast/toastHost';\nimport { PortalHostContext } from '../bodyEnd/portalHostContext';\nimport type { AhroweProviderProps } from './ahroweProvider.types';\n\nconst subscribeToNothing = () => () => {};\n\nfunction AhroweProvider({\n children,\n themes,\n currentThemeId,\n defaultProps,\n presentation,\n toast,\n scrollbars,\n}: AhroweProviderProps): ReactElement {\n // A nested provider themes and configures its section only. A second toast list would stack\n // over the first in the same corner, and a second host would split the portals in two.\n const isNested = useContext(PortalHostContext) !== undefined;\n\n // The server renders no portal, so hydration must not either: `false` there, and `true` from\n // the first render of an app that is not hydrating.\n const canPortal = useSyncExternalStore(\n subscribeToNothing,\n () => true,\n () => false,\n );\n\n // Created up front instead of rendered: a rendered host exists only after the first commit, so\n // a modal open on the first render mounted a commit late and its initial focus found nothing.\n const [host] = useState(() => (typeof document === 'undefined' ? null : document.createElement('div')));\n\n // Attached from a marker before the app, because refs attach in tree order: this way the host is\n // in the page before any layout effect runs. The slot stays last, so panels paint above the app.\n const attachHost = useCallback(\n (marker: HTMLTemplateElement | null) => {\n const slot = marker?.parentElement?.lastElementChild;\n if (!slot || !host) return;\n slot.appendChild(host);\n return () => host.remove();\n },\n [host],\n );\n\n // Read from the host rather than `themes`, for the resolved value, `var()` references included.\n const stylesPage = !isNested && scrollbars !== false;\n useLayoutEffect(() => {\n if (!stylesPage || !host) return;\n const thumb = getComputedStyle(host).getPropertyValue('--background-accent-light').trim();\n const page = document.documentElement.style;\n page.setProperty('--ahrowe-page-scrollbar-thumb', thumb);\n return () => {\n page.removeProperty('--ahrowe-page-scrollbar-thumb');\n };\n }, [stylesPage, host, themes, currentThemeId]);\n\n const ignoresRootProps = isNested && (toast !== undefined || scrollbars !== undefined);\n useEffect(() => {\n if (ignoresRootProps) {\n console.warn(\n '[AhroweProvider] `toast` and `scrollbars` are read by the outermost AhroweProvider only. Set them there.',\n );\n }\n }, [ignoresRootProps]);\n\n const root = (\n <PortalHostContext.Provider value={canPortal ? host : null}>\n <template ref={attachHost} />\n <ToastHost {...toast}>{children}</ToastHost>\n <div />\n </PortalHostContext.Provider>\n );\n\n return (\n <ConfigProvider defaultProps={defaultProps} presentation={presentation}>\n <ThemeProvider themes={themes} currentThemeId={currentThemeId}>\n {/* Around the portal slot too, so the scrollbars of the panels in it are styled as well. */}\n {isNested ? children : scrollbars === false ? root : <ScrollbarProvider>{root}</ScrollbarProvider>}\n </ThemeProvider>\n </ConfigProvider>\n );\n}\n\nexport default AhroweProvider;\n"],"mappings":"8bAiBA,IAAM,UAAiC,CAAC,EAExC,SAAS,EAAe,CACtB,WACA,SACA,iBACA,eACA,eACA,QACA,cACoC,CAGpC,IAAM,EAAW,EAAW,CAAiB,IAAM,IAAA,GAI7C,EAAY,EAChB,MACM,OACA,EACR,EAIM,CAAC,GAAQ,MAAgB,OAAO,SAAa,IAAc,KAAO,SAAS,cAAc,KAAK,CAAE,EAIhG,EAAa,EAChB,GAAuC,CACtC,IAAM,EAAO,GAAQ,eAAe,iBAChC,GAAC,GAAS,EAEd,OADA,EAAK,YAAY,CAAI,MACR,EAAK,OAAO,CAC3B,EACA,CAAC,CAAI,CACP,EAGM,EAAa,CAAC,GAAY,IAAe,GAC/C,MAAsB,CACpB,GAAI,CAAC,GAAc,CAAC,EAAM,OAC1B,IAAM,EAAQ,iBAAiB,CAAI,CAAC,CAAC,iBAAiB,2BAA2B,CAAC,CAAC,KAAK,EAClF,EAAO,SAAS,gBAAgB,MAEtC,OADA,EAAK,YAAY,gCAAiC,CAAK,MAC1C,CACX,EAAK,eAAe,+BAA+B,CACrD,CACF,EAAG,CAAC,EAAY,EAAM,EAAQ,CAAc,CAAC,EAE7C,IAAM,EAAmB,IAAa,IAAU,IAAA,IAAa,IAAe,IAAA,IAC5E,MAAgB,CACV,GACF,QAAQ,KACN,0GACF,CAEJ,EAAG,CAAC,CAAgB,CAAC,EAErB,IAAM,EACJ,EAAC,EAAkB,SAAnB,CAA4B,MAAO,EAAY,EAAO,KAAtD,SAAA,CACE,EAAC,WAAD,CAAU,IAAK,CAAa,CAAA,EAC5B,EAAC,EAAD,CAAW,GAAI,EAAQ,UAAoB,CAAA,EAC3C,EAAC,MAAD,CAAM,CAAA,CACoB,IAG9B,OACE,EAAC,EAAD,CAA8B,eAA4B,eACxD,SAAA,EAAC,EAAD,CAAuB,SAAwB,iBAE5C,SAAA,EAAW,EAAW,IAAe,GAAQ,EAAO,EAAC,EAAD,CAAA,SAAoB,CAAwB,CAAA,CACpF,CAAA,CACD,CAAA,CAEpB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{ThemeVariablesContext as e}from"../themeProvider/themeVariablesContext.mjs";import{useContext as
|
|
1
|
+
"use client";import{ThemeVariablesContext as e}from"../themeProvider/themeVariablesContext.mjs";import t from"../themeProvider/theme.module.mjs";import{PortalHostContext as n}from"./portalHostContext.mjs";import{useContext as r}from"react";import{jsx as i}from"react/jsx-runtime";import{createPortal as a}from"react-dom";function o({children:o=null}){let s=r(e),c=r(n),l=c===void 0?document.getElementById(`bodyEnd`):c;return l?a(s?i(`div`,{className:t.themeRoot,style:{display:`contents`,...s},children:o}):o,l):null}export{o as default};
|
|
2
2
|
//# sourceMappingURL=bodyEnd.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bodyEnd.mjs","names":[],"sources":["../../../../package/common/bodyEnd/bodyEnd.tsx"],"sourcesContent":["import { createPortal } from 'react-dom';\nimport { useContext, type CSSProperties, type ReactElement } from 'react';\n\nimport { ThemeVariablesContext } from '../themeProvider/themeVariablesContext';\nimport type { BodyEndProps } from './bodyEnd.types';\n\n// Module-scoped ambient typing for the bundler-replaced NODE_ENV guard below.\n// Browsers don't define `process`, so the value is read defensively at runtime;\n// bundlers (Vite/webpack) still statically replace the `process.env.NODE_ENV`\n// token. Declared at module scope (not globally), it isn't emitted into the\n// .d.ts and can't clash with a consumer's @types/node.\ndeclare const process: { env: { NODE_ENV?: string } };\n\nfunction BodyEnd({ children = null }: BodyEndProps): ReactElement | null {\n const themeVariables = useContext(ThemeVariablesContext);\n const target = document.getElementById('bodyEnd');\n if (!target) {\n if (typeof process !== 'undefined' && process.env.NODE_ENV !== 'production') {\n console.error('[BodyEnd]
|
|
1
|
+
{"version":3,"file":"bodyEnd.mjs","names":[],"sources":["../../../../package/common/bodyEnd/bodyEnd.tsx"],"sourcesContent":["import { createPortal } from 'react-dom';\nimport { useContext, type CSSProperties, type ReactElement } from 'react';\n\nimport { ThemeVariablesContext } from '../themeProvider/themeVariablesContext';\nimport themeStyles from '../themeProvider/theme.module.pcss';\nimport { PortalHostContext } from './portalHostContext';\nimport type { BodyEndProps } from './bodyEnd.types';\n\n// Module-scoped ambient typing for the bundler-replaced NODE_ENV guard below.\n// Browsers don't define `process`, so the value is read defensively at runtime;\n// bundlers (Vite/webpack) still statically replace the `process.env.NODE_ENV`\n// token. Declared at module scope (not globally), it isn't emitted into the\n// .d.ts and can't clash with a consumer's @types/node.\ndeclare const process: { env: { NODE_ENV?: string } };\n\nfunction BodyEnd({ children = null }: BodyEndProps): ReactElement | null {\n const themeVariables = useContext(ThemeVariablesContext);\n const host = useContext(PortalHostContext);\n const target = host === undefined ? document.getElementById('bodyEnd') : host;\n if (!target) {\n if (host === undefined && typeof process !== 'undefined' && process.env.NODE_ENV !== 'production') {\n console.error('[BodyEnd] Nowhere to render. Wrap your app in <AhroweProvider>, or add <div id=\"bodyEnd\"></div>.');\n }\n return null;\n }\n /*\n * Carry the nearest theme through the portal. `display: contents` is what makes this safe:\n * the wrapper generates no box, so positioning, stacking and clipping are untouched —\n * escaping clipping ancestors is the whole point of this component — while custom\n * properties still inherit, because inheritance follows the element tree, not the box tree.\n *\n * Variables this theme leaves unset still fall through to whatever wraps the target, which\n * is the same cascade the children would have seen rendered in place. `themeRoot` sets the\n * base typography again, which the target would otherwise pass down from its own theme.\n */\n if (!themeVariables) return createPortal(children, target);\n return createPortal(\n <div className={themeStyles.themeRoot} style={{ display: 'contents', ...themeVariables } as CSSProperties}>\n {children}\n </div>,\n target,\n );\n}\n\nexport default BodyEnd;\n"],"mappings":"iUAeA,SAAS,EAAQ,CAAE,WAAW,MAA2C,CACvE,IAAM,EAAiB,EAAW,CAAqB,EACjD,EAAO,EAAW,CAAiB,EACnC,EAAS,IAAS,IAAA,GAAY,SAAS,eAAe,SAAS,EAAI,EAkBzE,OAjBK,EAiBE,EADF,EAEH,EAAC,MAAD,CAAK,UAAW,EAAY,UAAW,MAAO,CAAE,QAAS,WAAY,GAAG,CAAe,EACpF,UACE,CAAA,EAJkC,EAKvC,CALuD,EAZhD,IAmBX"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portalHostContext.mjs","names":[],"sources":["../../../../package/common/bodyEnd/portalHostContext.ts"],"sourcesContent":["import { createContext } from 'react';\n\n/**\n * The element `AhroweProvider` portals into. `undefined` means there is no provider, so BodyEnd\n * falls back to `#bodyEnd`; `null` means a provider that cannot portal yet, on the server and\n * while hydrating, and must not be reported missing.\n */\nexport const PortalHostContext = createContext<HTMLElement | null | undefined>(undefined);\n"],"mappings":"mDAOA,IAAa,EAAoB,EAA8C,IAAA,EAAS"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{mergeRefs as n}from"../utils/mergeRefs.mjs";import{asDay as r,dateToDay as i,dayToDate as a}from"../utils/day.mjs";import{CalendarView as o}from"./calendar.types.mjs";import{addDays as s,dayDiff as c,hiddenDaySet as ee,periodRange as te,rangeWithNeighbours as ne,shownDay as re,shownDays as ie,startOfDay as l,stepDate as ae}from"./dates.mjs";import{formatPeriodTitle as oe,localeWeekStart as se}from"./format.mjs";import ce from"./components/agendaList/agendaList.mjs";import le from"./components/calendarHeader/calendarHeader.mjs";import ue from"./components/compactMonth/compactMonth.mjs";import de from"./components/monthView/monthView.mjs";import fe from"./components/timeGrid/timeGrid.mjs";import pe from"./calendar.module.mjs";import{useEffect as me,useLayoutEffect as u,useRef as d,useState as f}from"react";import p from"classnames";import{jsx as m,jsxs as h}from"react/jsx-runtime";var he=[o.Month,o.Week,o.Day,o.Agenda],ge=600,g={previous:`Previous`,next:`Next`,today:`Today`,viewSwitcher:`Calendar view`,month:`Month`,week:`Week`,day:`Day`,agenda:`Agenda`,allDay:`All day`,more:e=>`+${e} more`,eventCount:e=>e===1?`1 event`:`${e} events`,noEvents:`No events`,newEvent:`New event`};function _(_){let{events:v,date:y,defaultDate:_e,onDateChange:ve,view:b,defaultView:ye=o.Month,onViewChange:be,views:x=he,locale:S,weekStartsOn:xe,slotMinutes:Se=15,hiddenDays:C,scrollToHour:w,onRangeChange:T,onEventClick:E,onEventChange:D,onSlotCreate:O,renderEvent:k,labels:A,ref:j,className:Ce,style:we,classNames:M,styles:N,...P}=e(`Calendar`,_),F=t(`Calendar`,A,g),I=xe??se(S),L=ee(C),R=d(null),Te=d(null),[z,Ee]=f(0),[De,Oe]=f(1),[ke,Ae]=f(()=>{let e=r(_e);return e?a(e):l(new Date)}),B=r(y),V=re(B?a(B):ke,L),[je,Me]=f(ye),H=b??je;u(()=>{let e=R.current;if(!e)return;let t=()=>Ee(e.getBoundingClientRect().width);t();let n=new ResizeObserver(t);return n.observe(e),()=>n.disconnect()},[]);let U=z>0&&z<ge,W=ne(H,V,I,L),Ne=`${i(W.start)}/${i(W.end)}`,G=d({range:W,onRangeChange:T});u(()=>{G.current={range:W,onRangeChange:T}}),me(()=>{G.current.onRangeChange?.(G.current.range)},[Ne]);function K(e){let t=l(e);i(t)!==i(V)&&(Oe(t>V?1:-1),y===void 0&&Ae(t),ve?.(i(t)))}function q(e){e!==H&&(b===void 0&&Me(e),be?.(e))}let[J,Y]=f(()=>new Map);function Pe(e){let t=D?.(e);if(typeof t?.then!=`function`)return;let n=String(e.event.id),r={start:e.start,end:e.end};Y(e=>new Map(e).set(n,r));let i=()=>Y(e=>{if(e.get(n)!==r)return e;let t=new Map(e);return t.delete(n),t});t.then(i,i)}let X=J.size===0?v:v.map(e=>{let t=J.get(String(e.id));return t?{...e,...t}:e}),Z={events:X,date:V,view:H,locale:S,weekStartsOn:I,slotMinutes:Se,hidden:L,scrollToHour:w,text:F,onDateChange:K,onOpenDay:x.includes(o.Day)?e=>{K(e),q(o.Day)}:void 0,onEventClick:E,onEventChange:D&&Pe,onSlotCreate:O,renderEvent:k,classNames:M,slotStyles:N},Q=te(H,V,I),$=ie(Q.start,c(Q.start,Q.end),L),Fe={start:$[0],end:s($[$.length-1],1)};function Ie(){switch(H){case o.Week:case o.Day:return m(fe,{...Z,zoomRef:Te});case o.Agenda:return m(ce,{events:X,start:Q.start,days:c(Q.start,Q.end),hidden:L,scrollTo:V,showDayHeaders:!0,locale:S,text:F,onEventClick:E,renderEvent:k,classNames:M,slotStyles:N});default:return m(U?ue:de,{...Z})}}return h(`div`,{...P,ref:n(R,j),className:p(pe.calendar,Ce,M?.root),style:{...we,...N?.root},children:[m(le,{className:M?.header,style:N?.header,compact:U,title:oe(H,V,Fe,S),direction:De,view:H,views:x,text:F,onStep:e=>K(ae(H,V,e,L)),onToday:()=>K(new Date),onViewChange:q}),Ie()]})}export{_ as default};
|
|
2
|
+
//# sourceMappingURL=calendar.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar.mjs","names":[],"sources":["../../../../package/common/calendar/calendar.tsx"],"sourcesContent":["import { useEffect, useLayoutEffect, useRef, useState, type ReactElement } from 'react';\nimport cx from 'classnames';\n\nimport { useComponentDefaults, useLabels } from '../configProvider';\nimport { mergeRefs } from '../utils/mergeRefs';\nimport { asDay, dayToDate } from '../utils/day';\nimport {\n CalendarView,\n type CalendarEvent,\n type CalendarEventChange,\n type CalendarLabels,\n type CalendarProps,\n} from './calendar.types';\nimport {\n dayDiff,\n dateToDay,\n addDays,\n hiddenDaySet,\n periodRange,\n rangeWithNeighbours,\n shownDay,\n shownDays,\n startOfDay,\n stepDate,\n} from './dates';\nimport { formatPeriodTitle, localeWeekStart } from './format';\nimport AgendaList from './components/agendaList';\nimport CalendarHeader from './components/calendarHeader';\nimport CompactMonth from './components/compactMonth';\nimport MonthView from './components/monthView';\nimport TimeGrid from './components/timeGrid';\nimport type { TimeGridZoom } from './components/timeGrid/timeGrid.types';\nimport type { CalendarViewProps } from './view.types';\n\nimport styles from './calendar.module.pcss';\n\nconst ALL_VIEWS = [CalendarView.Month, CalendarView.Week, CalendarView.Day, CalendarView.Agenda];\n\n/** Below this width the month view folds into the compact month with a day list. */\nconst COMPACT_WIDTH = 600;\n\nconst DEFAULT_LABELS: Required<CalendarLabels> = {\n previous: 'Previous',\n next: 'Next',\n today: 'Today',\n viewSwitcher: 'Calendar view',\n month: 'Month',\n week: 'Week',\n day: 'Day',\n agenda: 'Agenda',\n allDay: 'All day',\n more: (count) => `+${count} more`,\n eventCount: (count) => (count === 1 ? '1 event' : `${count} events`),\n noEvents: 'No events',\n newEvent: 'New event',\n};\n\nfunction Calendar<E extends CalendarEvent = CalendarEvent>(props: CalendarProps<E>): ReactElement {\n const {\n events,\n date: controlledDate,\n defaultDate,\n onDateChange,\n view: controlledView,\n defaultView = CalendarView.Month,\n onViewChange,\n views = ALL_VIEWS,\n locale,\n weekStartsOn: weekStartsOnProp,\n slotMinutes = 15,\n hiddenDays,\n scrollToHour,\n onRangeChange,\n onEventClick,\n onEventChange,\n onSlotCreate,\n renderEvent,\n labels,\n ref,\n className,\n style,\n classNames,\n styles: slotStyles,\n ...rest\n } = useComponentDefaults('Calendar', props);\n const text = useLabels('Calendar', labels, DEFAULT_LABELS);\n const weekStartsOn = weekStartsOnProp ?? localeWeekStart(locale);\n const hidden = hiddenDaySet(hiddenDays);\n\n const rootRef = useRef<HTMLDivElement>(null);\n const zoomRef = useRef<TimeGridZoom | null>(null);\n const [width, setWidth] = useState(0);\n const [direction, setDirection] = useState<1 | -1>(1);\n\n // `date` is a day, the same wherever the calendar is opened, and read as its first local moment.\n const [internalDate, setInternalDate] = useState(() => {\n const initial = asDay(defaultDate);\n return initial ? dayToDate(initial) : startOfDay(new Date());\n });\n const controlledDay = asDay(controlledDate);\n // Only ever a day the views show. The selection itself is left alone: a hidden day in `date` is\n // the parent's, and stepping on from it lands where the parent would expect.\n const date = shownDay(controlledDay ? dayToDate(controlledDay) : internalDate, hidden);\n const [internalView, setInternalView] = useState(defaultView);\n const view = controlledView ?? internalView;\n\n // The layout switch follows the calendar's own width rather than the viewport's, so it also\n // happens in a sidebar on a wide screen. Width 0 means no layout (server, jsdom): stay wide.\n useLayoutEffect(() => {\n const root = rootRef.current;\n if (!root) return;\n // The border box, both times: an observer's `contentRect` leaves the border out, and 600px\n // wide would then read as 598.\n const measure = () => setWidth(root.getBoundingClientRect().width);\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(root);\n return () => observer.disconnect();\n }, []);\n const compact = width > 0 && width < COMPACT_WIDTH;\n\n // Reported per range, not per render: `date` is a new object on every render of a controlled\n // parent. Not `useEffectEvent` for the latest callback, which React only has from 19.2.\n const range = rangeWithNeighbours(view, date, weekStartsOn, hidden);\n const rangeKey = `${dateToDay(range.start)}/${dateToDay(range.end)}`;\n const latest = useRef({ range, onRangeChange });\n useLayoutEffect(() => {\n latest.current = { range, onRangeChange };\n });\n useEffect(() => {\n latest.current.onRangeChange?.(latest.current.range);\n }, [rangeKey]);\n\n function changeDate(next: Date) {\n const day = startOfDay(next);\n if (dateToDay(day) === dateToDay(date)) return;\n setDirection(day > date ? 1 : -1);\n if (controlledDate === undefined) setInternalDate(day);\n onDateChange?.(dateToDay(day));\n }\n\n function changeView(next: CalendarView) {\n if (next === view) return;\n if (controlledView === undefined) setInternalView(next);\n onViewChange?.(next);\n }\n\n // Moves whose promise has not settled yet, drawn where they were dropped meanwhile.\n const [pending, setPending] = useState<ReadonlyMap<string, { start: Date; end: Date }>>(() => new Map());\n function changeEvent(change: CalendarEventChange<E>) {\n const result = onEventChange?.(change);\n if (typeof (result as Promise<unknown> | undefined)?.then !== 'function') return;\n const key = String(change.event.id);\n const entry = { start: change.start, end: change.end };\n setPending((current) => new Map(current).set(key, entry));\n // A later move of the same event owns the entry by then, and keeps it.\n const settle = () =>\n setPending((current) => {\n if (current.get(key) !== entry) return current;\n const next = new Map(current);\n next.delete(key);\n return next;\n });\n (result as Promise<unknown>).then(settle, settle);\n }\n const shownEvents =\n pending.size === 0\n ? events\n : events.map((event) => {\n const moved = pending.get(String(event.id));\n return moved ? { ...event, ...moved } : event;\n });\n\n const viewProps: CalendarViewProps<E> = {\n events: shownEvents,\n date,\n view,\n locale,\n weekStartsOn,\n slotMinutes,\n hidden,\n scrollToHour,\n text,\n onDateChange: changeDate,\n onOpenDay: views.includes(CalendarView.Day)\n ? (day) => {\n changeDate(day);\n changeView(CalendarView.Day);\n }\n : undefined,\n onEventClick,\n onEventChange: onEventChange && changeEvent,\n onSlotCreate,\n renderEvent,\n classNames,\n slotStyles,\n };\n\n // The week's title names the days it shows, not the ones it hides at either end.\n const period = periodRange(view, date, weekStartsOn);\n const columns = shownDays(period.start, dayDiff(period.start, period.end), hidden);\n const titleRange = { start: columns[0], end: addDays(columns[columns.length - 1], 1) };\n\n function renderView() {\n switch (view) {\n case CalendarView.Week:\n case CalendarView.Day:\n return <TimeGrid {...viewProps} zoomRef={zoomRef} />;\n case CalendarView.Agenda: {\n return (\n <AgendaList\n events={shownEvents}\n start={period.start}\n days={dayDiff(period.start, period.end)}\n hidden={hidden}\n scrollTo={date}\n showDayHeaders\n locale={locale}\n text={text}\n onEventClick={onEventClick}\n renderEvent={renderEvent}\n classNames={classNames}\n slotStyles={slotStyles}\n />\n );\n }\n default:\n return compact ? <CompactMonth {...viewProps} /> : <MonthView {...viewProps} />;\n }\n }\n\n return (\n <div\n {...rest}\n ref={mergeRefs(rootRef, ref)}\n className={cx(styles.calendar, className, classNames?.root)}\n style={{ ...style, ...slotStyles?.root }}\n >\n <CalendarHeader\n className={classNames?.header}\n style={slotStyles?.header}\n compact={compact}\n title={formatPeriodTitle(view, date, titleRange, locale)}\n direction={direction}\n view={view}\n views={views}\n text={text}\n onStep={(step) => changeDate(stepDate(view, date, step, hidden))}\n onToday={() => changeDate(new Date())}\n onViewChange={changeView}\n />\n {renderView()}\n </div>\n );\n}\n\nexport default Calendar;\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar.module.mjs","names":[],"sources":["../../../../package/common/calendar/calendar.module.pcss"],"sourcesContent":[".calendar {\n /* Theme tokens resolved once, each with a built-in fallback. Set any of the public\n `--calendar-*` variables through ThemeProvider (theme-wide) or `style` (per instance). */\n --custom-calendar-hour-height: var(--calendar-hour-height, 3em);\n --custom-calendar-today-color: var(--calendar-today-color, var(--primary-color));\n --custom-calendar-now-color: var(--calendar-now-color, var(--error-color));\n --custom-calendar-event-radius: var(--calendar-event-radius, 6px);\n\n isolation: isolate;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n height: 40em;\n min-height: 0;\n overflow: hidden;\n border: 1px solid var(--border-color);\n border-radius: var(--default-border-radius);\n background: var(--background);\n color: var(--text-color);\n}\n"],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar.types.mjs","names":[],"sources":["../../../../package/common/calendar/calendar.types.ts"],"sourcesContent":["import type { CSSProperties, ReactNode, Ref } from 'react';\nimport type { SlotClassNames, SlotStyles, HtmlProps } from '../types/slots.types';\n\nexport enum CalendarView {\n Month = 'month',\n Week = 'week',\n Day = 'day',\n Agenda = 'agenda',\n}\n\n/** A day of the week, as `Date#getDay()` counts: 0 is Sunday, 1 is Monday. */\nexport type CalendarWeekday = 0 | 1 | 2 | 3 | 4 | 5 | 6;\n\n/** First day of the week, as `Date#getDay()` counts: 0 is Sunday, 1 is Monday. */\nexport type CalendarWeekStart = CalendarWeekday;\n\nexport interface CalendarEvent {\n id: string | number;\n title: string;\n /** Local time. */\n start: Date;\n /** Local time, exclusive. An all-day event on the 26th ends at midnight on the 27th. */\n end: Date;\n /** Shown in the all-day row instead of the time grid. Timed events of 24 hours or more are too. */\n allDay?: boolean;\n /** Any CSS colour. Falls back to `--primary-color`. */\n color?: string;\n /** Can be clicked but not moved or resized. */\n readOnly?: boolean;\n}\n\n/** A span of local time. `end` is exclusive. */\nexport interface CalendarRange {\n start: Date;\n end: Date;\n}\n\nexport interface CalendarEventChange<E extends CalendarEvent = CalendarEvent> {\n event: E;\n start: Date;\n end: Date;\n}\n\nexport interface CalendarSlot {\n start: Date;\n end: Date;\n allDay: boolean;\n}\n\n/** Where `renderEvent` draws an event. */\nexport interface CalendarEventContext {\n /**\n * The event has one line: an event under 45 minutes in the week and day views, an all-day bar,\n * or a row of the month view. The day and agenda lists have room for more.\n */\n singleLine: boolean;\n}\n\nexport type CalendarSlots = 'root' | 'header' | 'dayHeader' | 'cell' | 'event';\n\n/** Text Calendar renders of its own, for translating it. Dates and times come from `locale`. */\nexport interface CalendarLabels {\n /** Previous period button (default `Previous`). */\n previous?: string;\n /** Next period button (default `Next`). */\n next?: string;\n /** Jump to today (default `Today`). */\n today?: string;\n /** Name of the view switcher, read out by screen readers (default `Calendar view`). */\n viewSwitcher?: string;\n month?: string;\n week?: string;\n day?: string;\n agenda?: string;\n /** All-day row and all-day events (default `All day`). */\n allDay?: string;\n /** Overflow button in a month cell (default `+3 more`). */\n more?: (count: number) => string;\n /** Appended to a day's name for screen readers (default `3 events`). */\n eventCount?: (count: number) => string;\n /** A day or period without events (default `No events`). */\n noEvents?: string;\n /** Create button in a day's event list, shown when `onSlotCreate` is set (default `New event`). */\n newEvent?: string;\n}\n\nexport interface CalendarProps<E extends CalendarEvent = CalendarEvent> extends HtmlProps<HTMLDivElement> {\n /** The events to show. Only the ones inside the range `onRangeChange` reports are needed. */\n events: E[];\n /** Controlled: the selected day, `'YYYY-MM-DD'`, whose period is shown. Omit for uncontrolled. */\n date?: string;\n /** Day shown initially when uncontrolled, `'YYYY-MM-DD'` (default today). */\n defaultDate?: string;\n /** Called with the new day, `'YYYY-MM-DD'`: the value a DatePicker holds. */\n onDateChange?: (day: string) => void;\n /** Controlled view. Omit for uncontrolled. */\n view?: CalendarView;\n /** View shown initially when uncontrolled (default `CalendarView.Month`). */\n defaultView?: CalendarView;\n onViewChange?: (view: CalendarView) => void;\n /** Views offered in the switcher, in order. The switcher is hidden when there is only one (default all four). */\n views?: CalendarView[];\n /** BCP 47 tag for dates, times and the week start (default the browser's locale). */\n locale?: string;\n /** Overrides the locale's first day of the week. */\n weekStartsOn?: CalendarWeekStart;\n /** Minutes that creating, moving and resizing snap to (default `15`). */\n slotMinutes?: number;\n /** Days of the week left out of every view: `[0, 6]` hides the weekend. */\n hiddenDays?: CalendarWeekday[];\n /**\n * Hour the week and day views open at, such as `6` for 06:00 (default an hour before now while\n * today is shown, otherwise 07:00).\n */\n scrollToHour?: number;\n /**\n * Called on mount and whenever the shown period changes, with the period and one either side of\n * it, so the neighbours are already filled while swiping. Fetch events and expand recurring\n * series for this range.\n */\n onRangeChange?: (range: CalendarRange) => void;\n /** An event was clicked or tapped. `anchor` is its element, for positioning a popover. */\n onEventClick?: (event: E, anchor: HTMLElement) => void;\n /**\n * An event was moved or resized. Setting it is what makes events draggable. Update `events`\n * in the same render, or return a promise: the event then stays where it was dropped until the\n * promise settles, and is drawn from `events` again after that, back in place if it rejected.\n */\n onEventChange?: (change: CalendarEventChange<E>) => void | Promise<unknown>;\n /**\n * Empty time was clicked or dragged over. Setting it is what enables creating: a click creates\n * an hour, or an all-day slot in the month view. `anchor` marks the slot on screen, for a\n * popover's `anchor`: the day's cell in the month view, an invisible box over the slot in the\n * week and day views.\n */\n onSlotCreate?: (slot: CalendarSlot, anchor: HTMLElement) => void;\n /**\n * Content of an event, in place of its title. Must not contain interactive elements. Keep to the\n * title where `context.singleLine` is set: further lines have no room there.\n */\n renderEvent?: (event: E, context: CalendarEventContext) => ReactNode;\n /** The root element. */\n ref?: Ref<HTMLDivElement>;\n\n className?: string;\n style?: CSSProperties;\n classNames?: SlotClassNames<CalendarSlots>;\n styles?: SlotStyles<CalendarSlots>;\n /** Overrides the text Calendar renders of its own. Merged per key. */\n labels?: CalendarLabels;\n}\n\n/** The props `ConfigProvider` can set for every Calendar. The rest depend on the event type. */\nexport type CalendarDefaults = Pick<\n CalendarProps,\n 'labels' | 'locale' | 'weekStartsOn' | 'slotMinutes' | 'views' | 'hiddenDays' | 'scrollToHour'\n>;\n"],"mappings":"aAGA,IAAY,EAAL,SAAA,EAAA,OACL,GAAA,MAAA,QACA,EAAA,KAAA,OACA,EAAA,IAAA,MACA,EAAA,OAAA,UACF,EAAA,CAAA,CAAA"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{dateToDay as e}from"../../../utils/day.mjs";import{addDays as t,isSameDay as n,shownDays as r}from"../../dates.mjs";import{formatDayNumber as i,formatLongDate as a,formatTime as o,formatTimeRange as s,formatWeekday as c}from"../../format.mjs";import{eventEnd as l,eventsByDay as u,isAllDayLike as d}from"../../layout.mjs";import f from"./agendaList.module.mjs";import{useId as p,useLayoutEffect as m,useRef as h}from"react";import g from"classnames";import{Fragment as _,jsx as v,jsxs as y}from"react/jsx-runtime";function b({events:b,start:x,days:S,hidden:C,scrollTo:w,showDayHeaders:T,locale:E,text:D,onEventClick:O,renderEvent:k,className:A,classNames:j,slotStyles:M}){let N=p(),P=h(null),F=r(x,S,C),I=u(b,F),L=new Date,R=w?e(w):null;m(()=>{let e=P.current;if(!e||R===null)return;let t=[...e.querySelectorAll(`[data-cal-day]`)].find(e=>(e.dataset.calDay??``)>=R);e.scrollTop=t?t.offsetTop:0},[R]);let z=I.flatMap((e,t)=>e.length>0||!T?[{day:F[t],dayEvents:e}]:[]);return y(`div`,{ref:P,className:g(f.agendaList,A),children:[z.every(({dayEvents:e})=>e.length===0)&&v(`p`,{className:f.agendaListEmpty,children:D.noEvents}),z.map(({day:r,dayEvents:u})=>{if(u.length===0)return null;let p=`${N}-${e(r)}`,m=n(r,L),h=t(r,1);return y(`div`,{role:`group`,"aria-labelledby":T?p:void 0,className:g(f.agendaListDay,T&&f.agendaListDayWithHeader),"data-cal-day":e(r),children:[T&&y(`div`,{id:p,className:g(f.agendaListDayHeader,j?.dayHeader),style:M?.dayHeader,"aria-label":a(r,E),children:[v(`span`,{className:g(f.agendaListDayNumber,m&&f.agendaListDayNumberToday),"aria-hidden":!0,children:i(r,E)}),v(`span`,{className:f.agendaListDayName,"aria-hidden":!0,children:c(r,E,`short`)})]}),v(`ul`,{className:f.agendaListEvents,children:u.map(e=>{let t=l(e),n=e.start<r?r:e.start,i=t>h?h:t,a=d(e)||e.start<=r&&t>=h,c=a?D.allDay:s(e.start,t,E);return v(`li`,{children:y(`button`,{type:`button`,className:g(f.agendaListEvent,j?.event),style:{"--event-color":e.color,...M?.event},"aria-label":`${e.title}, ${c}`,"data-cal-event":String(e.id),onClick:t=>O?.(e,t.currentTarget),children:[v(`span`,{className:f.agendaListTime,"aria-hidden":!0,children:a?D.allDay:y(_,{children:[v(`span`,{children:o(n,E)}),v(`span`,{className:f.agendaListTimeEnd,children:o(i,E)})]})}),v(`span`,{className:f.agendaListAccent,"aria-hidden":!0}),v(`span`,{className:f.agendaListTitle,"aria-hidden":!0,children:k?k(e,{singleLine:!1}):e.title})]})},e.id)})})]},e(r))})]})}export{b as default};
|
|
2
|
+
//# sourceMappingURL=agendaList.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agendaList.mjs","names":[],"sources":["../../../../../../package/common/calendar/components/agendaList/agendaList.tsx"],"sourcesContent":["import { useId, useLayoutEffect, useRef, type CSSProperties, type ReactElement } from 'react';\nimport cx from 'classnames';\n\nimport type { CalendarEvent } from '../../calendar.types';\nimport { addDays, dateToDay, isSameDay, shownDays } from '../../dates';\nimport { formatDayNumber, formatLongDate, formatTime, formatTimeRange, formatWeekday } from '../../format';\nimport { eventEnd, eventsByDay, isAllDayLike } from '../../layout';\nimport type { AgendaListProps } from './agendaList.types';\n\nimport styles from './agendaList.module.pcss';\n\nfunction AgendaList<E extends CalendarEvent>({\n events,\n start,\n days,\n hidden,\n scrollTo,\n showDayHeaders,\n locale,\n text,\n onEventClick,\n renderEvent,\n className,\n classNames,\n slotStyles,\n}: AgendaListProps<E>): ReactElement {\n const id = useId();\n const listRef = useRef<HTMLDivElement>(null);\n const dates = shownDays(start, days, hidden);\n const perDay = eventsByDay(events, dates);\n const today = new Date();\n const scrollKey = scrollTo ? dateToDay(scrollTo) : null;\n\n useLayoutEffect(() => {\n const list = listRef.current;\n if (!list || scrollKey === null) return;\n const groups = list.querySelectorAll<HTMLElement>('[data-cal-day]');\n const target = [...groups].find((group) => (group.dataset.calDay ?? '') >= scrollKey);\n list.scrollTop = target ? target.offsetTop : 0;\n }, [scrollKey]);\n\n const listed = perDay.flatMap((dayEvents, index) =>\n dayEvents.length > 0 || !showDayHeaders ? [{ day: dates[index], dayEvents }] : [],\n );\n\n return (\n <div ref={listRef} className={cx(styles.agendaList, className)}>\n {listed.every(({ dayEvents }) => dayEvents.length === 0) && (\n <p className={styles.agendaListEmpty}>{text.noEvents}</p>\n )}\n {listed.map(({ day, dayEvents }) => {\n if (dayEvents.length === 0) return null;\n const headerId = `${id}-${dateToDay(day)}`;\n const isToday = isSameDay(day, today);\n const dayEnd = addDays(day, 1);\n return (\n <div\n key={dateToDay(day)}\n role='group'\n aria-labelledby={showDayHeaders ? headerId : undefined}\n className={cx(styles.agendaListDay, showDayHeaders && styles.agendaListDayWithHeader)}\n data-cal-day={dateToDay(day)}\n >\n {showDayHeaders && (\n <div\n id={headerId}\n className={cx(styles.agendaListDayHeader, classNames?.dayHeader)}\n style={slotStyles?.dayHeader}\n aria-label={formatLongDate(day, locale)}\n >\n <span\n className={cx(styles.agendaListDayNumber, isToday && styles.agendaListDayNumberToday)}\n aria-hidden\n >\n {formatDayNumber(day, locale)}\n </span>\n <span className={styles.agendaListDayName} aria-hidden>\n {formatWeekday(day, locale, 'short')}\n </span>\n </div>\n )}\n <ul className={styles.agendaListEvents}>\n {dayEvents.map((event) => {\n const end = eventEnd(event);\n const from = event.start < day ? day : event.start;\n const to = end > dayEnd ? dayEnd : end;\n const allDay = isAllDayLike(event) || (event.start <= day && end >= dayEnd);\n const when = allDay ? text.allDay : formatTimeRange(event.start, end, locale);\n return (\n <li key={event.id}>\n <button\n type='button'\n className={cx(styles.agendaListEvent, classNames?.event)}\n style={{ '--event-color': event.color, ...slotStyles?.event } as CSSProperties}\n aria-label={`${event.title}, ${when}`}\n data-cal-event={String(event.id)}\n onClick={(clickEvent) => onEventClick?.(event, clickEvent.currentTarget)}\n >\n <span className={styles.agendaListTime} aria-hidden>\n {allDay ? (\n text.allDay\n ) : (\n <>\n <span>{formatTime(from, locale)}</span>\n <span className={styles.agendaListTimeEnd}>{formatTime(to, locale)}</span>\n </>\n )}\n </span>\n <span className={styles.agendaListAccent} aria-hidden />\n <span className={styles.agendaListTitle} aria-hidden>\n {renderEvent ? renderEvent(event, { singleLine: false }) : event.title}\n </span>\n </button>\n </li>\n );\n })}\n </ul>\n </div>\n );\n })}\n </div>\n );\n}\n\nexport default AgendaList;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";var e=`agendaList_C00ZD`,t=`agendaList-empty_X742J`,n=`agendaList-day_S13Dn`,r=`agendaList-day-withHeader_DiXSD`,i=`agendaList-day-header_X9tfZ`,a=`agendaList-day-number_QfwoV`,o=`agendaList-day-number-today_v-2hj`,s=`agendaList-day-name_wqrBS`,c=`agendaList-events_PYc6m`,l=`agendaList-event_73lKv`,u=`agendaList-time_YyZCE`,d=`agendaList-time-end_zz3Xc`,f=`agendaList-accent_wCj9l`,p=`agendaList-title_0jQBA`,m={agendaList:e,"agendaList-empty":`agendaList-empty_X742J`,agendaListEmpty:t,"agendaList-day":`agendaList-day_S13Dn`,agendaListDay:n,"agendaList-day-withHeader":`agendaList-day-withHeader_DiXSD`,agendaListDayWithHeader:r,"agendaList-day-header":`agendaList-day-header_X9tfZ`,agendaListDayHeader:i,"agendaList-day-number":`agendaList-day-number_QfwoV`,agendaListDayNumber:a,"agendaList-day-number-today":`agendaList-day-number-today_v-2hj`,agendaListDayNumberToday:o,"agendaList-day-name":`agendaList-day-name_wqrBS`,agendaListDayName:s,"agendaList-events":`agendaList-events_PYc6m`,agendaListEvents:c,"agendaList-event":`agendaList-event_73lKv`,agendaListEvent:l,"agendaList-time":`agendaList-time_YyZCE`,agendaListTime:u,"agendaList-time-end":`agendaList-time-end_zz3Xc`,agendaListTimeEnd:d,"agendaList-accent":`agendaList-accent_wCj9l`,agendaListAccent:f,"agendaList-title":`agendaList-title_0jQBA`,agendaListTitle:p};export{e as agendaList,f as agendaListAccent,n as agendaListDay,i as agendaListDayHeader,s as agendaListDayName,a as agendaListDayNumber,o as agendaListDayNumberToday,r as agendaListDayWithHeader,t as agendaListEmpty,l as agendaListEvent,c as agendaListEvents,u as agendaListTime,d as agendaListTimeEnd,p as agendaListTitle,m as default};
|
|
2
|
+
//# sourceMappingURL=agendaList.module.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agendaList.module.mjs","names":[],"sources":["../../../../../../package/common/calendar/components/agendaList/agendaList.module.pcss"],"sourcesContent":[".agendaList {\n position: relative;\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n overscroll-behavior: contain;\n\n &-empty {\n margin: 0;\n padding: 2em 1em;\n text-align: center;\n color: var(--text-light);\n }\n\n &-day {\n padding: 0.25em 0.5em;\n\n & + & {\n border-top: 1px solid var(--border-color);\n }\n\n &-withHeader {\n display: grid;\n grid-template-columns: 3.5em minmax(0, 1fr);\n padding-left: 0;\n }\n\n &-header {\n position: sticky;\n top: 0;\n align-self: start;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.125em;\n padding: 0.5em 0;\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: 1.125em;\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n\n &-today {\n background: var(--custom-calendar-today-color);\n color: var(--text-on-primary);\n }\n }\n\n &-name {\n font-size: 0.6875em;\n font-weight: 600;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--text-dark);\n }\n }\n\n &-events {\n display: flex;\n flex-direction: column;\n gap: 0.125em;\n margin: 0;\n padding: 0.375em 0;\n list-style: none;\n }\n\n &-event {\n display: grid;\n grid-template-columns: auto 3px minmax(0, 1fr);\n align-items: center;\n gap: 0.75em;\n width: 100%;\n min-height: 2.75em;\n padding: 0.375em 0.625em;\n border: 0;\n border-radius: var(--custom-calendar-event-radius);\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n transition: background-color 0.15s ease;\n\n &:hover {\n background: color-mix(in oklab, var(--event-color, var(--primary-color)) 12%, transparent);\n }\n\n &:focus-visible {\n outline: 2px solid var(--focus-border-color, var(--primary-color));\n outline-offset: -2px;\n }\n }\n\n &-time {\n display: flex;\n flex-direction: column;\n min-width: 4.5em;\n font-size: 0.8125em;\n font-variant-numeric: tabular-nums;\n line-height: 1.35;\n\n &-end {\n color: var(--text-light);\n }\n }\n\n &-accent {\n align-self: stretch;\n width: 3px;\n border-radius: 3px;\n background: var(--event-color, var(--primary-color));\n }\n\n &-title {\n overflow: hidden;\n font-weight: 500;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n}\n"],"mappings":""}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{ButtonSize as e}from"../../../button/button.types.mjs";import t from"../../../button/button.mjs";import n from"../../../actionIcon/actionIcon.mjs";import r from"../../../optionPicker/optionPicker.mjs";import i from"./calendarHeader.module.mjs";import a from"classnames";import{faChevronLeft as o,faChevronRight as s}from"@fortawesome/free-solid-svg-icons";import{jsx as c,jsxs as l}from"react/jsx-runtime";function u({title:u,compact:d,direction:f,view:p,views:m,text:h,onStep:g,onToday:_,onViewChange:v,className:y,style:b}){return l(`div`,{className:a(i.calendarHeader,d&&i.calendarHeaderCompact,y),style:b,children:[c(`div`,{className:i.calendarHeaderTitle,"aria-live":`polite`,children:c(`span`,{className:i.calendarHeaderTitleText,style:{"--title-from":f},children:u},u)}),l(`div`,{className:i.calendarHeaderNav,children:[c(t,{className:i.calendarHeaderToday,size:e.Small,onClick:_,children:h.today}),c(n,{className:i.calendarHeaderStep,icon:o,title:h.previous,"aria-label":h.previous,onClick:()=>g(-1)}),c(n,{className:i.calendarHeaderStep,icon:s,title:h.next,"aria-label":h.next,onClick:()=>g(1)})]}),m.length>1&&c(r,{className:i.calendarHeaderViews,"aria-label":h.viewSwitcher,value:p,onChange:e=>v(e),options:m.map(e=>({key:e,label:h[e]}))})]})}export{u as default};
|
|
2
|
+
//# sourceMappingURL=calendarHeader.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendarHeader.mjs","names":[],"sources":["../../../../../../package/common/calendar/components/calendarHeader/calendarHeader.tsx"],"sourcesContent":["import type { CSSProperties, ReactElement } from 'react';\nimport cx from 'classnames';\nimport { faChevronLeft, faChevronRight } from '@fortawesome/free-solid-svg-icons';\n\nimport ActionIcon from 'components/common/actionIcon';\nimport Button, { ButtonSize } from 'components/common/button';\nimport OptionPicker from 'components/common/optionPicker';\nimport type { CalendarView } from '../../calendar.types';\nimport type { CalendarHeaderProps } from './calendarHeader.types';\n\nimport styles from './calendarHeader.module.pcss';\n\nfunction CalendarHeader({\n title,\n compact,\n direction,\n view,\n views,\n text,\n onStep,\n onToday,\n onViewChange,\n className,\n style,\n}: CalendarHeaderProps): ReactElement {\n return (\n <div className={cx(styles.calendarHeader, compact && styles.calendarHeaderCompact, className)} style={style}>\n {/* A live region, so paging is announced; its first content is not, as it was there on mount. */}\n <div className={styles.calendarHeaderTitle} aria-live='polite'>\n <span\n key={title}\n className={styles.calendarHeaderTitleText}\n style={{ '--title-from': direction } as CSSProperties}\n >\n {title}\n </span>\n </div>\n <div className={styles.calendarHeaderNav}>\n <Button className={styles.calendarHeaderToday} size={ButtonSize.Small} onClick={onToday}>\n {text.today}\n </Button>\n <ActionIcon\n className={styles.calendarHeaderStep}\n icon={faChevronLeft}\n title={text.previous}\n aria-label={text.previous}\n onClick={() => onStep(-1)}\n />\n <ActionIcon\n className={styles.calendarHeaderStep}\n icon={faChevronRight}\n title={text.next}\n aria-label={text.next}\n onClick={() => onStep(1)}\n />\n </div>\n {views.length > 1 && (\n <OptionPicker\n className={styles.calendarHeaderViews}\n aria-label={text.viewSwitcher}\n value={view}\n onChange={(key) => onViewChange(key as CalendarView)}\n options={views.map((option) => ({ key: option, label: text[option] }))}\n />\n )}\n </div>\n );\n}\n\nexport default CalendarHeader;\n"],"mappings":"0aAYA,SAAS,EAAe,CACtB,QACA,UACA,YACA,OACA,QACA,OACA,SACA,UACA,eACA,YACA,SACoC,CACpC,OACE,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,eAAgB,GAAW,EAAO,sBAAuB,CAAS,EAAU,QAAtG,SAAA,CAEE,EAAC,MAAD,CAAK,UAAW,EAAO,oBAAqB,YAAU,SACpD,SAAA,EAAC,OAAD,CAEE,UAAW,EAAO,wBAClB,MAAO,CAAE,eAAgB,CAAU,EAElC,SAAA,CACG,EALC,CAKD,CACH,CAAA,EACL,EAAC,MAAD,CAAK,UAAW,EAAO,kBAAvB,SAAA,CACE,EAAC,EAAD,CAAQ,UAAW,EAAO,oBAAqB,KAAM,EAAW,MAAO,QAAS,EAC7E,SAAA,EAAK,KACA,CAAA,EACR,EAAC,EAAD,CACE,UAAW,EAAO,mBAClB,KAAM,EACN,MAAO,EAAK,SACZ,aAAY,EAAK,SACjB,YAAe,EAAO,EAAE,CACzB,CAAA,EACD,EAAC,EAAD,CACE,UAAW,EAAO,mBAClB,KAAM,EACN,MAAO,EAAK,KACZ,aAAY,EAAK,KACjB,YAAe,EAAO,CAAC,CACxB,CAAA,CACE,IACJ,EAAM,OAAS,GACd,EAAC,EAAD,CACE,UAAW,EAAO,oBAClB,aAAY,EAAK,aACjB,MAAO,EACP,SAAW,GAAQ,EAAa,CAAmB,EACnD,QAAS,EAAM,IAAK,IAAY,CAAE,IAAK,EAAQ,MAAO,EAAK,EAAQ,EAAE,CACtE,CAAA,CAEA,GAET"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";var e=`calendarHeader_2y0rN`,t=`calendarHeader-title_oxE5q`,n=`calendarHeader-title-text_-Tc6u`,r=`calendarTitleIn_GgigY`,i=`calendarHeader-nav_vtXFu`,a=`calendarHeader-today_-IWRl`,o=`calendarHeader-step_cZkOq`,s=`calendarHeader-views_-ftrl`,c=`calendarHeader-compact_4jGIE`,l={calendarHeader:e,"calendarHeader-title":`calendarHeader-title_oxE5q`,calendarHeaderTitle:t,"calendarHeader-title-text":`calendarHeader-title-text_-Tc6u`,calendarHeaderTitleText:n,calendarTitleIn:r,"calendarHeader-nav":`calendarHeader-nav_vtXFu`,calendarHeaderNav:i,"calendarHeader-today":`calendarHeader-today_-IWRl`,calendarHeaderToday:a,"calendarHeader-step":`calendarHeader-step_cZkOq`,calendarHeaderStep:o,"calendarHeader-views":`calendarHeader-views_-ftrl`,calendarHeaderViews:s,"calendarHeader-compact":`calendarHeader-compact_4jGIE`,calendarHeaderCompact:c};export{e as calendarHeader,c as calendarHeaderCompact,i as calendarHeaderNav,o as calendarHeaderStep,t as calendarHeaderTitle,n as calendarHeaderTitleText,a as calendarHeaderToday,s as calendarHeaderViews,r as calendarTitleIn,l as default};
|
|
2
|
+
//# sourceMappingURL=calendarHeader.module.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendarHeader.module.mjs","names":[],"sources":["../../../../../../package/common/calendar/components/calendarHeader/calendarHeader.module.pcss"],"sourcesContent":[".calendarHeader {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0.5em 0.75em;\n padding: 0.625em 0.75em;\n border-bottom: 1px solid var(--border-color);\n\n &-title {\n flex: 1 1 6em;\n min-width: 0;\n overflow: hidden;\n font-size: 1.125em;\n font-weight: 600;\n white-space: nowrap;\n\n &-text {\n display: block;\n overflow: hidden;\n text-overflow: ellipsis;\n animation: calendarTitleIn 0.25s ease-out;\n }\n }\n\n &-nav {\n display: flex;\n align-items: center;\n gap: 0.125em;\n }\n\n &-today {\n margin-right: 0.25em;\n padding: 0.375em 0.75em;\n border: 1px solid var(--border-color);\n }\n\n &-step {\n display: grid;\n place-items: center;\n width: 2em;\n height: 2em;\n padding: 0;\n border-radius: 50%;\n color: var(--text-dark);\n\n &:hover {\n filter: none;\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 }\n }\n}\n\n/* Two classes, to outrank OptionPicker's own `width: 100%` whichever stylesheet loads first.\n OptionPicker's chip assumes equal options. As a flex row sized to its content they were equal\n at the average label's width, and Month and Agenda were cut; `1fr` columns take the widest. */\n.calendarHeader .calendarHeader-views {\n --option-picker-padding: 0.3125em 0.75em;\n\n display: grid;\n grid-auto-columns: 1fr;\n grid-auto-flow: column;\n flex: none;\n width: auto;\n font-size: 0.875em;\n}\n\n/* After the rule above, which it has to override on a narrow calendar: a row of its own, and\n less padding, so four view names still fit at phone widths. */\n.calendarHeader-compact .calendarHeader-views {\n --option-picker-padding: 0.3125em 0.25em;\n\n flex-basis: 100%;\n}\n\n@keyframes calendarTitleIn {\n from {\n opacity: 0;\n transform: translateX(calc(var(--title-from, 1) * 0.75em));\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .calendarHeader-title-text {\n animation: none;\n }\n}\n"],"mappings":""}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{ButtonSize as e}from"../../../button/button.types.mjs";import t from"../../../button/button.mjs";import n from"../../../hooks/useMediaQuery.mjs";import{dateToDay as r}from"../../../utils/day.mjs";import{CalendarView as i}from"../../calendar.types.mjs";import{addDays as a,addMonths as o,dayDiff as s,gridKeyTarget as c,isSameDay as l,periodRange as u,shownDays as d,startOfMonth as f,startOfWeek as p}from"../../dates.mjs";import{formatDayNumber as ee,formatLongDate as m,formatMonthTitle as h,formatWeekday as g}from"../../format.mjs";import{eventsByDay as _}from"../../layout.mjs";import v from"../agendaList/agendaList.mjs";import{pageStep as te}from"../../gesture.mjs";import{useGestures as ne}from"../../useGestures.mjs";import{usePager as y}from"../../usePager.mjs";import b from"../../pager.module.mjs";import x from"./compactMonth.module.mjs";import{useLayoutEffect as S,useRef as C,useState as w}from"react";import T from"classnames";import{jsx as E,jsxs as D}from"react/jsx-runtime";var re=[-1,0,1],ie=3,ae=150;function O({events:O,date:k,locale:A,weekStartsOn:j,hidden:M,text:N,onDateChange:P,onEventClick:F,onSlotCreate:I,renderEvent:L,classNames:R,slotStyles:z}){let B=C(null),V=C(null),H=C(null),U=C(null),W=C(null),G=C(0),[K,oe]=w(!1),q=n(`(prefers-reduced-motion: reduce)`),J=new Date,Y=f(k),X=p(k,j),Z=d(p(J,j),7,M),Q=y(r(K?X:Y),e=>P(K?a(k,7*e):o(k,e)),()=>U.current?.querySelector(`[tabindex="0"]`)??null);S(()=>{let e=B.current;if(!e)return;let t,n=!1;function r(){return(H.current?.clientHeight??0)*5/6}function i(){let t=r(),n=t>0?Math.min(e.scrollTop/t,1):0;q&&(n=+(n>.99)),G.current=n,e.style.setProperty(`--collapse`,String(n)),oe(n>=1)}function a(){if(n)return;let t=r(),i=e.scrollTop;i<=0||i>=t||e.scrollTo({top:i<t/2?0:t,behavior:q?`auto`:`smooth`})}function o(){clearTimeout(t),t=setTimeout(a,ae)}function s(){i(),o()}function c(){n=!0}function l(){n=!1,o()}return i(),e.addEventListener(`scroll`,s,{passive:!0}),e.addEventListener(`touchstart`,c,{passive:!0}),e.addEventListener(`touchend`,l,{passive:!0}),e.addEventListener(`touchcancel`,l,{passive:!0}),()=>{clearTimeout(t),e.removeEventListener(`scroll`,s),e.removeEventListener(`touchstart`,c),e.removeEventListener(`touchend`,l),e.removeEventListener(`touchcancel`,l)}},[q]),S(()=>{let e=W.current;e!==null&&(W.current=null,U.current?.querySelector(`[data-cal-day="${e}"]`)?.focus())}),ne(V,{onPress:Q.finish,canSwipe:()=>G.current<.01||G.current>.99,onSwipeMove:Q.move,onSwipeEnd:(e,t)=>Q.settle(te(e,Q.width(),t))});function se(e,t){let n=c(e.key,t,j,M);n&&(e.preventDefault(),W.current=r(n),P(n))}function $(e,t,n,i){let a=l(e,k),o=l(e,J),s=m(e,A);return D(`div`,{role:`gridcell`,"data-cal-day":r(e),tabIndex:n&&a?0:-1,"aria-selected":a,"aria-current":o?`date`:void 0,"aria-label":i.length>0?`${s}, ${N.eventCount(i.length)}`:s,className:T(x.compactMonthCell,t&&x.compactMonthCellOutside,R?.cell),style:z?.cell,onClick:()=>P(e),onKeyDown:t=>se(t,e),children:[E(`span`,{"aria-hidden":!0,className:T(x.compactMonthNumber,o&&x.compactMonthNumberToday,a&&x.compactMonthNumberSelected),children:ee(e,A)}),E(`span`,{"aria-hidden":!0,className:x.compactMonthDots,children:i.slice(0,ie).map(e=>E(`span`,{className:x.compactMonthDot,style:{"--event-color":e.color}},e.id))})]},r(e))}function ce(e){let t=e===0,n=T(b.pagerPane,e===-1&&b.pagerPanePrev,e===1&&b.pagerPaneNext,x.compactMonthPane);if(K){let i=a(X,7*e),o=d(i,7,M),s=_(O,o);return E(`div`,{ref:t?U:void 0,className:n,inert:!t,"aria-hidden":!t||void 0,children:E(`div`,{role:`row`,className:x.compactMonthWeek,children:o.map((e,n)=>$(e,!1,t,s[n]))})},r(i))}let c=o(Y,e),l=u(i.Month,c,j).start,f=t?Math.floor(s(l,k)/7):0;return E(`div`,{ref:t?U:void 0,className:n,inert:!t,"aria-hidden":!t||void 0,style:{"--selected-row":f},children:E(`div`,{className:x.compactMonthRows,children:Array.from({length:6},(e,n)=>{let i=a(l,n*7),o=d(i,7,M),s=_(O,o);return E(`div`,{role:`row`,className:T(x.compactMonthWeek,n!==f&&x.compactMonthWeekFolding),children:o.map((e,n)=>$(e,e.getMonth()!==c.getMonth(),t,s[n]))},r(i))})})},r(c))}return D(`div`,{ref:B,className:x.compactMonth,style:{"--days":Z.length},children:[E(`div`,{ref:V,className:x.compactMonthSticky,children:D(`div`,{role:`grid`,"aria-label":h(k,A),children:[E(`div`,{role:`row`,className:x.compactMonthWeekdays,children:Z.map(e=>E(`div`,{role:`columnheader`,"aria-label":g(e,A,`long`),className:T(x.compactMonthWeekday,R?.dayHeader),style:z?.dayHeader,children:g(e,A,`narrow`)},e.getDay()))}),E(`div`,{ref:H,className:T(b.pagerViewport,x.compactMonthViewport),children:E(`div`,{ref:Q.trackRef,className:b.pagerTrack,children:re.map(ce)})})]})}),D(`div`,{className:x.compactMonthList,children:[D(`div`,{className:x.compactMonthListHeader,children:[E(`div`,{className:x.compactMonthListTitle,children:m(k,A)}),I&&E(t,{size:e.Small,onClick:e=>I({start:k,end:a(k,1),allDay:!0},e.currentTarget),children:N.newEvent})]}),E(v,{className:x.compactMonthAgenda,events:O,start:k,days:1,showDayHeaders:!1,locale:A,text:N,onEventClick:F,renderEvent:L,classNames:R,slotStyles:z})]})]})}export{O as default};
|
|
2
|
+
//# sourceMappingURL=compactMonth.mjs.map
|