@windrun-huaiin/third-ui 29.1.0 → 29.2.1
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/dist/fuma/base/custom-header.js +6 -3
- package/dist/fuma/base/custom-header.mjs +6 -3
- package/dist/main/alert-dialog/confirm-dialog.d.ts +6 -3
- package/dist/main/alert-dialog/confirm-dialog.js +7 -7
- package/dist/main/alert-dialog/confirm-dialog.mjs +8 -8
- package/dist/main/alert-dialog/dialog-loading-action.d.ts +13 -0
- package/dist/main/alert-dialog/dialog-loading-action.js +42 -0
- package/dist/main/alert-dialog/dialog-loading-action.mjs +40 -0
- package/dist/main/alert-dialog/high-priority-confirm-dialog.d.ts +6 -3
- package/dist/main/alert-dialog/high-priority-confirm-dialog.js +10 -4
- package/dist/main/alert-dialog/high-priority-confirm-dialog.mjs +11 -5
- package/dist/main/alert-dialog/index.d.ts +1 -0
- package/dist/main/alert-dialog/info-dialog.d.ts +5 -2
- package/dist/main/alert-dialog/info-dialog.js +6 -5
- package/dist/main/alert-dialog/info-dialog.mjs +7 -6
- package/dist/main/alert-dialog/undoable-confirm-dialog.d.ts +7 -4
- package/dist/main/alert-dialog/undoable-confirm-dialog.js +18 -17
- package/dist/main/alert-dialog/undoable-confirm-dialog.mjs +19 -18
- package/dist/main/buttons/gradient-button.d.ts +3 -1
- package/dist/main/buttons/gradient-button.js +29 -3
- package/dist/main/buttons/gradient-button.mjs +29 -3
- package/dist/main/buttons/index.d.ts +1 -0
- package/dist/main/buttons/index.js +3 -0
- package/dist/main/buttons/index.mjs +1 -0
- package/dist/main/buttons/use-press-feedback.d.ts +18 -0
- package/dist/main/buttons/use-press-feedback.js +42 -0
- package/dist/main/buttons/use-press-feedback.mjs +39 -0
- package/dist/main/buttons/x-button.d.ts +3 -0
- package/dist/main/buttons/x-button.js +36 -6
- package/dist/main/buttons/x-button.mjs +36 -6
- package/dist/main/calendar/calendar-date-range-input.d.ts +17 -0
- package/dist/main/calendar/calendar-date-range-input.js +81 -0
- package/dist/main/calendar/calendar-date-range-input.mjs +79 -0
- package/dist/main/calendar/calendar-status-view.d.ts +23 -0
- package/dist/main/calendar/calendar-status-view.js +155 -0
- package/dist/main/calendar/calendar-status-view.mjs +153 -0
- package/dist/main/calendar/index.d.ts +3 -0
- package/dist/main/calendar/index.js +12 -0
- package/dist/main/calendar/index.mjs +4 -0
- package/dist/main/calendar/random-date-range-dialog.d.ts +18 -0
- package/dist/main/calendar/random-date-range-dialog.js +451 -0
- package/dist/main/calendar/random-date-range-dialog.mjs +449 -0
- package/package.json +6 -1
- package/src/fuma/base/custom-header.tsx +6 -3
- package/src/main/alert-dialog/confirm-dialog.tsx +54 -47
- package/src/main/alert-dialog/dialog-loading-action.tsx +78 -0
- package/src/main/alert-dialog/high-priority-confirm-dialog.tsx +63 -48
- package/src/main/alert-dialog/index.ts +1 -0
- package/src/main/alert-dialog/info-dialog.tsx +52 -44
- package/src/main/alert-dialog/undoable-confirm-dialog.tsx +90 -82
- package/src/main/buttons/gradient-button.tsx +36 -3
- package/src/main/buttons/index.ts +1 -0
- package/src/main/buttons/use-press-feedback.ts +58 -0
- package/src/main/buttons/x-button.tsx +53 -11
- package/src/main/calendar/calendar-date-range-input.tsx +173 -0
- package/src/main/calendar/calendar-status-view.tsx +365 -0
- package/src/main/calendar/index.ts +5 -0
- package/src/main/calendar/random-date-range-dialog.tsx +753 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
var React = require('react');
|
|
6
|
+
var icons = require('@windrun-huaiin/base-ui/icons');
|
|
7
|
+
var lib = require('@windrun-huaiin/base-ui/lib');
|
|
8
|
+
var utils = require('@windrun-huaiin/lib/utils');
|
|
9
|
+
var usePressFeedback = require('../buttons/use-press-feedback.js');
|
|
10
|
+
var randomDateRangeDialog = require('./random-date-range-dialog.js');
|
|
11
|
+
|
|
12
|
+
const DEFAULT_PLACEHOLDER = '滑动窗口日期';
|
|
13
|
+
const DEFAULT_RANGE_DAYS = 7;
|
|
14
|
+
const CLEAR_PRESS_FEEDBACK_MS = 180;
|
|
15
|
+
function parseDateString(value) {
|
|
16
|
+
return new Date(`${value}T00:00:00.000Z`);
|
|
17
|
+
}
|
|
18
|
+
function getTodayString() {
|
|
19
|
+
return new Date().toISOString().slice(0, 10);
|
|
20
|
+
}
|
|
21
|
+
function getInclusiveDayCount(value) {
|
|
22
|
+
if (!value.startDate || !value.endDate) {
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
25
|
+
const startTime = parseDateString(value.startDate).getTime();
|
|
26
|
+
const endTime = parseDateString(value.endDate).getTime();
|
|
27
|
+
return Math.max(0, Math.floor(Math.abs(endTime - startTime) / 86400000) + 1);
|
|
28
|
+
}
|
|
29
|
+
function getRangeLabel(value, showDayCount, dayCountUnit) {
|
|
30
|
+
if (!value.startDate || !value.endDate) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
const dateLabel = `${value.startDate} ~ ${value.endDate}`;
|
|
34
|
+
if (!showDayCount) {
|
|
35
|
+
return dateLabel;
|
|
36
|
+
}
|
|
37
|
+
return `${dateLabel} · ${getInclusiveDayCount(value)}${dayCountUnit}`;
|
|
38
|
+
}
|
|
39
|
+
function CalendarDateRangeInput({ value, onChange, placeholder = DEFAULT_PLACEHOLDER, defaultRangeDays = DEFAULT_RANGE_DAYS, disabled = false, className, showDayCount = false, dayCountUnit = 'D', themedCalendarIcon = true, clearPressFeedback = 'subtle', onOpenChange, }) {
|
|
40
|
+
var _a;
|
|
41
|
+
const [open, setOpen] = React.useState(false);
|
|
42
|
+
const pressMode = usePressFeedback.resolvePressFeedbackMode(clearPressFeedback);
|
|
43
|
+
const { pressedKey, flash, getPressProps } = usePressFeedback.usePressFeedback(CLEAR_PRESS_FEEDBACK_MS);
|
|
44
|
+
const label = getRangeLabel(value, showDayCount, dayCountUnit);
|
|
45
|
+
const hasValue = Boolean(value.startDate || value.endDate);
|
|
46
|
+
const isClearPressed = pressMode !== 'none' && pressedKey === 'clear' && !disabled;
|
|
47
|
+
function handleOpenChange(nextOpen) {
|
|
48
|
+
setOpen(nextOpen);
|
|
49
|
+
onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(nextOpen);
|
|
50
|
+
}
|
|
51
|
+
function handleClear() {
|
|
52
|
+
onChange({ startDate: null, endDate: null });
|
|
53
|
+
}
|
|
54
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { role: "button", tabIndex: disabled ? -1 : 0, "aria-disabled": disabled, onClick: () => {
|
|
55
|
+
if (!disabled) {
|
|
56
|
+
handleOpenChange(true);
|
|
57
|
+
}
|
|
58
|
+
}, onKeyDown: (event) => {
|
|
59
|
+
if (disabled) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
63
|
+
event.preventDefault();
|
|
64
|
+
handleOpenChange(true);
|
|
65
|
+
}
|
|
66
|
+
}, className: utils.cn('flex h-11 w-full cursor-pointer items-center rounded-2xl border border-border/70 bg-background/80 text-left text-sm shadow-sm transition hover:bg-accent/40', disabled && 'cursor-not-allowed opacity-60 hover:bg-background/80', className), children: [jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-1 items-center gap-2 px-3", children: [jsxRuntime.jsx(icons.CalendarDaysIcon, { className: utils.cn('h-4 w-4 shrink-0', themedCalendarIcon ? lib.themeIconColor : 'text-muted-foreground') }), jsxRuntime.jsx("span", { className: utils.cn('truncate', label ? 'text-foreground' : 'text-muted-foreground'), children: label !== null && label !== void 0 ? label : placeholder })] }), jsxRuntime.jsx("button", Object.assign({ type: "button", disabled: disabled || !hasValue, onClick: (event) => {
|
|
67
|
+
event.stopPropagation();
|
|
68
|
+
if (disabled || !hasValue) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (pressMode !== 'none') {
|
|
72
|
+
flash('clear');
|
|
73
|
+
}
|
|
74
|
+
handleClear();
|
|
75
|
+
}, className: utils.cn('mr-1 inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-[transform,background-color,color,box-shadow]', hasValue
|
|
76
|
+
? 'hover:bg-black/10 hover:text-foreground dark:hover:bg-white/12'
|
|
77
|
+
: 'cursor-default opacity-35', isClearPressed &&
|
|
78
|
+
'scale-90 bg-black/15 text-foreground shadow-inner dark:bg-white/18'), "aria-label": "Clear date range", title: "Clear date range" }, (pressMode !== 'none' && !disabled && hasValue ? getPressProps('clear') : {}), { children: jsxRuntime.jsx(icons.XIcon, { className: "h-4 w-4" }) }))] }), jsxRuntime.jsx(randomDateRangeDialog.RandomDateRangeDialog, { open: open, value: value, anchorDate: (_a = value.startDate) !== null && _a !== void 0 ? _a : getTodayString(), defaultRangeDays: defaultRangeDays, onOpenChange: handleOpenChange, onApply: onChange, onClear: onChange })] }));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
exports.CalendarDateRangeInput = CalendarDateRangeInput;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { CalendarDaysIcon, XIcon } from '@windrun-huaiin/base-ui/icons';
|
|
5
|
+
import { themeIconColor } from '@windrun-huaiin/base-ui/lib';
|
|
6
|
+
import { cn } from '@windrun-huaiin/lib/utils';
|
|
7
|
+
import { usePressFeedback, resolvePressFeedbackMode } from '../buttons/use-press-feedback.mjs';
|
|
8
|
+
import { RandomDateRangeDialog } from './random-date-range-dialog.mjs';
|
|
9
|
+
|
|
10
|
+
const DEFAULT_PLACEHOLDER = '滑动窗口日期';
|
|
11
|
+
const DEFAULT_RANGE_DAYS = 7;
|
|
12
|
+
const CLEAR_PRESS_FEEDBACK_MS = 180;
|
|
13
|
+
function parseDateString(value) {
|
|
14
|
+
return new Date(`${value}T00:00:00.000Z`);
|
|
15
|
+
}
|
|
16
|
+
function getTodayString() {
|
|
17
|
+
return new Date().toISOString().slice(0, 10);
|
|
18
|
+
}
|
|
19
|
+
function getInclusiveDayCount(value) {
|
|
20
|
+
if (!value.startDate || !value.endDate) {
|
|
21
|
+
return 0;
|
|
22
|
+
}
|
|
23
|
+
const startTime = parseDateString(value.startDate).getTime();
|
|
24
|
+
const endTime = parseDateString(value.endDate).getTime();
|
|
25
|
+
return Math.max(0, Math.floor(Math.abs(endTime - startTime) / 86400000) + 1);
|
|
26
|
+
}
|
|
27
|
+
function getRangeLabel(value, showDayCount, dayCountUnit) {
|
|
28
|
+
if (!value.startDate || !value.endDate) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
const dateLabel = `${value.startDate} ~ ${value.endDate}`;
|
|
32
|
+
if (!showDayCount) {
|
|
33
|
+
return dateLabel;
|
|
34
|
+
}
|
|
35
|
+
return `${dateLabel} · ${getInclusiveDayCount(value)}${dayCountUnit}`;
|
|
36
|
+
}
|
|
37
|
+
function CalendarDateRangeInput({ value, onChange, placeholder = DEFAULT_PLACEHOLDER, defaultRangeDays = DEFAULT_RANGE_DAYS, disabled = false, className, showDayCount = false, dayCountUnit = 'D', themedCalendarIcon = true, clearPressFeedback = 'subtle', onOpenChange, }) {
|
|
38
|
+
var _a;
|
|
39
|
+
const [open, setOpen] = useState(false);
|
|
40
|
+
const pressMode = resolvePressFeedbackMode(clearPressFeedback);
|
|
41
|
+
const { pressedKey, flash, getPressProps } = usePressFeedback(CLEAR_PRESS_FEEDBACK_MS);
|
|
42
|
+
const label = getRangeLabel(value, showDayCount, dayCountUnit);
|
|
43
|
+
const hasValue = Boolean(value.startDate || value.endDate);
|
|
44
|
+
const isClearPressed = pressMode !== 'none' && pressedKey === 'clear' && !disabled;
|
|
45
|
+
function handleOpenChange(nextOpen) {
|
|
46
|
+
setOpen(nextOpen);
|
|
47
|
+
onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(nextOpen);
|
|
48
|
+
}
|
|
49
|
+
function handleClear() {
|
|
50
|
+
onChange({ startDate: null, endDate: null });
|
|
51
|
+
}
|
|
52
|
+
return (jsxs(Fragment, { children: [jsxs("div", { role: "button", tabIndex: disabled ? -1 : 0, "aria-disabled": disabled, onClick: () => {
|
|
53
|
+
if (!disabled) {
|
|
54
|
+
handleOpenChange(true);
|
|
55
|
+
}
|
|
56
|
+
}, onKeyDown: (event) => {
|
|
57
|
+
if (disabled) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
61
|
+
event.preventDefault();
|
|
62
|
+
handleOpenChange(true);
|
|
63
|
+
}
|
|
64
|
+
}, className: cn('flex h-11 w-full cursor-pointer items-center rounded-2xl border border-border/70 bg-background/80 text-left text-sm shadow-sm transition hover:bg-accent/40', disabled && 'cursor-not-allowed opacity-60 hover:bg-background/80', className), children: [jsxs("span", { className: "flex min-w-0 flex-1 items-center gap-2 px-3", children: [jsx(CalendarDaysIcon, { className: cn('h-4 w-4 shrink-0', themedCalendarIcon ? themeIconColor : 'text-muted-foreground') }), jsx("span", { className: cn('truncate', label ? 'text-foreground' : 'text-muted-foreground'), children: label !== null && label !== void 0 ? label : placeholder })] }), jsx("button", Object.assign({ type: "button", disabled: disabled || !hasValue, onClick: (event) => {
|
|
65
|
+
event.stopPropagation();
|
|
66
|
+
if (disabled || !hasValue) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (pressMode !== 'none') {
|
|
70
|
+
flash('clear');
|
|
71
|
+
}
|
|
72
|
+
handleClear();
|
|
73
|
+
}, className: cn('mr-1 inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-[transform,background-color,color,box-shadow]', hasValue
|
|
74
|
+
? 'hover:bg-black/10 hover:text-foreground dark:hover:bg-white/12'
|
|
75
|
+
: 'cursor-default opacity-35', isClearPressed &&
|
|
76
|
+
'scale-90 bg-black/15 text-foreground shadow-inner dark:bg-white/18'), "aria-label": "Clear date range", title: "Clear date range" }, (pressMode !== 'none' && !disabled && hasValue ? getPressProps('clear') : {}), { children: jsx(XIcon, { className: "h-4 w-4" }) }))] }), jsx(RandomDateRangeDialog, { open: open, value: value, anchorDate: (_a = value.startDate) !== null && _a !== void 0 ? _a : getTodayString(), defaultRangeDays: defaultRangeDays, onOpenChange: handleOpenChange, onApply: onChange, onClear: onChange })] }));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export { CalendarDateRangeInput };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
export type CalendarDayTone = 'saved' | 'planned' | 'warning' | 'danger' | 'neutral';
|
|
3
|
+
export type CalendarDayState<TStateKey extends string = string> = {
|
|
4
|
+
key: TStateKey;
|
|
5
|
+
title?: string;
|
|
6
|
+
tone?: CalendarDayTone;
|
|
7
|
+
};
|
|
8
|
+
export type CalendarToolbarAction = {
|
|
9
|
+
icon: ReactNode;
|
|
10
|
+
label: string;
|
|
11
|
+
title?: string;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
onPress: () => void;
|
|
14
|
+
};
|
|
15
|
+
type CalendarStatusViewProps<TStateKey extends string = string> = {
|
|
16
|
+
selectedDate: string;
|
|
17
|
+
dayStates?: Map<string, CalendarDayState<TStateKey>>;
|
|
18
|
+
action?: CalendarToolbarAction;
|
|
19
|
+
className?: string;
|
|
20
|
+
onSelectedDateChange: (date: string) => void;
|
|
21
|
+
};
|
|
22
|
+
export declare const CalendarStatusView: import("react").MemoExoticComponent<(<TStateKey extends string = string>({ selectedDate, dayStates, action, className, onSelectedDateChange, }: CalendarStatusViewProps<TStateKey>) => import("react/jsx-runtime").JSX.Element)>;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
var React = require('react');
|
|
6
|
+
var icons = require('@windrun-huaiin/base-ui/icons');
|
|
7
|
+
var utils = require('@windrun-huaiin/lib/utils');
|
|
8
|
+
var usePressFeedback = require('../buttons/use-press-feedback.js');
|
|
9
|
+
|
|
10
|
+
const WEEKDAY_LABELS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
11
|
+
const CALENDAR_TOOLBAR_BUTTON_BASE_CLASS_NAME = 'inline-flex h-9 w-8 items-center justify-center border transition-[transform,background-color,color,box-shadow,border-color] duration-150 ease-out sm:w-9';
|
|
12
|
+
const CALENDAR_TOOLBAR_BUTTON_REST_CLASS_NAME = 'border-black/10 text-slate-700 hover:bg-black/5 dark:border-white/10 dark:text-slate-200 dark:hover:bg-white/5';
|
|
13
|
+
const CALENDAR_TOOLBAR_BUTTON_PRESSED_CLASS_NAME = 'translate-y-[2px] scale-[0.9] border-black/25 bg-black/10 text-slate-950 shadow-[inset_0_2px_4px_rgba(15,23,42,0.18)] dark:border-white/25 dark:bg-white/18 dark:text-white dark:shadow-[inset_0_2px_4px_rgba(255,255,255,0.14)]';
|
|
14
|
+
function parseDateString(value) {
|
|
15
|
+
return new Date(`${value}T00:00:00.000Z`);
|
|
16
|
+
}
|
|
17
|
+
function getTodayString() {
|
|
18
|
+
return new Date().toISOString().slice(0, 10);
|
|
19
|
+
}
|
|
20
|
+
function formatDateString(date) {
|
|
21
|
+
return date.toISOString().slice(0, 10);
|
|
22
|
+
}
|
|
23
|
+
function getMonthParts(date) {
|
|
24
|
+
return {
|
|
25
|
+
year: date.toLocaleDateString('en-US', {
|
|
26
|
+
year: 'numeric',
|
|
27
|
+
timeZone: 'UTC',
|
|
28
|
+
}),
|
|
29
|
+
month: date.toLocaleDateString('en-US', {
|
|
30
|
+
month: 'long',
|
|
31
|
+
timeZone: 'UTC',
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function buildMonthDays(currentMonth) {
|
|
36
|
+
const year = currentMonth.getUTCFullYear();
|
|
37
|
+
const month = currentMonth.getUTCMonth();
|
|
38
|
+
const firstDay = new Date(Date.UTC(year, month, 1));
|
|
39
|
+
const startWeekday = firstDay.getUTCDay();
|
|
40
|
+
const gridStart = new Date(Date.UTC(year, month, 1 - startWeekday));
|
|
41
|
+
return Array.from({ length: 42 }, (_, index) => new Date(Date.UTC(gridStart.getUTCFullYear(), gridStart.getUTCMonth(), gridStart.getUTCDate() + index)));
|
|
42
|
+
}
|
|
43
|
+
function addMonthsClamped(value, months) {
|
|
44
|
+
const source = parseDateString(value);
|
|
45
|
+
const sourceYear = source.getUTCFullYear();
|
|
46
|
+
const sourceMonth = source.getUTCMonth();
|
|
47
|
+
const sourceDay = source.getUTCDate();
|
|
48
|
+
const targetMonthIndex = sourceMonth + months;
|
|
49
|
+
const targetYear = sourceYear + Math.floor(targetMonthIndex / 12);
|
|
50
|
+
const normalizedMonth = ((targetMonthIndex % 12) + 12) % 12;
|
|
51
|
+
const targetMonthLastDay = new Date(Date.UTC(targetYear, normalizedMonth + 1, 0)).getUTCDate();
|
|
52
|
+
const targetDay = Math.min(sourceDay, targetMonthLastDay);
|
|
53
|
+
return formatDateString(new Date(Date.UTC(targetYear, normalizedMonth, targetDay)));
|
|
54
|
+
}
|
|
55
|
+
function getToneClassName(tone, selected) {
|
|
56
|
+
if (selected) {
|
|
57
|
+
return 'border-black/20 dark:border-white/20';
|
|
58
|
+
}
|
|
59
|
+
switch (tone) {
|
|
60
|
+
case 'saved':
|
|
61
|
+
return 'border-emerald-300 dark:border-emerald-400';
|
|
62
|
+
case 'planned':
|
|
63
|
+
return 'border-amber-300 dark:border-amber-400';
|
|
64
|
+
case 'warning':
|
|
65
|
+
return 'border-orange-300 dark:border-orange-400';
|
|
66
|
+
case 'danger':
|
|
67
|
+
return 'border-red-300 dark:border-red-400';
|
|
68
|
+
case 'neutral':
|
|
69
|
+
return 'border-slate-300 dark:border-slate-500';
|
|
70
|
+
default:
|
|
71
|
+
return 'border-black/10 dark:border-white/10';
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function getToneDotClassName(tone) {
|
|
75
|
+
switch (tone) {
|
|
76
|
+
case 'saved':
|
|
77
|
+
return 'bg-emerald-500 dark:bg-emerald-300';
|
|
78
|
+
case 'planned':
|
|
79
|
+
return 'bg-amber-500 dark:bg-amber-300';
|
|
80
|
+
case 'warning':
|
|
81
|
+
return 'bg-orange-500 dark:bg-orange-300';
|
|
82
|
+
case 'danger':
|
|
83
|
+
return 'bg-red-500 dark:bg-red-300';
|
|
84
|
+
case 'neutral':
|
|
85
|
+
return 'bg-slate-400 dark:bg-slate-300';
|
|
86
|
+
default:
|
|
87
|
+
return '';
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const CalendarStatusView = React.memo(function CalendarStatusView({ selectedDate, dayStates, action, className, onSelectedDateChange, }) {
|
|
91
|
+
var _a;
|
|
92
|
+
const calendarMonth = React.useMemo(() => parseDateString(`${selectedDate.slice(0, 7)}-01`), [selectedDate]);
|
|
93
|
+
const monthTitle = React.useMemo(() => getMonthParts(calendarMonth), [calendarMonth]);
|
|
94
|
+
const monthDays = React.useMemo(() => buildMonthDays(calendarMonth), [calendarMonth]);
|
|
95
|
+
const today = React.useMemo(() => getTodayString(), []);
|
|
96
|
+
const { pressedKey: pressedToolbarButton, flash: flashToolbarButtonPress, getPressProps: getToolbarButtonPressProps, } = usePressFeedback.usePressFeedback();
|
|
97
|
+
function getToolbarButtonClassName(button, shapeClassName) {
|
|
98
|
+
return utils.cn(CALENDAR_TOOLBAR_BUTTON_BASE_CLASS_NAME, shapeClassName, pressedToolbarButton === button
|
|
99
|
+
? CALENDAR_TOOLBAR_BUTTON_PRESSED_CLASS_NAME
|
|
100
|
+
: CALENDAR_TOOLBAR_BUTTON_REST_CLASS_NAME, button === 'action' && (action === null || action === void 0 ? void 0 : action.disabled) ? 'pointer-events-none opacity-45' : '');
|
|
101
|
+
}
|
|
102
|
+
const handlePreviousYear = React.useCallback(() => {
|
|
103
|
+
onSelectedDateChange(addMonthsClamped(selectedDate, -12));
|
|
104
|
+
}, [onSelectedDateChange, selectedDate]);
|
|
105
|
+
const handlePreviousMonth = React.useCallback(() => {
|
|
106
|
+
onSelectedDateChange(addMonthsClamped(selectedDate, -1));
|
|
107
|
+
}, [onSelectedDateChange, selectedDate]);
|
|
108
|
+
const handleSelectToday = React.useCallback(() => {
|
|
109
|
+
onSelectedDateChange(today);
|
|
110
|
+
}, [onSelectedDateChange, today]);
|
|
111
|
+
const handleNextMonth = React.useCallback(() => {
|
|
112
|
+
onSelectedDateChange(addMonthsClamped(selectedDate, 1));
|
|
113
|
+
}, [onSelectedDateChange, selectedDate]);
|
|
114
|
+
const handleNextYear = React.useCallback(() => {
|
|
115
|
+
onSelectedDateChange(addMonthsClamped(selectedDate, 12));
|
|
116
|
+
}, [onSelectedDateChange, selectedDate]);
|
|
117
|
+
const handleDayPress = React.useCallback((nextDate) => {
|
|
118
|
+
onSelectedDateChange(nextDate);
|
|
119
|
+
}, [onSelectedDateChange]);
|
|
120
|
+
return (jsxRuntime.jsx("div", { className: utils.cn('flex h-full w-full min-w-0 max-w-full flex-col overflow-hidden rounded-3xl border border-black/10 p-3 dark:border-white/10 sm:p-4 xl:self-stretch', className), children: jsxRuntime.jsxs("div", { className: "flex h-full flex-col space-y-4", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center", children: [jsxRuntime.jsx("button", Object.assign({ type: "button", onClick: () => {
|
|
121
|
+
flashToolbarButtonPress('prevYear');
|
|
122
|
+
handlePreviousYear();
|
|
123
|
+
}, className: getToolbarButtonClassName('prevYear', 'rounded-l-full') }, getToolbarButtonPressProps('prevYear'), { "aria-label": "Previous year", title: "Previous year", children: jsxRuntime.jsx(icons.ChevronsLeftIcon, { className: "h-4 w-4" }) })), jsxRuntime.jsx("button", Object.assign({ type: "button", onClick: () => {
|
|
124
|
+
flashToolbarButtonPress('prevMonth');
|
|
125
|
+
handlePreviousMonth();
|
|
126
|
+
}, className: getToolbarButtonClassName('prevMonth', '-ml-px') }, getToolbarButtonPressProps('prevMonth'), { "aria-label": "Previous month", title: "Previous month", children: jsxRuntime.jsx(icons.ChevronLeftIcon, { className: "h-4 w-4" }) })), jsxRuntime.jsx("button", Object.assign({ type: "button", onClick: () => {
|
|
127
|
+
flashToolbarButtonPress('today');
|
|
128
|
+
handleSelectToday();
|
|
129
|
+
}, className: getToolbarButtonClassName('today', '-ml-px rounded-r-full') }, getToolbarButtonPressProps('today'), { "aria-label": "Select today", title: "Select today", children: jsxRuntime.jsx(icons.CalendarHeartIcon, { className: "h-4 w-4" }) }))] }), jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 px-2 text-center", children: [jsxRuntime.jsx("div", { className: "text-[11px] font-semibold leading-none text-slate-500 dark:text-slate-400 sm:text-xs", children: monthTitle.year }), jsxRuntime.jsx("div", { className: "mt-1 truncate text-sm font-semibold leading-none text-slate-900 dark:text-white", children: monthTitle.month })] }), jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center", children: [action ? (jsxRuntime.jsx("button", Object.assign({ type: "button", onClick: () => {
|
|
130
|
+
if (action.disabled) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
flashToolbarButtonPress('action');
|
|
134
|
+
action.onPress();
|
|
135
|
+
}, className: getToolbarButtonClassName('action', 'rounded-l-full') }, getToolbarButtonPressProps('action'), { "aria-label": action.label, title: (_a = action.title) !== null && _a !== void 0 ? _a : action.label, disabled: action.disabled, children: action.icon }))) : null, jsxRuntime.jsx("button", Object.assign({ type: "button", onClick: () => {
|
|
136
|
+
flashToolbarButtonPress('nextMonth');
|
|
137
|
+
handleNextMonth();
|
|
138
|
+
}, className: getToolbarButtonClassName('nextMonth', action ? '-ml-px' : 'rounded-l-full') }, getToolbarButtonPressProps('nextMonth'), { "aria-label": "Next month", title: "Next month", children: jsxRuntime.jsx(icons.ChevronRightIcon, { className: "h-4 w-4" }) })), jsxRuntime.jsx("button", Object.assign({ type: "button", onClick: () => {
|
|
139
|
+
flashToolbarButtonPress('nextYear');
|
|
140
|
+
handleNextYear();
|
|
141
|
+
}, className: getToolbarButtonClassName('nextYear', '-ml-px rounded-r-full') }, getToolbarButtonPressProps('nextYear'), { "aria-label": "Next year", title: "Next year", children: jsxRuntime.jsx(icons.ChevronsRightIcon, { className: "h-4 w-4" }) }))] })] }), jsxRuntime.jsx("div", { className: "grid grid-cols-7 gap-1 text-center text-[11px] font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400", children: WEEKDAY_LABELS.map((label) => (jsxRuntime.jsx("div", { className: "py-1", children: label }, label))) }), jsxRuntime.jsx("div", { className: "grid grid-cols-7 gap-1", children: monthDays.map((day) => {
|
|
142
|
+
const date = formatDateString(day);
|
|
143
|
+
const state = dayStates === null || dayStates === void 0 ? void 0 : dayStates.get(date);
|
|
144
|
+
return (jsxRuntime.jsx(CalendarDayButton, { date: date, label: String(day.getUTCDate()), currentMonth: day.getUTCMonth() === calendarMonth.getUTCMonth(), selected: date === selectedDate, dayState: state, onPress: handleDayPress }, date));
|
|
145
|
+
}) })] }) }));
|
|
146
|
+
});
|
|
147
|
+
const CalendarDayButton = React.memo(function CalendarDayButton({ date, label, currentMonth, selected, dayState, onPress, }) {
|
|
148
|
+
var _a;
|
|
149
|
+
const tone = dayState === null || dayState === void 0 ? void 0 : dayState.tone;
|
|
150
|
+
return (jsxRuntime.jsxs("button", { type: "button", onClick: () => onPress(date), className: utils.cn('relative flex h-11 select-none items-center justify-center rounded-2xl border text-sm transition', selected
|
|
151
|
+
? 'bg-black text-white dark:bg-white dark:text-slate-950'
|
|
152
|
+
: 'text-slate-700 hover:bg-black/5 dark:text-slate-200 dark:hover:bg-white/5', getToneClassName(tone, selected), currentMonth ? '' : 'opacity-45'), title: (_a = dayState === null || dayState === void 0 ? void 0 : dayState.title) !== null && _a !== void 0 ? _a : `Open ${date}`, children: [jsxRuntime.jsx("span", { children: label }), tone ? (jsxRuntime.jsx("span", { className: utils.cn('absolute bottom-1 h-1.5 w-1.5 rounded-full', getToneDotClassName(tone)) })) : null] }));
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
exports.CalendarStatusView = CalendarStatusView;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
+
import { memo, useMemo, useCallback } from 'react';
|
|
4
|
+
import { ChevronsLeftIcon, ChevronLeftIcon, CalendarHeartIcon, ChevronRightIcon, ChevronsRightIcon } from '@windrun-huaiin/base-ui/icons';
|
|
5
|
+
import { cn } from '@windrun-huaiin/lib/utils';
|
|
6
|
+
import { usePressFeedback } from '../buttons/use-press-feedback.mjs';
|
|
7
|
+
|
|
8
|
+
const WEEKDAY_LABELS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
9
|
+
const CALENDAR_TOOLBAR_BUTTON_BASE_CLASS_NAME = 'inline-flex h-9 w-8 items-center justify-center border transition-[transform,background-color,color,box-shadow,border-color] duration-150 ease-out sm:w-9';
|
|
10
|
+
const CALENDAR_TOOLBAR_BUTTON_REST_CLASS_NAME = 'border-black/10 text-slate-700 hover:bg-black/5 dark:border-white/10 dark:text-slate-200 dark:hover:bg-white/5';
|
|
11
|
+
const CALENDAR_TOOLBAR_BUTTON_PRESSED_CLASS_NAME = 'translate-y-[2px] scale-[0.9] border-black/25 bg-black/10 text-slate-950 shadow-[inset_0_2px_4px_rgba(15,23,42,0.18)] dark:border-white/25 dark:bg-white/18 dark:text-white dark:shadow-[inset_0_2px_4px_rgba(255,255,255,0.14)]';
|
|
12
|
+
function parseDateString(value) {
|
|
13
|
+
return new Date(`${value}T00:00:00.000Z`);
|
|
14
|
+
}
|
|
15
|
+
function getTodayString() {
|
|
16
|
+
return new Date().toISOString().slice(0, 10);
|
|
17
|
+
}
|
|
18
|
+
function formatDateString(date) {
|
|
19
|
+
return date.toISOString().slice(0, 10);
|
|
20
|
+
}
|
|
21
|
+
function getMonthParts(date) {
|
|
22
|
+
return {
|
|
23
|
+
year: date.toLocaleDateString('en-US', {
|
|
24
|
+
year: 'numeric',
|
|
25
|
+
timeZone: 'UTC',
|
|
26
|
+
}),
|
|
27
|
+
month: date.toLocaleDateString('en-US', {
|
|
28
|
+
month: 'long',
|
|
29
|
+
timeZone: 'UTC',
|
|
30
|
+
}),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function buildMonthDays(currentMonth) {
|
|
34
|
+
const year = currentMonth.getUTCFullYear();
|
|
35
|
+
const month = currentMonth.getUTCMonth();
|
|
36
|
+
const firstDay = new Date(Date.UTC(year, month, 1));
|
|
37
|
+
const startWeekday = firstDay.getUTCDay();
|
|
38
|
+
const gridStart = new Date(Date.UTC(year, month, 1 - startWeekday));
|
|
39
|
+
return Array.from({ length: 42 }, (_, index) => new Date(Date.UTC(gridStart.getUTCFullYear(), gridStart.getUTCMonth(), gridStart.getUTCDate() + index)));
|
|
40
|
+
}
|
|
41
|
+
function addMonthsClamped(value, months) {
|
|
42
|
+
const source = parseDateString(value);
|
|
43
|
+
const sourceYear = source.getUTCFullYear();
|
|
44
|
+
const sourceMonth = source.getUTCMonth();
|
|
45
|
+
const sourceDay = source.getUTCDate();
|
|
46
|
+
const targetMonthIndex = sourceMonth + months;
|
|
47
|
+
const targetYear = sourceYear + Math.floor(targetMonthIndex / 12);
|
|
48
|
+
const normalizedMonth = ((targetMonthIndex % 12) + 12) % 12;
|
|
49
|
+
const targetMonthLastDay = new Date(Date.UTC(targetYear, normalizedMonth + 1, 0)).getUTCDate();
|
|
50
|
+
const targetDay = Math.min(sourceDay, targetMonthLastDay);
|
|
51
|
+
return formatDateString(new Date(Date.UTC(targetYear, normalizedMonth, targetDay)));
|
|
52
|
+
}
|
|
53
|
+
function getToneClassName(tone, selected) {
|
|
54
|
+
if (selected) {
|
|
55
|
+
return 'border-black/20 dark:border-white/20';
|
|
56
|
+
}
|
|
57
|
+
switch (tone) {
|
|
58
|
+
case 'saved':
|
|
59
|
+
return 'border-emerald-300 dark:border-emerald-400';
|
|
60
|
+
case 'planned':
|
|
61
|
+
return 'border-amber-300 dark:border-amber-400';
|
|
62
|
+
case 'warning':
|
|
63
|
+
return 'border-orange-300 dark:border-orange-400';
|
|
64
|
+
case 'danger':
|
|
65
|
+
return 'border-red-300 dark:border-red-400';
|
|
66
|
+
case 'neutral':
|
|
67
|
+
return 'border-slate-300 dark:border-slate-500';
|
|
68
|
+
default:
|
|
69
|
+
return 'border-black/10 dark:border-white/10';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function getToneDotClassName(tone) {
|
|
73
|
+
switch (tone) {
|
|
74
|
+
case 'saved':
|
|
75
|
+
return 'bg-emerald-500 dark:bg-emerald-300';
|
|
76
|
+
case 'planned':
|
|
77
|
+
return 'bg-amber-500 dark:bg-amber-300';
|
|
78
|
+
case 'warning':
|
|
79
|
+
return 'bg-orange-500 dark:bg-orange-300';
|
|
80
|
+
case 'danger':
|
|
81
|
+
return 'bg-red-500 dark:bg-red-300';
|
|
82
|
+
case 'neutral':
|
|
83
|
+
return 'bg-slate-400 dark:bg-slate-300';
|
|
84
|
+
default:
|
|
85
|
+
return '';
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const CalendarStatusView = memo(function CalendarStatusView({ selectedDate, dayStates, action, className, onSelectedDateChange, }) {
|
|
89
|
+
var _a;
|
|
90
|
+
const calendarMonth = useMemo(() => parseDateString(`${selectedDate.slice(0, 7)}-01`), [selectedDate]);
|
|
91
|
+
const monthTitle = useMemo(() => getMonthParts(calendarMonth), [calendarMonth]);
|
|
92
|
+
const monthDays = useMemo(() => buildMonthDays(calendarMonth), [calendarMonth]);
|
|
93
|
+
const today = useMemo(() => getTodayString(), []);
|
|
94
|
+
const { pressedKey: pressedToolbarButton, flash: flashToolbarButtonPress, getPressProps: getToolbarButtonPressProps, } = usePressFeedback();
|
|
95
|
+
function getToolbarButtonClassName(button, shapeClassName) {
|
|
96
|
+
return cn(CALENDAR_TOOLBAR_BUTTON_BASE_CLASS_NAME, shapeClassName, pressedToolbarButton === button
|
|
97
|
+
? CALENDAR_TOOLBAR_BUTTON_PRESSED_CLASS_NAME
|
|
98
|
+
: CALENDAR_TOOLBAR_BUTTON_REST_CLASS_NAME, button === 'action' && (action === null || action === void 0 ? void 0 : action.disabled) ? 'pointer-events-none opacity-45' : '');
|
|
99
|
+
}
|
|
100
|
+
const handlePreviousYear = useCallback(() => {
|
|
101
|
+
onSelectedDateChange(addMonthsClamped(selectedDate, -12));
|
|
102
|
+
}, [onSelectedDateChange, selectedDate]);
|
|
103
|
+
const handlePreviousMonth = useCallback(() => {
|
|
104
|
+
onSelectedDateChange(addMonthsClamped(selectedDate, -1));
|
|
105
|
+
}, [onSelectedDateChange, selectedDate]);
|
|
106
|
+
const handleSelectToday = useCallback(() => {
|
|
107
|
+
onSelectedDateChange(today);
|
|
108
|
+
}, [onSelectedDateChange, today]);
|
|
109
|
+
const handleNextMonth = useCallback(() => {
|
|
110
|
+
onSelectedDateChange(addMonthsClamped(selectedDate, 1));
|
|
111
|
+
}, [onSelectedDateChange, selectedDate]);
|
|
112
|
+
const handleNextYear = useCallback(() => {
|
|
113
|
+
onSelectedDateChange(addMonthsClamped(selectedDate, 12));
|
|
114
|
+
}, [onSelectedDateChange, selectedDate]);
|
|
115
|
+
const handleDayPress = useCallback((nextDate) => {
|
|
116
|
+
onSelectedDateChange(nextDate);
|
|
117
|
+
}, [onSelectedDateChange]);
|
|
118
|
+
return (jsx("div", { className: cn('flex h-full w-full min-w-0 max-w-full flex-col overflow-hidden rounded-3xl border border-black/10 p-3 dark:border-white/10 sm:p-4 xl:self-stretch', className), children: jsxs("div", { className: "flex h-full flex-col space-y-4", children: [jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxs("div", { className: "flex shrink-0 items-center", children: [jsx("button", Object.assign({ type: "button", onClick: () => {
|
|
119
|
+
flashToolbarButtonPress('prevYear');
|
|
120
|
+
handlePreviousYear();
|
|
121
|
+
}, className: getToolbarButtonClassName('prevYear', 'rounded-l-full') }, getToolbarButtonPressProps('prevYear'), { "aria-label": "Previous year", title: "Previous year", children: jsx(ChevronsLeftIcon, { className: "h-4 w-4" }) })), jsx("button", Object.assign({ type: "button", onClick: () => {
|
|
122
|
+
flashToolbarButtonPress('prevMonth');
|
|
123
|
+
handlePreviousMonth();
|
|
124
|
+
}, className: getToolbarButtonClassName('prevMonth', '-ml-px') }, getToolbarButtonPressProps('prevMonth'), { "aria-label": "Previous month", title: "Previous month", children: jsx(ChevronLeftIcon, { className: "h-4 w-4" }) })), jsx("button", Object.assign({ type: "button", onClick: () => {
|
|
125
|
+
flashToolbarButtonPress('today');
|
|
126
|
+
handleSelectToday();
|
|
127
|
+
}, className: getToolbarButtonClassName('today', '-ml-px rounded-r-full') }, getToolbarButtonPressProps('today'), { "aria-label": "Select today", title: "Select today", children: jsx(CalendarHeartIcon, { className: "h-4 w-4" }) }))] }), jsxs("div", { className: "min-w-0 flex-1 px-2 text-center", children: [jsx("div", { className: "text-[11px] font-semibold leading-none text-slate-500 dark:text-slate-400 sm:text-xs", children: monthTitle.year }), jsx("div", { className: "mt-1 truncate text-sm font-semibold leading-none text-slate-900 dark:text-white", children: monthTitle.month })] }), jsxs("div", { className: "flex shrink-0 items-center", children: [action ? (jsx("button", Object.assign({ type: "button", onClick: () => {
|
|
128
|
+
if (action.disabled) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
flashToolbarButtonPress('action');
|
|
132
|
+
action.onPress();
|
|
133
|
+
}, className: getToolbarButtonClassName('action', 'rounded-l-full') }, getToolbarButtonPressProps('action'), { "aria-label": action.label, title: (_a = action.title) !== null && _a !== void 0 ? _a : action.label, disabled: action.disabled, children: action.icon }))) : null, jsx("button", Object.assign({ type: "button", onClick: () => {
|
|
134
|
+
flashToolbarButtonPress('nextMonth');
|
|
135
|
+
handleNextMonth();
|
|
136
|
+
}, className: getToolbarButtonClassName('nextMonth', action ? '-ml-px' : 'rounded-l-full') }, getToolbarButtonPressProps('nextMonth'), { "aria-label": "Next month", title: "Next month", children: jsx(ChevronRightIcon, { className: "h-4 w-4" }) })), jsx("button", Object.assign({ type: "button", onClick: () => {
|
|
137
|
+
flashToolbarButtonPress('nextYear');
|
|
138
|
+
handleNextYear();
|
|
139
|
+
}, className: getToolbarButtonClassName('nextYear', '-ml-px rounded-r-full') }, getToolbarButtonPressProps('nextYear'), { "aria-label": "Next year", title: "Next year", children: jsx(ChevronsRightIcon, { className: "h-4 w-4" }) }))] })] }), jsx("div", { className: "grid grid-cols-7 gap-1 text-center text-[11px] font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400", children: WEEKDAY_LABELS.map((label) => (jsx("div", { className: "py-1", children: label }, label))) }), jsx("div", { className: "grid grid-cols-7 gap-1", children: monthDays.map((day) => {
|
|
140
|
+
const date = formatDateString(day);
|
|
141
|
+
const state = dayStates === null || dayStates === void 0 ? void 0 : dayStates.get(date);
|
|
142
|
+
return (jsx(CalendarDayButton, { date: date, label: String(day.getUTCDate()), currentMonth: day.getUTCMonth() === calendarMonth.getUTCMonth(), selected: date === selectedDate, dayState: state, onPress: handleDayPress }, date));
|
|
143
|
+
}) })] }) }));
|
|
144
|
+
});
|
|
145
|
+
const CalendarDayButton = memo(function CalendarDayButton({ date, label, currentMonth, selected, dayState, onPress, }) {
|
|
146
|
+
var _a;
|
|
147
|
+
const tone = dayState === null || dayState === void 0 ? void 0 : dayState.tone;
|
|
148
|
+
return (jsxs("button", { type: "button", onClick: () => onPress(date), className: cn('relative flex h-11 select-none items-center justify-center rounded-2xl border text-sm transition', selected
|
|
149
|
+
? 'bg-black text-white dark:bg-white dark:text-slate-950'
|
|
150
|
+
: 'text-slate-700 hover:bg-black/5 dark:text-slate-200 dark:hover:bg-white/5', getToneClassName(tone, selected), currentMonth ? '' : 'opacity-45'), title: (_a = dayState === null || dayState === void 0 ? void 0 : dayState.title) !== null && _a !== void 0 ? _a : `Open ${date}`, children: [jsx("span", { children: label }), tone ? (jsx("span", { className: cn('absolute bottom-1 h-1.5 w-1.5 rounded-full', getToneDotClassName(tone)) })) : null] }));
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
export { CalendarStatusView };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var calendarStatusView = require('./calendar-status-view.js');
|
|
5
|
+
var calendarDateRangeInput = require('./calendar-date-range-input.js');
|
|
6
|
+
var randomDateRangeDialog = require('./random-date-range-dialog.js');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
exports.CalendarStatusView = calendarStatusView.CalendarStatusView;
|
|
11
|
+
exports.CalendarDateRangeInput = calendarDateRangeInput.CalendarDateRangeInput;
|
|
12
|
+
exports.RandomDateRangeDialog = randomDateRangeDialog.RandomDateRangeDialog;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { DialogLoadingAction } from '../alert-dialog/dialog-loading-action';
|
|
2
|
+
export type RandomCalendarRange = {
|
|
3
|
+
startDate: string | null;
|
|
4
|
+
endDate: string | null;
|
|
5
|
+
};
|
|
6
|
+
type RandomDateRangeDialogProps = {
|
|
7
|
+
open: boolean;
|
|
8
|
+
value: RandomCalendarRange;
|
|
9
|
+
anchorDate: string;
|
|
10
|
+
defaultRangeDays?: number;
|
|
11
|
+
onOpenChange: (open: boolean) => void;
|
|
12
|
+
loadingActions?: readonly DialogLoadingAction[];
|
|
13
|
+
loadingFullPage?: boolean;
|
|
14
|
+
onApply: (range: RandomCalendarRange) => void | Promise<void>;
|
|
15
|
+
onClear?: (range: RandomCalendarRange) => void;
|
|
16
|
+
};
|
|
17
|
+
export declare function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays, onOpenChange, loadingActions, loadingFullPage, onApply, onClear, }: RandomDateRangeDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export {};
|