@penaprieto/design-system
Version:
Multi-brand React design system with design tokens from Figma
70 lines (69 loc) • 4.24 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Select = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
require("./Select.css");
const Dropdown_1 = require("../Dropdown");
const Icon_1 = require("../Icon");
const Select = ({ options, selectedId, defaultSelectedId, placeholder = 'Selecciona una opción', label, description, helperText, disabled = false, error = false, leadingIcon, onChange, className = '', id, ...rest }) => {
const isControlled = selectedId !== undefined;
const [internalSelectedId, setInternalSelectedId] = (0, react_1.useState)(defaultSelectedId);
const currentSelectedId = isControlled ? selectedId : internalSelectedId;
const selectedOption = (0, react_1.useMemo)(() => options.find((o) => o.id === currentSelectedId), [options, currentSelectedId]);
const [open, setOpen] = (0, react_1.useState)(false);
const rootRef = (0, react_1.useRef)(null);
const toggleOpen = () => {
if (disabled)
return;
setOpen((prev) => !prev);
};
const close = () => setOpen(false);
// Cierre al hacer click fuera
(0, react_1.useEffect)(() => {
if (!open)
return;
const handler = (event) => {
if (!rootRef.current)
return;
if (!rootRef.current.contains(event.target)) {
close();
}
};
document.addEventListener('mousedown', handler);
return () => document.removeEventListener('mousedown', handler);
}, [open]);
const handleSelect = (id, option) => {
if (!isControlled) {
setInternalSelectedId(id);
}
onChange === null || onChange === void 0 ? void 0 : onChange(id, option);
close();
};
const handleKeyDownTrigger = (event) => {
if (disabled)
return;
const key = event.key;
if (key === 'ArrowDown' || key === 'ArrowUp' || key === ' ' || key === 'Enter') {
event.preventDefault();
setOpen(true);
}
};
const hasSelection = !!selectedOption;
const rootClassName = [
'ds-select',
disabled && 'ds-select--disabled',
error && 'ds-select--error',
open && 'ds-select--open',
className,
]
.filter(Boolean)
.join(' ');
return ((0, jsx_runtime_1.jsxs)("div", { id: id, ref: rootRef, className: rootClassName, "aria-disabled": disabled || undefined, ...rest, children: [label && (0, jsx_runtime_1.jsx)("div", { className: "ds-select__label", children: label }), (0, jsx_runtime_1.jsxs)("button", { type: "button", className: "ds-select__trigger", onClick: toggleOpen, onKeyDown: handleKeyDownTrigger, disabled: disabled, "aria-haspopup": "listbox", "aria-expanded": open, children: [leadingIcon && ((0, jsx_runtime_1.jsx)("span", { className: "ds-select__icon ds-select__icon--left", "aria-hidden": "true", children: leadingIcon })), (0, jsx_runtime_1.jsxs)("span", { className: "ds-select__content", children: [(0, jsx_runtime_1.jsx)("span", { className: [
'ds-select__value',
!hasSelection && 'ds-select__value--placeholder',
]
.filter(Boolean)
.join(' '), children: hasSelection ? selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label : placeholder }), description && ((0, jsx_runtime_1.jsx)("span", { className: "ds-select__description", children: description }))] }), (0, jsx_runtime_1.jsx)("span", { className: "ds-select__icon ds-select__icon--right", "aria-hidden": "true", children: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "chevron-down", size: 16 }) })] }), helperText && ((0, jsx_runtime_1.jsx)("div", { className: "ds-select__helper", children: helperText })), open && options.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "ds-select__dropdown", children: (0, jsx_runtime_1.jsx)(Dropdown_1.Dropdown, { options: options, selectedId: currentSelectedId, disabled: disabled, onChange: handleSelect }) }))] }));
};
exports.Select = Select;