Files
sigpro-ui/src/components/Dropdown.js
2026-04-06 03:19:15 +02:00

78 lines
2.3 KiB
JavaScript

// components/Dropdown.js
// import { Tag, For, Watch } from "../sigpro.js";
import { ui } from "../core/utils.js";
/**
* Dropdown component - Solo soporta menús (items)
*
* daisyUI classes used:
* - dropdown, dropdown-content, dropdown-end, dropdown-top, dropdown-bottom
* - menu, btn
* - bg-base-100, shadow, rounded-box, border
* - z-50, p-2, w-52
* - m-1, flex, items-center, gap-2
*/
let currentOpen = null;
if (typeof window !== 'undefined' && !window.__dropdownHandlerRegistered) {
window.addEventListener('click', (e) => {
if (currentOpen && !currentOpen.contains(e.target)) {
currentOpen.open = false;
currentOpen = null;
}
});
window.__dropdownHandlerRegistered = true;
}
export const Dropdown = (props) => {
const { class: className, label, icon, items, ...rest } = props;
return Tag("details", {
...rest,
class: ui('dropdown', className),
}, [
Tag("summary", {
class: "btn m-1 flex items-center gap-2 list-none cursor-pointer",
style: "display: inline-flex;",
onclick: (e) => {
const details = e.currentTarget.closest('details');
if (currentOpen && currentOpen !== details) {
currentOpen.open = false;
}
setTimeout(() => {
currentOpen = details.open ? details : null;
}, 0);
}
}, [
() => icon ? (typeof icon === "function" ? icon() : icon) : null,
() => label ? (typeof label === "function" ? label() : label) : null
]),
Tag("ul", {
tabindex: "-1",
class: "dropdown-content z-[50] menu p-2 shadow bg-base-100 rounded-box w-52 border border-base-300"
}, [
() => {
const currentItems = typeof items === "function" ? items() : (items || []);
return currentItems.map(item =>
Tag("li", {}, [
Tag("a", {
class: item.class || "",
onclick: (e) => {
if (item.onclick) item.onclick(e);
const details = e.currentTarget.closest('details');
if (details) {
details.open = false;
if (currentOpen === details) currentOpen = null;
}
}
}, [
item.icon ? Tag("span", {}, item.icon) : null,
Tag("span", {}, item.label)
])
])
);
}
])
]);
};