myoperator-mcp 0.2.305 → 0.2.307
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 +772 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2503,6 +2503,681 @@ const DateDivider = React.forwardRef(
|
|
|
2503
2503
|
DateDivider.displayName = "DateDivider";
|
|
2504
2504
|
|
|
2505
2505
|
export { DateDivider };
|
|
2506
|
+
`,
|
|
2507
|
+
"date-time-picker": `import * as React from "react";
|
|
2508
|
+
import { createPortal } from "react-dom";
|
|
2509
|
+
import {
|
|
2510
|
+
autoUpdate,
|
|
2511
|
+
flip,
|
|
2512
|
+
offset,
|
|
2513
|
+
shift,
|
|
2514
|
+
size as floatingSize,
|
|
2515
|
+
useFloating,
|
|
2516
|
+
type Placement,
|
|
2517
|
+
type Strategy,
|
|
2518
|
+
} from "@floating-ui/react-dom";
|
|
2519
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
2520
|
+
import {
|
|
2521
|
+
ChevronLeft,
|
|
2522
|
+
ChevronRight,
|
|
2523
|
+
Clock2,
|
|
2524
|
+
X,
|
|
2525
|
+
} from "lucide-react";
|
|
2526
|
+
|
|
2527
|
+
import { cn } from "@/lib/utils";
|
|
2528
|
+
|
|
2529
|
+
const DEFAULT_START_TIME = "10:30:00";
|
|
2530
|
+
const DEFAULT_END_TIME = "12:30:00";
|
|
2531
|
+
const DEFAULT_PLACEHOLDER = "--/--/-- -- : --";
|
|
2532
|
+
const POPOVER_WIDTH = 336;
|
|
2533
|
+
const POPOVER_MARGIN = 8;
|
|
2534
|
+
const POPOVER_GAP = 4;
|
|
2535
|
+
const MAX_POPOVER_HEIGHT = 420;
|
|
2536
|
+
const POPOVER_SCROLL_HEIGHT_VAR = "--date-time-picker-scroll-height";
|
|
2537
|
+
const POPOVER_WIDTH_VAR = "--date-time-picker-popover-width";
|
|
2538
|
+
const CALENDAR_PLACEMENT: Placement = "bottom-start";
|
|
2539
|
+
|
|
2540
|
+
const weekDays = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
2541
|
+
const monthFormatter = new Intl.DateTimeFormat("en-US", {
|
|
2542
|
+
month: "long",
|
|
2543
|
+
year: "numeric",
|
|
2544
|
+
});
|
|
2545
|
+
|
|
2546
|
+
const dateTimePickerVariants = cva("relative inline-block w-full max-w-full", {
|
|
2547
|
+
variants: {
|
|
2548
|
+
size: {
|
|
2549
|
+
sm: "sm:w-[280px]",
|
|
2550
|
+
default: "sm:w-[336px]",
|
|
2551
|
+
lg: "sm:w-[360px]",
|
|
2552
|
+
},
|
|
2553
|
+
},
|
|
2554
|
+
defaultVariants: {
|
|
2555
|
+
size: "default",
|
|
2556
|
+
},
|
|
2557
|
+
});
|
|
2558
|
+
|
|
2559
|
+
const dateTimePickerTriggerVariants = cva(
|
|
2560
|
+
"flex w-full items-center justify-between border border-solid border-semantic-border-input bg-semantic-bg-primary text-left text-semantic-text-primary outline-none transition-colors hover:border-semantic-border-input-focus/50 disabled:cursor-not-allowed disabled:opacity-50",
|
|
2561
|
+
{
|
|
2562
|
+
variants: {
|
|
2563
|
+
size: {
|
|
2564
|
+
sm: "h-9 gap-2 rounded-lg px-3 py-2 text-sm",
|
|
2565
|
+
default: "h-10 gap-2 rounded-lg px-4 py-2.5 text-sm",
|
|
2566
|
+
lg: "h-10 gap-2 rounded-lg px-4 py-2.5 text-sm",
|
|
2567
|
+
},
|
|
2568
|
+
state: {
|
|
2569
|
+
default: "",
|
|
2570
|
+
error:
|
|
2571
|
+
"border-semantic-error-primary hover:border-semantic-error-primary",
|
|
2572
|
+
},
|
|
2573
|
+
},
|
|
2574
|
+
defaultVariants: {
|
|
2575
|
+
size: "default",
|
|
2576
|
+
state: "default",
|
|
2577
|
+
},
|
|
2578
|
+
}
|
|
2579
|
+
);
|
|
2580
|
+
|
|
2581
|
+
export interface DateTimePickerValue {
|
|
2582
|
+
date?: Date;
|
|
2583
|
+
startTime: string;
|
|
2584
|
+
endTime: string;
|
|
2585
|
+
}
|
|
2586
|
+
|
|
2587
|
+
export interface DateTimePickerProps
|
|
2588
|
+
extends
|
|
2589
|
+
Omit<React.HTMLAttributes<HTMLDivElement>, "defaultValue" | "onChange">,
|
|
2590
|
+
VariantProps<typeof dateTimePickerVariants>,
|
|
2591
|
+
Pick<VariantProps<typeof dateTimePickerTriggerVariants>, "state"> {
|
|
2592
|
+
value?: DateTimePickerValue;
|
|
2593
|
+
defaultValue?: DateTimePickerValue;
|
|
2594
|
+
onValueChange?: (value: DateTimePickerValue) => void;
|
|
2595
|
+
placeholder?: string;
|
|
2596
|
+
disabled?: boolean;
|
|
2597
|
+
readOnly?: boolean;
|
|
2598
|
+
name?: string;
|
|
2599
|
+
showEndTime?: boolean;
|
|
2600
|
+
showClear?: boolean;
|
|
2601
|
+
closeOnSelect?: boolean;
|
|
2602
|
+
startTimeLabel?: string;
|
|
2603
|
+
endTimeLabel?: string;
|
|
2604
|
+
minDate?: Date;
|
|
2605
|
+
maxDate?: Date;
|
|
2606
|
+
disablePastDates?: boolean;
|
|
2607
|
+
open?: boolean;
|
|
2608
|
+
defaultOpen?: boolean;
|
|
2609
|
+
onOpenChange?: (open: boolean) => void;
|
|
2610
|
+
portalContainer?: HTMLElement | null;
|
|
2611
|
+
}
|
|
2612
|
+
|
|
2613
|
+
function normalizeValue(
|
|
2614
|
+
value?: Partial<DateTimePickerValue>
|
|
2615
|
+
): DateTimePickerValue {
|
|
2616
|
+
return {
|
|
2617
|
+
date: value?.date,
|
|
2618
|
+
startTime: value?.startTime ?? DEFAULT_START_TIME,
|
|
2619
|
+
endTime: value?.endTime ?? DEFAULT_END_TIME,
|
|
2620
|
+
};
|
|
2621
|
+
}
|
|
2622
|
+
|
|
2623
|
+
function isSameDay(a?: Date, b?: Date) {
|
|
2624
|
+
if (!a || !b) return false;
|
|
2625
|
+
|
|
2626
|
+
return (
|
|
2627
|
+
a.getFullYear() === b.getFullYear() &&
|
|
2628
|
+
a.getMonth() === b.getMonth() &&
|
|
2629
|
+
a.getDate() === b.getDate()
|
|
2630
|
+
);
|
|
2631
|
+
}
|
|
2632
|
+
|
|
2633
|
+
function startOfDay(date: Date) {
|
|
2634
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
2635
|
+
}
|
|
2636
|
+
|
|
2637
|
+
function isBeforeDay(date: Date, minDate: Date) {
|
|
2638
|
+
return startOfDay(date).getTime() < startOfDay(minDate).getTime();
|
|
2639
|
+
}
|
|
2640
|
+
|
|
2641
|
+
function isAfterDay(date: Date, maxDate: Date) {
|
|
2642
|
+
return startOfDay(date).getTime() > startOfDay(maxDate).getTime();
|
|
2643
|
+
}
|
|
2644
|
+
|
|
2645
|
+
function startOfMonth(date: Date) {
|
|
2646
|
+
return new Date(date.getFullYear(), date.getMonth(), 1);
|
|
2647
|
+
}
|
|
2648
|
+
|
|
2649
|
+
function addMonths(date: Date, months: number) {
|
|
2650
|
+
return new Date(date.getFullYear(), date.getMonth() + months, 1);
|
|
2651
|
+
}
|
|
2652
|
+
|
|
2653
|
+
function getCalendarDays(month: Date) {
|
|
2654
|
+
const firstDay = startOfMonth(month);
|
|
2655
|
+
const gridStart = new Date(firstDay);
|
|
2656
|
+
gridStart.setDate(firstDay.getDate() - firstDay.getDay());
|
|
2657
|
+
|
|
2658
|
+
return Array.from({ length: 42 }, (_, index) => {
|
|
2659
|
+
const day = new Date(gridStart);
|
|
2660
|
+
day.setDate(gridStart.getDate() + index);
|
|
2661
|
+
return day;
|
|
2662
|
+
});
|
|
2663
|
+
}
|
|
2664
|
+
|
|
2665
|
+
function isPointerInsideElement(
|
|
2666
|
+
event: MouseEvent,
|
|
2667
|
+
element: HTMLElement | null
|
|
2668
|
+
) {
|
|
2669
|
+
if (!element) return false;
|
|
2670
|
+
|
|
2671
|
+
const target = event.target;
|
|
2672
|
+
if (target instanceof Node && element.contains(target)) return true;
|
|
2673
|
+
|
|
2674
|
+
if (typeof event.composedPath === "function") {
|
|
2675
|
+
return event
|
|
2676
|
+
.composedPath()
|
|
2677
|
+
.some((node) => node instanceof Node && element.contains(node));
|
|
2678
|
+
}
|
|
2679
|
+
|
|
2680
|
+
return false;
|
|
2681
|
+
}
|
|
2682
|
+
|
|
2683
|
+
function formatTimeForDisplay(time: string) {
|
|
2684
|
+
const [hour = "0", minute = "0"] = time.split(":");
|
|
2685
|
+
const hourNumber = Number(hour);
|
|
2686
|
+
const suffix = hourNumber >= 12 ? "PM" : "AM";
|
|
2687
|
+
const hour12 = hourNumber % 12 || 12;
|
|
2688
|
+
|
|
2689
|
+
return \`\${hour12.toString().padStart(2, "0")}:\${minute.padStart(2, "0")} \${suffix}\`;
|
|
2690
|
+
}
|
|
2691
|
+
|
|
2692
|
+
function formatDateForDisplay(date?: Date, time?: string) {
|
|
2693
|
+
if (!date) return "";
|
|
2694
|
+
|
|
2695
|
+
const month = (date.getMonth() + 1).toString().padStart(2, "0");
|
|
2696
|
+
const day = date.getDate().toString().padStart(2, "0");
|
|
2697
|
+
const year = date.getFullYear();
|
|
2698
|
+
const formattedTime = formatTimeForDisplay(time ?? DEFAULT_START_TIME);
|
|
2699
|
+
|
|
2700
|
+
return \`\${month}/\${day}/\${year} \${formattedTime}\`;
|
|
2701
|
+
}
|
|
2702
|
+
|
|
2703
|
+
function formatHiddenValue(value: DateTimePickerValue) {
|
|
2704
|
+
if (!value.date) return "";
|
|
2705
|
+
|
|
2706
|
+
const month = (value.date.getMonth() + 1).toString().padStart(2, "0");
|
|
2707
|
+
const day = value.date.getDate().toString().padStart(2, "0");
|
|
2708
|
+
const year = value.date.getFullYear();
|
|
2709
|
+
|
|
2710
|
+
return \`\${year}-\${month}-\${day}T\${value.startTime}\`;
|
|
2711
|
+
}
|
|
2712
|
+
|
|
2713
|
+
function FigmaCalendarIcon({ className }: { className?: string }) {
|
|
2714
|
+
return (
|
|
2715
|
+
<svg
|
|
2716
|
+
viewBox="0 0 18 18"
|
|
2717
|
+
fill="none"
|
|
2718
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
2719
|
+
className={className}
|
|
2720
|
+
aria-hidden="true"
|
|
2721
|
+
>
|
|
2722
|
+
<path
|
|
2723
|
+
d="M6 1.5V4.5M12 1.5V4.5M2.25 6.375H15.75M3.75 3H14.25C15.0784 3 15.75 3.67157 15.75 4.5V15C15.75 15.8284 15.0784 16.5 14.25 16.5H3.75C2.92157 16.5 2.25 15.8284 2.25 15V4.5C2.25 3.67157 2.92157 3 3.75 3Z"
|
|
2724
|
+
stroke="currentColor"
|
|
2725
|
+
strokeWidth="1.5"
|
|
2726
|
+
strokeLinecap="round"
|
|
2727
|
+
strokeLinejoin="round"
|
|
2728
|
+
/>
|
|
2729
|
+
</svg>
|
|
2730
|
+
);
|
|
2731
|
+
}
|
|
2732
|
+
|
|
2733
|
+
const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
2734
|
+
(
|
|
2735
|
+
{
|
|
2736
|
+
className,
|
|
2737
|
+
size,
|
|
2738
|
+
state,
|
|
2739
|
+
value,
|
|
2740
|
+
defaultValue,
|
|
2741
|
+
onValueChange,
|
|
2742
|
+
placeholder = DEFAULT_PLACEHOLDER,
|
|
2743
|
+
disabled = false,
|
|
2744
|
+
readOnly = false,
|
|
2745
|
+
name,
|
|
2746
|
+
showEndTime = true,
|
|
2747
|
+
showClear = true,
|
|
2748
|
+
closeOnSelect = false,
|
|
2749
|
+
startTimeLabel = "Start Time",
|
|
2750
|
+
endTimeLabel = "End Time",
|
|
2751
|
+
minDate,
|
|
2752
|
+
maxDate,
|
|
2753
|
+
disablePastDates = false,
|
|
2754
|
+
open: controlledOpen,
|
|
2755
|
+
defaultOpen = false,
|
|
2756
|
+
onOpenChange,
|
|
2757
|
+
portalContainer,
|
|
2758
|
+
id,
|
|
2759
|
+
...props
|
|
2760
|
+
},
|
|
2761
|
+
ref
|
|
2762
|
+
) => {
|
|
2763
|
+
const generatedId = React.useId();
|
|
2764
|
+
const triggerId = id ?? generatedId;
|
|
2765
|
+
const isValueControlled = value !== undefined;
|
|
2766
|
+
const isOpenControlled = controlledOpen !== undefined;
|
|
2767
|
+
const [internalValue, setInternalValue] = React.useState(() =>
|
|
2768
|
+
normalizeValue(defaultValue)
|
|
2769
|
+
);
|
|
2770
|
+
const [internalOpen, setInternalOpen] = React.useState(defaultOpen);
|
|
2771
|
+
const currentValue = normalizeValue(
|
|
2772
|
+
isValueControlled ? value : internalValue
|
|
2773
|
+
);
|
|
2774
|
+
const open = isOpenControlled ? controlledOpen : internalOpen;
|
|
2775
|
+
const [visibleMonth, setVisibleMonth] = React.useState(() =>
|
|
2776
|
+
startOfMonth(currentValue.date ?? new Date())
|
|
2777
|
+
);
|
|
2778
|
+
const rootRef = React.useRef<HTMLDivElement | null>(null);
|
|
2779
|
+
const triggerRef = React.useRef<HTMLButtonElement | null>(null);
|
|
2780
|
+
const popoverRef = React.useRef<HTMLDivElement | null>(null);
|
|
2781
|
+
const usesContainerPortal = portalContainer !== undefined;
|
|
2782
|
+
const floatingStrategy: Strategy = usesContainerPortal
|
|
2783
|
+
? "absolute"
|
|
2784
|
+
: "fixed";
|
|
2785
|
+
const floatingMiddleware = React.useMemo(
|
|
2786
|
+
() => [
|
|
2787
|
+
offset(POPOVER_GAP),
|
|
2788
|
+
flip({ padding: POPOVER_MARGIN }),
|
|
2789
|
+
shift({ padding: POPOVER_MARGIN }),
|
|
2790
|
+
floatingSize({
|
|
2791
|
+
padding: POPOVER_MARGIN,
|
|
2792
|
+
apply({ availableHeight, elements, rects }) {
|
|
2793
|
+
const maxHeight = Math.max(
|
|
2794
|
+
1,
|
|
2795
|
+
Math.min(MAX_POPOVER_HEIGHT, availableHeight)
|
|
2796
|
+
);
|
|
2797
|
+
elements.floating.style.setProperty(
|
|
2798
|
+
POPOVER_SCROLL_HEIGHT_VAR,
|
|
2799
|
+
\`\${maxHeight}px\`
|
|
2800
|
+
);
|
|
2801
|
+
elements.floating.style.setProperty(
|
|
2802
|
+
POPOVER_WIDTH_VAR,
|
|
2803
|
+
\`\${rects.reference.width}px\`
|
|
2804
|
+
);
|
|
2805
|
+
},
|
|
2806
|
+
}),
|
|
2807
|
+
],
|
|
2808
|
+
[]
|
|
2809
|
+
);
|
|
2810
|
+
const { refs, floatingStyles, isPositioned } =
|
|
2811
|
+
useFloating<HTMLButtonElement>({
|
|
2812
|
+
open,
|
|
2813
|
+
placement: CALENDAR_PLACEMENT,
|
|
2814
|
+
strategy: floatingStrategy,
|
|
2815
|
+
transform: false,
|
|
2816
|
+
middleware: floatingMiddleware,
|
|
2817
|
+
whileElementsMounted: (reference, floating, update) =>
|
|
2818
|
+
autoUpdate(reference, floating, update, { animationFrame: true }),
|
|
2819
|
+
});
|
|
2820
|
+
const calendarDays = React.useMemo(
|
|
2821
|
+
() => getCalendarDays(visibleMonth),
|
|
2822
|
+
[visibleMonth]
|
|
2823
|
+
);
|
|
2824
|
+
const displayValue = formatDateForDisplay(
|
|
2825
|
+
currentValue.date,
|
|
2826
|
+
currentValue.startTime
|
|
2827
|
+
);
|
|
2828
|
+
const effectiveMinDate = React.useMemo(() => {
|
|
2829
|
+
if (!disablePastDates) return minDate;
|
|
2830
|
+
|
|
2831
|
+
const today = startOfDay(new Date());
|
|
2832
|
+
if (!minDate) return today;
|
|
2833
|
+
|
|
2834
|
+
return isBeforeDay(minDate, today) ? today : minDate;
|
|
2835
|
+
}, [disablePastDates, minDate]);
|
|
2836
|
+
const portalMount =
|
|
2837
|
+
typeof document !== "undefined"
|
|
2838
|
+
? usesContainerPortal
|
|
2839
|
+
? portalContainer
|
|
2840
|
+
: document.body
|
|
2841
|
+
: null;
|
|
2842
|
+
|
|
2843
|
+
const setOpen = React.useCallback(
|
|
2844
|
+
(nextOpen: boolean) => {
|
|
2845
|
+
if (!isOpenControlled) {
|
|
2846
|
+
setInternalOpen(nextOpen);
|
|
2847
|
+
}
|
|
2848
|
+
|
|
2849
|
+
onOpenChange?.(nextOpen);
|
|
2850
|
+
},
|
|
2851
|
+
[isOpenControlled, onOpenChange]
|
|
2852
|
+
);
|
|
2853
|
+
|
|
2854
|
+
const setTriggerRef = React.useCallback(
|
|
2855
|
+
(node: HTMLButtonElement | null) => {
|
|
2856
|
+
triggerRef.current = node;
|
|
2857
|
+
refs.setReference(node);
|
|
2858
|
+
},
|
|
2859
|
+
[refs]
|
|
2860
|
+
);
|
|
2861
|
+
|
|
2862
|
+
const setPopoverRef = React.useCallback(
|
|
2863
|
+
(node: HTMLDivElement | null) => {
|
|
2864
|
+
popoverRef.current = node;
|
|
2865
|
+
refs.setFloating(node);
|
|
2866
|
+
},
|
|
2867
|
+
[refs]
|
|
2868
|
+
);
|
|
2869
|
+
|
|
2870
|
+
React.useEffect(() => {
|
|
2871
|
+
if (currentValue.date) {
|
|
2872
|
+
setVisibleMonth(startOfMonth(currentValue.date));
|
|
2873
|
+
}
|
|
2874
|
+
}, [currentValue.date]);
|
|
2875
|
+
|
|
2876
|
+
React.useEffect(() => {
|
|
2877
|
+
if (!open) return;
|
|
2878
|
+
|
|
2879
|
+
const handlePointerDown = (event: MouseEvent) => {
|
|
2880
|
+
if (
|
|
2881
|
+
!isPointerInsideElement(event, rootRef.current) &&
|
|
2882
|
+
!isPointerInsideElement(event, popoverRef.current)
|
|
2883
|
+
) {
|
|
2884
|
+
setOpen(false);
|
|
2885
|
+
}
|
|
2886
|
+
};
|
|
2887
|
+
|
|
2888
|
+
const handleKeyDown = (event: KeyboardEvent) => {
|
|
2889
|
+
if (event.key === "Escape") {
|
|
2890
|
+
setOpen(false);
|
|
2891
|
+
}
|
|
2892
|
+
};
|
|
2893
|
+
|
|
2894
|
+
document.addEventListener("mousedown", handlePointerDown);
|
|
2895
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
2896
|
+
|
|
2897
|
+
return () => {
|
|
2898
|
+
document.removeEventListener("mousedown", handlePointerDown);
|
|
2899
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
2900
|
+
};
|
|
2901
|
+
}, [open, setOpen]);
|
|
2902
|
+
|
|
2903
|
+
const updateValue = React.useCallback(
|
|
2904
|
+
(nextValue: DateTimePickerValue) => {
|
|
2905
|
+
if (!isValueControlled) {
|
|
2906
|
+
setInternalValue(nextValue);
|
|
2907
|
+
}
|
|
2908
|
+
|
|
2909
|
+
onValueChange?.(nextValue);
|
|
2910
|
+
},
|
|
2911
|
+
[isValueControlled, onValueChange]
|
|
2912
|
+
);
|
|
2913
|
+
|
|
2914
|
+
const clearValue = (event: React.MouseEvent<HTMLElement>) => {
|
|
2915
|
+
event.stopPropagation();
|
|
2916
|
+
if (readOnly) return;
|
|
2917
|
+
|
|
2918
|
+
updateValue({
|
|
2919
|
+
date: undefined,
|
|
2920
|
+
startTime: currentValue.startTime,
|
|
2921
|
+
endTime: currentValue.endTime,
|
|
2922
|
+
});
|
|
2923
|
+
};
|
|
2924
|
+
|
|
2925
|
+
const popover =
|
|
2926
|
+
open &&
|
|
2927
|
+
!disabled &&
|
|
2928
|
+
!readOnly &&
|
|
2929
|
+
portalMount &&
|
|
2930
|
+
createPortal(
|
|
2931
|
+
<div
|
|
2932
|
+
ref={setPopoverRef}
|
|
2933
|
+
role="dialog"
|
|
2934
|
+
aria-modal="false"
|
|
2935
|
+
aria-labelledby={\`\${triggerId}-calendar-heading\`}
|
|
2936
|
+
className={cn(
|
|
2937
|
+
"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",
|
|
2938
|
+
"[scrollbar-gutter:stable] [scrollbar-width:thin] [scrollbar-color:var(--semantic-border-secondary)_transparent]",
|
|
2939
|
+
"[&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-semantic-border-secondary"
|
|
2940
|
+
)}
|
|
2941
|
+
style={{
|
|
2942
|
+
...floatingStyles,
|
|
2943
|
+
width: \`var(\${POPOVER_WIDTH_VAR}, \${POPOVER_WIDTH}px)\`,
|
|
2944
|
+
maxHeight: \`var(\${POPOVER_SCROLL_HEIGHT_VAR}, min(\${MAX_POPOVER_HEIGHT}px, calc(100dvh - \${
|
|
2945
|
+
POPOVER_MARGIN * 2
|
|
2946
|
+
}px)))\`,
|
|
2947
|
+
zIndex: 10050,
|
|
2948
|
+
visibility: isPositioned ? undefined : "hidden",
|
|
2949
|
+
}}
|
|
2950
|
+
onPointerDown={(event) => event.stopPropagation()}
|
|
2951
|
+
onMouseDown={(event) => event.stopPropagation()}
|
|
2952
|
+
onWheel={(event) => event.stopPropagation()}
|
|
2953
|
+
onTouchMove={(event) => event.stopPropagation()}
|
|
2954
|
+
>
|
|
2955
|
+
<div className="p-3 touch-pan-y">
|
|
2956
|
+
<div className="mb-3 flex items-center justify-between">
|
|
2957
|
+
<button
|
|
2958
|
+
type="button"
|
|
2959
|
+
aria-label="Previous month"
|
|
2960
|
+
className="p-1 rounded hover:bg-semantic-bg-hover text-semantic-text-secondary transition-colors"
|
|
2961
|
+
onClick={() => setVisibleMonth((month) => addMonths(month, -1))}
|
|
2962
|
+
>
|
|
2963
|
+
<ChevronLeft className="size-4" aria-hidden="true" />
|
|
2964
|
+
</button>
|
|
2965
|
+
<div
|
|
2966
|
+
id={\`\${triggerId}-calendar-heading\`}
|
|
2967
|
+
className="text-sm font-semibold text-semantic-text-primary"
|
|
2968
|
+
>
|
|
2969
|
+
{monthFormatter.format(visibleMonth)}
|
|
2970
|
+
</div>
|
|
2971
|
+
<button
|
|
2972
|
+
type="button"
|
|
2973
|
+
aria-label="Next month"
|
|
2974
|
+
className="p-1 rounded hover:bg-semantic-bg-hover text-semantic-text-secondary transition-colors"
|
|
2975
|
+
onClick={() => setVisibleMonth((month) => addMonths(month, 1))}
|
|
2976
|
+
>
|
|
2977
|
+
<ChevronRight className="size-4" aria-hidden="true" />
|
|
2978
|
+
</button>
|
|
2979
|
+
</div>
|
|
2980
|
+
|
|
2981
|
+
<div className="grid grid-cols-7">
|
|
2982
|
+
{weekDays.map((day) => (
|
|
2983
|
+
<div
|
|
2984
|
+
key={day}
|
|
2985
|
+
className="flex size-8 items-center justify-center text-xs font-medium text-semantic-text-muted"
|
|
2986
|
+
>
|
|
2987
|
+
{day}
|
|
2988
|
+
</div>
|
|
2989
|
+
))}
|
|
2990
|
+
{calendarDays.map((day) => {
|
|
2991
|
+
const isCurrentMonth =
|
|
2992
|
+
day.getMonth() === visibleMonth.getMonth();
|
|
2993
|
+
const isSelected = isSameDay(day, currentValue.date);
|
|
2994
|
+
const isToday = isSameDay(day, new Date());
|
|
2995
|
+
const isDisabled =
|
|
2996
|
+
(effectiveMinDate && isBeforeDay(day, effectiveMinDate)) ||
|
|
2997
|
+
(maxDate && isAfterDay(day, maxDate));
|
|
2998
|
+
const dayLabel = day.toLocaleDateString("en-US", {
|
|
2999
|
+
month: "long",
|
|
3000
|
+
day: "numeric",
|
|
3001
|
+
year: "numeric",
|
|
3002
|
+
});
|
|
3003
|
+
|
|
3004
|
+
return (
|
|
3005
|
+
<button
|
|
3006
|
+
key={day.toISOString()}
|
|
3007
|
+
type="button"
|
|
3008
|
+
aria-label={dayLabel}
|
|
3009
|
+
aria-pressed={isSelected}
|
|
3010
|
+
aria-current={isToday ? "date" : undefined}
|
|
3011
|
+
disabled={!!isDisabled}
|
|
3012
|
+
className={cn(
|
|
3013
|
+
"relative flex items-center justify-center size-8 mx-auto rounded-full text-xs transition-colors",
|
|
3014
|
+
isSelected
|
|
3015
|
+
? "bg-semantic-primary text-semantic-text-inverted font-semibold"
|
|
3016
|
+
: isCurrentMonth
|
|
3017
|
+
? "text-semantic-text-primary hover:bg-semantic-bg-hover"
|
|
3018
|
+
: "text-semantic-text-muted hover:bg-semantic-bg-hover",
|
|
3019
|
+
isDisabled &&
|
|
3020
|
+
"opacity-40 cursor-not-allowed pointer-events-none"
|
|
3021
|
+
)}
|
|
3022
|
+
onClick={() => {
|
|
3023
|
+
if (isDisabled) return;
|
|
3024
|
+
|
|
3025
|
+
updateValue({ ...currentValue, date: day });
|
|
3026
|
+
if (closeOnSelect) {
|
|
3027
|
+
setOpen(false);
|
|
3028
|
+
}
|
|
3029
|
+
}}
|
|
3030
|
+
>
|
|
3031
|
+
{day.getDate()}
|
|
3032
|
+
{isToday && !isSelected && (
|
|
3033
|
+
<span className="absolute bottom-0.5 left-1/2 -translate-x-1/2 size-1 rounded-full bg-semantic-primary" />
|
|
3034
|
+
)}
|
|
3035
|
+
</button>
|
|
3036
|
+
);
|
|
3037
|
+
})}
|
|
3038
|
+
</div>
|
|
3039
|
+
</div>
|
|
3040
|
+
|
|
3041
|
+
<div className="space-y-3 border-t border-solid border-semantic-border-layout bg-semantic-bg-primary p-3">
|
|
3042
|
+
<div className="flex flex-col gap-1.5">
|
|
3043
|
+
<label
|
|
3044
|
+
htmlFor={\`\${triggerId}-start-time\`}
|
|
3045
|
+
className="block text-sm font-semibold text-semantic-text-primary"
|
|
3046
|
+
>
|
|
3047
|
+
{startTimeLabel}
|
|
3048
|
+
</label>
|
|
3049
|
+
<div className="relative">
|
|
3050
|
+
<Clock2
|
|
3051
|
+
className="pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-semantic-text-muted"
|
|
3052
|
+
aria-hidden="true"
|
|
3053
|
+
/>
|
|
3054
|
+
<input
|
|
3055
|
+
id={\`\${triggerId}-start-time\`}
|
|
3056
|
+
type="time"
|
|
3057
|
+
step="1"
|
|
3058
|
+
value={currentValue.startTime}
|
|
3059
|
+
className="h-8 w-full rounded-md border border-solid border-semantic-border-input bg-semantic-bg-primary pl-9 pr-3 text-sm text-semantic-text-primary outline-none transition-colors hover:border-semantic-border-input-focus/50 focus:border-semantic-border-input-focus/50 focus:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]"
|
|
3060
|
+
onChange={(event) =>
|
|
3061
|
+
updateValue({
|
|
3062
|
+
...currentValue,
|
|
3063
|
+
startTime: event.target.value,
|
|
3064
|
+
})
|
|
3065
|
+
}
|
|
3066
|
+
/>
|
|
3067
|
+
</div>
|
|
3068
|
+
</div>
|
|
3069
|
+
|
|
3070
|
+
{showEndTime && (
|
|
3071
|
+
<div className="flex flex-col gap-1.5">
|
|
3072
|
+
<label
|
|
3073
|
+
htmlFor={\`\${triggerId}-end-time\`}
|
|
3074
|
+
className="block text-sm font-semibold text-semantic-text-primary"
|
|
3075
|
+
>
|
|
3076
|
+
{endTimeLabel}
|
|
3077
|
+
</label>
|
|
3078
|
+
<div className="relative">
|
|
3079
|
+
<Clock2
|
|
3080
|
+
className="pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-semantic-text-muted"
|
|
3081
|
+
aria-hidden="true"
|
|
3082
|
+
/>
|
|
3083
|
+
<input
|
|
3084
|
+
id={\`\${triggerId}-end-time\`}
|
|
3085
|
+
type="time"
|
|
3086
|
+
step="1"
|
|
3087
|
+
value={currentValue.endTime}
|
|
3088
|
+
className="h-8 w-full rounded-md border border-solid border-semantic-border-input bg-semantic-bg-primary pl-9 pr-3 text-sm text-semantic-text-primary outline-none transition-colors hover:border-semantic-border-input-focus/50 focus:border-semantic-border-input-focus/50 focus:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]"
|
|
3089
|
+
onChange={(event) =>
|
|
3090
|
+
updateValue({
|
|
3091
|
+
...currentValue,
|
|
3092
|
+
endTime: event.target.value,
|
|
3093
|
+
})
|
|
3094
|
+
}
|
|
3095
|
+
/>
|
|
3096
|
+
</div>
|
|
3097
|
+
</div>
|
|
3098
|
+
)}
|
|
3099
|
+
</div>
|
|
3100
|
+
</div>,
|
|
3101
|
+
portalMount
|
|
3102
|
+
);
|
|
3103
|
+
|
|
3104
|
+
return (
|
|
3105
|
+
<div
|
|
3106
|
+
ref={(node) => {
|
|
3107
|
+
rootRef.current = node;
|
|
3108
|
+
|
|
3109
|
+
if (typeof ref === "function") {
|
|
3110
|
+
ref(node);
|
|
3111
|
+
} else if (ref) {
|
|
3112
|
+
(ref as React.MutableRefObject<HTMLDivElement | null>).current =
|
|
3113
|
+
node;
|
|
3114
|
+
}
|
|
3115
|
+
}}
|
|
3116
|
+
className={cn(dateTimePickerVariants({ size, className }))}
|
|
3117
|
+
{...props}
|
|
3118
|
+
>
|
|
3119
|
+
{name && (
|
|
3120
|
+
<input
|
|
3121
|
+
type="hidden"
|
|
3122
|
+
name={name}
|
|
3123
|
+
value={formatHiddenValue(currentValue)}
|
|
3124
|
+
/>
|
|
3125
|
+
)}
|
|
3126
|
+
<button
|
|
3127
|
+
ref={setTriggerRef}
|
|
3128
|
+
id={triggerId}
|
|
3129
|
+
type="button"
|
|
3130
|
+
disabled={disabled || readOnly}
|
|
3131
|
+
aria-haspopup="dialog"
|
|
3132
|
+
aria-expanded={open}
|
|
3133
|
+
className={cn(
|
|
3134
|
+
dateTimePickerTriggerVariants({ size, state }),
|
|
3135
|
+
open &&
|
|
3136
|
+
state !== "error" &&
|
|
3137
|
+
"border-semantic-border-input-focus/50 shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
|
|
3138
|
+
!displayValue && "text-semantic-text-placeholder"
|
|
3139
|
+
)}
|
|
3140
|
+
onClick={() => setOpen(!open)}
|
|
3141
|
+
>
|
|
3142
|
+
<span
|
|
3143
|
+
className={cn(
|
|
3144
|
+
"min-w-0 flex-1 truncate",
|
|
3145
|
+
!displayValue && "font-normal"
|
|
3146
|
+
)}
|
|
3147
|
+
>
|
|
3148
|
+
{displayValue || placeholder}
|
|
3149
|
+
</span>
|
|
3150
|
+
{showClear && displayValue && !disabled && !readOnly && (
|
|
3151
|
+
<span
|
|
3152
|
+
aria-hidden="true"
|
|
3153
|
+
className="inline-flex size-5 items-center justify-center rounded text-semantic-text-muted hover:bg-semantic-bg-hover hover:text-semantic-text-primary"
|
|
3154
|
+
onClick={clearValue}
|
|
3155
|
+
>
|
|
3156
|
+
<X className="size-4" aria-hidden="true" />
|
|
3157
|
+
</span>
|
|
3158
|
+
)}
|
|
3159
|
+
<FigmaCalendarIcon
|
|
3160
|
+
className={cn(
|
|
3161
|
+
"shrink-0 text-semantic-text-muted",
|
|
3162
|
+
size === "sm" ? "size-4" : "size-[18px]"
|
|
3163
|
+
)}
|
|
3164
|
+
/>
|
|
3165
|
+
</button>
|
|
3166
|
+
|
|
3167
|
+
{popover}
|
|
3168
|
+
</div>
|
|
3169
|
+
);
|
|
3170
|
+
}
|
|
3171
|
+
);
|
|
3172
|
+
DateTimePicker.displayName = "DateTimePicker";
|
|
3173
|
+
|
|
3174
|
+
export {
|
|
3175
|
+
DateTimePicker,
|
|
3176
|
+
dateTimePickerTriggerVariants,
|
|
3177
|
+
dateTimePickerVariants,
|
|
3178
|
+
formatDateForDisplay,
|
|
3179
|
+
formatTimeForDisplay,
|
|
3180
|
+
};
|
|
2506
3181
|
`,
|
|
2507
3182
|
"delete-confirmation-modal": `import * as React from "react";
|
|
2508
3183
|
|
|
@@ -4122,7 +4797,7 @@ const MultiSelect = React.forwardRef(
|
|
|
4122
4797
|
const secondaryLine = option.secondaryText ?? option.caption;
|
|
4123
4798
|
|
|
4124
4799
|
const rowClass = cn(
|
|
4125
|
-
"relative flex w-full cursor-pointer select-none items-center rounded-sm text-left text-semantic-text-primary outline-none",
|
|
4800
|
+
"relative flex w-full min-w-0 cursor-pointer select-none items-center rounded-sm text-left text-semantic-text-primary outline-none",
|
|
4126
4801
|
optionVariant === "detailed"
|
|
4127
4802
|
? "gap-2 px-2 py-2 text-sm"
|
|
4128
4803
|
: "py-2 pl-4 pr-8 text-base",
|
|
@@ -4148,7 +4823,9 @@ const MultiSelect = React.forwardRef(
|
|
|
4148
4823
|
<Check className="size-4 text-semantic-brand" />
|
|
4149
4824
|
)}
|
|
4150
4825
|
</span>
|
|
4151
|
-
|
|
4826
|
+
<span className="min-w-0 flex-1 whitespace-normal break-words text-left">
|
|
4827
|
+
{option.label}
|
|
4828
|
+
</span>
|
|
4152
4829
|
</button>
|
|
4153
4830
|
);
|
|
4154
4831
|
|
|
@@ -5172,6 +5849,7 @@ import { cn } from "@/lib/utils";
|
|
|
5172
5849
|
* \`\`\`tsx
|
|
5173
5850
|
* <PhoneInput placeholder="Enter phone number" />
|
|
5174
5851
|
* <PhoneInput countryFlag="\u{1F1FA}\u{1F1F8}" countryCode="+1" />
|
|
5852
|
+
* <PhoneInput phoneMaxNumber={10} />
|
|
5175
5853
|
* <PhoneInput onCountryClick={() => openCountryPicker()} />
|
|
5176
5854
|
* \`\`\`
|
|
5177
5855
|
*/
|
|
@@ -5187,6 +5865,8 @@ export interface PhoneInputProps
|
|
|
5187
5865
|
onCountryClick?: () => void;
|
|
5188
5866
|
/** Additional className for the outer wrapper */
|
|
5189
5867
|
wrapperClassName?: string;
|
|
5868
|
+
/** Maximum number of digits allowed in the phone number */
|
|
5869
|
+
phoneMaxNumber?: number;
|
|
5190
5870
|
}
|
|
5191
5871
|
|
|
5192
5872
|
const PhoneInput = React.forwardRef(
|
|
@@ -5199,10 +5879,62 @@ const PhoneInput = React.forwardRef(
|
|
|
5199
5879
|
onCountryClick,
|
|
5200
5880
|
wrapperClassName,
|
|
5201
5881
|
disabled,
|
|
5882
|
+
inputMode = "numeric",
|
|
5883
|
+
pattern = "[0-9]*",
|
|
5884
|
+
onBeforeInput,
|
|
5885
|
+
onChange,
|
|
5886
|
+
onKeyDown,
|
|
5887
|
+
maxLength,
|
|
5888
|
+
phoneMaxNumber,
|
|
5202
5889
|
...props
|
|
5203
5890
|
}: PhoneInputProps,
|
|
5204
5891
|
ref: React.Ref<HTMLInputElement>
|
|
5205
5892
|
) => {
|
|
5893
|
+
const effectiveMaxLength = phoneMaxNumber ?? maxLength;
|
|
5894
|
+
|
|
5895
|
+
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
|
5896
|
+
onKeyDown?.(event);
|
|
5897
|
+
if (
|
|
5898
|
+
event.defaultPrevented ||
|
|
5899
|
+
event.ctrlKey ||
|
|
5900
|
+
event.metaKey ||
|
|
5901
|
+
event.altKey ||
|
|
5902
|
+
event.key.length !== 1
|
|
5903
|
+
) {
|
|
5904
|
+
return;
|
|
5905
|
+
}
|
|
5906
|
+
|
|
5907
|
+
if (/\\D/.test(event.key)) {
|
|
5908
|
+
event.preventDefault();
|
|
5909
|
+
}
|
|
5910
|
+
};
|
|
5911
|
+
|
|
5912
|
+
const handleBeforeInput = (
|
|
5913
|
+
event: React.InputEvent<HTMLInputElement>
|
|
5914
|
+
) => {
|
|
5915
|
+
onBeforeInput?.(event);
|
|
5916
|
+
if (event.defaultPrevented) return;
|
|
5917
|
+
|
|
5918
|
+
const inputEvent = event.nativeEvent as InputEvent;
|
|
5919
|
+
if (inputEvent.data && /\\D/.test(inputEvent.data)) {
|
|
5920
|
+
event.preventDefault();
|
|
5921
|
+
}
|
|
5922
|
+
};
|
|
5923
|
+
|
|
5924
|
+
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
5925
|
+
const digitsOnlyValue = event.currentTarget.value.replace(/\\D/g, "");
|
|
5926
|
+
const sanitizedValue =
|
|
5927
|
+
effectiveMaxLength != null
|
|
5928
|
+
? digitsOnlyValue.slice(0, effectiveMaxLength)
|
|
5929
|
+
: digitsOnlyValue;
|
|
5930
|
+
|
|
5931
|
+
if (event.currentTarget.value !== sanitizedValue) {
|
|
5932
|
+
event.currentTarget.value = sanitizedValue;
|
|
5933
|
+
}
|
|
5934
|
+
|
|
5935
|
+
onChange?.(event);
|
|
5936
|
+
};
|
|
5937
|
+
|
|
5206
5938
|
return (
|
|
5207
5939
|
<div
|
|
5208
5940
|
className={cn(
|
|
@@ -5232,10 +5964,16 @@ const PhoneInput = React.forwardRef(
|
|
|
5232
5964
|
type="tel"
|
|
5233
5965
|
ref={ref}
|
|
5234
5966
|
disabled={disabled}
|
|
5967
|
+
inputMode={inputMode}
|
|
5968
|
+
pattern={pattern}
|
|
5969
|
+
maxLength={effectiveMaxLength}
|
|
5235
5970
|
className={cn(
|
|
5236
5971
|
"flex-1 h-10 px-3 text-sm text-semantic-text-primary placeholder:text-semantic-text-muted outline-none bg-transparent disabled:cursor-not-allowed",
|
|
5237
5972
|
className
|
|
5238
5973
|
)}
|
|
5974
|
+
onBeforeInput={handleBeforeInput}
|
|
5975
|
+
onChange={handleChange}
|
|
5976
|
+
onKeyDown={handleKeyDown}
|
|
5239
5977
|
{...props}
|
|
5240
5978
|
/>
|
|
5241
5979
|
</div>
|
|
@@ -5997,7 +6735,7 @@ import { cn } from "@/lib/utils";
|
|
|
5997
6735
|
* SelectTrigger variants matching TextField styling
|
|
5998
6736
|
*/
|
|
5999
6737
|
const selectTriggerVariants = cva(
|
|
6000
|
-
"flex h-[42px] w-full items-center justify-between rounded bg-semantic-bg-primary px-4 py-2 text-left text-base text-semantic-text-primary outline-none transition-all disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[var(--color-neutral-50)] [&>span]:
|
|
6738
|
+
"flex h-[42px] w-full items-center justify-between gap-2 rounded bg-semantic-bg-primary px-4 py-2 text-left text-base text-semantic-text-primary outline-none transition-all disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[var(--color-neutral-50)] [&>span]:min-w-0 [&>span]:flex-1 [&>span]:truncate",
|
|
6001
6739
|
{
|
|
6002
6740
|
variants: {
|
|
6003
6741
|
state: {
|
|
@@ -6039,7 +6777,7 @@ const SelectTrigger = React.forwardRef(({ className, state, children, ...props }
|
|
|
6039
6777
|
>
|
|
6040
6778
|
{children}
|
|
6041
6779
|
<SelectPrimitive.Icon asChild>
|
|
6042
|
-
<ChevronDown className="size-4 text-semantic-text-muted opacity-70" />
|
|
6780
|
+
<ChevronDown className="size-4 shrink-0 text-semantic-text-muted opacity-70" />
|
|
6043
6781
|
</SelectPrimitive.Icon>
|
|
6044
6782
|
</SelectPrimitive.Trigger>
|
|
6045
6783
|
));
|
|
@@ -6266,7 +7004,9 @@ const SelectItem = React.forwardRef(({ className, children, ...props }: React.Co
|
|
|
6266
7004
|
<Check className="size-4 text-semantic-brand" />
|
|
6267
7005
|
</SelectPrimitive.ItemIndicator>
|
|
6268
7006
|
</span>
|
|
6269
|
-
<SelectPrimitive.ItemText>
|
|
7007
|
+
<SelectPrimitive.ItemText asChild>
|
|
7008
|
+
<span className="min-w-0 flex-1 truncate">{children}</span>
|
|
7009
|
+
</SelectPrimitive.ItemText>
|
|
6270
7010
|
</SelectPrimitive.Item>
|
|
6271
7011
|
));
|
|
6272
7012
|
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
@@ -7249,8 +7989,10 @@ const textFieldContainerVariants = cva(
|
|
|
7249
7989
|
state: {
|
|
7250
7990
|
default:
|
|
7251
7991
|
"border border-solid border-semantic-border-input focus-within:border-semantic-border-input-focus focus-within:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
|
|
7992
|
+
empty:
|
|
7993
|
+
"border border-solid border-semantic-border-input focus-within:border-semantic-border-input-focus focus-within:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
|
|
7252
7994
|
error:
|
|
7253
|
-
"border border-solid border-semantic-error-primary
|
|
7995
|
+
"border border-solid border-semantic-error-primary focus-within:border-semantic-error-primary focus-within:shadow-[0_0_0_1px_rgba(240,68,56,0.12)]",
|
|
7254
7996
|
},
|
|
7255
7997
|
disabled: {
|
|
7256
7998
|
true: "cursor-not-allowed opacity-50 bg-[var(--color-neutral-50)]",
|
|
@@ -7274,8 +8016,10 @@ const textFieldInputVariants = cva(
|
|
|
7274
8016
|
state: {
|
|
7275
8017
|
default:
|
|
7276
8018
|
"border border-solid border-semantic-border-input focus:outline-none focus:border-semantic-border-input-focus focus:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
|
|
8019
|
+
empty:
|
|
8020
|
+
"border border-solid border-semantic-border-input focus:outline-none focus:border-semantic-border-input-focus focus:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
|
|
7277
8021
|
error:
|
|
7278
|
-
"border border-solid border-semantic-error-primary
|
|
8022
|
+
"border border-solid border-semantic-error-primary focus:outline-none focus:border-semantic-error-primary focus:shadow-[0_0_0_1px_rgba(240,68,56,0.12)]",
|
|
7279
8023
|
},
|
|
7280
8024
|
size: {
|
|
7281
8025
|
default: "h-[42px] px-4 py-2 text-base file:text-base",
|
|
@@ -7305,6 +8049,8 @@ export interface TextFieldProps
|
|
|
7305
8049
|
VariantProps<typeof textFieldInputVariants> {
|
|
7306
8050
|
/** Size of the text field \u2014 \`default\` (42px) or \`sm\` (36px, compact) */
|
|
7307
8051
|
size?: "default" | "sm";
|
|
8052
|
+
/** Visual state of the text field */
|
|
8053
|
+
state?: "default" | "empty" | "error";
|
|
7308
8054
|
/** Label text displayed above the input */
|
|
7309
8055
|
label?: string;
|
|
7310
8056
|
/** Shows red asterisk next to label when true */
|
|
@@ -9255,6 +10001,25 @@ var componentMetadata = {
|
|
|
9255
10001
|
}
|
|
9256
10002
|
]
|
|
9257
10003
|
},
|
|
10004
|
+
"date-time-picker": {
|
|
10005
|
+
"name": "DateTimePicker",
|
|
10006
|
+
"description": "A date time picker component.",
|
|
10007
|
+
"dependencies": [
|
|
10008
|
+
"class-variance-authority",
|
|
10009
|
+
"clsx",
|
|
10010
|
+
"tailwind-merge",
|
|
10011
|
+
"lucide-react"
|
|
10012
|
+
],
|
|
10013
|
+
"props": [],
|
|
10014
|
+
"variants": [],
|
|
10015
|
+
"examples": [
|
|
10016
|
+
{
|
|
10017
|
+
"title": "Basic DateTimePicker",
|
|
10018
|
+
"code": "<DateTimePicker>Content</DateTimePicker>",
|
|
10019
|
+
"description": "Simple date time picker usage"
|
|
10020
|
+
}
|
|
10021
|
+
]
|
|
10022
|
+
},
|
|
9258
10023
|
"delete-confirmation-modal": {
|
|
9259
10024
|
"name": "DeleteConfirmationModal",
|
|
9260
10025
|
"description": "A delete confirmation modal component.",
|
package/package.json
CHANGED