infinity-ui-elements 1.9.2 → 1.9.4

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 CHANGED
@@ -2091,7 +2091,7 @@ const datePickerVariants = classVarianceAuthority.cva("relative flex items-cente
2091
2091
  },
2092
2092
  });
2093
2093
  // Helper functions
2094
- const parseDate = (date) => {
2094
+ const parseDate$1 = (date) => {
2095
2095
  if (!date)
2096
2096
  return null;
2097
2097
  if (date instanceof Date)
@@ -2102,7 +2102,7 @@ const parseDate = (date) => {
2102
2102
  }
2103
2103
  return null;
2104
2104
  };
2105
- const formatDateDefault = (date) => {
2105
+ const formatDateDefault$1 = (date) => {
2106
2106
  return date.toLocaleDateString("en-US", {
2107
2107
  year: "numeric",
2108
2108
  month: "short",
@@ -2173,8 +2173,8 @@ const formatDateByPattern = (date, format) => {
2173
2173
  formatted = formatted.replace(/D/g, day.toString());
2174
2174
  return formatted;
2175
2175
  };
2176
- const DatePicker = React__namespace.forwardRef(({ className, value: controlledValue, defaultValue, onChange, placeholder = "Select a date", label, helperText, errorText, successText, validationState = "none", isDisabled = false, isRequired = false, isOptional = false, size = "medium", showClearButton = true, onClear, containerClassName, labelClassName, triggerClassName, calendarClassName, minDate, maxDate, formatDate = formatDateDefault, format, infoHeading, infoDescription, LinkComponent, linkText, linkHref, onLinkClick, ...props }, ref) => {
2177
- const [uncontrolledValue, setUncontrolledValue] = React__namespace.useState(parseDate(defaultValue));
2176
+ const DatePicker = React__namespace.forwardRef(({ className, value: controlledValue, defaultValue, onChange, placeholder = "Select a date", label, helperText, errorText, successText, validationState = "none", isDisabled = false, isRequired = false, isOptional = false, size = "medium", showClearButton = true, onClear, containerClassName, labelClassName, triggerClassName, calendarClassName, minDate, maxDate, formatDate = formatDateDefault$1, format, infoHeading, infoDescription, LinkComponent, linkText, linkHref, onLinkClick, ...props }, ref) => {
2177
+ const [uncontrolledValue, setUncontrolledValue] = React__namespace.useState(parseDate$1(defaultValue));
2178
2178
  const [isOpen, setIsOpen] = React__namespace.useState(false);
2179
2179
  const datePickerRef = React__namespace.useRef(null);
2180
2180
  const calendarRef = React__namespace.useRef(null);
@@ -2188,7 +2188,7 @@ const DatePicker = React__namespace.forwardRef(({ className, value: controlledVa
2188
2188
  });
2189
2189
  const [calendarHeight, setCalendarHeight] = React__namespace.useState(300); // Default height estimate
2190
2190
  const value = controlledValue !== undefined
2191
- ? parseDate(controlledValue)
2191
+ ? parseDate$1(controlledValue)
2192
2192
  : uncontrolledValue;
2193
2193
  const hasValue = value !== null;
2194
2194
  // Create a formatter function that uses format prop if provided, otherwise formatDate
@@ -2409,8 +2409,8 @@ const DatePicker = React__namespace.forwardRef(({ className, value: controlledVa
2409
2409
  };
2410
2410
  }
2411
2411
  }, [isOpen]);
2412
- const minDateParsed = parseDate(minDate);
2413
- const maxDateParsed = parseDate(maxDate);
2412
+ const minDateParsed = parseDate$1(minDate);
2413
+ const maxDateParsed = parseDate$1(maxDate);
2414
2414
  const sizeConfig = {
2415
2415
  small: {
2416
2416
  gap: "gap-2",
@@ -2448,7 +2448,7 @@ const DatePicker = React__namespace.forwardRef(({ className, value: controlledVa
2448
2448
  top: `${calendarTop}px`,
2449
2449
  left: `${position.left}px`,
2450
2450
  zIndex: isInsideModal ? 10001 : 9999,
2451
- }, className: cn("bg-surface-fill-neutral-intense rounded-large shadow-lg p-4 w-fit", calendarClassName), onClick: (e) => e.stopPropagation(), children: jsxRuntime.jsx("div", { className: "react-calendar-wrapper w-fit", children: jsxRuntime.jsx(Calendar, { onChange: handleCalendarChange, value: value ?? null, minDate: minDateParsed ?? undefined, maxDate: maxDateParsed ?? undefined, locale: "en-US", formatShortWeekday: (locale, date) => {
2451
+ }, className: cn("bg-surface-fill-neutral-intense rounded-large shadow-lg p-4 w-fit", calendarClassName), onClick: (e) => e.stopPropagation(), children: jsxRuntime.jsx("div", { className: "react-calendar-wrapper w-fit", children: jsxRuntime.jsx(Calendar, { onChange: handleCalendarChange, value: value ?? null, minDate: minDateParsed ?? undefined, maxDate: maxDateParsed ?? undefined, locale: "en-US", showNeighboringMonth: true, showFixedNumberOfWeeks: true, formatShortWeekday: (locale, date) => {
2452
2452
  const weekdayNames = [
2453
2453
  "Su",
2454
2454
  "Mo",
@@ -2465,6 +2465,502 @@ const DatePicker = React__namespace.forwardRef(({ className, value: controlledVa
2465
2465
  });
2466
2466
  DatePicker.displayName = "DatePicker";
2467
2467
 
2468
+ const listItemVariants = classVarianceAuthority.cva("flex items-start gap-3 p-3 rounded-medium transition-colors cursor-pointer", {
2469
+ variants: {
2470
+ variant: {
2471
+ default: `hover:bg-action-fill-neutral-faded
2472
+ focus:bg-action-fill-neutral-faded
2473
+ focus:ring-2
2474
+ ring-action-outline-primary-faded-hover
2475
+ border border-transparent
2476
+ `,
2477
+ bordered: "border border-action-outline-primary-faded hover:bg-surface-fill-primary-subtle",
2478
+ primary: `hover:bg-action-fill-neutral-faded
2479
+ focus:bg-action-fill-neutral-faded
2480
+ focus:ring-2
2481
+ ring-action-outline-primary-faded-hover
2482
+ border border-transparent
2483
+ `,
2484
+ negative: `hover:bg-action-fill-negative-faded
2485
+ focus:bg-action-fill-negative-faded
2486
+ focus:ring-2 ring-action-outline-negative-faded-hover
2487
+ border border-transparent
2488
+ `,
2489
+ },
2490
+ isDisabled: {
2491
+ true: "cursor-not-allowed opacity-60",
2492
+ false: "",
2493
+ },
2494
+ isSelected: {
2495
+ true: "bg-action-fill-primary-faded border-action-outline-primary-faded",
2496
+ false: "",
2497
+ },
2498
+ },
2499
+ defaultVariants: {
2500
+ variant: "default",
2501
+ isDisabled: false,
2502
+ isSelected: false,
2503
+ },
2504
+ });
2505
+ const ChevronRightIcon = ({ className }) => (jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: className, children: jsxRuntime.jsx("path", { d: "M7.5 15L12.5 10L7.5 5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }));
2506
+ const ListItem = React__namespace.forwardRef(({ className, type = "single", leadingIcon, title, description, trailingIcon, showChevron = true, variant = "default", isDisabled = false, isSelected = false, onSelectionChange, checkboxSize = "small", containerClassName, contentClassName, onClick, ...props }, ref) => {
2507
+ const [internalSelected, setInternalSelected] = React__namespace.useState(isSelected);
2508
+ // Sync internal state with prop
2509
+ React__namespace.useEffect(() => {
2510
+ setInternalSelected(isSelected);
2511
+ }, [isSelected]);
2512
+ const handleClick = (e) => {
2513
+ if (isDisabled)
2514
+ return;
2515
+ if (type === "multiple") {
2516
+ const newSelected = !internalSelected;
2517
+ setInternalSelected(newSelected);
2518
+ onSelectionChange?.(newSelected);
2519
+ }
2520
+ onClick?.(e);
2521
+ };
2522
+ const handleCheckboxChange = (e) => {
2523
+ e.stopPropagation();
2524
+ if (isDisabled)
2525
+ return;
2526
+ const newSelected = e.target.checked;
2527
+ setInternalSelected(newSelected);
2528
+ onSelectionChange?.(newSelected);
2529
+ };
2530
+ return (jsxRuntime.jsxs("div", { ref: ref, className: cn(listItemVariants({
2531
+ variant,
2532
+ isDisabled,
2533
+ isSelected: type === "multiple" ? internalSelected : false,
2534
+ }), containerClassName), onClick: handleClick, role: type === "multiple" ? "checkbox" : "button", "aria-checked": type === "multiple" ? internalSelected : undefined, "aria-disabled": isDisabled, tabIndex: isDisabled ? -1 : 0, ...props, children: [type === "multiple" && (jsxRuntime.jsx(Checkbox, { checked: internalSelected, onChange: handleCheckboxChange, isDisabled: isDisabled, size: checkboxSize, className: "shrink-0 mt-0.5" })), leadingIcon && (jsxRuntime.jsx("div", { className: cn(`shrink-0 flex items-center justify-center mt-0.5`, variant === "primary"
2535
+ ? "text-action-ink-primary-normal"
2536
+ : variant === "negative"
2537
+ ? "text-action-ink-negative-normal"
2538
+ : "text-action-ink-neutral-subtle", isDisabled && "text-surface-ink-neutral-disabled"), children: leadingIcon })), jsxRuntime.jsxs("div", { className: cn("flex-1 min-w-0 flex flex-col justify-center", contentClassName), children: [jsxRuntime.jsx("div", { className: cn("text-body-medium-regular truncate", variant === "primary"
2539
+ ? "text-action-ink-primary-normal"
2540
+ : variant === "negative"
2541
+ ? "text-action-ink-negative-normal"
2542
+ : "text-action-ink-neutral-normal", isDisabled && "text-surface-ink-neutral-disabled"), children: title }), description && (jsxRuntime.jsx("div", { className: cn("text-body-small-regular text-surface-ink-neutral-muted mt-0.5 line-clamp-2", isDisabled && "text-surface-ink-neutral-disabled"), children: description }))] }), (trailingIcon || showChevron) && (jsxRuntime.jsx("div", { className: "shrink-0 self-center text-action-ink-neutral-subtle", children: trailingIcon || jsxRuntime.jsx(ChevronRightIcon, {}) }))] }));
2543
+ });
2544
+ ListItem.displayName = "ListItem";
2545
+
2546
+ const dateRangePickerVariants = classVarianceAuthority.cva("relative flex items-center gap-2 border rounded-large transition-all font-functional font-size-100 leading-100 bg-surface-fill-neutral-intense", {
2547
+ variants: {
2548
+ size: {
2549
+ small: "h-[28px] px-3 text-xs gap-2",
2550
+ medium: "h-[36px] px-4 text-sm gap-2",
2551
+ large: "h-[44px] px-5 text-base gap-3",
2552
+ },
2553
+ isDisabled: {
2554
+ true: `
2555
+ border-[var(--border-width-thinner)]
2556
+ hover:border-action-outline-neutral-disabled
2557
+ border-action-outline-neutral-disabled
2558
+ bg-surface-fill-neutral-intense cursor-not-allowed opacity-60`,
2559
+ false: `
2560
+ border-action-outline-neutral-faded
2561
+ hover:border-action-outline-primary-hover
2562
+ focus-within:border-action-outline-primary-hover
2563
+ focus-within:ring-2
2564
+ ring-action-outline-primary-faded-hover`,
2565
+ },
2566
+ },
2567
+ defaultVariants: {
2568
+ size: "medium",
2569
+ isDisabled: false,
2570
+ },
2571
+ });
2572
+ // Default preset options
2573
+ const defaultPresets = [
2574
+ {
2575
+ label: "Today",
2576
+ value: "today",
2577
+ getDateRange: () => {
2578
+ const today = new Date();
2579
+ today.setHours(0, 0, 0, 0);
2580
+ return { startDate: today, endDate: today };
2581
+ },
2582
+ },
2583
+ {
2584
+ label: "Yesterday",
2585
+ value: "yesterday",
2586
+ getDateRange: () => {
2587
+ const yesterday = new Date();
2588
+ yesterday.setDate(yesterday.getDate() - 1);
2589
+ yesterday.setHours(0, 0, 0, 0);
2590
+ return { startDate: yesterday, endDate: yesterday };
2591
+ },
2592
+ },
2593
+ {
2594
+ label: "Last 7 days",
2595
+ value: "last7days",
2596
+ getDateRange: () => {
2597
+ const endDate = new Date();
2598
+ endDate.setHours(0, 0, 0, 0);
2599
+ const startDate = new Date();
2600
+ startDate.setDate(startDate.getDate() - 6);
2601
+ startDate.setHours(0, 0, 0, 0);
2602
+ return { startDate, endDate };
2603
+ },
2604
+ },
2605
+ {
2606
+ label: "Last 30 days",
2607
+ value: "last30days",
2608
+ getDateRange: () => {
2609
+ const endDate = new Date();
2610
+ endDate.setHours(0, 0, 0, 0);
2611
+ const startDate = new Date();
2612
+ startDate.setDate(startDate.getDate() - 29);
2613
+ startDate.setHours(0, 0, 0, 0);
2614
+ return { startDate, endDate };
2615
+ },
2616
+ },
2617
+ {
2618
+ label: "Last 6 months",
2619
+ value: "last6months",
2620
+ getDateRange: () => {
2621
+ const endDate = new Date();
2622
+ endDate.setHours(0, 0, 0, 0);
2623
+ const startDate = new Date();
2624
+ startDate.setMonth(startDate.getMonth() - 6);
2625
+ startDate.setHours(0, 0, 0, 0);
2626
+ return { startDate, endDate };
2627
+ },
2628
+ },
2629
+ {
2630
+ label: "All time",
2631
+ value: "alltime",
2632
+ getDateRange: () => {
2633
+ return { startDate: null, endDate: null };
2634
+ },
2635
+ },
2636
+ ];
2637
+ // Helper functions
2638
+ const parseDate = (date) => {
2639
+ if (!date)
2640
+ return null;
2641
+ if (date instanceof Date)
2642
+ return date;
2643
+ if (typeof date === "string") {
2644
+ const parsed = new Date(date);
2645
+ return isNaN(parsed.getTime()) ? null : parsed;
2646
+ }
2647
+ return null;
2648
+ };
2649
+ const formatDateDefault = (date) => {
2650
+ return date.toLocaleDateString("en-US", {
2651
+ year: "numeric",
2652
+ month: "short",
2653
+ day: "numeric",
2654
+ });
2655
+ };
2656
+ const isSameDay = (date1, date2) => {
2657
+ if (!date1 || !date2)
2658
+ return false;
2659
+ return (date1.getFullYear() === date2.getFullYear() &&
2660
+ date1.getMonth() === date2.getMonth() &&
2661
+ date1.getDate() === date2.getDate());
2662
+ };
2663
+ const formatMonthYear = (date) => {
2664
+ return date.toLocaleDateString("en-US", {
2665
+ month: "long",
2666
+ year: "numeric",
2667
+ });
2668
+ };
2669
+ const DateRangePicker = React__namespace.forwardRef(({ className, value: controlledValue, defaultValue, onChange, placeholder = "Select date range", isDisabled = false, size = "medium", triggerClassName, calendarClassName, minDate, maxDate, formatDate = formatDateDefault, presets = defaultPresets, showPresets = true, selectedPresetLabel, ...props }, ref) => {
2670
+ const [uncontrolledValue, setUncontrolledValue] = React__namespace.useState(defaultValue || { startDate: null, endDate: null });
2671
+ const [tempValue, setTempValue] = React__namespace.useState(defaultValue || { startDate: null, endDate: null });
2672
+ const [isOpen, setIsOpen] = React__namespace.useState(false);
2673
+ const [selectedPreset, setSelectedPreset] = React__namespace.useState(null);
2674
+ const [startMonth, setStartMonth] = React__namespace.useState(new Date());
2675
+ const [endMonth, setEndMonth] = React__namespace.useState(() => {
2676
+ const nextMonth = new Date();
2677
+ nextMonth.setMonth(nextMonth.getMonth() + 1);
2678
+ return nextMonth;
2679
+ });
2680
+ const datePickerRef = React__namespace.useRef(null);
2681
+ const calendarRef = React__namespace.useRef(null);
2682
+ const [position, setPosition] = React__namespace.useState({
2683
+ top: 0,
2684
+ left: 0,
2685
+ width: 0,
2686
+ bottom: 0,
2687
+ });
2688
+ const [dropdownPlacement, setDropdownPlacement] = React__namespace.useState("bottom");
2689
+ const [isInsideModal, setIsInsideModal] = React__namespace.useState(false);
2690
+ const value = controlledValue !== undefined ? controlledValue : uncontrolledValue;
2691
+ const hasValue = value.startDate !== null || value.endDate !== null;
2692
+ const handleOpenChange = (newOpen) => {
2693
+ if (!isDisabled) {
2694
+ setIsOpen(newOpen);
2695
+ if (newOpen) {
2696
+ // Set temp value to current value when opening
2697
+ setTempValue(value);
2698
+ }
2699
+ }
2700
+ };
2701
+ const toggleOpen = () => {
2702
+ handleOpenChange(!isOpen);
2703
+ };
2704
+ const handlePresetClick = (preset) => {
2705
+ const dateRange = preset.getDateRange();
2706
+ setTempValue(dateRange);
2707
+ setSelectedPreset(preset.value);
2708
+ };
2709
+ const handleStartDateChange = (value, event) => {
2710
+ const selectedDate = Array.isArray(value) ? value[0] : value;
2711
+ if (!selectedDate)
2712
+ return;
2713
+ const newStartDate = new Date(selectedDate);
2714
+ newStartDate.setHours(0, 0, 0, 0);
2715
+ setTempValue((prev) => ({
2716
+ startDate: newStartDate,
2717
+ endDate: prev.endDate,
2718
+ }));
2719
+ setSelectedPreset(null);
2720
+ };
2721
+ const handleEndDateChange = (value, event) => {
2722
+ const selectedDate = Array.isArray(value) ? value[0] : value;
2723
+ if (!selectedDate)
2724
+ return;
2725
+ const newEndDate = new Date(selectedDate);
2726
+ newEndDate.setHours(0, 0, 0, 0);
2727
+ setTempValue((prev) => ({
2728
+ startDate: prev.startDate,
2729
+ endDate: newEndDate,
2730
+ }));
2731
+ setSelectedPreset(null);
2732
+ };
2733
+ const handleApply = () => {
2734
+ if (controlledValue === undefined) {
2735
+ setUncontrolledValue(tempValue);
2736
+ }
2737
+ onChange?.(tempValue);
2738
+ setIsOpen(false);
2739
+ };
2740
+ const handleCancel = () => {
2741
+ setTempValue(value);
2742
+ setIsOpen(false);
2743
+ };
2744
+ const handlePrevStartMonth = () => {
2745
+ const newMonth = new Date(startMonth);
2746
+ newMonth.setMonth(newMonth.getMonth() - 1);
2747
+ setStartMonth(newMonth);
2748
+ };
2749
+ const handleNextStartMonth = () => {
2750
+ const newMonth = new Date(startMonth);
2751
+ newMonth.setMonth(newMonth.getMonth() + 1);
2752
+ setStartMonth(newMonth);
2753
+ };
2754
+ const handlePrevEndMonth = () => {
2755
+ const newMonth = new Date(endMonth);
2756
+ newMonth.setMonth(newMonth.getMonth() - 1);
2757
+ setEndMonth(newMonth);
2758
+ };
2759
+ const handleNextEndMonth = () => {
2760
+ const newMonth = new Date(endMonth);
2761
+ newMonth.setMonth(newMonth.getMonth() + 1);
2762
+ setEndMonth(newMonth);
2763
+ };
2764
+ // Check if date picker is inside a modal
2765
+ React__namespace.useEffect(() => {
2766
+ if (isOpen && datePickerRef.current) {
2767
+ let element = datePickerRef.current;
2768
+ let foundModal = false;
2769
+ while (element && !foundModal) {
2770
+ const styles = window.getComputedStyle(element);
2771
+ const zIndex = parseInt(styles.zIndex, 10);
2772
+ if (zIndex === 10000 || element.getAttribute("role") === "dialog") {
2773
+ foundModal = true;
2774
+ setIsInsideModal(true);
2775
+ break;
2776
+ }
2777
+ element = element.parentElement;
2778
+ }
2779
+ if (!foundModal) {
2780
+ setIsInsideModal(false);
2781
+ }
2782
+ }
2783
+ }, [isOpen]);
2784
+ // Update position and placement when calendar opens or window resizes
2785
+ React__namespace.useEffect(() => {
2786
+ if (isOpen && datePickerRef.current) {
2787
+ const updatePosition = () => {
2788
+ const rect = datePickerRef.current?.getBoundingClientRect();
2789
+ const calendarHeight = calendarRef.current?.offsetHeight || 600; // Estimated height
2790
+ if (rect) {
2791
+ const viewportHeight = window.innerHeight;
2792
+ const viewportWidth = window.innerWidth;
2793
+ const gap = 4;
2794
+ // Calculate available space
2795
+ const spaceBelow = viewportHeight - rect.bottom - gap;
2796
+ const spaceAbove = rect.top - gap;
2797
+ // Determine vertical placement
2798
+ const placement = spaceBelow >= calendarHeight || spaceBelow >= spaceAbove
2799
+ ? "bottom"
2800
+ : "top";
2801
+ setDropdownPlacement(placement);
2802
+ // Calculate horizontal position
2803
+ let leftPosition = rect.left;
2804
+ const calendarWidth = calendarRef.current?.offsetWidth || 900; // Estimated width
2805
+ // Adjust if dropdown would overflow right edge
2806
+ if (leftPosition + calendarWidth > viewportWidth) {
2807
+ leftPosition = viewportWidth - calendarWidth - 10; // 10px margin from edge
2808
+ }
2809
+ // Ensure it doesn't overflow left edge
2810
+ if (leftPosition < 10) {
2811
+ leftPosition = 10;
2812
+ }
2813
+ setPosition({
2814
+ top: rect.top,
2815
+ left: leftPosition,
2816
+ width: rect.width,
2817
+ bottom: rect.bottom,
2818
+ });
2819
+ }
2820
+ };
2821
+ updatePosition();
2822
+ // Small delay to ensure calendar is rendered for accurate measurements
2823
+ const timeoutId = setTimeout(updatePosition, 10);
2824
+ window.addEventListener("resize", updatePosition);
2825
+ window.addEventListener("scroll", updatePosition, true);
2826
+ return () => {
2827
+ clearTimeout(timeoutId);
2828
+ window.removeEventListener("resize", updatePosition);
2829
+ window.removeEventListener("scroll", updatePosition, true);
2830
+ };
2831
+ }
2832
+ }, [isOpen]);
2833
+ // Close calendar when clicking outside
2834
+ React__namespace.useEffect(() => {
2835
+ const handleClickOutside = (event) => {
2836
+ if (datePickerRef.current &&
2837
+ !datePickerRef.current.contains(event.target) &&
2838
+ calendarRef.current &&
2839
+ !calendarRef.current.contains(event.target)) {
2840
+ handleCancel();
2841
+ }
2842
+ };
2843
+ if (isOpen) {
2844
+ document.addEventListener("mousedown", handleClickOutside);
2845
+ return () => {
2846
+ document.removeEventListener("mousedown", handleClickOutside);
2847
+ };
2848
+ }
2849
+ }, [isOpen, value]);
2850
+ // Close on escape key
2851
+ React__namespace.useEffect(() => {
2852
+ const handleEscape = (event) => {
2853
+ if (event.key === "Escape") {
2854
+ handleCancel();
2855
+ }
2856
+ };
2857
+ if (isOpen) {
2858
+ document.addEventListener("keydown", handleEscape);
2859
+ return () => {
2860
+ document.removeEventListener("keydown", handleEscape);
2861
+ };
2862
+ }
2863
+ }, [isOpen, value]);
2864
+ const minDateParsed = parseDate(minDate);
2865
+ const maxDateParsed = parseDate(maxDate);
2866
+ const getDisplayText = () => {
2867
+ if (selectedPresetLabel) {
2868
+ return selectedPresetLabel;
2869
+ }
2870
+ if (selectedPreset) {
2871
+ const preset = presets.find((p) => p.value === selectedPreset);
2872
+ if (preset)
2873
+ return preset.label;
2874
+ }
2875
+ if (!hasValue) {
2876
+ return placeholder;
2877
+ }
2878
+ if (value.startDate && value.endDate) {
2879
+ if (isSameDay(value.startDate, value.endDate)) {
2880
+ return formatDate(value.startDate);
2881
+ }
2882
+ return `${formatDate(value.startDate)} - ${formatDate(value.endDate)}`;
2883
+ }
2884
+ if (value.startDate) {
2885
+ return `From ${formatDate(value.startDate)}`;
2886
+ }
2887
+ if (value.endDate) {
2888
+ return `Until ${formatDate(value.endDate)}`;
2889
+ }
2890
+ return placeholder;
2891
+ };
2892
+ return (jsxRuntime.jsxs("div", { ref: datePickerRef, className: cn("relative w-fit", className), children: [jsxRuntime.jsxs("div", { className: cn(dateRangePickerVariants({
2893
+ size,
2894
+ isDisabled,
2895
+ }), "cursor-pointer", triggerClassName), onClick: !isDisabled ? toggleOpen : undefined, role: "button", "aria-haspopup": "dialog", "aria-expanded": isOpen, "aria-disabled": isDisabled, ...props, children: [jsxRuntime.jsx(lucideReact.Calendar, { className: cn("shrink-0 w-4 h-4", isDisabled
2896
+ ? "text-surface-ink-neutral-disabled"
2897
+ : "text-surface-ink-neutral-muted") }), jsxRuntime.jsx("span", { className: cn("flex-1 text-left truncate", !hasValue && "text-surface-ink-neutral-muted", isDisabled && "text-surface-ink-neutral-disabled"), children: getDisplayText() }), jsxRuntime.jsx(Icon, { name: "chevronDown", size: 16, className: cn("shrink-0 transition-transform", isDisabled
2898
+ ? "text-surface-ink-neutral-disabled"
2899
+ : "text-surface-ink-neutral-muted", isOpen && "rotate-180") })] }), typeof document !== "undefined" &&
2900
+ isOpen &&
2901
+ !isDisabled &&
2902
+ (() => {
2903
+ const gap = 4;
2904
+ const calendarHeight = calendarRef.current?.offsetHeight || 0;
2905
+ // Calculate top position based on placement
2906
+ const calendarTop = dropdownPlacement === "bottom"
2907
+ ? position.bottom + gap
2908
+ : position.top - calendarHeight - gap;
2909
+ const calendarPopup = (jsxRuntime.jsx("div", { ref: calendarRef, style: {
2910
+ position: "fixed",
2911
+ top: `${calendarTop}px`,
2912
+ left: `${position.left}px`,
2913
+ zIndex: isInsideModal ? 10001 : 9999,
2914
+ maxHeight: dropdownPlacement === "bottom"
2915
+ ? `${window.innerHeight - position.bottom - gap - 10}px`
2916
+ : `${position.top - gap - 10}px`,
2917
+ overflowY: "auto",
2918
+ }, className: cn("bg-surface-fill-neutral-intense rounded-large shadow-lg border border-surface-outline-neutral-subtle", calendarClassName), onClick: (e) => e.stopPropagation(), children: jsxRuntime.jsxs("div", { className: "flex", children: [showPresets && presets.length > 0 && (jsxRuntime.jsx("div", { className: "w-48 border-r border-surface-outline-neutral-subtle p-4 flex flex-col", children: presets.map((preset) => (jsxRuntime.jsx(ListItem, { title: preset.label, type: "single", showChevron: false, isSelected: selectedPreset === preset.value, onClick: () => handlePresetClick(preset), containerClassName: "mb-1 last:mb-0" }, preset.value))) })), jsxRuntime.jsxs("div", { className: "p-4", children: [jsxRuntime.jsxs("div", { className: "flex gap-6", children: [jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [jsxRuntime.jsx("div", { className: "flex flex-col px-3", children: jsxRuntime.jsx("p", { className: "text-body-small-medium", children: "Start Date" }) }), jsxRuntime.jsxs("div", { className: "flex flex-col p-5 rounded-[8px] bg-surface-fill-neutral-moderate", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-3 px-3", children: [jsxRuntime.jsx("h3", { className: "text-body-small-medium font-medium text-surface-ink-neutral-normal", children: formatMonthYear(startMonth) }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("button", { onClick: handlePrevStartMonth, className: "p-1 hover:bg-surface-fill-neutral-faded rounded transition-colors", "aria-label": "Previous month", children: jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "w-4 h-4 text-surface-ink-neutral-normal" }) }), jsxRuntime.jsx("button", { onClick: handleNextStartMonth, className: "p-1 hover:bg-surface-fill-neutral-faded rounded transition-colors", "aria-label": "Next month", children: jsxRuntime.jsx(lucideReact.ChevronRight, { className: "w-4 h-4 text-surface-ink-neutral-normal" }) })] })] }), jsxRuntime.jsx("div", { className: "date-range-calendar-wrapper", children: jsxRuntime.jsx(Calendar, { onChange: handleStartDateChange, value: tempValue.startDate, minDate: minDateParsed ?? undefined, maxDate: tempValue.endDate
2919
+ ? tempValue.endDate
2920
+ : maxDateParsed ?? undefined, activeStartDate: startMonth, onActiveStartDateChange: ({ activeStartDate, }) => {
2921
+ if (activeStartDate)
2922
+ setStartMonth(activeStartDate);
2923
+ }, locale: "en-US", showNavigation: false, showNeighboringMonth: true, showFixedNumberOfWeeks: true, formatShortWeekday: (locale, date) => {
2924
+ const weekdayNames = [
2925
+ "SUN",
2926
+ "MON",
2927
+ "TUE",
2928
+ "WED",
2929
+ "THU",
2930
+ "FRI",
2931
+ "SAT",
2932
+ ];
2933
+ return weekdayNames[date.getDay()];
2934
+ } }) })] })] }), jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 ", children: [jsxRuntime.jsx("div", { className: "flex flex-col px-3", children: jsxRuntime.jsx("p", { className: "text-body-small-medium", children: "End Date" }) }), jsxRuntime.jsxs("div", { className: "flex flex-col p-5 rounded-[8px] bg-surface-fill-neutral-moderate", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-3 px-3", children: [jsxRuntime.jsx("h3", { className: "text-body-small-medium font-medium text-surface-ink-neutral-normal", children: formatMonthYear(endMonth) }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("button", { onClick: handlePrevEndMonth, className: "p-1 hover:bg-surface-fill-neutral-faded rounded transition-colors", "aria-label": "Previous month", children: jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "w-4 h-4 text-surface-ink-neutral-normal" }) }), jsxRuntime.jsx("button", { onClick: handleNextEndMonth, className: "p-1 hover:bg-surface-fill-neutral-faded rounded transition-colors", "aria-label": "Next month", children: jsxRuntime.jsx(lucideReact.ChevronRight, { className: "w-4 h-4 text-surface-ink-neutral-normal" }) })] })] }), jsxRuntime.jsx("div", { className: "date-range-calendar-wrapper", children: jsxRuntime.jsx(Calendar, { onChange: handleEndDateChange, value: tempValue.endDate, minDate: tempValue.startDate
2935
+ ? tempValue.startDate
2936
+ : minDateParsed ?? undefined, maxDate: maxDateParsed ?? undefined, activeStartDate: endMonth, onActiveStartDateChange: ({ activeStartDate, }) => {
2937
+ if (activeStartDate)
2938
+ setEndMonth(activeStartDate);
2939
+ }, locale: "en-US", showNavigation: false, showNeighboringMonth: true, showFixedNumberOfWeeks: true, formatShortWeekday: (locale, date) => {
2940
+ const weekdayNames = [
2941
+ "SUN",
2942
+ "MON",
2943
+ "TUE",
2944
+ "WED",
2945
+ "THU",
2946
+ "FRI",
2947
+ "SAT",
2948
+ ];
2949
+ return weekdayNames[date.getDay()];
2950
+ } }) })] })] })] }), jsxRuntime.jsxs("div", { className: "mt-4 pt-4 border-t border-surface-outline-neutral-subtle flex items-center justify-between", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("div", { className: "w-2 h-2 rounded-full bg-action-fill-primary-default" }), jsxRuntime.jsx("span", { className: "text-sm text-surface-ink-neutral-normal", children: tempValue.startDate && tempValue.endDate
2951
+ ? isSameDay(tempValue.startDate, tempValue.endDate)
2952
+ ? "Today"
2953
+ : `${formatDate(tempValue.startDate)} - ${formatDate(tempValue.endDate)}`
2954
+ : tempValue.startDate
2955
+ ? `From ${formatDate(tempValue.startDate)}`
2956
+ : tempValue.endDate
2957
+ ? `Until ${formatDate(tempValue.endDate)}`
2958
+ : "No selection" })] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx(Button, { variant: "secondary", color: "neutral", size: "small", onClick: handleCancel, children: "Cancel" }), jsxRuntime.jsx(Button, { variant: "primary", color: "primary", size: "small", onClick: handleApply, children: "Apply date range" })] })] })] })] }) }));
2959
+ return reactDom.createPortal(calendarPopup, document.body);
2960
+ })()] }));
2961
+ });
2962
+ DateRangePicker.displayName = "DateRangePicker";
2963
+
2468
2964
  const dividerVariants = classVarianceAuthority.cva("", {
2469
2965
  variants: {
2470
2966
  orientation: {
@@ -2558,84 +3054,6 @@ const Divider = React__namespace.forwardRef(({ className, orientation = "horizon
2558
3054
  });
2559
3055
  Divider.displayName = "Divider";
2560
3056
 
2561
- const listItemVariants = classVarianceAuthority.cva("flex items-start gap-3 p-3 rounded-medium transition-colors cursor-pointer", {
2562
- variants: {
2563
- variant: {
2564
- default: `hover:bg-action-fill-neutral-faded
2565
- focus:bg-action-fill-neutral-faded
2566
- focus:ring-2
2567
- ring-action-outline-primary-faded-hover
2568
- border border-transparent
2569
- `,
2570
- bordered: "border border-action-outline-primary-faded hover:bg-surface-fill-primary-subtle",
2571
- primary: `hover:bg-action-fill-neutral-faded
2572
- focus:bg-action-fill-neutral-faded
2573
- focus:ring-2
2574
- ring-action-outline-primary-faded-hover
2575
- border border-transparent
2576
- `,
2577
- negative: `hover:bg-action-fill-negative-faded
2578
- focus:bg-action-fill-negative-faded
2579
- focus:ring-2 ring-action-outline-negative-faded-hover
2580
- border border-transparent
2581
- `,
2582
- },
2583
- isDisabled: {
2584
- true: "cursor-not-allowed opacity-60",
2585
- false: "",
2586
- },
2587
- isSelected: {
2588
- true: "bg-action-fill-primary-faded border-action-outline-primary-faded",
2589
- false: "",
2590
- },
2591
- },
2592
- defaultVariants: {
2593
- variant: "default",
2594
- isDisabled: false,
2595
- isSelected: false,
2596
- },
2597
- });
2598
- const ChevronRightIcon = ({ className }) => (jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: className, children: jsxRuntime.jsx("path", { d: "M7.5 15L12.5 10L7.5 5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }));
2599
- const ListItem = React__namespace.forwardRef(({ className, type = "single", leadingIcon, title, description, trailingIcon, showChevron = true, variant = "default", isDisabled = false, isSelected = false, onSelectionChange, checkboxSize = "small", containerClassName, contentClassName, onClick, ...props }, ref) => {
2600
- const [internalSelected, setInternalSelected] = React__namespace.useState(isSelected);
2601
- // Sync internal state with prop
2602
- React__namespace.useEffect(() => {
2603
- setInternalSelected(isSelected);
2604
- }, [isSelected]);
2605
- const handleClick = (e) => {
2606
- if (isDisabled)
2607
- return;
2608
- if (type === "multiple") {
2609
- const newSelected = !internalSelected;
2610
- setInternalSelected(newSelected);
2611
- onSelectionChange?.(newSelected);
2612
- }
2613
- onClick?.(e);
2614
- };
2615
- const handleCheckboxChange = (e) => {
2616
- e.stopPropagation();
2617
- if (isDisabled)
2618
- return;
2619
- const newSelected = e.target.checked;
2620
- setInternalSelected(newSelected);
2621
- onSelectionChange?.(newSelected);
2622
- };
2623
- return (jsxRuntime.jsxs("div", { ref: ref, className: cn(listItemVariants({
2624
- variant,
2625
- isDisabled,
2626
- isSelected: type === "multiple" ? internalSelected : false,
2627
- }), containerClassName), onClick: handleClick, role: type === "multiple" ? "checkbox" : "button", "aria-checked": type === "multiple" ? internalSelected : undefined, "aria-disabled": isDisabled, tabIndex: isDisabled ? -1 : 0, ...props, children: [type === "multiple" && (jsxRuntime.jsx(Checkbox, { checked: internalSelected, onChange: handleCheckboxChange, isDisabled: isDisabled, size: checkboxSize, className: "shrink-0 mt-0.5" })), leadingIcon && (jsxRuntime.jsx("div", { className: cn(`shrink-0 flex items-center justify-center mt-0.5`, variant === "primary"
2628
- ? "text-action-ink-primary-normal"
2629
- : variant === "negative"
2630
- ? "text-action-ink-negative-normal"
2631
- : "text-action-ink-neutral-subtle", isDisabled && "text-surface-ink-neutral-disabled"), children: leadingIcon })), jsxRuntime.jsxs("div", { className: cn("flex-1 min-w-0 flex flex-col justify-center", contentClassName), children: [jsxRuntime.jsx("div", { className: cn("text-body-medium-regular truncate", variant === "primary"
2632
- ? "text-action-ink-primary-normal"
2633
- : variant === "negative"
2634
- ? "text-action-ink-negative-normal"
2635
- : "text-action-ink-neutral-normal", isDisabled && "text-surface-ink-neutral-disabled"), children: title }), description && (jsxRuntime.jsx("div", { className: cn("text-body-small-regular text-surface-ink-neutral-muted mt-0.5 line-clamp-2", isDisabled && "text-surface-ink-neutral-disabled"), children: description }))] }), (trailingIcon || showChevron) && (jsxRuntime.jsx("div", { className: "shrink-0 self-center text-action-ink-neutral-subtle", children: trailingIcon || jsxRuntime.jsx(ChevronRightIcon, {}) }))] }));
2636
- });
2637
- ListItem.displayName = "ListItem";
2638
-
2639
3057
  const DropdownMenu = React__namespace.forwardRef(({ items = [], customContent, customContentClassName, sectionHeading, isLoading = false, isEmpty = false, emptyTitle = "No Search Results Found", emptyDescription = "Add description of what the user can search for here.", emptyLinkText = "Link to support site", onEmptyLinkClick, primaryButtonText = "Primary", secondaryButtonText = "Secondary", onPrimaryClick, onSecondaryClick, showChevron = false, emptyIcon, disableFooter = false, showFooter, footerLayout = "horizontal", onClose, focusedIndex = -1, className, width = "auto", maxHeight = "400px", }, ref) => {
2640
3058
  const renderContent = () => {
2641
3059
  if (isLoading) {
@@ -5561,6 +5979,7 @@ exports.ButtonGroup = ButtonGroup;
5561
5979
  exports.Checkbox = Checkbox;
5562
5980
  exports.Counter = Counter;
5563
5981
  exports.DatePicker = DatePicker;
5982
+ exports.DateRangePicker = DateRangePicker;
5564
5983
  exports.Divider = Divider;
5565
5984
  exports.Dropdown = Dropdown;
5566
5985
  exports.DropdownMenu = DropdownMenu;
@@ -5604,6 +6023,7 @@ exports.checkboxVariants = checkboxVariants;
5604
6023
  exports.cn = cn;
5605
6024
  exports.counterVariants = counterVariants;
5606
6025
  exports.datePickerVariants = datePickerVariants;
6026
+ exports.dateRangePickerVariants = dateRangePickerVariants;
5607
6027
  exports.dropdownVariants = dropdownVariants;
5608
6028
  exports.getAvailableIcons = getAvailableIcons;
5609
6029
  exports.hasIcon = hasIcon;