infinity-ui-elements 1.8.29 → 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/components/DatePicker/DatePicker.d.ts.map +1 -1
- package/dist/components/Radio/RadioGroup.d.ts +132 -0
- package/dist/components/Radio/RadioGroup.d.ts.map +1 -0
- package/dist/components/Radio/RadioGroup.stories.d.ts +32 -0
- package/dist/components/Radio/RadioGroup.stories.d.ts.map +1 -0
- package/dist/components/Radio/index.d.ts +2 -0
- package/dist/components/Radio/index.d.ts.map +1 -1
- package/dist/index.esm.js +130 -4
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +129 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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 =
|
|
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,
|
|
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 = [
|
|
@@ -3119,6 +3119,132 @@ const Radio = React__namespace.forwardRef(({ label, errorText, size = "medium",
|
|
|
3119
3119
|
});
|
|
3120
3120
|
Radio.displayName = "Radio";
|
|
3121
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
|
+
|
|
3122
3248
|
const textFieldVariants = classVarianceAuthority.cva("relative flex items-center gap-2 border rounded-large transition-all font-functional font-size-100 leading-100", {
|
|
3123
3249
|
variants: {
|
|
3124
3250
|
size: {
|
|
@@ -4737,6 +4863,7 @@ exports.Modal = Modal;
|
|
|
4737
4863
|
exports.NumberCell = NumberCell;
|
|
4738
4864
|
exports.Pagination = Pagination;
|
|
4739
4865
|
exports.Radio = Radio;
|
|
4866
|
+
exports.RadioGroup = RadioGroup;
|
|
4740
4867
|
exports.SearchableDropdown = SearchableDropdown;
|
|
4741
4868
|
exports.Select = Select;
|
|
4742
4869
|
exports.SelectTextField = SelectTextField;
|