dropdown ok
This commit is contained in:
415
dist/sigpro-ui.js
vendored
415
dist/sigpro-ui.js
vendored
@@ -266,7 +266,7 @@
|
|||||||
runner();
|
runner();
|
||||||
return runner.stop;
|
return runner.stop;
|
||||||
};
|
};
|
||||||
var $html = (tag, props = {}, content = []) => {
|
var $html2 = (tag, props = {}, content = []) => {
|
||||||
if (props instanceof Node || Array.isArray(props) || typeof props !== "object") {
|
if (props instanceof Node || Array.isArray(props) || typeof props !== "object") {
|
||||||
content = props;
|
content = props;
|
||||||
props = {};
|
props = {};
|
||||||
@@ -328,7 +328,7 @@
|
|||||||
};
|
};
|
||||||
var $if = (condition, thenVal, otherwiseVal = null) => {
|
var $if = (condition, thenVal, otherwiseVal = null) => {
|
||||||
const marker = document.createTextNode("");
|
const marker = document.createTextNode("");
|
||||||
const container = $html("div", { style: "display:contents" }, [marker]);
|
const container = $html2("div", { style: "display:contents" }, [marker]);
|
||||||
let current = null, last = null;
|
let current = null, last = null;
|
||||||
$watch(() => {
|
$watch(() => {
|
||||||
const state = !!(typeof condition === "function" ? condition() : condition);
|
const state = !!(typeof condition === "function" ? condition() : condition);
|
||||||
@@ -348,7 +348,7 @@
|
|||||||
$if.not = (condition, thenVal, otherwiseVal) => $if(() => !(typeof condition === "function" ? condition() : condition), thenVal, otherwiseVal);
|
$if.not = (condition, thenVal, otherwiseVal) => $if(() => !(typeof condition === "function" ? condition() : condition), thenVal, otherwiseVal);
|
||||||
var $for = (source, render, keyFn) => {
|
var $for = (source, render, keyFn) => {
|
||||||
const marker = document.createTextNode("");
|
const marker = document.createTextNode("");
|
||||||
const container = $html("div", { style: "display:contents" }, [marker]);
|
const container = $html2("div", { style: "display:contents" }, [marker]);
|
||||||
let cache = new Map;
|
let cache = new Map;
|
||||||
$watch(() => {
|
$watch(() => {
|
||||||
const items = (typeof source === "function" ? source() : source) || [];
|
const items = (typeof source === "function" ? source() : source) || [];
|
||||||
@@ -385,7 +385,7 @@
|
|||||||
var $router = (routes) => {
|
var $router = (routes) => {
|
||||||
const sPath = $(window.location.hash.replace(/^#/, "") || "/");
|
const sPath = $(window.location.hash.replace(/^#/, "") || "/");
|
||||||
window.addEventListener("hashchange", () => sPath(window.location.hash.replace(/^#/, "") || "/"));
|
window.addEventListener("hashchange", () => sPath(window.location.hash.replace(/^#/, "") || "/"));
|
||||||
const outlet = $html("div", { class: "router-outlet" });
|
const outlet = $html2("div", { class: "router-outlet" });
|
||||||
let current = null;
|
let current = null;
|
||||||
$watch([sPath], async () => {
|
$watch([sPath], async () => {
|
||||||
const path = sPath();
|
const path = sPath();
|
||||||
@@ -411,7 +411,7 @@
|
|||||||
try {
|
try {
|
||||||
return typeof comp === "function" ? comp(params) : comp;
|
return typeof comp === "function" ? comp(params) : comp;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return $html("div", { class: "p-4 text-error" }, "Error loading view");
|
return $html2("div", { class: "p-4 text-error" }, "Error loading view");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
outlet.appendChild(current.container);
|
outlet.appendChild(current.container);
|
||||||
@@ -434,7 +434,7 @@
|
|||||||
MOUNTED_NODES.set(el, instance);
|
MOUNTED_NODES.set(el, instance);
|
||||||
return instance;
|
return instance;
|
||||||
};
|
};
|
||||||
var SigProCore = { $, $watch, $html, $if, $for, $router, $mount };
|
var SigProCore = { $, $watch, $html: $html2, $if, $for, $router, $mount };
|
||||||
if (typeof window !== "undefined") {
|
if (typeof window !== "undefined") {
|
||||||
const install = (registry) => {
|
const install = (registry) => {
|
||||||
Object.keys(registry).forEach((key) => {
|
Object.keys(registry).forEach((key) => {
|
||||||
@@ -444,7 +444,7 @@
|
|||||||
tags.forEach((tagName) => {
|
tags.forEach((tagName) => {
|
||||||
const helperName = tagName.charAt(0).toUpperCase() + tagName.slice(1);
|
const helperName = tagName.charAt(0).toUpperCase() + tagName.slice(1);
|
||||||
if (!(helperName in window)) {
|
if (!(helperName in window)) {
|
||||||
window[helperName] = (props, content) => $html(tagName, props, content);
|
window[helperName] = (props, content) => $html2(tagName, props, content);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
window.SigPro = Object.freeze(registry);
|
window.SigPro = Object.freeze(registry);
|
||||||
@@ -509,10 +509,10 @@
|
|||||||
if (!icon)
|
if (!icon)
|
||||||
return null;
|
return null;
|
||||||
if (typeof icon === "function") {
|
if (typeof icon === "function") {
|
||||||
return $html("span", { class: "mr-1" }, icon());
|
return $html2("span", { class: "mr-1" }, icon());
|
||||||
}
|
}
|
||||||
if (typeof icon === "object") {
|
if (typeof icon === "object") {
|
||||||
return $html("span", { class: "mr-1" }, icon);
|
return $html2("span", { class: "mr-1" }, icon);
|
||||||
}
|
}
|
||||||
if (typeof icon === "string") {
|
if (typeof icon === "string") {
|
||||||
const parts = icon.trim().split(/\s+/);
|
const parts = icon.trim().split(/\s+/);
|
||||||
@@ -520,9 +520,9 @@
|
|||||||
const iconClass = hasRight ? parts.slice(0, -1).join(" ") : icon;
|
const iconClass = hasRight ? parts.slice(0, -1).join(" ") : icon;
|
||||||
const spacing = hasRight ? "ml-1" : "mr-1";
|
const spacing = hasRight ? "ml-1" : "mr-1";
|
||||||
if (iconClass && !iconClass.startsWith("icon-[") && !iconClass.includes("--")) {
|
if (iconClass && !iconClass.startsWith("icon-[") && !iconClass.includes("--")) {
|
||||||
return $html("span", { class: spacing }, iconClass);
|
return $html2("span", { class: spacing }, iconClass);
|
||||||
}
|
}
|
||||||
return $html("span", { class: `${iconClass} ${spacing}`.trim() });
|
return $html2("span", { class: `${iconClass} ${spacing}`.trim() });
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
@@ -530,17 +530,17 @@
|
|||||||
// src/components/Accordion.js
|
// src/components/Accordion.js
|
||||||
var Accordion = (props, children) => {
|
var Accordion = (props, children) => {
|
||||||
const { class: className, title, name, open, ...rest } = props;
|
const { class: className, title, name, open, ...rest } = props;
|
||||||
return $html("div", {
|
return $html2("div", {
|
||||||
...rest,
|
...rest,
|
||||||
class: ui("collapse collapse-arrow bg-base-200 mb-2", className)
|
class: ui("collapse collapse-arrow bg-base-200 mb-2", className)
|
||||||
}, [
|
}, [
|
||||||
$html("input", {
|
$html2("input", {
|
||||||
type: name ? "radio" : "checkbox",
|
type: name ? "radio" : "checkbox",
|
||||||
name,
|
name,
|
||||||
checked: val(open)
|
checked: val(open)
|
||||||
}),
|
}),
|
||||||
$html("div", { class: "collapse-title text-xl font-medium" }, title),
|
$html2("div", { class: "collapse-title text-xl font-medium" }, title),
|
||||||
$html("div", { class: "collapse-content" }, children)
|
$html2("div", { class: "collapse-content" }, children)
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -561,16 +561,16 @@
|
|||||||
const softClass = soft ? "alert-soft" : "";
|
const softClass = soft ? "alert-soft" : "";
|
||||||
const allClasses = [typeClass, softClass, className].filter(Boolean).join(" ");
|
const allClasses = [typeClass, softClass, className].filter(Boolean).join(" ");
|
||||||
const content = children || props.message;
|
const content = children || props.message;
|
||||||
return $html("div", {
|
return $html2("div", {
|
||||||
...rest,
|
...rest,
|
||||||
role: "alert",
|
role: "alert",
|
||||||
class: ui("alert", allClasses)
|
class: ui("alert", allClasses)
|
||||||
}, () => [
|
}, () => [
|
||||||
getIcon(iconMap[type]),
|
getIcon(iconMap[type]),
|
||||||
$html("div", { class: "flex-1" }, [
|
$html2("div", { class: "flex-1" }, [
|
||||||
$html("span", {}, [typeof content === "function" ? content() : content])
|
$html2("span", {}, [typeof content === "function" ? content() : content])
|
||||||
]),
|
]),
|
||||||
actions ? $html("div", { class: "flex-none" }, [
|
actions ? $html2("div", { class: "flex-none" }, [
|
||||||
typeof actions === "function" ? actions() : actions
|
typeof actions === "function" ? actions() : actions
|
||||||
]) : null
|
]) : null
|
||||||
].filter(Boolean));
|
].filter(Boolean));
|
||||||
@@ -646,8 +646,8 @@
|
|||||||
return "btn-lg";
|
return "btn-lg";
|
||||||
return "btn-md";
|
return "btn-md";
|
||||||
};
|
};
|
||||||
return $html("div", { class: "relative w-full" }, () => [
|
return $html2("div", { class: "relative w-full" }, () => [
|
||||||
$html("input", {
|
$html2("input", {
|
||||||
...rest,
|
...rest,
|
||||||
type: () => isPassword ? visible() ? "text" : "password" : type,
|
type: () => isPassword ? visible() ? "text" : "password" : type,
|
||||||
placeholder: placeholder || " ",
|
placeholder: placeholder || " ",
|
||||||
@@ -656,10 +656,10 @@
|
|||||||
oninput: (e) => oninput?.(e),
|
oninput: (e) => oninput?.(e),
|
||||||
disabled: () => val(disabled)
|
disabled: () => val(disabled)
|
||||||
}),
|
}),
|
||||||
leftIcon ? $html("div", {
|
leftIcon ? $html2("div", {
|
||||||
class: "absolute left-3 inset-y-0 flex items-center pointer-events-none text-base-content/60"
|
class: "absolute left-3 inset-y-0 flex items-center pointer-events-none text-base-content/60"
|
||||||
}, leftIcon) : null,
|
}, leftIcon) : null,
|
||||||
isPassword ? $html("button", {
|
isPassword ? $html2("button", {
|
||||||
type: "button",
|
type: "button",
|
||||||
class: ui("absolute right-3 inset-y-0 flex items-center", "btn btn-ghost btn-circle opacity-50 hover:opacity-100", buttonSize()),
|
class: ui("absolute right-3 inset-y-0 flex items-center", "btn btn-ghost btn-circle opacity-50 hover:opacity-100", buttonSize()),
|
||||||
onclick: (e) => {
|
onclick: (e) => {
|
||||||
@@ -707,7 +707,7 @@
|
|||||||
isOpen(false);
|
isOpen(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return $html("div", { class: "relative w-full" }, [
|
return $html2("div", { class: "relative w-full" }, [
|
||||||
Input({
|
Input({
|
||||||
label,
|
label,
|
||||||
class: className,
|
class: className,
|
||||||
@@ -726,18 +726,18 @@
|
|||||||
},
|
},
|
||||||
...rest
|
...rest
|
||||||
}),
|
}),
|
||||||
$html("ul", {
|
$html2("ul", {
|
||||||
class: "absolute left-0 w-full menu bg-base-100 rounded-box mt-1 p-2 shadow-xl max-h-60 overflow-y-auto border border-base-300 z-50",
|
class: "absolute left-0 w-full menu bg-base-100 rounded-box mt-1 p-2 shadow-xl max-h-60 overflow-y-auto border border-base-300 z-50",
|
||||||
style: () => isOpen() && list().length ? "display:block" : "display:none"
|
style: () => isOpen() && list().length ? "display:block" : "display:none"
|
||||||
}, [
|
}, [
|
||||||
$for(list, (opt, i) => $html("li", {}, [
|
$for(list, (opt, i) => $html2("li", {}, [
|
||||||
$html("a", {
|
$html2("a", {
|
||||||
class: () => `block w-full ${cursor() === i ? "active bg-primary text-primary-content" : ""}`,
|
class: () => `block w-full ${cursor() === i ? "active bg-primary text-primary-content" : ""}`,
|
||||||
onclick: () => pick(opt),
|
onclick: () => pick(opt),
|
||||||
onmouseenter: () => cursor(i)
|
onmouseenter: () => cursor(i)
|
||||||
}, typeof opt === "string" ? opt : opt.label)
|
}, typeof opt === "string" ? opt : opt.label)
|
||||||
]), (opt, i) => (typeof opt === "string" ? opt : opt.value) + i),
|
]), (opt, i) => (typeof opt === "string" ? opt : opt.value) + i),
|
||||||
() => list().length ? null : $html("li", { class: "p-2 text-center opacity-50" }, tt("nodata")())
|
() => list().length ? null : $html2("li", { class: "p-2 text-center opacity-50" }, tt("nodata")())
|
||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
@@ -749,7 +749,7 @@
|
|||||||
});
|
});
|
||||||
var Badge = (props, children) => {
|
var Badge = (props, children) => {
|
||||||
const { class: className, ...rest } = props;
|
const { class: className, ...rest } = props;
|
||||||
return $html("span", {
|
return $html2("span", {
|
||||||
...rest,
|
...rest,
|
||||||
class: ui("badge", className)
|
class: ui("badge", className)
|
||||||
}, children);
|
}, children);
|
||||||
@@ -763,12 +763,12 @@
|
|||||||
var Button = (props, children) => {
|
var Button = (props, children) => {
|
||||||
const { class: className, loading, icon, ...rest } = props;
|
const { class: className, loading, icon, ...rest } = props;
|
||||||
const iconEl = getIcon(icon);
|
const iconEl = getIcon(icon);
|
||||||
return $html("button", {
|
return $html2("button", {
|
||||||
...rest,
|
...rest,
|
||||||
class: ui("btn", className),
|
class: ui("btn", className),
|
||||||
disabled: () => val(loading) || val(props.disabled)
|
disabled: () => val(loading) || val(props.disabled)
|
||||||
}, () => [
|
}, () => [
|
||||||
val(loading) && $html("span", { class: "loading loading-spinner" }),
|
val(loading) && $html2("span", { class: "loading loading-spinner" }),
|
||||||
iconEl,
|
iconEl,
|
||||||
children
|
children
|
||||||
].filter(Boolean));
|
].filter(Boolean));
|
||||||
@@ -781,17 +781,17 @@
|
|||||||
});
|
});
|
||||||
var Checkbox = (props) => {
|
var Checkbox = (props) => {
|
||||||
const { class: className, value, tooltip, toggle, label, ...rest } = props;
|
const { class: className, value, tooltip, toggle, label, ...rest } = props;
|
||||||
const checkEl = $html("input", {
|
const checkEl = $html2("input", {
|
||||||
...rest,
|
...rest,
|
||||||
type: "checkbox",
|
type: "checkbox",
|
||||||
class: () => ui(val(toggle) ? "toggle" : "checkbox", className),
|
class: () => ui(val(toggle) ? "toggle" : "checkbox", className),
|
||||||
checked: value
|
checked: value
|
||||||
});
|
});
|
||||||
const layout = $html("label", { class: "label cursor-pointer justify-start gap-3" }, [
|
const layout = $html2("label", { class: "label cursor-pointer justify-start gap-3" }, [
|
||||||
checkEl,
|
checkEl,
|
||||||
label ? $html("span", { class: "label-text" }, label) : null
|
label ? $html2("span", { class: "label-text" }, label) : null
|
||||||
]);
|
]);
|
||||||
return tooltip ? $html("div", { class: "tooltip", "data-tip": tooltip }, layout) : layout;
|
return tooltip ? $html2("div", { class: "tooltip", "data-tip": tooltip }, layout) : layout;
|
||||||
};
|
};
|
||||||
|
|
||||||
// src/components/Colorpicker.js
|
// src/components/Colorpicker.js
|
||||||
@@ -813,8 +813,8 @@
|
|||||||
...["#2e1065", "#4c1d95", "#6d28d9", "#7c3aed", "#8b5cf6", "#a855f7", "#d946ef", "#fae8ff"]
|
...["#2e1065", "#4c1d95", "#6d28d9", "#7c3aed", "#8b5cf6", "#a855f7", "#d946ef", "#fae8ff"]
|
||||||
];
|
];
|
||||||
const getColor = () => val(value) || "#000000";
|
const getColor = () => val(value) || "#000000";
|
||||||
return $html("div", { class: ui("relative w-fit", className) }, [
|
return $html2("div", { class: ui("relative w-fit", className) }, [
|
||||||
$html("button", {
|
$html2("button", {
|
||||||
type: "button",
|
type: "button",
|
||||||
class: "btn px-3 bg-base-100 border-base-300 hover:border-primary/50 flex items-center gap-2 shadow-sm font-normal normal-case",
|
class: "btn px-3 bg-base-100 border-base-300 hover:border-primary/50 flex items-center gap-2 shadow-sm font-normal normal-case",
|
||||||
onclick: (e) => {
|
onclick: (e) => {
|
||||||
@@ -823,17 +823,17 @@
|
|||||||
},
|
},
|
||||||
...rest
|
...rest
|
||||||
}, [
|
}, [
|
||||||
$html("div", {
|
$html2("div", {
|
||||||
class: "size-5 rounded-sm shadow-inner border border-black/10 shrink-0",
|
class: "size-5 rounded-sm shadow-inner border border-black/10 shrink-0",
|
||||||
style: () => `background-color: ${getColor()}`
|
style: () => `background-color: ${getColor()}`
|
||||||
}),
|
}),
|
||||||
label ? $html("span", { class: "opacity-80" }, label) : null
|
label ? $html2("span", { class: "opacity-80" }, label) : null
|
||||||
]),
|
]),
|
||||||
$if(isOpen, () => $html("div", {
|
$if(isOpen, () => $html2("div", {
|
||||||
class: "absolute left-0 mt-2 p-3 bg-base-100 border border-base-300 shadow-2xl rounded-box z-[110] w-64 select-none",
|
class: "absolute left-0 mt-2 p-3 bg-base-100 border border-base-300 shadow-2xl rounded-box z-[110] w-64 select-none",
|
||||||
onclick: (e) => e.stopPropagation()
|
onclick: (e) => e.stopPropagation()
|
||||||
}, [
|
}, [
|
||||||
$html("div", { class: "grid grid-cols-8 gap-1" }, palette.map((c) => $html("button", {
|
$html2("div", { class: "grid grid-cols-8 gap-1" }, palette.map((c) => $html2("button", {
|
||||||
type: "button",
|
type: "button",
|
||||||
style: `background-color: ${c}`,
|
style: `background-color: ${c}`,
|
||||||
class: () => {
|
class: () => {
|
||||||
@@ -848,7 +848,7 @@
|
|||||||
}
|
}
|
||||||
})))
|
})))
|
||||||
])),
|
])),
|
||||||
$if(isOpen, () => $html("div", {
|
$if(isOpen, () => $html2("div", {
|
||||||
class: "fixed inset-0 z-[100]",
|
class: "fixed inset-0 z-[100]",
|
||||||
onclick: () => isOpen(false)
|
onclick: () => isOpen(false)
|
||||||
}))
|
}))
|
||||||
@@ -936,9 +936,9 @@
|
|||||||
internalDate(new Date(d.getFullYear() + y, d.getMonth(), 1));
|
internalDate(new Date(d.getFullYear() + y, d.getMonth(), 1));
|
||||||
};
|
};
|
||||||
const HourSlider = ({ value: hVal, onChange }) => {
|
const HourSlider = ({ value: hVal, onChange }) => {
|
||||||
return $html("div", { class: "flex-1" }, [
|
return $html2("div", { class: "flex-1" }, [
|
||||||
$html("div", { class: "flex gap-2 items-center" }, [
|
$html2("div", { class: "flex gap-2 items-center" }, [
|
||||||
$html("input", {
|
$html2("input", {
|
||||||
type: "range",
|
type: "range",
|
||||||
min: 0,
|
min: 0,
|
||||||
max: 23,
|
max: 23,
|
||||||
@@ -949,11 +949,11 @@
|
|||||||
onChange(newHour);
|
onChange(newHour);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
$html("span", { class: "text-sm font-mono min-w-[48px] text-center" }, () => String(val(hVal)).padStart(2, "0") + ":00")
|
$html2("span", { class: "text-sm font-mono min-w-[48px] text-center" }, () => String(val(hVal)).padStart(2, "0") + ":00")
|
||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
return $html("div", { class: ui("relative w-full", className) }, [
|
return $html2("div", { class: ui("relative w-full", className) }, [
|
||||||
Input({
|
Input({
|
||||||
label,
|
label,
|
||||||
placeholder: placeholder || (isRangeMode() ? "Seleccionar rango..." : "Seleccionar fecha..."),
|
placeholder: placeholder || (isRangeMode() ? "Seleccionar rango..." : "Seleccionar fecha..."),
|
||||||
@@ -966,25 +966,25 @@
|
|||||||
},
|
},
|
||||||
...rest
|
...rest
|
||||||
}),
|
}),
|
||||||
$if(isOpen, () => $html("div", {
|
$if(isOpen, () => $html2("div", {
|
||||||
class: "absolute left-0 mt-2 p-4 bg-base-100 border border-base-300 shadow-2xl rounded-box z-[100] w-80 select-none",
|
class: "absolute left-0 mt-2 p-4 bg-base-100 border border-base-300 shadow-2xl rounded-box z-[100] w-80 select-none",
|
||||||
onclick: (e) => e.stopPropagation()
|
onclick: (e) => e.stopPropagation()
|
||||||
}, [
|
}, [
|
||||||
$html("div", { class: "flex justify-between items-center mb-4 gap-1" }, [
|
$html2("div", { class: "flex justify-between items-center mb-4 gap-1" }, [
|
||||||
$html("div", { class: "flex gap-0.5" }, [
|
$html2("div", { class: "flex gap-0.5" }, [
|
||||||
$html("button", { type: "button", class: "btn btn-ghost btn-xs px-1", onclick: () => moveYear(-1) }, getIcon("icon-[lucide--chevrons-left]")),
|
$html2("button", { type: "button", class: "btn btn-ghost btn-xs px-1", onclick: () => moveYear(-1) }, getIcon("icon-[lucide--chevrons-left]")),
|
||||||
$html("button", { type: "button", class: "btn btn-ghost btn-xs px-1", onclick: () => move(-1) }, getIcon("icon-[lucide--chevron-left]"))
|
$html2("button", { type: "button", class: "btn btn-ghost btn-xs px-1", onclick: () => move(-1) }, getIcon("icon-[lucide--chevron-left]"))
|
||||||
]),
|
]),
|
||||||
$html("span", { class: "font-bold uppercase flex-1 text-center" }, [
|
$html2("span", { class: "font-bold uppercase flex-1 text-center" }, [
|
||||||
() => internalDate().toLocaleString("es-ES", { month: "short", year: "numeric" })
|
() => internalDate().toLocaleString("es-ES", { month: "short", year: "numeric" })
|
||||||
]),
|
]),
|
||||||
$html("div", { class: "flex gap-0.5" }, [
|
$html2("div", { class: "flex gap-0.5" }, [
|
||||||
$html("button", { type: "button", class: "btn btn-ghost btn-xs px-1", onclick: () => move(1) }, getIcon("icon-[lucide--chevron-right]")),
|
$html2("button", { type: "button", class: "btn btn-ghost btn-xs px-1", onclick: () => move(1) }, getIcon("icon-[lucide--chevron-right]")),
|
||||||
$html("button", { type: "button", class: "btn btn-ghost btn-xs px-1", onclick: () => moveYear(1) }, getIcon("icon-[lucide--chevrons-right]"))
|
$html2("button", { type: "button", class: "btn btn-ghost btn-xs px-1", onclick: () => moveYear(1) }, getIcon("icon-[lucide--chevrons-right]"))
|
||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
$html("div", { class: "grid grid-cols-7 gap-1", onmouseleave: () => hoverDate(null) }, [
|
$html2("div", { class: "grid grid-cols-7 gap-1", onmouseleave: () => hoverDate(null) }, [
|
||||||
...["L", "M", "X", "J", "V", "S", "D"].map((d) => $html("div", { class: "text-[10px] opacity-40 font-bold text-center" }, d)),
|
...["L", "M", "X", "J", "V", "S", "D"].map((d) => $html2("div", { class: "text-[10px] opacity-40 font-bold text-center" }, d)),
|
||||||
() => {
|
() => {
|
||||||
const d = internalDate();
|
const d = internalDate();
|
||||||
const year = d.getFullYear();
|
const year = d.getFullYear();
|
||||||
@@ -994,11 +994,11 @@
|
|||||||
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
||||||
const nodes = [];
|
const nodes = [];
|
||||||
for (let i = 0;i < offset; i++)
|
for (let i = 0;i < offset; i++)
|
||||||
nodes.push($html("div"));
|
nodes.push($html2("div"));
|
||||||
for (let i = 1;i <= daysInMonth; i++) {
|
for (let i = 1;i <= daysInMonth; i++) {
|
||||||
const date = new Date(year, month, i);
|
const date = new Date(year, month, i);
|
||||||
const dStr = formatDate(date);
|
const dStr = formatDate(date);
|
||||||
nodes.push($html("button", {
|
nodes.push($html2("button", {
|
||||||
type: "button",
|
type: "button",
|
||||||
class: () => {
|
class: () => {
|
||||||
const v = val(value);
|
const v = val(value);
|
||||||
@@ -1029,8 +1029,8 @@
|
|||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
]),
|
]),
|
||||||
hour ? $html("div", { class: "mt-3 pt-2 border-t border-base-300" }, [
|
hour ? $html2("div", { class: "mt-3 pt-2 border-t border-base-300" }, [
|
||||||
isRangeMode() ? $html("div", { class: "flex gap-4" }, [
|
isRangeMode() ? $html2("div", { class: "flex gap-4" }, [
|
||||||
HourSlider({
|
HourSlider({
|
||||||
value: startHour,
|
value: startHour,
|
||||||
onChange: (newHour) => {
|
onChange: (newHour) => {
|
||||||
@@ -1061,7 +1061,7 @@
|
|||||||
})
|
})
|
||||||
]) : null
|
]) : null
|
||||||
])),
|
])),
|
||||||
$if(isOpen, () => $html("div", { class: "fixed inset-0 z-[90]", onclick: () => isOpen(false) }))
|
$if(isOpen, () => $html2("div", { class: "fixed inset-0 z-[90]", onclick: () => isOpen(false) }))
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1073,11 +1073,11 @@
|
|||||||
var Drawer = (props, children) => {
|
var Drawer = (props, children) => {
|
||||||
const { class: className, id, open, side, content, ...rest } = props;
|
const { class: className, id, open, side, content, ...rest } = props;
|
||||||
const drawerId = id || `drawer-${Math.random().toString(36).slice(2, 9)}`;
|
const drawerId = id || `drawer-${Math.random().toString(36).slice(2, 9)}`;
|
||||||
return $html("div", {
|
return $html2("div", {
|
||||||
...rest,
|
...rest,
|
||||||
class: ui("drawer", className)
|
class: ui("drawer", className)
|
||||||
}, [
|
}, [
|
||||||
$html("input", {
|
$html2("input", {
|
||||||
id: drawerId,
|
id: drawerId,
|
||||||
type: "checkbox",
|
type: "checkbox",
|
||||||
class: "drawer-toggle",
|
class: "drawer-toggle",
|
||||||
@@ -1087,11 +1087,11 @@
|
|||||||
open(e.target.checked);
|
open(e.target.checked);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
$html("div", { class: "drawer-content" }, [
|
$html2("div", { class: "drawer-content" }, [
|
||||||
typeof content === "function" ? content() : content
|
typeof content === "function" ? content() : content
|
||||||
]),
|
]),
|
||||||
$html("div", { class: "drawer-side" }, [
|
$html2("div", { class: "drawer-side" }, [
|
||||||
$html("label", {
|
$html2("label", {
|
||||||
for: drawerId,
|
for: drawerId,
|
||||||
class: "drawer-overlay",
|
class: "drawer-overlay",
|
||||||
onclick: () => {
|
onclick: () => {
|
||||||
@@ -1099,7 +1099,7 @@
|
|||||||
open(false);
|
open(false);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
$html("div", { class: "min-h-full bg-base-200 w-80" }, [
|
$html2("div", { class: "min-h-full bg-base-200 w-80" }, [
|
||||||
typeof side === "function" ? side() : side
|
typeof side === "function" ? side() : side
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
@@ -1111,51 +1111,64 @@
|
|||||||
__export(exports_Dropdown, {
|
__export(exports_Dropdown, {
|
||||||
Dropdown: () => Dropdown
|
Dropdown: () => Dropdown
|
||||||
});
|
});
|
||||||
var Dropdown = (props, children) => {
|
var 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;
|
||||||
|
}
|
||||||
|
var Dropdown = (props) => {
|
||||||
const { class: className, label, icon, items, ...rest } = props;
|
const { class: className, label, icon, items, ...rest } = props;
|
||||||
const renderContent = () => {
|
return $html("details", {
|
||||||
if (items) {
|
...rest,
|
||||||
const source = typeof items === "function" ? items : () => items;
|
class: ui("dropdown", className)
|
||||||
return $html("ul", {
|
}, [
|
||||||
tabindex: 0,
|
$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"
|
class: "dropdown-content z-[50] menu p-2 shadow bg-base-100 rounded-box w-52 border border-base-300"
|
||||||
}, [
|
}, [
|
||||||
$for(source, (item) => $html("li", {}, [
|
() => {
|
||||||
|
const currentItems = typeof items === "function" ? items() : items || [];
|
||||||
|
return currentItems.map((item) => $html("li", {}, [
|
||||||
$html("a", {
|
$html("a", {
|
||||||
class: item.class || "",
|
class: item.class || "",
|
||||||
onclick: (e) => {
|
onclick: (e) => {
|
||||||
if (item.onclick)
|
if (item.onclick)
|
||||||
item.onclick(e);
|
item.onclick(e);
|
||||||
if (document.activeElement)
|
const details = e.currentTarget.closest("details");
|
||||||
document.activeElement.blur();
|
if (details) {
|
||||||
|
details.open = false;
|
||||||
|
if (currentOpen === details)
|
||||||
|
currentOpen = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
item.icon ? $html("span", {}, item.icon) : null,
|
item.icon ? $html("span", {}, item.icon) : null,
|
||||||
$html("span", {}, item.label)
|
$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()
|
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1166,11 +1179,11 @@
|
|||||||
});
|
});
|
||||||
var Fab = (props) => {
|
var Fab = (props) => {
|
||||||
const { class: className, icon, label, actions = [], position = "bottom-6 right-6", ...rest } = props;
|
const { class: className, icon, label, actions = [], position = "bottom-6 right-6", ...rest } = props;
|
||||||
return $html("div", {
|
return $html2("div", {
|
||||||
...rest,
|
...rest,
|
||||||
class: ui(`fab absolute ${position} flex flex-col-reverse items-end gap-3 z-[100]`, className)
|
class: ui(`fab absolute ${position} flex flex-col-reverse items-end gap-3 z-[100]`, className)
|
||||||
}, [
|
}, [
|
||||||
$html("div", {
|
$html2("div", {
|
||||||
tabindex: 0,
|
tabindex: 0,
|
||||||
role: "button",
|
role: "button",
|
||||||
class: "btn btn-lg btn-circle btn-primary shadow-2xl"
|
class: "btn btn-lg btn-circle btn-primary shadow-2xl"
|
||||||
@@ -1178,9 +1191,9 @@
|
|||||||
icon ? getIcon(icon) : null,
|
icon ? getIcon(icon) : null,
|
||||||
!icon && label ? label : null
|
!icon && label ? label : null
|
||||||
]),
|
]),
|
||||||
...val(actions).map((act) => $html("div", { class: "flex items-center gap-3 transition-all duration-300" }, [
|
...val(actions).map((act) => $html2("div", { class: "flex items-center gap-3 transition-all duration-300" }, [
|
||||||
act.label ? $html("span", { class: "badge badge-ghost shadow-sm whitespace-nowrap" }, act.label) : null,
|
act.label ? $html2("span", { class: "badge badge-ghost shadow-sm whitespace-nowrap" }, act.label) : null,
|
||||||
$html("button", {
|
$html2("button", {
|
||||||
type: "button",
|
type: "button",
|
||||||
class: `btn btn-circle shadow-lg ${act.class || ""}`,
|
class: `btn btn-circle shadow-lg ${act.class || ""}`,
|
||||||
onclick: (e) => {
|
onclick: (e) => {
|
||||||
@@ -1199,13 +1212,13 @@
|
|||||||
});
|
});
|
||||||
var Fieldset = (props, children) => {
|
var Fieldset = (props, children) => {
|
||||||
const { class: className, legend, ...rest } = props;
|
const { class: className, legend, ...rest } = props;
|
||||||
return $html("fieldset", {
|
return $html2("fieldset", {
|
||||||
...rest,
|
...rest,
|
||||||
class: ui("fieldset bg-base-200 border border-base-300 p-4 rounded-lg", className)
|
class: ui("fieldset bg-base-200 border border-base-300 p-4 rounded-lg", className)
|
||||||
}, [
|
}, [
|
||||||
() => {
|
() => {
|
||||||
const legendText = val(legend);
|
const legendText = val(legend);
|
||||||
return legendText ? $html("legend", { class: "fieldset-legend font-bold" }, [legendText]) : null;
|
return legendText ? $html2("legend", { class: "fieldset-legend font-bold" }, [legendText]) : null;
|
||||||
},
|
},
|
||||||
children
|
children
|
||||||
]);
|
]);
|
||||||
@@ -1238,12 +1251,12 @@
|
|||||||
selectedFiles(updated);
|
selectedFiles(updated);
|
||||||
onSelect?.(updated);
|
onSelect?.(updated);
|
||||||
};
|
};
|
||||||
return $html("fieldset", { ...rest, class: ui("fieldset w-full p-0", className) }, [
|
return $html2("fieldset", { ...rest, class: ui("fieldset w-full p-0", className) }, [
|
||||||
$html("div", {
|
$html2("div", {
|
||||||
class: () => `w-full ${tooltip ? "tooltip tooltip-top before:z-50 after:z-50" : ""}`,
|
class: () => `w-full ${tooltip ? "tooltip tooltip-top before:z-50 after:z-50" : ""}`,
|
||||||
"data-tip": tooltip
|
"data-tip": tooltip
|
||||||
}, [
|
}, [
|
||||||
$html("label", {
|
$html2("label", {
|
||||||
class: () => `
|
class: () => `
|
||||||
relative flex items-center justify-between w-full h-12 px-4
|
relative flex items-center justify-between w-full h-12 px-4
|
||||||
border-2 border-dashed rounded-lg cursor-pointer
|
border-2 border-dashed rounded-lg cursor-pointer
|
||||||
@@ -1261,12 +1274,12 @@
|
|||||||
handleFiles(e.dataTransfer.files);
|
handleFiles(e.dataTransfer.files);
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
$html("div", { class: "flex items-center gap-3 w-full" }, [
|
$html2("div", { class: "flex items-center gap-3 w-full" }, [
|
||||||
getIcon("icon-[lucide--upload]"),
|
getIcon("icon-[lucide--upload]"),
|
||||||
$html("span", { class: "text-sm opacity-70 truncate grow text-left" }, "Arrastra o selecciona archivos..."),
|
$html2("span", { class: "text-sm opacity-70 truncate grow text-left" }, "Arrastra o selecciona archivos..."),
|
||||||
$html("span", { class: "text-[10px] opacity-40 shrink-0" }, `Máx ${max}MB`)
|
$html2("span", { class: "text-[10px] opacity-40 shrink-0" }, `Máx ${max}MB`)
|
||||||
]),
|
]),
|
||||||
$html("input", {
|
$html2("input", {
|
||||||
type: "file",
|
type: "file",
|
||||||
multiple: true,
|
multiple: true,
|
||||||
accept,
|
accept,
|
||||||
@@ -1275,15 +1288,15 @@
|
|||||||
})
|
})
|
||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
() => error() ? $html("span", { class: "text-[10px] text-error mt-1 px-1 font-medium" }, error()) : null,
|
() => error() ? $html2("span", { class: "text-[10px] text-error mt-1 px-1 font-medium" }, error()) : null,
|
||||||
$if(() => selectedFiles().length > 0, () => $html("ul", { class: "mt-2 space-y-1" }, [
|
$if(() => selectedFiles().length > 0, () => $html2("ul", { class: "mt-2 space-y-1" }, [
|
||||||
$for(selectedFiles, (file, index) => $html("li", { class: "flex items-center justify-between p-1.5 pl-3 text-xs bg-base-200/50 rounded-md border border-base-300" }, [
|
$for(selectedFiles, (file, index) => $html2("li", { class: "flex items-center justify-between p-1.5 pl-3 text-xs bg-base-200/50 rounded-md border border-base-300" }, [
|
||||||
$html("div", { class: "flex items-center gap-2 truncate" }, [
|
$html2("div", { class: "flex items-center gap-2 truncate" }, [
|
||||||
$html("span", { class: "opacity-50" }, "\uD83D\uDCC4"),
|
$html2("span", { class: "opacity-50" }, "\uD83D\uDCC4"),
|
||||||
$html("span", { class: "truncate font-medium max-w-[200px]" }, file.name),
|
$html2("span", { class: "truncate font-medium max-w-[200px]" }, file.name),
|
||||||
$html("span", { class: "text-[9px] opacity-40" }, `(${(file.size / 1024).toFixed(0)} KB)`)
|
$html2("span", { class: "text-[9px] opacity-40" }, `(${(file.size / 1024).toFixed(0)} KB)`)
|
||||||
]),
|
]),
|
||||||
$html("button", {
|
$html2("button", {
|
||||||
type: "button",
|
type: "button",
|
||||||
class: "btn btn-ghost btn-xs btn-circle",
|
class: "btn btn-ghost btn-xs btn-circle",
|
||||||
onclick: (e) => {
|
onclick: (e) => {
|
||||||
@@ -1302,9 +1315,9 @@
|
|||||||
__export(exports_Indicator, {
|
__export(exports_Indicator, {
|
||||||
Indicator: () => Indicator
|
Indicator: () => Indicator
|
||||||
});
|
});
|
||||||
var Indicator = (props, children) => $html("div", { class: "indicator" }, () => [
|
var Indicator = (props, children) => $html2("div", { class: "indicator" }, () => [
|
||||||
children,
|
children,
|
||||||
props.value && $html("span", { class: ui("indicator-item badge", props.class) }, props.value)
|
props.value && $html2("span", { class: ui("indicator-item badge", props.class) }, props.value)
|
||||||
].filter(Boolean));
|
].filter(Boolean));
|
||||||
|
|
||||||
// src/components/Label.js
|
// src/components/Label.js
|
||||||
@@ -1315,16 +1328,16 @@
|
|||||||
var Label = (props) => {
|
var Label = (props) => {
|
||||||
const { children, value, floating = false, error, required, class: className, ...rest } = props;
|
const { children, value, floating = false, error, required, class: className, ...rest } = props;
|
||||||
if (floating) {
|
if (floating) {
|
||||||
return $html("label", { class: ui("floating-label w-full", className), ...rest }, () => [
|
return $html2("label", { class: ui("floating-label w-full", className), ...rest }, () => [
|
||||||
value ? $html("span", {}, value) : null,
|
value ? $html2("span", {}, value) : null,
|
||||||
children,
|
children,
|
||||||
error ? $html("span", { class: "text-error text-xs" }, val(error)) : null
|
error ? $html2("span", { class: "text-error text-xs" }, val(error)) : null
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
return $html("label", { class: ui("input w-full", className), ...rest }, () => [
|
return $html2("label", { class: ui("input w-full", className), ...rest }, () => [
|
||||||
value ? $html("span", { class: "label" }, value) : null,
|
value ? $html2("span", { class: "label" }, value) : null,
|
||||||
children,
|
children,
|
||||||
error ? $html("span", { class: "text-error text-xs" }, val(error)) : null
|
error ? $html2("span", { class: "text-error text-xs" }, val(error)) : null
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1335,11 +1348,11 @@
|
|||||||
});
|
});
|
||||||
var List = (props) => {
|
var List = (props) => {
|
||||||
const { class: className, items, header, render, keyFn = (item, index) => index, ...rest } = props;
|
const { class: className, items, header, render, keyFn = (item, index) => index, ...rest } = props;
|
||||||
const listItems = $for(items, (item, index) => $html("li", { class: "list-row" }, [render(item, index)]), keyFn);
|
const listItems = $for(items, (item, index) => $html2("li", { class: "list-row" }, [render(item, index)]), keyFn);
|
||||||
return $html("ul", {
|
return $html2("ul", {
|
||||||
...rest,
|
...rest,
|
||||||
class: ui("list bg-base-100 rounded-box shadow-md", className)
|
class: ui("list bg-base-100 rounded-box shadow-md", className)
|
||||||
}, header ? [$if(header, () => $html("li", { class: "p-4 pb-2 text-xs opacity-60" }, [val(header)])), listItems] : listItems);
|
}, header ? [$if(header, () => $html2("li", { class: "p-4 pb-2 text-xs opacity-60" }, [val(header)])), listItems] : listItems);
|
||||||
};
|
};
|
||||||
|
|
||||||
// src/components/Loading.js
|
// src/components/Loading.js
|
||||||
@@ -1348,10 +1361,10 @@
|
|||||||
Loading: () => Loading
|
Loading: () => Loading
|
||||||
});
|
});
|
||||||
var Loading = (props) => {
|
var Loading = (props) => {
|
||||||
return $if(props.$show, () => $html("div", {
|
return $if(props.$show, () => $html2("div", {
|
||||||
class: "fixed inset-0 z-[100] flex items-center justify-center backdrop-blur-sm bg-base-100/30"
|
class: "fixed inset-0 z-[100] flex items-center justify-center backdrop-blur-sm bg-base-100/30"
|
||||||
}, [
|
}, [
|
||||||
$html("span", { class: "loading loading-spinner loading-lg text-primary" })
|
$html2("span", { class: "loading loading-spinner loading-lg text-primary" })
|
||||||
]));
|
]));
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1362,16 +1375,16 @@
|
|||||||
});
|
});
|
||||||
var Menu = (props) => {
|
var Menu = (props) => {
|
||||||
const { class: className, items, ...rest } = props;
|
const { class: className, items, ...rest } = props;
|
||||||
const renderItems = (items2) => $for(() => items2 || [], (it) => $html("li", {}, [
|
const renderItems = (items2) => $for(() => items2 || [], (it) => $html2("li", {}, [
|
||||||
it.children ? $html("details", { open: it.open }, [
|
it.children ? $html2("details", { open: it.open }, [
|
||||||
$html("summary", {}, [it.icon && $html("span", { class: "mr-2" }, it.icon), it.label]),
|
$html2("summary", {}, [it.icon && $html2("span", { class: "mr-2" }, it.icon), it.label]),
|
||||||
$html("ul", {}, renderItems(it.children))
|
$html2("ul", {}, renderItems(it.children))
|
||||||
]) : $html("a", { class: () => val(it.active) ? "active" : "", onclick: it.onclick }, [
|
]) : $html2("a", { class: () => val(it.active) ? "active" : "", onclick: it.onclick }, [
|
||||||
it.icon && $html("span", { class: "mr-2" }, it.icon),
|
it.icon && $html2("span", { class: "mr-2" }, it.icon),
|
||||||
it.label
|
it.label
|
||||||
])
|
])
|
||||||
]), (it, i) => it.label || i);
|
]), (it, i) => it.label || i);
|
||||||
return $html("ul", { ...rest, class: ui("menu bg-base-200 rounded-box", className) }, renderItems(items));
|
return $html2("ul", { ...rest, class: ui("menu bg-base-200 rounded-box", className) }, renderItems(items));
|
||||||
};
|
};
|
||||||
|
|
||||||
// src/components/Modal.js
|
// src/components/Modal.js
|
||||||
@@ -1400,28 +1413,28 @@
|
|||||||
if (typeof open === "function")
|
if (typeof open === "function")
|
||||||
open(false);
|
open(false);
|
||||||
};
|
};
|
||||||
return $html("dialog", {
|
return $html2("dialog", {
|
||||||
...rest,
|
...rest,
|
||||||
ref: dialogRef,
|
ref: dialogRef,
|
||||||
class: ui("modal", className),
|
class: ui("modal", className),
|
||||||
oncancel: () => typeof open === "function" && open(false)
|
oncancel: () => typeof open === "function" && open(false)
|
||||||
}, [
|
}, [
|
||||||
$html("div", { class: "modal-box" }, [
|
$html2("div", { class: "modal-box" }, [
|
||||||
title ? $html("h3", { class: "text-lg font-bold mb-4" }, title) : null,
|
title ? $html2("h3", { class: "text-lg font-bold mb-4" }, title) : null,
|
||||||
$html("div", { class: "py-2" }, [
|
$html2("div", { class: "py-2" }, [
|
||||||
typeof children === "function" ? children() : children
|
typeof children === "function" ? children() : children
|
||||||
]),
|
]),
|
||||||
$html("div", { class: "modal-action flex gap-2" }, [
|
$html2("div", { class: "modal-action flex gap-2" }, [
|
||||||
...(Array.isArray(buttons) ? buttons : [buttons]).filter(Boolean),
|
...(Array.isArray(buttons) ? buttons : [buttons]).filter(Boolean),
|
||||||
Button({ type: "button", onclick: close }, tt("close")())
|
Button({ type: "button", onclick: close }, tt("close")())
|
||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
$html("form", {
|
$html2("form", {
|
||||||
method: "dialog",
|
method: "dialog",
|
||||||
class: "modal-backdrop",
|
class: "modal-backdrop",
|
||||||
onsubmit: close
|
onsubmit: close
|
||||||
}, [
|
}, [
|
||||||
$html("button", {}, "close")
|
$html2("button", {}, "close")
|
||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
@@ -1433,7 +1446,7 @@
|
|||||||
});
|
});
|
||||||
var Navbar = (props, children) => {
|
var Navbar = (props, children) => {
|
||||||
const { class: className, ...rest } = props;
|
const { class: className, ...rest } = props;
|
||||||
return $html("div", { ...rest, class: ui("navbar bg-base-100 shadow-sm px-4", className) }, children);
|
return $html2("div", { ...rest, class: ui("navbar bg-base-100 shadow-sm px-4", className) }, children);
|
||||||
};
|
};
|
||||||
|
|
||||||
// src/components/Radio.js
|
// src/components/Radio.js
|
||||||
@@ -1443,7 +1456,7 @@
|
|||||||
});
|
});
|
||||||
var Radio = (props) => {
|
var Radio = (props) => {
|
||||||
const { class: className, label, tooltip, value, inputValue, name, ...rest } = props;
|
const { class: className, label, tooltip, value, inputValue, name, ...rest } = props;
|
||||||
const radioEl = $html("input", {
|
const radioEl = $html2("input", {
|
||||||
...rest,
|
...rest,
|
||||||
type: "radio",
|
type: "radio",
|
||||||
name,
|
name,
|
||||||
@@ -1456,11 +1469,11 @@
|
|||||||
});
|
});
|
||||||
if (!label && !tooltip)
|
if (!label && !tooltip)
|
||||||
return radioEl;
|
return radioEl;
|
||||||
const layout = $html("label", { class: "label cursor-pointer justify-start gap-3" }, [
|
const layout = $html2("label", { class: "label cursor-pointer justify-start gap-3" }, [
|
||||||
radioEl,
|
radioEl,
|
||||||
label ? $html("span", { class: "label-text" }, label) : null
|
label ? $html2("span", { class: "label-text" }, label) : null
|
||||||
]);
|
]);
|
||||||
return tooltip ? $html("div", { class: "tooltip", "data-tip": tooltip }, layout) : layout;
|
return tooltip ? $html2("div", { class: "tooltip", "data-tip": tooltip }, layout) : layout;
|
||||||
};
|
};
|
||||||
|
|
||||||
// src/components/Range.js
|
// src/components/Range.js
|
||||||
@@ -1470,7 +1483,7 @@
|
|||||||
});
|
});
|
||||||
var Range = (props) => {
|
var Range = (props) => {
|
||||||
const { class: className, label, tooltip, value, ...rest } = props;
|
const { class: className, label, tooltip, value, ...rest } = props;
|
||||||
const rangeEl = $html("input", {
|
const rangeEl = $html2("input", {
|
||||||
...rest,
|
...rest,
|
||||||
type: "range",
|
type: "range",
|
||||||
class: ui("range", className),
|
class: ui("range", className),
|
||||||
@@ -1479,11 +1492,11 @@
|
|||||||
});
|
});
|
||||||
if (!label && !tooltip)
|
if (!label && !tooltip)
|
||||||
return rangeEl;
|
return rangeEl;
|
||||||
const layout = $html("div", { class: "flex flex-col gap-2" }, [
|
const layout = $html2("div", { class: "flex flex-col gap-2" }, [
|
||||||
label ? $html("span", { class: "label-text" }, label) : null,
|
label ? $html2("span", { class: "label-text" }, label) : null,
|
||||||
rangeEl
|
rangeEl
|
||||||
]);
|
]);
|
||||||
return tooltip ? $html("div", { class: "tooltip", "data-tip": tooltip }, layout) : layout;
|
return tooltip ? $html2("div", { class: "tooltip", "data-tip": tooltip }, layout) : layout;
|
||||||
};
|
};
|
||||||
|
|
||||||
// src/components/Rating.js
|
// src/components/Rating.js
|
||||||
@@ -1494,12 +1507,12 @@
|
|||||||
var Rating = (props) => {
|
var Rating = (props) => {
|
||||||
const { class: className, value, count = 5, mask = "mask-star", readonly = false, onchange, ...rest } = props;
|
const { class: className, value, count = 5, mask = "mask-star", readonly = false, onchange, ...rest } = props;
|
||||||
const ratingGroup = `rating-${Math.random().toString(36).slice(2, 7)}`;
|
const ratingGroup = `rating-${Math.random().toString(36).slice(2, 7)}`;
|
||||||
return $html("div", {
|
return $html2("div", {
|
||||||
...rest,
|
...rest,
|
||||||
class: () => ui(`rating ${val(readonly) ? "pointer-events-none" : ""}`, className)
|
class: () => ui(`rating ${val(readonly) ? "pointer-events-none" : ""}`, className)
|
||||||
}, Array.from({ length: val(count) }, (_, i) => {
|
}, Array.from({ length: val(count) }, (_, i) => {
|
||||||
const starValue = i + 1;
|
const starValue = i + 1;
|
||||||
return $html("input", {
|
return $html2("input", {
|
||||||
type: "radio",
|
type: "radio",
|
||||||
name: ratingGroup,
|
name: ratingGroup,
|
||||||
class: `mask ${mask}`,
|
class: `mask ${mask}`,
|
||||||
@@ -1524,18 +1537,18 @@
|
|||||||
});
|
});
|
||||||
var Select = (props) => {
|
var Select = (props) => {
|
||||||
const { class: className, label, items, value, ...rest } = props;
|
const { class: className, label, items, value, ...rest } = props;
|
||||||
const selectEl = $html("select", {
|
const selectEl = $html2("select", {
|
||||||
...rest,
|
...rest,
|
||||||
class: ui("select select-bordered w-full", className),
|
class: ui("select select-bordered w-full", className),
|
||||||
value
|
value
|
||||||
}, $for(() => val(items) || [], (opt) => $html("option", {
|
}, $for(() => val(items) || [], (opt) => $html2("option", {
|
||||||
value: opt.value,
|
value: opt.value,
|
||||||
$selected: () => String(val(value)) === String(opt.value)
|
$selected: () => String(val(value)) === String(opt.value)
|
||||||
}, opt.label), (opt) => opt.value));
|
}, opt.label), (opt) => opt.value));
|
||||||
if (!label)
|
if (!label)
|
||||||
return selectEl;
|
return selectEl;
|
||||||
return $html("label", { class: "fieldset-label flex flex-col gap-1" }, [
|
return $html2("label", { class: "fieldset-label flex flex-col gap-1" }, [
|
||||||
$html("span", {}, label),
|
$html2("span", {}, label),
|
||||||
selectEl
|
selectEl
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
@@ -1547,7 +1560,7 @@
|
|||||||
});
|
});
|
||||||
var Stack = (props, children) => {
|
var Stack = (props, children) => {
|
||||||
const { class: className, ...rest } = props;
|
const { class: className, ...rest } = props;
|
||||||
return $html("div", { ...rest, class: ui("stack", className) }, children);
|
return $html2("div", { ...rest, class: ui("stack", className) }, children);
|
||||||
};
|
};
|
||||||
|
|
||||||
// src/components/Stat.js
|
// src/components/Stat.js
|
||||||
@@ -1557,11 +1570,11 @@
|
|||||||
});
|
});
|
||||||
var Stat = (props) => {
|
var Stat = (props) => {
|
||||||
const { class: className, icon, label, value, desc, ...rest } = props;
|
const { class: className, icon, label, value, desc, ...rest } = props;
|
||||||
return $html("div", { ...rest, class: ui("stat", className) }, [
|
return $html2("div", { ...rest, class: ui("stat", className) }, [
|
||||||
icon && $html("div", { class: "stat-figure text-secondary" }, icon),
|
icon && $html2("div", { class: "stat-figure text-secondary" }, icon),
|
||||||
label && $html("div", { class: "stat-title" }, label),
|
label && $html2("div", { class: "stat-title" }, label),
|
||||||
$html("div", { class: "stat-value" }, () => val(value) ?? value),
|
$html2("div", { class: "stat-value" }, () => val(value) ?? value),
|
||||||
desc && $html("div", { class: "stat-desc" }, desc)
|
desc && $html2("div", { class: "stat-desc" }, desc)
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1572,13 +1585,13 @@
|
|||||||
});
|
});
|
||||||
var Swap = (props) => {
|
var Swap = (props) => {
|
||||||
const { class: className, value, on, off, ...rest } = props;
|
const { class: className, value, on, off, ...rest } = props;
|
||||||
return $html("label", { ...rest, class: ui("swap", className) }, [
|
return $html2("label", { ...rest, class: ui("swap", className) }, [
|
||||||
$html("input", {
|
$html2("input", {
|
||||||
type: "checkbox",
|
type: "checkbox",
|
||||||
checked: val(value)
|
checked: val(value)
|
||||||
}),
|
}),
|
||||||
$html("div", { class: "swap-on" }, on),
|
$html2("div", { class: "swap-on" }, on),
|
||||||
$html("div", { class: "swap-off" }, off)
|
$html2("div", { class: "swap-off" }, off)
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1594,31 +1607,31 @@
|
|||||||
const pinRowsClass = val(pinRows) ? "table-pin-rows" : "";
|
const pinRowsClass = val(pinRows) ? "table-pin-rows" : "";
|
||||||
return ui("table", className, zebraClass, pinRowsClass);
|
return ui("table", className, zebraClass, pinRowsClass);
|
||||||
};
|
};
|
||||||
return $html("div", { class: "overflow-x-auto w-full bg-base-100 rounded-box border border-base-300" }, [
|
return $html2("div", { class: "overflow-x-auto w-full bg-base-100 rounded-box border border-base-300" }, [
|
||||||
$html("table", { ...rest, class: tableClass }, [
|
$html2("table", { ...rest, class: tableClass }, [
|
||||||
$html("thead", {}, [
|
$html2("thead", {}, [
|
||||||
$html("tr", {}, columns.map((col) => $html("th", { class: col.class || "" }, col.label)))
|
$html2("tr", {}, columns.map((col) => $html2("th", { class: col.class || "" }, col.label)))
|
||||||
]),
|
]),
|
||||||
$html("tbody", {}, [
|
$html2("tbody", {}, [
|
||||||
$for(items, (item, index) => {
|
$for(items, (item, index) => {
|
||||||
return $html("tr", { class: "hover" }, columns.map((col) => {
|
return $html2("tr", { class: "hover" }, columns.map((col) => {
|
||||||
const cellContent = () => {
|
const cellContent = () => {
|
||||||
if (col.render)
|
if (col.render)
|
||||||
return col.render(item, index);
|
return col.render(item, index);
|
||||||
const value = item[col.key];
|
const value = item[col.key];
|
||||||
return val(value);
|
return val(value);
|
||||||
};
|
};
|
||||||
return $html("td", { class: col.class || "" }, [cellContent]);
|
return $html2("td", { class: col.class || "" }, [cellContent]);
|
||||||
}));
|
}));
|
||||||
}, keyFn || ((item, idx) => item.id || idx)),
|
}, keyFn || ((item, idx) => item.id || idx)),
|
||||||
$if(() => val(items).length === 0, () => $html("tr", {}, [
|
$if(() => val(items).length === 0, () => $html2("tr", {}, [
|
||||||
$html("td", { colspan: columns.length, class: "text-center p-10 opacity-50" }, [
|
$html2("td", { colspan: columns.length, class: "text-center p-10 opacity-50" }, [
|
||||||
val(empty)
|
val(empty)
|
||||||
])
|
])
|
||||||
]))
|
]))
|
||||||
]),
|
]),
|
||||||
$if(() => columns.some((c) => c.footer), () => $html("tfoot", {}, [
|
$if(() => columns.some((c) => c.footer), () => $html2("tfoot", {}, [
|
||||||
$html("tr", {}, columns.map((col) => $html("th", {}, col.footer || "")))
|
$html2("tr", {}, columns.map((col) => $html2("th", {}, col.footer || "")))
|
||||||
]))
|
]))
|
||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
@@ -1640,13 +1653,13 @@
|
|||||||
}
|
}
|
||||||
onClick?.(e);
|
onClick?.(e);
|
||||||
};
|
};
|
||||||
return $html("div", { ...rest, class: "flex flex-col gap-4 w-full" }, [
|
return $html2("div", { ...rest, class: "flex flex-col gap-4 w-full" }, [
|
||||||
$html("div", {
|
$html2("div", {
|
||||||
role: "tablist",
|
role: "tablist",
|
||||||
class: ui("tabs tabs-box", className)
|
class: ui("tabs tabs-box", className)
|
||||||
}, $for(itemsSignal, (it, idx) => {
|
}, $for(itemsSignal, (it, idx) => {
|
||||||
const isActive = val(it.active) ?? currentActive() === idx;
|
const isActive = val(it.active) ?? currentActive() === idx;
|
||||||
return $html("a", {
|
return $html2("a", {
|
||||||
role: "tab",
|
role: "tab",
|
||||||
class: () => ui("tab", isActive ? "tab-active" : "", val(it.disabled) ? "tab-disabled" : ""),
|
class: () => ui("tab", isActive ? "tab-active" : "", val(it.disabled) ? "tab-disabled" : ""),
|
||||||
onclick: !val(it.disabled) ? handleTabClick(idx, it.onclick) : undefined
|
onclick: !val(it.disabled) ? handleTabClick(idx, it.onclick) : undefined
|
||||||
@@ -1657,7 +1670,7 @@
|
|||||||
if (!activeItem)
|
if (!activeItem)
|
||||||
return null;
|
return null;
|
||||||
const content = val(activeItem.content);
|
const content = val(activeItem.content);
|
||||||
return $html("div", { class: "p-4" }, [
|
return $html2("div", { class: "p-4" }, [
|
||||||
typeof content === "function" ? content() : content
|
typeof content === "function" ? content() : content
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -1677,7 +1690,7 @@
|
|||||||
warning: "icon-[lucide--alert-triangle]",
|
warning: "icon-[lucide--alert-triangle]",
|
||||||
error: "icon-[lucide--alert-circle]"
|
error: "icon-[lucide--alert-circle]"
|
||||||
};
|
};
|
||||||
return $html("ul", {
|
return $html2("ul", {
|
||||||
...rest,
|
...rest,
|
||||||
class: () => ui(`timeline ${val(vertical) ? "timeline-vertical" : "timeline-horizontal"} ${val(compact) ? "timeline-compact" : ""}`, className)
|
class: () => ui(`timeline ${val(vertical) ? "timeline-vertical" : "timeline-horizontal"} ${val(compact) ? "timeline-compact" : ""}`, className)
|
||||||
}, [
|
}, [
|
||||||
@@ -1686,14 +1699,14 @@
|
|||||||
const isLast = i === val(items).length - 1;
|
const isLast = i === val(items).length - 1;
|
||||||
const itemType = item.type || "success";
|
const itemType = item.type || "success";
|
||||||
const renderSlot = (content) => typeof content === "function" ? content() : content;
|
const renderSlot = (content) => typeof content === "function" ? content() : content;
|
||||||
return $html("li", { class: "flex-1" }, [
|
return $html2("li", { class: "flex-1" }, [
|
||||||
!isFirst ? $html("hr", { class: item.completed ? "bg-primary" : "" }) : null,
|
!isFirst ? $html2("hr", { class: item.completed ? "bg-primary" : "" }) : null,
|
||||||
$html("div", { class: "timeline-start" }, [renderSlot(item.title)]),
|
$html2("div", { class: "timeline-start" }, [renderSlot(item.title)]),
|
||||||
$html("div", { class: "timeline-middle" }, [
|
$html2("div", { class: "timeline-middle" }, [
|
||||||
item.icon ? getIcon(item.icon) : getIcon(iconMap[itemType] || iconMap.success)
|
item.icon ? getIcon(item.icon) : getIcon(iconMap[itemType] || iconMap.success)
|
||||||
]),
|
]),
|
||||||
$html("div", { class: "timeline-end timeline-box shadow-sm" }, [renderSlot(item.detail)]),
|
$html2("div", { class: "timeline-end timeline-box shadow-sm" }, [renderSlot(item.detail)]),
|
||||||
!isLast ? $html("hr", { class: item.completed ? "bg-primary" : "" }) : null
|
!isLast ? $html2("hr", { class: item.completed ? "bg-primary" : "" }) : null
|
||||||
]);
|
]);
|
||||||
}, (item, i) => item.id || i)
|
}, (item, i) => item.id || i)
|
||||||
]);
|
]);
|
||||||
@@ -1707,13 +1720,13 @@
|
|||||||
var Toast = (message, type = "alert-success", duration = 3500) => {
|
var Toast = (message, type = "alert-success", duration = 3500) => {
|
||||||
let container = document.getElementById("sigpro-toast-container");
|
let container = document.getElementById("sigpro-toast-container");
|
||||||
if (!container) {
|
if (!container) {
|
||||||
container = $html("div", {
|
container = $html2("div", {
|
||||||
id: "sigpro-toast-container",
|
id: "sigpro-toast-container",
|
||||||
class: "fixed top-0 right-0 z-[9999] p-4 flex flex-col gap-2 pointer-events-none"
|
class: "fixed top-0 right-0 z-[9999] p-4 flex flex-col gap-2 pointer-events-none"
|
||||||
});
|
});
|
||||||
document.body.appendChild(container);
|
document.body.appendChild(container);
|
||||||
}
|
}
|
||||||
const toastHost = $html("div", { style: "display: contents" });
|
const toastHost = $html2("div", { style: "display: contents" });
|
||||||
container.appendChild(toastHost);
|
container.appendChild(toastHost);
|
||||||
let timeoutId;
|
let timeoutId;
|
||||||
const close = () => {
|
const close = () => {
|
||||||
@@ -1734,10 +1747,10 @@
|
|||||||
};
|
};
|
||||||
const ToastComponent = () => {
|
const ToastComponent = () => {
|
||||||
const closeIcon = getIcon("icon-[lucide--x]");
|
const closeIcon = getIcon("icon-[lucide--x]");
|
||||||
const el = $html("div", {
|
const el = $html2("div", {
|
||||||
class: `alert alert-soft ${type} shadow-lg transition-all duration-300 translate-x-10 opacity-0 pointer-events-auto`
|
class: `alert alert-soft ${type} shadow-lg transition-all duration-300 translate-x-10 opacity-0 pointer-events-auto`
|
||||||
}, [
|
}, [
|
||||||
$html("span", {}, [typeof message === "function" ? message() : message]),
|
$html2("span", {}, [typeof message === "function" ? message() : message]),
|
||||||
Button({
|
Button({
|
||||||
class: "btn-xs btn-circle btn-ghost",
|
class: "btn-xs btn-circle btn-ghost",
|
||||||
onclick: close
|
onclick: close
|
||||||
@@ -1758,7 +1771,7 @@
|
|||||||
__export(exports_Tooltip, {
|
__export(exports_Tooltip, {
|
||||||
Tooltip: () => Tooltip
|
Tooltip: () => Tooltip
|
||||||
});
|
});
|
||||||
var Tooltip = (props, children) => $html("div", {
|
var Tooltip = (props, children) => $html2("div", {
|
||||||
...props,
|
...props,
|
||||||
class: () => ui("tooltip", props.ui, props.class),
|
class: () => ui("tooltip", props.ui, props.class),
|
||||||
"data-tip": props.tip
|
"data-tip": props.tip
|
||||||
|
|||||||
6
dist/sigpro-ui.min.js
vendored
6
dist/sigpro-ui.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
|||||||
# Dropdown
|
# Dropdown
|
||||||
|
|
||||||
Dropdown component for creating menus, selectors, and action panels that appear when triggered. Supports both array-based items and custom content.
|
Dropdown component for creating menus that appear when triggered. Uses DaisyUI's native details/summary pattern.
|
||||||
|
|
||||||
## Tag
|
## Tag
|
||||||
|
|
||||||
@@ -12,11 +12,10 @@ Dropdown component for creating menus, selectors, and action panels that appear
|
|||||||
| :--- | :--- | :--- | :--- |
|
| :--- | :--- | :--- | :--- |
|
||||||
| `label` | `string \| VNode \| Signal` | `-` | Button label or content |
|
| `label` | `string \| VNode \| Signal` | `-` | Button label or content |
|
||||||
| `icon` | `string \| VNode \| Signal` | `-` | Icon displayed next to label |
|
| `icon` | `string \| VNode \| Signal` | `-` | Icon displayed next to label |
|
||||||
| `items` | `Array<MenuItem> \| Signal<Array>` | `-` | Array of menu items (alternative to children) |
|
| `items` | `Array<MenuItem> \| Signal<Array>` | Required | Array of menu items |
|
||||||
| `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) |
|
| `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) |
|
||||||
| `children` | `VNode \| function` | `-` | Custom dropdown content (alternative to items) |
|
|
||||||
|
|
||||||
### MenuItem Structure (when using `items`)
|
### MenuItem Structure
|
||||||
|
|
||||||
| Property | Type | Description |
|
| Property | Type | Description |
|
||||||
| :--- | :--- | :--- |
|
| :--- | :--- | :--- |
|
||||||
@@ -43,14 +42,16 @@ Dropdown supports all **daisyUI Dropdown classes**:
|
|||||||
Dropdown({
|
Dropdown({
|
||||||
label: "Menu",
|
label: "Menu",
|
||||||
class: "dropdown-end dropdown-hover",
|
class: "dropdown-end dropdown-hover",
|
||||||
items: menuItems
|
items: [
|
||||||
|
{ label: "Profile", onclick: () => console.log("Profile") },
|
||||||
|
{ label: "Settings", onclick: () => console.log("Settings") }
|
||||||
|
]
|
||||||
});
|
});
|
||||||
// Applies: right-aligned, opens on hover
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Live Examples
|
## Live Examples
|
||||||
|
|
||||||
### Basic Dropdown (Items Array)
|
### Basic Dropdown
|
||||||
|
|
||||||
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@@ -73,7 +74,7 @@ const BasicDemo = () => {
|
|||||||
$mount(BasicDemo, '#demo-basic');
|
$mount(BasicDemo, '#demo-basic');
|
||||||
```
|
```
|
||||||
|
|
||||||
### With Icons (Items Array)
|
### With Icons
|
||||||
|
|
||||||
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@@ -98,7 +99,7 @@ const IconsDemo = () => {
|
|||||||
$mount(IconsDemo, '#demo-icons');
|
$mount(IconsDemo, '#demo-icons');
|
||||||
```
|
```
|
||||||
|
|
||||||
### Action Dropdown (Items Array)
|
### Action Dropdown
|
||||||
|
|
||||||
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@@ -126,7 +127,7 @@ const ActionsDemo = () => {
|
|||||||
$mount(ActionsDemo, '#demo-actions');
|
$mount(ActionsDemo, '#demo-actions');
|
||||||
```
|
```
|
||||||
|
|
||||||
### User Dropdown (Items Array)
|
### User Dropdown
|
||||||
|
|
||||||
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@@ -167,7 +168,7 @@ $mount(UserDropdown, '#demo-user');
|
|||||||
```javascript
|
```javascript
|
||||||
const ReactiveDropdown = () => {
|
const ReactiveDropdown = () => {
|
||||||
const count = $(0);
|
const count = $(0);
|
||||||
|
$watch(()=>console.log(count()));
|
||||||
const items = () => [
|
const items = () => [
|
||||||
{ label: `Count: ${count()}`, onclick: () => {} },
|
{ label: `Count: ${count()}`, onclick: () => {} },
|
||||||
{ label: 'Increment', onclick: () => count(count() + 1) },
|
{ label: 'Increment', onclick: () => count(count() + 1) },
|
||||||
@@ -183,7 +184,7 @@ const ReactiveDropdown = () => {
|
|||||||
$mount(ReactiveDropdown, '#demo-reactive');
|
$mount(ReactiveDropdown, '#demo-reactive');
|
||||||
```
|
```
|
||||||
|
|
||||||
### Notification Dropdown (Custom Children)
|
### Notification Dropdown
|
||||||
|
|
||||||
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@@ -200,81 +201,34 @@ const NotificationsDropdown = () => {
|
|||||||
{ id: 3, title: 'Task completed', time: '2 hours ago', read: true }
|
{ id: 3, title: 'Task completed', time: '2 hours ago', read: true }
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const unreadCount = () => notifications().filter(n => !n.read).length;
|
||||||
|
|
||||||
const markAsRead = (id) => {
|
const markAsRead = (id) => {
|
||||||
notifications(notifications().map(n =>
|
notifications(notifications().map(n =>
|
||||||
n.id === id ? { ...n, read: true } : n
|
n.id === id ? { ...n, read: true } : n
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
const unreadCount = () => notifications().filter(n => !n.read).length;
|
|
||||||
|
|
||||||
return Dropdown({
|
return Dropdown({
|
||||||
label: Span({ class: 'relative' }, [
|
label: Span({ class: 'relative' }, [
|
||||||
'🔔',
|
'🔔',
|
||||||
() => unreadCount() > 0 ? Span({ class: 'badge badge-xs badge-error absolute -top-1 -right-2' }, unreadCount()) : null
|
() => unreadCount() > 0 ? Span({ class: 'badge badge-xs badge-error absolute -top-1 -right-2' }, unreadCount()) : null
|
||||||
]),
|
]),
|
||||||
class: 'dropdown-end',
|
class: 'dropdown-end',
|
||||||
children: () => Div({ class: 'w-80' }, [
|
items: () => notifications().map(notif => ({
|
||||||
Div({ class: 'p-3 border-b border-base-300 font-bold' }, `Notifications (${unreadCount()} unread)`),
|
label: Div({ class: 'flex flex-col' }, [
|
||||||
Div({ class: 'max-h-64 overflow-y-auto' }, notifications().map(notif =>
|
Span({ class: 'font-medium' }, notif.title),
|
||||||
Div({
|
Span({ class: 'text-xs opacity-60' }, notif.time)
|
||||||
class: `p-3 border-b border-base-300 cursor-pointer hover:bg-base-200 ${!notif.read ? 'bg-primary/5' : ''}`,
|
]),
|
||||||
|
class: notif.read ? '' : 'bg-primary/5',
|
||||||
onclick: () => markAsRead(notif.id)
|
onclick: () => markAsRead(notif.id)
|
||||||
}, [
|
}))
|
||||||
Div({ class: 'font-medium' }, notif.title),
|
|
||||||
Div({ class: 'text-xs opacity-60' }, notif.time),
|
|
||||||
!notif.read && Span({ class: 'badge badge-xs badge-primary mt-1' }, 'New')
|
|
||||||
])
|
|
||||||
)),
|
|
||||||
Div({ class: 'p-2 text-center' }, [
|
|
||||||
Button({
|
|
||||||
class: 'btn btn-xs btn-ghost w-full',
|
|
||||||
onclick: () => notifications([])
|
|
||||||
}, 'Clear all')
|
|
||||||
])
|
|
||||||
])
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$mount(NotificationsDropdown, '#demo-notifications');
|
$mount(NotificationsDropdown, '#demo-notifications');
|
||||||
```
|
```
|
||||||
|
|
||||||
### Custom Content Dropdown
|
|
||||||
|
|
||||||
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
|
||||||
<div class="card-body">
|
|
||||||
<h3 class="card-title text-sm uppercase opacity-50 mb-4">Live Demo</h3>
|
|
||||||
<div id="demo-custom" class="bg-base-100 p-6 rounded-xl border border-base-300 flex items-center justify-center"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const CustomDropdown = () => {
|
|
||||||
const selected = $('Option 1');
|
|
||||||
|
|
||||||
return Dropdown({
|
|
||||||
label: () => selected(),
|
|
||||||
children: () => Div({ class: 'p-4 min-w-48' }, [
|
|
||||||
Div({ class: 'text-sm font-bold mb-2' }, 'Select an option'),
|
|
||||||
Div({ class: 'flex flex-col gap-1' }, [
|
|
||||||
Button({
|
|
||||||
class: 'btn btn-ghost btn-sm justify-start',
|
|
||||||
onclick: () => selected('Option 1')
|
|
||||||
}, 'Option 1'),
|
|
||||||
Button({
|
|
||||||
class: 'btn btn-ghost btn-sm justify-start',
|
|
||||||
onclick: () => selected('Option 2')
|
|
||||||
}, 'Option 2'),
|
|
||||||
Button({
|
|
||||||
class: 'btn btn-ghost btn-sm justify-start',
|
|
||||||
onclick: () => selected('Option 3')
|
|
||||||
}, 'Option 3')
|
|
||||||
])
|
|
||||||
])
|
|
||||||
});
|
|
||||||
};
|
|
||||||
$mount(CustomDropdown, '#demo-custom');
|
|
||||||
```
|
|
||||||
|
|
||||||
### All Variants
|
### All Variants
|
||||||
|
|
||||||
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
||||||
|
|||||||
6
docs/sigpro-ui.min.js
vendored
6
docs/sigpro-ui.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -12,7 +12,6 @@ import { ui } from "../core/utils.js";
|
|||||||
export const Drawer = (props, children) => {
|
export const Drawer = (props, children) => {
|
||||||
const { class: className, id, open, side, content, ...rest } = props;
|
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)}`;
|
const drawerId = id || `drawer-${Math.random().toString(36).slice(2, 9)}`;
|
||||||
|
|
||||||
return $html("div", {
|
return $html("div", {
|
||||||
@@ -32,7 +31,6 @@ export const Drawer = (props, children) => {
|
|||||||
typeof content === "function" ? content() : content
|
typeof content === "function" ? content() : content
|
||||||
]),
|
]),
|
||||||
$html("div", { class: "drawer-side" }, [
|
$html("div", { class: "drawer-side" }, [
|
||||||
// El overlay debe tener for apuntando al checkbox
|
|
||||||
$html("label", {
|
$html("label", {
|
||||||
for: drawerId,
|
for: drawerId,
|
||||||
class: "drawer-overlay",
|
class: "drawer-overlay",
|
||||||
|
|||||||
@@ -1,65 +1,78 @@
|
|||||||
// components/Dropdown.js
|
// components/Dropdown.js
|
||||||
import { $html, $for } from "sigpro";
|
// import { $html, $for, $watch } from "sigpro";
|
||||||
import { ui } from "../core/utils.js";
|
import { ui } from "../core/utils.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dropdown component
|
* Dropdown component - Solo soporta menús (items)
|
||||||
*
|
*
|
||||||
* daisyUI classes used:
|
* daisyUI classes used:
|
||||||
* - dropdown, dropdown-content, dropdown-end, dropdown-top, dropdown-bottom
|
* - dropdown, dropdown-content, dropdown-end, dropdown-top, dropdown-bottom
|
||||||
* - menu, menu-dropdown, menu-dropdown-show
|
* - menu, btn
|
||||||
* - btn, btn-ghost, btn-sm, btn-md, btn-lg
|
* - bg-base-100, shadow, rounded-box, border
|
||||||
* - bg-base-100, shadow, rounded-box, border, border-base-300
|
* - z-50, p-2, w-52
|
||||||
* - z-50, p-2, w-52, min-w-max
|
|
||||||
* - m-1, flex, items-center, gap-2
|
* - 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 { class: className, label, icon, items, ...rest } = props;
|
||||||
|
|
||||||
const renderContent = () => {
|
return $html("details", {
|
||||||
if (items) {
|
...rest,
|
||||||
const source = typeof items === "function" ? items : () => items;
|
class: ui('dropdown', className),
|
||||||
return $html("ul", {
|
}, [
|
||||||
tabindex: 0,
|
$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"
|
class: "dropdown-content z-[50] menu p-2 shadow bg-base-100 rounded-box w-52 border border-base-300"
|
||||||
}, [
|
}, [
|
||||||
$for(source, (item) =>
|
() => {
|
||||||
|
const currentItems = typeof items === "function" ? items() : (items || []);
|
||||||
|
return currentItems.map(item =>
|
||||||
$html("li", {}, [
|
$html("li", {}, [
|
||||||
$html("a", {
|
$html("a", {
|
||||||
class: item.class || "",
|
class: item.class || "",
|
||||||
onclick: (e) => {
|
onclick: (e) => {
|
||||||
if (item.onclick) item.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,
|
item.icon ? $html("span", {}, item.icon) : null,
|
||||||
$html("span", {}, item.label)
|
$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()
|
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user