infinity-ui-elements 1.8.57 → 1.8.59

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.esm.js CHANGED
@@ -5,7 +5,7 @@ import { Slot } from '@radix-ui/react-slot';
5
5
  import { PulseLoader, ClipLoader } from 'react-spinners';
6
6
  import { clsx } from 'clsx';
7
7
  import { twMerge } from 'tailwind-merge';
8
- import { ExternalLink, Calendar, X, Loader2, Search, ChevronDown, ChevronLeft, ChevronRight } from 'lucide-react';
8
+ import { ExternalLink, Calendar, X, Loader2, Search, ChevronLeft, ChevronRight, ChevronDown } from 'lucide-react';
9
9
  import { createPortal } from 'react-dom';
10
10
  import Calendar$1 from 'react-calendar';
11
11
  import 'react-calendar/dist/Calendar.css';
@@ -68,6 +68,14 @@ const iconRegistry = {
68
68
  file: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
69
69
  <path d="M19.1111 21H4.88889C4.39797 21 4 20.5971 4 20.1V3.9C4 3.40295 4.39797 3 4.88889 3H19.1111C19.602 3 20 3.40295 20 3.9V20.1C20 20.5971 19.602 21 19.1111 21ZM18.2222 19.2V4.8H5.77778V19.2H18.2222ZM8.44444 9.3H15.5556V11.1H8.44444V9.3ZM8.44444 12.9H15.5556V14.7H8.44444V12.9Z" fill="#081416"/>
70
70
  </svg>
71
+ `,
72
+ chevronDown: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
73
+ <path d="M12 13.7272L17.4445 8L19 9.63635L12 17L5 9.63635L6.55555 8L12 13.7272Z" fill="#081416"/>
74
+ </svg>
75
+ `,
76
+ chevronUp: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
77
+ <path d="M12 11.2727L6.55555 17L5 15.3637L12 8L19 15.3637L17.4445 17L12 11.2727Z" fill="#081416"/>
78
+ </svg>
71
79
  `,
72
80
  };
73
81
  const Icon = ({ name, size = 24, className = "", style = {}, ...props }) => {
@@ -2830,7 +2838,7 @@ const Modal = React.forwardRef(({ isOpen, onClose, title, description, footer, c
2830
2838
  });
2831
2839
  Modal.displayName = "Modal";
2832
2840
 
2833
- const selectVariants = cva("relative flex items-center gap-2 border rounded-large transition-all font-functional font-size-100 leading-100", {
2841
+ const textFieldVariants = cva("relative flex items-center gap-3 border rounded-large transition-all font-functional font-size-100 leading-100", {
2834
2842
  variants: {
2835
2843
  size: {
2836
2844
  small: "h-[28px] px-3 text-xs gap-2",
@@ -2840,10 +2848,11 @@ const selectVariants = cva("relative flex items-center gap-2 border rounded-larg
2840
2848
  validationState: {
2841
2849
  none: `
2842
2850
  border-action-outline-neutral-faded
2843
- hover:border-action-outline-primary-hover
2844
- focus-within:border-action-outline-primary-hover
2851
+ hover:border-action-outline-neutral-faded-hover
2852
+ hover:bg-action-fill-neutral-faded-hover
2853
+ focus-within:border-action-outline-primary-default
2845
2854
  focus-within:ring-2
2846
- ring-action-outline-primary-faded-hover`,
2855
+ ring-surface-outline-primary-muted`,
2847
2856
  positive: `
2848
2857
  border-action-outline-positive-default
2849
2858
  focus-within:border-action-outline-positive-hover
@@ -2856,11 +2865,13 @@ const selectVariants = cva("relative flex items-center gap-2 border rounded-larg
2856
2865
  },
2857
2866
  isDisabled: {
2858
2867
  true: `
2859
- border-[var(--border-width-thinner)]
2860
- hover:border-action-outline-neutral-disabled
2868
+ border
2861
2869
  border-action-outline-neutral-disabled
2862
- bg-surface-fill-neutral-intense cursor-not-allowed opacity-60`,
2863
- false: "bg-surface-fill-neutral-intense",
2870
+ hover:border-action-outline-neutral-disabled
2871
+ bg-surface-fill-neutral-intense
2872
+ hover:bg-surface-fill-neutral-intense
2873
+ cursor-not-allowed`,
2874
+ false: "",
2864
2875
  },
