infinity-ui-elements 1.9.18 → 1.9.20
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/Dropdown/Dropdown.d.ts.map +1 -1
- package/dist/components/Dropdown/DropdownMenu.d.ts +4 -0
- package/dist/components/Dropdown/DropdownMenu.d.ts.map +1 -1
- package/dist/components/SearchableDropdown/SearchableDropdown.d.ts.map +1 -1
- package/dist/components/Select/Select.d.ts.map +1 -1
- package/dist/components/SelectTextField/SelectTextField.d.ts.map +1 -1
- package/dist/index.esm.js +79 -14
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +79 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3138,7 +3138,7 @@ const DateRangePicker = React__namespace.forwardRef(({ className, value: control
|
|
|
3138
3138
|
});
|
|
3139
3139
|
DateRangePicker.displayName = "DateRangePicker";
|
|
3140
3140
|
|
|
3141
|
-
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) => {
|
|
3141
|
+
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", unstyled = false, }, ref) => {
|
|
3142
3142
|
const renderContent = () => {
|
|
3143
3143
|
if (isLoading) {
|
|
3144
3144
|
return (jsxRuntime.jsx("div", { className: "flex flex-col items-center justify-center py-12 px-6", children: jsxRuntime.jsx(lucideReact.Loader2, { className: "w-12 h-12 text-action-ink-primary-normal mb-4 animate-spin" }) }));
|
|
@@ -3156,8 +3156,10 @@ const DropdownMenu = React__namespace.forwardRef(({ items = [], customContent, c
|
|
|
3156
3156
|
};
|
|
3157
3157
|
const widthClass = width === "full" ? "w-full" : width === "auto" ? "w-auto" : "";
|
|
3158
3158
|
const footerVisible = showFooter ?? !disableFooter;
|
|
3159
|
-
return (jsxRuntime.jsxs("div", { ref: ref, className: cn("bg-white
|
|
3160
|
-
|
|
3159
|
+
return (jsxRuntime.jsxs("div", { ref: ref, className: cn(!unstyled && "bg-white rounded-large overflow-hidden", unstyled && "w-full", widthClass, className), style: {
|
|
3160
|
+
...(!unstyled && {
|
|
3161
|
+
boxShadow: "0 1px 2px rgba(25, 25, 30, 0.1), 0 2px 6px rgba(25, 25, 30, 0.06)",
|
|
3162
|
+
}),
|
|
3161
3163
|
...(width !== "full" && width !== "auto" ? { width } : {}),
|
|
3162
3164
|
}, children: [renderContent(), footerVisible && (jsxRuntime.jsxs("div", { className: "flex flex-col", children: [jsxRuntime.jsx(Divider, { thickness: "thin", variant: "muted" }), jsxRuntime.jsxs("div", { className: cn("flex gap-3 p-4", footerLayout === "vertical"
|
|
3163
3165
|
? "flex-col"
|
|
@@ -3189,6 +3191,18 @@ const Dropdown = React__namespace.forwardRef(({ className, trigger, items = [],
|
|
|
3189
3191
|
right: "auto",
|
|
3190
3192
|
maxHeight: "400px",
|
|
3191
3193
|
});
|
|
3194
|
+
// Detect if we're on mobile (< 768px)
|
|
3195
|
+
const [isMobile, setIsMobile] = React__namespace.useState(false);
|
|
3196
|
+
React__namespace.useEffect(() => {
|
|
3197
|
+
const checkMobile = () => {
|
|
3198
|
+
setIsMobile(window.innerWidth < 768);
|
|
3199
|
+
};
|
|
3200
|
+
// Check on mount
|
|
3201
|
+
checkMobile();
|
|
3202
|
+
// Add resize listener
|
|
3203
|
+
window.addEventListener('resize', checkMobile);
|
|
3204
|
+
return () => window.removeEventListener('resize', checkMobile);
|
|
3205
|
+
}, []);
|
|
3192
3206
|
const handleOpenChange = (newOpen) => {
|
|
3193
3207
|
if (controlledOpen === undefined) {
|
|
3194
3208
|
setUncontrolledOpen(newOpen);
|
|
@@ -3305,14 +3319,18 @@ const Dropdown = React__namespace.forwardRef(({ className, trigger, items = [],
|
|
|
3305
3319
|
medium: "w-80",
|
|
3306
3320
|
large: "w-96",
|
|
3307
3321
|
};
|
|
3308
|
-
|
|
3322
|
+
// Render dropdown menu content wrapped in BottomSheet for mobile
|
|
3323
|
+
const renderDropdownContent = () => (jsxRuntime.jsx(DropdownMenu, { ref: ref, items: items, customContent: customContent, customContentClassName: customContentClassName, sectionHeading: sectionHeading, isLoading: isLoading, isEmpty: isEmpty, emptyTitle: emptyTitle, emptyDescription: emptyDescription, emptyLinkText: emptyLinkText, onEmptyLinkClick: onEmptyLinkClick, primaryButtonText: primaryButtonText, secondaryButtonText: secondaryButtonText, onPrimaryClick: onPrimaryClick, onSecondaryClick: onSecondaryClick, showChevron: showChevron, emptyIcon: emptyIcon, disableFooter: disableFooter, showFooter: showFooter, onClose: () => handleOpenChange(false), className: className, width: isMobile ? "full" : sizeMap[size], maxHeight: menuPosition.maxHeight, unstyled: isMobile }));
|
|
3324
|
+
return (jsxRuntime.jsxs("div", { ref: dropdownRef, className: cn("relative inline-block", containerClassName), ...props, children: [trigger && (jsxRuntime.jsx("div", { onClick: toggleOpen, className: "cursor-pointer", children: trigger })), isMobile ? (jsxRuntime.jsx(BottomSheet, { isOpen: isOpen, onClose: () => handleOpenChange(false), title: sectionHeading, variant: "default", showDragHandle: true, closeOnOverlayClick: true, closeOnEscape: true, closeOnSwipeDown: true, children: renderDropdownContent() })) : (
|
|
3325
|
+
/* Desktop: Regular Dropdown Menu */
|
|
3326
|
+
isOpen && (jsxRuntime.jsx("div", { ref: menuRef, className: cn("absolute z-50", menuClassName), style: {
|
|
3309
3327
|
top: menuPosition.top,
|
|
3310
3328
|
bottom: menuPosition.bottom,
|
|
3311
3329
|
left: menuPosition.left,
|
|
3312
3330
|
right: menuPosition.right,
|
|
3313
3331
|
marginTop: menuPosition.top === "100%" ? "0.5rem" : "0",
|
|
3314
3332
|
marginBottom: menuPosition.bottom === "100%" ? "0.5rem" : "0",
|
|
3315
|
-
}, children:
|
|
3333
|
+
}, children: renderDropdownContent() })))] }));
|
|
3316
3334
|
});
|
|
3317
3335
|
Dropdown.displayName = "Dropdown";
|
|
3318
3336
|
|
|
@@ -3480,10 +3498,22 @@ const Select = React__namespace.forwardRef(({ className, options = [], value: co
|
|
|
3480
3498
|
const [uncontrolledValue, setUncontrolledValue] = React__namespace.useState(defaultValue);
|
|
3481
3499
|
const [isOpen, setIsOpen] = React__namespace.useState(false);
|
|
3482
3500
|
const [dropdownPlacement, setDropdownPlacement] = React__namespace.useState("bottom");
|
|
3501
|
+
const [isMobile, setIsMobile] = React__namespace.useState(false);
|
|
3483
3502
|
const containerRef = React__namespace.useRef(null);
|
|
3484
3503
|
const dropdownContainerRef = React__namespace.useRef(null);
|
|
3485
3504
|
const inputRef = React__namespace.useRef(null);
|
|
3486
3505
|
React__namespace.useImperativeHandle(ref, () => inputRef.current);
|
|
3506
|
+
// Detect if we're on mobile (< 768px)
|
|
3507
|
+
React__namespace.useEffect(() => {
|
|
3508
|
+
const checkMobile = () => {
|
|
3509
|
+
setIsMobile(window.innerWidth < 768);
|
|
3510
|
+
};
|
|
3511
|
+
// Check on mount
|
|
3512
|
+
checkMobile();
|
|
3513
|
+
// Add resize listener
|
|
3514
|
+
window.addEventListener('resize', checkMobile);
|
|
3515
|
+
return () => window.removeEventListener('resize', checkMobile);
|
|
3516
|
+
}, []);
|
|
3487
3517
|
const value = controlledValue !== undefined ? controlledValue : uncontrolledValue;
|
|
3488
3518
|
// Find the selected option
|
|
3489
3519
|
const selectedOption = options.find((opt) => opt.value === value);
|
|
@@ -3640,9 +3670,11 @@ const Select = React__namespace.forwardRef(({ className, options = [], value: co
|
|
|
3640
3670
|
// Build the suffix: include both the optional suffix and the chevron icon
|
|
3641
3671
|
const chevronIcon = (jsxRuntime.jsx(Icon, { name: isOpen ? "chevronUp" : "chevronDown", size: 16, className: "shrink-0 transition-colors" }));
|
|
3642
3672
|
const displaySuffix = suffix ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [suffix, chevronIcon] })) : (chevronIcon);
|
|
3643
|
-
|
|
3673
|
+
// Render dropdown menu content
|
|
3674
|
+
const renderDropdownContent = () => (jsxRuntime.jsx(DropdownMenu, { items: menuItems, sectionHeading: sectionHeading, isEmpty: options.length === 0, emptyTitle: emptyTitle, emptyDescription: emptyDescription, emptyIcon: emptyIcon, disableFooter: true, onClose: () => handleOpenChange(false), className: menuClassName, width: isMobile ? "full" : widthStyle, unstyled: isMobile }));
|
|
3675
|
+
return (jsxRuntime.jsxs("div", { ref: containerRef, className: "relative w-full", children: [jsxRuntime.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: cn("w-full", 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 && (isMobile ? (jsxRuntime.jsx(BottomSheet, { isOpen: isOpen, onClose: () => handleOpenChange(false), title: sectionHeading || label, variant: "default", showDragHandle: true, closeOnOverlayClick: true, closeOnEscape: true, closeOnSwipeDown: true, children: renderDropdownContent() })) : (jsxRuntime.jsx("div", { ref: dropdownContainerRef, className: cn("absolute z-50 left-0 right-0", dropdownPlacement === "bottom"
|
|
3644
3676
|
? "top-full mt-1"
|
|
3645
|
-
: "bottom-full mb-1"), children:
|
|
3677
|
+
: "bottom-full mb-1"), children: renderDropdownContent() })))] }));
|
|
3646
3678
|
});
|
|
3647
3679
|
Select.displayName = "Select";
|
|
3648
3680
|
|
|
@@ -4096,6 +4128,7 @@ const SearchableDropdown = React__namespace.forwardRef(({ className, items = [],
|
|
|
4096
4128
|
const [isOpen, setIsOpen] = React__namespace.useState(false);
|
|
4097
4129
|
const [focusedIndex, setFocusedIndex] = React__namespace.useState(-1);
|
|
4098
4130
|
const [isInsideModal, setIsInsideModal] = React__namespace.useState(false);
|
|
4131
|
+
const [isMobile, setIsMobile] = React__namespace.useState(false);
|
|
4099
4132
|
const dropdownRef = React__namespace.useRef(null);
|
|
4100
4133
|
const inputRef = React__namespace.useRef(null);
|
|
4101
4134
|
const menuRef = React__namespace.useRef(null);
|
|
@@ -4104,6 +4137,17 @@ const SearchableDropdown = React__namespace.forwardRef(({ className, items = [],
|
|
|
4104
4137
|
left: 0,
|
|
4105
4138
|
width: 0,
|
|
4106
4139
|
});
|
|
4140
|
+
// Detect if we're on mobile (< 768px)
|
|
4141
|
+
React__namespace.useEffect(() => {
|
|
4142
|
+
const checkMobile = () => {
|
|
4143
|
+
setIsMobile(window.innerWidth < 768);
|
|
4144
|
+
};
|
|
4145
|
+
// Check on mount
|
|
4146
|
+
checkMobile();
|
|
4147
|
+
// Add resize listener
|
|
4148
|
+
window.addEventListener('resize', checkMobile);
|
|
4149
|
+
return () => window.removeEventListener('resize', checkMobile);
|
|
4150
|
+
}, []);
|
|
4107
4151
|
React__namespace.useImperativeHandle(ref, () => inputRef.current);
|
|
4108
4152
|
// Determine current value (controlled or uncontrolled)
|
|
4109
4153
|
const value = controlledValue !== undefined ? controlledValue : uncontrolledValue;
|
|
@@ -4338,16 +4382,23 @@ const SearchableDropdown = React__namespace.forwardRef(({ className, items = [],
|
|
|
4338
4382
|
};
|
|
4339
4383
|
});
|
|
4340
4384
|
const showDropdown = isOpen && searchValue.length >= minSearchLength;
|
|
4341
|
-
|
|
4385
|
+
// Render dropdown menu content
|
|
4386
|
+
const renderDropdownContent = () => (jsxRuntime.jsx(DropdownMenu, { items: itemsWithHandlers, sectionHeading: sectionHeading, isLoading: isLoading, isEmpty: itemsWithAddNew.length === 0 && !showAddNew, emptyTitle: emptyTitle, emptyDescription: emptyDescription, emptyLinkText: emptyLinkText, onEmptyLinkClick: onEmptyLinkClick, primaryButtonText: primaryButtonText, secondaryButtonText: secondaryButtonText, onPrimaryClick: onPrimaryClick, onSecondaryClick: onSecondaryClick, showChevron: showChevron, emptyIcon: emptyIcon, disableFooter: disableFooter, showFooter: (primaryButtonText || secondaryButtonText) && !disableFooter
|
|
4387
|
+
? true
|
|
4388
|
+
: false, footerLayout: footerLayout, onClose: () => setIsOpen(false), focusedIndex: focusedIndex, className: dropdownClassName, width: isMobile ? "full" : (dropdownWidth === "full" ? "full" : "auto"), unstyled: isMobile }));
|
|
4389
|
+
// Mobile: BottomSheet, Desktop: Regular Dropdown
|
|
4390
|
+
const dropdownMenu = showDropdown && (isMobile ? (jsxRuntime.jsxs(BottomSheet, { isOpen: isOpen, onClose: () => setIsOpen(false), title: sectionHeading, variant: "default", showDragHandle: true, closeOnOverlayClick: true, closeOnEscape: true, closeOnSwipeDown: true, children: [jsxRuntime.jsx("div", { className: "mb-4", children: jsxRuntime.jsx(TextField, { value: searchValue, onChange: handleSearchChange, onKeyDown: handleKeyDown, containerClassName: "mb-0", placeholder: textFieldProps.placeholder || "Search...", autoFocus: true, ...textFieldProps }) }), renderDropdownContent()] })) : (jsxRuntime.jsx("div", { ref: menuRef, style: {
|
|
4342
4391
|
position: "absolute",
|
|
4343
4392
|
top: `${position.top + 8}px`,
|
|
4344
4393
|
left: `${position.left}px`,
|
|
4345
4394
|
width: dropdownWidth === "full" ? `${position.width}px` : "auto",
|
|
4346
4395
|
zIndex: isInsideModal ? 10001 : 9999,
|
|
4347
|
-
}, children:
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4396
|
+
}, children: renderDropdownContent() })));
|
|
4397
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { ref: dropdownRef, className: cn("relative", containerClassName), children: [!isMobile && (jsxRuntime.jsx(TextField, { ref: inputRef, value: searchValue, onChange: handleSearchChange, onFocus: handleFocus, onKeyDown: handleKeyDown, containerClassName: "mb-0", ...textFieldProps })), isMobile && (jsxRuntime.jsx(TextField, { ref: inputRef, value: searchValue, onFocus: () => {
|
|
4398
|
+
if (showOnFocus && searchValue.length >= minSearchLength) {
|
|
4399
|
+
setIsOpen(true);
|
|
4400
|
+
}
|
|
4401
|
+
}, onClick: () => setIsOpen(true), readOnly: true, containerClassName: "mb-0", ...textFieldProps }))] }), typeof document !== "undefined" &&
|
|
4351
4402
|
dropdownMenu &&
|
|
4352
4403
|
reactDom.createPortal(dropdownMenu, document.body)] }));
|
|
4353
4404
|
});
|
|
@@ -4525,9 +4576,21 @@ const SelectTextField = React__namespace.forwardRef(({ textValue: controlledText
|
|
|
4525
4576
|
const [uncontrolledSelectValue, setUncontrolledSelectValue] = React__namespace.useState(defaultSelectValue);
|
|
4526
4577
|
const [isSelectOpen, setIsSelectOpen] = React__namespace.useState(false);
|
|
4527
4578
|
const [dropdownPlacement, setDropdownPlacement] = React__namespace.useState("bottom");
|
|
4579
|
+
const [isMobile, setIsMobile] = React__namespace.useState(false);
|
|
4528
4580
|
const selectRef = React__namespace.useRef(null);
|
|
4529
4581
|
const dropdownContainerRef = React__namespace.useRef(null);
|
|
4530
4582
|
const componentRef = React__namespace.useRef(null);
|
|
4583
|
+
// Detect if we're on mobile (< 768px)
|
|
4584
|
+
React__namespace.useEffect(() => {
|
|
4585
|
+
const checkMobile = () => {
|
|
4586
|
+
setIsMobile(window.innerWidth < 768);
|
|
4587
|
+
};
|
|
4588
|
+
// Check on mount
|
|
4589
|
+
checkMobile();
|
|
4590
|
+
// Add resize listener
|
|
4591
|
+
window.addEventListener('resize', checkMobile);
|
|
4592
|
+
return () => window.removeEventListener('resize', checkMobile);
|
|
4593
|
+
}, []);
|
|
4531
4594
|
const textValue = controlledTextValue !== undefined
|
|
4532
4595
|
? controlledTextValue
|
|
4533
4596
|
: uncontrolledTextValue;
|
|
@@ -4675,6 +4738,8 @@ const SelectTextField = React__namespace.forwardRef(({ textValue: controlledText
|
|
|
4675
4738
|
gap: "gap-3",
|
|
4676
4739
|
},
|
|
4677
4740
|
};
|
|
4741
|
+
// Render dropdown menu content
|
|
4742
|
+
const renderDropdownContent = () => (jsxRuntime.jsx(DropdownMenu, { items: menuItems, sectionHeading: selectSectionHeading, isEmpty: selectOptions.length === 0, emptyTitle: selectEmptyTitle, emptyDescription: selectEmptyDescription, emptyIcon: selectEmptyIcon, disableFooter: true, onClose: () => handleSelectOpenChange(false), className: selectMenuClassName, width: isMobile ? "full" : widthStyle, unstyled: isMobile }));
|
|
4678
4743
|
// Create the select component (prefix or suffix)
|
|
4679
4744
|
const selectComponent = (jsxRuntime.jsxs("div", { className: cn("relative flex items-stretch h-full"), children: [jsxRuntime.jsxs("div", { ref: selectRef, className: cn(selectTriggerVariants({
|
|
4680
4745
|
size,
|
|
@@ -4692,9 +4757,9 @@ const SelectTextField = React__namespace.forwardRef(({ textValue: controlledText
|
|
|
4692
4757
|
? "text-feedback-ink-positive-intense"
|
|
4693
4758
|
: currentValidationState === "negative"
|
|
4694
4759
|
? "text-feedback-ink-negative-subtle"
|
|
4695
|
-
: "text-surface-ink-neutral-muted", isSelectOpen && "transform rotate-180") })] }), isSelectOpen && !isDisabled && (jsxRuntime.jsx("div", { ref: dropdownContainerRef, className: cn("absolute z-50", position === "prefix" ? "left-[-12px]" : "right-[-12px]", dropdownPlacement === "bottom"
|
|
4760
|
+
: "text-surface-ink-neutral-muted", isSelectOpen && "transform rotate-180") })] }), isSelectOpen && !isDisabled && (isMobile ? (jsxRuntime.jsx(BottomSheet, { isOpen: isSelectOpen, onClose: () => handleSelectOpenChange(false), title: selectSectionHeading || label, variant: "default", showDragHandle: true, closeOnOverlayClick: true, closeOnEscape: true, closeOnSwipeDown: true, children: renderDropdownContent() })) : (jsxRuntime.jsx("div", { ref: dropdownContainerRef, className: cn("absolute z-50", position === "prefix" ? "left-[-12px]" : "right-[-12px]", dropdownPlacement === "bottom"
|
|
4696
4761
|
? "top-[30px] mt-1"
|
|
4697
|
-
: "bottom-full mb-1"), children:
|
|
4762
|
+
: "bottom-full mb-1"), children: renderDropdownContent() })))] }));
|
|
4698
4763
|
return (jsxRuntime.jsxs("div", { ref: componentRef, className: cn("w-full flex flex-col", sizeConfig[size].gap, containerClassName), children: [label && (jsxRuntime.jsx(FormHeader, { label: label, size: size, isRequired: isRequired, isOptional: isOptional, infoHeading: textFieldProps.infoHeading, infoDescription: textFieldProps.infoDescription, LinkComponent: textFieldProps.LinkComponent, linkText: textFieldProps.linkText, linkHref: textFieldProps.linkHref, onLinkClick: textFieldProps.onLinkClick, htmlFor: textFieldProps.id, className: "mb-2", labelClassName: labelClassName })), jsxRuntime.jsx(TextField, { ref: ref, value: textValue, onChange: handleTextChange, ...(position === "prefix"
|
|
4699
4764
|
? { prefix: selectComponent }
|
|
4700
4765
|
: { suffix: selectComponent }), size: size, validationState: currentValidationState, isDisabled: isDisabled, isRequired: isRequired, isOptional: isOptional, containerClassName: "gap-0", className: className, inputClassName: inputClassName, ...textFieldProps }), jsxRuntime.jsx(FormFooter, { helperText: displayHelperText, validationState: currentValidationState === "none"
|