@pos-360/horizon 0.30.0 → 0.30.2
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/{chunk-6LDS7PWF.js → chunk-3FXR4PA7.js} +83 -126
- package/dist/chunk-3FXR4PA7.js.map +1 -0
- package/dist/{chunk-EZDGMHS7.mjs → chunk-EZL7UCWW.mjs} +45 -3
- package/dist/chunk-EZL7UCWW.mjs.map +1 -0
- package/dist/{chunk-PQN73YBV.mjs → chunk-FUSOMGHI.mjs} +4 -46
- package/dist/chunk-FUSOMGHI.mjs.map +1 -0
- package/dist/{chunk-OWU2ABN4.mjs → chunk-HFDHLY24.mjs} +508 -429
- package/dist/chunk-HFDHLY24.mjs.map +1 -0
- package/dist/{chunk-23BJPJOK.js → chunk-NTUQQDCL.js} +45 -2
- package/dist/chunk-NTUQQDCL.js.map +1 -0
- package/dist/{chunk-MOCMPGHB.js → chunk-ZYPPWLV6.js} +620 -541
- package/dist/chunk-ZYPPWLV6.js.map +1 -0
- package/dist/enhanced.js +35 -35
- package/dist/enhanced.mjs +2 -2
- package/dist/index.js +156 -156
- package/dist/index.mjs +3 -3
- package/dist/primitives.js +120 -120
- package/dist/primitives.mjs +2 -2
- package/package.json +1 -1
- package/dist/chunk-23BJPJOK.js.map +0 -1
- package/dist/chunk-6LDS7PWF.js.map +0 -1
- package/dist/chunk-EZDGMHS7.mjs.map +0 -1
- package/dist/chunk-MOCMPGHB.js.map +0 -1
- package/dist/chunk-OWU2ABN4.mjs.map +0 -1
- package/dist/chunk-PQN73YBV.mjs.map +0 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { cn, Label, Tooltip, Text, mergeRefs } from './chunk-
|
|
1
|
+
import { cn, Label, Tooltip, Text, TextButton, mergeRefs } from './chunk-EZL7UCWW.mjs';
|
|
2
2
|
import * as React10 from 'react';
|
|
3
3
|
import { useState, useEffect, useCallback } from 'react';
|
|
4
4
|
import { Slot } from '@radix-ui/react-slot';
|
|
5
5
|
import { cva } from 'class-variance-authority';
|
|
6
6
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
7
|
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
|
|
8
|
-
import { Check, X, ChevronRight, Circle, ChevronDown, ChevronUp, Search, Minus, PenLine, SlidersHorizontal, CalendarIcon,
|
|
8
|
+
import { Check, X, ChevronRight, Circle, ChevronDown, ChevronUp, Search, Minus, PenLine, SlidersHorizontal, CalendarIcon, Clock, ChevronLeft } from 'lucide-react';
|
|
9
9
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
10
10
|
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
11
11
|
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
@@ -15,7 +15,7 @@ import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
|
|
|
15
15
|
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
|
16
16
|
import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group';
|
|
17
17
|
import * as SwitchPrimitive from '@radix-ui/react-switch';
|
|
18
|
-
import { endOfDay, startOfDay,
|
|
18
|
+
import { endOfDay, startOfDay, min, startOfWeek, startOfMonth, subDays, endOfWeek, endOfMonth, subMonths, addMonths, subYears, isBefore, isSameDay, format, isSameMonth, isAfter, eachDayOfInterval, isWithinInterval } from 'date-fns';
|
|
19
19
|
|
|
20
20
|
var buttonVariants = cva(
|
|
21
21
|
"group inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-hz-md text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
@@ -2099,15 +2099,16 @@ function to24Hour(hour12, period) {
|
|
|
2099
2099
|
function pad(n) {
|
|
2100
2100
|
return n.toString().padStart(2, "0");
|
|
2101
2101
|
}
|
|
2102
|
-
function clamp(val,
|
|
2103
|
-
return Math.max(
|
|
2102
|
+
function clamp(val, min2, max) {
|
|
2103
|
+
return Math.max(min2, Math.min(max, val));
|
|
2104
2104
|
}
|
|
2105
2105
|
function TimeInput({
|
|
2106
2106
|
value,
|
|
2107
|
-
min,
|
|
2107
|
+
min: min2,
|
|
2108
2108
|
max,
|
|
2109
2109
|
onChange,
|
|
2110
2110
|
onComplete,
|
|
2111
|
+
onDirty,
|
|
2111
2112
|
inputRef,
|
|
2112
2113
|
disabled = false,
|
|
2113
2114
|
"aria-label": ariaLabel
|
|
@@ -2115,39 +2116,59 @@ function TimeInput({
|
|
|
2115
2116
|
const [editValue, setEditValue] = React10.useState(null);
|
|
2116
2117
|
const internalRef = React10.useRef(null);
|
|
2117
2118
|
const committedRef = React10.useRef(false);
|
|
2119
|
+
const pendingDigitRef = React10.useRef(null);
|
|
2118
2120
|
const setRefs = React10.useCallback(mergeRefs(internalRef, inputRef), [inputRef]);
|
|
2119
|
-
const
|
|
2120
|
-
const raw = e.target.value.replace(/\D/g, "").slice(0, 2);
|
|
2121
|
-
if (raw === "") {
|
|
2122
|
-
setEditValue(raw);
|
|
2123
|
-
return;
|
|
2124
|
-
}
|
|
2125
|
-
if (raw.length === 1) {
|
|
2126
|
-
setEditValue(raw);
|
|
2127
|
-
return;
|
|
2128
|
-
}
|
|
2121
|
+
const commitTwoDigits = (raw) => {
|
|
2129
2122
|
const parsed = parseInt(raw, 10);
|
|
2130
|
-
const clamped = clamp(parsed,
|
|
2123
|
+
const clamped = clamp(parsed, min2, max);
|
|
2124
|
+
pendingDigitRef.current = null;
|
|
2131
2125
|
committedRef.current = true;
|
|
2132
2126
|
onChange(clamped);
|
|
2133
2127
|
setEditValue(null);
|
|
2134
2128
|
onComplete?.();
|
|
2135
2129
|
};
|
|
2130
|
+
const handleChange = (e) => {
|
|
2131
|
+
const allDigits = e.target.value.replace(/\D/g, "");
|
|
2132
|
+
if (allDigits === "") {
|
|
2133
|
+
setEditValue("");
|
|
2134
|
+
pendingDigitRef.current = null;
|
|
2135
|
+
return;
|
|
2136
|
+
}
|
|
2137
|
+
if (pendingDigitRef.current !== null) {
|
|
2138
|
+
if (allDigits.length > 2) {
|
|
2139
|
+
commitTwoDigits(pendingDigitRef.current + allDigits[allDigits.length - 1]);
|
|
2140
|
+
return;
|
|
2141
|
+
}
|
|
2142
|
+
pendingDigitRef.current = null;
|
|
2143
|
+
setEditValue("");
|
|
2144
|
+
return;
|
|
2145
|
+
}
|
|
2146
|
+
if (allDigits.length === 1) {
|
|
2147
|
+
pendingDigitRef.current = allDigits;
|
|
2148
|
+
setEditValue("0" + allDigits);
|
|
2149
|
+
onDirty?.();
|
|
2150
|
+
return;
|
|
2151
|
+
}
|
|
2152
|
+
commitTwoDigits(allDigits.slice(0, 2));
|
|
2153
|
+
};
|
|
2136
2154
|
const commit = () => {
|
|
2137
2155
|
if (committedRef.current) {
|
|
2138
2156
|
committedRef.current = false;
|
|
2157
|
+
pendingDigitRef.current = null;
|
|
2139
2158
|
setEditValue(null);
|
|
2140
2159
|
return;
|
|
2141
2160
|
}
|
|
2142
2161
|
if (editValue === null) return;
|
|
2143
2162
|
if (editValue === "") {
|
|
2163
|
+
pendingDigitRef.current = null;
|
|
2144
2164
|
setEditValue(null);
|
|
2145
2165
|
return;
|
|
2146
2166
|
}
|
|
2147
2167
|
const parsed = parseInt(editValue, 10);
|
|
2148
2168
|
if (!isNaN(parsed)) {
|
|
2149
|
-
onChange(clamp(parsed,
|
|
2169
|
+
onChange(clamp(parsed, min2, max));
|
|
2150
2170
|
}
|
|
2171
|
+
pendingDigitRef.current = null;
|
|
2151
2172
|
setEditValue(null);
|
|
2152
2173
|
};
|
|
2153
2174
|
const handleKeyDown = (e) => {
|
|
@@ -2155,18 +2176,21 @@ function TimeInput({
|
|
|
2155
2176
|
commit();
|
|
2156
2177
|
internalRef.current?.blur();
|
|
2157
2178
|
} else if (e.key === "Escape") {
|
|
2179
|
+
pendingDigitRef.current = null;
|
|
2158
2180
|
setEditValue(null);
|
|
2159
2181
|
internalRef.current?.blur();
|
|
2160
2182
|
} else if (e.key === "ArrowUp") {
|
|
2161
2183
|
e.preventDefault();
|
|
2162
|
-
|
|
2163
|
-
const
|
|
2184
|
+
pendingDigitRef.current = null;
|
|
2185
|
+
const curr = value ?? min2;
|
|
2186
|
+
const next = curr >= max ? min2 : curr + 1;
|
|
2164
2187
|
onChange(next);
|
|
2165
2188
|
setEditValue(pad(next));
|
|
2166
2189
|
} else if (e.key === "ArrowDown") {
|
|
2167
2190
|
e.preventDefault();
|
|
2191
|
+
pendingDigitRef.current = null;
|
|
2168
2192
|
const curr = value ?? max;
|
|
2169
|
-
const next = curr <=
|
|
2193
|
+
const next = curr <= min2 ? max : curr - 1;
|
|
2170
2194
|
onChange(next);
|
|
2171
2195
|
setEditValue(pad(next));
|
|
2172
2196
|
}
|
|
@@ -2182,6 +2206,7 @@ function TimeInput({
|
|
|
2182
2206
|
value: editValue ?? (value === null ? "--" : pad(value)),
|
|
2183
2207
|
onChange: handleChange,
|
|
2184
2208
|
onFocus: (e) => {
|
|
2209
|
+
pendingDigitRef.current = null;
|
|
2185
2210
|
setEditValue("");
|
|
2186
2211
|
requestAnimationFrame(() => e.target.select());
|
|
2187
2212
|
},
|
|
@@ -2232,6 +2257,7 @@ function TimeField({
|
|
|
2232
2257
|
hourRef,
|
|
2233
2258
|
minuteRef,
|
|
2234
2259
|
onMinuteComplete,
|
|
2260
|
+
onDirty,
|
|
2235
2261
|
disabled = false
|
|
2236
2262
|
}) {
|
|
2237
2263
|
const { hour12, period } = to12Hour(value.hour);
|
|
@@ -2270,6 +2296,7 @@ function TimeField({
|
|
|
2270
2296
|
max: 12,
|
|
2271
2297
|
onChange: handleHourChange,
|
|
2272
2298
|
onComplete: focusMinute,
|
|
2299
|
+
onDirty,
|
|
2273
2300
|
inputRef: hourRef,
|
|
2274
2301
|
disabled,
|
|
2275
2302
|
"aria-label": `${label} hour`
|
|
@@ -2293,6 +2320,7 @@ function TimeField({
|
|
|
2293
2320
|
max: 59,
|
|
2294
2321
|
onChange: handleMinuteChange,
|
|
2295
2322
|
onComplete: onMinuteComplete,
|
|
2323
|
+
onDirty,
|
|
2296
2324
|
inputRef: mergedMinuteRef,
|
|
2297
2325
|
disabled,
|
|
2298
2326
|
"aria-label": `${label} minute`
|
|
@@ -2309,11 +2337,14 @@ function TimeField({
|
|
|
2309
2337
|
] })
|
|
2310
2338
|
] });
|
|
2311
2339
|
}
|
|
2312
|
-
function
|
|
2313
|
-
const toHourRef = React10.useRef(null);
|
|
2340
|
+
function useTimeFieldState(value) {
|
|
2314
2341
|
const fromSet = isTimeSet(value.from);
|
|
2315
2342
|
const toSet = isTimeSet(value.to);
|
|
2316
2343
|
const bothSet = fromSet && toSet;
|
|
2344
|
+
const orphanMinutes = value.from.hour === null && value.from.minute !== null || value.to.hour === null && value.to.minute !== null;
|
|
2345
|
+
const fromPartial = !fromSet && (value.from.hour !== null || value.from.minute !== null);
|
|
2346
|
+
const toPartial = !toSet && (value.to.hour !== null || value.to.minute !== null);
|
|
2347
|
+
const oneSideMissing = fromSet && !toSet && !toPartial || toSet && !fromSet && !fromPartial;
|
|
2317
2348
|
const fromMinutes = (value.from.hour ?? 0) * 60 + (value.from.minute ?? 0);
|
|
2318
2349
|
const toMinutes = (value.to.hour ?? 0) * 60 + (value.to.minute ?? 0);
|
|
2319
2350
|
const bothEqual = fromMinutes === toMinutes;
|
|
@@ -2323,140 +2354,142 @@ function TimePickerColumn({ value, onChange, disabled = false }) {
|
|
|
2323
2354
|
const durationRemaining = durationMinutes % 60;
|
|
2324
2355
|
const showDuration = bothSet && !bothEqual;
|
|
2325
2356
|
const durationLabel = durationRemaining > 0 ? `${durationHours}h ${durationRemaining}m window${isOvernight ? " (overnight)" : ""}` : `${durationHours}h window${isOvernight ? " (overnight)" : ""}`;
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2357
|
+
const incompleteHint = orphanMinutes ? "Please set hours for the time to take effect" : fromPartial || toPartial ? "Please complete both hour and minute fields" : oneSideMissing ? `Please set the ${fromSet ? "to" : "from"} time` : null;
|
|
2358
|
+
return { showDuration, durationLabel, isOvernight, incompleteHint };
|
|
2359
|
+
}
|
|
2360
|
+
function TimePickerColumn({ value, onChange, disabled = false, onRemove, showRemove = false, onDirty }) {
|
|
2361
|
+
const toHourRef = React10.useRef(null);
|
|
2362
|
+
const { showDuration, durationLabel, isOvernight, incompleteHint } = useTimeFieldState(value);
|
|
2363
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col px-2 pt-2 pb-2 gap-1", children: [
|
|
2364
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2365
|
+
/* @__PURE__ */ jsx(
|
|
2366
|
+
Clock,
|
|
2367
|
+
{
|
|
2368
|
+
className: cn(
|
|
2369
|
+
"w-4 h-4 shrink-0",
|
|
2370
|
+
disabled ? "text-gray-300 dark:text-gray-600" : "text-gray-400 dark:text-gray-500"
|
|
2371
|
+
)
|
|
2372
|
+
}
|
|
2332
2373
|
),
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
"w-4 h-4 shrink-0",
|
|
2340
|
-
disabled ? "text-gray-300 dark:text-gray-600" : "text-gray-400 dark:text-gray-500"
|
|
2341
|
-
)
|
|
2342
|
-
}
|
|
2343
|
-
),
|
|
2344
|
-
/* @__PURE__ */ jsx(
|
|
2345
|
-
"span",
|
|
2346
|
-
{
|
|
2347
|
-
className: cn(
|
|
2348
|
-
"text-xs font-semibold uppercase tracking-wider",
|
|
2349
|
-
disabled ? "text-gray-300 dark:text-gray-600" : "text-gray-400 dark:text-gray-500"
|
|
2350
|
-
),
|
|
2351
|
-
children: "Time"
|
|
2352
|
-
}
|
|
2353
|
-
),
|
|
2354
|
-
/* @__PURE__ */ jsx("span", { className: "text-[9px] font-medium text-gray-400 dark:text-gray-600 tracking-wide", children: "(Optional)" })
|
|
2355
|
-
] }),
|
|
2356
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 pl-6", children: [
|
|
2357
|
-
/* @__PURE__ */ jsx(
|
|
2358
|
-
TimeField,
|
|
2359
|
-
{
|
|
2360
|
-
label: "From",
|
|
2361
|
-
value: value.from,
|
|
2362
|
-
onChange: (from) => onChange({ ...value, from }),
|
|
2363
|
-
onMinuteComplete: () => toHourRef.current?.focus(),
|
|
2364
|
-
disabled
|
|
2365
|
-
}
|
|
2366
|
-
),
|
|
2367
|
-
/* @__PURE__ */ jsx(
|
|
2368
|
-
TimeField,
|
|
2369
|
-
{
|
|
2370
|
-
label: "To",
|
|
2371
|
-
value: value.to,
|
|
2372
|
-
onChange: (to) => onChange({ ...value, to }),
|
|
2373
|
-
hourRef: toHourRef,
|
|
2374
|
-
disabled
|
|
2375
|
-
}
|
|
2374
|
+
/* @__PURE__ */ jsx(
|
|
2375
|
+
"span",
|
|
2376
|
+
{
|
|
2377
|
+
className: cn(
|
|
2378
|
+
"text-xs font-semibold uppercase tracking-wider",
|
|
2379
|
+
disabled ? "text-gray-300 dark:text-gray-600" : "text-gray-400 dark:text-gray-500"
|
|
2376
2380
|
),
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2381
|
+
children: "Time"
|
|
2382
|
+
}
|
|
2383
|
+
),
|
|
2384
|
+
/* @__PURE__ */ jsx("span", { className: "text-[9px] font-medium text-gray-400 dark:text-gray-600 tracking-wide", children: "(Optional)" }),
|
|
2385
|
+
showRemove && onRemove && /* @__PURE__ */ jsx("div", { className: "ml-auto", children: /* @__PURE__ */ jsx(
|
|
2386
|
+
TextButton,
|
|
2387
|
+
{
|
|
2388
|
+
variant: "danger",
|
|
2389
|
+
onClick: onRemove,
|
|
2390
|
+
size: "sm",
|
|
2391
|
+
className: "!text-[0.625rem]",
|
|
2392
|
+
children: "Remove"
|
|
2393
|
+
}
|
|
2394
|
+
) })
|
|
2395
|
+
] }),
|
|
2396
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 pl-6", children: [
|
|
2397
|
+
/* @__PURE__ */ jsx(
|
|
2398
|
+
TimeField,
|
|
2399
|
+
{
|
|
2400
|
+
label: "From",
|
|
2401
|
+
value: value.from,
|
|
2402
|
+
onChange: (from) => onChange({ ...value, from }),
|
|
2403
|
+
onMinuteComplete: () => toHourRef.current?.focus(),
|
|
2404
|
+
onDirty,
|
|
2405
|
+
disabled
|
|
2406
|
+
}
|
|
2407
|
+
),
|
|
2408
|
+
/* @__PURE__ */ jsx(
|
|
2409
|
+
TimeField,
|
|
2410
|
+
{
|
|
2411
|
+
label: "To",
|
|
2412
|
+
value: value.to,
|
|
2413
|
+
onChange: (to) => onChange({ ...value, to }),
|
|
2414
|
+
hourRef: toHourRef,
|
|
2415
|
+
onDirty,
|
|
2416
|
+
disabled
|
|
2417
|
+
}
|
|
2418
|
+
),
|
|
2419
|
+
showDuration && /* @__PURE__ */ jsx("span", { className: cn(
|
|
2420
|
+
"text-[10px] font-medium",
|
|
2421
|
+
isOvernight ? "text-amber-500 dark:text-amber-400" : "text-gray-400 dark:text-gray-500"
|
|
2422
|
+
), children: durationLabel }),
|
|
2423
|
+
incompleteHint && /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium text-amber-500 dark:text-amber-400", children: incompleteHint })
|
|
2424
|
+
] })
|
|
2425
|
+
] });
|
|
2385
2426
|
}
|
|
2386
|
-
function TimePickerRow({ value, onChange, disabled = false }) {
|
|
2427
|
+
function TimePickerRow({ value, onChange, disabled = false, onRemove, showRemove = false, onDirty }) {
|
|
2387
2428
|
const toHourRef = React10.useRef(null);
|
|
2388
|
-
const
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
const durationLabel = durationRemaining > 0 ? `${durationHours}h ${durationRemaining}m window${isOvernight ? " (overnight)" : ""}` : `${durationHours}h window${isOvernight ? " (overnight)" : ""}`;
|
|
2400
|
-
return /* @__PURE__ */ jsx(
|
|
2401
|
-
"div",
|
|
2402
|
-
{
|
|
2403
|
-
className: cn(
|
|
2404
|
-
"flex flex-col px-4 pt-2 pb-3 gap-1",
|
|
2405
|
-
"border-t border-gray-100 dark:border-neutral-700"
|
|
2429
|
+
const { showDuration, durationLabel, isOvernight, incompleteHint } = useTimeFieldState(value);
|
|
2430
|
+
return /* @__PURE__ */ jsx("div", { className: "flex flex-col px-4 pt-2 pb-3 gap-1", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
|
|
2431
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-1", children: [
|
|
2432
|
+
/* @__PURE__ */ jsx(
|
|
2433
|
+
Clock,
|
|
2434
|
+
{
|
|
2435
|
+
className: cn(
|
|
2436
|
+
"w-4 h-4 shrink-0",
|
|
2437
|
+
disabled ? "text-gray-300 dark:text-gray-600" : "text-gray-400 dark:text-gray-500"
|
|
2438
|
+
)
|
|
2439
|
+
}
|
|
2406
2440
|
),
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
}
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
onMinuteComplete: () => toHourRef.current?.focus(),
|
|
2429
|
-
disabled
|
|
2430
|
-
}
|
|
2431
|
-
),
|
|
2432
|
-
/* @__PURE__ */ jsx(
|
|
2433
|
-
"div",
|
|
2434
|
-
{
|
|
2435
|
-
className: cn(
|
|
2436
|
-
"w-4 h-px",
|
|
2437
|
-
disabled ? "bg-gray-200 dark:bg-neutral-700" : "bg-gray-300 dark:bg-neutral-600"
|
|
2438
|
-
)
|
|
2439
|
-
}
|
|
2440
|
-
),
|
|
2441
|
-
/* @__PURE__ */ jsx(
|
|
2442
|
-
TimeField,
|
|
2443
|
-
{
|
|
2444
|
-
label: "To",
|
|
2445
|
-
value: value.to,
|
|
2446
|
-
onChange: (to) => onChange({ ...value, to }),
|
|
2447
|
-
hourRef: toHourRef,
|
|
2448
|
-
disabled
|
|
2449
|
-
}
|
|
2441
|
+
/* @__PURE__ */ jsx("span", { className: "text-[9px] font-medium text-gray-300 dark:text-gray-600 tracking-wide", children: "OPT" })
|
|
2442
|
+
] }),
|
|
2443
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 flex-1", children: [
|
|
2444
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
2445
|
+
/* @__PURE__ */ jsx(
|
|
2446
|
+
TimeField,
|
|
2447
|
+
{
|
|
2448
|
+
label: "From",
|
|
2449
|
+
value: value.from,
|
|
2450
|
+
onChange: (from) => onChange({ ...value, from }),
|
|
2451
|
+
onMinuteComplete: () => toHourRef.current?.focus(),
|
|
2452
|
+
onDirty,
|
|
2453
|
+
disabled
|
|
2454
|
+
}
|
|
2455
|
+
),
|
|
2456
|
+
/* @__PURE__ */ jsx(
|
|
2457
|
+
"div",
|
|
2458
|
+
{
|
|
2459
|
+
className: cn(
|
|
2460
|
+
"w-4 h-px",
|
|
2461
|
+
disabled ? "bg-gray-200 dark:bg-neutral-700" : "bg-gray-300 dark:bg-neutral-600"
|
|
2450
2462
|
)
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2463
|
+
}
|
|
2464
|
+
),
|
|
2465
|
+
/* @__PURE__ */ jsx(
|
|
2466
|
+
TimeField,
|
|
2467
|
+
{
|
|
2468
|
+
label: "To",
|
|
2469
|
+
value: value.to,
|
|
2470
|
+
onChange: (to) => onChange({ ...value, to }),
|
|
2471
|
+
hourRef: toHourRef,
|
|
2472
|
+
onDirty,
|
|
2473
|
+
disabled
|
|
2474
|
+
}
|
|
2475
|
+
),
|
|
2476
|
+
showRemove && onRemove && /* @__PURE__ */ jsx(
|
|
2477
|
+
Button,
|
|
2478
|
+
{
|
|
2479
|
+
variant: "outline",
|
|
2480
|
+
onClick: onRemove,
|
|
2481
|
+
className: "text-[0.625rem] border border-red-100 dark:border-red-700 rounded-md px-2 py-1 h-8 text-red-500 hover:text-red-600 dark:text-red-400 dark:hover:text-red-300 transition-colors",
|
|
2482
|
+
children: "Remove"
|
|
2483
|
+
}
|
|
2484
|
+
)
|
|
2485
|
+
] }),
|
|
2486
|
+
showDuration && /* @__PURE__ */ jsx("span", { className: cn(
|
|
2487
|
+
"text-[10px] font-medium pl-0.5",
|
|
2488
|
+
isOvernight ? "text-amber-500 dark:text-amber-400" : "text-gray-400 dark:text-gray-500"
|
|
2489
|
+
), children: durationLabel }),
|
|
2490
|
+
incompleteHint && /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium pl-0.5 text-amber-500 dark:text-amber-400", children: incompleteHint })
|
|
2491
|
+
] })
|
|
2492
|
+
] }) });
|
|
2460
2493
|
}
|
|
2461
2494
|
var WEEKDAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
2462
2495
|
function getCalendarDays(month) {
|
|
@@ -2539,9 +2572,14 @@ function CalendarMonth({
|
|
|
2539
2572
|
onMouseLeave: () => onDayHover(void 0),
|
|
2540
2573
|
children: days.map((day, idx) => {
|
|
2541
2574
|
const outside = !isSameMonth(day, month);
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2575
|
+
if (outside) {
|
|
2576
|
+
return /* @__PURE__ */ jsx("div", { className: "h-9" }, idx);
|
|
2577
|
+
}
|
|
2578
|
+
const isFuture = isAfter(startOfDay(day), startOfDay(today));
|
|
2579
|
+
const disabled = isFuture;
|
|
2580
|
+
const inRange = !disabled && isInRange(day);
|
|
2581
|
+
const rangeStart = !disabled && isRangeStart(day);
|
|
2582
|
+
const rangeEnd = !disabled && isRangeEnd(day);
|
|
2545
2583
|
const isToday = isSameDay(day, today);
|
|
2546
2584
|
return /* @__PURE__ */ jsx(
|
|
2547
2585
|
"div",
|
|
@@ -2556,16 +2594,17 @@ function CalendarMonth({
|
|
|
2556
2594
|
children: /* @__PURE__ */ jsx(
|
|
2557
2595
|
"button",
|
|
2558
2596
|
{
|
|
2559
|
-
onClick: () => !
|
|
2560
|
-
onMouseEnter: () => !
|
|
2561
|
-
tabIndex:
|
|
2597
|
+
onClick: () => !disabled && onDayClick(day),
|
|
2598
|
+
onMouseEnter: () => !disabled && onDayHover(day),
|
|
2599
|
+
tabIndex: disabled ? -1 : 0,
|
|
2600
|
+
disabled,
|
|
2562
2601
|
className: cn(
|
|
2563
2602
|
"w-8 h-8 rounded-full text-sm flex items-center justify-center transition-colors",
|
|
2564
|
-
|
|
2565
|
-
!
|
|
2566
|
-
!
|
|
2603
|
+
isFuture && "text-gray-300 dark:text-gray-600 pointer-events-none cursor-not-allowed",
|
|
2604
|
+
!disabled && !rangeStart && !rangeEnd && "text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-neutral-700",
|
|
2605
|
+
!disabled && inRange && !rangeStart && !rangeEnd && "text-blue-700 dark:text-blue-300 hover:bg-blue-100 dark:hover:bg-blue-900/50",
|
|
2567
2606
|
(rangeStart || rangeEnd) && "bg-blue-600 text-white hover:bg-blue-700 dark:hover:bg-blue-500",
|
|
2568
|
-
isToday && !rangeStart && !rangeEnd && !
|
|
2607
|
+
isToday && !rangeStart && !rangeEnd && !disabled && "font-bold"
|
|
2569
2608
|
),
|
|
2570
2609
|
children: format(day, "d")
|
|
2571
2610
|
}
|
|
@@ -2578,6 +2617,167 @@ function CalendarMonth({
|
|
|
2578
2617
|
)
|
|
2579
2618
|
] });
|
|
2580
2619
|
}
|
|
2620
|
+
function useDateRangePicker({
|
|
2621
|
+
value,
|
|
2622
|
+
onChange,
|
|
2623
|
+
showTimePicker = false,
|
|
2624
|
+
timeValue,
|
|
2625
|
+
onTimeChange
|
|
2626
|
+
}) {
|
|
2627
|
+
const [open, setOpen] = React10.useState(false);
|
|
2628
|
+
const [internalRange, setInternalRange] = React10.useState({
|
|
2629
|
+
from: void 0,
|
|
2630
|
+
to: void 0
|
|
2631
|
+
});
|
|
2632
|
+
const [draft, setDraft] = React10.useState({
|
|
2633
|
+
from: void 0,
|
|
2634
|
+
to: void 0
|
|
2635
|
+
});
|
|
2636
|
+
const [hoverDate, setHoverDate] = React10.useState();
|
|
2637
|
+
const [viewMonth, setViewMonth] = React10.useState(
|
|
2638
|
+
() => startOfMonth(value?.from ?? /* @__PURE__ */ new Date())
|
|
2639
|
+
);
|
|
2640
|
+
const [activePreset, setActivePreset] = React10.useState();
|
|
2641
|
+
const [committedInternalTime, setCommittedInternalTime] = React10.useState(DEFAULT_TIME_RANGE);
|
|
2642
|
+
const [draftTime, setDraftTime] = React10.useState(DEFAULT_TIME_RANGE);
|
|
2643
|
+
const [timeExpanded, setTimeExpanded] = React10.useState(false);
|
|
2644
|
+
const [timeDirty, setTimeDirty] = React10.useState(false);
|
|
2645
|
+
const committedRange = value ?? internalRange;
|
|
2646
|
+
const committedTime = timeValue ?? committedInternalTime;
|
|
2647
|
+
const timeVisible = !!(draft.from && draft.to);
|
|
2648
|
+
const hasAnyTimeInput = timeDirty || draftTime.from.hour !== null || draftTime.from.minute !== null || draftTime.to.hour !== null || draftTime.to.minute !== null;
|
|
2649
|
+
const isTimeComplete2 = draftTime.from.hour !== null && draftTime.from.minute !== null && draftTime.to.hour !== null && draftTime.to.minute !== null;
|
|
2650
|
+
const hasPartialTime = showTimePicker && timeExpanded && !isTimeComplete2;
|
|
2651
|
+
const canClear = !!(draft.from || committedRange.from);
|
|
2652
|
+
const canApply = !(draft.from && !draft.to) && !!(draft.from || committedRange.from) && !hasPartialTime;
|
|
2653
|
+
const resetTime = React10.useCallback(() => {
|
|
2654
|
+
setDraftTime(DEFAULT_TIME_RANGE);
|
|
2655
|
+
setTimeExpanded(false);
|
|
2656
|
+
setTimeDirty(false);
|
|
2657
|
+
}, []);
|
|
2658
|
+
const handleTimeChange = React10.useCallback((newTime) => {
|
|
2659
|
+
setDraftTime(newTime);
|
|
2660
|
+
}, []);
|
|
2661
|
+
const handleOpenChange = React10.useCallback(
|
|
2662
|
+
(newOpen) => {
|
|
2663
|
+
if (newOpen) {
|
|
2664
|
+
setDraft(committedRange);
|
|
2665
|
+
if (committedRange.from)
|
|
2666
|
+
setViewMonth(startOfMonth(committedRange.from));
|
|
2667
|
+
setDraftTime(committedTime);
|
|
2668
|
+
const hasExistingTime = committedTime.from.hour !== null || committedTime.from.minute !== null || committedTime.to.hour !== null || committedTime.to.minute !== null;
|
|
2669
|
+
setTimeExpanded(hasExistingTime);
|
|
2670
|
+
setTimeDirty(false);
|
|
2671
|
+
}
|
|
2672
|
+
setOpen(newOpen);
|
|
2673
|
+
},
|
|
2674
|
+
[committedRange, committedTime]
|
|
2675
|
+
);
|
|
2676
|
+
const handleDayClick = React10.useCallback(
|
|
2677
|
+
(date) => {
|
|
2678
|
+
const { from, to } = draft;
|
|
2679
|
+
if (!from || from && to) {
|
|
2680
|
+
setDraft({ from: date, to: void 0 });
|
|
2681
|
+
setActivePreset(void 0);
|
|
2682
|
+
if (showTimePicker && timeExpanded) {
|
|
2683
|
+
resetTime();
|
|
2684
|
+
}
|
|
2685
|
+
return;
|
|
2686
|
+
}
|
|
2687
|
+
const [start, end] = isBefore(from, date) ? [from, date] : [date, from];
|
|
2688
|
+
setDraft({ from: start, to: end });
|
|
2689
|
+
setHoverDate(void 0);
|
|
2690
|
+
},
|
|
2691
|
+
[draft, showTimePicker, timeExpanded, resetTime]
|
|
2692
|
+
);
|
|
2693
|
+
const handlePreset = React10.useCallback(
|
|
2694
|
+
(preset) => {
|
|
2695
|
+
const newRange = preset.getRange();
|
|
2696
|
+
setDraft(newRange);
|
|
2697
|
+
setActivePreset(preset.label);
|
|
2698
|
+
if (newRange.from) setViewMonth(startOfMonth(newRange.from));
|
|
2699
|
+
if (showTimePicker) resetTime();
|
|
2700
|
+
},
|
|
2701
|
+
[showTimePicker, resetTime]
|
|
2702
|
+
);
|
|
2703
|
+
const handleApply = React10.useCallback(() => {
|
|
2704
|
+
if (draft.from && !draft.to) return;
|
|
2705
|
+
const newRange = draft.from && draft.to ? draft : void 0;
|
|
2706
|
+
const rangeChanged = newRange?.from?.getTime() !== committedRange.from?.getTime() || newRange?.to?.getTime() !== committedRange.to?.getTime();
|
|
2707
|
+
const timeChanged = draftTime.from.hour !== committedTime.from.hour || draftTime.from.minute !== committedTime.from.minute || draftTime.to.hour !== committedTime.to.hour || draftTime.to.minute !== committedTime.to.minute;
|
|
2708
|
+
if (rangeChanged) {
|
|
2709
|
+
if (onChange) onChange(newRange);
|
|
2710
|
+
else setInternalRange(newRange ?? { from: void 0, to: void 0 });
|
|
2711
|
+
}
|
|
2712
|
+
if (timeChanged) {
|
|
2713
|
+
if (onTimeChange) onTimeChange(draftTime);
|
|
2714
|
+
else setCommittedInternalTime(draftTime);
|
|
2715
|
+
}
|
|
2716
|
+
setOpen(false);
|
|
2717
|
+
}, [draft, onChange, committedRange, draftTime, committedTime, onTimeChange]);
|
|
2718
|
+
const handleClear = React10.useCallback(() => {
|
|
2719
|
+
setDraft({ from: void 0, to: void 0 });
|
|
2720
|
+
setActivePreset(void 0);
|
|
2721
|
+
if (showTimePicker) resetTime();
|
|
2722
|
+
}, [showTimePicker, resetTime]);
|
|
2723
|
+
const expandTime = React10.useCallback(() => {
|
|
2724
|
+
setTimeExpanded(true);
|
|
2725
|
+
}, []);
|
|
2726
|
+
const markTimeDirty = React10.useCallback(() => {
|
|
2727
|
+
setTimeDirty(true);
|
|
2728
|
+
}, []);
|
|
2729
|
+
return {
|
|
2730
|
+
open,
|
|
2731
|
+
draft,
|
|
2732
|
+
hoverDate,
|
|
2733
|
+
viewMonth,
|
|
2734
|
+
activePreset,
|
|
2735
|
+
committedRange,
|
|
2736
|
+
committedTime,
|
|
2737
|
+
draftTime,
|
|
2738
|
+
timeExpanded,
|
|
2739
|
+
timeVisible,
|
|
2740
|
+
hasAnyTimeInput,
|
|
2741
|
+
canClear,
|
|
2742
|
+
canApply,
|
|
2743
|
+
showTimePicker,
|
|
2744
|
+
setHoverDate,
|
|
2745
|
+
setViewMonth,
|
|
2746
|
+
handleTimeChange,
|
|
2747
|
+
handleOpenChange,
|
|
2748
|
+
handleDayClick,
|
|
2749
|
+
handlePreset,
|
|
2750
|
+
handleApply,
|
|
2751
|
+
handleClear,
|
|
2752
|
+
resetTime,
|
|
2753
|
+
expandTime,
|
|
2754
|
+
markTimeDirty
|
|
2755
|
+
};
|
|
2756
|
+
}
|
|
2757
|
+
function formatTime(hour, minute) {
|
|
2758
|
+
const period = hour >= 12 ? "PM" : "AM";
|
|
2759
|
+
const h = hour % 12 || 12;
|
|
2760
|
+
const m = minute.toString().padStart(2, "0");
|
|
2761
|
+
return `${h}:${m} ${period}`;
|
|
2762
|
+
}
|
|
2763
|
+
function isTimeComplete(time) {
|
|
2764
|
+
return time.from.hour !== null && time.from.minute !== null && time.to.hour !== null && time.to.minute !== null;
|
|
2765
|
+
}
|
|
2766
|
+
function formatDateRange(range, placeholder, time) {
|
|
2767
|
+
if (!range?.from) return placeholder;
|
|
2768
|
+
const hasTime = time && isTimeComplete(time);
|
|
2769
|
+
if (!range.to || isSameDay(range.from, range.to)) {
|
|
2770
|
+
const dateStr = format(range.from, "MMM d, yyyy");
|
|
2771
|
+
return hasTime ? `${dateStr} ${formatTime(time.from.hour, time.from.minute)} \u2013 ${formatTime(time.to.hour, time.to.minute)}` : dateStr;
|
|
2772
|
+
}
|
|
2773
|
+
const sameYear = range.from.getFullYear() === range.to.getFullYear();
|
|
2774
|
+
const fromDate = format(range.from, sameYear ? "MMM d" : "MMM d, yyyy");
|
|
2775
|
+
const toDate = format(range.to, "MMM d, yyyy");
|
|
2776
|
+
if (hasTime) {
|
|
2777
|
+
return `${fromDate} ${formatTime(time.from.hour, time.from.minute)} \u2013 ${toDate} ${formatTime(time.to.hour, time.to.minute)}`;
|
|
2778
|
+
}
|
|
2779
|
+
return `${fromDate} \u2013 ${toDate}`;
|
|
2780
|
+
}
|
|
2581
2781
|
var DEFAULT_PRESETS = [
|
|
2582
2782
|
{
|
|
2583
2783
|
label: "Today",
|
|
@@ -2597,7 +2797,7 @@ var DEFAULT_PRESETS = [
|
|
|
2597
2797
|
label: "This Week",
|
|
2598
2798
|
getRange: () => ({
|
|
2599
2799
|
from: startOfWeek(/* @__PURE__ */ new Date(), { weekStartsOn: 0 }),
|
|
2600
|
-
to: endOfWeek(/* @__PURE__ */ new Date(), { weekStartsOn: 0 })
|
|
2800
|
+
to: min([endOfWeek(/* @__PURE__ */ new Date(), { weekStartsOn: 0 }), endOfDay(/* @__PURE__ */ new Date())])
|
|
2601
2801
|
})
|
|
2602
2802
|
},
|
|
2603
2803
|
{
|
|
@@ -2614,7 +2814,7 @@ var DEFAULT_PRESETS = [
|
|
|
2614
2814
|
label: "This Month",
|
|
2615
2815
|
getRange: () => ({
|
|
2616
2816
|
from: startOfMonth(/* @__PURE__ */ new Date()),
|
|
2617
|
-
to: endOfMonth(/* @__PURE__ */ new Date())
|
|
2817
|
+
to: min([endOfMonth(/* @__PURE__ */ new Date()), endOfDay(/* @__PURE__ */ new Date())])
|
|
2618
2818
|
})
|
|
2619
2819
|
},
|
|
2620
2820
|
{
|
|
@@ -2625,26 +2825,6 @@ var DEFAULT_PRESETS = [
|
|
|
2625
2825
|
}
|
|
2626
2826
|
}
|
|
2627
2827
|
];
|
|
2628
|
-
function formatTime(tv) {
|
|
2629
|
-
if (tv.hour === null || tv.minute === null) return "--:--";
|
|
2630
|
-
const period = tv.hour >= 12 ? "PM" : "AM";
|
|
2631
|
-
const h = tv.hour % 12 || 12;
|
|
2632
|
-
const m = tv.minute.toString().padStart(2, "0");
|
|
2633
|
-
return `${h}:${m} ${period}`;
|
|
2634
|
-
}
|
|
2635
|
-
function formatDateRange(range, placeholder, time) {
|
|
2636
|
-
if (!range?.from) return placeholder;
|
|
2637
|
-
const timeActive = time && time.from.hour !== null && time.to.hour !== null;
|
|
2638
|
-
const timeSuffix = timeActive ? ` ${formatTime(time.from)} \u2013 ${formatTime(time.to)}` : "";
|
|
2639
|
-
if (!range.to || isSameDay(range.from, range.to)) {
|
|
2640
|
-
return format(range.from, "MMM d, yyyy") + timeSuffix;
|
|
2641
|
-
}
|
|
2642
|
-
const sameYear = range.from.getFullYear() === range.to.getFullYear();
|
|
2643
|
-
if (sameYear) {
|
|
2644
|
-
return `${format(range.from, "MMM d")} \u2013 ${format(range.to, "MMM d, yyyy")}${timeSuffix}`;
|
|
2645
|
-
}
|
|
2646
|
-
return `${format(range.from, "MMM d, yyyy")} \u2013 ${format(range.to, "MMM d, yyyy")}${timeSuffix}`;
|
|
2647
|
-
}
|
|
2648
2828
|
function DateRangePicker({
|
|
2649
2829
|
value,
|
|
2650
2830
|
onChange,
|
|
@@ -2658,77 +2838,15 @@ function DateRangePicker({
|
|
|
2658
2838
|
timeValue,
|
|
2659
2839
|
onTimeChange
|
|
2660
2840
|
}) {
|
|
2661
|
-
const
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2841
|
+
const picker = useDateRangePicker({
|
|
2842
|
+
value,
|
|
2843
|
+
onChange,
|
|
2844
|
+
showTimePicker,
|
|
2845
|
+
timeValue,
|
|
2846
|
+
onTimeChange
|
|
2665
2847
|
});
|
|
2666
|
-
const
|
|
2667
|
-
|
|
2668
|
-
to: void 0
|
|
2669
|
-
});
|
|
2670
|
-
const [hoverDate, setHoverDate] = React10.useState();
|
|
2671
|
-
const [leftMonth, setLeftMonth] = React10.useState(
|
|
2672
|
-
() => startOfMonth(value?.from ?? /* @__PURE__ */ new Date())
|
|
2673
|
-
);
|
|
2674
|
-
const [activePreset, setActivePreset] = React10.useState();
|
|
2675
|
-
const [internalTime, setInternalTime] = React10.useState(DEFAULT_TIME_RANGE);
|
|
2676
|
-
const committedRange = value ?? internalRange;
|
|
2677
|
-
const currentTime = timeValue ?? internalTime;
|
|
2678
|
-
const handleTimeChange = (newTime) => {
|
|
2679
|
-
if (onTimeChange) onTimeChange(newTime);
|
|
2680
|
-
else setInternalTime(newTime);
|
|
2681
|
-
};
|
|
2682
|
-
const timeVisible = !!(draft.from && draft.to);
|
|
2683
|
-
const handleOpenChange = (newOpen) => {
|
|
2684
|
-
if (newOpen) {
|
|
2685
|
-
setDraft(committedRange);
|
|
2686
|
-
if (committedRange.from) setLeftMonth(startOfMonth(committedRange.from));
|
|
2687
|
-
if (!onTimeChange) setInternalTime(currentTime);
|
|
2688
|
-
}
|
|
2689
|
-
setOpen(newOpen);
|
|
2690
|
-
};
|
|
2691
|
-
const handleDayClick = (date) => {
|
|
2692
|
-
const { from, to } = draft;
|
|
2693
|
-
if (!from || from && to) {
|
|
2694
|
-
setDraft({ from: date, to: void 0 });
|
|
2695
|
-
setActivePreset(void 0);
|
|
2696
|
-
return;
|
|
2697
|
-
}
|
|
2698
|
-
const [start, end] = isBefore(from, date) ? [from, date] : [date, from];
|
|
2699
|
-
setDraft({ from: start, to: end });
|
|
2700
|
-
setHoverDate(void 0);
|
|
2701
|
-
};
|
|
2702
|
-
const handlePreset = (preset) => {
|
|
2703
|
-
const newRange = preset.getRange();
|
|
2704
|
-
if (showTimePicker) {
|
|
2705
|
-
setDraft(newRange);
|
|
2706
|
-
setActivePreset(preset.label);
|
|
2707
|
-
if (newRange.from) setLeftMonth(startOfMonth(newRange.from));
|
|
2708
|
-
} else {
|
|
2709
|
-
if (onChange) onChange(newRange);
|
|
2710
|
-
else setInternalRange(newRange);
|
|
2711
|
-
setActivePreset(preset.label);
|
|
2712
|
-
if (newRange.from) setLeftMonth(startOfMonth(newRange.from));
|
|
2713
|
-
setOpen(false);
|
|
2714
|
-
}
|
|
2715
|
-
};
|
|
2716
|
-
const handleApply = () => {
|
|
2717
|
-
if (draft.from && !draft.to) return;
|
|
2718
|
-
const newRange = draft.from && draft.to ? draft : void 0;
|
|
2719
|
-
if (onChange) onChange(newRange);
|
|
2720
|
-
else setInternalRange(newRange ?? { from: void 0, to: void 0 });
|
|
2721
|
-
setOpen(false);
|
|
2722
|
-
};
|
|
2723
|
-
const handleClear = () => {
|
|
2724
|
-
setDraft({ from: void 0, to: void 0 });
|
|
2725
|
-
setActivePreset(void 0);
|
|
2726
|
-
if (showTimePicker) handleTimeChange(DEFAULT_TIME_RANGE);
|
|
2727
|
-
};
|
|
2728
|
-
const canClear = !!(draft.from || committedRange.from);
|
|
2729
|
-
const canApply = !(draft.from && !draft.to) && !!(draft.from || committedRange.from);
|
|
2730
|
-
const rightMonth = addMonths(leftMonth, 1);
|
|
2731
|
-
return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: handleOpenChange, children: [
|
|
2848
|
+
const rightMonth = addMonths(picker.viewMonth, 1);
|
|
2849
|
+
return /* @__PURE__ */ jsxs(Popover, { open: picker.open, onOpenChange: picker.handleOpenChange, children: [
|
|
2732
2850
|
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
2733
2851
|
"button",
|
|
2734
2852
|
{
|
|
@@ -2738,15 +2856,15 @@ function DateRangePicker({
|
|
|
2738
2856
|
"hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2",
|
|
2739
2857
|
"dark:border-neutral-600 dark:bg-neutral-800 dark:hover:bg-neutral-700",
|
|
2740
2858
|
"disabled:pointer-events-none disabled:opacity-50",
|
|
2741
|
-
committedRange.from ? "text-gray-900 dark:text-gray-100" : "text-gray-400 dark:text-gray-500",
|
|
2859
|
+
picker.committedRange.from ? "text-gray-900 dark:text-gray-100" : "text-gray-400 dark:text-gray-500",
|
|
2742
2860
|
className
|
|
2743
2861
|
),
|
|
2744
2862
|
children: [
|
|
2745
2863
|
/* @__PURE__ */ jsx(CalendarIcon, { className: "w-4 h-4 shrink-0 text-gray-400 dark:text-gray-500" }),
|
|
2746
2864
|
/* @__PURE__ */ jsx("span", { children: formatDateRange(
|
|
2747
|
-
committedRange,
|
|
2865
|
+
picker.committedRange,
|
|
2748
2866
|
placeholder,
|
|
2749
|
-
showTimePicker ?
|
|
2867
|
+
showTimePicker ? picker.committedTime : void 0
|
|
2750
2868
|
) })
|
|
2751
2869
|
]
|
|
2752
2870
|
}
|
|
@@ -2758,10 +2876,10 @@ function DateRangePicker({
|
|
|
2758
2876
|
section.options.map((preset) => /* @__PURE__ */ jsx(
|
|
2759
2877
|
"button",
|
|
2760
2878
|
{
|
|
2761
|
-
onClick: () => handlePreset(preset),
|
|
2879
|
+
onClick: () => picker.handlePreset(preset),
|
|
2762
2880
|
className: cn(
|
|
2763
2881
|
"w-full text-left px-2 py-1.5 rounded-md text-sm transition-colors",
|
|
2764
|
-
activePreset === preset.label ? "bg-blue-50 text-blue-600 font-medium dark:bg-blue-950/50 dark:text-blue-400" : "text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-neutral-700"
|
|
2882
|
+
picker.activePreset === preset.label ? "bg-blue-50 text-blue-600 font-medium dark:bg-blue-950/50 dark:text-blue-400" : "text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-neutral-700"
|
|
2765
2883
|
),
|
|
2766
2884
|
children: preset.label
|
|
2767
2885
|
},
|
|
@@ -2773,12 +2891,12 @@ function DateRangePicker({
|
|
|
2773
2891
|
/* @__PURE__ */ jsx(
|
|
2774
2892
|
CalendarMonth,
|
|
2775
2893
|
{
|
|
2776
|
-
month:
|
|
2777
|
-
range: draft,
|
|
2778
|
-
hoverDate,
|
|
2779
|
-
onDayClick: handleDayClick,
|
|
2780
|
-
onDayHover: setHoverDate,
|
|
2781
|
-
onPrevMonth: () =>
|
|
2894
|
+
month: picker.viewMonth,
|
|
2895
|
+
range: picker.draft,
|
|
2896
|
+
hoverDate: picker.hoverDate,
|
|
2897
|
+
onDayClick: picker.handleDayClick,
|
|
2898
|
+
onDayHover: picker.setHoverDate,
|
|
2899
|
+
onPrevMonth: () => picker.setViewMonth(subMonths(picker.viewMonth, 1)),
|
|
2782
2900
|
showPrevNav: true,
|
|
2783
2901
|
showNextNav: false
|
|
2784
2902
|
}
|
|
@@ -2788,46 +2906,72 @@ function DateRangePicker({
|
|
|
2788
2906
|
CalendarMonth,
|
|
2789
2907
|
{
|
|
2790
2908
|
month: rightMonth,
|
|
2791
|
-
range: draft,
|
|
2792
|
-
hoverDate,
|
|
2793
|
-
onDayClick: handleDayClick,
|
|
2794
|
-
onDayHover: setHoverDate,
|
|
2795
|
-
onNextMonth: () =>
|
|
2909
|
+
range: picker.draft,
|
|
2910
|
+
hoverDate: picker.hoverDate,
|
|
2911
|
+
onDayClick: picker.handleDayClick,
|
|
2912
|
+
onDayHover: picker.setHoverDate,
|
|
2913
|
+
onNextMonth: () => picker.setViewMonth(addMonths(picker.viewMonth, 1)),
|
|
2796
2914
|
showPrevNav: false,
|
|
2797
2915
|
showNextNav: true
|
|
2798
2916
|
}
|
|
2799
2917
|
)
|
|
2800
2918
|
] }),
|
|
2801
|
-
showTimePicker && /* @__PURE__ */ jsx(
|
|
2919
|
+
showTimePicker && /* @__PURE__ */ jsx(
|
|
2802
2920
|
motion.div,
|
|
2803
2921
|
{
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
opacity: { duration: 0.2 }
|
|
2810
|
-
},
|
|
2811
|
-
className: "overflow-hidden",
|
|
2812
|
-
children: /* @__PURE__ */ jsx(
|
|
2813
|
-
TimePickerRow,
|
|
2922
|
+
layout: true,
|
|
2923
|
+
transition: { layout: { duration: 0.2, ease: "easeInOut" } },
|
|
2924
|
+
className: "border-t border-gray-100 dark:border-neutral-700",
|
|
2925
|
+
children: /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", initial: false, children: picker.timeVisible && !picker.timeExpanded ? /* @__PURE__ */ jsx(
|
|
2926
|
+
motion.div,
|
|
2814
2927
|
{
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2928
|
+
initial: { opacity: 0 },
|
|
2929
|
+
animate: { opacity: 1 },
|
|
2930
|
+
exit: { opacity: 0 },
|
|
2931
|
+
transition: { duration: 0.12 },
|
|
2932
|
+
children: /* @__PURE__ */ jsx("div", { className: "px-4 py-2 ", children: /* @__PURE__ */ jsx(
|
|
2933
|
+
Button,
|
|
2934
|
+
{
|
|
2935
|
+
variant: "outline",
|
|
2936
|
+
onClick: picker.expandTime,
|
|
2937
|
+
leadingDecorator: /* @__PURE__ */ jsx(Clock, { className: "w-3.5 h-3.5" }),
|
|
2938
|
+
className: "w-full rounded-md h-9",
|
|
2939
|
+
children: "Add time range"
|
|
2940
|
+
}
|
|
2941
|
+
) })
|
|
2942
|
+
},
|
|
2943
|
+
"add-time-btn"
|
|
2944
|
+
) : picker.timeVisible && picker.timeExpanded ? /* @__PURE__ */ jsx(
|
|
2945
|
+
motion.div,
|
|
2946
|
+
{
|
|
2947
|
+
initial: { opacity: 0 },
|
|
2948
|
+
animate: { opacity: 1 },
|
|
2949
|
+
exit: { opacity: 0 },
|
|
2950
|
+
transition: { duration: 0.12 },
|
|
2951
|
+
children: /* @__PURE__ */ jsx(
|
|
2952
|
+
TimePickerRow,
|
|
2953
|
+
{
|
|
2954
|
+
value: picker.draftTime,
|
|
2955
|
+
onChange: picker.handleTimeChange,
|
|
2956
|
+
onRemove: picker.resetTime,
|
|
2957
|
+
showRemove: picker.timeExpanded,
|
|
2958
|
+
onDirty: picker.markTimeDirty
|
|
2959
|
+
}
|
|
2960
|
+
)
|
|
2961
|
+
},
|
|
2962
|
+
"time-picker"
|
|
2963
|
+
) : null })
|
|
2964
|
+
}
|
|
2965
|
+
),
|
|
2822
2966
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-2 px-4 py-3 border-t border-gray-100 dark:border-neutral-700", children: [
|
|
2823
2967
|
/* @__PURE__ */ jsx(
|
|
2824
2968
|
"button",
|
|
2825
2969
|
{
|
|
2826
|
-
onClick: handleClear,
|
|
2827
|
-
disabled: !canClear,
|
|
2970
|
+
onClick: picker.handleClear,
|
|
2971
|
+
disabled: !picker.canClear,
|
|
2828
2972
|
className: cn(
|
|
2829
2973
|
"px-3 py-1.5 rounded-md text-sm transition-colors",
|
|
2830
|
-
canClear ? "text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-neutral-700" : "text-gray-300 dark:text-gray-600 cursor-not-allowed"
|
|
2974
|
+
picker.canClear ? "text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-neutral-700" : "text-gray-300 dark:text-gray-600 cursor-not-allowed"
|
|
2831
2975
|
),
|
|
2832
2976
|
children: "Clear"
|
|
2833
2977
|
}
|
|
@@ -2835,11 +2979,11 @@ function DateRangePicker({
|
|
|
2835
2979
|
/* @__PURE__ */ jsx(
|
|
2836
2980
|
"button",
|
|
2837
2981
|
{
|
|
2838
|
-
onClick: handleApply,
|
|
2839
|
-
disabled: !canApply,
|
|
2982
|
+
onClick: picker.handleApply,
|
|
2983
|
+
disabled: !picker.canApply,
|
|
2840
2984
|
className: cn(
|
|
2841
2985
|
"px-3 py-1.5 rounded-md text-sm font-medium transition-colors",
|
|
2842
|
-
canApply ? "bg-blue-600 text-white hover:bg-blue-700 dark:hover:bg-blue-500" : "bg-blue-100 text-blue-300 cursor-not-allowed dark:bg-blue-950/30 dark:text-blue-800"
|
|
2986
|
+
picker.canApply ? "bg-blue-600 text-white hover:bg-blue-700 dark:hover:bg-blue-500" : "bg-blue-100 text-blue-300 cursor-not-allowed dark:bg-blue-950/30 dark:text-blue-800"
|
|
2843
2987
|
),
|
|
2844
2988
|
children: "Apply"
|
|
2845
2989
|
}
|
|
@@ -2849,30 +2993,6 @@ function DateRangePicker({
|
|
|
2849
2993
|
] }) })
|
|
2850
2994
|
] });
|
|
2851
2995
|
}
|
|
2852
|
-
function formatTime2(tv) {
|
|
2853
|
-
if (tv.hour === null || tv.minute === null) return "";
|
|
2854
|
-
const period = tv.hour >= 12 ? "PM" : "AM";
|
|
2855
|
-
const h = tv.hour % 12 || 12;
|
|
2856
|
-
const m = tv.minute.toString().padStart(2, "0");
|
|
2857
|
-
return `${h}:${m} ${period}`;
|
|
2858
|
-
}
|
|
2859
|
-
function formatDateWithTime(date, dateFmt, time) {
|
|
2860
|
-
const dateStr = format(date, dateFmt);
|
|
2861
|
-
const timeStr = time ? formatTime2(time) : "";
|
|
2862
|
-
return timeStr ? `${dateStr}, ${timeStr}` : dateStr;
|
|
2863
|
-
}
|
|
2864
|
-
function formatDateRange2(range, placeholder, time) {
|
|
2865
|
-
if (!range?.from) return placeholder;
|
|
2866
|
-
const hasTime = time && time.from.hour !== null && time.to.hour !== null;
|
|
2867
|
-
if (!range.to || isSameDay(range.from, range.to)) {
|
|
2868
|
-
return formatDateWithTime(range.from, "MMMM d, yyyy", hasTime ? time.from : void 0);
|
|
2869
|
-
}
|
|
2870
|
-
const sameYear = range.from.getFullYear() === range.to.getFullYear();
|
|
2871
|
-
const fromFmt = sameYear ? "MMMM d" : "MMMM d, yyyy";
|
|
2872
|
-
const fromStr = formatDateWithTime(range.from, fromFmt, hasTime ? time.from : void 0);
|
|
2873
|
-
const toStr = formatDateWithTime(range.to, "MMMM d, yyyy", hasTime ? time.to : void 0);
|
|
2874
|
-
return `${fromStr} \u2013 ${toStr}`;
|
|
2875
|
-
}
|
|
2876
2996
|
function DateRangePickerMobile({
|
|
2877
2997
|
label,
|
|
2878
2998
|
value,
|
|
@@ -2886,78 +3006,16 @@ function DateRangePickerMobile({
|
|
|
2886
3006
|
timeValue,
|
|
2887
3007
|
onTimeChange
|
|
2888
3008
|
}) {
|
|
2889
|
-
const
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
from: void 0,
|
|
2896
|
-
to: void 0
|
|
3009
|
+
const picker = useDateRangePicker({
|
|
3010
|
+
value,
|
|
3011
|
+
onChange,
|
|
3012
|
+
showTimePicker,
|
|
3013
|
+
timeValue,
|
|
3014
|
+
onTimeChange
|
|
2897
3015
|
});
|
|
2898
|
-
const [hoverDate, setHoverDate] = React10.useState();
|
|
2899
|
-
const [viewMonth, setViewMonth] = React10.useState(
|
|
2900
|
-
() => startOfMonth(value?.from ?? /* @__PURE__ */ new Date())
|
|
2901
|
-
);
|
|
2902
|
-
const [activePreset, setActivePreset] = React10.useState();
|
|
2903
|
-
const [internalTime, setInternalTime] = React10.useState(DEFAULT_TIME_RANGE);
|
|
2904
|
-
const committedRange = value ?? internalRange;
|
|
2905
|
-
const currentTime = timeValue ?? internalTime;
|
|
2906
|
-
const handleTimeChange = (newTime) => {
|
|
2907
|
-
if (onTimeChange) onTimeChange(newTime);
|
|
2908
|
-
else setInternalTime(newTime);
|
|
2909
|
-
};
|
|
2910
|
-
const timeVisible = !!(draft.from && draft.to);
|
|
2911
|
-
const handleOpenChange = (newOpen) => {
|
|
2912
|
-
if (newOpen) {
|
|
2913
|
-
setDraft(committedRange);
|
|
2914
|
-
if (committedRange.from) setViewMonth(startOfMonth(committedRange.from));
|
|
2915
|
-
if (!onTimeChange) setInternalTime(currentTime);
|
|
2916
|
-
}
|
|
2917
|
-
setOpen(newOpen);
|
|
2918
|
-
};
|
|
2919
|
-
const handleDayClick = (date) => {
|
|
2920
|
-
const { from, to } = draft;
|
|
2921
|
-
if (!from || from && to) {
|
|
2922
|
-
setDraft({ from: date, to: void 0 });
|
|
2923
|
-
setActivePreset(void 0);
|
|
2924
|
-
return;
|
|
2925
|
-
}
|
|
2926
|
-
const [start, end] = isBefore(from, date) ? [from, date] : [date, from];
|
|
2927
|
-
setDraft({ from: start, to: end });
|
|
2928
|
-
setHoverDate(void 0);
|
|
2929
|
-
};
|
|
2930
|
-
const handlePreset = (preset) => {
|
|
2931
|
-
const newRange = preset.getRange();
|
|
2932
|
-
if (showTimePicker) {
|
|
2933
|
-
setDraft(newRange);
|
|
2934
|
-
setActivePreset(preset.label);
|
|
2935
|
-
if (newRange.from) setViewMonth(startOfMonth(newRange.from));
|
|
2936
|
-
} else {
|
|
2937
|
-
if (onChange) onChange(newRange);
|
|
2938
|
-
else setInternalRange(newRange);
|
|
2939
|
-
setActivePreset(preset.label);
|
|
2940
|
-
if (newRange.from) setViewMonth(startOfMonth(newRange.from));
|
|
2941
|
-
setOpen(false);
|
|
2942
|
-
}
|
|
2943
|
-
};
|
|
2944
|
-
const handleApply = () => {
|
|
2945
|
-
if (draft.from && !draft.to) return;
|
|
2946
|
-
const newRange = draft.from && draft.to ? draft : void 0;
|
|
2947
|
-
if (onChange) onChange(newRange);
|
|
2948
|
-
else setInternalRange(newRange ?? { from: void 0, to: void 0 });
|
|
2949
|
-
setOpen(false);
|
|
2950
|
-
};
|
|
2951
|
-
const handleClear = () => {
|
|
2952
|
-
setDraft({ from: void 0, to: void 0 });
|
|
2953
|
-
setActivePreset(void 0);
|
|
2954
|
-
if (showTimePicker) handleTimeChange(DEFAULT_TIME_RANGE);
|
|
2955
|
-
};
|
|
2956
|
-
const canClear = !!(draft.from || committedRange.from);
|
|
2957
|
-
const canApply = !(draft.from && !draft.to) && !!(draft.from || committedRange.from);
|
|
2958
3016
|
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-1.5", className), children: [
|
|
2959
3017
|
label && /* @__PURE__ */ jsx(Label, { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: label }),
|
|
2960
|
-
/* @__PURE__ */ jsxs(Popover, { open, onOpenChange: handleOpenChange, children: [
|
|
3018
|
+
/* @__PURE__ */ jsxs(Popover, { open: picker.open, onOpenChange: picker.handleOpenChange, children: [
|
|
2961
3019
|
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
2962
3020
|
"button",
|
|
2963
3021
|
{
|
|
@@ -2967,14 +3025,14 @@ function DateRangePickerMobile({
|
|
|
2967
3025
|
"hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2",
|
|
2968
3026
|
"dark:border-neutral-600 dark:bg-neutral-800 dark:hover:bg-neutral-700",
|
|
2969
3027
|
"disabled:pointer-events-none disabled:opacity-50",
|
|
2970
|
-
committedRange.from ? "text-gray-900 dark:text-gray-100" : "text-gray-400 dark:text-gray-500"
|
|
3028
|
+
picker.committedRange.from ? "text-gray-900 dark:text-gray-100" : "text-gray-400 dark:text-gray-500"
|
|
2971
3029
|
),
|
|
2972
3030
|
children: [
|
|
2973
3031
|
/* @__PURE__ */ jsx(CalendarIcon, { className: "w-4 h-4 shrink-0 text-gray-400 dark:text-gray-500" }),
|
|
2974
|
-
/* @__PURE__ */ jsx("span", { className: "truncate", children:
|
|
2975
|
-
committedRange,
|
|
3032
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: formatDateRange(
|
|
3033
|
+
picker.committedRange,
|
|
2976
3034
|
placeholder,
|
|
2977
|
-
showTimePicker ?
|
|
3035
|
+
showTimePicker ? picker.committedTime : void 0
|
|
2978
3036
|
) })
|
|
2979
3037
|
]
|
|
2980
3038
|
}
|
|
@@ -2987,10 +3045,10 @@ function DateRangePickerMobile({
|
|
|
2987
3045
|
section.options.map((preset) => /* @__PURE__ */ jsx(
|
|
2988
3046
|
"button",
|
|
2989
3047
|
{
|
|
2990
|
-
onClick: () => handlePreset(preset),
|
|
3048
|
+
onClick: () => picker.handlePreset(preset),
|
|
2991
3049
|
className: cn(
|
|
2992
3050
|
"w-full text-left px-2 py-1.5 rounded-md text-sm transition-colors",
|
|
2993
|
-
activePreset === preset.label ? "bg-blue-50 text-blue-600 font-medium dark:bg-blue-950/50 dark:text-blue-400" : "text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-neutral-700"
|
|
3051
|
+
picker.activePreset === preset.label ? "bg-blue-50 text-blue-600 font-medium dark:bg-blue-950/50 dark:text-blue-400" : "text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-neutral-700"
|
|
2994
3052
|
),
|
|
2995
3053
|
children: preset.label
|
|
2996
3054
|
},
|
|
@@ -3002,52 +3060,73 @@ function DateRangePickerMobile({
|
|
|
3002
3060
|
/* @__PURE__ */ jsx("div", { className: "p-2", children: /* @__PURE__ */ jsx(
|
|
3003
3061
|
CalendarMonth,
|
|
3004
3062
|
{
|
|
3005
|
-
month: viewMonth,
|
|
3006
|
-
range: draft,
|
|
3007
|
-
hoverDate,
|
|
3008
|
-
onDayClick: handleDayClick,
|
|
3009
|
-
onDayHover: setHoverDate,
|
|
3010
|
-
onPrevMonth: () => setViewMonth(subMonths(viewMonth, 1)),
|
|
3011
|
-
onNextMonth: () => setViewMonth(addMonths(viewMonth, 1)),
|
|
3063
|
+
month: picker.viewMonth,
|
|
3064
|
+
range: picker.draft,
|
|
3065
|
+
hoverDate: picker.hoverDate,
|
|
3066
|
+
onDayClick: picker.handleDayClick,
|
|
3067
|
+
onDayHover: picker.setHoverDate,
|
|
3068
|
+
onPrevMonth: () => picker.setViewMonth(subMonths(picker.viewMonth, 1)),
|
|
3069
|
+
onNextMonth: () => picker.setViewMonth(addMonths(picker.viewMonth, 1)),
|
|
3012
3070
|
showPrevNav: true,
|
|
3013
3071
|
showNextNav: true
|
|
3014
3072
|
}
|
|
3015
3073
|
) }),
|
|
3016
|
-
showTimePicker && /* @__PURE__ */ jsx(
|
|
3074
|
+
showTimePicker && /* @__PURE__ */ jsx(
|
|
3017
3075
|
motion.div,
|
|
3018
3076
|
{
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3077
|
+
layout: true,
|
|
3078
|
+
transition: { layout: { duration: 0.2, ease: "easeInOut" } },
|
|
3079
|
+
className: "border-t border-gray-100 dark:border-neutral-700",
|
|
3080
|
+
children: /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", initial: false, children: picker.timeVisible && !picker.timeExpanded ? /* @__PURE__ */ jsx(
|
|
3081
|
+
motion.div,
|
|
3082
|
+
{
|
|
3083
|
+
initial: { opacity: 0 },
|
|
3084
|
+
animate: { opacity: 1 },
|
|
3085
|
+
exit: { opacity: 0 },
|
|
3086
|
+
transition: { duration: 0.12 },
|
|
3087
|
+
children: /* @__PURE__ */ jsx("div", { className: "px-2 py-2", children: /* @__PURE__ */ jsx(
|
|
3088
|
+
Button,
|
|
3089
|
+
{
|
|
3090
|
+
variant: "outline",
|
|
3091
|
+
onClick: picker.expandTime,
|
|
3092
|
+
leadingDecorator: /* @__PURE__ */ jsx(Clock, { className: "w-3.5 h-3.5" }),
|
|
3093
|
+
className: "w-full rounded-md h-9",
|
|
3094
|
+
children: "Add time range"
|
|
3095
|
+
}
|
|
3096
|
+
) })
|
|
3028
3097
|
},
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
children: /* @__PURE__ */ jsx(
|
|
3033
|
-
TimePickerColumn,
|
|
3098
|
+
"add-time-btn"
|
|
3099
|
+
) : picker.timeVisible && picker.timeExpanded ? /* @__PURE__ */ jsx(
|
|
3100
|
+
motion.div,
|
|
3034
3101
|
{
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3102
|
+
initial: { opacity: 0 },
|
|
3103
|
+
animate: { opacity: 1 },
|
|
3104
|
+
exit: { opacity: 0 },
|
|
3105
|
+
transition: { duration: 0.12 },
|
|
3106
|
+
children: /* @__PURE__ */ jsx(
|
|
3107
|
+
TimePickerColumn,
|
|
3108
|
+
{
|
|
3109
|
+
value: picker.draftTime,
|
|
3110
|
+
onChange: picker.handleTimeChange,
|
|
3111
|
+
onRemove: picker.resetTime,
|
|
3112
|
+
showRemove: picker.timeExpanded,
|
|
3113
|
+
onDirty: picker.markTimeDirty
|
|
3114
|
+
}
|
|
3115
|
+
)
|
|
3116
|
+
},
|
|
3117
|
+
"time-picker"
|
|
3118
|
+
) : null })
|
|
3119
|
+
}
|
|
3120
|
+
),
|
|
3042
3121
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-2 px-2 py-3 border-t border-gray-100 dark:border-neutral-700", children: [
|
|
3043
3122
|
/* @__PURE__ */ jsx(
|
|
3044
3123
|
"button",
|
|
3045
3124
|
{
|
|
3046
|
-
onClick: handleClear,
|
|
3047
|
-
disabled: !canClear,
|
|
3125
|
+
onClick: picker.handleClear,
|
|
3126
|
+
disabled: !picker.canClear,
|
|
3048
3127
|
className: cn(
|
|
3049
3128
|
"px-3 py-1.5 rounded-md text-sm transition-colors",
|
|
3050
|
-
canClear ? "text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-neutral-700" : "text-gray-300 dark:text-gray-600 cursor-not-allowed"
|
|
3129
|
+
picker.canClear ? "text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-neutral-700" : "text-gray-300 dark:text-gray-600 cursor-not-allowed"
|
|
3051
3130
|
),
|
|
3052
3131
|
children: "Clear"
|
|
3053
3132
|
}
|
|
@@ -3055,11 +3134,11 @@ function DateRangePickerMobile({
|
|
|
3055
3134
|
/* @__PURE__ */ jsx(
|
|
3056
3135
|
"button",
|
|
3057
3136
|
{
|
|
3058
|
-
onClick: handleApply,
|
|
3059
|
-
disabled: !canApply,
|
|
3137
|
+
onClick: picker.handleApply,
|
|
3138
|
+
disabled: !picker.canApply,
|
|
3060
3139
|
className: cn(
|
|
3061
3140
|
"px-3 py-1.5 rounded-md text-sm font-medium transition-colors",
|
|
3062
|
-
canApply ? "bg-blue-600 text-white hover:bg-blue-700 dark:hover:bg-blue-500" : "bg-blue-100 text-blue-300 cursor-not-allowed dark:bg-blue-950/30 dark:text-blue-800"
|
|
3141
|
+
picker.canApply ? "bg-blue-600 text-white hover:bg-blue-700 dark:hover:bg-blue-500" : "bg-blue-100 text-blue-300 cursor-not-allowed dark:bg-blue-950/30 dark:text-blue-800"
|
|
3063
3142
|
),
|
|
3064
3143
|
children: "Apply"
|
|
3065
3144
|
}
|
|
@@ -3319,5 +3398,5 @@ function PeriodComparisonSelector({
|
|
|
3319
3398
|
}
|
|
3320
3399
|
|
|
3321
3400
|
export { Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, ColumnSelection, DEFAULT_COMPARISON_PERIODS, DEFAULT_PRESETS, DEFAULT_TIME_RANGE, DateRangePicker, DateRangePickerMobile, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Form, FormControl, FormDescription, FormField, FormLabel, FormMessage, MobileDataCard, PeriodComparisonSelector, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, SegmentedControl, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator3 as Separator, Skeleton, SkeletonAvatar, SkeletonBadge, SkeletonButton, SkeletonCard, SkeletonIcon, SkeletonInput, SkeletonSubtitle, SkeletonTableRow, SkeletonTableRows, SkeletonText, SkeletonTitle, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, TableRowCheckbox, TableSelectAll, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toggle, buttonVariants, segmentedControlItemVariants, segmentedControlVariants, separatorVariants, switchLabelVariants, switchThumbVariants, switchTrackVariants, toggleGroupVariants, toggleItemVariants, useColumnVisibility, useFormContext, useFormFieldContext, useTableSelection };
|
|
3322
|
-
//# sourceMappingURL=chunk-
|
|
3323
|
-
//# sourceMappingURL=chunk-
|
|
3401
|
+
//# sourceMappingURL=chunk-HFDHLY24.mjs.map
|
|
3402
|
+
//# sourceMappingURL=chunk-HFDHLY24.mjs.map
|