2865
2876
  },
2866
2877
  defaultVariants: {
@@ -2869,23 +2880,83 @@ const selectVariants = cva("relative flex items-center gap-2 border rounded-larg
2869
2880
  isDisabled: false,
2870
2881
  },
2871
2882
  });
2883
+ const TextField = React.forwardRef(({ label, helperText, errorText, successText, size = "medium", validationState = "none", isDisabled = false, isLoading = false, isRequired = false, isOptional = false, prefix, suffix, showClearButton = false, infoDescription, infoHeading, LinkComponent, linkText, linkHref, onLinkClick, onClear, containerClassName, labelClassName, inputClassName, className, value, onChange, ...props }, ref) => {
2884
+ const [internalValue, setInternalValue] = React.useState("");
2885
+ const inputValue = value !== undefined ? value : internalValue;
2886
+ const hasValue = inputValue && String(inputValue).length > 0;
2887
+ const handleChange = (e) => {
2888
+ if (onChange) {
2889
+ onChange(e);
2890
+ }
2891
+ else {
2892
+ setInternalValue(e.target.value);
2893
+ }
2894
+ };
2895
+ const handleClear = () => {
2896
+ if (onClear) {
2897
+ onClear();
2898
+ }
2899
+ else {
2900
+ setInternalValue("");
2901
+ }
2902
+ // Focus the input after clearing
2903
+ const input = document.getElementById(props.id || "");
2904
+ if (input) {
2905
+ input.focus();
2906
+ }
2907
+ };
2908
+ // Determine which helper text to show
2909
+ const displayHelperText = errorText || successText || helperText;
2910
+ const currentValidationState = errorText
2911
+ ? "negative"
2912
+ : successText
2913
+ ? "positive"
2914
+ : validationState;
2915
+ const sizeConfig = {
2916
+ small: {
2917
+ gap: "gap-2",
2918
+ },
2919
+ medium: {
2920
+ gap: "gap-2",
2921
+ },
2922
+ large: {
2923
+ gap: "gap-3",
2924
+ },
2925
+ };
2926
+ return (jsxs("div", { className: cn("w-full flex flex-col", sizeConfig[size].gap, containerClassName), children: [label && (jsx(FormHeader, { label: label, size: size, isRequired: isRequired, isOptional: isOptional, infoHeading: infoHeading, infoDescription: infoDescription, LinkComponent: LinkComponent, linkText: linkText, linkHref: linkHref, onLinkClick: onLinkClick, htmlFor: props.id, className: "mb-2", labelClassName: labelClassName })), jsxs("div", { className: cn(textFieldVariants({
2927
+ size,
2928
+ validationState: currentValidationState,
2929
+ isDisabled,
2930
+ }), isLoading && "text-field-loading", className), children: [prefix && (jsx("span", { className: cn("shrink-0 flex items-center", isDisabled
2931
+ ? "text-surface-ink-neutral-disabled"
2932
+ : currentValidationState === "positive"
2933
+ ? "text-feedback-ink-positive-intense"
2934
+ : currentValidationState === "negative"
2935
+ ? "text-feedback-ink-negative-subtle"
2936
+ : "text-surface-ink-neutral-muted"), children: prefix })), jsx("input", { ref: ref, value: inputValue, onChange: handleChange, disabled: isDisabled, required: isRequired, className: cn("flex-1 bg-transparent border-none outline-none text-surface-ink-neutral-normal placeholder:text-surface-ink-neutral-muted disabled:cursor-not-allowed disabled:text-surface-ink-neutral-disabled", inputClassName), ...props }), showClearButton && hasValue && !isDisabled && (jsx("button", { type: "button", onClick: handleClear, className: "shrink-0 flex items-center justify-center text-surface-ink-neutral-muted hover:text-surface-ink-neutral-normal transition-colors", tabIndex: -1, children: jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: jsx("path", { d: "M12 4L4 12M4 4L12 12", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) }) })), suffix && (jsx("span", { className: cn("shrink-0 flex items-center", isDisabled
2937
+ ? "text-surface-ink-neutral-disabled"
2938
+ : currentValidationState === "positive"
2939
+ ? "text-feedback-ink-positive-intense"
2940
+ : currentValidationState === "negative"
2941
+ ? "text-feedback-ink-negative-subtle"
2942
+ : "text-surface-ink-neutral-muted"), children: suffix }))] }), jsx(FormFooter, { helperText: displayHelperText, validationState: currentValidationState === "none"
2943
+ ? "default"
2944
+ : currentValidationState, size: size, isDisabled: isDisabled, className: "mt-1" })] }));
2945
+ });
2946
+ TextField.displayName = "TextField";
2947
+
2872
2948
  const Select = React.forwardRef(({ className, options = [], value: controlledValue, defaultValue, onChange, placeholder = "Select an option", label, helperText, errorText, successText, validationState = "none", isDisabled = false, isRequired = false, isOptional = false, isLoading = false, size = "medium", prefix, suffix, showClearButton = false, onClear, showLeadingIcon = false, containerClassName, labelClassName, triggerClassName, menuClassName, menuWidth = "full", sectionHeading, emptyTitle = "No options available", emptyDescription = "There are no options to select from.", emptyIcon, infoHeading, infoDescription, LinkComponent, linkText, linkHref, onLinkClick, ...props }, ref) => {
2873
2949
  const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue);
2874
2950
  const [isOpen, setIsOpen] = React.useState(false);
2875
2951
  const [dropdownPlacement, setDropdownPlacement] = React.useState("bottom");
2876
- const selectRef = React.useRef(null);
2952
+ const containerRef = React.useRef(null);
2877
2953
  const dropdownContainerRef = React.useRef(null);
2954
+ const inputRef = React.useRef(null);
2955
+ React.useImperativeHandle(ref, () => inputRef.current);
2878
2956
  const value = controlledValue !== undefined ? controlledValue : uncontrolledValue;
2879
2957
  // Find the selected option
2880
2958
  const selectedOption = options.find((opt) => opt.value === value);
2881
2959
  const hasValue = value !== undefined && value !== "";
2882
- // Determine which helper text to show
2883
- const displayHelperText = errorText || successText || helperText;
2884
- const currentValidationState = errorText
2885
- ? "negative"
2886
- : successText
2887
- ? "positive"
2888
- : validationState;
2889
2960
  const handleOpenChange = (newOpen) => {
2890
2961
  if (!isDisabled && !isLoading) {
2891
2962
  setIsOpen(newOpen);
@@ -2900,9 +2971,9 @@ const Select = React.forwardRef(({ className, options = [], value: controlledVal
2900
2971
  }
2901
2972
  onChange?.(option.value, option);
2902
2973
  setIsOpen(false);
2974
+ inputRef.current?.focus();
2903
2975
  };
2904
- const handleClear = (e) => {
2905
- e.stopPropagation();
2976
+ const handleClear = () => {
2906
2977
  if (onClear) {
2907
2978
  onClear();
2908
2979
  }
@@ -2916,7 +2987,7 @@ const Select = React.forwardRef(({ className, options = [], value: controlledVal
2916
2987
  const updateDropdownPlacement = React.useCallback(() => {
2917
2988
  if (typeof window === "undefined")
2918
2989
  return;
2919
- const trigger = selectRef.current;
2990
+ const trigger = containerRef.current;
2920
2991
  if (!trigger)
2921
2992
  return;
2922
2993
  const triggerRect = trigger.getBoundingClientRect();
@@ -2965,8 +3036,10 @@ const Select = React.forwardRef(({ className, options = [], value: controlledVal
2965
3036
  // Close dropdown when clicking outside
2966
3037
  React.useEffect(() => {
2967
3038
  const handleClickOutside = (event) => {
2968
- if (selectRef.current &&
2969
- !selectRef.current.contains(event.target)) {
3039
+ if (containerRef.current &&
3040
+ !containerRef.current.contains(event.target) &&
3041
+ dropdownContainerRef.current &&
3042
+ !dropdownContainerRef.current.contains(event.target)) {
2970
3043
  handleOpenChange(false);
2971
3044
  }
2972
3045
  };
@@ -2992,35 +3065,27 @@ const Select = React.forwardRef(({ className, options = [], value: controlledVal
2992
3065
  }
2993
3066
  }, [isOpen]);
2994
3067
  // Handle keyboard navigation
2995
- React.useEffect(() => {
2996
- const handleKeyDown = (event) => {
2997
- if (isDisabled || isLoading)
2998
- return;
2999
- if (!isOpen && (event.key === "Enter" || event.key === " ")) {
3068
+ const handleKeyDown = (event) => {
3069
+ if (isDisabled || isLoading)
3070
+ return;
3071
+ if (!isOpen && (event.key === "Enter" || event.key === " ")) {
3072
+ event.preventDefault();
3073
+ setIsOpen(true);
3074
+ return;
3075
+ }
3076
+ if (isOpen) {
3077
+ if (event.key === "ArrowDown" || event.key === "ArrowUp") {
3000
3078
  event.preventDefault();
3001
- setIsOpen(true);
3002
- return;
3003
- }
3004
- if (isOpen) {
3005
- if (event.key === "ArrowDown" || event.key === "ArrowUp") {
3006
- event.preventDefault();
3007
- const currentIndex = options.findIndex((opt) => opt.value === value);
3008
- const nextIndex = event.key === "ArrowDown"
3009
- ? Math.min(currentIndex + 1, options.length - 1)
3010
- : Math.max(currentIndex - 1, 0);
3011
- if (options[nextIndex] && !options[nextIndex].isDisabled) {
3012
- handleSelect(options[nextIndex]);
3013
- }
3079
+ const currentIndex = options.findIndex((opt) => opt.value === value);
3080
+ const nextIndex = event.key === "ArrowDown"
3081
+ ? Math.min(currentIndex + 1, options.length - 1)
3082
+ : Math.max(currentIndex - 1, 0);
3083
+ if (options[nextIndex] && !options[nextIndex].isDisabled) {
3084
+ handleSelect(options[nextIndex]);
3014
3085
  }
3015
3086
  }
3016
- };
3017
- if (selectRef.current) {
3018
- selectRef.current.addEventListener("keydown", handleKeyDown);
3019
- return () => {
3020
- selectRef.current?.removeEventListener("keydown", handleKeyDown);
3021
- };
3022
3087
  }
3023
- }, [isOpen, value, options, isDisabled, isLoading]);
3088
+ };
3024
3089
  // Transform options to dropdown menu items
3025
3090
  const menuItems = options.map((option) => ({
3026
3091
  value: option.value,
@@ -3033,50 +3098,20 @@ const Select = React.forwardRef(({ className, options = [], value: controlledVal
3033
3098
  onClick: () => handleSelect(option),
3034
3099
  }));
3035
3100
  const widthStyle = menuWidth === "full" ? "100%" : menuWidth === "auto" ? "auto" : menuWidth;
3036
- const sizeConfig = {
3037
- small: {
3038
- gap: "gap-2",
3039
- },
3040
- medium: {
3041
- gap: "gap-2",
3042
- },
3043
- large: {
3044
- gap: "gap-3",
3045
- },
3046
- };
3047
- return (jsxs("div", { className: cn("w-full flex flex-col", sizeConfig[size].gap, containerClassName), children: [label && (jsx(FormHeader, { label: label, size: size, isRequired: isRequired, isOptional: isOptional, infoHeading: infoHeading, infoDescription: infoDescription, LinkComponent: LinkComponent, linkText: linkText, linkHref: linkHref, onLinkClick: onLinkClick, htmlFor: props.id, className: "mb-2", labelClassName: labelClassName })), jsxs("div", { ref: selectRef, className: cn(selectVariants({
3048
- size,
3049
- validationState: currentValidationState,
3050
- isDisabled,
3051
- }), "relative w-full cursor-pointer", className), onClick: !isDisabled && !isLoading ? toggleOpen : undefined, role: "combobox", "aria-haspopup": "listbox", "aria-expanded": isOpen, "aria-disabled": isDisabled, ...props, children: [prefix ? (jsx("span", { className: cn("shrink-0 flex items-center", isDisabled
3052
- ? "text-surface-ink-neutral-disabled"
3053
- : currentValidationState === "positive"
3054
- ? "text-feedback-ink-positive-intense"
3055
- : currentValidationState === "negative"
3056
- ? "text-feedback-ink-negative-subtle"
3057
- : "text-surface-ink-neutral-muted"), children: prefix })) : showLeadingIcon && selectedOption?.leadingIcon ? (jsx("span", { className: cn("shrink-0 flex items-center", isDisabled
3058
- ? "text-surface-ink-neutral-disabled"
3059
- : currentValidationState === "positive"
3060
- ? "text-feedback-ink-positive-intense"
3061
- : currentValidationState === "negative"
3062
- ? "text-feedback-ink-negative-subtle"
3063
- : "text-surface-ink-neutral-muted"), children: selectedOption.leadingIcon })) : null, jsx("span", { className: cn("flex-1 text-left truncate", !selectedOption && "text-surface-ink-neutral-muted", isDisabled && "text-surface-ink-neutral-disabled"), children: isLoading ? "Loading..." : selectedOption?.label || placeholder }), showClearButton && hasValue && !isDisabled && !isLoading && (jsx("button", { type: "button", onClick: handleClear, className: "shrink-0 flex items-center justify-center text-surface-ink-neutral-muted hover:text-surface-ink-neutral-normal transition-colors", tabIndex: -1, children: jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: jsx("path", { d: "M12 4L4 12M4 4L12 12", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) }) })), suffix && !showClearButton && (jsx("span", { className: cn("shrink-0 flex items-center", isDisabled
3064
- ? "text-surface-ink-neutral-disabled"
3065
- : currentValidationState === "positive"
3066
- ? "text-feedback-ink-positive-intense"
3067
- : currentValidationState === "negative"
3068
- ? "text-feedback-ink-negative-subtle"
3069
- : "text-surface-ink-neutral-muted"), children: suffix })), jsx(ChevronDown, { className: cn("shrink-0 w-4 h-4 transition-transform", isDisabled
3070
- ? "text-surface-ink-neutral-disabled"
3071
- : currentValidationState === "positive"
3072
- ? "text-feedback-ink-positive-intense"
3073
- : currentValidationState === "negative"
3074
- ? "text-feedback-ink-negative-subtle"
3075
- : "text-surface-ink-neutral-muted", isOpen && "transform rotate-180") }), isOpen && !isDisabled && !isLoading && (jsx("div", { ref: dropdownContainerRef, className: cn("absolute z-50 left-0 right-0", dropdownPlacement === "bottom"
3076
- ? "top-full mt-1"
3077
- : "bottom-full mb-1"), children: jsx(DropdownMenu, { ref: ref, items: menuItems, sectionHeading: sectionHeading, isEmpty: options.length === 0, emptyTitle: emptyTitle, emptyDescription: emptyDescription, emptyIcon: emptyIcon, disableFooter: true, onClose: () => handleOpenChange(false), className: menuClassName, width: widthStyle }) }))] }), jsx(FormFooter, { helperText: displayHelperText, validationState: currentValidationState === "none"
3078
- ? "default"
3079
- : currentValidationState, size: size, isDisabled: isDisabled, className: "mt-1" })] }));
3101
+ // Get the display value for the TextField
3102
+ const displayValue = isLoading ? "Loading..." : selectedOption?.label || "";
3103
+ // Build the prefix: either provided prefix or selected option's leadingIcon
3104
+ const displayPrefix = prefix
3105
+ ? prefix
3106
+ : showLeadingIcon && selectedOption?.leadingIcon
3107
+ ? selectedOption.leadingIcon
3108
+ : undefined;
3109
+ // Build the suffix: include both the optional suffix and the chevron icon
3110
+ const chevronIcon = (jsx(Icon, { name: isOpen ? "chevronUp" : "chevronDown", size: 16, className: "shrink-0 transition-colors" }));
3111
+ const displaySuffix = suffix ? (jsxs(Fragment, { children: [suffix, chevronIcon] })) : (chevronIcon);
3112
+ return (jsxs("div", { ref: containerRef, className: "relative", children: [jsx(TextField, { ref: inputRef, label: label, helperText: helperText, errorText: errorText, successText: successText, validationState: validationState, isDisabled: isDisabled, isRequired: isRequired, isOptional: isOptional, isLoading: isLoading, size: size, prefix: displayPrefix, suffix: displaySuffix, showClearButton: showClearButton && hasValue && !isLoading, onClear: handleClear, placeholder: placeholder, value: displayValue, readOnly: true, containerClassName: containerClassName, labelClassName: labelClassName, className: cn("cursor-pointer", triggerClassName, className), inputClassName: "cursor-pointer", infoHeading: infoHeading, infoDescription: infoDescription, LinkComponent: LinkComponent, linkText: linkText, linkHref: linkHref, onLinkClick: onLinkClick, onClick: toggleOpen, onKeyDown: handleKeyDown, role: "combobox", "aria-haspopup": "listbox", "aria-expanded": isOpen, ...props }), isOpen && !isDisabled && !isLoading && (jsx("div", { ref: dropdownContainerRef, className: cn("absolute z-50 left-0 right-0", dropdownPlacement === "bottom"
3113
+ ? "top-full mt-1"
3114
+ : "bottom-full mb-1"), children: jsx(DropdownMenu, { items: menuItems, sectionHeading: sectionHeading, isEmpty: options.length === 0, emptyTitle: emptyTitle, emptyDescription: emptyDescription, emptyIcon: emptyIcon, disableFooter: true, onClose: () => handleOpenChange(false), className: menuClassName, width: widthStyle }) }))] }));
3080
3115
  });
3081
3116
  Select.displayName = "Select";
3082
3117
 
@@ -3504,110 +3539,6 @@ const RadioGroup = React.forwardRef(({ value: controlledValue, defaultValue, onC
3504
3539
  });
3505
3540
  RadioGroup.displayName = "RadioGroup";
3506
3541
 
3507
- const textFieldVariants = cva("relative flex items-center gap-2 border rounded-large transition-all font-functional font-size-100 leading-100", {
3508
- variants: {
3509
- size: {
3510
- small: "h-[28px] px-3 text-xs gap-2",
3511
- medium: "h-[36px] px-4 text-sm gap-2",
3512
- large: "h-[44px] px-5 text-base gap-3",
3513
- },
3514
- validationState: {
3515
- none: `
3516
- border-action-outline-neutral-faded
3517
- hover:border-action-outline-primary-hover
3518
- focus-within:border-action-outline-primary-hover
3519
- focus-within:ring-2
3520
- ring-action-outline-primary-faded-hover`,
3521
- positive: `
3522
- border-action-outline-positive-default
3523
- focus-within:border-action-outline-positive-hover
3524
- focus-within:ring-2
3525
- ring-action-outline-positive-faded-hover`,
3526
- negative: `border-action-outline-negative-default
3527
- focus-within:border-action-outline-negative-hover
3528
- focus-within:ring-2
3529
- ring-action-outline-negative-faded-hover`,
3530
- },
3531
- isDisabled: {
3532
- true: `
3533
- border-[var(--border-width-thinner)]
3534
- hover:border-action-outline-neutral-disabled
3535
- border-action-outline-neutral-disabled
3536
- bg-surface-fill-neutral-intense cursor-not-allowed opacity-60`,
3537
- false: "bg-surface-fill-neutral-intense",
3538
- },
3539
- },
3540
- defaultVariants: {
3541
- size: "medium",
3542
- validationState: "none",
3543
- isDisabled: false,
3544
- },
3545
- });
3546
- const TextField = React.forwardRef(({ label, helperText, errorText, successText, size = "medium", validationState = "none", isDisabled = false, isLoading = false, isRequired = false, isOptional = false, prefix, suffix, showClearButton = false, infoDescription, infoHeading, LinkComponent, linkText, linkHref, onLinkClick, onClear, containerClassName, labelClassName, inputClassName, className, value, onChange, ...props }, ref) => {
3547
- const [internalValue, setInternalValue] = React.useState("");
3548
- const inputValue = value !== undefined ? value : internalValue;
3549
- const hasValue = inputValue && String(inputValue).length > 0;
3550
- const handleChange = (e) => {
3551
- if (onChange) {
3552
- onChange(e);
3553
- }
3554
- else {
3555
- setInternalValue(e.target.value);
3556
- }
3557
- };
3558
- const handleClear = () => {
3559
- if (onClear) {
3560
- onClear();
3561
- }
3562
- else {
3563
- setInternalValue("");
3564
- }
3565
- // Focus the input after clearing
3566
- const input = document.getElementById(props.id || "");
3567
- if (input) {
3568
- input.focus();
3569
- }
3570
- };
3571
- // Determine which helper text to show
3572
- const displayHelperText = errorText || successText || helperText;
3573
- const currentValidationState = errorText
3574
- ? "negative"
3575
- : successText
3576
- ? "positive"
3577
- : validationState;
3578
- const sizeConfig = {
3579
- small: {
3580
- gap: "gap-2",
3581
- },
3582
- medium: {
3583
- gap: "gap-2",
3584
- },
3585
- large: {
3586
- gap: "gap-3",
3587
- },
3588
- };
3589
- return (jsxs("div", { className: cn("w-full flex flex-col", sizeConfig[size].gap, containerClassName), children: [label && (jsx(FormHeader, { label: label, size: size, isRequired: isRequired, isOptional: isOptional, infoHeading: infoHeading, infoDescription: infoDescription, LinkComponent: LinkComponent, linkText: linkText, linkHref: linkHref, onLinkClick: onLinkClick, htmlFor: props.id, className: "mb-2", labelClassName: labelClassName })), jsxs("div", { className: cn(textFieldVariants({
3590
- size,
3591
- validationState: currentValidationState,
3592
- isDisabled,
3593
- }), isLoading && "text-field-loading", className), children: [prefix && (jsx("span", { className: cn("shrink-0 flex items-center", isDisabled
3594
- ? "text-surface-ink-neutral-disabled"
3595
- : currentValidationState === "positive"
3596
- ? "text-feedback-ink-positive-intense"
3597
- : currentValidationState === "negative"
3598
- ? "text-feedback-ink-negative-subtle"
3599
- : "text-surface-ink-neutral-muted"), children: prefix })), jsx("input", { ref: ref, value: inputValue, onChange: handleChange, disabled: isDisabled, required: isRequired, className: cn("flex-1 bg-transparent border-none outline-none text-surface-ink-neutral-normal placeholder:text-surface-ink-neutral-muted disabled:cursor-not-allowed disabled:text-surface-ink-neutral-disabled", inputClassName), ...props }), showClearButton && hasValue && !isDisabled && (jsx("button", { type: "button", onClick: handleClear, className: "shrink-0 flex items-center justify-center text-surface-ink-neutral-muted hover:text-surface-ink-neutral-normal transition-colors", tabIndex: -1, children: jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: jsx("path", { d: "M12 4L4 12M4 4L12 12", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) }) })), suffix && (jsx("span", { className: cn("shrink-0 flex items-center", isDisabled
3600
- ? "text-surface-ink-neutral-disabled"
3601
- : currentValidationState === "positive"
3602
- ? "text-feedback-ink-positive-intense"
3603
- : currentValidationState === "negative"
3604
- ? "text-feedback-ink-negative-subtle"
3605
- : "text-surface-ink-neutral-muted"), children: suffix }))] }), jsx(FormFooter, { helperText: displayHelperText, validationState: currentValidationState === "none"
3606
- ? "default"
3607
- : currentValidationState, size: size, isDisabled: isDisabled, className: "mt-1" })] }));
3608
- });
3609
- TextField.displayName = "TextField";
3610
-
3611
3542
  const defaultFilter = (item, query) => {
3612
3543
  const searchQuery = query?.toLowerCase();
3613
3544
  return (item.label?.toLowerCase()?.includes(searchQuery) ||
@@ -5181,5 +5112,5 @@ const UploadBox = React.forwardRef(({ label, helperText, errorText, successText,
5181
5112
  });
5182
5113
  UploadBox.displayName = "UploadBox";
5183
5114
 
5184
- export { Alert, Amount, Avatar, AvatarCell, Badge, Button, ButtonGroup, Checkbox, Counter, DatePicker, Divider, Dropdown, DropdownMenu, FormFooter, FormHeader, Icon, IconButton, IconCell, Link, ListItem, Modal, NumberCell, Pagination, Radio, RadioGroup, SearchableDropdown, Select, SelectTextField, SidePanel, Skeleton, SlotCell, SpacerCell, Switch, TabItem, Table, TableDetailPanel, Tabs, Text, TextArea, TextField, Tooltip, UploadBox, alertVariants, avatarVariants, badgeVariants, buttonGroupVariants, buttonVariants, checkboxVariants, cn, counterVariants, datePickerVariants, dropdownVariants, getAvailableIcons, hasIcon, iconButtonVariants, iconRegistry, linkVariants, listItemVariants, paginationVariants, radioVariants, selectTriggerVariants, selectVariants, switchVariants, tableCellVariants, tableHeaderVariants, tableVariants, textAreaVariants, textFieldVariants, tooltipVariants, uploadBoxVariants };
5115
+ export { Alert, Amount, Avatar, AvatarCell, Badge, Button, ButtonGroup, Checkbox, Counter, DatePicker, Divider, Dropdown, DropdownMenu, FormFooter, FormHeader, Icon, IconButton, IconCell, Link, ListItem, Modal, NumberCell, Pagination, Radio, RadioGroup, SearchableDropdown, Select, SelectTextField, SidePanel, Skeleton, SlotCell, SpacerCell, Switch, TabItem, Table, TableDetailPanel, Tabs, Text, TextArea, TextField, Tooltip, UploadBox, alertVariants, avatarVariants, badgeVariants, buttonGroupVariants, buttonVariants, checkboxVariants, cn, counterVariants, datePickerVariants, dropdownVariants, getAvailableIcons, hasIcon, iconButtonVariants, iconRegistry, linkVariants, listItemVariants, paginationVariants, radioVariants, selectTriggerVariants, switchVariants, tableCellVariants, tableHeaderVariants, tableVariants, textAreaVariants, textFieldVariants, tooltipVariants, uploadBoxVariants };
5185
5116
  //# sourceMappingURL=index.esm.js.map