dropdown ok

This commit is contained in:
2026-04-02 21:40:07 +02:00
parent f0c710f8c2
commit b0629ef3d0
6 changed files with 301 additions and 323 deletions

View File

@@ -12,7 +12,6 @@ import { ui } from "../core/utils.js";
export const Drawer = (props, children) => {
const { class: className, id, open, side, content, ...rest } = props;
// Generar un id único si no se proporciona
const drawerId = id || `drawer-${Math.random().toString(36).slice(2, 9)}`;
return $html("div", {
@@ -32,7 +31,6 @@ export const Drawer = (props, children) => {
typeof content === "function" ? content() : content
]),
$html("div", { class: "drawer-side" }, [
// El overlay debe tener for apuntando al checkbox
$html("label", {
for: drawerId,
class: "drawer-overlay",

View File

@@ -1,65 +1,78 @@
// components/Dropdown.js
import { $html, $for } from "sigpro";
// import { $html, $for, $watch } from "sigpro";
import { ui } from "../core/utils.js";
/**
* Dropdown component
* Dropdown component - Solo soporta menús (items)
*
* daisyUI classes used:
* - dropdown, dropdown-content, dropdown-end, dropdown-top, dropdown-bottom
* - menu, menu-dropdown, menu-dropdown-show
* - btn, btn-ghost, btn-sm, btn-md, btn-lg
* - bg-base-100, shadow, rounded-box, border, border-base-300
* - z-50, p-2, w-52, min-w-max
* - menu, btn
* - bg-base-100, shadow, rounded-box, border
* - z-50, p-2, w-52
* - m-1, flex, items-center, gap-2
*/
export const Dropdown = (props, children) => {
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;
const renderContent = () => {
if (items) {
const source = typeof items === "function" ? items : () => items;
return $html("ul", {
tabindex: 0,
class: "dropdown-content z-[50] menu p-2 shadow bg-base-100 rounded-box w-52 border border-base-300"
}, [
$for(source, (item) =>
return $html("details", {
...rest,
class: ui('dropdown', className),
}, [
$html("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
]),
$html("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 =>
$html("li", {}, [
$html("a", {
class: item.class || "",
onclick: (e) => {
if (item.onclick) item.onclick(e);
if (document.activeElement) document.activeElement.blur();
const details = e.currentTarget.closest('details');
if (details) {
details.open = false;
if (currentOpen === details) currentOpen = null;
}
}
}, [
item.icon ? $html("span", {}, item.icon) : null,
$html("span", {}, item.label)
])
])
)
]);
}
return $html("div", {
tabindex: 0,
class: "dropdown-content z-[50] p-2 shadow bg-base-100 rounded-box min-w-max border border-base-300"
}, [
typeof children === "function" ? children() : children
]);
};
return $html("div", {
...rest,
class: ui('dropdown', className),
}, [
$html("div", {
tabindex: 0,
role: "button",
class: "btn m-1 flex items-center gap-2",
}, [
icon ? (typeof icon === "function" ? icon() : icon) : null,
label ? (typeof label === "function" ? label() : label) : null
]),
renderContent()
);
}
])
]);
};