@penaprieto/design-system
Version:
Multi-brand React design system with design tokens from Figma
82 lines (81 loc) • 4.75 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Combobox = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const Icon_1 = require("../Icon");
require("./Combobox.css");
const Combobox = ({ options, value: controlledValue, defaultValue = '', onChange, placeholder = 'Buscar o seleccionar...', disabled = false, error = false, className = '', }) => {
const isControlled = controlledValue !== undefined;
const [internalValue, setInternalValue] = (0, react_1.useState)(defaultValue);
const [inputValue, setInputValue] = (0, react_1.useState)('');
const [isOpen, setIsOpen] = (0, react_1.useState)(false);
const containerRef = (0, react_1.useRef)(null);
const inputRef = (0, react_1.useRef)(null);
const value = isControlled ? controlledValue : internalValue;
(0, react_1.useEffect)(() => {
const selectedOption = options.find((opt) => opt.value === value);
if (selectedOption && !isOpen) {
setInputValue(selectedOption.label);
}
}, [value, options, isOpen]);
(0, react_1.useEffect)(() => {
const handleClickOutside = (e) => {
if (containerRef.current && !containerRef.current.contains(e.target)) {
setIsOpen(false);
const selectedOption = options.find((opt) => opt.value === value);
setInputValue((selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label) || '');
}
};
if (isOpen) {
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}
}, [isOpen, value, options]);
const filteredOptions = options.filter((option) => option.label.toLowerCase().includes(inputValue.toLowerCase()));
const handleInputChange = (e) => {
setInputValue(e.target.value);
setIsOpen(true);
};
const handleOptionSelect = (option) => {
var _a;
if (option.disabled)
return;
if (!isControlled) {
setInternalValue(option.value);
}
onChange === null || onChange === void 0 ? void 0 : onChange(option.value);
setInputValue(option.label);
setIsOpen(false);
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.blur();
};
const handleInputFocus = () => {
setIsOpen(true);
};
const handleClear = () => {
var _a;
if (!isControlled) {
setInternalValue('');
}
onChange === null || onChange === void 0 ? void 0 : onChange('');
setInputValue('');
setIsOpen(false);
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
};
const rootClassName = [
'ds-combobox',
error && 'ds-combobox--error',
disabled && 'ds-combobox--disabled',
className,
]
.filter(Boolean)
.join(' ');
return ((0, jsx_runtime_1.jsxs)("div", { ref: containerRef, className: rootClassName, children: [(0, jsx_runtime_1.jsxs)("div", { className: "ds-combobox__input-wrapper", children: [(0, jsx_runtime_1.jsx)("input", { ref: inputRef, type: "text", className: "ds-combobox__input", value: inputValue, onChange: handleInputChange, onFocus: handleInputFocus, placeholder: placeholder, disabled: disabled, autoComplete: "off" }), (0, jsx_runtime_1.jsxs)("div", { className: "ds-combobox__icons", children: [inputValue && !disabled && ((0, jsx_runtime_1.jsx)("button", { type: "button", className: "ds-combobox__clear", onClick: handleClear, tabIndex: -1, children: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "x", size: 16 }) })), (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "chevron-down", size: 20 })] })] }), isOpen && filteredOptions.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "ds-combobox__dropdown", children: filteredOptions.map((option) => ((0, jsx_runtime_1.jsx)("button", { type: "button", className: [
'ds-combobox__option',
option.value === value && 'ds-combobox__option--selected',
option.disabled && 'ds-combobox__option--disabled',
]
.filter(Boolean)
.join(' '), onClick: () => handleOptionSelect(option), disabled: option.disabled, children: option.label }, option.value))) })), isOpen && filteredOptions.length === 0 && ((0, jsx_runtime_1.jsx)("div", { className: "ds-combobox__dropdown", children: (0, jsx_runtime_1.jsx)("div", { className: "ds-combobox__empty", children: "No se encontraron resultados" }) }))] }));
};
exports.Combobox = Combobox;