pixelize-design-library 2.4.2-beta.58 → 2.4.2-beta.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +149 -5
- package/COMPONENT-GOTCHAS.md +205 -18
- package/DESIGN-GUIDE.md +43 -9
- package/dist/Components/AppSwitcher/AppSwitcher.js +5 -1
- package/dist/Components/AppSwitcher/AppSwitcherProps.d.ts +2 -0
- package/dist/Components/AppSwitcher/AppSwitcherProps.js +7 -4
- package/dist/Components/AudioRecorder/AudioRecorder.d.ts +8 -0
- package/dist/Components/AudioRecorder/AudioRecorder.js +169 -0
- package/dist/Components/AudioRecorder/AudioRecorderProps.d.ts +20 -0
- package/dist/Components/AudioRecorder/AudioRecorderProps.js +2 -0
- package/dist/Components/Breadcrumbs/Breadcrumbs.d.ts +1 -1
- package/dist/Components/Breadcrumbs/Breadcrumbs.js +33 -10
- package/dist/Components/Breadcrumbs/BreadcrumbsProps.d.ts +16 -2
- package/dist/Components/BulkSelectionBar/BulkSelectionBar.d.ts +3 -0
- package/dist/Components/BulkSelectionBar/BulkSelectionBar.js +43 -0
- package/dist/Components/BulkSelectionBar/BulkSelectionBarProps.d.ts +35 -0
- package/dist/Components/BulkSelectionBar/BulkSelectionBarProps.js +2 -0
- package/dist/Components/BulkSelectionBar/index.d.ts +2 -0
- package/dist/Components/BulkSelectionBar/index.js +8 -0
- package/dist/Components/CalendarGrid/CalendarGrid.d.ts +3 -0
- package/dist/Components/CalendarGrid/CalendarGrid.js +173 -0
- package/dist/Components/CalendarGrid/CalendarGridProps.d.ts +54 -0
- package/dist/Components/CalendarGrid/CalendarGridProps.js +2 -0
- package/dist/Components/CalendarGrid/calendarMath.d.ts +49 -0
- package/dist/Components/CalendarGrid/calendarMath.js +178 -0
- package/dist/Components/Card/Card.d.ts +3 -1
- package/dist/Components/Card/Card.js +12 -2
- package/dist/Components/Card/CardProps.d.ts +5 -1
- package/dist/Components/CircularProgress/CircularProgress.d.ts +4 -0
- package/dist/Components/CircularProgress/CircularProgress.js +39 -0
- package/dist/Components/CircularProgress/CircularProgressProps.d.ts +22 -0
- package/dist/Components/CircularProgress/CircularProgressProps.js +2 -0
- package/dist/Components/CircularProgress/arc.d.ts +12 -0
- package/dist/Components/CircularProgress/arc.js +16 -0
- package/dist/Components/Common/fieldStyles.d.ts +1 -0
- package/dist/Components/Common/fieldStyles.js +2 -1
- package/dist/Components/Drawer/Drawer.d.ts +1 -1
- package/dist/Components/Drawer/Drawer.js +4 -2
- package/dist/Components/Drawer/DrawerProps.d.ts +3 -1
- package/dist/Components/Editor/Editor.js +50 -2
- package/dist/Components/Editor/EditorFieldBar.d.ts +15 -0
- package/dist/Components/Editor/EditorFieldBar.js +19 -0
- package/dist/Components/Editor/EditorProps.d.ts +74 -1
- package/dist/Components/Editor/MakeDynamicDialog.d.ts +12 -0
- package/dist/Components/Editor/MakeDynamicDialog.js +59 -0
- package/dist/Components/Editor/editorLabels.d.ts +4 -0
- package/dist/Components/Editor/editorLabels.js +24 -0
- package/dist/Components/Editor/editorTokenStyles.d.ts +28 -0
- package/dist/Components/Editor/editorTokenStyles.js +30 -0
- package/dist/Components/Editor/editorTokens.d.ts +26 -0
- package/dist/Components/Editor/editorTokens.js +134 -0
- package/dist/Components/Editor/useEditorBridge.d.ts +40 -0
- package/dist/Components/Editor/useEditorBridge.js +141 -0
- package/dist/Components/EmptyState/EmptyState.js +2 -1
- package/dist/Components/EmptyState/EmptyStateProps.d.ts +2 -2
- package/dist/Components/FormDrawer/FormDrawer.d.ts +2 -0
- package/dist/Components/FormDrawer/FormDrawer.js +97 -0
- package/dist/Components/FormDrawer/FormDrawerProps.d.ts +55 -0
- package/dist/Components/FormDrawer/FormDrawerProps.js +2 -0
- package/dist/Components/Kbd/Kbd.d.ts +6 -0
- package/dist/Components/Kbd/Kbd.js +33 -0
- package/dist/Components/Kbd/KbdProps.d.ts +17 -0
- package/dist/Components/Kbd/KbdProps.js +2 -0
- package/dist/Components/LauncherTrigger/LauncherTrigger.d.ts +4 -0
- package/dist/Components/LauncherTrigger/LauncherTrigger.js +48 -0
- package/dist/Components/LauncherTrigger/LauncherTriggerProps.d.ts +18 -0
- package/dist/Components/LauncherTrigger/LauncherTriggerProps.js +2 -0
- package/dist/Components/Modal/Modal.d.ts +1 -1
- package/dist/Components/Modal/Modal.js +4 -2
- package/dist/Components/Modal/ModalProps.d.ts +3 -1
- package/dist/Components/Modal/warnDroppedSlotChildren.d.ts +2 -0
- package/dist/Components/Modal/warnDroppedSlotChildren.js +45 -0
- package/dist/Components/NavLauncher/NavLauncher.d.ts +3 -0
- package/dist/Components/NavLauncher/NavLauncher.js +452 -0
- package/dist/Components/NavLauncher/NavLauncherProps.d.ts +187 -0
- package/dist/Components/NavLauncher/NavLauncherProps.js +2 -0
- package/dist/Components/NavLauncher/NewTabLink.d.ts +3 -0
- package/dist/Components/NavLauncher/NewTabLink.js +14 -0
- package/dist/Components/NavLauncher/PinToggle.d.ts +3 -0
- package/dist/Components/NavLauncher/PinToggle.js +21 -0
- package/dist/Components/NavLauncher/launcherParts.d.ts +152 -0
- package/dist/Components/NavLauncher/launcherParts.js +212 -0
- package/dist/Components/NavLauncher/match.d.ts +53 -0
- package/dist/Components/NavLauncher/match.js +178 -0
- package/dist/Components/NavLauncher/revealStyles.d.ts +4 -0
- package/dist/Components/NavLauncher/revealStyles.js +19 -0
- package/dist/Components/NavigationBar/NavigationBar.d.ts +1 -1
- package/dist/Components/NavigationBar/NavigationBar.js +2 -2
- package/dist/Components/NavigationBar/NavigationBarProps.d.ts +2 -0
- package/dist/Components/PageHeader/PageHeader.d.ts +1 -1
- package/dist/Components/PageHeader/PageHeader.js +9 -2
- package/dist/Components/PageHeader/PageHeaderProps.d.ts +8 -0
- package/dist/Components/PdfViewer/PdfViewer.d.ts +21 -4
- package/dist/Components/PdfViewer/PdfViewer.js +124 -3
- package/dist/Components/ProfilePhotoViewer/ProfilePhotoViewer.js +5 -0
- package/dist/Components/ProfilePhotoViewer/ProfilePhotoViewerProps.d.ts +1 -1
- package/dist/Components/QueryState/QueryStateBoundary.d.ts +2 -2
- package/dist/Components/QueryState/QueryStateBoundary.js +9 -3
- package/dist/Components/QueryState/QueryStateProps.d.ts +19 -2
- package/dist/Components/Search/Search.js +2 -1
- package/dist/Components/SectionRail/SectionRail.d.ts +3 -0
- package/dist/Components/SectionRail/SectionRail.js +49 -0
- package/dist/Components/SectionRail/SectionRailProps.d.ts +23 -0
- package/dist/Components/SectionRail/SectionRailProps.js +2 -0
- package/dist/Components/SectionRail/index.d.ts +2 -0
- package/dist/Components/SectionRail/index.js +8 -0
- package/dist/Components/SegmentedControl/SegmentedControl.js +9 -14
- package/dist/Components/SegmentedControl/segmentedInk.d.ts +0 -2
- package/dist/Components/SegmentedControl/segmentedInk.js +1 -5
- package/dist/Components/SideBar/SecondaryBar.js +4 -3
- package/dist/Components/SideBar/SideBar.d.ts +1 -1
- package/dist/Components/SideBar/SideBar.js +30 -9
- package/dist/Components/SideBar/SideBarProps.d.ts +32 -0
- package/dist/Components/SideBar/components/MenuItemBox.d.ts +6 -0
- package/dist/Components/SideBar/components/MenuItemBox.js +8 -4
- package/dist/Components/SideBar/components/MenuPopoverContent.js +3 -2
- package/dist/Components/SideBar/components/OtherApps.js +2 -1
- package/dist/Components/SideBar/components/PinnedSection.d.ts +17 -0
- package/dist/Components/SideBar/components/PinnedSection.js +98 -0
- package/dist/Components/SideBar/sidebarFocus.d.ts +23 -0
- package/dist/Components/SideBar/sidebarFocus.js +20 -0
- package/dist/Components/StageProgress/StageProgress.js +2 -2
- package/dist/Components/StageProgress/StageProgressProps.d.ts +2 -0
- package/dist/Components/StageProgress/StepperStage.js +5 -2
- package/dist/Components/StatCard/StatCard.d.ts +1 -1
- package/dist/Components/StatCard/StatCard.js +6 -2
- package/dist/Components/StatCard/StatCardProps.d.ts +3 -0
- package/dist/Components/StatusTag/StatusTag.d.ts +4 -0
- package/dist/Components/StatusTag/StatusTag.js +24 -0
- package/dist/Components/StatusTag/StatusTagProps.d.ts +20 -0
- package/dist/Components/StatusTag/StatusTagProps.js +2 -0
- package/dist/Components/Table/Table.d.ts +1 -1
- package/dist/Components/Table/Table.js +6 -2
- package/dist/Components/Table/TableProps.d.ts +20 -0
- package/dist/Components/Table/components/TableBody.d.ts +1 -1
- package/dist/Components/Table/components/TableBody.js +43 -18
- package/dist/Components/Table/components/TableHeader.d.ts +1 -1
- package/dist/Components/Table/components/TableHeader.js +7 -5
- package/dist/Components/Table/components/rowDetail.d.ts +32 -0
- package/dist/Components/Table/components/rowDetail.js +20 -0
- package/dist/Components/Table/hooks/useRowExpansion.d.ts +7 -0
- package/dist/Components/Table/hooks/useRowExpansion.js +27 -0
- package/dist/Components/Tabs/Tabs.d.ts +1 -1
- package/dist/Components/Tabs/Tabs.js +15 -2
- package/dist/Components/Tabs/TabsProps.d.ts +6 -2
- package/dist/Components/Tabs/components/Tab.js +4 -33
- package/dist/Components/Tabs/components/TabLinkList.d.ts +7 -0
- package/dist/Components/Tabs/components/TabLinkList.js +34 -0
- package/dist/Components/Tabs/useTabAppearance.d.ts +17 -0
- package/dist/Components/Tabs/useTabAppearance.js +67 -0
- package/dist/Components/Tag/Tag.js +11 -1
- package/dist/Components/Tag/TagProps.d.ts +4 -0
- package/dist/Components/Tag/tagDot.d.ts +3 -0
- package/dist/Components/Tag/tagDot.js +21 -0
- package/dist/Components/WizardDialog/WizardDialog.d.ts +9 -0
- package/dist/Components/WizardDialog/WizardDialog.js +102 -0
- package/dist/Components/WizardDialog/WizardDialogProps.d.ts +48 -0
- package/dist/Components/WizardDialog/WizardDialogProps.js +2 -0
- package/dist/Components/WizardDialog/useWizardFlow.d.ts +22 -0
- package/dist/Components/WizardDialog/useWizardFlow.js +47 -0
- package/dist/Components/WizardDialog/wizardSteps.d.ts +31 -0
- package/dist/Components/WizardDialog/wizardSteps.js +40 -0
- package/dist/esm/Components/AppSwitcher/AppSwitcher.js +2 -1
- package/dist/esm/Components/AppSwitcher/AppSwitcherProps.js +5 -3
- package/dist/esm/Components/AudioRecorder/AudioRecorder.js +161 -0
- package/dist/esm/Components/AudioRecorder/AudioRecorderProps.js +1 -0
- package/dist/esm/Components/Breadcrumbs/Breadcrumbs.js +35 -12
- package/dist/esm/Components/BulkSelectionBar/BulkSelectionBar.js +38 -0
- package/dist/esm/Components/BulkSelectionBar/BulkSelectionBarProps.js +1 -0
- package/dist/esm/Components/BulkSelectionBar/index.js +1 -0
- package/dist/esm/Components/CalendarGrid/CalendarGrid.js +168 -0
- package/dist/esm/Components/CalendarGrid/CalendarGridProps.js +1 -0
- package/dist/esm/Components/CalendarGrid/calendarMath.js +155 -0
- package/dist/esm/Components/Card/Card.js +12 -2
- package/dist/esm/Components/CircularProgress/CircularProgress.js +37 -0
- package/dist/esm/Components/CircularProgress/CircularProgressProps.js +1 -0
- package/dist/esm/Components/CircularProgress/arc.js +11 -0
- package/dist/esm/Components/Common/fieldStyles.js +2 -1
- package/dist/esm/Components/Drawer/Drawer.js +4 -2
- package/dist/esm/Components/Editor/Editor.js +48 -3
- package/dist/esm/Components/Editor/EditorFieldBar.js +13 -0
- package/dist/esm/Components/Editor/MakeDynamicDialog.js +20 -0
- package/dist/esm/Components/Editor/editorLabels.js +20 -0
- package/dist/esm/Components/Editor/editorTokenStyles.js +25 -0
- package/dist/esm/Components/Editor/editorTokens.js +121 -0
- package/dist/esm/Components/Editor/useEditorBridge.js +138 -0
- package/dist/esm/Components/EmptyState/EmptyState.js +2 -1
- package/dist/esm/Components/FormDrawer/FormDrawer.js +58 -0
- package/dist/esm/Components/FormDrawer/FormDrawerProps.js +1 -0
- package/dist/esm/Components/Kbd/Kbd.js +28 -0
- package/dist/esm/Components/Kbd/KbdProps.js +1 -0
- package/dist/esm/Components/LauncherTrigger/LauncherTrigger.js +41 -0
- package/dist/esm/Components/LauncherTrigger/LauncherTriggerProps.js +1 -0
- package/dist/esm/Components/Modal/Modal.js +4 -2
- package/dist/esm/Components/Modal/warnDroppedSlotChildren.js +38 -0
- package/dist/esm/Components/NavLauncher/NavLauncher.js +413 -0
- package/dist/esm/Components/NavLauncher/NavLauncherProps.js +1 -0
- package/dist/esm/Components/NavLauncher/NewTabLink.js +11 -0
- package/dist/esm/Components/NavLauncher/PinToggle.js +18 -0
- package/dist/esm/Components/NavLauncher/launcherParts.js +187 -0
- package/dist/esm/Components/NavLauncher/match.js +172 -0
- package/dist/esm/Components/NavLauncher/revealStyles.js +15 -0
- package/dist/esm/Components/NavigationBar/NavigationBar.js +3 -3
- package/dist/esm/Components/PageHeader/PageHeader.js +9 -2
- package/dist/esm/Components/PdfViewer/PdfViewer.js +123 -2
- package/dist/esm/Components/ProfilePhotoViewer/ProfilePhotoViewer.js +5 -0
- package/dist/esm/Components/QueryState/QueryStateBoundary.js +10 -4
- package/dist/esm/Components/Search/Search.js +3 -2
- package/dist/esm/Components/SectionRail/SectionRail.js +44 -0
- package/dist/esm/Components/SectionRail/SectionRailProps.js +1 -0
- package/dist/esm/Components/SectionRail/index.js +1 -0
- package/dist/esm/Components/SegmentedControl/SegmentedControl.js +11 -16
- package/dist/esm/Components/SegmentedControl/segmentedInk.js +0 -3
- package/dist/esm/Components/SideBar/SecondaryBar.js +4 -3
- package/dist/esm/Components/SideBar/SideBar.js +31 -10
- package/dist/esm/Components/SideBar/components/MenuItemBox.js +4 -2
- package/dist/esm/Components/SideBar/components/MenuPopoverContent.js +3 -2
- package/dist/esm/Components/SideBar/components/OtherApps.js +2 -1
- package/dist/esm/Components/SideBar/components/PinnedSection.js +92 -0
- package/dist/esm/Components/SideBar/sidebarFocus.js +15 -0
- package/dist/esm/Components/StageProgress/StageProgress.js +2 -2
- package/dist/esm/Components/StageProgress/StepperStage.js +5 -2
- package/dist/esm/Components/StatCard/StatCard.js +6 -2
- package/dist/esm/Components/StatusTag/StatusTag.js +19 -0
- package/dist/esm/Components/StatusTag/StatusTagProps.js +1 -0
- package/dist/esm/Components/Table/Table.js +7 -3
- package/dist/esm/Components/Table/components/TableBody.js +43 -18
- package/dist/esm/Components/Table/components/TableHeader.js +7 -5
- package/dist/esm/Components/Table/components/rowDetail.js +14 -0
- package/dist/esm/Components/Table/hooks/useRowExpansion.js +23 -0
- package/dist/esm/Components/Tabs/Tabs.js +15 -2
- package/dist/esm/Components/Tabs/components/Tab.js +4 -33
- package/dist/esm/Components/Tabs/components/TabLinkList.js +29 -0
- package/dist/esm/Components/Tabs/useTabAppearance.js +63 -0
- package/dist/esm/Components/Tag/Tag.js +12 -2
- package/dist/esm/Components/Tag/tagDot.js +17 -0
- package/dist/esm/Components/WizardDialog/WizardDialog.js +58 -0
- package/dist/esm/Components/WizardDialog/WizardDialogProps.js +1 -0
- package/dist/esm/Components/WizardDialog/useWizardFlow.js +44 -0
- package/dist/esm/Components/WizardDialog/wizardSteps.js +35 -0
- package/dist/esm/index.js +14 -0
- package/dist/index.d.ts +35 -6
- package/dist/index.js +38 -4
- package/package.json +1 -1
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
|
+
const react_1 = require("react");
|
|
8
|
+
const react_2 = require("@chakra-ui/react");
|
|
9
|
+
const lucide_react_1 = require("lucide-react");
|
|
10
|
+
const Button_1 = __importDefault(require("../Button/Button"));
|
|
11
|
+
const Skeletons_1 = __importDefault(require("../Skeletons/Skeletons"));
|
|
12
|
+
const useCustomTheme_1 = require("../../Theme/useCustomTheme");
|
|
13
|
+
const focusRing_styles_1 = require("../../Theme/chakra/focusRing.styles");
|
|
14
|
+
const tone_1 = require("../../Theme/tokens/builders/tone");
|
|
15
|
+
const calendarMath_1 = require("./calendarMath");
|
|
16
|
+
const plural = (n, one, many) => `${n} ${n === 1 ? one : many}`;
|
|
17
|
+
const DEFAULT_LABELS = {
|
|
18
|
+
today: "Today",
|
|
19
|
+
previous: "Previous",
|
|
20
|
+
next: "Next",
|
|
21
|
+
month: "Month",
|
|
22
|
+
week: "Week",
|
|
23
|
+
day: "Day",
|
|
24
|
+
more: (count) => `+${count} more`,
|
|
25
|
+
moreLabel: (count, date) => `${plural(count, "more event", "more events")} on ${date}`,
|
|
26
|
+
eventCount: (count) => plural(count, "event", "events"),
|
|
27
|
+
};
|
|
28
|
+
const VIEWS = ["month", "week", "day"];
|
|
29
|
+
const MAX_LANES = { month: 3, week: 6, day: Infinity };
|
|
30
|
+
const MIN_CELL_HEIGHT = { month: "6.5rem", week: "12rem", day: "16rem" };
|
|
31
|
+
const LANE_HEIGHT = "1.5rem";
|
|
32
|
+
const CHIP_HEIGHT = "1.375rem";
|
|
33
|
+
const CHIP_INSET = "2px";
|
|
34
|
+
const EventChip = ({ event, colors, surface, onEventClick, segment }) => {
|
|
35
|
+
var _a;
|
|
36
|
+
const tone = (0, tone_1.resolveSoftTone)(colors, (0, tone_1.toneScale)(colors, (_a = event.tone) !== null && _a !== void 0 ? _a : "neutral"), surface);
|
|
37
|
+
const left = (segment === null || segment === void 0 ? void 0 : segment.continuesBefore) ? "0px" : CHIP_INSET;
|
|
38
|
+
const right = (segment === null || segment === void 0 ? void 0 : segment.continuesAfter) ? "0px" : CHIP_INSET;
|
|
39
|
+
const span = segment ? segment.endCol - segment.startCol + 1 : 1;
|
|
40
|
+
const placement = segment
|
|
41
|
+
? {
|
|
42
|
+
position: "absolute",
|
|
43
|
+
zIndex: 1,
|
|
44
|
+
top: `calc(${segment.lane} * ${LANE_HEIGHT})`,
|
|
45
|
+
left,
|
|
46
|
+
width: `calc(${span * 100}% + ${span - 1}px - ${left} - ${right})`,
|
|
47
|
+
}
|
|
48
|
+
: { width: "100%" };
|
|
49
|
+
const common = {
|
|
50
|
+
...placement,
|
|
51
|
+
display: "flex",
|
|
52
|
+
alignItems: "center",
|
|
53
|
+
h: CHIP_HEIGHT,
|
|
54
|
+
px: 2,
|
|
55
|
+
fontSize: "0.75rem",
|
|
56
|
+
fontWeight: 500,
|
|
57
|
+
lineHeight: 1,
|
|
58
|
+
textAlign: "left",
|
|
59
|
+
whiteSpace: "nowrap",
|
|
60
|
+
overflow: "hidden",
|
|
61
|
+
textOverflow: "ellipsis",
|
|
62
|
+
textDecoration: "none",
|
|
63
|
+
cursor: "pointer",
|
|
64
|
+
bg: tone.bg,
|
|
65
|
+
color: tone.fg,
|
|
66
|
+
border: "1px solid",
|
|
67
|
+
borderColor: tone.border,
|
|
68
|
+
borderLeftRadius: (segment === null || segment === void 0 ? void 0 : segment.continuesBefore) ? 0 : "md",
|
|
69
|
+
borderRightRadius: (segment === null || segment === void 0 ? void 0 : segment.continuesAfter) ? 0 : "md",
|
|
70
|
+
title: event.label,
|
|
71
|
+
"data-event-id": event.id,
|
|
72
|
+
onClick: () => onEventClick === null || onEventClick === void 0 ? void 0 : onEventClick(event),
|
|
73
|
+
_hover: { bg: tone.hoverBg, borderColor: tone.hoverBorder },
|
|
74
|
+
_active: { bg: tone.activeBg, borderColor: tone.activeBorder },
|
|
75
|
+
sx: (0, focusRing_styles_1.focusVisibleStyles)(colors),
|
|
76
|
+
};
|
|
77
|
+
return event.href ? ((0, jsx_runtime_1.jsx)(react_2.Box, { as: "a", href: event.href, ...common, children: event.label })) : ((0, jsx_runtime_1.jsx)(react_2.Box, { as: "button", type: "button", ...common, children: event.label }));
|
|
78
|
+
};
|
|
79
|
+
const CalendarGrid = ({ view, date, events, onViewChange, onDateChange, onEventClick, renderDayCell, weekStartsOn = 0, locale, isLoading = false, labels, }) => {
|
|
80
|
+
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
81
|
+
const text = { ...DEFAULT_LABELS, ...labels };
|
|
82
|
+
const today = new Date();
|
|
83
|
+
const anchor = (0, calendarMath_1.startOfDay)(date);
|
|
84
|
+
const anchorKey = (0, calendarMath_1.dayKey)(anchor);
|
|
85
|
+
const weeks = (0, calendarMath_1.visibleWeeks)(view, anchor, weekStartsOn);
|
|
86
|
+
const columns = weeks[0].length;
|
|
87
|
+
const visibleKeys = new Set(weeks.flat().map(calendarMath_1.dayKey));
|
|
88
|
+
const shownEvents = isLoading ? [] : events;
|
|
89
|
+
const maxLanes = MAX_LANES[view];
|
|
90
|
+
const [focusedKey, setFocusedKey] = (0, react_1.useState)(anchorKey);
|
|
91
|
+
const pendingFocus = (0, react_1.useRef)(false);
|
|
92
|
+
const cellRefs = (0, react_1.useRef)(new Map());
|
|
93
|
+
const activeKey = visibleKeys.has(focusedKey) ? focusedKey : visibleKeys.has(anchorKey) ? anchorKey : (0, calendarMath_1.dayKey)(weeks[0][0]);
|
|
94
|
+
(0, react_1.useEffect)(() => {
|
|
95
|
+
setFocusedKey(anchorKey);
|
|
96
|
+
}, [anchorKey]);
|
|
97
|
+
(0, react_1.useEffect)(() => {
|
|
98
|
+
if (!pendingFocus.current)
|
|
99
|
+
return;
|
|
100
|
+
const el = cellRefs.current.get(activeKey);
|
|
101
|
+
if (!el)
|
|
102
|
+
return;
|
|
103
|
+
pendingFocus.current = false;
|
|
104
|
+
el.focus();
|
|
105
|
+
});
|
|
106
|
+
const handleCellKeyDown = (e, cellDate) => {
|
|
107
|
+
if (e.target !== e.currentTarget)
|
|
108
|
+
return;
|
|
109
|
+
if ((0, calendarMath_1.isNavKey)(e.key)) {
|
|
110
|
+
e.preventDefault();
|
|
111
|
+
const next = (0, calendarMath_1.moveFocus)(view, cellDate, e.key, weekStartsOn);
|
|
112
|
+
const inRange = visibleKeys.has((0, calendarMath_1.dayKey)(next));
|
|
113
|
+
if (!inRange && !onDateChange)
|
|
114
|
+
return;
|
|
115
|
+
setFocusedKey((0, calendarMath_1.dayKey)(next));
|
|
116
|
+
pendingFocus.current = true;
|
|
117
|
+
if (!inRange)
|
|
118
|
+
onDateChange === null || onDateChange === void 0 ? void 0 : onDateChange(next);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if ((e.key === "Enter" || e.key === " ") && onDateChange) {
|
|
122
|
+
e.preventDefault();
|
|
123
|
+
onDateChange(cellDate);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
const drillIntoDay = (day) => {
|
|
127
|
+
onDateChange === null || onDateChange === void 0 ? void 0 : onDateChange(day);
|
|
128
|
+
onViewChange === null || onViewChange === void 0 ? void 0 : onViewChange("day");
|
|
129
|
+
};
|
|
130
|
+
const weekdayShort = (0, calendarMath_1.weekdayLabels)(locale, weekStartsOn, "short");
|
|
131
|
+
const weekdayLong = (0, calendarMath_1.weekdayLabels)(locale, weekStartsOn, "long");
|
|
132
|
+
const headerDays = view === "day" ? [(anchor.getDay() - weekStartsOn + 7) % 7] : weekdayShort.map((_, i) => i);
|
|
133
|
+
const title = (0, calendarMath_1.formatTitle)(view, anchor, locale, weekStartsOn);
|
|
134
|
+
const template = `repeat(${columns}, minmax(0, 1fr))`;
|
|
135
|
+
const border = colors.boxborder[200];
|
|
136
|
+
const renderCell = (day, col, weekIndex, layout) => {
|
|
137
|
+
const key = (0, calendarMath_1.dayKey)(day);
|
|
138
|
+
const isToday = (0, calendarMath_1.isSameDay)(day, today);
|
|
139
|
+
const inMonth = view !== "month" || day.getMonth() === anchor.getMonth();
|
|
140
|
+
const surface = (0, calendarMath_1.isWeekend)(day) ? colors.backgroundColor.secondary : colors.backgroundColor.main;
|
|
141
|
+
const dayEvents = (0, calendarMath_1.eventsOnDay)(shownEvents, day);
|
|
142
|
+
const hidden = layout.hiddenByCol[col];
|
|
143
|
+
const active = key === activeKey;
|
|
144
|
+
const label = `${(0, calendarMath_1.formatFullDate)(day, locale)}${dayEvents.length ? `, ${text.eventCount(dayEvents.length)}` : ""}`;
|
|
145
|
+
const ownSegments = layout.segments.filter((s) => s.startCol === col && s.lane < maxLanes);
|
|
146
|
+
let body = null;
|
|
147
|
+
if (isLoading) {
|
|
148
|
+
body = ((0, jsx_runtime_1.jsx)(react_2.Box, { mt: 1, "aria-hidden": true, children: (weekIndex * 7 + col) % 3 === 0 ? (0, jsx_runtime_1.jsx)(Skeletons_1.default, { type: "skeleton", height: CHIP_HEIGHT, borderRadius: "md" }) : null }));
|
|
149
|
+
}
|
|
150
|
+
else if (renderDayCell) {
|
|
151
|
+
body = (0, jsx_runtime_1.jsx)(react_2.Box, { mt: 1, children: renderDayCell(day, dayEvents) });
|
|
152
|
+
}
|
|
153
|
+
else if (view === "day") {
|
|
154
|
+
body = ((0, jsx_runtime_1.jsx)(react_2.Flex, { direction: "column", gap: 1, mt: 2, children: dayEvents.map((event) => ((0, jsx_runtime_1.jsx)(EventChip, { event: event, colors: colors, surface: surface, onEventClick: onEventClick }, event.id))) }));
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
body = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_2.Box, { position: "relative", mt: 1, h: `calc(${layout.visibleLanes} * ${LANE_HEIGHT})`, children: ownSegments.map((s) => ((0, jsx_runtime_1.jsx)(EventChip, { event: s.event, colors: colors, surface: surface, onEventClick: onEventClick, segment: s }, s.event.id))) }), hidden > 0 ? ((0, jsx_runtime_1.jsx)(react_2.Box, { as: "button", type: "button", "aria-label": text.moreLabel(hidden, (0, calendarMath_1.formatFullDate)(day, locale)), onClick: () => drillIntoDay(day), px: 1, fontSize: "0.75rem", fontWeight: 600, color: colors.header[900], textAlign: "left", textDecoration: "underline", sx: (0, focusRing_styles_1.focusVisibleStyles)(colors), children: text.more(hidden) })) : null] }));
|
|
158
|
+
}
|
|
159
|
+
return ((0, jsx_runtime_1.jsxs)(react_2.Box, { role: "gridcell", ref: (el) => {
|
|
160
|
+
if (el)
|
|
161
|
+
cellRefs.current.set(key, el);
|
|
162
|
+
else
|
|
163
|
+
cellRefs.current.delete(key);
|
|
164
|
+
}, "data-date": key, "aria-label": label, "aria-current": isToday ? "date" : undefined, tabIndex: active ? 0 : -1, onFocus: () => setFocusedKey(key), onKeyDown: (e) => handleCellKeyDown(e, day), position: "relative", minH: MIN_CELL_HEIGHT[view], p: 1, bg: surface, borderRight: "1px solid", borderBottom: "1px solid", borderColor: border, outline: "none", _focusVisible: {
|
|
165
|
+
boxShadow: `inset 0 0 0 2px ${colors.focusRing.halo}, inset 0 0 0 4px ${colors.focusRing.ring}`,
|
|
166
|
+
}, children: [(0, jsx_runtime_1.jsx)(react_2.Text, { as: "span", display: "inline-flex", alignItems: "center", justifyContent: "center", minW: "1.5rem", h: "1.5rem", px: 1, borderRadius: "full", fontSize: "0.8125rem", fontWeight: isToday ? 700 : 500, color: isToday ? colors.accentText : inMonth ? colors.header[900] : colors.textMuted, boxShadow: isToday ? `inset 0 0 0 1.5px ${colors.accentText}` : undefined, "aria-hidden": true, children: day.getDate() }), body] }, key));
|
|
167
|
+
};
|
|
168
|
+
return ((0, jsx_runtime_1.jsxs)(react_2.Box, { children: [(0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", justify: "space-between", wrap: "wrap", gap: 2, mb: 3, children: [(0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", gap: 2, children: [onDateChange ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Button_1.default, { label: text.today, size: "sm", variant: "outline", onClick: () => onDateChange((0, calendarMath_1.startOfDay)(new Date())) }), (0, jsx_runtime_1.jsx)(Button_1.default, { "aria-label": text.previous, size: "sm", variant: "ghost", leftIcon: (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronLeft, { size: 16, "aria-hidden": true }), onClick: () => onDateChange((0, calendarMath_1.shiftAnchor)(view, anchor, -1)) }), (0, jsx_runtime_1.jsx)(Button_1.default, { "aria-label": text.next, size: "sm", variant: "ghost", leftIcon: (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRight, { size: 16, "aria-hidden": true }), onClick: () => onDateChange((0, calendarMath_1.shiftAnchor)(view, anchor, 1)) })] })) : null, (0, jsx_runtime_1.jsx)(react_2.Text, { as: "h2", fontSize: "1rem", fontWeight: 600, color: colors.header[900], children: title })] }), onViewChange ? ((0, jsx_runtime_1.jsx)(react_2.Flex, { role: "group", "aria-label": text[view], gap: 1, children: VIEWS.map((v) => ((0, jsx_runtime_1.jsx)(Button_1.default, { label: text[v], size: "sm", variant: v === view ? "solid" : "outline", "aria-pressed": v === view, onClick: () => onViewChange(v) }, v))) })) : null] }), (0, jsx_runtime_1.jsx)(react_2.Box, { overflowX: "auto", children: (0, jsx_runtime_1.jsxs)(react_2.Box, { role: "grid", "aria-label": title, "aria-busy": isLoading || undefined, "data-view": view, minW: view === "day" ? undefined : "42rem", borderTop: "1px solid", borderLeft: "1px solid", borderColor: border, borderRadius: "lg", overflow: "hidden", children: [(0, jsx_runtime_1.jsx)(react_2.Grid, { role: "row", templateColumns: template, children: headerDays.map((i) => ((0, jsx_runtime_1.jsx)(react_2.Box, { role: "columnheader", "aria-label": weekdayLong[i], px: 2, py: 1, fontSize: "0.75rem", fontWeight: 600, color: colors.textMuted, bg: colors.backgroundColor.main, borderRight: "1px solid", borderBottom: "1px solid", borderColor: border, children: weekdayShort[i] }, i))) }), weeks.map((week, weekIndex) => {
|
|
169
|
+
const layout = (0, calendarMath_1.layoutWeek)(week, shownEvents, maxLanes);
|
|
170
|
+
return ((0, jsx_runtime_1.jsx)(react_2.Grid, { role: "row", templateColumns: template, children: week.map((day, col) => renderCell(day, col, weekIndex, layout)) }, (0, calendarMath_1.dayKey)(week[0])));
|
|
171
|
+
})] }) })] }));
|
|
172
|
+
};
|
|
173
|
+
exports.default = CalendarGrid;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { Tone } from "../../Theme/tokens/builders/tone";
|
|
3
|
+
/** Which span the grid shows: a month of weeks, one week, or a single day. */
|
|
4
|
+
export type CalendarGridView = "month" | "week" | "day";
|
|
5
|
+
/** A date-granularity event; time of day is ignored. */
|
|
6
|
+
export type CalendarEvent = {
|
|
7
|
+
id: string;
|
|
8
|
+
/** First day covered; only the date part is read. */
|
|
9
|
+
start: Date;
|
|
10
|
+
/** Last day covered, inclusive. Omit for a single-day event; a value before `start` is swapped. */
|
|
11
|
+
end?: Date;
|
|
12
|
+
label: string;
|
|
13
|
+
/** Status tint of the chip, same tones as Tag. Defaults to "neutral". */
|
|
14
|
+
tone?: Tone;
|
|
15
|
+
/** Renders the chip as a link; without it the chip is a button that fires `onEventClick`. */
|
|
16
|
+
href?: string;
|
|
17
|
+
};
|
|
18
|
+
/** Visible text and accessible names; every key falls back to English. */
|
|
19
|
+
export type CalendarGridLabels = {
|
|
20
|
+
today: string;
|
|
21
|
+
previous: string;
|
|
22
|
+
next: string;
|
|
23
|
+
month: string;
|
|
24
|
+
week: string;
|
|
25
|
+
day: string;
|
|
26
|
+
/** Receives the number of hidden events, e.g. "+3 more". */
|
|
27
|
+
more: (count: number) => string;
|
|
28
|
+
/** Accessible name of the "more" button, e.g. "3 more events on Tuesday, 14 October 2026". */
|
|
29
|
+
moreLabel: (count: number, date: string) => string;
|
|
30
|
+
/** Appended to a day cell's accessible name, e.g. "3 events". */
|
|
31
|
+
eventCount: (count: number) => string;
|
|
32
|
+
};
|
|
33
|
+
/** Props for the month/week/day event grid; fully controlled through `view` and `date`. */
|
|
34
|
+
export interface CalendarGridProps {
|
|
35
|
+
view: CalendarGridView;
|
|
36
|
+
/** Anchor date: any day inside the month, week or day being shown. */
|
|
37
|
+
date: Date;
|
|
38
|
+
events: CalendarEvent[];
|
|
39
|
+
/** Called by the toolbar's view switcher and by a cell's "+N more" button (with "day"). */
|
|
40
|
+
onViewChange?: (view: CalendarGridView) => void;
|
|
41
|
+
/** Called when the anchor should move: toolbar, arrow keys leaving the visible range, Enter on a cell, "+N more". */
|
|
42
|
+
onDateChange?: (date: Date) => void;
|
|
43
|
+
/** Called when an event chip is activated; link chips still navigate to `href`. */
|
|
44
|
+
onEventClick?: (event: CalendarEvent) => void;
|
|
45
|
+
/** Replaces a cell's event chips (and the multi-day spanning) with your own content, under the day number. */
|
|
46
|
+
renderDayCell?: (date: Date, events: CalendarEvent[]) => ReactNode;
|
|
47
|
+
/** First column of the week; defaults to 0 (Sunday). */
|
|
48
|
+
weekStartsOn?: 0 | 1;
|
|
49
|
+
/** BCP 47 tag for month, weekday and date names via Intl; defaults to the runtime locale. */
|
|
50
|
+
locale?: string;
|
|
51
|
+
/** Keeps the grid's shape and swaps the events for skeleton bars; sets aria-busy. */
|
|
52
|
+
isLoading?: boolean;
|
|
53
|
+
labels?: Partial<CalendarGridLabels>;
|
|
54
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export type CalendarView = "month" | "week" | "day";
|
|
2
|
+
export type WeekStart = 0 | 1;
|
|
3
|
+
export type SpanEvent = {
|
|
4
|
+
id: string;
|
|
5
|
+
start: Date;
|
|
6
|
+
end?: Date;
|
|
7
|
+
label: string;
|
|
8
|
+
};
|
|
9
|
+
export type WeekSegment<E extends SpanEvent> = {
|
|
10
|
+
event: E;
|
|
11
|
+
startCol: number;
|
|
12
|
+
endCol: number;
|
|
13
|
+
lane: number;
|
|
14
|
+
continuesBefore: boolean;
|
|
15
|
+
continuesAfter: boolean;
|
|
16
|
+
};
|
|
17
|
+
export type WeekLayout<E extends SpanEvent> = {
|
|
18
|
+
segments: WeekSegment<E>[];
|
|
19
|
+
visibleLanes: number;
|
|
20
|
+
hiddenByCol: number[];
|
|
21
|
+
};
|
|
22
|
+
export declare const startOfDay: (d: Date) => Date;
|
|
23
|
+
export declare const addDays: (d: Date, n: number) => Date;
|
|
24
|
+
export declare const addMonths: (d: Date, n: number) => Date;
|
|
25
|
+
export declare const isSameDay: (a: Date, b: Date) => boolean;
|
|
26
|
+
export declare const dayKey: (d: Date) => string;
|
|
27
|
+
export declare const isWeekend: (d: Date) => boolean;
|
|
28
|
+
/** Whole calendar days from `a` to `b`, counted on date components so a DST day is still one day. */
|
|
29
|
+
export declare const diffDays: (a: Date, b: Date) => number;
|
|
30
|
+
export declare const startOfWeek: (d: Date, weekStartsOn: WeekStart) => Date;
|
|
31
|
+
export declare const weekDays: (d: Date, weekStartsOn: WeekStart) => Date[];
|
|
32
|
+
/** Whole weeks that cover the month of `d`, padded with the neighbouring months' days. */
|
|
33
|
+
export declare const monthWeeks: (d: Date, weekStartsOn: WeekStart) => Date[][];
|
|
34
|
+
export declare const visibleWeeks: (view: CalendarView, d: Date, weekStartsOn: WeekStart) => Date[][];
|
|
35
|
+
export declare const shiftAnchor: (view: CalendarView, d: Date, direction: 1 | -1) => Date;
|
|
36
|
+
export declare const eventRange: (e: Pick<SpanEvent, "start" | "end">) => {
|
|
37
|
+
start: Date;
|
|
38
|
+
end: Date;
|
|
39
|
+
};
|
|
40
|
+
export declare const eventsOnDay: <E extends SpanEvent>(events: readonly E[], day: Date) => E[];
|
|
41
|
+
/** Lays events out in lanes across one week row; lanes past `maxLanes` are counted per column, not drawn. */
|
|
42
|
+
export declare const layoutWeek: <E extends SpanEvent>(days: readonly Date[], events: readonly E[], maxLanes: number) => WeekLayout<E>;
|
|
43
|
+
export type NavKey = "ArrowLeft" | "ArrowRight" | "ArrowUp" | "ArrowDown" | "Home" | "End" | "PageUp" | "PageDown";
|
|
44
|
+
export declare const NAV_KEYS: readonly string[];
|
|
45
|
+
export declare const isNavKey: (key: string) => key is NavKey;
|
|
46
|
+
export declare const moveFocus: (view: CalendarView, d: Date, key: NavKey, weekStartsOn: WeekStart) => Date;
|
|
47
|
+
export declare const weekdayLabels: (locale: string | undefined, weekStartsOn: WeekStart, style?: "short" | "long") => string[];
|
|
48
|
+
export declare const formatTitle: (view: CalendarView, d: Date, locale: string | undefined, weekStartsOn: WeekStart) => string;
|
|
49
|
+
export declare const formatFullDate: (d: Date, locale: string | undefined) => string;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatFullDate = exports.formatTitle = exports.weekdayLabels = exports.moveFocus = exports.isNavKey = exports.NAV_KEYS = exports.layoutWeek = exports.eventsOnDay = exports.eventRange = exports.shiftAnchor = exports.visibleWeeks = exports.monthWeeks = exports.weekDays = exports.startOfWeek = exports.diffDays = exports.isWeekend = exports.dayKey = exports.isSameDay = exports.addMonths = exports.addDays = exports.startOfDay = void 0;
|
|
4
|
+
const MS_PER_DAY = 86400000;
|
|
5
|
+
const startOfDay = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
6
|
+
exports.startOfDay = startOfDay;
|
|
7
|
+
const addDays = (d, n) => new Date(d.getFullYear(), d.getMonth(), d.getDate() + n);
|
|
8
|
+
exports.addDays = addDays;
|
|
9
|
+
const addMonths = (d, n) => {
|
|
10
|
+
const target = new Date(d.getFullYear(), d.getMonth() + n, 1);
|
|
11
|
+
const lastDay = new Date(target.getFullYear(), target.getMonth() + 1, 0).getDate();
|
|
12
|
+
return new Date(target.getFullYear(), target.getMonth(), Math.min(d.getDate(), lastDay));
|
|
13
|
+
};
|
|
14
|
+
exports.addMonths = addMonths;
|
|
15
|
+
const isSameDay = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
16
|
+
exports.isSameDay = isSameDay;
|
|
17
|
+
const dayKey = (d) => `${String(d.getFullYear()).padStart(4, "0")}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
|
|
18
|
+
exports.dayKey = dayKey;
|
|
19
|
+
const isWeekend = (d) => d.getDay() === 0 || d.getDay() === 6;
|
|
20
|
+
exports.isWeekend = isWeekend;
|
|
21
|
+
/** Whole calendar days from `a` to `b`, counted on date components so a DST day is still one day. */
|
|
22
|
+
const diffDays = (a, b) => Math.round((Date.UTC(b.getFullYear(), b.getMonth(), b.getDate()) - Date.UTC(a.getFullYear(), a.getMonth(), a.getDate())) /
|
|
23
|
+
MS_PER_DAY);
|
|
24
|
+
exports.diffDays = diffDays;
|
|
25
|
+
const startOfWeek = (d, weekStartsOn) => (0, exports.addDays)(d, -((d.getDay() - weekStartsOn + 7) % 7));
|
|
26
|
+
exports.startOfWeek = startOfWeek;
|
|
27
|
+
const weekDays = (d, weekStartsOn) => {
|
|
28
|
+
const first = (0, exports.startOfWeek)(d, weekStartsOn);
|
|
29
|
+
return Array.from({ length: 7 }, (_, i) => (0, exports.addDays)(first, i));
|
|
30
|
+
};
|
|
31
|
+
exports.weekDays = weekDays;
|
|
32
|
+
/** Whole weeks that cover the month of `d`, padded with the neighbouring months' days. */
|
|
33
|
+
const monthWeeks = (d, weekStartsOn) => {
|
|
34
|
+
const first = new Date(d.getFullYear(), d.getMonth(), 1);
|
|
35
|
+
const last = new Date(d.getFullYear(), d.getMonth() + 1, 0);
|
|
36
|
+
const gridStart = (0, exports.startOfWeek)(first, weekStartsOn);
|
|
37
|
+
const weekCount = Math.ceil(((0, exports.diffDays)(gridStart, last) + 1) / 7);
|
|
38
|
+
return Array.from({ length: weekCount }, (_, w) => Array.from({ length: 7 }, (_, i) => (0, exports.addDays)(gridStart, w * 7 + i)));
|
|
39
|
+
};
|
|
40
|
+
exports.monthWeeks = monthWeeks;
|
|
41
|
+
const visibleWeeks = (view, d, weekStartsOn) => {
|
|
42
|
+
if (view === "month")
|
|
43
|
+
return (0, exports.monthWeeks)(d, weekStartsOn);
|
|
44
|
+
if (view === "week")
|
|
45
|
+
return [(0, exports.weekDays)(d, weekStartsOn)];
|
|
46
|
+
return [[(0, exports.startOfDay)(d)]];
|
|
47
|
+
};
|
|
48
|
+
exports.visibleWeeks = visibleWeeks;
|
|
49
|
+
const shiftAnchor = (view, d, direction) => {
|
|
50
|
+
if (view === "month")
|
|
51
|
+
return (0, exports.addMonths)(d, direction);
|
|
52
|
+
return (0, exports.addDays)(d, view === "week" ? 7 * direction : direction);
|
|
53
|
+
};
|
|
54
|
+
exports.shiftAnchor = shiftAnchor;
|
|
55
|
+
const eventRange = (e) => {
|
|
56
|
+
const start = (0, exports.startOfDay)(e.start);
|
|
57
|
+
const end = e.end ? (0, exports.startOfDay)(e.end) : start;
|
|
58
|
+
return end < start ? { start: end, end: start } : { start, end };
|
|
59
|
+
};
|
|
60
|
+
exports.eventRange = eventRange;
|
|
61
|
+
const eventsOnDay = (events, day) => {
|
|
62
|
+
const d = (0, exports.startOfDay)(day);
|
|
63
|
+
return events.filter((e) => {
|
|
64
|
+
const r = (0, exports.eventRange)(e);
|
|
65
|
+
return r.start <= d && d <= r.end;
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
exports.eventsOnDay = eventsOnDay;
|
|
69
|
+
/** Lays events out in lanes across one week row; lanes past `maxLanes` are counted per column, not drawn. */
|
|
70
|
+
const layoutWeek = (days, events, maxLanes) => {
|
|
71
|
+
const first = days[0];
|
|
72
|
+
const lastCol = days.length - 1;
|
|
73
|
+
const candidates = events
|
|
74
|
+
.map((event) => {
|
|
75
|
+
const r = (0, exports.eventRange)(event);
|
|
76
|
+
const rawStart = (0, exports.diffDays)(first, r.start);
|
|
77
|
+
const rawEnd = (0, exports.diffDays)(first, r.end);
|
|
78
|
+
if (rawEnd < 0 || rawStart > lastCol)
|
|
79
|
+
return null;
|
|
80
|
+
return {
|
|
81
|
+
event,
|
|
82
|
+
rawStart,
|
|
83
|
+
length: rawEnd - rawStart,
|
|
84
|
+
startCol: Math.max(0, rawStart),
|
|
85
|
+
endCol: Math.min(lastCol, rawEnd),
|
|
86
|
+
continuesBefore: rawStart < 0,
|
|
87
|
+
continuesAfter: rawEnd > lastCol,
|
|
88
|
+
};
|
|
89
|
+
})
|
|
90
|
+
.filter((c) => c !== null)
|
|
91
|
+
.sort((a, b) => a.rawStart - b.rawStart ||
|
|
92
|
+
b.length - a.length ||
|
|
93
|
+
a.event.label.localeCompare(b.event.label) ||
|
|
94
|
+
a.event.id.localeCompare(b.event.id));
|
|
95
|
+
const occupied = [];
|
|
96
|
+
const segments = [];
|
|
97
|
+
for (const c of candidates) {
|
|
98
|
+
let lane = occupied.findIndex((row) => row.slice(c.startCol, c.endCol + 1).every((taken) => !taken));
|
|
99
|
+
if (lane === -1) {
|
|
100
|
+
lane = occupied.length;
|
|
101
|
+
occupied.push(new Array(days.length).fill(false));
|
|
102
|
+
}
|
|
103
|
+
for (let col = c.startCol; col <= c.endCol; col += 1)
|
|
104
|
+
occupied[lane][col] = true;
|
|
105
|
+
segments.push({
|
|
106
|
+
event: c.event,
|
|
107
|
+
startCol: c.startCol,
|
|
108
|
+
endCol: c.endCol,
|
|
109
|
+
lane,
|
|
110
|
+
continuesBefore: c.continuesBefore,
|
|
111
|
+
continuesAfter: c.continuesAfter,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
const hiddenByCol = new Array(days.length).fill(0);
|
|
115
|
+
for (const s of segments) {
|
|
116
|
+
if (s.lane < maxLanes)
|
|
117
|
+
continue;
|
|
118
|
+
for (let col = s.startCol; col <= s.endCol; col += 1)
|
|
119
|
+
hiddenByCol[col] += 1;
|
|
120
|
+
}
|
|
121
|
+
return { segments, visibleLanes: Math.min(occupied.length, maxLanes), hiddenByCol };
|
|
122
|
+
};
|
|
123
|
+
exports.layoutWeek = layoutWeek;
|
|
124
|
+
exports.NAV_KEYS = [
|
|
125
|
+
"ArrowLeft",
|
|
126
|
+
"ArrowRight",
|
|
127
|
+
"ArrowUp",
|
|
128
|
+
"ArrowDown",
|
|
129
|
+
"Home",
|
|
130
|
+
"End",
|
|
131
|
+
"PageUp",
|
|
132
|
+
"PageDown",
|
|
133
|
+
];
|
|
134
|
+
const isNavKey = (key) => exports.NAV_KEYS.includes(key);
|
|
135
|
+
exports.isNavKey = isNavKey;
|
|
136
|
+
const moveFocus = (view, d, key, weekStartsOn) => {
|
|
137
|
+
const columns = view === "day" ? 1 : 7;
|
|
138
|
+
switch (key) {
|
|
139
|
+
case "ArrowLeft":
|
|
140
|
+
return (0, exports.addDays)(d, -1);
|
|
141
|
+
case "ArrowRight":
|
|
142
|
+
return (0, exports.addDays)(d, 1);
|
|
143
|
+
case "ArrowUp":
|
|
144
|
+
return (0, exports.addDays)(d, -columns);
|
|
145
|
+
case "ArrowDown":
|
|
146
|
+
return (0, exports.addDays)(d, columns);
|
|
147
|
+
case "Home":
|
|
148
|
+
return view === "day" ? d : (0, exports.startOfWeek)(d, weekStartsOn);
|
|
149
|
+
case "End":
|
|
150
|
+
return view === "day" ? d : (0, exports.addDays)((0, exports.startOfWeek)(d, weekStartsOn), 6);
|
|
151
|
+
case "PageUp":
|
|
152
|
+
return (0, exports.shiftAnchor)(view, d, -1);
|
|
153
|
+
default:
|
|
154
|
+
return (0, exports.shiftAnchor)(view, d, 1);
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
exports.moveFocus = moveFocus;
|
|
158
|
+
const probe = (weekday) => new Date(2024, 0, 7 + weekday);
|
|
159
|
+
const weekdayLabels = (locale, weekStartsOn, style = "short") => {
|
|
160
|
+
const fmt = new Intl.DateTimeFormat(locale, { weekday: style });
|
|
161
|
+
return Array.from({ length: 7 }, (_, i) => fmt.format(probe((i + weekStartsOn) % 7)));
|
|
162
|
+
};
|
|
163
|
+
exports.weekdayLabels = weekdayLabels;
|
|
164
|
+
const formatTitle = (view, d, locale, weekStartsOn) => {
|
|
165
|
+
if (view === "month")
|
|
166
|
+
return new Intl.DateTimeFormat(locale, { month: "long", year: "numeric" }).format(d);
|
|
167
|
+
if (view === "day")
|
|
168
|
+
return new Intl.DateTimeFormat(locale, { weekday: "long", day: "numeric", month: "long", year: "numeric" }).format(d);
|
|
169
|
+
const days = (0, exports.weekDays)(d, weekStartsOn);
|
|
170
|
+
const opts = { day: "numeric", month: "short", year: "numeric" };
|
|
171
|
+
const fmt = new Intl.DateTimeFormat(locale, opts);
|
|
172
|
+
return typeof fmt.formatRange === "function"
|
|
173
|
+
? fmt.formatRange(days[0], days[6])
|
|
174
|
+
: `${fmt.format(days[0])} - ${fmt.format(days[6])}`;
|
|
175
|
+
};
|
|
176
|
+
exports.formatTitle = formatTitle;
|
|
177
|
+
const formatFullDate = (d, locale) => new Intl.DateTimeFormat(locale, { weekday: "long", day: "numeric", month: "long", year: "numeric" }).format(d);
|
|
178
|
+
exports.formatFullDate = formatFullDate;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { CardPadding } from "./CardProps";
|
|
2
|
+
declare const Card: import("react").ForwardRefExoticComponent<Omit<import("@chakra-ui/react").CardProps, "color" | "colorScheme" | "direction" | "padding" | "size" | "justify" | "children" | "variant" | "align"> & {
|
|
2
3
|
dividercolor?: "gray" | "red" | "orange" | "yellow" | "green" | "teal" | "blue" | "cyan" | "purple" | "pink" | "whiteAlpha" | "blackAlpha";
|
|
3
4
|
dividersize?: string;
|
|
4
5
|
dividervariant?: "solid" | "dashed";
|
|
@@ -13,6 +14,7 @@ declare const Card: import("react").ForwardRefExoticComponent<Omit<import("@chak
|
|
|
13
14
|
direction?: import("@chakra-ui/react").ResponsiveValue<"row" | "column" | "row-reverse" | "column-reverse">;
|
|
14
15
|
align?: import("@chakra-ui/react").CardBodyProps["alignItems"];
|
|
15
16
|
justify?: import("@chakra-ui/react").CardBodyProps["justifyContent"];
|
|
17
|
+
padding?: CardPadding;
|
|
16
18
|
bodyProps?: import("@chakra-ui/react").CardBodyProps;
|
|
17
19
|
} & import("react").RefAttributes<HTMLDivElement>>;
|
|
18
20
|
export default Card;
|
|
@@ -3,11 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
4
4
|
const react_1 = require("react");
|
|
5
5
|
const react_2 = require("@chakra-ui/react");
|
|
6
|
-
const
|
|
6
|
+
const HEADER_PADDING_WHEN_FLUSH = "0.75rem";
|
|
7
|
+
const PADDING_VALUES = {
|
|
8
|
+
none: "0",
|
|
9
|
+
"2xs": "0.375rem",
|
|
10
|
+
xs: "0.75rem",
|
|
11
|
+
sm: "0.75rem 1rem",
|
|
12
|
+
md: "1rem 1.25rem",
|
|
13
|
+
lg: "1.25rem 1.5rem",
|
|
14
|
+
};
|
|
15
|
+
const Card = (0, react_1.forwardRef)(function Card({ header, footer, children, color, colorScheme, direction = "column", align, justify, bodyProps, padding, ...rest }, ref) {
|
|
7
16
|
const cardProps = { ...rest };
|
|
8
17
|
delete cardProps.dividercolor;
|
|
9
18
|
delete cardProps.dividersize;
|
|
10
19
|
delete cardProps.dividervariant;
|
|
11
|
-
|
|
20
|
+
const sx = padding ? { "--card-padding": PADDING_VALUES[padding], ...cardProps.sx } : cardProps.sx;
|
|
21
|
+
return ((0, jsx_runtime_1.jsxs)(react_2.Card, { ref: ref, colorScheme: colorScheme !== null && colorScheme !== void 0 ? colorScheme : color, ...cardProps, sx: sx, children: [header && ((0, jsx_runtime_1.jsx)(react_2.CardHeader, { sx: padding === "none" ? { "--card-padding": HEADER_PADDING_WHEN_FLUSH } : undefined, children: header })), (0, jsx_runtime_1.jsx)(react_2.CardBody, { display: "flex", flexDirection: direction, alignItems: align, justifyContent: justify, ...bodyProps, children: children }), footer && (0, jsx_runtime_1.jsx)(react_2.CardFooter, { children: footer })] }));
|
|
12
22
|
});
|
|
13
23
|
exports.default = Card;
|
|
@@ -6,8 +6,10 @@ type DeadDividerProps = {
|
|
|
6
6
|
dividersize?: string;
|
|
7
7
|
dividervariant?: "solid" | "dashed";
|
|
8
8
|
};
|
|
9
|
+
/** Padding steps: "none" flush, "2xs" 0.375rem, "xs" 0.75rem all round, "sm" / "md" / "lg" match `size`. */
|
|
10
|
+
export type CardPadding = "none" | "2xs" | "xs" | "sm" | "md" | "lg";
|
|
9
11
|
/** Themed outline surface with optional header/footer slots; children and direction/align/justify apply to the body. */
|
|
10
|
-
export type CardProps = Omit<ChakraCardProps, "children" | "variant" | "size" | "color" | "colorScheme" | "direction" | "align" | "justify"> & DeadDividerProps & {
|
|
12
|
+
export type CardProps = Omit<ChakraCardProps, "children" | "variant" | "size" | "color" | "colorScheme" | "direction" | "align" | "justify" | "padding"> & DeadDividerProps & {
|
|
11
13
|
/** Rendered in CardHeader (semibold header ink) only when truthy. */
|
|
12
14
|
header?: React.ReactNode;
|
|
13
15
|
/** Rendered in CardFooter only when truthy. */
|
|
@@ -27,6 +29,8 @@ export type CardProps = Omit<ChakraCardProps, "children" | "variant" | "size" |
|
|
|
27
29
|
align?: CardBodyProps["alignItems"];
|
|
28
30
|
/** Body justifyContent; `bodyProps` wins if it sets the same thing. */
|
|
29
31
|
justify?: CardBodyProps["justifyContent"];
|
|
32
|
+
/** Overrides `size`'s padding for header, body and footer; "none" is flush (a header keeps "xs"), "2xs" is 6px. */
|
|
33
|
+
padding?: CardPadding;
|
|
30
34
|
/** Props for the body wrapper, e.g. `p={0}` for edge-to-edge media. */
|
|
31
35
|
bodyProps?: CardBodyProps;
|
|
32
36
|
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CircularProgressProps } from "./CircularProgressProps";
|
|
2
|
+
/** Ring-shaped determinate progress with a centred label — for a linear bar use ProgressBar. */
|
|
3
|
+
declare const CircularProgress: ({ value, max, size, thickness, tone, label, "aria-label": ariaLabel, "data-testid": testId, }: CircularProgressProps) => import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
export default CircularProgress;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
4
|
+
const react_1 = require("@chakra-ui/react");
|
|
5
|
+
const useCustomTheme_1 = require("../../Theme/useCustomTheme");
|
|
6
|
+
const tone_1 = require("../../Theme/tokens/builders/tone");
|
|
7
|
+
const motion_1 = require("../../Theme/tokens/primitives/motion");
|
|
8
|
+
const motion_2 = require("../../Theme/chakra/motion");
|
|
9
|
+
const arc_1 = require("./arc");
|
|
10
|
+
const Circle = (0, react_1.chakra)("circle");
|
|
11
|
+
const LABEL_FONT = {
|
|
12
|
+
sm: "0.625rem",
|
|
13
|
+
md: "0.75rem",
|
|
14
|
+
lg: "1rem",
|
|
15
|
+
};
|
|
16
|
+
const scaleFor = (colors, tone) => tone === "info" ? colors.primary : (0, tone_1.toneScale)(colors, tone);
|
|
17
|
+
/** Ring-shaped determinate progress with a centred label — for a linear bar use ProgressBar. */
|
|
18
|
+
const CircularProgress = ({ value, max = 100, size = "md", thickness, tone = "info", label, "aria-label": ariaLabel, "data-testid": testId, }) => {
|
|
19
|
+
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
20
|
+
const diameter = arc_1.SIZE_PX[size];
|
|
21
|
+
const stroke = thickness !== null && thickness !== void 0 ? thickness : arc_1.THICKNESS_PX[size];
|
|
22
|
+
const { radius, circumference, fraction, clamped, safeMax, dashOffset } = (0, arc_1.arcGeometry)(diameter, stroke, value, max);
|
|
23
|
+
const ink = (0, tone_1.resolveSoftTone)(colors, scaleFor(colors, tone), colors.background[50]).fg;
|
|
24
|
+
const center = diameter / 2;
|
|
25
|
+
const valueText = typeof label === "string" || typeof label === "number" ? String(label) : undefined;
|
|
26
|
+
return ((0, jsx_runtime_1.jsxs)(react_1.Box, { role: "progressbar", "aria-label": ariaLabel, "aria-valuenow": clamped, "aria-valuemin": 0, "aria-valuemax": safeMax, "aria-valuetext": valueText, "data-testid": testId, position: "relative", display: "inline-flex", flexShrink: 0, boxSize: `${diameter}px`, children: [(0, jsx_runtime_1.jsxs)("svg", { width: diameter, height: diameter, viewBox: `0 0 ${diameter} ${diameter}`, "aria-hidden": true, focusable: "false", children: [(0, jsx_runtime_1.jsx)(Circle, { cx: center, cy: center, r: radius, fill: "none", sx: { stroke: colors.backgroundColor.subtle, strokeWidth: stroke } }), (0, jsx_runtime_1.jsx)(Circle, { cx: center, cy: center, r: radius, fill: "none", "data-testid": testId ? `${testId}-arc` : undefined, sx: {
|
|
27
|
+
stroke: ink,
|
|
28
|
+
strokeWidth: stroke,
|
|
29
|
+
strokeLinecap: "round",
|
|
30
|
+
strokeDasharray: circumference,
|
|
31
|
+
strokeDashoffset: dashOffset,
|
|
32
|
+
strokeOpacity: fraction > 0 ? 1 : 0,
|
|
33
|
+
transform: "rotate(-90deg)",
|
|
34
|
+
transformOrigin: "50% 50%",
|
|
35
|
+
transition: (0, motion_1.transitionFor)(["stroke-dashoffset"]),
|
|
36
|
+
...(0, motion_2.reducedMotionSx)(),
|
|
37
|
+
} })] }), label !== undefined && label !== null && ((0, jsx_runtime_1.jsx)(react_1.Flex, { position: "absolute", inset: 0, align: "center", justify: "center", fontSize: LABEL_FONT[size], fontWeight: 600, lineHeight: 1, color: colors.header[900], sx: { fontVariantNumeric: "tabular-nums" }, children: label }))] }));
|
|
38
|
+
};
|
|
39
|
+
exports.default = CircularProgress;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { Tone } from "../../Theme/tokens/builders/tone";
|
|
3
|
+
/** Diameter preset: sm 32px, md 48px, lg 72px. */
|
|
4
|
+
export type CircularProgressSize = "sm" | "md" | "lg";
|
|
5
|
+
/** Props for the SVG ring CircularProgress; the arc starts at 12 o'clock and fills clockwise. */
|
|
6
|
+
export interface CircularProgressProps {
|
|
7
|
+
/** Current progress, clamped to 0..max. */
|
|
8
|
+
value: number;
|
|
9
|
+
/** Upper bound of the range; default 100. */
|
|
10
|
+
max?: number;
|
|
11
|
+
/** Diameter preset (32 / 48 / 72px); default "md". */
|
|
12
|
+
size?: CircularProgressSize;
|
|
13
|
+
/** Ring stroke in px; defaults by size (4 / 5 / 7). */
|
|
14
|
+
thickness?: number;
|
|
15
|
+
/** Fill colour; default "info", which paints the brand primary rather than blue. */
|
|
16
|
+
tone?: Tone;
|
|
17
|
+
/** Centred content such as "7/10"; a string or number is also spoken as aria-valuetext. */
|
|
18
|
+
label?: ReactNode;
|
|
19
|
+
/** Required accessible name; the ring has no visible caption of its own. */
|
|
20
|
+
"aria-label": string;
|
|
21
|
+
"data-testid"?: string;
|
|
22
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CircularProgressSize } from "./CircularProgressProps";
|
|
2
|
+
export declare const SIZE_PX: Record<CircularProgressSize, number>;
|
|
3
|
+
export declare const THICKNESS_PX: Record<CircularProgressSize, number>;
|
|
4
|
+
export declare const clampValue: (value: number, max: number) => number;
|
|
5
|
+
export declare const arcGeometry: (diameter: number, thickness: number, value: number, max: number) => {
|
|
6
|
+
radius: number;
|
|
7
|
+
circumference: number;
|
|
8
|
+
fraction: number;
|
|
9
|
+
clamped: number;
|
|
10
|
+
safeMax: number;
|
|
11
|
+
dashOffset: number;
|
|
12
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.arcGeometry = exports.clampValue = exports.THICKNESS_PX = exports.SIZE_PX = void 0;
|
|
4
|
+
exports.SIZE_PX = { sm: 32, md: 48, lg: 72 };
|
|
5
|
+
exports.THICKNESS_PX = { sm: 4, md: 5, lg: 7 };
|
|
6
|
+
const clampValue = (value, max) => Number.isFinite(value) ? Math.min(Math.max(value, 0), max) : 0;
|
|
7
|
+
exports.clampValue = clampValue;
|
|
8
|
+
const arcGeometry = (diameter, thickness, value, max) => {
|
|
9
|
+
const safeMax = max > 0 ? max : 100;
|
|
10
|
+
const clamped = (0, exports.clampValue)(value, safeMax);
|
|
11
|
+
const radius = Math.max((diameter - thickness) / 2, 0);
|
|
12
|
+
const circumference = 2 * Math.PI * radius;
|
|
13
|
+
const fraction = clamped / safeMax;
|
|
14
|
+
return { radius, circumference, fraction, clamped, safeMax, dashOffset: circumference * (1 - fraction) };
|
|
15
|
+
};
|
|
16
|
+
exports.arcGeometry = arcGeometry;
|
|
@@ -4,6 +4,7 @@ import type { PaletteProps } from "../../Theme/tokens/types";
|
|
|
4
4
|
import { type ControlSize } from "../../Theme/tokens/primitives/controlSizes";
|
|
5
5
|
export declare const FIELD_RADIUS = "lg";
|
|
6
6
|
export declare const FIELD_BORDER_WIDTH = "1px";
|
|
7
|
+
/** No box-shadow: the focus ring must be present the frame focus lands, not fade in. */
|
|
7
8
|
export declare const FIELD_TRANSITION: string;
|
|
8
9
|
/** Chakra `h`/`fontSize`/`px` for a field or select of this size. */
|
|
9
10
|
export declare const controlSizeStyles: (size: ControlSize) => {
|