myoperator-mcp 0.2.381 → 0.2.383
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/index.js +290 -129
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2736,8 +2736,44 @@ function getCalendarDays(month: Date) {
|
|
|
2736
2736
|
});
|
|
2737
2737
|
}
|
|
2738
2738
|
|
|
2739
|
+
function isMonthSelectable(
|
|
2740
|
+
year: number,
|
|
2741
|
+
monthIndex: number,
|
|
2742
|
+
minDate?: Date,
|
|
2743
|
+
maxDate?: Date
|
|
2744
|
+
) {
|
|
2745
|
+
const firstDay = new Date(year, monthIndex, 1);
|
|
2746
|
+
const lastDay = new Date(year, monthIndex + 1, 0);
|
|
2747
|
+
|
|
2748
|
+
if (minDate && isBeforeDay(lastDay, minDate)) return false;
|
|
2749
|
+
if (maxDate && isAfterDay(firstDay, maxDate)) return false;
|
|
2750
|
+
|
|
2751
|
+
return true;
|
|
2752
|
+
}
|
|
2753
|
+
|
|
2754
|
+
function clampRange(
|
|
2755
|
+
range: DateRangeValue,
|
|
2756
|
+
minDate?: Date,
|
|
2757
|
+
maxDate?: Date
|
|
2758
|
+
): DateRangeValue | null {
|
|
2759
|
+
let { start, end } = range;
|
|
2760
|
+
|
|
2761
|
+
// The window and the preset don't overlap at all \u2014 clamping would collapse
|
|
2762
|
+
// the range onto the boundary day, which is not what the preset means.
|
|
2763
|
+
if (end && minDate && isBeforeDay(end, minDate)) return null;
|
|
2764
|
+
if (start && maxDate && isAfterDay(start, maxDate)) return null;
|
|
2765
|
+
|
|
2766
|
+
if (start && minDate && isBeforeDay(start, minDate)) start = minDate;
|
|
2767
|
+
if (end && maxDate && isAfterDay(end, maxDate)) end = maxDate;
|
|
2768
|
+
|
|
2769
|
+
// The whole preset sits outside the allowed window \u2014 nothing to select.
|
|
2770
|
+
if (start && end && isAfterDay(start, end)) return null;
|
|
2771
|
+
|
|
2772
|
+
return { start, end };
|
|
2773
|
+
}
|
|
2774
|
+
|
|
2739
2775
|
function isPointerInsideElement(
|
|
2740
|
-
event: MouseEvent,
|
|
2776
|
+
event: MouseEvent | PointerEvent,
|
|
2741
2777
|
element: HTMLElement | null
|
|
2742
2778
|
) {
|
|
2743
2779
|
if (!element) return false;
|
|
@@ -2886,6 +2922,11 @@ const DateRangePicker = React.forwardRef<HTMLDivElement, DateRangePickerProps>(
|
|
|
2886
2922
|
// start a new one (false). Drives the "click 1 = start, click 2 = end,
|
|
2887
2923
|
// click 3 = restart" cycle.
|
|
2888
2924
|
const [pendingEnd, setPendingEnd] = React.useState(false);
|
|
2925
|
+
// Month and year share one slot so opening either closes the other \u2014
|
|
2926
|
+
// two independent uncontrolled menus can otherwise sit open at once.
|
|
2927
|
+
const [openMenu, setOpenMenu] = React.useState<"month" | "year" | null>(
|
|
2928
|
+
null
|
|
2929
|
+
);
|
|
2889
2930
|
const [visibleMonth, setVisibleMonth] = React.useState(() =>
|
|
2890
2931
|
startOfMonth(currentValue.start ?? currentValue.end ?? new Date())
|
|
2891
2932
|
);
|
|
@@ -2941,6 +2982,21 @@ const DateRangePicker = React.forwardRef<HTMLDivElement, DateRangePickerProps>(
|
|
|
2941
2982
|
|
|
2942
2983
|
return isBeforeDay(minDate, today) ? today : minDate;
|
|
2943
2984
|
}, [disablePastDates, minDate]);
|
|
2985
|
+
// Year list is centred on the visible year but never offers a year that
|
|
2986
|
+
// has no selectable day in it.
|
|
2987
|
+
const yearOptions = React.useMemo(() => {
|
|
2988
|
+
const centre = visibleMonth.getFullYear();
|
|
2989
|
+
const all = Array.from(
|
|
2990
|
+
{ length: YEAR_OPTIONS_SPAN * 2 + 1 },
|
|
2991
|
+
(_, index) => centre - YEAR_OPTIONS_SPAN + index
|
|
2992
|
+
);
|
|
2993
|
+
|
|
2994
|
+
return all.filter(
|
|
2995
|
+
(year) =>
|
|
2996
|
+
!(effectiveMinDate && year < effectiveMinDate.getFullYear()) &&
|
|
2997
|
+
!(maxDate && year > maxDate.getFullYear())
|
|
2998
|
+
);
|
|
2999
|
+
}, [visibleMonth, effectiveMinDate, maxDate]);
|
|
2944
3000
|
const portalMount =
|
|
2945
3001
|
typeof document !== "undefined"
|
|
2946
3002
|
? usesContainerPortal
|
|
@@ -2989,6 +3045,7 @@ const DateRangePicker = React.forwardRef<HTMLDivElement, DateRangePickerProps>(
|
|
|
2989
3045
|
const latestValue = currentValueRef.current;
|
|
2990
3046
|
setDraftValue(latestValue);
|
|
2991
3047
|
setPendingEnd(false);
|
|
3048
|
+
setOpenMenu(null);
|
|
2992
3049
|
setVisibleMonth(
|
|
2993
3050
|
startOfMonth(latestValue.start ?? latestValue.end ?? new Date())
|
|
2994
3051
|
);
|
|
@@ -2997,7 +3054,7 @@ const DateRangePicker = React.forwardRef<HTMLDivElement, DateRangePickerProps>(
|
|
|
2997
3054
|
React.useEffect(() => {
|
|
2998
3055
|
if (!open) return;
|
|
2999
3056
|
|
|
3000
|
-
const handlePointerDown = (event:
|
|
3057
|
+
const handlePointerDown = (event: PointerEvent) => {
|
|
3001
3058
|
if (
|
|
3002
3059
|
!isPointerInsideElement(event, rootRef.current) &&
|
|
3003
3060
|
!isPointerInsideElement(event, popoverRef.current)
|
|
@@ -3009,14 +3066,17 @@ const DateRangePicker = React.forwardRef<HTMLDivElement, DateRangePickerProps>(
|
|
|
3009
3066
|
const handleKeyDown = (event: KeyboardEvent) => {
|
|
3010
3067
|
if (event.key === "Escape") {
|
|
3011
3068
|
setOpen(false);
|
|
3069
|
+
// Escape must hand focus back to the trigger, otherwise focus is
|
|
3070
|
+
// stranded on a node that is about to unmount.
|
|
3071
|
+
triggerRef.current?.focus();
|
|
3012
3072
|
}
|
|
3013
3073
|
};
|
|
3014
3074
|
|
|
3015
|
-
document.addEventListener("
|
|
3075
|
+
document.addEventListener("pointerdown", handlePointerDown);
|
|
3016
3076
|
document.addEventListener("keydown", handleKeyDown);
|
|
3017
3077
|
|
|
3018
3078
|
return () => {
|
|
3019
|
-
document.removeEventListener("
|
|
3079
|
+
document.removeEventListener("pointerdown", handlePointerDown);
|
|
3020
3080
|
document.removeEventListener("keydown", handleKeyDown);
|
|
3021
3081
|
};
|
|
3022
3082
|
}, [open, setOpen]);
|
|
@@ -3032,10 +3092,21 @@ const DateRangePicker = React.forwardRef<HTMLDivElement, DateRangePickerProps>(
|
|
|
3032
3092
|
[isValueControlled, onValueChange]
|
|
3033
3093
|
);
|
|
3034
3094
|
|
|
3095
|
+
// Radix dismisses the open menu on the same pointerdown that would toggle
|
|
3096
|
+
// the sibling trigger, so its own toggle is swallowed and switching menus
|
|
3097
|
+
// takes two clicks. Drive the slot from the trigger directly and
|
|
3098
|
+
// preventDefault so Radix's toggle stays out of it.
|
|
3099
|
+
const toggleCalendarMenu = (menu: "month" | "year") => {
|
|
3100
|
+
setOpenMenu((current) => (current === menu ? null : menu));
|
|
3101
|
+
};
|
|
3102
|
+
|
|
3035
3103
|
const handlePresetClick = (preset: DateRangePreset) => {
|
|
3036
|
-
const range = preset.getRange();
|
|
3104
|
+
const range = clampRange(preset.getRange(), effectiveMinDate, maxDate);
|
|
3105
|
+
if (!range) return;
|
|
3106
|
+
|
|
3037
3107
|
commitValue(range);
|
|
3038
3108
|
setOpen(false);
|
|
3109
|
+
triggerRef.current?.focus();
|
|
3039
3110
|
};
|
|
3040
3111
|
|
|
3041
3112
|
const handleDayClick = (day: Date) => {
|
|
@@ -3056,6 +3127,7 @@ const DateRangePicker = React.forwardRef<HTMLDivElement, DateRangePickerProps>(
|
|
|
3056
3127
|
setPendingEnd(false);
|
|
3057
3128
|
commitValue(nextValue);
|
|
3058
3129
|
setOpen(false);
|
|
3130
|
+
triggerRef.current?.focus();
|
|
3059
3131
|
};
|
|
3060
3132
|
|
|
3061
3133
|
const popover =
|
|
@@ -3087,23 +3159,34 @@ const DateRangePicker = React.forwardRef<HTMLDivElement, DateRangePickerProps>(
|
|
|
3087
3159
|
onWheel={(event) => event.stopPropagation()}
|
|
3088
3160
|
onTouchMove={(event) => event.stopPropagation()}
|
|
3089
3161
|
>
|
|
3090
|
-
<div className="flex flex-row">
|
|
3162
|
+
<div className="flex flex-col sm:flex-row">
|
|
3091
3163
|
{presets.length > 0 && (
|
|
3092
|
-
<div className="flex
|
|
3093
|
-
{presets.map((preset) =>
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3164
|
+
<div className="flex shrink-0 gap-0.5 border-solid border-semantic-border-layout p-3 max-sm:w-full max-sm:flex-row max-sm:overflow-x-auto max-sm:border-b sm:w-36 sm:flex-col sm:border-r">
|
|
3165
|
+
{presets.map((preset) => {
|
|
3166
|
+
const presetDisabled =
|
|
3167
|
+
clampRange(preset.getRange(), effectiveMinDate, maxDate) ===
|
|
3168
|
+
null;
|
|
3169
|
+
|
|
3170
|
+
return (
|
|
3171
|
+
<button
|
|
3172
|
+
key={preset.label}
|
|
3173
|
+
type="button"
|
|
3174
|
+
disabled={presetDisabled}
|
|
3175
|
+
className={cn(
|
|
3176
|
+
"shrink-0 whitespace-nowrap rounded px-2 py-2 text-left text-sm text-semantic-text-primary transition-colors hover:bg-semantic-bg-hover max-sm:border max-sm:border-solid max-sm:border-semantic-border-layout sm:w-full sm:py-1.5",
|
|
3177
|
+
presetDisabled &&
|
|
3178
|
+
"cursor-not-allowed opacity-40 hover:bg-transparent"
|
|
3179
|
+
)}
|
|
3180
|
+
onClick={() => handlePresetClick(preset)}
|
|
3181
|
+
>
|
|
3182
|
+
{preset.label}
|
|
3183
|
+
</button>
|
|
3184
|
+
);
|
|
3185
|
+
})}
|
|
3103
3186
|
</div>
|
|
3104
3187
|
)}
|
|
3105
3188
|
|
|
3106
|
-
<div className="min-w-
|
|
3189
|
+
<div className="min-w-0 flex-1 p-3 touch-pan-y sm:min-w-[272px]">
|
|
3107
3190
|
<div className="mb-3 flex items-center justify-between gap-2">
|
|
3108
3191
|
<button
|
|
3109
3192
|
type="button"
|
|
@@ -3120,10 +3203,25 @@ const DateRangePicker = React.forwardRef<HTMLDivElement, DateRangePickerProps>(
|
|
|
3120
3203
|
id={\`\${triggerId}-calendar-heading\`}
|
|
3121
3204
|
className="flex items-center gap-2"
|
|
3122
3205
|
>
|
|
3123
|
-
<DropdownMenu
|
|
3206
|
+
<DropdownMenu
|
|
3207
|
+
modal={false}
|
|
3208
|
+
open={openMenu === "month"}
|
|
3209
|
+
onOpenChange={(nextOpen) =>
|
|
3210
|
+
setOpenMenu((current) => {
|
|
3211
|
+
if (nextOpen) return "month";
|
|
3212
|
+
// Clicking the other trigger dismisses this menu
|
|
3213
|
+
// *after* the other one has opened \u2014 only clear the
|
|
3214
|
+
// slot if it is still ours.
|
|
3215
|
+
return current === "month" ? null : current;
|
|
3216
|
+
})
|
|
3217
|
+
}
|
|
3218
|
+
>
|
|
3124
3219
|
<DropdownMenuTrigger asChild>
|
|
3125
3220
|
<button
|
|
3126
3221
|
type="button"
|
|
3222
|
+
data-calendar-menu="month"
|
|
3223
|
+
onPointerDown={(event) => event.preventDefault()}
|
|
3224
|
+
onClick={() => toggleCalendarMenu("month")}
|
|
3127
3225
|
className="rounded border border-solid border-semantic-border-layout px-3 py-1.5 text-sm font-semibold text-semantic-text-primary transition-colors hover:bg-semantic-bg-hover"
|
|
3128
3226
|
>
|
|
3129
3227
|
{MONTH_LONG_NAMES[visibleMonth.getMonth()]}
|
|
@@ -3131,11 +3229,23 @@ const DateRangePicker = React.forwardRef<HTMLDivElement, DateRangePickerProps>(
|
|
|
3131
3229
|
</DropdownMenuTrigger>
|
|
3132
3230
|
<DropdownMenuContent
|
|
3133
3231
|
align="start"
|
|
3232
|
+
// Closing must not pull focus back to the trigger: the
|
|
3233
|
+
// sibling menu opening in the same click would then see
|
|
3234
|
+
// focus land outside itself and dismiss immediately.
|
|
3235
|
+
onCloseAutoFocus={(event) => event.preventDefault()}
|
|
3134
3236
|
className={cn(CALENDAR_DROPDOWN_Z_INDEX, "max-h-[240px] overflow-y-auto")}
|
|
3135
3237
|
>
|
|
3136
3238
|
{MONTH_LONG_NAMES.map((label, monthIndex) => (
|
|
3137
3239
|
<DropdownMenuItem
|
|
3138
3240
|
key={label}
|
|
3241
|
+
disabled={
|
|
3242
|
+
!isMonthSelectable(
|
|
3243
|
+
visibleMonth.getFullYear(),
|
|
3244
|
+
monthIndex,
|
|
3245
|
+
effectiveMinDate,
|
|
3246
|
+
maxDate
|
|
3247
|
+
)
|
|
3248
|
+
}
|
|
3139
3249
|
onSelect={() =>
|
|
3140
3250
|
setVisibleMonth(
|
|
3141
3251
|
startOfMonth(
|
|
@@ -3150,10 +3260,25 @@ const DateRangePicker = React.forwardRef<HTMLDivElement, DateRangePickerProps>(
|
|
|
3150
3260
|
</DropdownMenuContent>
|
|
3151
3261
|
</DropdownMenu>
|
|
3152
3262
|
|
|
3153
|
-
<DropdownMenu
|
|
3263
|
+
<DropdownMenu
|
|
3264
|
+
modal={false}
|
|
3265
|
+
open={openMenu === "year"}
|
|
3266
|
+
onOpenChange={(nextOpen) =>
|
|
3267
|
+
setOpenMenu((current) => {
|
|
3268
|
+
if (nextOpen) return "year";
|
|
3269
|
+
// Clicking the other trigger dismisses this menu
|
|
3270
|
+
// *after* the other one has opened \u2014 only clear the
|
|
3271
|
+
// slot if it is still ours.
|
|
3272
|
+
return current === "year" ? null : current;
|
|
3273
|
+
})
|
|
3274
|
+
}
|
|
3275
|
+
>
|
|
3154
3276
|
<DropdownMenuTrigger asChild>
|
|
3155
3277
|
<button
|
|
3156
3278
|
type="button"
|
|
3279
|
+
data-calendar-menu="year"
|
|
3280
|
+
onPointerDown={(event) => event.preventDefault()}
|
|
3281
|
+
onClick={() => toggleCalendarMenu("year")}
|
|
3157
3282
|
className="flex items-center gap-1 rounded border border-solid border-semantic-border-layout px-3 py-1.5 text-sm font-semibold text-semantic-text-primary transition-colors hover:bg-semantic-bg-hover"
|
|
3158
3283
|
>
|
|
3159
3284
|
{visibleMonth.getFullYear()}
|
|
@@ -3165,12 +3290,13 @@ const DateRangePicker = React.forwardRef<HTMLDivElement, DateRangePickerProps>(
|
|
|
3165
3290
|
</DropdownMenuTrigger>
|
|
3166
3291
|
<DropdownMenuContent
|
|
3167
3292
|
align="start"
|
|
3293
|
+
// Closing must not pull focus back to the trigger: the
|
|
3294
|
+
// sibling menu opening in the same click would then see
|
|
3295
|
+
// focus land outside itself and dismiss immediately.
|
|
3296
|
+
onCloseAutoFocus={(event) => event.preventDefault()}
|
|
3168
3297
|
className={cn(CALENDAR_DROPDOWN_Z_INDEX, "max-h-[240px] overflow-y-auto")}
|
|
3169
3298
|
>
|
|
3170
|
-
{
|
|
3171
|
-
{ length: YEAR_OPTIONS_SPAN * 2 + 1 },
|
|
3172
|
-
(_, index) => visibleMonth.getFullYear() - YEAR_OPTIONS_SPAN + index
|
|
3173
|
-
).map((year) => (
|
|
3299
|
+
{yearOptions.map((year) => (
|
|
3174
3300
|
<DropdownMenuItem
|
|
3175
3301
|
key={year}
|
|
3176
3302
|
onSelect={() =>
|
|
@@ -3198,11 +3324,11 @@ const DateRangePicker = React.forwardRef<HTMLDivElement, DateRangePickerProps>(
|
|
|
3198
3324
|
</button>
|
|
3199
3325
|
</div>
|
|
3200
3326
|
|
|
3201
|
-
<div className="grid grid-cols-7">
|
|
3327
|
+
<div className="grid w-full grid-cols-7">
|
|
3202
3328
|
{weekDays.map((day) => (
|
|
3203
3329
|
<div
|
|
3204
3330
|
key={day}
|
|
3205
|
-
className="flex h-
|
|
3331
|
+
className="flex h-9 items-center justify-center text-xs font-medium text-semantic-text-muted sm:h-8"
|
|
3206
3332
|
>
|
|
3207
3333
|
{day}
|
|
3208
3334
|
</div>
|
|
@@ -3238,7 +3364,7 @@ const DateRangePicker = React.forwardRef<HTMLDivElement, DateRangePickerProps>(
|
|
|
3238
3364
|
<div
|
|
3239
3365
|
key={day.toISOString()}
|
|
3240
3366
|
className={cn(
|
|
3241
|
-
"relative flex h-
|
|
3367
|
+
"relative flex h-9 items-center justify-center sm:h-8",
|
|
3242
3368
|
isInBand && "bg-semantic-info-surface",
|
|
3243
3369
|
isRangeStart && hasRange && "rounded-l-full",
|
|
3244
3370
|
isRangeEnd && hasRange && "rounded-r-full"
|
|
@@ -3251,7 +3377,7 @@ const DateRangePicker = React.forwardRef<HTMLDivElement, DateRangePickerProps>(
|
|
|
3251
3377
|
aria-current={isToday ? "date" : undefined}
|
|
3252
3378
|
disabled={!!isDisabled}
|
|
3253
3379
|
className={cn(
|
|
3254
|
-
"relative flex
|
|
3380
|
+
"relative flex h-9 w-full max-w-9 items-center justify-center rounded-full text-xs transition-colors sm:h-8 sm:max-w-8",
|
|
3255
3381
|
isSelectedEdge
|
|
3256
3382
|
? "bg-semantic-primary text-semantic-text-inverted font-semibold"
|
|
3257
3383
|
: isCurrentMonth
|
|
@@ -3347,12 +3473,23 @@ import {
|
|
|
3347
3473
|
type Strategy,
|
|
3348
3474
|
} from "@floating-ui/react-dom";
|
|
3349
3475
|
import { cva, type VariantProps } from "class-variance-authority";
|
|
3350
|
-
import {
|
|
3476
|
+
import {
|
|
3477
|
+
ChevronDown,
|
|
3478
|
+
ChevronLeft,
|
|
3479
|
+
ChevronRight,
|
|
3480
|
+
Clock2,
|
|
3481
|
+
X,
|
|
3482
|
+
} from "lucide-react";
|
|
3351
3483
|
|
|
3352
3484
|
import { cn } from "@/lib/utils";
|
|
3353
3485
|
|
|
3354
3486
|
const DEFAULT_START_TIME = "10:30:00";
|
|
3355
|
-
|
|
3487
|
+
/**
|
|
3488
|
+
* What the time columns show while no time is selected. Clearing the value
|
|
3489
|
+
* returns the picker to this state, so an unset time always reads 12:00 AM
|
|
3490
|
+
* rather than re-proposing the sample default.
|
|
3491
|
+
*/
|
|
3492
|
+
const UNSET_TIME = "00:00:00";
|
|
3356
3493
|
const DEFAULT_MINUTE_STEP = 5;
|
|
3357
3494
|
const DEFAULT_SECOND_STEP = 5;
|
|
3358
3495
|
const TIME_COLUMN_MAX_HEIGHT = 168;
|
|
@@ -3427,8 +3564,10 @@ const dateTimePickerTriggerVariants = cva(
|
|
|
3427
3564
|
|
|
3428
3565
|
export interface DateTimePickerValue {
|
|
3429
3566
|
date?: Date;
|
|
3430
|
-
|
|
3431
|
-
|
|
3567
|
+
/** Undefined until a time is explicitly selected */
|
|
3568
|
+
startTime?: string;
|
|
3569
|
+
/** Undefined until a time is explicitly selected */
|
|
3570
|
+
endTime?: string;
|
|
3432
3571
|
}
|
|
3433
3572
|
|
|
3434
3573
|
export interface DateTimePickerProps
|
|
@@ -3482,8 +3621,8 @@ function normalizeValue(
|
|
|
3482
3621
|
): DateTimePickerValue {
|
|
3483
3622
|
return {
|
|
3484
3623
|
date: value?.date,
|
|
3485
|
-
startTime: value?.startTime
|
|
3486
|
-
endTime: value?.endTime
|
|
3624
|
+
startTime: value?.startTime,
|
|
3625
|
+
endTime: value?.endTime,
|
|
3487
3626
|
};
|
|
3488
3627
|
}
|
|
3489
3628
|
|
|
@@ -3760,7 +3899,6 @@ function formatValueForDisplay(
|
|
|
3760
3899
|
value: DateTimePickerValue,
|
|
3761
3900
|
variant: DateTimePickerVariant,
|
|
3762
3901
|
showEndTime: boolean,
|
|
3763
|
-
hasTimeValue: boolean,
|
|
3764
3902
|
showSeconds: boolean
|
|
3765
3903
|
) {
|
|
3766
3904
|
if (variant === "date-only") {
|
|
@@ -3768,14 +3906,21 @@ function formatValueForDisplay(
|
|
|
3768
3906
|
}
|
|
3769
3907
|
|
|
3770
3908
|
if (variant === "time-only") {
|
|
3771
|
-
if (!
|
|
3909
|
+
if (!value.startTime && !value.endTime) return "";
|
|
3772
3910
|
|
|
3773
3911
|
return showEndTime
|
|
3774
|
-
? \`\${formatTimeForDisplay(value.startTime, showSeconds)} - \${formatTimeForDisplay(value.endTime, showSeconds)}\`
|
|
3775
|
-
: formatTimeForDisplay(value.startTime, showSeconds);
|
|
3912
|
+
? \`\${formatTimeForDisplay(value.startTime ?? UNSET_TIME, showSeconds)} - \${formatTimeForDisplay(value.endTime ?? UNSET_TIME, showSeconds)}\`
|
|
3913
|
+
: formatTimeForDisplay(value.startTime ?? UNSET_TIME, showSeconds);
|
|
3776
3914
|
}
|
|
3777
3915
|
|
|
3778
|
-
|
|
3916
|
+
const datePart = formatDateOnlyForDisplay(value.date);
|
|
3917
|
+
const timePart = value.startTime
|
|
3918
|
+
? formatTimeForDisplay(value.startTime, showSeconds)
|
|
3919
|
+
: "";
|
|
3920
|
+
|
|
3921
|
+
if (!datePart && !timePart) return "";
|
|
3922
|
+
|
|
3923
|
+
return [datePart, timePart].filter(Boolean).join(" ");
|
|
3779
3924
|
}
|
|
3780
3925
|
|
|
3781
3926
|
function getDefaultPlaceholder(
|
|
@@ -3962,10 +4107,7 @@ function splitTypedDateInput(value: string) {
|
|
|
3962
4107
|
dateSource.split(/[/-]/);
|
|
3963
4108
|
const dayResult = consumeDigits(dayPart, 2);
|
|
3964
4109
|
const monthResult = consumeDigits(\`\${dayResult.rest}\${monthPart}\`, 2);
|
|
3965
|
-
const yearResult = consumeDigits(
|
|
3966
|
-
\`\${monthResult.rest}\${yearPart}\`,
|
|
3967
|
-
4
|
|
3968
|
-
);
|
|
4110
|
+
const yearResult = consumeDigits(\`\${monthResult.rest}\${yearPart}\`, 4);
|
|
3969
4111
|
const day = dayResult.digits;
|
|
3970
4112
|
const month = monthResult.digits;
|
|
3971
4113
|
const year = yearResult.digits;
|
|
@@ -4003,7 +4145,10 @@ function splitTypedDateInput(value: string) {
|
|
|
4003
4145
|
};
|
|
4004
4146
|
}
|
|
4005
4147
|
|
|
4006
|
-
function isPotentiallyValidTimeDigits(
|
|
4148
|
+
function isPotentiallyValidTimeDigits(
|
|
4149
|
+
timeDigits: string,
|
|
4150
|
+
showSeconds: boolean
|
|
4151
|
+
) {
|
|
4007
4152
|
const hourValue = timeDigits.slice(0, 2);
|
|
4008
4153
|
const minuteValue = timeDigits.slice(2, 4);
|
|
4009
4154
|
const secondValue = showSeconds ? timeDigits.slice(4, 6) : "";
|
|
@@ -4037,7 +4182,10 @@ function formatTimeInput(restValue: string, showSeconds: boolean) {
|
|
|
4037
4182
|
const meridiem = formatMeridiemInput(meridiemLetters.slice(0, 2));
|
|
4038
4183
|
|
|
4039
4184
|
if (!timeDigits && !meridiem) return "";
|
|
4040
|
-
if (
|
|
4185
|
+
if (
|
|
4186
|
+
!isPotentiallyValidTimeDigits(timeDigits, showSeconds) ||
|
|
4187
|
+
meridiem === null
|
|
4188
|
+
) {
|
|
4041
4189
|
return null;
|
|
4042
4190
|
}
|
|
4043
4191
|
|
|
@@ -4057,7 +4205,8 @@ function sanitizeTypedDateInput(value: string, previousValue: string) {
|
|
|
4057
4205
|
if (/^[A-Za-z]/.test(trimmedValue)) return previousValue;
|
|
4058
4206
|
|
|
4059
4207
|
const normalizedValue = value.toUpperCase().replace(/[^0-9\\s/-]/g, "");
|
|
4060
|
-
const { dateDigits, dateValue, isValid } =
|
|
4208
|
+
const { dateDigits, dateValue, isValid } =
|
|
4209
|
+
splitTypedDateInput(normalizedValue);
|
|
4061
4210
|
const limitedDateDigits = dateDigits.slice(0, 8);
|
|
4062
4211
|
|
|
4063
4212
|
if (!limitedDateDigits) return "";
|
|
@@ -4091,9 +4240,7 @@ function sanitizeTypedDateTimeInput(
|
|
|
4091
4240
|
const trimmedValue = value.trimStart();
|
|
4092
4241
|
if (/^[A-Za-z]/.test(trimmedValue)) return previousValue;
|
|
4093
4242
|
|
|
4094
|
-
const normalizedValue = value
|
|
4095
|
-
.toUpperCase()
|
|
4096
|
-
.replace(/[^0-9\\s/:APM-]/g, "");
|
|
4243
|
+
const normalizedValue = value.toUpperCase().replace(/[^0-9\\s/:APM-]/g, "");
|
|
4097
4244
|
const { dateDigits, dateValue, isComplete, isValid, restValue } =
|
|
4098
4245
|
splitTypedDateInput(normalizedValue);
|
|
4099
4246
|
const limitedDateDigits = dateDigits.slice(0, 8);
|
|
@@ -4101,7 +4248,9 @@ function sanitizeTypedDateTimeInput(
|
|
|
4101
4248
|
if (!limitedDateDigits) return "";
|
|
4102
4249
|
if (!isValid) return previousValue;
|
|
4103
4250
|
|
|
4104
|
-
const formattedTime = isComplete
|
|
4251
|
+
const formattedTime = isComplete
|
|
4252
|
+
? formatTimeInput(restValue, showSeconds)
|
|
4253
|
+
: "";
|
|
4105
4254
|
if (formattedTime === null) return previousValue;
|
|
4106
4255
|
|
|
4107
4256
|
return [dateValue, formattedTime].filter(Boolean).join(" ");
|
|
@@ -4177,7 +4326,11 @@ function stepDateTimeInputValue(
|
|
|
4177
4326
|
const [hourValue = "0", minuteValue = "0", secondValue = "00"] = (
|
|
4178
4327
|
typedDateTime.startTime ?? fallbackTime
|
|
4179
4328
|
).split(":");
|
|
4180
|
-
nextDate.setHours(
|
|
4329
|
+
nextDate.setHours(
|
|
4330
|
+
Number(hourValue),
|
|
4331
|
+
Number(minuteValue),
|
|
4332
|
+
Number(secondValue)
|
|
4333
|
+
);
|
|
4181
4334
|
|
|
4182
4335
|
if (segment === "day") {
|
|
4183
4336
|
nextDate.setDate(nextDate.getDate() + direction);
|
|
@@ -4221,10 +4374,7 @@ function stepDateTimeInputValue(
|
|
|
4221
4374
|
.padStart(2, "0")}:\${nextDate
|
|
4222
4375
|
.getMinutes()
|
|
4223
4376
|
.toString()
|
|
4224
|
-
.padStart(2, "0")}:\${nextDate
|
|
4225
|
-
.getSeconds()
|
|
4226
|
-
.toString()
|
|
4227
|
-
.padStart(2, "0")}\`;
|
|
4377
|
+
.padStart(2, "0")}:\${nextDate.getSeconds().toString().padStart(2, "0")}\`;
|
|
4228
4378
|
|
|
4229
4379
|
return {
|
|
4230
4380
|
date: startOfDay(nextDate),
|
|
@@ -4307,13 +4457,15 @@ function parseTypedDate(value: string) {
|
|
|
4307
4457
|
function formatHiddenValue(
|
|
4308
4458
|
value: DateTimePickerValue,
|
|
4309
4459
|
variant: DateTimePickerVariant,
|
|
4310
|
-
showEndTime: boolean
|
|
4311
|
-
hasTimeValue: boolean
|
|
4460
|
+
showEndTime: boolean
|
|
4312
4461
|
) {
|
|
4462
|
+
const startTime = value.startTime ?? UNSET_TIME;
|
|
4463
|
+
const endTime = value.endTime ?? UNSET_TIME;
|
|
4464
|
+
|
|
4313
4465
|
if (variant === "time-only") {
|
|
4314
|
-
if (!
|
|
4466
|
+
if (!value.startTime && !value.endTime) return "";
|
|
4315
4467
|
|
|
4316
|
-
return showEndTime ? \`\${
|
|
4468
|
+
return showEndTime ? \`\${startTime}/\${endTime}\` : startTime;
|
|
4317
4469
|
}
|
|
4318
4470
|
|
|
4319
4471
|
if (!value.date) return "";
|
|
@@ -4330,6 +4482,8 @@ function formatHiddenValue(
|
|
|
4330
4482
|
const day = value.date.getDate().toString().padStart(2, "0");
|
|
4331
4483
|
const year = value.date.getFullYear();
|
|
4332
4484
|
|
|
4485
|
+
if (!value.startTime) return \`\${year}-\${month}-\${day}\`;
|
|
4486
|
+
|
|
4333
4487
|
return \`\${year}-\${month}-\${day}T\${value.startTime}\`;
|
|
4334
4488
|
}
|
|
4335
4489
|
|
|
@@ -4353,6 +4507,26 @@ function FigmaCalendarIcon({ className }: { className?: string }) {
|
|
|
4353
4507
|
);
|
|
4354
4508
|
}
|
|
4355
4509
|
|
|
4510
|
+
function FigmaClockIcon({ className }: { className?: string }) {
|
|
4511
|
+
return (
|
|
4512
|
+
<svg
|
|
4513
|
+
viewBox="0 0 18 18"
|
|
4514
|
+
fill="none"
|
|
4515
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
4516
|
+
className={className}
|
|
4517
|
+
aria-hidden="true"
|
|
4518
|
+
>
|
|
4519
|
+
<path
|
|
4520
|
+
d="M9 4.5V9L11.25 11.25M15.75 9C15.75 12.7279 12.7279 15.75 9 15.75C5.27208 15.75 2.25 12.7279 2.25 9C2.25 5.27208 5.27208 2.25 9 2.25C12.7279 2.25 15.75 5.27208 15.75 9Z"
|
|
4521
|
+
stroke="currentColor"
|
|
4522
|
+
strokeWidth="1.5"
|
|
4523
|
+
strokeLinecap="round"
|
|
4524
|
+
strokeLinejoin="round"
|
|
4525
|
+
/>
|
|
4526
|
+
</svg>
|
|
4527
|
+
);
|
|
4528
|
+
}
|
|
4529
|
+
|
|
4356
4530
|
function CalendarDropdown({
|
|
4357
4531
|
id,
|
|
4358
4532
|
label,
|
|
@@ -4649,7 +4823,9 @@ function TimeField({
|
|
|
4649
4823
|
ariaLabel={\`\${label} hours\`}
|
|
4650
4824
|
options={hourOptions}
|
|
4651
4825
|
onSelect={(key) =>
|
|
4652
|
-
onChange(
|
|
4826
|
+
onChange(
|
|
4827
|
+
composeTime(Number(key), minute, effectiveSecond, meridiem)
|
|
4828
|
+
)
|
|
4653
4829
|
}
|
|
4654
4830
|
/>
|
|
4655
4831
|
<TimeColumn
|
|
@@ -4657,7 +4833,9 @@ function TimeField({
|
|
|
4657
4833
|
ariaLabel={\`\${label} minutes\`}
|
|
4658
4834
|
options={minuteOptions}
|
|
4659
4835
|
onSelect={(key) =>
|
|
4660
|
-
onChange(
|
|
4836
|
+
onChange(
|
|
4837
|
+
composeTime(hour12, Number(key), effectiveSecond, meridiem)
|
|
4838
|
+
)
|
|
4661
4839
|
}
|
|
4662
4840
|
/>
|
|
4663
4841
|
{showSeconds && (
|
|
@@ -4735,22 +4913,19 @@ const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
|
4735
4913
|
const [internalValue, setInternalValue] = React.useState(() =>
|
|
4736
4914
|
normalizeValue(defaultValue)
|
|
4737
4915
|
);
|
|
4738
|
-
const [internalHasTimeValue, setInternalHasTimeValue] = React.useState(() =>
|
|
4739
|
-
Boolean(defaultValue?.date || defaultValue?.startTime || defaultValue?.endTime)
|
|
4740
|
-
);
|
|
4741
4916
|
const [internalOpen, setInternalOpen] = React.useState(defaultOpen);
|
|
4742
4917
|
const currentValue = normalizeValue(
|
|
4743
4918
|
isValueControlled ? value : internalValue
|
|
4744
4919
|
);
|
|
4745
|
-
const
|
|
4746
|
-
|
|
4747
|
-
: internalHasTimeValue;
|
|
4920
|
+
const resolvedStartTime = currentValue.startTime ?? UNSET_TIME;
|
|
4921
|
+
const resolvedEndTime = currentValue.endTime ?? UNSET_TIME;
|
|
4748
4922
|
const resolvedShowSeconds =
|
|
4749
4923
|
showSeconds ??
|
|
4750
4924
|
(timeHasVisibleSeconds(currentValue.startTime) ||
|
|
4751
4925
|
(resolvedShowEndTime && timeHasVisibleSeconds(currentValue.endTime)));
|
|
4752
4926
|
const placeholder =
|
|
4753
|
-
placeholderProp ??
|
|
4927
|
+
placeholderProp ??
|
|
4928
|
+
getDefaultPlaceholder(pickerVariant, resolvedShowSeconds);
|
|
4754
4929
|
const open = isOpenControlled ? controlledOpen : internalOpen;
|
|
4755
4930
|
const [visibleMonth, setVisibleMonth] = React.useState(() =>
|
|
4756
4931
|
startOfMonth(currentValue.date ?? new Date())
|
|
@@ -4760,7 +4935,6 @@ const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
|
4760
4935
|
currentValue,
|
|
4761
4936
|
pickerVariant,
|
|
4762
4937
|
resolvedShowEndTime,
|
|
4763
|
-
hasTimeValue,
|
|
4764
4938
|
resolvedShowSeconds
|
|
4765
4939
|
)
|
|
4766
4940
|
);
|
|
@@ -4792,7 +4966,10 @@ const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
|
4792
4966
|
const maxWidth = Math.min(MAX_POPOVER_WIDTH, availableWidth);
|
|
4793
4967
|
const width = Math.max(
|
|
4794
4968
|
1,
|
|
4795
|
-
Math.min(
|
|
4969
|
+
Math.min(
|
|
4970
|
+
Math.max(rects.reference.width, MIN_POPOVER_WIDTH),
|
|
4971
|
+
maxWidth
|
|
4972
|
+
)
|
|
4796
4973
|
);
|
|
4797
4974
|
elements.floating.style.setProperty(
|
|
4798
4975
|
POPOVER_SCROLL_HEIGHT_VAR,
|
|
@@ -4824,7 +5001,6 @@ const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
|
4824
5001
|
currentValue,
|
|
4825
5002
|
pickerVariant,
|
|
4826
5003
|
resolvedShowEndTime,
|
|
4827
|
-
hasTimeValue,
|
|
4828
5004
|
resolvedShowSeconds
|
|
4829
5005
|
);
|
|
4830
5006
|
const effectiveMinDate = React.useMemo(() => {
|
|
@@ -4915,15 +5091,9 @@ const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
|
4915
5091
|
}, [open, setOpen]);
|
|
4916
5092
|
|
|
4917
5093
|
const updateValue = React.useCallback(
|
|
4918
|
-
(
|
|
4919
|
-
nextValue: DateTimePickerValue,
|
|
4920
|
-
options?: { hasTimeValue?: boolean }
|
|
4921
|
-
) => {
|
|
5094
|
+
(nextValue: DateTimePickerValue) => {
|
|
4922
5095
|
if (!isValueControlled) {
|
|
4923
5096
|
setInternalValue(nextValue);
|
|
4924
|
-
if (options?.hasTimeValue !== undefined) {
|
|
4925
|
-
setInternalHasTimeValue(options.hasTimeValue);
|
|
4926
|
-
}
|
|
4927
5097
|
}
|
|
4928
5098
|
|
|
4929
5099
|
onValueChange?.(nextValue);
|
|
@@ -4936,11 +5106,14 @@ const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
|
4936
5106
|
if (readOnly) return;
|
|
4937
5107
|
|
|
4938
5108
|
setDateInputValue("");
|
|
5109
|
+
setOpenTimeField(null);
|
|
5110
|
+
setOpenCalendarDropdown(null);
|
|
5111
|
+
setVisibleMonth(startOfMonth(new Date()));
|
|
4939
5112
|
updateValue({
|
|
4940
5113
|
date: undefined,
|
|
4941
|
-
startTime:
|
|
4942
|
-
endTime:
|
|
4943
|
-
}
|
|
5114
|
+
startTime: undefined,
|
|
5115
|
+
endTime: undefined,
|
|
5116
|
+
});
|
|
4944
5117
|
};
|
|
4945
5118
|
|
|
4946
5119
|
const yearOptions = React.useMemo(
|
|
@@ -4999,13 +5172,7 @@ const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
|
4999
5172
|
updateValue({ ...currentValue, date: nextSelectedDate });
|
|
5000
5173
|
}
|
|
5001
5174
|
},
|
|
5002
|
-
[
|
|
5003
|
-
currentValue,
|
|
5004
|
-
effectiveMinDate,
|
|
5005
|
-
maxDate,
|
|
5006
|
-
pickerVariant,
|
|
5007
|
-
updateValue,
|
|
5008
|
-
]
|
|
5175
|
+
[currentValue, effectiveMinDate, maxDate, pickerVariant, updateValue]
|
|
5009
5176
|
);
|
|
5010
5177
|
|
|
5011
5178
|
const handleTypedDateChange = (
|
|
@@ -5029,18 +5196,12 @@ const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
|
5029
5196
|
|
|
5030
5197
|
const typedTime = parseTimePart(nextInputValue);
|
|
5031
5198
|
if (typedTime === undefined) {
|
|
5032
|
-
updateValue({ ...currentValue,
|
|
5199
|
+
updateValue({ ...currentValue, startTime: undefined });
|
|
5033
5200
|
return;
|
|
5034
5201
|
}
|
|
5035
5202
|
|
|
5036
5203
|
if (typedTime) {
|
|
5037
|
-
updateValue(
|
|
5038
|
-
{
|
|
5039
|
-
...currentValue,
|
|
5040
|
-
startTime: typedTime,
|
|
5041
|
-
},
|
|
5042
|
-
{ hasTimeValue: true }
|
|
5043
|
-
);
|
|
5204
|
+
updateValue({ ...currentValue, startTime: typedTime });
|
|
5044
5205
|
}
|
|
5045
5206
|
|
|
5046
5207
|
return;
|
|
@@ -5130,7 +5291,7 @@ const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
|
5130
5291
|
dateInputValue,
|
|
5131
5292
|
cursorPosition,
|
|
5132
5293
|
direction,
|
|
5133
|
-
|
|
5294
|
+
resolvedStartTime,
|
|
5134
5295
|
resolvedShowSeconds
|
|
5135
5296
|
);
|
|
5136
5297
|
|
|
@@ -5182,7 +5343,6 @@ const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
|
5182
5343
|
currentValue,
|
|
5183
5344
|
pickerVariant,
|
|
5184
5345
|
resolvedShowEndTime,
|
|
5185
|
-
hasTimeValue,
|
|
5186
5346
|
resolvedShowSeconds
|
|
5187
5347
|
)
|
|
5188
5348
|
);
|
|
@@ -5198,7 +5358,9 @@ const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
|
5198
5358
|
ref={setPopoverRef}
|
|
5199
5359
|
role="dialog"
|
|
5200
5360
|
aria-modal="false"
|
|
5201
|
-
aria-labelledby={
|
|
5361
|
+
aria-labelledby={
|
|
5362
|
+
showCalendar ? \`\${triggerId}-calendar-heading\` : undefined
|
|
5363
|
+
}
|
|
5202
5364
|
aria-label={showCalendar ? undefined : "Time picker"}
|
|
5203
5365
|
className={cn(
|
|
5204
5366
|
"rounded-lg border border-solid border-semantic-border-layout bg-semantic-bg-primary shadow-lg flex flex-col min-h-0 overflow-y-auto overflow-x-hidden overscroll-contain pointer-events-auto",
|
|
@@ -5288,11 +5450,7 @@ const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
|
5288
5450
|
}))}
|
|
5289
5451
|
onValueChange={(nextYear) => {
|
|
5290
5452
|
syncCalendarMonthAndValue(
|
|
5291
|
-
new Date(
|
|
5292
|
-
Number(nextYear),
|
|
5293
|
-
visibleMonth.getMonth(),
|
|
5294
|
-
1
|
|
5295
|
-
)
|
|
5453
|
+
new Date(Number(nextYear), visibleMonth.getMonth(), 1)
|
|
5296
5454
|
);
|
|
5297
5455
|
}}
|
|
5298
5456
|
/>
|
|
@@ -5384,7 +5542,7 @@ const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
|
5384
5542
|
<TimeField
|
|
5385
5543
|
id={\`\${triggerId}-start-time\`}
|
|
5386
5544
|
label={startTimeLabel}
|
|
5387
|
-
value={
|
|
5545
|
+
value={resolvedStartTime}
|
|
5388
5546
|
showSeconds={resolvedShowSeconds}
|
|
5389
5547
|
minuteStep={minuteStep}
|
|
5390
5548
|
secondStep={secondStep}
|
|
@@ -5395,10 +5553,7 @@ const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
|
5395
5553
|
setOpenTimeField(nextOpen ? "start" : null)
|
|
5396
5554
|
}
|
|
5397
5555
|
onChange={(startTime) =>
|
|
5398
|
-
updateValue(
|
|
5399
|
-
{ ...currentValue, startTime },
|
|
5400
|
-
{ hasTimeValue: true }
|
|
5401
|
-
)
|
|
5556
|
+
updateValue({ ...currentValue, startTime })
|
|
5402
5557
|
}
|
|
5403
5558
|
/>
|
|
5404
5559
|
|
|
@@ -5406,7 +5561,7 @@ const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
|
5406
5561
|
<TimeField
|
|
5407
5562
|
id={\`\${triggerId}-end-time\`}
|
|
5408
5563
|
label={endTimeLabel}
|
|
5409
|
-
value={
|
|
5564
|
+
value={resolvedEndTime}
|
|
5410
5565
|
showSeconds={resolvedShowSeconds}
|
|
5411
5566
|
minuteStep={minuteStep}
|
|
5412
5567
|
secondStep={secondStep}
|
|
@@ -5417,15 +5572,13 @@ const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
|
5417
5572
|
setOpenTimeField(nextOpen ? "end" : null)
|
|
5418
5573
|
}
|
|
5419
5574
|
onChange={(endTime) =>
|
|
5420
|
-
updateValue(
|
|
5421
|
-
{ ...currentValue, endTime },
|
|
5422
|
-
{ hasTimeValue: true }
|
|
5423
|
-
)
|
|
5575
|
+
updateValue({ ...currentValue, endTime })
|
|
5424
5576
|
}
|
|
5425
5577
|
/>
|
|
5426
5578
|
)}
|
|
5427
5579
|
</div>
|
|
5428
5580
|
)}
|
|
5581
|
+
|
|
5429
5582
|
</div>,
|
|
5430
5583
|
portalMount
|
|
5431
5584
|
);
|
|
@@ -5452,8 +5605,7 @@ const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
|
5452
5605
|
value={formatHiddenValue(
|
|
5453
5606
|
currentValue,
|
|
5454
5607
|
pickerVariant,
|
|
5455
|
-
resolvedShowEndTime
|
|
5456
|
-
hasTimeValue
|
|
5608
|
+
resolvedShowEndTime
|
|
5457
5609
|
)}
|
|
5458
5610
|
/>
|
|
5459
5611
|
)}
|
|
@@ -5509,16 +5661,19 @@ const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
|
5509
5661
|
onKeyDown={handleTypedDateKeyDown}
|
|
5510
5662
|
onBlur={handleTypedDateBlur}
|
|
5511
5663
|
/>
|
|
5512
|
-
{showClear &&
|
|
5513
|
-
|
|
5514
|
-
|
|
5515
|
-
|
|
5516
|
-
|
|
5517
|
-
|
|
5518
|
-
|
|
5519
|
-
|
|
5520
|
-
|
|
5521
|
-
|
|
5664
|
+
{showClear &&
|
|
5665
|
+
(displayValue || dateInputValue) &&
|
|
5666
|
+
!disabled &&
|
|
5667
|
+
!readOnly && (
|
|
5668
|
+
<button
|
|
5669
|
+
type="button"
|
|
5670
|
+
aria-label="Clear date"
|
|
5671
|
+
className="inline-flex size-5 items-center justify-center rounded text-semantic-text-muted hover:bg-semantic-bg-hover hover:text-semantic-text-primary"
|
|
5672
|
+
onClick={clearValue}
|
|
5673
|
+
>
|
|
5674
|
+
<X className="size-4" aria-hidden="true" />
|
|
5675
|
+
</button>
|
|
5676
|
+
)}
|
|
5522
5677
|
<button
|
|
5523
5678
|
type="button"
|
|
5524
5679
|
disabled={disabled || readOnly}
|
|
@@ -5526,9 +5681,15 @@ const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
|
5526
5681
|
className="inline-flex shrink-0 items-center justify-center rounded text-semantic-text-muted hover:bg-semantic-bg-hover hover:text-semantic-text-primary disabled:cursor-not-allowed"
|
|
5527
5682
|
onClick={() => setOpen(!open)}
|
|
5528
5683
|
>
|
|
5529
|
-
|
|
5530
|
-
|
|
5531
|
-
|
|
5684
|
+
{showCalendar ? (
|
|
5685
|
+
<FigmaCalendarIcon
|
|
5686
|
+
className={cn(size === "sm" ? "size-4" : "size-[18px]")}
|
|
5687
|
+
/>
|
|
5688
|
+
) : (
|
|
5689
|
+
<FigmaClockIcon
|
|
5690
|
+
className={cn(size === "sm" ? "size-4" : "size-[18px]")}
|
|
5691
|
+
/>
|
|
5692
|
+
)}
|
|
5532
5693
|
</button>
|
|
5533
5694
|
</div>
|
|
5534
5695
|
|
package/package.json
CHANGED