infinity-ui-elements 1.8.28 → 1.8.30

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
@@ -2098,7 +2098,7 @@ const formatDateDefault = (date) => {
2098
2098
  day: "numeric",
2099
2099
  });
2100
2100
  };
2101
- 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 = false, onClear, containerClassName, labelClassName, triggerClassName, calendarClassName, minDate, maxDate, formatDate = formatDateDefault, infoHeading, infoDescription, LinkComponent, linkText, linkHref, onLinkClick, ...props }, ref) => {
2101
+ 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, infoHeading, infoDescription, LinkComponent, linkText, linkHref, onLinkClick, ...props }, ref) => {
2102
2102
  const [uncontrolledValue, setUncontrolledValue] = React__namespace.useState(parseDate(defaultValue));
2103
2103
  const [isOpen, setIsOpen] = React__namespace.useState(false);
2104
2104
  const datePickerRef = React__namespace.useRef(null);
@@ -2251,7 +2251,7 @@ const DatePicker = React__namespace.forwardRef(({ className, value: controlledVa
2251
2251
  ? "text-feedback-ink-positive-intense"
2252
2252
  : currentValidationState === "negative"
2253
2253
  ? "text-feedback-ink-negative-subtle"
2254
- : "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: hasValue && value ? formatDate(value) : placeholder }), showClearButton && hasValue && !isDisabled && (jsxRuntime.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: jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: jsxRuntime.jsx("path", { d: "M12 4L4 12M4 4L12 12", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) }) })), isOpen && !isDisabled && (jsxRuntime.jsx("div", { ref: calendarRef, className: cn("absolute z-50 left-0 bg-surface-fill-neutral-intense rounded-large shadow-lg p-4", dropdownPlacement === "bottom"
2254
+ : "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: hasValue && value ? formatDate(value) : placeholder }), showClearButton && hasValue && !isDisabled && (jsxRuntime.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, "aria-label": "Clear date", children: jsxRuntime.jsx(lucideReact.X, { className: "w-4 h-4" }) })), isOpen && !isDisabled && (jsxRuntime.jsx("div", { ref: calendarRef, className: cn("absolute z-50 left-0 bg-surface-fill-neutral-intense rounded-large shadow-lg p-4", dropdownPlacement === "bottom"
2255
2255
  ? "top-full mt-1"
2256
2256
  : "bottom-full mb-1", 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) => {
2257
2257
  const weekdayNames = [
@@ -2618,7 +2618,7 @@ const selectVariants = classVarianceAuthority.cva("relative flex items-center ga
2618
2618
  isDisabled: false,
2619
2619
  },
2620
2620
  });
2621
- const Select = React__namespace.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, 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) => {
2621
+ const Select = React__namespace.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) => {
2622
2622
  const [uncontrolledValue, setUncontrolledValue] = React__namespace.useState(defaultValue);
2623
2623
  const [isOpen, setIsOpen] = React__namespace.useState(false);
2624
2624
  const [dropdownPlacement, setDropdownPlacement] = React__namespace.useState("bottom");
@@ -2797,13 +2797,19 @@ const Select = React__namespace.forwardRef(({ className, options = [], value: co
2797
2797
  size,
2798
2798
  validationState: currentValidationState,
2799
2799
  isDisabled,
2800
- }), "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 && (jsxRuntime.jsx("span", { className: cn("shrink-0 flex items-center", isDisabled
2800
+ }), "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 ? (jsxRuntime.jsx("span", { className: cn("shrink-0 flex items-center", isDisabled
2801
2801
  ? "text-surface-ink-neutral-disabled"
2802
2802
  : currentValidationState === "positive"
2803
2803
  ? "text-feedback-ink-positive-intense"
2804
2804
  : currentValidationState === "negative"
2805
2805
  ? "text-feedback-ink-negative-subtle"
2806
- : "text-surface-ink-neutral-muted"), children: prefix })), jsxRuntime.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 && (jsxRuntime.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: jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: jsxRuntime.jsx("path", { d: "M12 4L4 12M4 4L12 12", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) }) })), suffix && !showClearButton && (jsxRuntime.jsx("span", { className: cn("shrink-0 flex items-center", isDisabled
2806
+ : "text-surface-ink-neutral-muted"), children: prefix })) : showLeadingIcon && selectedOption?.leadingIcon ? (jsxRuntime.jsx("span", { className: cn("shrink-0 flex items-center", isDisabled
2807
+ ? "text-surface-ink-neutral-disabled"
2808
+ : currentValidationState === "positive"
2809
+ ? "text-feedback-ink-positive-intense"
2810
+ : currentValidationState === "negative"
2811
+ ? "text-feedback-ink-negative-subtle"
2812
+ : "text-surface-ink-neutral-muted"), children: selectedOption.leadingIcon })) : null, jsxRuntime.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 && (jsxRuntime.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: jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: jsxRuntime.jsx("path", { d: "M12 4L4 12M4 4L12 12", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) }) })), suffix && !showClearButton && (jsxRuntime.jsx("span", { className: cn("shrink-0 flex items-center", isDisabled
2807
2813
  ? "text-surface-ink-neutral-disabled"
2808
2814
  : currentValidationState === "positive"
2809
2815
  ? "text-feedback-ink-positive-intense"
@@ -3113,6 +3119,132 @@ const Radio = React__namespace.forwardRef(({ label, errorText, size = "medium",
3113
3119
  });
3114
3120
  Radio.displayName = "Radio";
3115
3121
 
3122
+ const RadioGroup = React__namespace.forwardRef(({ value: controlledValue, defaultValue, onChange, options, children, label, helperText, errorText, successText, validationState = "none", isDisabled = false, isRequired = false, isOptional = false, size = "medium", name: nameProp, orientation = "vertical", spacing = "normal", containerClassName, labelClassName, groupClassName, infoHeading, infoDescription, LinkComponent, linkText, linkHref, onLinkClick, className, id, ...props }, ref) => {
3123
+ const [uncontrolledValue, setUncontrolledValue] = React__namespace.useState(defaultValue);
3124
+ const groupId = React__namespace.useId();
3125
+ const name = nameProp || `radio-group-${groupId}`;
3126
+ const groupRef = React__namespace.useRef(null);
3127
+ const radioRefs = React__namespace.useRef([]);
3128
+ const value = controlledValue !== undefined ? controlledValue : uncontrolledValue;
3129
+ // Determine which helper text to show
3130
+ const displayHelperText = errorText || successText || helperText;
3131
+ const currentValidationState = errorText ? "error" : validationState;
3132
+ const handleChange = (optionValue) => {
3133
+ if (onChange) {
3134
+ onChange(optionValue);
3135
+ }
3136
+ else {
3137
+ setUncontrolledValue(optionValue);
3138
+ }
3139
+ };
3140
+ // Keyboard navigation
3141
+ const handleKeyDown = (e) => {
3142
+ if (isDisabled)
3143
+ return;
3144
+ const currentIndex = radioRefs.current.findIndex((ref) => ref === document.activeElement);
3145
+ if (currentIndex === -1)
3146
+ return;
3147
+ const direction = orientation === "horizontal"
3148
+ ? (e.key === "ArrowRight" ? 1 : e.key === "ArrowLeft" ? -1 : 0)
3149
+ : (e.key === "ArrowDown" ? 1 : e.key === "ArrowUp" ? -1 : 0);
3150
+ if (direction === 0)
3151
+ return;
3152
+ e.preventDefault();
3153
+ // Find next enabled radio
3154
+ let nextIndex = currentIndex;
3155
+ const total = radioRefs.current.length;
3156
+ let attempts = 0;
3157
+ while (attempts < total) {
3158
+ nextIndex = (nextIndex + direction + total) % total;
3159
+ const nextRadio = radioRefs.current[nextIndex];
3160
+ if (nextRadio && !nextRadio.disabled) {
3161
+ nextRadio.focus();
3162
+ nextRadio.click();
3163
+ return;
3164
+ }
3165
+ attempts++;
3166
+ }
3167
+ };
3168
+ // Spacing configuration
3169
+ const spacingConfig = {
3170
+ tight: orientation === "horizontal" ? "gap-3" : "gap-2",
3171
+ normal: orientation === "horizontal" ? "gap-4" : "gap-3",
3172
+ loose: orientation === "horizontal" ? "gap-6" : "gap-4",
3173
+ };
3174
+ // Size configuration
3175
+ const sizeConfig = {
3176
+ small: {
3177
+ gap: "gap-2",
3178
+ },
3179
+ medium: {
3180
+ gap: "gap-2",
3181
+ },
3182
+ large: {
3183
+ gap: "gap-3",
3184
+ },
3185
+ };
3186
+ // Render options from array
3187
+ const renderOptions = () => {
3188
+ if (!options)
3189
+ return null;
3190
+ return options.map((option, index) => {
3191
+ const isChecked = value === option.value;
3192
+ const optionDisabled = isDisabled || option.isDisabled;
3193
+ return (jsxRuntime.jsx(Radio, { ref: (el) => {
3194
+ radioRefs.current[index] = el;
3195
+ }, name: name, value: option.value, label: option.label, checked: isChecked, onChange: (e) => {
3196
+ if (e.target.checked) {
3197
+ handleChange(option.value);
3198
+ }
3199
+ }, size: size, validationState: currentValidationState, isDisabled: optionDisabled, showErrorText: false, containerClassName: option.containerClassName, labelClassName: option.labelClassName }, option.value));
3200
+ });
3201
+ };
3202
+ // Clone children and inject props
3203
+ const renderChildren = () => {
3204
+ if (!children)
3205
+ return null;
3206
+ return React__namespace.Children.map(children, (child, index) => {
3207
+ if (!React__namespace.isValidElement(child)) {
3208
+ return child;
3209
+ }
3210
+ const childValue = child.props.value;
3211
+ const isChecked = value === childValue;
3212
+ const childDisabled = isDisabled || child.props.isDisabled;
3213
+ return React__namespace.cloneElement(child, {
3214
+ ...child.props,
3215
+ ref: (el) => {
3216
+ radioRefs.current[index] = el;
3217
+ // Preserve original ref if it exists
3218
+ const originalRef = child.ref;
3219
+ if (typeof originalRef === "function") {
3220
+ originalRef(el);
3221
+ }
3222
+ else if (originalRef && "current" in originalRef) {
3223
+ originalRef.current = el;
3224
+ }
3225
+ },
3226
+ name,
3227
+ checked: isChecked,
3228
+ onChange: (e) => {
3229
+ if (e.target.checked) {
3230
+ handleChange(childValue || "");
3231
+ }
3232
+ // Call original onChange if it exists
3233
+ if (child.props.onChange) {
3234
+ child.props.onChange(e);
3235
+ }
3236
+ },
3237
+ size: child.props.size || size,
3238
+ validationState: child.props.validationState || currentValidationState,
3239
+ isDisabled: childDisabled,
3240
+ showErrorText: false,
3241
+ });
3242
+ });
3243
+ };
3244
+ return (jsxRuntime.jsxs("div", { ref: ref, className: cn("w-full flex flex-col", sizeConfig[size].gap, containerClassName), ...props, children: [label && (jsxRuntime.jsx(FormHeader, { label: label, size: size, isRequired: isRequired, isOptional: isOptional, infoHeading: infoHeading, infoDescription: infoDescription, LinkComponent: LinkComponent, linkText: linkText, linkHref: linkHref, onLinkClick: onLinkClick, htmlFor: id, className: "mb-2", labelClassName: labelClassName })), jsxRuntime.jsx("div", { ref: groupRef, role: "radiogroup", "aria-label": label, "aria-required": isRequired, "aria-invalid": currentValidationState === "error", "aria-disabled": isDisabled, className: cn("flex", orientation === "horizontal" ? "flex-row items-center" : "flex-col items-start", spacingConfig[spacing], groupClassName, className), onKeyDown: handleKeyDown, id: id, children: options ? renderOptions() : renderChildren() }), jsxRuntime.jsx(FormFooter, { helperText: displayHelperText, validationState: currentValidationState === "none" ? "default" : currentValidationState, size: size, isDisabled: isDisabled, className: "mt-1" })] }));
3245
+ });
3246
+ RadioGroup.displayName = "RadioGroup";
3247
+
3116
3248
  const textFieldVariants = classVarianceAuthority.cva("relative flex items-center gap-2 border rounded-large transition-all font-functional font-size-100 leading-100", {
3117
3249
  variants: {
3118
3250
  size: {
@@ -4731,6 +4863,7 @@ exports.Modal = Modal;
4731
4863
  exports.NumberCell = NumberCell;
4732
4864
  exports.Pagination = Pagination;
4733
4865
  exports.Radio = Radio;
4866
+ exports.RadioGroup = RadioGroup;
4734
4867
  exports.SearchableDropdown = SearchableDropdown;
4735
4868
  exports.Select = Select;
4736
4869
  exports.SelectTextField = SelectTextField;