@achs/webkit
Version:
Conjunto de componentes de UI con el estilo del Sistema de Diseño ACHS (Asociación Chilena de Seguridad), para reutilizar de forma transversal en las aplicaciones web de ACHS. Construido con **React 19**, **TypeScript** y **Vite**, con soporte para las
272 lines (271 loc) • 9.52 kB
JavaScript
import { jsxs as w, jsx as p } from "react/jsx-runtime";
import { useState as N, useRef as Q, useId as J, useEffect as x } from "react";
import s from "./Select.module.scss.mjs";
import { Checkbox as M } from "../../atoms/Checkbox/index.mjs";
const C = ({
options: g,
multiple: v = !1,
value: d,
onChange: u,
onBlur: n,
disabled: r = !1,
placeholder: j = "Select an option",
status: I = "default",
searchEnabled: S = !1,
...O
}) => {
const [h, A] = N(
Array.isArray(d) ? d : d !== void 0 ? [d] : []
), [i, b] = N(!1), [D, f] = N(""), [F, y] = N(!1), [m, E] = N(-1), R = Q(null), c = Q(null), q = J(), $ = `${q}-listbox`, K = (e) => `${q}-opt-${e}`;
x(() => {
A(
Array.isArray(d) ? d : d !== void 0 ? [d] : []
);
}, [d]), x(() => {
var e;
r && i && (b(!1), y(!1), f(""), n == null || n(), (e = c.current) == null || e.blur());
}, [r, i, n]), x(() => {
const e = (t) => {
r || R.current && !R.current.contains(t.target) && i && (b(!1), n == null || n(), f(""), y(!1));
};
return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
}, [i, n, r]);
const T = () => {
var e;
r || (i ? (n == null || n(), (e = c.current) == null || e.blur()) : c.current && S && setTimeout(() => {
var t;
(t = c.current) == null || t.focus(), requestAnimationFrame(() => {
var a;
(a = c.current) == null || a.setSelectionRange(0, 0);
});
}, 0), b((t) => !t), f(""), y(!1));
}, V = (e) => {
if (!(r || e.disabled)) {
if (!v)
A([e.value]), u == null || u(e.value), b(!1), y(!1);
else {
const t = h.includes(e.value) ? h.filter((a) => a !== e.value) : [...h, e.value];
A(t), u == null || u(t), c.current && S && (c.current.setSelectionRange(0, 0), c.current.focus());
}
f("");
}
}, U = (e) => {
if (r) return;
const t = h.filter((a) => a !== e);
A(t), u == null || u(t);
}, z = () => {
var e;
return O.text ? O.text : v ? h.map((t) => {
var a;
return (a = g.find((k) => k.value === t)) == null ? void 0 : a.label;
}).filter(Boolean).join(", ") : ((e = g.find((t) => t.value === h[0])) == null ? void 0 : e.label) ?? "";
}, l = g.filter(
(e) => e.label.toLowerCase().includes(D.toLowerCase())
), W = () => v && S || F ? D : z();
return x(() => {
i || E(-1);
}, [i]), x(() => {
E(-1);
}, [D]), x(() => {
const e = (t) => {
var a, k;
if (!(r || !i)) {
if (t.key === "Escape") {
t.preventDefault(), b(!1), f(""), y(!1), n == null || n(), (a = c.current) == null || a.blur();
return;
}
if (t.key === "ArrowDown" || t.key === "ArrowUp") {
t.preventDefault();
const o = t.key === "ArrowDown" ? 1 : -1;
E((G) => {
var H;
if (l.length === 0) return -1;
let L = G;
for (let P = 0; P < l.length && (L = (L + o + l.length) % l.length, !!((H = l[L]) != null && H.disabled)); P++)
;
return L;
});
return;
}
if (t.key === "Enter") {
m >= 0 && l[m] && (t.preventDefault(), V(l[m]));
return;
}
document.activeElement !== c.current && (t.key.length === 1 && !t.metaKey && !t.ctrlKey && !t.altKey && ((k = c.current) == null || k.focus(), f((o) => o + t.key), y(!0)), t.key === "Backspace" && f((o) => o.slice(0, -1)));
}
};
return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
}, [i, r, l, m, n]), /* @__PURE__ */ w(
"div",
{
className: s.dropdown,
ref: R,
"data-disabled": r,
"aria-disabled": r || void 0,
...O,
children: [
S ? /* @__PURE__ */ w(
"div",
{
className: s.header,
"data-open": i,
"data-status": I,
"data-disabled": r,
onClick: () => {
r || T();
},
role: "button",
"aria-haspopup": "listbox",
"aria-controls": $,
"aria-expanded": i,
"aria-disabled": r || void 0,
tabIndex: r ? -1 : 0,
onKeyDown: (e) => {
r || (e.key === "Enter" || e.key === " ") && (e.preventDefault(), T());
},
children: [
/* @__PURE__ */ w("div", { className: s.inputWrapper, children: [
v && h.map((e) => {
const t = g.find((a) => a.value === e);
return t ? /* @__PURE__ */ w("span", { className: s.chip, children: [
t.label,
/* @__PURE__ */ p(
"button",
{
type: "button",
className: s.removeChip,
onClick: (a) => {
a.stopPropagation(), U(e);
},
disabled: r,
"aria-label": `Quitar ${t.label}`,
children: "×"
}
)
] }, e) : null;
}),
/* @__PURE__ */ p(
"input",
{
type: "text",
ref: c,
value: W(),
onChange: (e) => {
if (r) return;
const t = e.target.value;
if (F)
f(t);
else {
const a = t.charAt(t.length - 1);
y(!0), f(a);
}
i || b(!0);
},
onFocus: (e) => {
r || requestAnimationFrame(() => {
e.target.setSelectionRange(0, 0);
});
},
className: s.searchInput,
placeholder: j,
disabled: r,
role: "combobox",
"aria-expanded": i,
"aria-controls": $,
"aria-autocomplete": "list",
"aria-activedescendant": i && m >= 0 ? K(m) : void 0,
"aria-disabled": r || void 0
}
)
] }),
/* @__PURE__ */ p(
"i",
{
className: `bi ${i ? "bi-chevron-up" : "bi-chevron-down"} ${s.chevron}`,
"data-status": I,
"aria-hidden": "true"
}
)
]
}
) : /* @__PURE__ */ w(
"button",
{
type: "button",
className: s.header,
onClick: T,
"data-open": i,
"data-status": I,
"data-disabled": r,
disabled: r,
"aria-haspopup": "listbox",
"aria-controls": $,
"aria-expanded": i,
"aria-activedescendant": i && m >= 0 ? K(m) : void 0,
children: [
/* @__PURE__ */ p("span", { className: s.placeholder, children: z() || j }),
/* @__PURE__ */ p("i", { className: `bi bi-chevron-down ${s.chevron}`, "data-status": I, "aria-hidden": "true" })
]
}
),
/* @__PURE__ */ w(
"ul",
{
id: $,
role: "listbox",
"aria-multiselectable": v || void 0,
className: `${s.menu} ${i ? s.menuOpen : ""}`,
"aria-hidden": !i,
children: [
l.length === 0 && /* @__PURE__ */ p("li", { className: s.noOptions, role: "option", "aria-selected": !1, children: "No hay opciones" }),
l.map((e, t) => {
const a = h.includes(e.value), k = t === l.length - 1, o = r || e.disabled;
return /* @__PURE__ */ w(
"li",
{
id: K(t),
role: "option",
"aria-selected": a,
className: s.menuItem,
"data-disabled": o,
"data-active": a,
"data-highlighted": t === m || void 0,
"aria-disabled": o || void 0,
children: [
v && /* @__PURE__ */ p(
M,
{
checked: a,
onChange: () => V(e),
size: "small",
style: { marginLeft: "0.5rem" },
disabled: o
}
),
/* @__PURE__ */ p(
"button",
{
type: "button",
className: s.itemButton,
onClick: () => V(e),
disabled: o,
children: e.label
}
),
!k && /* @__PURE__ */ p("hr", { className: s.separator })
]
},
e.value
);
})
]
}
)
]
}
);
};
export {
C as Select,
C as default
};