From c9411be60088a5256b1188e464cbbb86e0612011 Mon Sep 17 00:00:00 2001 From: natxocc Date: Wed, 1 Apr 2026 09:26:52 +0200 Subject: [PATCH] Complete 1 fase docs components --- dist/sigpro-ui.cjs | 86 ++-- dist/sigpro-ui.esm.js | 86 ++-- dist/sigpro-ui.umd.js | 86 ++-- dist/sigpro-ui.umd.min.js | 2 +- docs/_sidebar.md | 35 +- docs/components/accordion.md | 730 ++++++++++++++++++++++++++++ docs/components/drawer.md | 918 +++++++++++++++++++++++++++++++++++ docs/components/dropdown.md | 489 +++++++++++++++++++ docs/components/fab.md | 688 ++++++++++++++++++++++++++ docs/components/fieldset.md | 549 +++++++++++++++++++++ docs/components/loading.md | 597 +++++++++++++++++++++++ docs/components/menu.md | 760 +++++++++++++++++++++++++++++ docs/components/navbar.md | 551 +++++++++++++++++++++ docs/components/tabs.md | 677 ++++++++++++++++++++++++++ docs/components/tooltip.md | 554 +++++++++++++++++++++ docs/index.html | 6 +- docs/sigpro-ui.umd.min.js | 1 + docs/sigpro.min.js | 1 + rollup.config.js | 13 + src/components/Dropdown.js | 82 ++-- src/components/Fab.js | 10 +- 21 files changed, 6748 insertions(+), 173 deletions(-) create mode 100644 docs/components/accordion.md create mode 100644 docs/components/drawer.md create mode 100644 docs/components/dropdown.md create mode 100644 docs/components/fab.md create mode 100644 docs/components/fieldset.md create mode 100644 docs/components/loading.md create mode 100644 docs/components/menu.md create mode 100644 docs/components/navbar.md create mode 100644 docs/components/tabs.md create mode 100644 docs/components/tooltip.md create mode 100644 docs/sigpro-ui.umd.min.js create mode 100644 docs/sigpro.min.js diff --git a/dist/sigpro-ui.cjs b/dist/sigpro-ui.cjs index 73327d4..81baa1b 100644 --- a/dist/sigpro-ui.cjs +++ b/dist/sigpro-ui.cjs @@ -750,39 +750,55 @@ var DrawerModule = /*#__PURE__*/Object.freeze({ Drawer: Drawer }); -/** DROPDOWN */ const Dropdown = (props, children) => { - const { label, icon, ...rest } = props; + const { label, icon, items, ...rest } = props; - return sigpro.$html( - "div", - { - ...rest, - class: () => `dropdown ${val(props.class) || props.class || ""}`, - }, - [ - sigpro.$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 - ], - ), - sigpro.$html( - "ul", - { - tabindex: 0, - class: "dropdown-content z-[50] menu p-2 shadow bg-base-100 rounded-box min-w-max border border-base-300", - }, - [typeof children === "function" ? children() : children], - ), - ], - ); + const renderContent = () => { + if (items) { + const source = typeof items === "function" ? items : () => items; + return sigpro.$html("ul", { + tabindex: 0, + class: "dropdown-content z-[50] menu p-2 shadow bg-base-100 rounded-box w-52 border border-base-300" + }, [ + sigpro.$for(source, (item) => + sigpro.$html("li", {}, [ + sigpro.$html("a", { + class: item.class || "", + onclick: (e) => { + if (item.onclick) item.onclick(e); + if (document.activeElement) document.activeElement.blur(); + } + }, [ + item.icon ? sigpro.$html("span", {}, item.icon) : null, + sigpro.$html("span", {}, item.label) + ]) + ]) + ) + ]); + } + + return sigpro.$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 sigpro.$html("div", { + ...rest, + class: () => `dropdown ${val(props.class) || ""}`, + }, [ + sigpro.$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() + ]); }; var DropdownModule = /*#__PURE__*/Object.freeze({ @@ -792,18 +808,15 @@ var DropdownModule = /*#__PURE__*/Object.freeze({ /** FAB (Floating Action Button) */ const Fab = (props) => { - const { icon, label, actions = [], position = "bottom-6 right-6", ...rest } = props; + const { icon, label, actions = [], position = "bottom-6 right-6", class: className = "", ...rest } = props; return sigpro.$html( "div", { ...rest, - class: () => `fab fixed ${val(position)} flex flex-col-reverse items-end gap-3 z-[100] ${ - props.class || "" - }`, + class: `fab absolute ${position} flex flex-col-reverse items-end gap-3 z-[100] ${className}`, }, [ - // Botón principal sigpro.$html( "div", { @@ -817,7 +830,6 @@ const Fab = (props) => { ], ), - // Acciones secundarias (se despliegan hacia arriba) ...val(actions).map((act) => sigpro.$html("div", { class: "flex items-center gap-3 transition-all duration-300" }, [ act.label ? sigpro.$html("span", { class: "badge badge-ghost shadow-sm whitespace-nowrap" }, act.label) : null, diff --git a/dist/sigpro-ui.esm.js b/dist/sigpro-ui.esm.js index 34a2398..5bc61bf 100644 --- a/dist/sigpro-ui.esm.js +++ b/dist/sigpro-ui.esm.js @@ -746,39 +746,55 @@ var DrawerModule = /*#__PURE__*/Object.freeze({ Drawer: Drawer }); -/** DROPDOWN */ const Dropdown = (props, children) => { - const { label, icon, ...rest } = props; + const { label, icon, items, ...rest } = props; - return $html( - "div", - { - ...rest, - class: () => `dropdown ${val(props.class) || props.class || ""}`, - }, - [ - $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 - ], - ), - $html( - "ul", - { - tabindex: 0, - class: "dropdown-content z-[50] menu p-2 shadow bg-base-100 rounded-box min-w-max border border-base-300", - }, - [typeof children === "function" ? children() : children], - ), - ], - ); + 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) => + $html("li", {}, [ + $html("a", { + class: item.class || "", + onclick: (e) => { + if (item.onclick) item.onclick(e); + if (document.activeElement) document.activeElement.blur(); + } + }, [ + 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: () => `dropdown ${val(props.class) || ""}`, + }, [ + $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() + ]); }; var DropdownModule = /*#__PURE__*/Object.freeze({ @@ -788,18 +804,15 @@ var DropdownModule = /*#__PURE__*/Object.freeze({ /** FAB (Floating Action Button) */ const Fab = (props) => { - const { icon, label, actions = [], position = "bottom-6 right-6", ...rest } = props; + const { icon, label, actions = [], position = "bottom-6 right-6", class: className = "", ...rest } = props; return $html( "div", { ...rest, - class: () => `fab fixed ${val(position)} flex flex-col-reverse items-end gap-3 z-[100] ${ - props.class || "" - }`, + class: `fab absolute ${position} flex flex-col-reverse items-end gap-3 z-[100] ${className}`, }, [ - // Botón principal $html( "div", { @@ -813,7 +826,6 @@ const Fab = (props) => { ], ), - // Acciones secundarias (se despliegan hacia arriba) ...val(actions).map((act) => $html("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, diff --git a/dist/sigpro-ui.umd.js b/dist/sigpro-ui.umd.js index 4107981..f4c0d6b 100644 --- a/dist/sigpro-ui.umd.js +++ b/dist/sigpro-ui.umd.js @@ -747,39 +747,55 @@ var SigProUI = (function (exports, sigpro) { Drawer: Drawer }); - /** DROPDOWN */ const Dropdown = (props, children) => { - const { label, icon, ...rest } = props; + const { label, icon, items, ...rest } = props; - return sigpro.$html( - "div", - { - ...rest, - class: () => `dropdown ${val(props.class) || props.class || ""}`, - }, - [ - sigpro.$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 - ], - ), - sigpro.$html( - "ul", - { - tabindex: 0, - class: "dropdown-content z-[50] menu p-2 shadow bg-base-100 rounded-box min-w-max border border-base-300", - }, - [typeof children === "function" ? children() : children], - ), - ], - ); + const renderContent = () => { + if (items) { + const source = typeof items === "function" ? items : () => items; + return sigpro.$html("ul", { + tabindex: 0, + class: "dropdown-content z-[50] menu p-2 shadow bg-base-100 rounded-box w-52 border border-base-300" + }, [ + sigpro.$for(source, (item) => + sigpro.$html("li", {}, [ + sigpro.$html("a", { + class: item.class || "", + onclick: (e) => { + if (item.onclick) item.onclick(e); + if (document.activeElement) document.activeElement.blur(); + } + }, [ + item.icon ? sigpro.$html("span", {}, item.icon) : null, + sigpro.$html("span", {}, item.label) + ]) + ]) + ) + ]); + } + + return sigpro.$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 sigpro.$html("div", { + ...rest, + class: () => `dropdown ${val(props.class) || ""}`, + }, [ + sigpro.$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() + ]); }; var DropdownModule = /*#__PURE__*/Object.freeze({ @@ -789,18 +805,15 @@ var SigProUI = (function (exports, sigpro) { /** FAB (Floating Action Button) */ const Fab = (props) => { - const { icon, label, actions = [], position = "bottom-6 right-6", ...rest } = props; + const { icon, label, actions = [], position = "bottom-6 right-6", class: className = "", ...rest } = props; return sigpro.$html( "div", { ...rest, - class: () => `fab fixed ${val(position)} flex flex-col-reverse items-end gap-3 z-[100] ${ - props.class || "" - }`, + class: `fab absolute ${position} flex flex-col-reverse items-end gap-3 z-[100] ${className}`, }, [ - // Botón principal sigpro.$html( "div", { @@ -814,7 +827,6 @@ var SigProUI = (function (exports, sigpro) { ], ), - // Acciones secundarias (se despliegan hacia arriba) ...val(actions).map((act) => sigpro.$html("div", { class: "flex items-center gap-3 transition-all duration-300" }, [ act.label ? sigpro.$html("span", { class: "badge badge-ghost shadow-sm whitespace-nowrap" }, act.label) : null, diff --git a/dist/sigpro-ui.umd.min.js b/dist/sigpro-ui.umd.min.js index f6ff5f6..65f7fb1 100644 --- a/dist/sigpro-ui.umd.min.js +++ b/dist/sigpro-ui.umd.min.js @@ -1 +1 @@ -var SigProUI=function(t,e){"use strict";const l=t=>"function"==typeof t?t():t,a=(t,e)=>"function"==typeof e?()=>`${t} ${e()||""}`.trim():`${t} ${e||""}`.trim();var o=Object.freeze({__proto__:null,joinClass:a,val:l});const n=(t,l)=>{const{title:o,name:n,open:s,...A}=t;return e.$html("div",{...A,class:a("collapse collapse-arrow bg-base-200 mb-2",t.class)},[e.$html("input",{type:n?"radio":"checkbox",name:n,checked:s}),e.$html("div",{class:"collapse-title text-xl font-medium"},o),e.$html("div",{class:"collapse-content"},l)])};var s=Object.freeze({__proto__:null,Accordion:n});const A="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADjSURBVDiN3dJNSgNBEAXgz4DZeAAVJ9tko2St3kaIFxAVt4KZeAD1GKKi7vQSydI/yHgALxAXU02GxniAFBR0v1ev+3V1sZSxjxtM8BM5wTX2/hNu4gFvOMI21iJ3cIwP3GMjF/dQ4RyraOMS34GPAmvjIrBeEnfwjoPGgSM8ooh8QtngB6Ep4BWnmaMqkY1LqqzmDC8tzNDK3/RHzLL9SloUYWfQIMuw3Yl8xrDBH6qbvZWALqbqBqVmlWF7GuKEDwPr5hbXcYdPnKBv/o39wL5wG7ULY1c9NGPzQRrjKrhli1/02zEjWyWMBwAAAABJRU5ErkJggg==",c="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAEDSURBVDiN1dK/K8VhFAbwD+VLGSxKcu9guSQ/Zils/gNkuaX4BxRZDTdklYU/QAaDlEVGGwu2Kz/uVbKJzWDwfuv1+jHz1Km3c85znuf0Hv4jxnD2W8MItnCJ5xAX2MQcHsOQL+jEAapYQD9aQwxiDy+B3JKSe1DHCpqQYQ0PeMJOpDyAmyAAirjGbDRwFYcoYCZSzjGP+8B1gqXEUT2QxyPlqaRnGceNeENzUswwil1MBocbSU9DCAXUUI6K25HtIo5QSVaooitP9OEO65iIbE+HXSvBVRbeNZQSR9pxGil3o83HNw5hEbfYR0dKFki5ci+u8OrzIQ1/R8xx7ocL+9t4B0HPOVXjoptxAAAAAElFTkSuQmCC",r="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABcSURBVDiN3dIxDoAwCIXhL563g3bSm+hlq4O6GFNbO+k/EV54QIDfsSBk9IA5ZxCQEG+0eGi5BqDHivEhV2xSXXwy2EdOR3xLV+ta0/26wvSm+KTYpPmMzY/0QTZeZR2f+FxhRQAAAABJRU5ErkJggg==",i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAACLSURBVDiN7dO9CQJBFEXhb38K0FwQrMNEVpuwB0NjrcYabECsQk0sQ1mTF4zIjrgmBh54MMx998AEwzOrmC5e8gJjbDHCJO7PHYI0v2JT4Ig9DljGwq5DkOZTLOCOMoIhBpknpHmFWx3ldaaUo6oTc2/ab7rl+508f8GvCC5oenTn4tM1cWg/nBNmD4fBH/Kfvt2TAAAAAElFTkSuQmCC",d="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAWQAAAFkBqp2phgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAACQSURBVDiN7dKxDcJQDATQJ0YgXQQ1bAgDEIZBETPQwjakIjRQ8CMSyR8SiZKTrvHZd/r+JsYSNZrEI1ZR4ywzfElcJ55xwiITOECNTVDf4jDGoEEZ1Etcxxg8pmjRDiahb7BH20uKKPVUkVmL+YjQArdI+PT2bO9Pd/A34O71Rd9QeN/LAFUSckfUscWuG3oCgP8nrDH6T5AAAAAASUVORK5CYII=",m="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADFSURBVDiN7dCxSoIBFAXgr1BbgmgSB5ubxKAHaAkcgnBpySVaDET3WhzcpQfoHZojawgX0ZZcfAWDSDdBoeUKP/8ojZ7tnnPv4dzDFv+KZzwl5jf84B354C4wwjdeUV4vl7DCEsXgxmhigDpOMcMVjoKr7cTyI/ZxiE90wmCB4zi+RRatZOxd7OEavxHtBmvjIV5wH2a59N8ZXIZQisMCzkL/wgGq6EYffXzgHHNo4y5h+oBGlLjEBJVUiVP0cJJOtMUG+APtfyYzbH7eVgAAAABJRU5ErkJggg==",u="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAB2AAAAdgFOeyYIAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAMxJREFUOI3t0bFKwlEUBvBfmmBEr1APIDZJ9AJJQyAIvkGP0C4uQruza+DUmuIc9AC9gBG4Nmpkw/8IB3Vw1w8u95zvnvPde77LEeUUV9HAF67QRA2nmMf5A+o4x3cWOsMYy8j7WMX6jaYbLBL/mAWe8RcHm1ihs8G94gVKQQzwlAouMcQo8p/Y28HdYpYFZmsi0MVdxD1MdrxsC500wijdvgtbI1AYtDbxMwkuFAZmE1uYwkkSqOIaHyHcxEU0vUXNPSqKr37fZ6xDwD9DPS0OyHjQHQAAAABJRU5ErkJggg==",p="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAC4SURBVDiNxdIxagJRFIXhLzLFBNJYaJslSEylWOhq3IorMGQ16SyjYCFiZWU5pTaDFvOUyTAZ8RHID69555577oXLf/OEGaY4R3g/4IhORHg3eOXYYvSAeRQ8OWQYYoNPvDQYnxUr7zBB1grCAv3QbIlxjXmAb7Txhq+rkFUKq9NUU8vcJiizwDtOWGEdmvTKqT+61H0GXsP7jSxpEGF/R1e3wkO0FBeVRnhTSBTneBB3yvOI4D/mAnvrIwKM5s4AAAAAAElFTkSuQmCC",h="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAnXAAAJ1wGxbhe3AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAASVJREFUOI190r0uhFEQBuBnVxaF2PUTCkFchV0SV6BQi0rEbShFlCqNktJP0Iqf3i3YVSlXVEQozojP8e2+ySSTed+ZMzNnKnpjCFPhv+C9j/YPlnCBV3TCujhHq19iFftoYxOjBa4esTb2QvsP+7jFWJ9HxnEXRf5gGU9Z8gKucBl+sUgHTahE8AJnOCoIT/AcmhmsF7gtrGINBqWFFWcmLXMUhzjIuEbk1GA+2i/DNh4wUsK1MVfFV2GUHJO4xlsPHr8j1Eu44bAcDek2agP4lDZaxWMm3MEKbrL4hjT/8U+gJc00nglnw4qYkL5xMW9rTzqSvEiefI/dMrIaRTrSPzcKXCNinUguPeUfNKWj6kqH9Bz+aVnbvb6PtKTp8F/wUSb6Bu5YN5n7ff0kAAAAAElFTkSuQmCC",g="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAnXAAAJ1wGxbhe3AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAQtJREFUOI2F0jFOAlEQBuAPImoFqyTa6TEEbfUihruYDYfwCAg3UDsTY20na0VjgqUWWuxgHsuy/skk82bmn/fPm9eyHXs4Cn+Br4baNZxjhk8UYUtMMWwitjHGHNfoJrlexObIo3YDY9zjoOGSQzxEkzVc4O0fctqkwCANzkJiE9LmI9ytDrvKB+tWGQnylIAsOB04VcrfdluO55CeYo6THfygVUne4jX8S1zho1LTDu7fCL2KxCe8oF8zUqb8G51VYGrzEffD6jDCJA0MY6bqnHXoK9d4Vk3kyk/S1KSPR9zUJdvRpAiJWZLLIlYEufYrrzBQ7nyJ97ClcuYN2dX1pejgOPwFvuuKfgHXiDR+HL1j1AAAAABJRU5ErkJggg==",b="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAnXAAAJ1wGxbhe3AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAARZJREFUOI2V0j1KQ1EQBeDPp4lWRiMoKVyAK9AoiLgJGytxD9oJNhKyDyvBnw2IugC3YGKVRk1KRbR48yC5vjzwwIHL3DPnzp2ZGdMxj9U4D/BZoZ3ANu4wQj84xC3aVYkZuujhCItjd42I9dAJ7R908YDlikeaeAyTCezgpST5IJia9LFVlA0nOMd7It4IjuMttKeFQR17uKooPcUV9lHL0ArX0T8MPqLa1hx+MDNFWDX7LHLV4/VGiWghmGJJvhu1WXzLO5rhORGeYRf3SfwQNVwWgbZ8SZqJcD04jhX5GDfTsjryJUlN0uQnXJRdZmHSx7H8nwWWItaP5NJVLrCFG3mTXoNDXJeVPW185E1ai/MAX2WiX9S3NSPYbj+uAAAAAElFTkSuQmCC",f="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAnXAAAJ1wGxbhe3AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAARJJREFUOI2l0r8uRFEQBvAfu9glwUYiUaxHUEl0VDpKeq+wpZBINAqFRHgTKg0tCSqVhmKDEM1u/Esodm725rq7iC+ZzMnM982ZmXP4JwpdchWsYBrXeMkj9XQQV3GEi+BMYR63v+mqiDPUUrEaTiP3I1ZxEOcySnE+jFxXVPEQPimWiCYzOdCbKbCFPe1Z+8PgBvvBycVMCIdSsY2wBEPBmcnrYBtraKRib2EJGljHjswLLuI8Z6SS9hLTl15iIR08wZLv2AzLYjk0YATP8n9lVWbrgUJohosYxCdG8Zghdvp5ldCUi6hrPd0VjvGEVzTxEYLkogGMYQ67uEtvcgKzGA8y9IV/D9/Evdb89Q7d/Q1fB8U0mpUmzV0AAAAASUVORK5CYII=",$="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABfSURBVDiNY2AY8oCZSHWxDAwMEgwMDHfJsaSAgYHhH9QQsjT/Z2BgKKe75gQGiLMLCSlkwiHOSI6t6ADmhYoBN6SIARIeidgkiUlIxxkYGB4xMDB8YmBguE6JSwYpAACvLRHTKwPjZgAAAABJRU5ErkJggg==",v="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABNSURBVDiN3dAxCoAwFATRh3fU2oAHiDbi5Y1F2jT+gKLbzyy7/DYjUo8g4cTWI8koOF6XrOqc5ifDDVGJthfsj8OLujtHYJgwR+GP5QKMxA9/SolDQgAAAABJRU5ErkJggg==",B="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABlSURBVDiN3ZLBDUBAEEUfmtCchA5woUMlOO1FCQrAwbqwf8eFhHd7mfzJn2Tg82TGvABywAmPUgOLD4XcDK9AJ/y5cOlrNsIvpCdPDL/FUbkX/t6Slv3+SjgQf6QBmIAZGAP+FzZJViOd89x8pAAAAABJRU5ErkJggg==",w="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABmSURBVDiN3dGxCoAgEMbxfz1dL1BTREJzmUv08trgDYcg6VCD3/YD7zvkoLmMgFEegLmmwAAecOJVvNeUWCAAt7IHjt9LThkyiRf9qC8oCom70u0BuDL+bngj/tNm/JqJePucW8wDvGYdzT0nMUkAAAAASUVORK5CYII=",x="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADNSURBVDiNndOxTgJRFIThz41ZDMFKqH0DLSRSq4lQ0RifUcMzUJlYQKjtLcHVSimBggPRNSzs/sk0kzPnTHEvxZyHKnGJD3yhXSWcYRnKwvvH0Y7wEG/4wQI1XOEek6LLF3FtiDoGoXp4WcxsSXILHjFCH/Nf/jy8ER6KGuTZNNhJvkFpEpygUyHbRi1BFy8VFryilyANlSVFerxn6N36IRVyG0PNEtdbkbmBU8zwdOCSJp4xRWNj3sWS5YGaRvM/f6GBa5ztafCJMb5hBQQ/MMwXLnnZAAAAAElFTkSuQmCC";var y=Object.freeze({__proto__:null,icon123:u,iconAbc:m,iconCalendar:i,iconClose:r,iconError:b,iconHide:c,iconInfo:h,iconLLeft:B,iconLeft:$,iconLock:d,iconMail:p,iconRRight:w,iconRight:v,iconShow:A,iconSuccess:g,iconUpload:x,iconWarning:f});const S=(t,a)=>{const{type:o="info",soft:n=!0,...s}=t,A={info:h,success:g,warning:f,error:b},c=a||t.message;return e.$html("div",{...s,role:"alert",class:()=>`alert ${(()=>{const t=l(o);return{info:"alert-info",success:"alert-success",warning:"alert-warning",error:"alert-error"}[t]||t})()} ${l(n)?"alert-soft":""} ${t.class||""}`},[e.$html("img",{src:A[l(o)]||A.info,class:"w-4 h-4 object-contain",alt:l(o)}),e.$html("div",{class:"flex-1"},[e.$html("span",{},["function"==typeof c?c():c])]),t.actions?e.$html("div",{class:"flex-none"},["function"==typeof t.actions?t.actions():t.actions]):null])};var C=Object.freeze({__proto__:null,Alert:S});const U={es:{close:"Cerrar",confirm:"Confirmar",cancel:"Cancelar",search:"Buscar...",loading:"Cargando...",nodata:"Sin datos"},en:{close:"Close",confirm:"Confirm",cancel:"Cancel",search:"Search...",loading:"Loading...",nodata:"No data"}},k=e.$("es"),R=t=>()=>U[k()][t]||t,D=t=>{const{label:o,tip:n,value:s,error:r,isSearch:h,icon:g,type:b="text",...f}=t,$="password"===b,v=e.$(!1),B={text:m,password:d,date:i,number:u,email:p},w=e.$html("input",{...f,type:()=>$?v()?"text":"password":b,placeholder:t.placeholder||o||(h?R("search")():" "),class:a("grow order-2 focus:outline-none",t.class),value:s,oninput:e=>t.oninput?.(e),disabled:()=>l(t.disabled)}),x=g||(B[b]?e.$html("img",{src:B[b],class:"opacity-50",alt:b}):null);return e.$html("label",{class:()=>a("input input-bordered floating-label flex items-center gap-2 w-full relative",l(r)?"input-error":"")},[x?e.$html("div",{class:"order-1 shrink-0"},x):null,o?e.$html("span",{class:"text-base-content/60 order-0"},o):null,w,$?e.$html("button",{type:"button",class:"order-3 btn btn-ghost btn-xs btn-circle opacity-50 hover:opacity-100",onclick:t=>{t.preventDefault(),v(!v())}},()=>e.$html("img",{class:"w-5 h-5",src:v()?A:c})):null,n?e.$html("div",{class:"tooltip tooltip-left order-4","data-tip":n},e.$html("span",{class:"badge badge-ghost badge-xs cursor-help"},"?")):null,()=>l(r)?e.$html("span",{class:"text-error text-[10px] absolute -bottom-5 left-2"},l(r)):null])};var j=Object.freeze({__proto__:null,Input:D});const _=t=>{const{options:a=[],value:o,onSelect:n,label:s,placeholder:A,...c}=t,r=e.$(l(o)||""),i=e.$(!1),d=e.$(-1),m=e.$(()=>{const t=r().toLowerCase(),e=l(a)||[];return t?e.filter(e=>("string"==typeof e?e:e.label).toLowerCase().includes(t)):e}),u=t=>{const e="string"==typeof t?t:t.value,l="string"==typeof t?t:t.label;r(l),"function"==typeof o&&o(e),n?.(t),i(!1),d(-1)};return e.$html("div",{class:"relative w-full"},[D({label:s,placeholder:A||R("search")(),value:r,onfocus:()=>i(!0),onblur:()=>setTimeout(()=>i(!1),150),onkeydown:t=>{const e=m();"ArrowDown"===t.key?(t.preventDefault(),i(!0),d(Math.min(d()+1,e.length-1))):"ArrowUp"===t.key?(t.preventDefault(),d(Math.max(d()-1,0))):"Enter"===t.key&&d()>=0?(t.preventDefault(),u(e[d()])):"Escape"===t.key&&i(!1)},oninput:t=>{const e=t.target.value;r(e),"function"==typeof o&&o(e),i(!0),d(-1)},...c}),e.$html("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",style:()=>i()&&m().length?"display:block":"display:none"},[e.$for(m,(t,l)=>e.$html("li",{},[e.$html("a",{class:()=>"block w-full "+(d()===l?"active bg-primary text-primary-content":""),onclick:()=>u(t),onmouseenter:()=>d(l)},"string"==typeof t?t:t.label)]),(t,e)=>("string"==typeof t?t:t.value)+e),()=>m().length?null:e.$html("li",{class:"p-2 text-center opacity-50"},"No results")])])};const z=(t,l)=>e.$html("span",{...t,class:a("badge",t.class)},l);const E=(t,o)=>{const{badge:n,badgeClass:s,tooltip:A,icon:c,loading:r,...i}=t;let d=e.$html("button",{...i,class:a("btn",t.class),disabled:()=>l(r)||l(t.disabled)},[()=>l(r)?e.$html("span",{class:"loading loading-spinner"}):null,c?e.$html("span",{class:"mr-1"},c):null,o]);return n&&(d=e.$html("div",{class:"indicator"},[e.$html("span",{class:a("indicator-item badge",s||"badge-secondary")},n),d])),A?e.$html("div",{class:"tooltip","data-tip":A},d):d};const I=t=>{const{value:a,tooltip:o,toggle:n,label:s,...A}=t,c=e.$html("input",{...A,type:"checkbox",class:()=>l(n)?"toggle":"checkbox",checked:a}),r=e.$html("label",{class:"label cursor-pointer justify-start gap-3"},[c,s?e.$html("span",{class:"label-text"},s):null]);return o?e.$html("div",{class:"tooltip","data-tip":o},r):r};const Y=t=>{const{value:a,label:o,...n}=t,s=e.$(!1),A=["#000","#1A1A1A","#333","#4D4D4D","#666","#808080","#B3B3B3","#FFF","#450a0a","#7f1d1d","#991b1b","#b91c1c","#dc2626","#ef4444","#f87171","#fca5a5","#431407","#7c2d12","#9a3412","#c2410c","#ea580c","#f97316","#fb923c","#ffedd5","#713f12","#a16207","#ca8a04","#eab308","#facc15","#fde047","#fef08a","#fff9c4","#064e3b","#065f46","#059669","#10b981","#34d399","#4ade80","#84cc16","#d9f99d","#082f49","#075985","#0284c7","#0ea5e9","#38bdf8","#7dd3fc","#22d3ee","#cffafe","#1e1b4b","#312e81","#4338ca","#4f46e5","#6366f1","#818cf8","#a5b4fc","#e0e7ff","#2e1065","#4c1d95","#6d28d9","#7c3aed","#8b5cf6","#a855f7","#d946ef","#fae8ff"],c=()=>l(a)||"#000000";return e.$html("div",{class:"relative w-fit"},[e.$html("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",onclick:t=>{t.stopPropagation(),s(!s())},...n},[e.$html("div",{class:"size-5 rounded-sm shadow-inner border border-black/10 shrink-0",style:()=>`background-color: ${c()}`}),o?e.$html("span",{class:"opacity-80"},o):null]),e.$if(s,()=>e.$html("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",onclick:t=>t.stopPropagation()},[e.$html("div",{class:"grid grid-cols-8 gap-1"},A.map(t=>e.$html("button",{type:"button",style:`background-color: ${t}`,class:()=>"size-6 rounded-sm cursor-pointer transition-all hover:scale-125 hover:z-10 active:scale-95 outline-none border border-black/5 \n "+(c().toLowerCase()===t.toLowerCase()?"ring-2 ring-offset-1 ring-primary z-10 scale-110":""),onclick:()=>{"function"==typeof a&&a(t),s(!1)}})))])),e.$if(s,()=>e.$html("div",{class:"fixed inset-0 z-[100]",onclick:()=>s(!1)}))])};const V=t=>{const{value:a,range:o,label:n,placeholder:s,hour:A=!1,...c}=t,r=e.$(!1),d=e.$(new Date),m=e.$(null),u=e.$(0),p=e.$(0),h=()=>!0===l(o),g=new Date,b=`${g.getFullYear()}-${String(g.getMonth()+1).padStart(2,"0")}-${String(g.getDate()).padStart(2,"0")}`,f=t=>`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")}`,x=t=>{const e=f(t),o=l(a);if(h())if(!o?.start||o.start&&o.end)"function"==typeof a&&a({start:e,end:null,...A&&{startHour:u()}});else{const t=o.start;if("function"==typeof a){const l=e{const t=l(a);if(!t)return"";if("string"==typeof t)return A&&t.includes("T")?t.replace("T"," "):t;if(t.start&&t.end){return`${A&&t.startHour?`${t.start} ${String(t.startHour).padStart(2,"0")}:00`:t.start} - ${A&&t.endHour?`${t.end} ${String(t.endHour).padStart(2,"0")}:00`:t.end}`}if(t.start){return`${A&&t.startHour?`${t.start} ${String(t.startHour).padStart(2,"0")}:00`:t.start}...`}return""}),S=t=>{const e=d();d(new Date(e.getFullYear(),e.getMonth()+t,1))},C=t=>{const e=d();d(new Date(e.getFullYear()+t,e.getMonth(),1))},U=({value:t,onChange:a})=>e.$html("div",{class:"flex-1"},[e.$html("div",{class:"flex gap-2 items-center"},[e.$html("input",{type:"range",min:0,max:23,value:t,class:"range range-xs flex-1",oninput:t=>{const e=parseInt(t.target.value);a(e)}}),e.$html("span",{class:"text-sm font-mono min-w-[48px] text-center"},()=>String(l(t)).padStart(2,"0")+":00")])]);return e.$html("div",{class:"relative w-full"},[D({label:n,placeholder:s||(h()?"Seleccionar rango...":"Seleccionar fecha..."),value:y,readonly:!0,icon:e.$html("img",{src:i,class:"opacity-40"}),onclick:t=>{t.stopPropagation(),r(!r())},...c}),e.$if(r,()=>e.$html("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",onclick:t=>t.stopPropagation()},[e.$html("div",{class:"flex justify-between items-center mb-4 gap-1"},[e.$html("div",{class:"flex gap-0.5"},[e.$html("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>C(-1)},e.$html("img",{src:B,class:"opacity-40"})),e.$html("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>S(-1)},e.$html("img",{src:$,class:"opacity-40"}))]),e.$html("span",{class:"font-bold uppercase flex-1 text-center"},[()=>d().toLocaleString("es-ES",{month:"short",year:"numeric"})]),e.$html("div",{class:"flex gap-0.5"},[e.$html("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>S(1)},e.$html("img",{src:v,class:"opacity-40"})),e.$html("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>C(1)},e.$html("img",{src:w,class:"opacity-40"}))])]),e.$html("div",{class:"grid grid-cols-7 gap-1",onmouseleave:()=>m(null)},[...["L","M","X","J","V","S","D"].map(t=>e.$html("div",{class:"text-[10px] opacity-40 font-bold text-center"},t)),()=>{const t=d(),o=t.getFullYear(),n=t.getMonth(),s=new Date(o,n,1).getDay(),A=0===s?6:s-1,c=new Date(o,n+1,0).getDate(),r=[];for(let t=0;t{const t=l(a),e=m(),o="string"==typeof t?t.split("T")[0]===A:t?.start===A,n=t?.end===A;let s=!1;if(h()&&t?.start){const l=t.start;!t.end&&e?s=A>l&&A<=e||A=e:t.end&&(s=A>l&&A{h()&&m(A)},onclick:()=>x(s)},[t.toString()]))}return r}]),A?e.$html("div",{class:"mt-3 pt-2 border-t border-base-300"},[h()?e.$html("div",{class:"flex gap-4"},[U({value:u,onChange:t=>{u(t);const e=l(a);e?.start&&a({...e,startHour:t})}}),U({value:p,onChange:t=>{p(t);const e=l(a);e?.end&&a({...e,endHour:t})}})]):U({value:u,onChange:t=>{u(t);const e=l(a);e&&"string"==typeof e&&e.includes("-")&&a(e.split("T")[0]+"T"+String(t).padStart(2,"0")+":00:00")}})]):null])),e.$if(r,()=>e.$html("div",{class:"fixed inset-0 z-[90]",onclick:()=>r(!1)}))])};const H=t=>e.$html("div",{class:a("drawer",t.class)},[e.$html("input",{id:t.id,type:"checkbox",class:"drawer-toggle",checked:t.open}),e.$html("div",{class:"drawer-content"},t.content),e.$html("div",{class:"drawer-side"},[e.$html("label",{for:t.id,class:"drawer-overlay",onclick:()=>t.open?.(!1)}),e.$html("div",{class:"min-h-full bg-base-200 w-80"},t.side)])]);const O=(t,a)=>{const{label:o,icon:n,...s}=t;return e.$html("div",{...s,class:()=>`dropdown ${l(t.class)||t.class||""}`},[e.$html("div",{tabindex:0,role:"button",class:"btn m-1 flex items-center gap-2"},[n?"function"==typeof n?n():n:null,o?"function"==typeof o?o():o:null]),e.$html("ul",{tabindex:0,class:"dropdown-content z-[50] menu p-2 shadow bg-base-100 rounded-box min-w-max border border-base-300"},["function"==typeof a?a():a])])};const F=t=>{const{icon:a,label:o,actions:n=[],position:s="bottom-6 right-6",...A}=t;return e.$html("div",{...A,class:()=>`fab fixed ${l(s)} flex flex-col-reverse items-end gap-3 z-[100] ${t.class||""}`},[e.$html("div",{tabindex:0,role:"button",class:"btn btn-lg btn-circle btn-primary shadow-2xl"},[a?"function"==typeof a?a():a:null,!a&&o?o:null]),...l(n).map(t=>e.$html("div",{class:"flex items-center gap-3 transition-all duration-300"},[t.label?e.$html("span",{class:"badge badge-ghost shadow-sm whitespace-nowrap"},t.label):null,e.$html("button",{type:"button",class:`btn btn-circle shadow-lg ${t.class||""}`,onclick:e=>{e.stopPropagation(),t.onclick?.(e)}},[t.icon?"function"==typeof t.icon?t.icon():t.icon:t.text||""])]))])};const Q=(t,o)=>e.$html("fieldset",{...t,class:a("fieldset bg-base-200 border border-base-300 p-4 rounded-lg",t.class)},[()=>{const a=l(t.legend);return a?e.$html("legend",{class:"fieldset-legend font-bold"},[a]):null},o]);const N=t=>{const{tooltip:l,max:a=2,accept:o="*",onSelect:n}=t,s=e.$([]),A=e.$(!1),c=e.$(null),i=1024*a*1024,d=t=>{const e=Array.from(t);c(null);e.find(t=>t.size>i)?c(`Máx ${a}MB`):(s([...s(),...e]),n?.(s()))};return e.$html("fieldset",{class:"fieldset w-full p-0"},[e.$html("div",{class:()=>"w-full "+(l?"tooltip tooltip-top before:z-50 after:z-50":""),"data-tip":l},[e.$html("label",{class:()=>`\n relative flex items-center justify-between w-full h-12 px-4\n border-2 border-dashed rounded-lg cursor-pointer\n transition-all duration-200\n ${A()?"border-primary bg-primary/10":"border-base-content/20 bg-base-100 hover:bg-base-200"}\n `,ondragover:t=>{t.preventDefault(),A(!0)},ondragleave:()=>A(!1),ondrop:t=>{t.preventDefault(),A(!1),d(t.dataTransfer.files)}},[e.$html("div",{class:"flex items-center gap-3 w-full"},[e.$html("img",{src:x,class:"w-5 h-5 opacity-50 shrink-0"}),e.$html("span",{class:"text-sm opacity-70 truncate grow text-left"},"Arrastra o selecciona archivos..."),e.$html("span",{class:"text-[10px] opacity-40 shrink-0"},`Máx ${a}MB`)]),e.$html("input",{type:"file",multiple:!0,accept:o,class:"hidden",onchange:t=>d(t.target.files)})])]),()=>c()?e.$html("span",{class:"text-[10px] text-error mt-1 px-1 font-medium"},c()):null,e.$if(()=>s().length>0,()=>e.$html("ul",{class:"mt-2 space-y-1"},[e.$for(s,(t,l)=>e.$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"},[e.$html("div",{class:"flex items-center gap-2 truncate"},[e.$html("span",{class:"opacity-50"},"📄"),e.$html("span",{class:"truncate font-medium max-w-[200px]"},t.name),e.$html("span",{class:"text-[9px] opacity-40"},`(${(t.size/1024).toFixed(0)} KB)`)]),e.$html("button",{type:"button",class:"btn btn-ghost btn-xs btn-circle",onclick:t=>{t.preventDefault(),t.stopPropagation(),(t=>{const e=s().filter((e,l)=>l!==t);s(e),n?.(e)})(l)}},[e.$html("img",{src:r,class:"w-3 h-3 opacity-70"})])]),t=>t.name+t.lastModified)]))])};const L=(t,l)=>e.$html("div",{class:a("indicator",t.class)},[l,e.$html("span",{class:a("indicator-item badge",t.badgeClass)},t.badge)]);const T=t=>{const{items:o,header:n,render:s,keyFn:A=(t,e)=>e,class:c,...r}=t,i=e.$for(o,(t,l)=>e.$html("li",{class:"list-row"},[s(t,l)]),A);return e.$html("ul",{...r,class:a("list bg-base-100 rounded-box shadow-md",c)},n?[e.$if(n,()=>e.$html("li",{class:"p-4 pb-2 text-xs opacity-60"},[l(n)])),i]:i)};const G=t=>e.$if(t.$show,()=>e.$html("div",{class:"fixed inset-0 z-[100] flex items-center justify-center backdrop-blur-sm bg-base-100/30"},[e.$html("span",{class:"loading loading-spinner loading-lg text-primary"})]));const M=t=>{const o=t=>e.$for(()=>t||[],t=>e.$html("li",{},[t.children?e.$html("details",{open:t.open},[e.$html("summary",{},[t.icon&&e.$html("span",{class:"mr-2"},t.icon),t.label]),e.$html("ul",{},o(t.children))]):e.$html("a",{class:()=>l(t.active)?"active":"",onclick:t.onclick},[t.icon&&e.$html("span",{class:"mr-2"},t.icon),t.label])]),(t,e)=>t.label||e);return e.$html("ul",{...t,class:a("menu bg-base-200 rounded-box",t.class)},o(t.items))};const J=(t,l)=>{const{title:a,buttons:o,open:n,...s}=t,A={current:null};e.$watch(()=>{const t=A.current;t&&(n()?t.open||t.showModal():t.open&&t.close())});const c=t=>{t&&t.preventDefault&&t.preventDefault(),n(!1)};return e.$html("dialog",{...s,ref:A,class:"modal",oncancel:()=>n(!1)},[e.$html("div",{class:"modal-box"},[a?e.$html("h3",{class:"text-lg font-bold mb-4"},a):null,e.$html("div",{class:"py-2"},["function"==typeof l?l():l]),e.$html("div",{class:"modal-action flex gap-2"},[...(Array.isArray(o)?o:[o]).filter(Boolean),E({type:"button",onclick:c},R("close")())])]),e.$html("form",{method:"dialog",class:"modal-backdrop",onsubmit:c},[e.$html("button",{},"close")])])};const K=(t,l)=>e.$html("div",{...t,class:a("navbar bg-base-100 shadow-sm px-4",t.class)},l);const P=t=>{const{label:o,tooltip:n,value:s,inputValue:A,name:c,...r}=t,i=e.$html("input",{...r,type:"radio",name:c,class:a("radio",t.class),checked:()=>l(s)===A,onclick:()=>{"function"==typeof s&&s(A)}});return o||n?e.$html("label",{class:"label cursor-pointer justify-start gap-3"},[i,o?e.$html("span",{class:"label-text"},o):null]):i};const X=t=>{const{label:o,tooltip:n,value:s,...A}=t,c=e.$html("input",{...A,type:"range",class:a("range",t.class),value:s,disabled:()=>l(t.disabled)});if(!o&&!n)return c;const r=e.$html("div",{class:"flex flex-col gap-2"},[o?e.$html("span",{class:"label-text"},o):null,c]);return n?e.$html("div",{class:"tooltip","data-tip":n},r):r};const Z=t=>{const{value:a,count:o=5,mask:n="mask-star",readonly:s=!1,onchange:A,...c}=t,r=`rating-${Math.random().toString(36).slice(2,7)}`;return e.$html("div",{...c,class:()=>`rating ${l(s)?"pointer-events-none":""} ${t.class||""}`},Array.from({length:l(o)},(t,o)=>{const c=o+1;return e.$html("input",{type:"radio",name:r,class:`mask ${n}`,checked:()=>Math.round(l(a))===c,onchange:()=>{l(s)||("function"==typeof A?A(c):"function"==typeof a&&a(c))}})}))};const W=t=>{const{label:o,options:n,value:s,...A}=t,c=e.$html("select",{...A,class:a("select select-bordered w-full",t.class),value:s},e.$for(()=>l(n)||[],t=>e.$html("option",{value:t.value,$selected:()=>String(l(s))===String(t.value)},t.label),t=>t.value));return o?e.$html("label",{class:"fieldset-label flex flex-col gap-1"},[e.$html("span",{},o),c]):c};const q=(t,l)=>e.$html("div",{...t,class:a("stack",t.class)},l);const tt=t=>e.$html("div",{...t,class:a("stat",t.class)},[t.icon&&e.$html("div",{class:"stat-figure text-secondary"},t.icon),t.label&&e.$html("div",{class:"stat-title"},t.label),e.$html("div",{class:"stat-value"},()=>l(t.value)??t.value),t.desc&&e.$html("div",{class:"stat-desc"},t.desc)]);const et=t=>e.$html("label",{class:a("swap",t.class)},[e.$html("input",{type:"checkbox",checked:t.value}),e.$html("div",{class:"swap-on"},t.on),e.$html("div",{class:"swap-off"},t.off)]);const lt=t=>{const{items:o=[],columns:n=[],keyFn:s,zebra:A=!1,pinRows:c=!1,empty:r=R("nodata")(),...i}=t;return e.$html("div",{class:"overflow-x-auto w-full bg-base-100 rounded-box border border-base-300"},[e.$html("table",{...i,class:()=>a("table",`${l(A)?"table-zebra":""} ${l(c)?"table-pin-rows":""} ${t.class||""}`)},[e.$html("thead",{},[e.$html("tr",{},n.map(t=>e.$html("th",{class:t.class||""},t.label)))]),e.$html("tbody",{},[e.$for(o,(t,a)=>e.$html("tr",{class:"hover"},n.map(o=>e.$html("td",{class:o.class||""},[()=>{if(o.render)return o.render(t,a);const e=t[o.key];return l(e)}]))),s||((t,e)=>t.id||e)),e.$if(()=>0===l(o).length,()=>e.$html("tr",{},[e.$html("td",{colspan:n.length,class:"text-center p-10 opacity-50"},[l(r)])]))]),e.$if(()=>n.some(t=>t.footer),()=>e.$html("tfoot",{},[e.$html("tr",{},n.map(t=>e.$html("th",{},t.footer||"")))]))])])};const at=t=>{const{items:o,...n}=t,s="function"==typeof o?o:()=>o||[];return e.$html("div",{...n,class:"flex flex-col gap-4 w-full"},[e.$html("div",{role:"tablist",class:a("tabs tabs-box",t.class)},e.$for(s,t=>e.$html("a",{role:"tab",class:()=>a("tab",l(t.active)&&"tab-active",l(t.disabled),t.tip),"data-tip":t.tip,onclick:e=>!l(t.disabled)&&t.onclick?.(e)},t.label),t=>t.label)),()=>{const t=s().find(t=>l(t.active));if(!t)return null;const a=l(t.content);return e.$html("div",{class:"p-4"},["function"==typeof a?a():a])}])};const ot=t=>{const{items:a=[],vertical:o=!0,compact:n=!1,...s}=t,A={info:h,success:g,warning:f,error:b};return e.$html("ul",{...s,class:()=>`timeline ${l(o)?"timeline-vertical":"timeline-horizontal"} ${l(n)?"timeline-compact":""} ${t.class||""}`},[e.$for(a,(t,o)=>{const n=0===o,s=o===l(a).length-1,c=t.type||"success",r=t=>"function"==typeof t?t():t;return e.$html("li",{class:"flex-1"},[n?null:e.$html("hr",{class:t.completed?"bg-primary":""}),e.$html("div",{class:"timeline-start"},[r(t.title)]),e.$html("div",{class:"timeline-middle"},[e.$html("img",{src:A[c]||t.icon||A.success,class:"w-4 h-4 object-contain mx-1",alt:c})]),e.$html("div",{class:"timeline-end timeline-box shadow-sm"},[r(t.detail)]),s?null:e.$html("hr",{class:t.completed?"bg-primary":""})])},(t,e)=>t.id||e)])};const nt=(t,l="alert-success",a=3500)=>{let o=document.getElementById("sigpro-toast-container");o||(o=e.$html("div",{id:"sigpro-toast-container",class:"fixed top-0 right-0 z-[9999] p-4 flex flex-col gap-2 pointer-events-none"}),document.body.appendChild(o));const n=e.$html("div",{style:"display: contents"});let s;o.appendChild(n);const A=()=>{clearTimeout(s);const t=n.firstElementChild;t&&!t.classList.contains("opacity-0")?(t.classList.add("translate-x-full","opacity-0"),setTimeout(()=>{c.destroy(),n.remove(),o.hasChildNodes()||o.remove()},300)):(c.destroy(),n.remove())},c=e.$mount(()=>{const a=e.$html("div",{class:`alert alert-soft ${l} shadow-lg transition-all duration-300 translate-x-10 opacity-0 pointer-events-auto`},[e.$html("span",{},["function"==typeof t?t():t]),E({class:"btn-xs btn-circle btn-ghost",onclick:A},"✕")]);return requestAnimationFrame(()=>a.classList.remove("translate-x-10","opacity-0")),a},n);return a>0&&(s=setTimeout(A,a)),A};const st=(t,l)=>e.$html("div",{...t,class:a("tooltip",t.class),"data-tip":t.tip},l);const At={...s,...C,...Object.freeze({__proto__:null,Autocomplete:_}),...Object.freeze({__proto__:null,Badge:z}),...Object.freeze({__proto__:null,Button:E}),...Object.freeze({__proto__:null,Checkbox:I}),...Object.freeze({__proto__:null,Colorpicker:Y}),...Object.freeze({__proto__:null,Datepicker:V}),...Object.freeze({__proto__:null,Drawer:H}),...Object.freeze({__proto__:null,Dropdown:O}),...Object.freeze({__proto__:null,Fab:F}),...Object.freeze({__proto__:null,Fieldset:Q}),...Object.freeze({__proto__:null,Fileinput:N}),...Object.freeze({__proto__:null,Indicator:L}),...j,...Object.freeze({__proto__:null,List:T}),...Object.freeze({__proto__:null,Loading:G}),...Object.freeze({__proto__:null,Menu:M}),...Object.freeze({__proto__:null,Modal:J}),...Object.freeze({__proto__:null,Navbar:K}),...Object.freeze({__proto__:null,Radio:P}),...Object.freeze({__proto__:null,Range:X}),...Object.freeze({__proto__:null,Rating:Z}),...Object.freeze({__proto__:null,Select:W}),...Object.freeze({__proto__:null,Stack:q}),...Object.freeze({__proto__:null,Stat:tt}),...Object.freeze({__proto__:null,Swap:et}),...Object.freeze({__proto__:null,Table:lt}),...Object.freeze({__proto__:null,Tabs:at}),...Object.freeze({__proto__:null,Timeline:ot}),...Object.freeze({__proto__:null,Toast:nt}),...Object.freeze({__proto__:null,Tooltip:st})};var ct={...At,install:(t=window)=>{Object.entries(At).forEach(([e,l])=>{t[e]=l}),console.log("🚀 SigproUI")}},rt=Object.freeze({__proto__:null,Accordion:n,Alert:S,Autocomplete:_,Badge:z,Button:E,Checkbox:I,Colorpicker:Y,Datepicker:V,Drawer:H,Dropdown:O,Fab:F,Fieldset:Q,Fileinput:N,Indicator:L,Input:D,List:T,Loading:G,Menu:M,Modal:J,Navbar:K,Radio:P,Range:X,Rating:Z,Select:W,Stack:q,Stat:tt,Swap:et,Table:lt,Tabs:at,Timeline:ot,Toast:nt,Tooltip:st,default:ct});const it={...rt,Icons:y,Utils:o,tt:R,install:(t=("undefined"!=typeof window?window:{}))=>{Object.entries(rt).forEach(([e,l])=>{t[e]=l}),t.Icons=y,t.Utils=o,t.tt=R,console.log("🌟 SigproUI")}};return"undefined"!=typeof window&&it.install(window),t.Accordion=n,t.Alert=S,t.Autocomplete=_,t.Badge=z,t.Button=E,t.Checkbox=I,t.Colorpicker=Y,t.Datepicker=V,t.Drawer=H,t.Dropdown=O,t.Fab=F,t.Fieldset=Q,t.Fileinput=N,t.Indicator=L,t.Input=D,t.List=T,t.Loading=G,t.Menu=M,t.Modal=J,t.Navbar=K,t.Radio=P,t.Range=X,t.Rating=Z,t.Select=W,t.Stack=q,t.Stat=tt,t.Swap=et,t.Table=lt,t.Tabs=at,t.Timeline=ot,t.Toast=nt,t.Tooltip=st,t.default=it,t.icon123=u,t.iconAbc=m,t.iconCalendar=i,t.iconClose=r,t.iconError=b,t.iconHide=c,t.iconInfo=h,t.iconLLeft=B,t.iconLeft=$,t.iconLock=d,t.iconMail=p,t.iconRRight=w,t.iconRight=v,t.iconShow=A,t.iconSuccess=g,t.iconUpload=x,t.iconWarning=f,t.joinClass=a,t.tt=R,t.val=l,Object.defineProperty(t,"__esModule",{value:!0}),t}({},SigPro); +var SigProUI=function(t,e){"use strict";const l=t=>"function"==typeof t?t():t,a=(t,e)=>"function"==typeof e?()=>`${t} ${e()||""}`.trim():`${t} ${e||""}`.trim();var o=Object.freeze({__proto__:null,joinClass:a,val:l});const n=(t,l)=>{const{title:o,name:n,open:s,...A}=t;return e.$html("div",{...A,class:a("collapse collapse-arrow bg-base-200 mb-2",t.class)},[e.$html("input",{type:n?"radio":"checkbox",name:n,checked:s}),e.$html("div",{class:"collapse-title text-xl font-medium"},o),e.$html("div",{class:"collapse-content"},l)])};var s=Object.freeze({__proto__:null,Accordion:n});const A="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADjSURBVDiN3dJNSgNBEAXgz4DZeAAVJ9tko2St3kaIFxAVt4KZeAD1GKKi7vQSydI/yHgALxAXU02GxniAFBR0v1ev+3V1sZSxjxtM8BM5wTX2/hNu4gFvOMI21iJ3cIwP3GMjF/dQ4RyraOMS34GPAmvjIrBeEnfwjoPGgSM8ooh8QtngB6Ep4BWnmaMqkY1LqqzmDC8tzNDK3/RHzLL9SloUYWfQIMuw3Yl8xrDBH6qbvZWALqbqBqVmlWF7GuKEDwPr5hbXcYdPnKBv/o39wL5wG7ULY1c9NGPzQRrjKrhli1/02zEjWyWMBwAAAABJRU5ErkJggg==",c="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAEDSURBVDiN1dK/K8VhFAbwD+VLGSxKcu9guSQ/Zils/gNkuaX4BxRZDTdklYU/QAaDlEVGGwu2Kz/uVbKJzWDwfuv1+jHz1Km3c85znuf0Hv4jxnD2W8MItnCJ5xAX2MQcHsOQL+jEAapYQD9aQwxiDy+B3JKSe1DHCpqQYQ0PeMJOpDyAmyAAirjGbDRwFYcoYCZSzjGP+8B1gqXEUT2QxyPlqaRnGceNeENzUswwil1MBocbSU9DCAXUUI6K25HtIo5QSVaooitP9OEO65iIbE+HXSvBVRbeNZQSR9pxGil3o83HNw5hEbfYR0dKFki5ci+u8OrzIQ1/R8xx7ocL+9t4B0HPOVXjoptxAAAAAElFTkSuQmCC",r="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABcSURBVDiN3dIxDoAwCIXhL563g3bSm+hlq4O6GFNbO+k/EV54QIDfsSBk9IA5ZxCQEG+0eGi5BqDHivEhV2xSXXwy2EdOR3xLV+ta0/26wvSm+KTYpPmMzY/0QTZeZR2f+FxhRQAAAABJRU5ErkJggg==",i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAACLSURBVDiN7dO9CQJBFEXhb38K0FwQrMNEVpuwB0NjrcYabECsQk0sQ1mTF4zIjrgmBh54MMx998AEwzOrmC5e8gJjbDHCJO7PHYI0v2JT4Ig9DljGwq5DkOZTLOCOMoIhBpknpHmFWx3ldaaUo6oTc2/ab7rl+508f8GvCC5oenTn4tM1cWg/nBNmD4fBH/Kfvt2TAAAAAElFTkSuQmCC",d="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAWQAAAFkBqp2phgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAACQSURBVDiN7dKxDcJQDATQJ0YgXQQ1bAgDEIZBETPQwjakIjRQ8CMSyR8SiZKTrvHZd/r+JsYSNZrEI1ZR4ywzfElcJ55xwiITOECNTVDf4jDGoEEZ1Etcxxg8pmjRDiahb7BH20uKKPVUkVmL+YjQArdI+PT2bO9Pd/A34O71Rd9QeN/LAFUSckfUscWuG3oCgP8nrDH6T5AAAAAASUVORK5CYII=",m="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADFSURBVDiN7dCxSoIBFAXgr1BbgmgSB5ubxKAHaAkcgnBpySVaDET3WhzcpQfoHZojawgX0ZZcfAWDSDdBoeUKP/8ojZ7tnnPv4dzDFv+KZzwl5jf84B354C4wwjdeUV4vl7DCEsXgxmhigDpOMcMVjoKr7cTyI/ZxiE90wmCB4zi+RRatZOxd7OEavxHtBmvjIV5wH2a59N8ZXIZQisMCzkL/wgGq6EYffXzgHHNo4y5h+oBGlLjEBJVUiVP0cJJOtMUG+APtfyYzbH7eVgAAAABJRU5ErkJggg==",u="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAB2AAAAdgFOeyYIAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAMxJREFUOI3t0bFKwlEUBvBfmmBEr1APIDZJ9AJJQyAIvkGP0C4uQruza+DUmuIc9AC9gBG4Nmpkw/8IB3Vw1w8u95zvnvPde77LEeUUV9HAF67QRA2nmMf5A+o4x3cWOsMYy8j7WMX6jaYbLBL/mAWe8RcHm1ihs8G94gVKQQzwlAouMcQo8p/Y28HdYpYFZmsi0MVdxD1MdrxsC500wijdvgtbI1AYtDbxMwkuFAZmE1uYwkkSqOIaHyHcxEU0vUXNPSqKr37fZ6xDwD9DPS0OyHjQHQAAAABJRU5ErkJggg==",p="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAC4SURBVDiNxdIxagJRFIXhLzLFBNJYaJslSEylWOhq3IorMGQ16SyjYCFiZWU5pTaDFvOUyTAZ8RHID69555577oXLf/OEGaY4R3g/4IhORHg3eOXYYvSAeRQ8OWQYYoNPvDQYnxUr7zBB1grCAv3QbIlxjXmAb7Txhq+rkFUKq9NUU8vcJiizwDtOWGEdmvTKqT+61H0GXsP7jSxpEGF/R1e3wkO0FBeVRnhTSBTneBB3yvOI4D/mAnvrIwKM5s4AAAAAAElFTkSuQmCC",h="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAnXAAAJ1wGxbhe3AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAASVJREFUOI190r0uhFEQBuBnVxaF2PUTCkFchV0SV6BQi0rEbShFlCqNktJP0Iqf3i3YVSlXVEQozojP8e2+ySSTed+ZMzNnKnpjCFPhv+C9j/YPlnCBV3TCujhHq19iFftoYxOjBa4esTb2QvsP+7jFWJ9HxnEXRf5gGU9Z8gKucBl+sUgHTahE8AJnOCoIT/AcmhmsF7gtrGINBqWFFWcmLXMUhzjIuEbk1GA+2i/DNh4wUsK1MVfFV2GUHJO4xlsPHr8j1Eu44bAcDek2agP4lDZaxWMm3MEKbrL4hjT/8U+gJc00nglnw4qYkL5xMW9rTzqSvEiefI/dMrIaRTrSPzcKXCNinUguPeUfNKWj6kqH9Bz+aVnbvb6PtKTp8F/wUSb6Bu5YN5n7ff0kAAAAAElFTkSuQmCC",b="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAnXAAAJ1wGxbhe3AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAQtJREFUOI2F0jFOAlEQBuAPImoFqyTa6TEEbfUihruYDYfwCAg3UDsTY20na0VjgqUWWuxgHsuy/skk82bmn/fPm9eyHXs4Cn+Br4baNZxjhk8UYUtMMWwitjHGHNfoJrlexObIo3YDY9zjoOGSQzxEkzVc4O0fctqkwCANzkJiE9LmI9ytDrvKB+tWGQnylIAsOB04VcrfdluO55CeYo6THfygVUne4jX8S1zho1LTDu7fCL2KxCe8oF8zUqb8G51VYGrzEffD6jDCJA0MY6bqnHXoK9d4Vk3kyk/S1KSPR9zUJdvRpAiJWZLLIlYEufYrrzBQ7nyJ97ClcuYN2dX1pejgOPwFvuuKfgHXiDR+HL1j1AAAAABJRU5ErkJggg==",g="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAnXAAAJ1wGxbhe3AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAARZJREFUOI2V0j1KQ1EQBeDPp4lWRiMoKVyAK9AoiLgJGytxD9oJNhKyDyvBnw2IugC3YGKVRk1KRbR48yC5vjzwwIHL3DPnzp2ZGdMxj9U4D/BZoZ3ANu4wQj84xC3aVYkZuujhCItjd42I9dAJ7R908YDlikeaeAyTCezgpST5IJia9LFVlA0nOMd7It4IjuMttKeFQR17uKooPcUV9lHL0ArX0T8MPqLa1hx+MDNFWDX7LHLV4/VGiWghmGJJvhu1WXzLO5rhORGeYRf3SfwQNVwWgbZ8SZqJcD04jhX5GDfTsjryJUlN0uQnXJRdZmHSx7H8nwWWItaP5NJVLrCFG3mTXoNDXJeVPW185E1ai/MAX2WiX9S3NSPYbj+uAAAAAElFTkSuQmCC",f="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAnXAAAJ1wGxbhe3AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAARJJREFUOI2l0r8uRFEQBvAfu9glwUYiUaxHUEl0VDpKeq+wpZBINAqFRHgTKg0tCSqVhmKDEM1u/Esodm725rq7iC+ZzMnM982ZmXP4JwpdchWsYBrXeMkj9XQQV3GEi+BMYR63v+mqiDPUUrEaTiP3I1ZxEOcySnE+jFxXVPEQPimWiCYzOdCbKbCFPe1Z+8PgBvvBycVMCIdSsY2wBEPBmcnrYBtraKRib2EJGljHjswLLuI8Z6SS9hLTl15iIR08wZLv2AzLYjk0YATP8n9lVWbrgUJohosYxCdG8Zghdvp5ldCUi6hrPd0VjvGEVzTxEYLkogGMYQ67uEtvcgKzGA8y9IV/D9/Evdb89Q7d/Q1fB8U0mpUmzV0AAAAASUVORK5CYII=",$="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABfSURBVDiNY2AY8oCZSHWxDAwMEgwMDHfJsaSAgYHhH9QQsjT/Z2BgKKe75gQGiLMLCSlkwiHOSI6t6ADmhYoBN6SIARIeidgkiUlIxxkYGB4xMDB8YmBguE6JSwYpAACvLRHTKwPjZgAAAABJRU5ErkJggg==",v="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABNSURBVDiN3dAxCoAwFATRh3fU2oAHiDbi5Y1F2jT+gKLbzyy7/DYjUo8g4cTWI8koOF6XrOqc5ifDDVGJthfsj8OLujtHYJgwR+GP5QKMxA9/SolDQgAAAABJRU5ErkJggg==",B="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABlSURBVDiN3ZLBDUBAEEUfmtCchA5woUMlOO1FCQrAwbqwf8eFhHd7mfzJn2Tg82TGvABywAmPUgOLD4XcDK9AJ/y5cOlrNsIvpCdPDL/FUbkX/t6Slv3+SjgQf6QBmIAZGAP+FzZJViOd89x8pAAAAABJRU5ErkJggg==",w="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABmSURBVDiN3dGxCoAgEMbxfz1dL1BTREJzmUv08trgDYcg6VCD3/YD7zvkoLmMgFEegLmmwAAecOJVvNeUWCAAt7IHjt9LThkyiRf9qC8oCom70u0BuDL+bngj/tNm/JqJePucW8wDvGYdzT0nMUkAAAAASUVORK5CYII=",x="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADNSURBVDiNndOxTgJRFIThz41ZDMFKqH0DLSRSq4lQ0RifUcMzUJlYQKjtLcHVSimBggPRNSzs/sk0kzPnTHEvxZyHKnGJD3yhXSWcYRnKwvvH0Y7wEG/4wQI1XOEek6LLF3FtiDoGoXp4WcxsSXILHjFCH/Nf/jy8ER6KGuTZNNhJvkFpEpygUyHbRi1BFy8VFryilyANlSVFerxn6N36IRVyG0PNEtdbkbmBU8zwdOCSJp4xRWNj3sWS5YGaRvM/f6GBa5ztafCJMb5hBQQ/MMwXLnnZAAAAAElFTkSuQmCC";var y=Object.freeze({__proto__:null,icon123:u,iconAbc:m,iconCalendar:i,iconClose:r,iconError:g,iconHide:c,iconInfo:h,iconLLeft:B,iconLeft:$,iconLock:d,iconMail:p,iconRRight:w,iconRight:v,iconShow:A,iconSuccess:b,iconUpload:x,iconWarning:f});const S=(t,a)=>{const{type:o="info",soft:n=!0,...s}=t,A={info:h,success:b,warning:f,error:g},c=a||t.message;return e.$html("div",{...s,role:"alert",class:()=>`alert ${(()=>{const t=l(o);return{info:"alert-info",success:"alert-success",warning:"alert-warning",error:"alert-error"}[t]||t})()} ${l(n)?"alert-soft":""} ${t.class||""}`},[e.$html("img",{src:A[l(o)]||A.info,class:"w-4 h-4 object-contain",alt:l(o)}),e.$html("div",{class:"flex-1"},[e.$html("span",{},["function"==typeof c?c():c])]),t.actions?e.$html("div",{class:"flex-none"},["function"==typeof t.actions?t.actions():t.actions]):null])};var C=Object.freeze({__proto__:null,Alert:S});const U={es:{close:"Cerrar",confirm:"Confirmar",cancel:"Cancelar",search:"Buscar...",loading:"Cargando...",nodata:"Sin datos"},en:{close:"Close",confirm:"Confirm",cancel:"Cancel",search:"Search...",loading:"Loading...",nodata:"No data"}},k=e.$("es"),R=t=>()=>U[k()][t]||t,D=t=>{const{label:o,tip:n,value:s,error:r,isSearch:h,icon:b,type:g="text",...f}=t,$="password"===g,v=e.$(!1),B={text:m,password:d,date:i,number:u,email:p},w=e.$html("input",{...f,type:()=>$?v()?"text":"password":g,placeholder:t.placeholder||o||(h?R("search")():" "),class:a("grow order-2 focus:outline-none",t.class),value:s,oninput:e=>t.oninput?.(e),disabled:()=>l(t.disabled)}),x=b||(B[g]?e.$html("img",{src:B[g],class:"opacity-50",alt:g}):null);return e.$html("label",{class:()=>a("input input-bordered floating-label flex items-center gap-2 w-full relative",l(r)?"input-error":"")},[x?e.$html("div",{class:"order-1 shrink-0"},x):null,o?e.$html("span",{class:"text-base-content/60 order-0"},o):null,w,$?e.$html("button",{type:"button",class:"order-3 btn btn-ghost btn-xs btn-circle opacity-50 hover:opacity-100",onclick:t=>{t.preventDefault(),v(!v())}},()=>e.$html("img",{class:"w-5 h-5",src:v()?A:c})):null,n?e.$html("div",{class:"tooltip tooltip-left order-4","data-tip":n},e.$html("span",{class:"badge badge-ghost badge-xs cursor-help"},"?")):null,()=>l(r)?e.$html("span",{class:"text-error text-[10px] absolute -bottom-5 left-2"},l(r)):null])};var j=Object.freeze({__proto__:null,Input:D});const _=t=>{const{options:a=[],value:o,onSelect:n,label:s,placeholder:A,...c}=t,r=e.$(l(o)||""),i=e.$(!1),d=e.$(-1),m=e.$(()=>{const t=r().toLowerCase(),e=l(a)||[];return t?e.filter(e=>("string"==typeof e?e:e.label).toLowerCase().includes(t)):e}),u=t=>{const e="string"==typeof t?t:t.value,l="string"==typeof t?t:t.label;r(l),"function"==typeof o&&o(e),n?.(t),i(!1),d(-1)};return e.$html("div",{class:"relative w-full"},[D({label:s,placeholder:A||R("search")(),value:r,onfocus:()=>i(!0),onblur:()=>setTimeout(()=>i(!1),150),onkeydown:t=>{const e=m();"ArrowDown"===t.key?(t.preventDefault(),i(!0),d(Math.min(d()+1,e.length-1))):"ArrowUp"===t.key?(t.preventDefault(),d(Math.max(d()-1,0))):"Enter"===t.key&&d()>=0?(t.preventDefault(),u(e[d()])):"Escape"===t.key&&i(!1)},oninput:t=>{const e=t.target.value;r(e),"function"==typeof o&&o(e),i(!0),d(-1)},...c}),e.$html("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",style:()=>i()&&m().length?"display:block":"display:none"},[e.$for(m,(t,l)=>e.$html("li",{},[e.$html("a",{class:()=>"block w-full "+(d()===l?"active bg-primary text-primary-content":""),onclick:()=>u(t),onmouseenter:()=>d(l)},"string"==typeof t?t:t.label)]),(t,e)=>("string"==typeof t?t:t.value)+e),()=>m().length?null:e.$html("li",{class:"p-2 text-center opacity-50"},"No results")])])};const z=(t,l)=>e.$html("span",{...t,class:a("badge",t.class)},l);const E=(t,o)=>{const{badge:n,badgeClass:s,tooltip:A,icon:c,loading:r,...i}=t;let d=e.$html("button",{...i,class:a("btn",t.class),disabled:()=>l(r)||l(t.disabled)},[()=>l(r)?e.$html("span",{class:"loading loading-spinner"}):null,c?e.$html("span",{class:"mr-1"},c):null,o]);return n&&(d=e.$html("div",{class:"indicator"},[e.$html("span",{class:a("indicator-item badge",s||"badge-secondary")},n),d])),A?e.$html("div",{class:"tooltip","data-tip":A},d):d};const I=t=>{const{value:a,tooltip:o,toggle:n,label:s,...A}=t,c=e.$html("input",{...A,type:"checkbox",class:()=>l(n)?"toggle":"checkbox",checked:a}),r=e.$html("label",{class:"label cursor-pointer justify-start gap-3"},[c,s?e.$html("span",{class:"label-text"},s):null]);return o?e.$html("div",{class:"tooltip","data-tip":o},r):r};const Y=t=>{const{value:a,label:o,...n}=t,s=e.$(!1),A=["#000","#1A1A1A","#333","#4D4D4D","#666","#808080","#B3B3B3","#FFF","#450a0a","#7f1d1d","#991b1b","#b91c1c","#dc2626","#ef4444","#f87171","#fca5a5","#431407","#7c2d12","#9a3412","#c2410c","#ea580c","#f97316","#fb923c","#ffedd5","#713f12","#a16207","#ca8a04","#eab308","#facc15","#fde047","#fef08a","#fff9c4","#064e3b","#065f46","#059669","#10b981","#34d399","#4ade80","#84cc16","#d9f99d","#082f49","#075985","#0284c7","#0ea5e9","#38bdf8","#7dd3fc","#22d3ee","#cffafe","#1e1b4b","#312e81","#4338ca","#4f46e5","#6366f1","#818cf8","#a5b4fc","#e0e7ff","#2e1065","#4c1d95","#6d28d9","#7c3aed","#8b5cf6","#a855f7","#d946ef","#fae8ff"],c=()=>l(a)||"#000000";return e.$html("div",{class:"relative w-fit"},[e.$html("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",onclick:t=>{t.stopPropagation(),s(!s())},...n},[e.$html("div",{class:"size-5 rounded-sm shadow-inner border border-black/10 shrink-0",style:()=>`background-color: ${c()}`}),o?e.$html("span",{class:"opacity-80"},o):null]),e.$if(s,()=>e.$html("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",onclick:t=>t.stopPropagation()},[e.$html("div",{class:"grid grid-cols-8 gap-1"},A.map(t=>e.$html("button",{type:"button",style:`background-color: ${t}`,class:()=>"size-6 rounded-sm cursor-pointer transition-all hover:scale-125 hover:z-10 active:scale-95 outline-none border border-black/5 \n "+(c().toLowerCase()===t.toLowerCase()?"ring-2 ring-offset-1 ring-primary z-10 scale-110":""),onclick:()=>{"function"==typeof a&&a(t),s(!1)}})))])),e.$if(s,()=>e.$html("div",{class:"fixed inset-0 z-[100]",onclick:()=>s(!1)}))])};const V=t=>{const{value:a,range:o,label:n,placeholder:s,hour:A=!1,...c}=t,r=e.$(!1),d=e.$(new Date),m=e.$(null),u=e.$(0),p=e.$(0),h=()=>!0===l(o),b=new Date,g=`${b.getFullYear()}-${String(b.getMonth()+1).padStart(2,"0")}-${String(b.getDate()).padStart(2,"0")}`,f=t=>`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")}`,x=t=>{const e=f(t),o=l(a);if(h())if(!o?.start||o.start&&o.end)"function"==typeof a&&a({start:e,end:null,...A&&{startHour:u()}});else{const t=o.start;if("function"==typeof a){const l=e{const t=l(a);if(!t)return"";if("string"==typeof t)return A&&t.includes("T")?t.replace("T"," "):t;if(t.start&&t.end){return`${A&&t.startHour?`${t.start} ${String(t.startHour).padStart(2,"0")}:00`:t.start} - ${A&&t.endHour?`${t.end} ${String(t.endHour).padStart(2,"0")}:00`:t.end}`}if(t.start){return`${A&&t.startHour?`${t.start} ${String(t.startHour).padStart(2,"0")}:00`:t.start}...`}return""}),S=t=>{const e=d();d(new Date(e.getFullYear(),e.getMonth()+t,1))},C=t=>{const e=d();d(new Date(e.getFullYear()+t,e.getMonth(),1))},U=({value:t,onChange:a})=>e.$html("div",{class:"flex-1"},[e.$html("div",{class:"flex gap-2 items-center"},[e.$html("input",{type:"range",min:0,max:23,value:t,class:"range range-xs flex-1",oninput:t=>{const e=parseInt(t.target.value);a(e)}}),e.$html("span",{class:"text-sm font-mono min-w-[48px] text-center"},()=>String(l(t)).padStart(2,"0")+":00")])]);return e.$html("div",{class:"relative w-full"},[D({label:n,placeholder:s||(h()?"Seleccionar rango...":"Seleccionar fecha..."),value:y,readonly:!0,icon:e.$html("img",{src:i,class:"opacity-40"}),onclick:t=>{t.stopPropagation(),r(!r())},...c}),e.$if(r,()=>e.$html("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",onclick:t=>t.stopPropagation()},[e.$html("div",{class:"flex justify-between items-center mb-4 gap-1"},[e.$html("div",{class:"flex gap-0.5"},[e.$html("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>C(-1)},e.$html("img",{src:B,class:"opacity-40"})),e.$html("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>S(-1)},e.$html("img",{src:$,class:"opacity-40"}))]),e.$html("span",{class:"font-bold uppercase flex-1 text-center"},[()=>d().toLocaleString("es-ES",{month:"short",year:"numeric"})]),e.$html("div",{class:"flex gap-0.5"},[e.$html("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>S(1)},e.$html("img",{src:v,class:"opacity-40"})),e.$html("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>C(1)},e.$html("img",{src:w,class:"opacity-40"}))])]),e.$html("div",{class:"grid grid-cols-7 gap-1",onmouseleave:()=>m(null)},[...["L","M","X","J","V","S","D"].map(t=>e.$html("div",{class:"text-[10px] opacity-40 font-bold text-center"},t)),()=>{const t=d(),o=t.getFullYear(),n=t.getMonth(),s=new Date(o,n,1).getDay(),A=0===s?6:s-1,c=new Date(o,n+1,0).getDate(),r=[];for(let t=0;t{const t=l(a),e=m(),o="string"==typeof t?t.split("T")[0]===A:t?.start===A,n=t?.end===A;let s=!1;if(h()&&t?.start){const l=t.start;!t.end&&e?s=A>l&&A<=e||A=e:t.end&&(s=A>l&&A{h()&&m(A)},onclick:()=>x(s)},[t.toString()]))}return r}]),A?e.$html("div",{class:"mt-3 pt-2 border-t border-base-300"},[h()?e.$html("div",{class:"flex gap-4"},[U({value:u,onChange:t=>{u(t);const e=l(a);e?.start&&a({...e,startHour:t})}}),U({value:p,onChange:t=>{p(t);const e=l(a);e?.end&&a({...e,endHour:t})}})]):U({value:u,onChange:t=>{u(t);const e=l(a);e&&"string"==typeof e&&e.includes("-")&&a(e.split("T")[0]+"T"+String(t).padStart(2,"0")+":00:00")}})]):null])),e.$if(r,()=>e.$html("div",{class:"fixed inset-0 z-[90]",onclick:()=>r(!1)}))])};const H=t=>e.$html("div",{class:a("drawer",t.class)},[e.$html("input",{id:t.id,type:"checkbox",class:"drawer-toggle",checked:t.open}),e.$html("div",{class:"drawer-content"},t.content),e.$html("div",{class:"drawer-side"},[e.$html("label",{for:t.id,class:"drawer-overlay",onclick:()=>t.open?.(!1)}),e.$html("div",{class:"min-h-full bg-base-200 w-80"},t.side)])]);const O=(t,a)=>{const{label:o,icon:n,items:s,...A}=t;return e.$html("div",{...A,class:()=>`dropdown ${l(t.class)||""}`},[e.$html("div",{tabindex:0,role:"button",class:"btn m-1 flex items-center gap-2"},[n?"function"==typeof n?n():n:null,o?"function"==typeof o?o():o:null]),(()=>{if(s){const t="function"==typeof s?s:()=>s;return e.$html("ul",{tabindex:0,class:"dropdown-content z-[50] menu p-2 shadow bg-base-100 rounded-box w-52 border border-base-300"},[e.$for(t,t=>e.$html("li",{},[e.$html("a",{class:t.class||"",onclick:e=>{t.onclick&&t.onclick(e),document.activeElement&&document.activeElement.blur()}},[t.icon?e.$html("span",{},t.icon):null,e.$html("span",{},t.label)])]))])}return e.$html("div",{tabindex:0,class:"dropdown-content z-[50] p-2 shadow bg-base-100 rounded-box min-w-max border border-base-300"},["function"==typeof a?a():a])})()])};const F=t=>{const{icon:a,label:o,actions:n=[],position:s="bottom-6 right-6",class:A="",...c}=t;return e.$html("div",{...c,class:`fab absolute ${s} flex flex-col-reverse items-end gap-3 z-[100] ${A}`},[e.$html("div",{tabindex:0,role:"button",class:"btn btn-lg btn-circle btn-primary shadow-2xl"},[a?"function"==typeof a?a():a:null,!a&&o?o:null]),...l(n).map(t=>e.$html("div",{class:"flex items-center gap-3 transition-all duration-300"},[t.label?e.$html("span",{class:"badge badge-ghost shadow-sm whitespace-nowrap"},t.label):null,e.$html("button",{type:"button",class:`btn btn-circle shadow-lg ${t.class||""}`,onclick:e=>{e.stopPropagation(),t.onclick?.(e)}},[t.icon?"function"==typeof t.icon?t.icon():t.icon:t.text||""])]))])};const Q=(t,o)=>e.$html("fieldset",{...t,class:a("fieldset bg-base-200 border border-base-300 p-4 rounded-lg",t.class)},[()=>{const a=l(t.legend);return a?e.$html("legend",{class:"fieldset-legend font-bold"},[a]):null},o]);const N=t=>{const{tooltip:l,max:a=2,accept:o="*",onSelect:n}=t,s=e.$([]),A=e.$(!1),c=e.$(null),i=1024*a*1024,d=t=>{const e=Array.from(t);c(null);e.find(t=>t.size>i)?c(`Máx ${a}MB`):(s([...s(),...e]),n?.(s()))};return e.$html("fieldset",{class:"fieldset w-full p-0"},[e.$html("div",{class:()=>"w-full "+(l?"tooltip tooltip-top before:z-50 after:z-50":""),"data-tip":l},[e.$html("label",{class:()=>`\n relative flex items-center justify-between w-full h-12 px-4\n border-2 border-dashed rounded-lg cursor-pointer\n transition-all duration-200\n ${A()?"border-primary bg-primary/10":"border-base-content/20 bg-base-100 hover:bg-base-200"}\n `,ondragover:t=>{t.preventDefault(),A(!0)},ondragleave:()=>A(!1),ondrop:t=>{t.preventDefault(),A(!1),d(t.dataTransfer.files)}},[e.$html("div",{class:"flex items-center gap-3 w-full"},[e.$html("img",{src:x,class:"w-5 h-5 opacity-50 shrink-0"}),e.$html("span",{class:"text-sm opacity-70 truncate grow text-left"},"Arrastra o selecciona archivos..."),e.$html("span",{class:"text-[10px] opacity-40 shrink-0"},`Máx ${a}MB`)]),e.$html("input",{type:"file",multiple:!0,accept:o,class:"hidden",onchange:t=>d(t.target.files)})])]),()=>c()?e.$html("span",{class:"text-[10px] text-error mt-1 px-1 font-medium"},c()):null,e.$if(()=>s().length>0,()=>e.$html("ul",{class:"mt-2 space-y-1"},[e.$for(s,(t,l)=>e.$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"},[e.$html("div",{class:"flex items-center gap-2 truncate"},[e.$html("span",{class:"opacity-50"},"📄"),e.$html("span",{class:"truncate font-medium max-w-[200px]"},t.name),e.$html("span",{class:"text-[9px] opacity-40"},`(${(t.size/1024).toFixed(0)} KB)`)]),e.$html("button",{type:"button",class:"btn btn-ghost btn-xs btn-circle",onclick:t=>{t.preventDefault(),t.stopPropagation(),(t=>{const e=s().filter((e,l)=>l!==t);s(e),n?.(e)})(l)}},[e.$html("img",{src:r,class:"w-3 h-3 opacity-70"})])]),t=>t.name+t.lastModified)]))])};const L=(t,l)=>e.$html("div",{class:a("indicator",t.class)},[l,e.$html("span",{class:a("indicator-item badge",t.badgeClass)},t.badge)]);const T=t=>{const{items:o,header:n,render:s,keyFn:A=(t,e)=>e,class:c,...r}=t,i=e.$for(o,(t,l)=>e.$html("li",{class:"list-row"},[s(t,l)]),A);return e.$html("ul",{...r,class:a("list bg-base-100 rounded-box shadow-md",c)},n?[e.$if(n,()=>e.$html("li",{class:"p-4 pb-2 text-xs opacity-60"},[l(n)])),i]:i)};const G=t=>e.$if(t.$show,()=>e.$html("div",{class:"fixed inset-0 z-[100] flex items-center justify-center backdrop-blur-sm bg-base-100/30"},[e.$html("span",{class:"loading loading-spinner loading-lg text-primary"})]));const M=t=>{const o=t=>e.$for(()=>t||[],t=>e.$html("li",{},[t.children?e.$html("details",{open:t.open},[e.$html("summary",{},[t.icon&&e.$html("span",{class:"mr-2"},t.icon),t.label]),e.$html("ul",{},o(t.children))]):e.$html("a",{class:()=>l(t.active)?"active":"",onclick:t.onclick},[t.icon&&e.$html("span",{class:"mr-2"},t.icon),t.label])]),(t,e)=>t.label||e);return e.$html("ul",{...t,class:a("menu bg-base-200 rounded-box",t.class)},o(t.items))};const J=(t,l)=>{const{title:a,buttons:o,open:n,...s}=t,A={current:null};e.$watch(()=>{const t=A.current;t&&(n()?t.open||t.showModal():t.open&&t.close())});const c=t=>{t&&t.preventDefault&&t.preventDefault(),n(!1)};return e.$html("dialog",{...s,ref:A,class:"modal",oncancel:()=>n(!1)},[e.$html("div",{class:"modal-box"},[a?e.$html("h3",{class:"text-lg font-bold mb-4"},a):null,e.$html("div",{class:"py-2"},["function"==typeof l?l():l]),e.$html("div",{class:"modal-action flex gap-2"},[...(Array.isArray(o)?o:[o]).filter(Boolean),E({type:"button",onclick:c},R("close")())])]),e.$html("form",{method:"dialog",class:"modal-backdrop",onsubmit:c},[e.$html("button",{},"close")])])};const K=(t,l)=>e.$html("div",{...t,class:a("navbar bg-base-100 shadow-sm px-4",t.class)},l);const P=t=>{const{label:o,tooltip:n,value:s,inputValue:A,name:c,...r}=t,i=e.$html("input",{...r,type:"radio",name:c,class:a("radio",t.class),checked:()=>l(s)===A,onclick:()=>{"function"==typeof s&&s(A)}});return o||n?e.$html("label",{class:"label cursor-pointer justify-start gap-3"},[i,o?e.$html("span",{class:"label-text"},o):null]):i};const X=t=>{const{label:o,tooltip:n,value:s,...A}=t,c=e.$html("input",{...A,type:"range",class:a("range",t.class),value:s,disabled:()=>l(t.disabled)});if(!o&&!n)return c;const r=e.$html("div",{class:"flex flex-col gap-2"},[o?e.$html("span",{class:"label-text"},o):null,c]);return n?e.$html("div",{class:"tooltip","data-tip":n},r):r};const Z=t=>{const{value:a,count:o=5,mask:n="mask-star",readonly:s=!1,onchange:A,...c}=t,r=`rating-${Math.random().toString(36).slice(2,7)}`;return e.$html("div",{...c,class:()=>`rating ${l(s)?"pointer-events-none":""} ${t.class||""}`},Array.from({length:l(o)},(t,o)=>{const c=o+1;return e.$html("input",{type:"radio",name:r,class:`mask ${n}`,checked:()=>Math.round(l(a))===c,onchange:()=>{l(s)||("function"==typeof A?A(c):"function"==typeof a&&a(c))}})}))};const W=t=>{const{label:o,options:n,value:s,...A}=t,c=e.$html("select",{...A,class:a("select select-bordered w-full",t.class),value:s},e.$for(()=>l(n)||[],t=>e.$html("option",{value:t.value,$selected:()=>String(l(s))===String(t.value)},t.label),t=>t.value));return o?e.$html("label",{class:"fieldset-label flex flex-col gap-1"},[e.$html("span",{},o),c]):c};const q=(t,l)=>e.$html("div",{...t,class:a("stack",t.class)},l);const tt=t=>e.$html("div",{...t,class:a("stat",t.class)},[t.icon&&e.$html("div",{class:"stat-figure text-secondary"},t.icon),t.label&&e.$html("div",{class:"stat-title"},t.label),e.$html("div",{class:"stat-value"},()=>l(t.value)??t.value),t.desc&&e.$html("div",{class:"stat-desc"},t.desc)]);const et=t=>e.$html("label",{class:a("swap",t.class)},[e.$html("input",{type:"checkbox",checked:t.value}),e.$html("div",{class:"swap-on"},t.on),e.$html("div",{class:"swap-off"},t.off)]);const lt=t=>{const{items:o=[],columns:n=[],keyFn:s,zebra:A=!1,pinRows:c=!1,empty:r=R("nodata")(),...i}=t;return e.$html("div",{class:"overflow-x-auto w-full bg-base-100 rounded-box border border-base-300"},[e.$html("table",{...i,class:()=>a("table",`${l(A)?"table-zebra":""} ${l(c)?"table-pin-rows":""} ${t.class||""}`)},[e.$html("thead",{},[e.$html("tr",{},n.map(t=>e.$html("th",{class:t.class||""},t.label)))]),e.$html("tbody",{},[e.$for(o,(t,a)=>e.$html("tr",{class:"hover"},n.map(o=>e.$html("td",{class:o.class||""},[()=>{if(o.render)return o.render(t,a);const e=t[o.key];return l(e)}]))),s||((t,e)=>t.id||e)),e.$if(()=>0===l(o).length,()=>e.$html("tr",{},[e.$html("td",{colspan:n.length,class:"text-center p-10 opacity-50"},[l(r)])]))]),e.$if(()=>n.some(t=>t.footer),()=>e.$html("tfoot",{},[e.$html("tr",{},n.map(t=>e.$html("th",{},t.footer||"")))]))])])};const at=t=>{const{items:o,...n}=t,s="function"==typeof o?o:()=>o||[];return e.$html("div",{...n,class:"flex flex-col gap-4 w-full"},[e.$html("div",{role:"tablist",class:a("tabs tabs-box",t.class)},e.$for(s,t=>e.$html("a",{role:"tab",class:()=>a("tab",l(t.active)&&"tab-active",l(t.disabled),t.tip),"data-tip":t.tip,onclick:e=>!l(t.disabled)&&t.onclick?.(e)},t.label),t=>t.label)),()=>{const t=s().find(t=>l(t.active));if(!t)return null;const a=l(t.content);return e.$html("div",{class:"p-4"},["function"==typeof a?a():a])}])};const ot=t=>{const{items:a=[],vertical:o=!0,compact:n=!1,...s}=t,A={info:h,success:b,warning:f,error:g};return e.$html("ul",{...s,class:()=>`timeline ${l(o)?"timeline-vertical":"timeline-horizontal"} ${l(n)?"timeline-compact":""} ${t.class||""}`},[e.$for(a,(t,o)=>{const n=0===o,s=o===l(a).length-1,c=t.type||"success",r=t=>"function"==typeof t?t():t;return e.$html("li",{class:"flex-1"},[n?null:e.$html("hr",{class:t.completed?"bg-primary":""}),e.$html("div",{class:"timeline-start"},[r(t.title)]),e.$html("div",{class:"timeline-middle"},[e.$html("img",{src:A[c]||t.icon||A.success,class:"w-4 h-4 object-contain mx-1",alt:c})]),e.$html("div",{class:"timeline-end timeline-box shadow-sm"},[r(t.detail)]),s?null:e.$html("hr",{class:t.completed?"bg-primary":""})])},(t,e)=>t.id||e)])};const nt=(t,l="alert-success",a=3500)=>{let o=document.getElementById("sigpro-toast-container");o||(o=e.$html("div",{id:"sigpro-toast-container",class:"fixed top-0 right-0 z-[9999] p-4 flex flex-col gap-2 pointer-events-none"}),document.body.appendChild(o));const n=e.$html("div",{style:"display: contents"});let s;o.appendChild(n);const A=()=>{clearTimeout(s);const t=n.firstElementChild;t&&!t.classList.contains("opacity-0")?(t.classList.add("translate-x-full","opacity-0"),setTimeout(()=>{c.destroy(),n.remove(),o.hasChildNodes()||o.remove()},300)):(c.destroy(),n.remove())},c=e.$mount(()=>{const a=e.$html("div",{class:`alert alert-soft ${l} shadow-lg transition-all duration-300 translate-x-10 opacity-0 pointer-events-auto`},[e.$html("span",{},["function"==typeof t?t():t]),E({class:"btn-xs btn-circle btn-ghost",onclick:A},"✕")]);return requestAnimationFrame(()=>a.classList.remove("translate-x-10","opacity-0")),a},n);return a>0&&(s=setTimeout(A,a)),A};const st=(t,l)=>e.$html("div",{...t,class:a("tooltip",t.class),"data-tip":t.tip},l);const At={...s,...C,...Object.freeze({__proto__:null,Autocomplete:_}),...Object.freeze({__proto__:null,Badge:z}),...Object.freeze({__proto__:null,Button:E}),...Object.freeze({__proto__:null,Checkbox:I}),...Object.freeze({__proto__:null,Colorpicker:Y}),...Object.freeze({__proto__:null,Datepicker:V}),...Object.freeze({__proto__:null,Drawer:H}),...Object.freeze({__proto__:null,Dropdown:O}),...Object.freeze({__proto__:null,Fab:F}),...Object.freeze({__proto__:null,Fieldset:Q}),...Object.freeze({__proto__:null,Fileinput:N}),...Object.freeze({__proto__:null,Indicator:L}),...j,...Object.freeze({__proto__:null,List:T}),...Object.freeze({__proto__:null,Loading:G}),...Object.freeze({__proto__:null,Menu:M}),...Object.freeze({__proto__:null,Modal:J}),...Object.freeze({__proto__:null,Navbar:K}),...Object.freeze({__proto__:null,Radio:P}),...Object.freeze({__proto__:null,Range:X}),...Object.freeze({__proto__:null,Rating:Z}),...Object.freeze({__proto__:null,Select:W}),...Object.freeze({__proto__:null,Stack:q}),...Object.freeze({__proto__:null,Stat:tt}),...Object.freeze({__proto__:null,Swap:et}),...Object.freeze({__proto__:null,Table:lt}),...Object.freeze({__proto__:null,Tabs:at}),...Object.freeze({__proto__:null,Timeline:ot}),...Object.freeze({__proto__:null,Toast:nt}),...Object.freeze({__proto__:null,Tooltip:st})};var ct={...At,install:(t=window)=>{Object.entries(At).forEach(([e,l])=>{t[e]=l}),console.log("🚀 SigproUI")}},rt=Object.freeze({__proto__:null,Accordion:n,Alert:S,Autocomplete:_,Badge:z,Button:E,Checkbox:I,Colorpicker:Y,Datepicker:V,Drawer:H,Dropdown:O,Fab:F,Fieldset:Q,Fileinput:N,Indicator:L,Input:D,List:T,Loading:G,Menu:M,Modal:J,Navbar:K,Radio:P,Range:X,Rating:Z,Select:W,Stack:q,Stat:tt,Swap:et,Table:lt,Tabs:at,Timeline:ot,Toast:nt,Tooltip:st,default:ct});const it={...rt,Icons:y,Utils:o,tt:R,install:(t=("undefined"!=typeof window?window:{}))=>{Object.entries(rt).forEach(([e,l])=>{t[e]=l}),t.Icons=y,t.Utils=o,t.tt=R,console.log("🌟 SigproUI")}};return"undefined"!=typeof window&&it.install(window),t.Accordion=n,t.Alert=S,t.Autocomplete=_,t.Badge=z,t.Button=E,t.Checkbox=I,t.Colorpicker=Y,t.Datepicker=V,t.Drawer=H,t.Dropdown=O,t.Fab=F,t.Fieldset=Q,t.Fileinput=N,t.Indicator=L,t.Input=D,t.List=T,t.Loading=G,t.Menu=M,t.Modal=J,t.Navbar=K,t.Radio=P,t.Range=X,t.Rating=Z,t.Select=W,t.Stack=q,t.Stat=tt,t.Swap=et,t.Table=lt,t.Tabs=at,t.Timeline=ot,t.Toast=nt,t.Tooltip=st,t.default=it,t.icon123=u,t.iconAbc=m,t.iconCalendar=i,t.iconClose=r,t.iconError=g,t.iconHide=c,t.iconInfo=h,t.iconLLeft=B,t.iconLeft=$,t.iconLock=d,t.iconMail=p,t.iconRRight=w,t.iconRight=v,t.iconShow=A,t.iconSuccess=b,t.iconUpload=x,t.iconWarning=f,t.joinClass=a,t.tt=R,t.val=l,Object.defineProperty(t,"__esModule",{value:!0}),t}({},SigPro); diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 25c37ae..6a2653e 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -7,46 +7,43 @@ * [Quick Reference](quick.md) * **Forms & Inputs** - * [Button](components/button.md) - * [Input](components/input.md) - * [Select](components/select.md) * [Autocomplete](components/autocomplete.md) - * [Datepicker](components/datepicker.md) - * [Colorpicker](components/colorpicker.md) + * [Button](components/button.md) * [Checkbox](components/checkbox.md) + * [Colorpicker](components/colorpicker.md) + * [Datepicker](components/datepicker.md) + * [Input](components/input.md) * [Radio](components/radio.md) * [Range](components/range.md) * [Rating](components/rating.md) + * [Select](components/select.md) * [Swap](components/swap.md) * **Data Display** - * [Table](components/table.md) - * [List](components/list.md) * [Badge](components/badge.md) - * [Stat](components/stat.md) - * [Timeline](components/timeline.md) - * [Stack](components/stack.md) * [Indicator](components/indicator.md) + * [List](components/list.md) + * [Stack](components/stack.md) + * [Stat](components/stat.md) + * [Table](components/table.md) + * [Timeline](components/timeline.md) * **Feedback & Overlays** * [Alert](components/alert.md) + * [Loading](components/loading.md) * [Modal](components/modal.md) * [Toast](components/toast.md) - * [Loading](components/loading.md) * [Tooltip](components/tooltip.md) * **Navigation & Layout** - * [Navbar](components/navbar.md) - * [Menu](components/menu.md) - * [Drawer](components/drawer.md) - * [Tabs](components/tabs.md) * [Accordion](components/accordion.md) + * [Drawer](components/drawer.md) * [Dropdown](components/dropdown.md) - * [Fieldset](components/fieldset.md) - -* **Utilities** * [Fab](components/fab.md) - * [Toast](components/toast.md) + * [Fieldset](components/fieldset.md) + * [Menu](components/menu.md) + * [Navbar](components/navbar.md) + * [Tabs](components/tabs.md) * **Advanced** * [Reactivity Guide](advanced/reactivity.md) diff --git a/docs/components/accordion.md b/docs/components/accordion.md new file mode 100644 index 0000000..7ef4a85 --- /dev/null +++ b/docs/components/accordion.md @@ -0,0 +1,730 @@ +# Accordion + +Collapsible accordion component for organizing content into expandable sections with DaisyUI styling. + +## Tag + +`Accordion` + +## Props + +| Prop | Type | Default | Description | +| :----------- | :-------------------------------------- | :---------- | :----------------------------------------------- | +| `title` | `string \| VNode \| Signal` | Required | Accordion section title | +| `open` | `boolean \| Signal` | `false` | Whether the accordion is expanded | +| `name` | `string` | `-` | Group name for radio-style accordions (only one open at a time) | +| `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) | +| `children` | `VNode \| Array` | Required | Content to display when expanded | + +## Live Examples + +### Basic Accordion + +
+
+

Live Demo

+
+
+
+ +```javascript +const BasicDemo = () => { + const open1 = $(false); + const open2 = $(false); + const open3 = $(false); + + return Div({ class: 'flex flex-col gap-2' }, [ + Accordion({ + title: 'Section 1', + open: open1, + onclick: () => open1(!open1()) + }, [ + Div({ class: 'p-2' }, 'Content for section 1. This is a basic accordion section.') + ]), + Accordion({ + title: 'Section 2', + open: open2, + onclick: () => open2(!open2()) + }, [ + Div({ class: 'p-2' }, 'Content for section 2. You can put any content here.') + ]), + Accordion({ + title: 'Section 3', + open: open3, + onclick: () => open3(!open3()) + }, [ + Div({ class: 'p-2' }, 'Content for section 3. Accordions are great for FAQs.') + ]) + ]); +}; +$mount(BasicDemo, '#demo-basic'); +``` + +### Group Accordion (Radio Style) + +
+
+

Live Demo

+
+
+
+ +```javascript +const GroupDemo = () => { + const openSection = $('section1'); + + return Div({ class: 'flex flex-col gap-2' }, [ + Accordion({ + title: 'Section 1', + name: 'group', + open: () => openSection() === 'section1', + onclick: () => openSection('section1') + }, [ + Div({ class: 'p-2' }, 'Content for section 1. Only one section can be open at a time.') + ]), + Accordion({ + title: 'Section 2', + name: 'group', + open: () => openSection() === 'section2', + onclick: () => openSection('section2') + }, [ + Div({ class: 'p-2' }, 'Content for section 2. Opening this will close section 1.') + ]), + Accordion({ + title: 'Section 3', + name: 'group', + open: () => openSection() === 'section3', + onclick: () => openSection('section3') + }, [ + Div({ class: 'p-2' }, 'Content for section 3. This is useful for FAQ sections.') + ]) + ]); +}; +$mount(GroupDemo, '#demo-group'); +``` + +### FAQ Accordion + +
+
+

Live Demo

+
+
+
+ +```javascript +const FaqDemo = () => { + const openFaq = $('faq1'); + + const faqs = [ + { id: 'faq1', question: 'What is this component?', answer: 'This is an accordion component built with DaisyUI and Tailwind CSS for creating collapsible content sections.' }, + { id: 'faq2', question: 'How do I use it?', answer: 'Simply import the Accordion component and pass title and children props. Use the open prop to control expansion.' }, + { id: 'faq3', question: 'Can I have multiple open?', answer: 'Yes! By default, accordions can be opened independently. Use the name prop to create groups where only one can be open.' }, + { id: 'faq4', question: 'Is it accessible?', answer: 'Yes, the accordion uses proper ARIA attributes and keyboard navigation support.' } + ]; + + return Div({ class: 'flex flex-col gap-2' }, faqs.map(faq => + Accordion({ + title: faq.question, + name: 'faq-group', + open: () => openFaq() === faq.id, + onclick: () => openFaq(openFaq() === faq.id ? '' : faq.id) + }, [ + Div({ class: 'p-2 text-sm' }, faq.answer) + ]) + )); +}; +$mount(FaqDemo, '#demo-faq'); +``` + +### With Rich Content + +
+
+

Live Demo

+
+
+
+ +```javascript +const RichDemo = () => { + const open1 = $(true); + const open2 = $(false); + + return Div({ class: 'flex flex-col gap-2' }, [ + Accordion({ + title: Span({ class: 'flex items-center gap-2' }, ['📊', 'Statistics']), + open: open1, + onclick: () => open1(!open1()) + }, [ + Div({ class: 'p-2' }, [ + Div({ class: 'grid grid-cols-2 gap-4' }, [ + Div({ class: 'stat bg-base-100 rounded-lg p-3' }, [ + Div({ class: 'stat-title' }, 'Users'), + Div({ class: 'stat-value text-lg' }, '1,234') + ]), + Div({ class: 'stat bg-base-100 rounded-lg p-3' }, [ + Div({ class: 'stat-title' }, 'Revenue'), + Div({ class: 'stat-value text-lg' }, '$45,678') + ]), + Div({ class: 'stat bg-base-100 rounded-lg p-3' }, [ + Div({ class: 'stat-title' }, 'Growth'), + Div({ class: 'stat-value text-lg text-success' }, '+23%') + ]), + Div({ class: 'stat bg-base-100 rounded-lg p-3' }, [ + Div({ class: 'stat-title' }, 'Active'), + Div({ class: 'stat-value text-lg' }, '89%') + ]) + ]) + ]) + ]), + Accordion({ + title: Span({ class: 'flex items-center gap-2' }, ['👥', 'Team Members']), + open: open2, + onclick: () => open2(!open2()) + }, [ + Div({ class: 'p-2 space-y-2' }, [ + Div({ class: 'flex items-center gap-3 p-2 hover:bg-base-100 rounded-lg' }, [ + Div({ class: 'avatar placeholder' }, [ + Div({ class: 'bg-primary text-primary-content rounded-full w-10 h-10 flex items-center justify-center' }, 'JD') + ]), + Div({ class: 'flex-1' }, [ + Div({ class: 'font-medium' }, 'John Doe'), + Div({ class: 'text-sm opacity-70' }, 'Developer') + ]) + ]), + Div({ class: 'flex items-center gap-3 p-2 hover:bg-base-100 rounded-lg' }, [ + Div({ class: 'avatar placeholder' }, [ + Div({ class: 'bg-secondary text-secondary-content rounded-full w-10 h-10 flex items-center justify-center' }, 'JS') + ]), + Div({ class: 'flex-1' }, [ + Div({ class: 'font-medium' }, 'Jane Smith'), + Div({ class: 'text-sm opacity-70' }, 'Designer') + ]) + ]) + ]) + ]) + ]); +}; +$mount(RichDemo, '#demo-rich'); +``` + +### Form Accordion + +
+
+

Live Demo

+
+
+
+ +```javascript +const FormAccordion = () => { + const openStep = $('step1'); + const formData = $({ + name: '', + email: '', + address: '', + payment: 'credit' + }); + + const updateField = (field, value) => { + formData({ ...formData(), [field]: value }); + }; + + const nextStep = () => { + if (openStep() === 'step1') openStep('step2'); + else if (openStep() === 'step2') openStep('step3'); + }; + + const prevStep = () => { + if (openStep() === 'step2') openStep('step1'); + else if (openStep() === 'step3') openStep('step2'); + }; + + const handleSubmit = () => { + Toast('Form submitted!', 'alert-success', 2000); + console.log(formData()); + }; + + return Div({ class: 'flex flex-col gap-2' }, [ + Accordion({ + title: Span({ class: 'flex items-center gap-2' }, ['1️⃣', 'Personal Information']), + name: 'form-steps', + open: () => openStep() === 'step1', + onclick: () => openStep('step1') + }, [ + Div({ class: 'p-4 space-y-4' }, [ + Input({ + label: 'Full Name', + value: () => formData().name, + placeholder: 'Enter your name', + oninput: (e) => updateField('name', e.target.value) + }), + Input({ + label: 'Email', + type: 'email', + value: () => formData().email, + placeholder: 'email@example.com', + oninput: (e) => updateField('email', e.target.value) + }), + Div({ class: 'flex justify-end mt-2' }, [ + Button({ + class: 'btn btn-primary btn-sm', + onclick: nextStep, + disabled: () => !formData().name || !formData().email + }, 'Next →') + ]) + ]) + ]), + Accordion({ + title: Span({ class: 'flex items-center gap-2' }, ['2️⃣', 'Address']), + name: 'form-steps', + open: () => openStep() === 'step2', + onclick: () => openStep('step2') + }, [ + Div({ class: 'p-4 space-y-4' }, [ + Input({ + label: 'Address', + value: () => formData().address, + placeholder: 'Street address', + oninput: (e) => updateField('address', e.target.value) + }), + Div({ class: 'flex justify-between mt-2' }, [ + Button({ class: 'btn btn-ghost btn-sm', onclick: prevStep }, '← Back'), + Button({ + class: 'btn btn-primary btn-sm', + onclick: nextStep + }, 'Next →') + ]) + ]) + ]), + Accordion({ + title: Span({ class: 'flex items-center gap-2' }, ['3️⃣', 'Payment']), + name: 'form-steps', + open: () => openStep() === 'step3', + onclick: () => openStep('step3') + }, [ + Div({ class: 'p-4 space-y-4' }, [ + Div({ class: 'flex flex-col gap-2' }, [ + Radio({ + label: 'Credit Card', + value: () => formData().payment, + radioValue: 'credit', + onclick: () => updateField('payment', 'credit') + }), + Radio({ + label: 'PayPal', + value: () => formData().payment, + radioValue: 'paypal', + onclick: () => updateField('payment', 'paypal') + }), + Radio({ + label: 'Bank Transfer', + value: () => formData().payment, + radioValue: 'bank', + onclick: () => updateField('payment', 'bank') + }) + ]), + Div({ class: 'flex justify-between mt-2' }, [ + Button({ class: 'btn btn-ghost btn-sm', onclick: prevStep }, '← Back'), + Button({ class: 'btn btn-success btn-sm', onclick: handleSubmit }, 'Submit') + ]) + ]) + ]) + ]); +}; +$mount(FormAccordion, '#demo-form'); +``` + +### All Variants + +
+
+

Live Demo

+
+
+
+ +```javascript +const VariantsDemo = () => { + const open1 = $(true); + const open2 = $(false); + const open3 = $(false); + + return Div({ class: 'flex flex-col gap-4' }, [ + Div({ class: 'text-sm font-bold' }, 'Default Accordion'), + Div({ class: 'flex flex-col gap-2' }, [ + Accordion({ title: 'Default style', open: open1, onclick: () => open1(!open1()) }, [ + Div({ class: 'p-2' }, 'Default accordion with standard styling.') + ]) + ]), + + Div({ class: 'text-sm font-bold mt-2' }, 'Custom Styling'), + Div({ class: 'flex flex-col gap-2' }, [ + Accordion({ + title: Span({ class: 'text-primary font-bold' }, 'Primary Title'), + open: open2, + onclick: () => open2(!open2()), + class: 'bg-primary/5 border-primary/20' + }, [ + Div({ class: 'p-2' }, 'Accordion with custom styling and primary color.') + ]) + ]), + + Div({ class: 'text-sm font-bold mt-2' }, 'With Icons'), + Div({ class: 'flex flex-col gap-2' }, [ + Accordion({ + title: Span({ class: 'flex items-center gap-2' }, ['✨', 'Featured Content']), + open: open3, + onclick: () => open3(!open3()) + }, [ + Div({ class: 'p-2' }, 'Accordion with emoji icons in the title.') + ]) + ]) + ]); +}; +$mount(VariantsDemo, '#demo-variants'); +``` + + diff --git a/docs/components/drawer.md b/docs/components/drawer.md new file mode 100644 index 0000000..290d329 --- /dev/null +++ b/docs/components/drawer.md @@ -0,0 +1,918 @@ +# Drawer + +Drawer component for creating off-canvas side panels with overlay and toggle functionality. + +## Tag + +`Drawer` + +## Props + +| Prop | Type | Default | Description | +| :----------- | :--------------------------- | :---------- | :----------------------------------------------- | +| `id` | `string` | Required | Unique identifier for the drawer | +| `open` | `boolean \| Signal` | `false` | Drawer open state | +| `side` | `VNode` | Required | Content to display in the drawer panel | +| `content` | `VNode` | Required | Main page content | +| `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) | + +## Live Examples + +### Basic Drawer + +
+
+

Live Demo

+
+
+
+ +```javascript +const BasicDemo = () => { + const isOpen = $(false); + + return Drawer({ + id: 'basic-drawer', + open: isOpen, + side: Div({ class: 'p-4' }, [ + Div({ class: 'text-lg font-bold mb-4' }, 'Menu'), + Div({ class: 'flex flex-col gap-2' }, [ + Button({ class: 'btn btn-ghost justify-start' }, 'Home'), + Button({ class: 'btn btn-ghost justify-start' }, 'About'), + Button({ class: 'btn btn-ghost justify-start' }, 'Contact') + ]) + ]), + content: Div({ class: 'p-4 text-center' }, [ + Button({ + class: 'btn btn-primary', + onclick: () => isOpen(true) + }, 'Open Drawer') + ]) + }); +}; +$mount(BasicDemo, '#demo-basic'); +``` + +### Navigation Drawer + +
+
+

Live Demo

+
+
+
+ +```javascript +const NavDrawer = () => { + const isOpen = $(false); + const activePage = $('home'); + + const pages = { + home: 'Welcome to the Home Page!', + about: 'About Us - Learn more about our company', + services: 'Our Services - What we offer', + contact: 'Contact Us - Get in touch' + }; + + return Drawer({ + id: 'nav-drawer', + open: isOpen, + side: Div({ class: 'p-4 w-64' }, [ + Div({ class: 'text-xl font-bold mb-6' }, 'MyApp'), + Div({ class: 'flex flex-col gap-1' }, [ + Button({ + class: `btn btn-ghost justify-start ${activePage() === 'home' ? 'btn-active' : ''}`, + onclick: () => { + activePage('home'); + isOpen(false); + } + }, '🏠 Home'), + Button({ + class: `btn btn-ghost justify-start ${activePage() === 'about' ? 'btn-active' : ''}`, + onclick: () => { + activePage('about'); + isOpen(false); + } + }, 'ℹ️ About'), + Button({ + class: `btn btn-ghost justify-start ${activePage() === 'services' ? 'btn-active' : ''}`, + onclick: () => { + activePage('services'); + isOpen(false); + } + }, '⚙️ Services'), + Button({ + class: `btn btn-ghost justify-start ${activePage() === 'contact' ? 'btn-active' : ''}`, + onclick: () => { + activePage('contact'); + isOpen(false); + } + }, '📧 Contact') + ]) + ]), + content: Div({ class: 'p-4' }, [ + Div({ class: 'flex justify-between items-center mb-4' }, [ + Button({ + class: 'btn btn-ghost btn-circle', + onclick: () => isOpen(true) + }, '☰'), + Span({ class: 'text-lg font-bold' }, 'MyApp') + ]), + Div({ class: 'card bg-base-200 shadow-lg' }, [ + Div({ class: 'card-body' }, [ + Div({ class: 'text-2xl font-bold mb-2' }, () => activePage().charAt(0).toUpperCase() + activePage().slice(1)), + Div({ class: 'text-lg' }, () => pages[activePage()]) + ]) + ]) + ]) + }); +}; +$mount(NavDrawer, '#demo-nav'); +``` + +### Settings Drawer + +
+
+

Live Demo

+
+
+
+ +```javascript +const SettingsDrawer = () => { + const isOpen = $(false); + const darkMode = $(false); + const notifications = $(true); + const autoSave = $(false); + + return Drawer({ + id: 'settings-drawer', + open: isOpen, + side: Div({ class: 'p-4 w-80' }, [ + Div({ class: 'flex justify-between items-center mb-6' }, [ + Span({ class: 'text-xl font-bold' }, 'Settings'), + Button({ + class: 'btn btn-ghost btn-circle btn-sm', + onclick: () => isOpen(false) + }, '✕') + ]), + Div({ class: 'flex flex-col gap-4' }, [ + Div({ class: 'flex justify-between items-center' }, [ + Span({}, 'Dark Mode'), + Swap({ + value: darkMode, + on: "🌙", + off: "☀️", + onclick: () => darkMode(!darkMode()) + }) + ]), + Div({ class: 'flex justify-between items-center' }, [ + Span({}, 'Notifications'), + Swap({ + value: notifications, + on: "🔔", + off: "🔕", + onclick: () => notifications(!notifications()) + }) + ]), + Div({ class: 'flex justify-between items-center' }, [ + Span({}, 'Auto Save'), + Swap({ + value: autoSave, + on: "✅", + off: "⭕", + onclick: () => autoSave(!autoSave()) + }) + ]) + ]), + Div({ class: 'divider my-4' }), + Div({ class: 'flex gap-2' }, [ + Button({ + class: 'btn btn-primary flex-1', + onclick: () => { + isOpen(false); + Toast('Settings saved!', 'alert-success', 2000); + } + }, 'Save'), + Button({ + class: 'btn btn-ghost flex-1', + onclick: () => isOpen(false) + }, 'Cancel') + ]) + ]), + content: Div({ class: 'p-4' }, [ + Div({ class: 'flex justify-between items-center' }, [ + Span({ class: 'text-lg font-bold' }, 'Dashboard'), + Button({ + class: 'btn btn-ghost btn-circle', + onclick: () => isOpen(true) + }, '⚙️') + ]), + Div({ class: 'mt-4 grid grid-cols-2 gap-4' }, [ + Div({ class: 'stat bg-base-200 rounded-lg p-4' }, [ + Div({ class: 'stat-title' }, 'Users'), + Div({ class: 'stat-value' }, '1,234') + ]), + Div({ class: 'stat bg-base-200 rounded-lg p-4' }, [ + Div({ class: 'stat-title' }, 'Revenue'), + Div({ class: 'stat-value' }, '$45K') + ]) + ]) + ]) + }); +}; +$mount(SettingsDrawer, '#demo-settings'); +``` + +### Cart Drawer + +
+
+

Live Demo

+
+
+
+ +```javascript +const CartDrawer = () => { + const isOpen = $(false); + const cart = $([ + { id: 1, name: 'Product 1', price: 29, quantity: 2 }, + { id: 2, name: 'Product 2', price: 49, quantity: 1 } + ]); + + const updateQuantity = (id, delta) => { + cart(cart().map(item => { + if (item.id === id) { + const newQty = Math.max(0, item.quantity + delta); + return newQty === 0 ? null : { ...item, quantity: newQty }; + } + return item; + }).filter(Boolean)); + }; + + const total = () => cart().reduce((sum, item) => sum + (item.price * item.quantity), 0); + + return Drawer({ + id: 'cart-drawer', + open: isOpen, + side: Div({ class: 'flex flex-col h-full' }, [ + Div({ class: 'p-4 border-b border-base-300' }, [ + Div({ class: 'flex justify-between items-center' }, [ + Span({ class: 'text-xl font-bold' }, `Cart (${cart().length} items)`), + Button({ + class: 'btn btn-ghost btn-circle btn-sm', + onclick: () => isOpen(false) + }, '✕') + ]) + ]), + Div({ class: 'flex-1 overflow-y-auto p-4' }, cart().length === 0 + ? Div({ class: 'text-center text-gray-500 mt-8' }, 'Your cart is empty') + : Div({ class: 'flex flex-col gap-3' }, cart().map(item => + Div({ class: 'flex gap-3 items-center p-2 bg-base-200 rounded-lg' }, [ + Div({ class: 'flex-1' }, [ + Div({ class: 'font-medium' }, item.name), + Div({ class: 'text-sm' }, `$${item.price} each`) + ]), + Div({ class: 'flex items-center gap-2' }, [ + Button({ + class: 'btn btn-xs btn-circle', + onclick: () => updateQuantity(item.id, -1) + }, '-'), + Span({ class: 'w-8 text-center' }, item.quantity), + Button({ + class: 'btn btn-xs btn-circle', + onclick: () => updateQuantity(item.id, 1) + }, '+') + ]), + Span({ class: 'font-bold w-16 text-right' }, `$${item.price * item.quantity}`) + ]) + )) + ), + Div({ class: 'p-4 border-t border-base-300' }, [ + Div({ class: 'flex justify-between items-center mb-4' }, [ + Span({ class: 'font-bold' }, 'Total'), + Span({ class: 'text-xl font-bold' }, () => `$${total()}`) + ]), + Button({ + class: 'btn btn-primary w-full', + onclick: () => { + isOpen(false); + Toast('Checkout initiated!', 'alert-success', 2000); + }, + disabled: () => cart().length === 0 + }, 'Checkout') + ]) + ]), + content: Div({ class: 'p-4' }, [ + Div({ class: 'flex justify-between items-center' }, [ + Span({ class: 'text-lg font-bold' }, 'Store'), + Button({ + class: 'btn btn-primary', + onclick: () => isOpen(true) + }, () => `🛒 Cart (${cart().length})`) + ]), + Div({ class: 'mt-4 grid grid-cols-2 gap-4' }, [ + Button({ + class: 'btn btn-outline h-32 flex flex-col', + onclick: () => { + cart([...cart(), { id: Date.now(), name: 'New Product', price: 39, quantity: 1 }]); + Toast('Added to cart!', 'alert-success', 1500); + } + }, ['📦', 'Add to Cart']) + ]) + ]) + }); +}; +$mount(CartDrawer, '#demo-cart'); +``` + +### Responsive Drawer + +
+
+

Live Demo

+
+
+
+ +```javascript +const ResponsiveDrawer = () => { + const isOpen = $(false); + const activePage = $('home'); + + const MenuItems = () => Div({ class: 'flex flex-col gap-1 p-4' }, [ + Button({ + class: `btn btn-ghost justify-start ${activePage() === 'home' ? 'btn-active' : ''}`, + onclick: () => { + activePage('home'); + if (window.innerWidth < 1024) isOpen(false); + } + }, '🏠 Home'), + Button({ + class: `btn btn-ghost justify-start ${activePage() === 'analytics' ? 'btn-active' : ''}`, + onclick: () => { + activePage('analytics'); + if (window.innerWidth < 1024) isOpen(false); + } + }, '📊 Analytics'), + Button({ + class: `btn btn-ghost justify-start ${activePage() === 'settings' ? 'btn-active' : ''}`, + onclick: () => { + activePage('settings'); + if (window.innerWidth < 1024) isOpen(false); + } + }, '⚙️ Settings') + ]); + + return Drawer({ + id: 'responsive-drawer', + open: isOpen, + side: Div({ class: 'w-64' }, [ + Div({ class: 'text-xl font-bold p-4 border-b border-base-300' }, 'Menu'), + MenuItems() + ]), + content: Div({ class: 'flex' }, [ + Div({ class: 'hidden lg:block w-64 border-r border-base-300' }, [MenuItems()]), + Div({ class: 'flex-1 p-4' }, [ + Div({ class: 'flex justify-between items-center lg:hidden mb-4' }, [ + Button({ + class: 'btn btn-ghost btn-circle', + onclick: () => isOpen(true) + }, '☰'), + Span({ class: 'text-lg font-bold' }, 'MyApp') + ]), + Div({ class: 'card bg-base-200' }, [ + Div({ class: 'card-body' }, [ + Div({ class: 'text-2xl font-bold' }, () => activePage().charAt(0).toUpperCase() + activePage().slice(1)), + Div({}, 'Content area. On desktop, the menu is always visible on the left.') + ]) + ]) + ]) + ]) + }); +}; +$mount(ResponsiveDrawer, '#demo-responsive'); +``` + +### Form Drawer + +
+
+

Live Demo

+
+
+
+ +```javascript +const FormDrawer = () => { + const isOpen = $(false); + const name = $(''); + const email = $(''); + const message = $(''); + + const handleSubmit = () => { + if (name() && email() && message()) { + Toast('Message sent!', 'alert-success', 2000); + isOpen(false); + name(''); + email(''); + message(''); + } else { + Toast('Please fill all fields', 'alert-warning', 2000); + } + }; + + return Drawer({ + id: 'form-drawer', + open: isOpen, + side: Div({ class: 'p-4 w-96' }, [ + Div({ class: 'flex justify-between items-center mb-4' }, [ + Span({ class: 'text-xl font-bold' }, 'Contact Us'), + Button({ + class: 'btn btn-ghost btn-circle btn-sm', + onclick: () => isOpen(false) + }, '✕') + ]), + Div({ class: 'flex flex-col gap-4' }, [ + Input({ + label: 'Name', + value: name, + placeholder: 'Your name', + oninput: (e) => name(e.target.value) + }), + Input({ + label: 'Email', + type: 'email', + value: email, + placeholder: 'your@email.com', + oninput: (e) => email(e.target.value) + }), + Div({ class: 'form-control' }, [ + Span({ class: 'label-text mb-1' }, 'Message'), + $html('textarea', { + class: 'textarea textarea-bordered h-24', + placeholder: 'Your message', + value: message, + oninput: (e) => message(e.target.value) + }) + ]), + Div({ class: 'flex gap-2 mt-2' }, [ + Button({ + class: 'btn btn-primary flex-1', + onclick: handleSubmit + }, 'Send'), + Button({ + class: 'btn btn-ghost flex-1', + onclick: () => isOpen(false) + }, 'Cancel') + ]) + ]) + ]), + content: Div({ class: 'p-4 text-center' }, [ + Button({ + class: 'btn btn-primary', + onclick: () => isOpen(true) + }, 'Contact Us') + ]) + }); +}; +$mount(FormDrawer, '#demo-form'); +``` + + diff --git a/docs/components/dropdown.md b/docs/components/dropdown.md new file mode 100644 index 0000000..ea00098 --- /dev/null +++ b/docs/components/dropdown.md @@ -0,0 +1,489 @@ +# Dropdown + +Dropdown component for creating menus, selectors, and action panels that appear when triggered. Supports both array-based items and custom content. + +## Tag + +`Dropdown` + +## Props + +| Prop | Type | Default | Description | +| :----------- | :-------------------------------------- | :---------- | :----------------------------------------------- | +| `label` | `string \| VNode \| Signal` | `-` | Button label or content | +| `icon` | `string \| VNode \| Signal` | `-` | Icon displayed next to label | +| `items` | `Array \| Signal` | `-` | Array of menu items (alternative to children) | +| `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) | +| `children` | `VNode \| function` | `-` | Custom dropdown content (alternative to items) | + +### MenuItem Structure (when using `items`) + +| Property | Type | Description | +| :---------- | :--------------------------- | :----------------------------------------------- | +| `label` | `string \| VNode` | Menu item text | +| `icon` | `string \| VNode` | Optional icon for the menu item | +| `onclick` | `function` | Click handler | +| `class` | `string` | Additional CSS classes for the menu item | + +## Live Examples + +### Basic Dropdown (Items Array) + +
+
+

Live Demo

+
+
+
+ +```javascript +const BasicDemo = () => { + return Dropdown({ + label: 'Options', + items: [ + { label: 'Profile', onclick: () => Toast('Profile clicked', 'alert-info', 2000) }, + { label: 'Settings', onclick: () => Toast('Settings clicked', 'alert-info', 2000) }, + { label: 'Logout', onclick: () => Toast('Logged out', 'alert-warning', 2000), class: 'text-error' } + ] + }); +}; +$mount(BasicDemo, '#demo-basic'); +``` + +### With Icons (Items Array) + +
+
+

Live Demo

+
+
+
+ +```javascript +const IconsDemo = () => { + return Dropdown({ + label: 'Menu', + icon: '☰', + items: [ + { icon: '👤', label: 'Profile', onclick: () => Toast('Profile', 'alert-info', 2000) }, + { icon: '⭐', label: 'Favorites', onclick: () => Toast('Favorites', 'alert-info', 2000) }, + { icon: '📁', label: 'Documents', onclick: () => Toast('Documents', 'alert-info', 2000) }, + { icon: '⚙️', label: 'Settings', onclick: () => Toast('Settings', 'alert-info', 2000) } + ] + }); +}; +$mount(IconsDemo, '#demo-icons'); +``` + +### Action Dropdown (Items Array) + +
+
+

Live Demo

+
+
+
+ +```javascript +const ActionsDemo = () => { + const handleAction = (action) => { + Toast(`${action} action`, 'alert-info', 2000); + }; + + return Dropdown({ + label: 'Actions', + class: 'dropdown-end', + items: [ + { icon: '✏️', label: 'Edit', onclick: () => handleAction('Edit') }, + { icon: '📋', label: 'Copy', onclick: () => handleAction('Copy') }, + { icon: '🗑️', label: 'Delete', onclick: () => handleAction('Delete'), class: 'text-error' } + ] + }); +}; +$mount(ActionsDemo, '#demo-actions'); +``` + +### User Dropdown (Items Array) + +
+
+

Live Demo

+
+
+
+ +```javascript +const UserDropdown = () => { + return Dropdown({ + label: Span({ class: 'flex items-center gap-2' }, [ + Div({ class: 'avatar placeholder' }, [ + Div({ class: 'bg-primary text-primary-content rounded-full w-8 h-8 flex items-center justify-center text-sm' }, 'JD') + ]), + 'John Doe' + ]), + class: 'dropdown-end', + items: [ + { label: 'Profile', onclick: () => Toast('Profile', 'alert-info', 2000) }, + { label: 'Settings', onclick: () => Toast('Settings', 'alert-info', 2000) }, + { label: 'Sign Out', onclick: () => Toast('Signed out', 'alert-warning', 2000), class: 'text-error' } + ] + }); +}; +$mount(UserDropdown, '#demo-user'); +``` + +### Reactive Items + +
+
+

Live Demo

+
+
+
+ +```javascript +const ReactiveDropdown = () => { + const count = $(0); + + const items = () => [ + { label: `Count: ${count()}`, onclick: () => {} }, + { label: 'Increment', onclick: () => count(count() + 1) }, + { label: 'Decrement', onclick: () => count(count() - 1) }, + { label: 'Reset', onclick: () => count(0) } + ]; + + return Dropdown({ + label: () => `Counter (${count()})`, + items: items + }); +}; +$mount(ReactiveDropdown, '#demo-reactive'); +``` + +### Notification Dropdown (Custom Children) + +
+
+

Live Demo

+
+
+
+ +```javascript +const NotificationsDropdown = () => { + const notifications = $([ + { id: 1, title: 'New message', time: '5 min ago', read: false }, + { id: 2, title: 'Update available', time: '1 hour ago', read: false }, + { id: 3, title: 'Task completed', time: '2 hours ago', read: true } + ]); + + const markAsRead = (id) => { + notifications(notifications().map(n => + n.id === id ? { ...n, read: true } : n + )); + }; + + const unreadCount = () => notifications().filter(n => !n.read).length; + + return Dropdown({ + label: Span({ class: 'relative' }, [ + '🔔', + () => unreadCount() > 0 ? Span({ class: 'badge badge-xs badge-error absolute -top-1 -right-2' }, unreadCount()) : null + ]), + class: 'dropdown-end', + children: () => Div({ class: 'w-80' }, [ + Div({ class: 'p-3 border-b border-base-300 font-bold' }, `Notifications (${unreadCount()} unread)`), + Div({ class: 'max-h-64 overflow-y-auto' }, notifications().map(notif => + Div({ + class: `p-3 border-b border-base-300 cursor-pointer hover:bg-base-200 ${!notif.read ? 'bg-primary/5' : ''}`, + 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'); +``` + +### Custom Content Dropdown + +
+
+

Live Demo

+
+
+
+ +```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 + +
+
+

Live Demo

+
+
+
+ +```javascript +const VariantsDemo = () => { + const commonItems = [ + { label: 'Item 1', onclick: () => Toast('Item 1', 'alert-info', 2000) }, + { label: 'Item 2', onclick: () => Toast('Item 2', 'alert-info', 2000) }, + { label: 'Item 3', onclick: () => Toast('Item 3', 'alert-info', 2000) } + ]; + + return Div({ class: 'flex flex-wrap gap-4 justify-center' }, [ + Dropdown({ label: 'Default', items: commonItems }), + Dropdown({ label: 'With Icon', icon: '☰', items: commonItems }), + Dropdown({ label: 'End Position', class: 'dropdown-end', items: commonItems }) + ]); +}; +$mount(VariantsDemo, '#demo-variants'); +``` + + \ No newline at end of file diff --git a/docs/components/fab.md b/docs/components/fab.md new file mode 100644 index 0000000..c34e631 --- /dev/null +++ b/docs/components/fab.md @@ -0,0 +1,688 @@ +# Fab + +Floating Action Button (FAB) component for primary actions with expandable menu options. Each example uses a container with `position: relative` and explicit height to position the FAB correctly. + +## Tag + +`Fab` + +## Props + +| Prop | Type | Default | Description | +| :----------- | :-------------------------------------- | :--------------- | :----------------------------------------------- | +| `icon` | `string \| VNode \| Signal` | `-` | Main FAB icon | +| `label` | `string \| VNode \| Signal` | `-` | Text label for main button | +| `actions` | `Array \| Signal` | `[]` | Array of action buttons that expand from FAB | +| `position` | `string` | `'bottom-6 right-6'` | CSS position classes (e.g., 'bottom-6 left-6') | +| `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) | + +### Action Structure + +| Property | Type | Description | +| :---------- | :--------------------------- | :----------------------------------------------- | +| `label` | `string \| VNode` | Label text shown next to action button | +| `icon` | `string \| VNode` | Icon for the action button | +| `onclick` | `function` | Click handler | +| `class` | `string` | Additional CSS classes for the action button | + +## Live Examples + +### Basic FAB + +
+
+

Live Demo

+
+
+
+ +```javascript +const BasicDemo = () => { + return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [ + Fab({ + icon: '➕', + actions: [ + { icon: '📝', label: 'New Note', onclick: () => Toast('Create note', 'alert-info', 2000) }, + { icon: '📷', label: 'Take Photo', onclick: () => Toast('Open camera', 'alert-info', 2000) }, + { icon: '📎', label: 'Attach File', onclick: () => Toast('Attach file', 'alert-info', 2000) } + ] + }) + ]); +}; +$mount(BasicDemo, '#demo-basic'); +``` + +### With Label + +
+
+

Live Demo

+
+
+
+ +```javascript +const LabelDemo = () => { + return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [ + Fab({ + label: 'Create', + icon: '✨', + actions: [ + { icon: '📝', label: 'Document', onclick: () => Toast('New document', 'alert-success', 2000) }, + { icon: '🎨', label: 'Design', onclick: () => Toast('New design', 'alert-success', 2000) }, + { icon: '📊', label: 'Spreadsheet', onclick: () => Toast('New spreadsheet', 'alert-success', 2000) } + ] + }) + ]); +}; +$mount(LabelDemo, '#demo-label'); +``` + +### Different Positions + +
+
+

Live Demo

+
+
+
+ +```javascript +const PositionsDemo = () => { + const position = $('bottom-6 right-6'); + + return Div({ class: 'relative h-[500px] w-full bg-base-100 rounded-lg overflow-hidden' }, [ + Div({ class: 'absolute top-4 left-4 z-20 bg-base-200 p-2 rounded-lg shadow' }, [ + Select({ + value: position, + options: [ + { value: 'bottom-6 right-6', label: 'Bottom Right' }, + { value: 'bottom-6 left-6', label: 'Bottom Left' }, + { value: 'top-6 right-6', label: 'Top Right' }, + { value: 'top-6 left-6', label: 'Top Left' } + ], + onchange: (e) => position(e.target.value) + }) + ]), + Div({ class: 'absolute inset-0 flex items-center justify-center text-sm opacity-50 pointer-events-none' }, [ + 'FAB position changes relative to this container' + ]), + Fab({ + position: () => position(), + icon: '🧭', + actions: [ + { icon: '⬅️', label: 'Bottom Left', onclick: () => position('bottom-6 left-6') }, + { icon: '➡️', label: 'Bottom Right', onclick: () => position('bottom-6 right-6') }, + { icon: '⬆️', label: 'Top Right', onclick: () => position('top-6 right-6') }, + { icon: '⬇️', label: 'Top Left', onclick: () => position('top-6 left-6') } + ] + }) + ]); +}; +$mount(PositionsDemo, '#demo-positions'); +``` + +### Color Variants + +
+
+

Live Demo

+
+
+
+ +```javascript +const ColorsDemo = () => { + const variant = $('primary'); + + const variants = { + primary: { class: 'btn-primary', icon: '🔵' }, + secondary: { class: 'btn-secondary', icon: '🟣' }, + accent: { class: 'btn-accent', icon: '🔴' }, + info: { class: 'btn-info', icon: '🔷' }, + success: { class: 'btn-success', icon: '🟢' }, + warning: { class: 'btn-warning', icon: '🟡' }, + error: { class: 'btn-error', icon: '🔴' } + }; + + return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [ + Div({ class: 'absolute top-4 left-4 z-20 bg-base-200 p-2 rounded-lg shadow' }, [ + Select({ + value: variant, + options: Object.keys(variants).map(v => ({ value: v, label: v.charAt(0).toUpperCase() + v.slice(1) })), + onchange: (e) => variant(e.target.value) + }) + ]), + Fab({ + class: variants[variant()].class, + icon: variants[variant()].icon, + actions: [ + { icon: '📝', label: 'Action 1', onclick: () => Toast('Action 1', 'alert-info', 2000) }, + { icon: '🎨', label: 'Action 2', onclick: () => Toast('Action 2', 'alert-info', 2000) }, + { icon: '⚙️', label: 'Action 3', onclick: () => Toast('Action 3', 'alert-info', 2000) } + ] + }) + ]); +}; +$mount(ColorsDemo, '#demo-colors'); +``` + +### Reactive Actions + +
+
+

Live Demo

+
+
+
+ +```javascript +const ReactiveActions = () => { + const count = $(0); + + const actions = () => [ + { + icon: '🔢', + label: `Count: ${count()}`, + onclick: () => {} + }, + { + icon: '➕', + label: 'Increment', + onclick: () => count(count() + 1) + }, + { + icon: '➖', + label: 'Decrement', + onclick: () => count(count() - 1) + }, + { + icon: '🔄', + label: 'Reset', + onclick: () => count(0) + } + ]; + + return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [ + Fab({ + icon: () => count() > 0 ? `🔢 ${count()}` : '🎛️', + actions: actions + }) + ]); +}; +$mount(ReactiveActions, '#demo-reactive'); +``` + +### Document Actions + +
+
+

Live Demo

+
+
+
+ +```javascript +const DocumentActions = () => { + const saved = $(false); + + const handleSave = () => { + saved(true); + Toast('Document saved!', 'alert-success', 2000); + setTimeout(() => saved(false), 3000); + }; + + return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [ + Div({ class: 'absolute inset-0 flex flex-col items-center justify-center' }, [ + Div({ class: 'text-6xl mb-4' }, '📄'), + Div({ class: 'text-sm opacity-70' }, 'Untitled Document'), + () => saved() ? Div({ class: 'mt-4' }, Alert({ type: 'success', message: '✓ Saved successfully' })) : null + ]), + Fab({ + icon: '✏️', + actions: [ + { icon: '💾', label: 'Save', onclick: handleSave }, + { icon: '📋', label: 'Copy', onclick: () => Toast('Copied!', 'alert-info', 2000) }, + { icon: '✂️', label: 'Cut', onclick: () => Toast('Cut!', 'alert-info', 2000) }, + { icon: '📎', label: 'Share', onclick: () => Toast('Share dialog', 'alert-info', 2000) } + ] + }) + ]); +}; +$mount(DocumentActions, '#demo-document'); +``` + +### Messaging FAB + +
+
+

Live Demo

+
+
+
+ +```javascript +const MessagingFAB = () => { + const unread = $(3); + + return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [ + Div({ class: 'absolute inset-0 flex flex-col items-center justify-center' }, [ + Div({ class: 'text-6xl mb-4' }, '💬'), + Div({ class: 'text-sm opacity-70' }, 'Messages'), + () => unread() > 0 ? Div({ class: 'badge badge-error mt-2' }, `${unread()} unread`) : null + ]), + Fab({ + icon: () => `💬${unread() > 0 ? ` ${unread()}` : ''}`, + class: 'btn-primary', + actions: [ + { + icon: '👤', + label: 'New Message', + onclick: () => Toast('Start new conversation', 'alert-info', 2000) + }, + { + icon: '👥', + label: 'Group Chat', + onclick: () => Toast('Create group', 'alert-info', 2000) + }, + { + icon: '📞', + label: 'Voice Call', + onclick: () => Toast('Start call', 'alert-info', 2000) + }, + { + icon: '📹', + label: 'Video Call', + onclick: () => Toast('Start video call', 'alert-info', 2000) + }, + { + icon: '🔔', + label: () => `Mark as read (${unread()})`, + onclick: () => { + unread(0); + Toast('All messages read', 'alert-success', 2000); + } + } + ] + }) + ]); +}; +$mount(MessagingFAB, '#demo-messaging'); +``` + +### Flower Style FAB + +
+
+

Live Demo

+
+
+
+ +```javascript +const FlowerDemo = () => { + return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [ + Div({ class: 'absolute inset-0 flex items-center justify-center text-sm opacity-50' }, [ + 'Flower style FAB (quarter circle arrangement)' + ]), + Fab({ + icon: '🌸', + class: 'fab-flower', + actions: [ + { icon: '📷', label: 'Camera', onclick: () => Toast('Camera', 'alert-info', 2000) }, + { icon: '🎨', label: 'Gallery', onclick: () => Toast('Gallery', 'alert-info', 2000) }, + { icon: '🎤', label: 'Voice', onclick: () => Toast('Voice', 'alert-info', 2000) }, + { icon: '📍', label: 'Location', onclick: () => Toast('Location', 'alert-info', 2000) } + ] + }) + ]); +}; +$mount(FlowerDemo, '#demo-flower'); +``` + +### All Variants + +
+
+

Live Demo

+
+
+
+ +```javascript +const VariantsDemo = () => { + const actions = [ + { icon: '⭐', label: 'Favorite', onclick: () => Toast('Favorited', 'alert-info', 2000) }, + { icon: '🔔', label: 'Remind', onclick: () => Toast('Reminder set', 'alert-info', 2000) }, + { icon: '📅', label: 'Schedule', onclick: () => Toast('Scheduled', 'alert-info', 2000) } + ]; + + return Div({ class: 'relative h-[400px] w-full bg-base-100 rounded-lg overflow-hidden' }, [ + Div({ class: 'grid grid-cols-2 gap-4 p-4 h-full' }, [ + Div({ class: 'relative border rounded-lg bg-base-200' }, [ + Span({ class: 'absolute top-2 left-2 text-xs opacity-50' }, 'Primary'), + Fab({ icon: '🔵', class: 'btn-primary', actions, position: 'bottom-6 left-6' }) + ]), + Div({ class: 'relative border rounded-lg bg-base-200' }, [ + Span({ class: 'absolute top-2 left-2 text-xs opacity-50' }, 'Secondary'), + Fab({ icon: '🟣', class: 'btn-secondary', actions, position: 'bottom-6 right-6' }) + ]), + Div({ class: 'relative border rounded-lg bg-base-200' }, [ + Span({ class: 'absolute top-2 left-2 text-xs opacity-50' }, 'Accent'), + Fab({ icon: '🔴', class: 'btn-accent', actions, position: 'top-6 left-6' }) + ]), + Div({ class: 'relative border rounded-lg bg-base-200' }, [ + Span({ class: 'absolute top-2 left-2 text-xs opacity-50' }, 'Success'), + Fab({ icon: '🟢', class: 'btn-success', actions, position: 'top-6 right-6' }) + ]) + ]) + ]); +}; +$mount(VariantsDemo, '#demo-variants'); +``` + + diff --git a/docs/components/fieldset.md b/docs/components/fieldset.md new file mode 100644 index 0000000..0714f98 --- /dev/null +++ b/docs/components/fieldset.md @@ -0,0 +1,549 @@ +# Fieldset + +Fieldset component for grouping form fields with optional legend and consistent styling. + +## Tag + +`Fieldset` + +## Props + +| Prop | Type | Default | Description | +| :----------- | :--------------------------- | :---------- | :----------------------------------------------- | +| `legend` | `string \| VNode \| Signal` | `-` | Fieldset legend/title | +| `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) | +| `children` | `VNode \| Array` | Required | Form fields or content inside the fieldset | + +## Live Examples + +### Basic Fieldset + +
+
+

Live Demo

+
+
+
+ +```javascript +const BasicDemo = () => { + return Fieldset({ + legend: 'User Information', + class: 'w-full max-w-md mx-auto' + }, [ + Div({ class: 'space-y-4' }, [ + Input({ label: 'Full Name', placeholder: 'Enter your name' }), + Input({ label: 'Email', type: 'email', placeholder: 'user@example.com' }), + Input({ label: 'Phone', type: 'tel', placeholder: '+1 234 567 890' }) + ]) + ]); +}; +$mount(BasicDemo, '#demo-basic'); +``` + +### With Reactive Legend + +
+
+

Live Demo

+
+
+
+ +```javascript +const ReactiveDemo = () => { + const name = $(''); + const email = $(''); + const isValid = () => name().length > 0 && email().includes('@'); + + return Fieldset({ + legend: () => isValid() ? '✓ Valid Form' : '✗ Incomplete Form', + class: 'w-full max-w-md mx-auto' + }, [ + Div({ class: 'space-y-4' }, [ + Input({ + label: 'Full Name', + value: name, + oninput: (e) => name(e.target.value), + placeholder: 'Enter your name' + }), + Input({ + label: 'Email', + type: 'email', + value: email, + oninput: (e) => email(e.target.value), + placeholder: 'user@example.com' + }), + () => isValid() + ? Alert({ type: 'success', message: 'Form is ready to submit' }) + : Alert({ type: 'warning', message: 'Please fill all required fields' }) + ]) + ]); +}; +$mount(ReactiveDemo, '#demo-reactive'); +``` + +### Address Form + +
+
+

Live Demo

+
+
+
+ +```javascript +const AddressDemo = () => { + const address = $(''); + const city = $(''); + const zip = $(''); + const country = $('us'); + + return Fieldset({ + legend: Span({ class: 'flex items-center gap-2' }, ['📍', 'Shipping Address']), + class: 'w-full max-w-md mx-auto' + }, [ + Div({ class: 'space-y-4' }, [ + Input({ label: 'Street Address', value: address, placeholder: '123 Main St', oninput: (e) => address(e.target.value) }), + Div({ class: 'grid grid-cols-2 gap-4' }, [ + Input({ label: 'City', value: city, placeholder: 'City', oninput: (e) => city(e.target.value) }), + Input({ label: 'ZIP Code', value: zip, placeholder: 'ZIP', oninput: (e) => zip(e.target.value) }) + ]), + Select({ + label: 'Country', + value: country, + options: [ + { value: 'us', label: 'United States' }, + { value: 'ca', label: 'Canada' }, + { value: 'mx', label: 'Mexico' } + ], + onchange: (e) => country(e.target.value) + }) + ]) + ]); +}; +$mount(AddressDemo, '#demo-address'); +``` + +### Payment Method + +
+
+

Live Demo

+
+
+
+ +```javascript +const PaymentDemo = () => { + const method = $('credit'); + const cardNumber = $(''); + const expiry = $(''); + const cvv = $(''); + + return Fieldset({ + legend: Span({ class: 'flex items-center gap-2' }, ['💳', 'Payment Details']), + class: 'w-full max-w-md mx-auto' + }, [ + Div({ class: 'space-y-4' }, [ + Div({ class: 'flex gap-4' }, [ + Radio({ label: 'Credit Card', value: method, radioValue: 'credit', onclick: () => method('credit') }), + Radio({ label: 'PayPal', value: method, radioValue: 'paypal', onclick: () => method('paypal') }), + Radio({ label: 'Bank Transfer', value: method, radioValue: 'bank', onclick: () => method('bank') }) + ]), + () => method() === 'credit' ? Div({ class: 'space-y-4' }, [ + Input({ label: 'Card Number', value: cardNumber, placeholder: '1234 5678 9012 3456', oninput: (e) => cardNumber(e.target.value) }), + Div({ class: 'grid grid-cols-2 gap-4' }, [ + Input({ label: 'Expiry Date', value: expiry, placeholder: 'MM/YY', oninput: (e) => expiry(e.target.value) }), + Input({ label: 'CVV', type: 'password', value: cvv, placeholder: '123', oninput: (e) => cvv(e.target.value) }) + ]) + ]) : null, + () => method() === 'paypal' ? Alert({ type: 'info', message: 'You will be redirected to PayPal after confirming.' }) : null, + () => method() === 'bank' ? Alert({ type: 'warning', message: 'Bank transfer details will be sent via email.' }) : null + ]) + ]); +}; +$mount(PaymentDemo, '#demo-payment'); +``` + +### Preferences Panel + +
+
+

Live Demo

+
+
+
+ +```javascript +const PreferencesDemo = () => { + const theme = $('light'); + const language = $('en'); + const notifications = $(true); + + return Fieldset({ + legend: Span({ class: 'flex items-center gap-2' }, ['⚙️', 'Preferences']), + class: 'w-full max-w-md mx-auto' + }, [ + Div({ class: 'space-y-4' }, [ + Div({ class: 'form-control' }, [ + Span({ class: 'label-text mb-2' }, 'Theme'), + Div({ class: 'flex gap-4' }, [ + Radio({ label: 'Light', value: theme, radioValue: 'light', onclick: () => theme('light') }), + Radio({ label: 'Dark', value: theme, radioValue: 'dark', onclick: () => theme('dark') }), + Radio({ label: 'System', value: theme, radioValue: 'system', onclick: () => theme('system') }) + ]) + ]), + Select({ + label: 'Language', + value: language, + options: [ + { value: 'en', label: 'English' }, + { value: 'es', label: 'Español' }, + { value: 'fr', label: 'Français' } + ], + onchange: (e) => language(e.target.value) + }), + Checkbox({ + label: 'Enable notifications', + value: notifications, + onclick: () => notifications(!notifications()) + }) + ]) + ]); +}; +$mount(PreferencesDemo, '#demo-preferences'); +``` + +### Registration Form + +
+
+

Live Demo

+
+
+
+ +```javascript +const RegistrationDemo = () => { + const username = $(''); + const email = $(''); + const password = $(''); + const confirmPassword = $(''); + const accepted = $(false); + + const passwordsMatch = () => password() === confirmPassword(); + const isFormValid = () => username() && email().includes('@') && password().length >= 6 && passwordsMatch() && accepted(); + + const handleSubmit = () => { + if (isFormValid()) { + Toast('Registration successful!', 'alert-success', 2000); + } + }; + + return Fieldset({ + legend: Span({ class: 'flex items-center gap-2' }, ['📝', 'Create Account']), + class: 'w-full max-w-md mx-auto' + }, [ + Div({ class: 'space-y-4' }, [ + Input({ label: 'Username', value: username, placeholder: 'Choose a username', oninput: (e) => username(e.target.value) }), + Input({ label: 'Email', type: 'email', value: email, placeholder: 'your@email.com', oninput: (e) => email(e.target.value) }), + Input({ label: 'Password', type: 'password', value: password, placeholder: 'Min. 6 characters', oninput: (e) => password(e.target.value) }), + Input({ + label: 'Confirm Password', + type: 'password', + value: confirmPassword, + error: () => confirmPassword() && !passwordsMatch() ? 'Passwords do not match' : '', + oninput: (e) => confirmPassword(e.target.value) + }), + Checkbox({ + label: 'I accept the Terms and Conditions', + value: accepted, + onclick: () => accepted(!accepted()) + }), + () => !isFormValid() && (username() || email() || password()) ? Alert({ type: 'warning', message: 'Please complete all fields correctly' }) : null, + Button({ + class: 'btn btn-primary w-full', + onclick: handleSubmit, + disabled: () => !isFormValid() + }, 'Register') + ]) + ]); +}; +$mount(RegistrationDemo, '#demo-registration'); +``` + +### All Variants + +
+
+

Live Demo

+
+
+
+ +```javascript +const VariantsDemo = () => { + const commonContent = Div({ class: 'space-y-4' }, [ + Input({ label: 'Field 1', placeholder: 'Enter value' }), + Input({ label: 'Field 2', placeholder: 'Enter value' }), + Button({ class: 'btn btn-primary' }, 'Submit') + ]); + + return Div({ class: 'flex flex-col gap-4' }, [ + Fieldset({ legend: 'Default Fieldset', class: 'w-full' }, [commonContent]), + Fieldset({ legend: 'With Shadow', class: 'w-full shadow-lg' }, [commonContent]), + Fieldset({ legend: 'With Background', class: 'w-full bg-base-100' }, [commonContent]) + ]); +}; +$mount(VariantsDemo, '#demo-variants'); +``` + + diff --git a/docs/components/loading.md b/docs/components/loading.md new file mode 100644 index 0000000..9f5b0a4 --- /dev/null +++ b/docs/components/loading.md @@ -0,0 +1,597 @@ +# Loading + +Loading spinner component for indicating loading states with customizable size and colors. + +## Tag + +`Loading` + +## Props + +| Prop | Type | Default | Description | +| :----------- | :--------------------------- | :--------------- | :----------------------------------------------- | +| `$show` | `boolean \| Signal` | `true` | Show/hide the loading spinner | +| `class` | `string` | `''` | Additional CSS classes (DaisyUI loading variants)| + +## Live Examples + +### Basic Loading + +
+
+

Live Demo

+
+
+
+ +```javascript +const BasicDemo = () => { + return Div({ class: 'flex flex-wrap gap-8 justify-center items-center' }, [ + Loading({ $show: true, class: 'loading-spinner' }), + Loading({ $show: true, class: 'loading-dots' }), + Loading({ $show: true, class: 'loading-ring' }), + Loading({ $show: true, class: 'loading-ball' }), + Loading({ $show: true, class: 'loading-bars' }), + Loading({ $show: true, class: 'loading-infinity' }) + ]); +}; +$mount(BasicDemo, '#demo-basic'); +``` + +### Loading Sizes + +
+
+

Live Demo

+
+
+
+ +```javascript +const SizesDemo = () => { + return Div({ class: 'flex flex-wrap gap-8 justify-center items-center' }, [ + Div({ class: 'text-center' }, [ + Loading({ $show: true, class: 'loading-spinner loading-xs' }), + Div({ class: 'text-xs mt-2' }, 'Extra Small') + ]), + Div({ class: 'text-center' }, [ + Loading({ $show: true, class: 'loading-spinner loading-sm' }), + Div({ class: 'text-xs mt-2' }, 'Small') + ]), + Div({ class: 'text-center' }, [ + Loading({ $show: true, class: 'loading-spinner loading-md' }), + Div({ class: 'text-xs mt-2' }, 'Medium') + ]), + Div({ class: 'text-center' }, [ + Loading({ $show: true, class: 'loading-spinner loading-lg' }), + Div({ class: 'text-xs mt-2' }, 'Large') + ]) + ]); +}; +$mount(SizesDemo, '#demo-sizes'); +``` + +### Loading Colors + +
+
+

Live Demo

+
+
+
+ +```javascript +const ColorsDemo = () => { + return Div({ class: 'flex flex-wrap gap-8 justify-center items-center' }, [ + Loading({ $show: true, class: 'loading-spinner text-primary' }), + Loading({ $show: true, class: 'loading-spinner text-secondary' }), + Loading({ $show: true, class: 'loading-spinner text-accent' }), + Loading({ $show: true, class: 'loading-spinner text-info' }), + Loading({ $show: true, class: 'loading-spinner text-success' }), + Loading({ $show: true, class: 'loading-spinner text-warning' }), + Loading({ $show: true, class: 'loading-spinner text-error' }) + ]); +}; +$mount(ColorsDemo, '#demo-colors'); +``` + +### Button Loading State + +
+
+

Live Demo

+
+
+
+ +```javascript +const ButtonDemo = () => { + const isLoading = $(false); + + const handleClick = async () => { + isLoading(true); + await new Promise(resolve => setTimeout(resolve, 2000)); + isLoading(false); + Toast('Operation completed!', 'alert-success', 2000); + }; + + return Div({ class: 'flex flex-col gap-4 items-center' }, [ + Button({ + class: 'btn btn-primary', + loading: isLoading, + onclick: handleClick + }, 'Submit'), + Div({ class: 'text-sm opacity-70' }, 'Click the button to see loading state') + ]); +}; +$mount(ButtonDemo, '#demo-button'); +``` + +### Async Data Loading + +
+
+

Live Demo

+
+
+
+ +```javascript +const AsyncDemo = () => { + const loading = $(false); + const data = $(null); + const error = $(null); + + const loadData = async () => { + loading(true); + error(null); + data(null); + + try { + await new Promise(resolve => setTimeout(resolve, 2000)); + const result = { + users: 1234, + posts: 5678, + comments: 9012 + }; + data(result); + Toast('Data loaded successfully!', 'alert-success', 2000); + } catch (err) { + error('Failed to load data'); + Toast('Error loading data', 'alert-error', 2000); + } finally { + loading(false); + } + }; + + return Div({ class: 'flex flex-col gap-4' }, [ + Div({ class: 'flex justify-center' }, [ + Button({ + class: 'btn btn-primary', + onclick: loadData, + disabled: () => loading() + }, loading() ? 'Loading...' : 'Load Data') + ]), + Div({ class: 'relative min-h-[200px] flex items-center justify-center' }, [ + () => loading() ? Loading({ $show: true, class: 'loading-spinner loading-lg' }) : null, + () => data() ? Div({ class: 'grid grid-cols-3 gap-4 w-full' }, [ + Div({ class: 'stat' }, [ + Div({ class: 'stat-title' }, 'Users'), + Div({ class: 'stat-value' }, data().users) + ]), + Div({ class: 'stat' }, [ + Div({ class: 'stat-title' }, 'Posts'), + Div({ class: 'stat-value' }, data().posts) + ]), + Div({ class: 'stat' }, [ + Div({ class: 'stat-title' }, 'Comments'), + Div({ class: 'stat-value' }, data().comments) + ]) + ]) : null, + () => error() ? Alert({ type: 'error', message: error() }) : null + ]) + ]); +}; +$mount(AsyncDemo, '#demo-async'); +``` + +### Full Page Loading + +
+
+

Live Demo

+
+
+
+ +```javascript +const FullpageDemo = () => { + const isLoading = $(false); + + const simulatePageLoad = () => { + isLoading(true); + setTimeout(() => { + isLoading(false); + Toast('Page loaded!', 'alert-success', 2000); + }, 2000); + }; + + return Div({ class: 'relative' }, [ + Div({ class: 'flex justify-center p-8' }, [ + Button({ + class: 'btn btn-primary', + onclick: simulatePageLoad + }, 'Simulate Page Load') + ]), + () => isLoading() ? Loading({ $show: true, class: 'loading-spinner loading-lg' }) : null + ]); +}; +$mount(FullpageDemo, '#demo-fullpage'); +``` + +### Conditional Loading + +
+
+

Live Demo

+
+
+
+ +```javascript +const ConditionalDemo = () => { + const loadingState = $('idle'); + const content = $(''); + + const simulateAction = (action) => { + loadingState('loading'); + setTimeout(() => { + content(`Action: ${action} completed at ${new Date().toLocaleTimeString()}`); + loadingState('success'); + setTimeout(() => loadingState('idle'), 1500); + }, 1500); + }; + + const loadingStates = { + idle: null, + loading: Loading({ $show: true, class: 'loading-spinner text-primary' }), + success: Alert({ type: 'success', message: '✓ Done!' }) + }; + + return Div({ class: 'flex flex-col gap-4' }, [ + Div({ class: 'flex gap-2 justify-center' }, [ + Button({ + class: 'btn btn-sm', + onclick: () => simulateAction('Save') + }, 'Save'), + Button({ + class: 'btn btn-sm', + onclick: () => simulateAction('Update') + }, 'Update'), + Button({ + class: 'btn btn-sm', + onclick: () => simulateAction('Delete') + }, 'Delete') + ]), + Div({ class: 'flex justify-center min-h-[100px] items-center' }, [ + () => loadingStates[loadingState()], + () => content() && loadingState() === 'idle' ? Div({ class: 'text-center' }, content()) : null + ]) + ]); +}; +$mount(ConditionalDemo, '#demo-conditional'); +``` + +### All Variants + +
+
+

Live Demo

+
+
+
+ +```javascript +const VariantsDemo = () => { + return Div({ class: 'flex flex-col gap-6' }, [ + Div({ class: 'text-center' }, [ + Div({ class: 'text-sm font-bold mb-2' }, 'Spinner'), + Div({ class: 'flex gap-4 justify-center' }, [ + Loading({ $show: true, class: 'loading-spinner loading-xs' }), + Loading({ $show: true, class: 'loading-spinner loading-sm' }), + Loading({ $show: true, class: 'loading-spinner loading-md' }), + Loading({ $show: true, class: 'loading-spinner loading-lg' }) + ]) + ]), + Div({ class: 'text-center' }, [ + Div({ class: 'text-sm font-bold mb-2' }, 'Dots'), + Div({ class: 'flex gap-4 justify-center' }, [ + Loading({ $show: true, class: 'loading-dots loading-xs' }), + Loading({ $show: true, class: 'loading-dots loading-sm' }), + Loading({ $show: true, class: 'loading-dots loading-md' }), + Loading({ $show: true, class: 'loading-dots loading-lg' }) + ]) + ]), + Div({ class: 'text-center' }, [ + Div({ class: 'text-sm font-bold mb-2' }, 'Ring'), + Div({ class: 'flex gap-4 justify-center' }, [ + Loading({ $show: true, class: 'loading-ring loading-xs' }), + Loading({ $show: true, class: 'loading-ring loading-sm' }), + Loading({ $show: true, class: 'loading-ring loading-md' }), + Loading({ $show: true, class: 'loading-ring loading-lg' }) + ]) + ]) + ]); +}; +$mount(VariantsDemo, '#demo-variants'); +``` + + diff --git a/docs/components/menu.md b/docs/components/menu.md new file mode 100644 index 0000000..21c33c7 --- /dev/null +++ b/docs/components/menu.md @@ -0,0 +1,760 @@ +# Menu + +Menu component for creating navigation menus, sidebars, and dropdowns with support for nested items, icons, and active states. + +## Tag + +`Menu` + +## Props + +| Prop | Type | Default | Description | +| :----------- | :-------------------------------------- | :---------- | :----------------------------------------------- | +| `items` | `Array` | `[]` | Menu items configuration | +| `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) | + +### MenuItem Structure + +| Property | Type | Description | +| :---------- | :--------------------------- | :----------------------------------------------- | +| `label` | `string \| VNode` | Menu item text or content | +| `icon` | `string \| VNode` | Optional icon to display | +| `active` | `boolean \| Signal` | Active state highlighting | +| `onclick` | `function` | Click handler | +| `children` | `Array` | Nested submenu items | +| `open` | `boolean` | Whether submenu is open (for nested items) | + +## Live Examples + +### Basic Menu + +
+
+

Live Demo

+
+
+
+ +```javascript +const BasicDemo = () => { + const activeItem = $('home'); + + return Menu({ + items: [ + { + label: 'Home', + active: () => activeItem() === 'home', + onclick: () => activeItem('home') + }, + { + label: 'About', + active: () => activeItem() === 'about', + onclick: () => activeItem('about') + }, + { + label: 'Contact', + active: () => activeItem() === 'contact', + onclick: () => activeItem('contact') + } + ] + }); +}; +$mount(BasicDemo, '#demo-basic'); +``` + +### With Icons + +
+
+

Live Demo

+
+
+
+ +```javascript +const IconsDemo = () => { + const activeItem = $('dashboard'); + + return Menu({ + items: [ + { + icon: '🏠', + label: 'Dashboard', + active: () => activeItem() === 'dashboard', + onclick: () => activeItem('dashboard') + }, + { + icon: '📊', + label: 'Analytics', + active: () => activeItem() === 'analytics', + onclick: () => activeItem('analytics') + }, + { + icon: '⚙️', + label: 'Settings', + active: () => activeItem() === 'settings', + onclick: () => activeItem('settings') + }, + { + icon: '👤', + label: 'Profile', + active: () => activeItem() === 'profile', + onclick: () => activeItem('profile') + } + ] + }); +}; +$mount(IconsDemo, '#demo-icons'); +``` + +### Nested Menu + +
+
+

Live Demo

+
+
+
+ +```javascript +const NestedDemo = () => { + const activeItem = $('products'); + + return Menu({ + items: [ + { + label: 'Dashboard', + onclick: () => activeItem('dashboard'), + active: () => activeItem() === 'dashboard' + }, + { + label: 'Products', + icon: '📦', + open: true, + children: [ + { + label: 'All Products', + onclick: () => activeItem('all-products'), + active: () => activeItem() === 'all-products' + }, + { + label: 'Add New', + onclick: () => activeItem('add-product'), + active: () => activeItem() === 'add-product' + }, + { + label: 'Categories', + children: [ + { + label: 'Electronics', + onclick: () => activeItem('electronics'), + active: () => activeItem() === 'electronics' + }, + { + label: 'Clothing', + onclick: () => activeItem('clothing'), + active: () => activeItem() === 'clothing' + } + ] + } + ] + }, + { + label: 'Orders', + icon: '📋', + onclick: () => activeItem('orders'), + active: () => activeItem() === 'orders' + }, + { + label: 'Settings', + icon: '⚙️', + onclick: () => activeItem('settings'), + active: () => activeItem() === 'settings' + } + ] + }); +}; +$mount(NestedDemo, '#demo-nested'); +``` + +### Horizontal Menu + +
+
+

Live Demo

+
+
+
+ +```javascript +const HorizontalDemo = () => { + const activeItem = $('home'); + + return Menu({ + class: 'menu-horizontal rounded-box', + items: [ + { + label: 'Home', + active: () => activeItem() === 'home', + onclick: () => activeItem('home') + }, + { + label: 'Products', + children: [ + { label: 'Electronics', onclick: () => activeItem('electronics') }, + { label: 'Clothing', onclick: () => activeItem('clothing') }, + { label: 'Books', onclick: () => activeItem('books') } + ] + }, + { + label: 'About', + onclick: () => activeItem('about'), + active: () => activeItem() === 'about' + }, + { + label: 'Contact', + onclick: () => activeItem('contact'), + active: () => activeItem() === 'contact' + } + ] + }); +}; +$mount(HorizontalDemo, '#demo-horizontal'); +``` + +### Sidebar Menu + +
+
+

Live Demo

+
+
+
+ +```javascript +const SidebarDemo = () => { + const activeItem = $('dashboard'); + + return Div({ class: 'flex' }, [ + Div({ class: 'w-64' }, [ + Menu({ + class: 'rounded-box w-full', + items: [ + { + icon: '📊', + label: 'Dashboard', + active: () => activeItem() === 'dashboard', + onclick: () => activeItem('dashboard') + }, + { + icon: '👥', + label: 'Users', + children: [ + { + label: 'All Users', + onclick: () => activeItem('all-users'), + active: () => activeItem() === 'all-users' + }, + { + label: 'Add User', + onclick: () => activeItem('add-user'), + active: () => activeItem() === 'add-user' + } + ] + }, + { + icon: '📁', + label: 'Files', + onclick: () => activeItem('files'), + active: () => activeItem() === 'files' + }, + { + icon: '⚙️', + label: 'Settings', + onclick: () => activeItem('settings'), + active: () => activeItem() === 'settings' + } + ] + }) + ]), + Div({ class: 'flex-1 p-4' }, [ + Div({ class: 'alert alert-info' }, () => `Current page: ${activeItem()}`) + ]) + ]); +}; +$mount(SidebarDemo, '#demo-sidebar'); +``` + +### Account Menu + +
+
+

Live Demo

+
+
+
+ +```javascript +const AccountDemo = () => { + const [notifications, setNotifications] = $(3); + + return Menu({ + class: 'rounded-box w-56', + items: [ + { + icon: '👤', + label: 'My Profile', + onclick: () => Toast('Profile clicked', 'alert-info', 2000) + }, + { + icon: '📧', + label: 'Messages', + badge: '3', + onclick: () => Toast('Messages opened', 'alert-info', 2000) + }, + { + icon: '🔔', + label: 'Notifications', + badge: () => notifications(), + onclick: () => { + setNotifications(0); + Toast('Notifications cleared', 'alert-success', 2000); + } + }, + { + icon: '⚙️', + label: 'Settings', + onclick: () => Toast('Settings opened', 'alert-info', 2000) + }, + { + icon: '🚪', + label: 'Logout', + onclick: () => Toast('Logged out', 'alert-warning', 2000) + } + ] + }); +}; +$mount(AccountDemo, '#demo-account'); +``` + +### Collapsible Sidebar + +
+
+

Live Demo

+
+
+
+ +```javascript +const CollapsibleDemo = () => { + const collapsed = $(false); + const activeItem = $('dashboard'); + + return Div({ class: 'flex gap-4' }, [ + Div({ class: `transition-all duration-300 ${collapsed() ? 'w-16' : 'w-64'}` }, [ + Button({ + class: 'btn btn-ghost btn-sm mb-2 w-full', + onclick: () => collapsed(!collapsed()) + }, collapsed() ? '→' : '←'), + Menu({ + class: `rounded-box ${collapsed() ? 'menu-compact' : ''}`, + items: [ + { icon: '📊', label: collapsed() ? '' : 'Dashboard', active: () => activeItem() === 'dashboard', onclick: () => activeItem('dashboard') }, + { icon: '👥', label: collapsed() ? '' : 'Users', active: () => activeItem() === 'users', onclick: () => activeItem('users') }, + { icon: '📁', label: collapsed() ? '' : 'Files', active: () => activeItem() === 'files', onclick: () => activeItem('files') }, + { icon: '⚙️', label: collapsed() ? '' : 'Settings', active: () => activeItem() === 'settings', onclick: () => activeItem('settings') } + ] + }) + ]), + Div({ class: 'flex-1' }, [ + Div({ class: 'alert alert-info' }, () => `Selected: ${activeItem()}`) + ]) + ]); +}; +$mount(CollapsibleDemo, '#demo-collapsible'); +``` + +### All Variants + +
+
+

Live Demo

+
+
+
+ +```javascript +const VariantsDemo = () => { + const items = [ + { label: 'Item 1' }, + { label: 'Item 2' }, + { label: 'Item 3', children: [ + { label: 'Subitem 1' }, + { label: 'Subitem 2' } + ]} + ]; + + return Div({ class: 'flex flex-wrap gap-8' }, [ + Div({ class: 'w-48' }, [ + Div({ class: 'text-sm font-bold mb-2' }, 'Default'), + Menu({ items }) + ]), + Div({ class: 'w-48' }, [ + Div({ class: 'text-sm font-bold mb-2' }, 'Compact'), + Menu({ items, class: 'menu-compact' }) + ]), + Div({ class: 'w-48' }, [ + Div({ class: 'text-sm font-bold mb-2' }, 'With Shadow'), + Menu({ items, class: 'shadow-lg' }) + ]) + ]); +}; +$mount(VariantsDemo, '#demo-variants'); +``` + + diff --git a/docs/components/navbar.md b/docs/components/navbar.md new file mode 100644 index 0000000..292c80d --- /dev/null +++ b/docs/components/navbar.md @@ -0,0 +1,551 @@ +# Navbar + +Navigation bar component for creating responsive headers with logo, navigation links, and actions. + +## Tag + +`Navbar` + +## Props + +| Prop | Type | Default | Description | +| :----------- | :--------------------------- | :---------- | :----------------------------------------------- | +| `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) | +| `children` | `VNode \| Array` | `-` | Navbar content (should contain left, center, right sections) | + +## Live Examples + +### Basic Navbar + +
+
+

Live Demo

+
+
+
+ +```javascript +const BasicDemo = () => { + return Navbar({ class: 'rounded-box' }, [ + Div({ class: 'navbar-start' }, [ + Span({ class: 'text-xl font-bold' }, 'Logo') + ]), + Div({ class: 'navbar-center hidden lg:flex' }, [ + Span({ class: 'text-sm' }, 'Navigation Items') + ]), + Div({ class: 'navbar-end' }, [ + Button({ class: 'btn btn-ghost btn-sm' }, 'Login') + ]) + ]); +}; +$mount(BasicDemo, '#demo-basic'); +``` + +### With Navigation Links + +
+
+

Live Demo

+ +
+
+ +```javascript +const LinksDemo = () => { + const active = $('home'); + + return Navbar({ class: 'rounded-box' }, [ + Div({ class: 'navbar-start' }, [ + Span({ class: 'text-xl font-bold' }, 'MyApp') + ]), + Div({ class: 'navbar-center hidden lg:flex' }, [ + Div({ class: 'menu menu-horizontal px-1' }, [ + Button({ + class: `btn btn-ghost btn-sm ${active() === 'home' ? 'btn-active' : ''}`, + onclick: () => active('home') + }, 'Home'), + Button({ + class: `btn btn-ghost btn-sm ${active() === 'about' ? 'btn-active' : ''}`, + onclick: () => active('about') + }, 'About'), + Button({ + class: `btn btn-ghost btn-sm ${active() === 'contact' ? 'btn-active' : ''}`, + onclick: () => active('contact') + }, 'Contact') + ]) + ]), + Div({ class: 'navbar-end' }, [ + Button({ class: 'btn btn-primary btn-sm' }, 'Sign Up') + ]) + ]); +}; +$mount(LinksDemo, '#demo-links'); +``` + +### With Dropdown Menu + +
+
+

Live Demo

+
+
+
+ +```javascript +const DropdownDemo = () => { + return Navbar({ class: 'rounded-box' }, [ + Div({ class: 'navbar-start' }, [ + Div({ class: 'dropdown' }, [ + Div({ tabindex: 0, role: 'button', class: 'btn btn-ghost lg:hidden' }, [ + Span({ class: 'sr-only' }, 'Open menu'), + Icons.iconInfo + ]), + Div({ tabindex: 0, class: 'dropdown-content menu bg-base-100 rounded-box z-[1] w-52 p-2 shadow' }, [ + Div({ class: 'menu-item' }, 'Home'), + Div({ class: 'menu-item' }, 'About'), + Div({ class: 'menu-item' }, 'Contact') + ]) + ]), + Span({ class: 'text-xl font-bold' }, 'MyApp') + ]), + Div({ class: 'navbar-center hidden lg:flex' }, [ + Div({ class: 'menu menu-horizontal px-1' }, [ + Div({ class: 'menu-item' }, 'Home'), + Div({ class: 'menu-item' }, 'About'), + Div({ class: 'menu-item' }, 'Contact') + ]) + ]), + Div({ class: 'navbar-end' }, [ + Button({ class: 'btn btn-primary btn-sm' }, 'Login') + ]) + ]); +}; +$mount(DropdownDemo, '#demo-dropdown'); +``` + +### With Search + +
+
+

Live Demo

+ +
+
+ +```javascript +const SearchDemo = () => { + const searchQuery = $(''); + + return Navbar({ class: 'rounded-box' }, [ + Div({ class: 'navbar-start' }, [ + Span({ class: 'text-xl font-bold' }, 'MyApp') + ]), + Div({ class: 'navbar-center' }, [ + Div({ class: 'form-control' }, [ + Input({ + placeholder: 'Search...', + value: searchQuery, + class: 'input input-bordered w-48 md:w-auto', + oninput: (e) => searchQuery(e.target.value) + }) + ]) + ]), + Div({ class: 'navbar-end' }, [ + Button({ class: 'btn btn-ghost btn-circle' }, '🔔'), + Button({ class: 'btn btn-ghost btn-circle' }, '👤') + ]) + ]); +}; +$mount(SearchDemo, '#demo-search'); +``` + +### With Avatar and Dropdown + +
+
+

Live Demo

+
+
+
+ +```javascript +const AvatarDemo = () => { + return Navbar({ class: 'rounded-box' }, [ + Div({ class: 'navbar-start' }, [ + Span({ class: 'text-xl font-bold' }, 'MyApp') + ]), + Div({ class: 'navbar-center hidden lg:flex' }, [ + Div({ class: 'menu menu-horizontal px-1' }, [ + Div({ class: 'menu-item' }, 'Dashboard'), + Div({ class: 'menu-item' }, 'Projects'), + Div({ class: 'menu-item' }, 'Tasks') + ]) + ]), + Div({ class: 'navbar-end' }, [ + Div({ class: 'dropdown dropdown-end' }, [ + Div({ tabindex: 0, role: 'button', class: 'btn btn-ghost btn-circle avatar' }, [ + Div({ class: 'w-8 rounded-full bg-primary text-primary-content flex items-center justify-center' }, 'JD') + ]), + Div({ tabindex: 0, class: 'dropdown-content menu bg-base-100 rounded-box z-[1] w-52 p-2 shadow' }, [ + Div({ class: 'menu-item' }, 'Profile'), + Div({ class: 'menu-item' }, 'Settings'), + Div({ class: 'menu-item' }, 'Logout') + ]) + ]) + ]) + ]); +}; +$mount(AvatarDemo, '#demo-avatar'); +``` + +### Responsive Navbar + +
+
+

Live Demo

+
+
+
+ +```javascript +const ResponsiveDemo = () => { + const isOpen = $(false); + + return Div({ class: 'flex flex-col' }, [ + Navbar({ class: 'rounded-box' }, [ + Div({ class: 'navbar-start' }, [ + Button({ + class: 'btn btn-ghost btn-circle lg:hidden', + onclick: () => isOpen(!isOpen()) + }, '☰') + ]), + Div({ class: 'navbar-center' }, [ + Span({ class: 'text-xl font-bold' }, 'MyApp') + ]), + Div({ class: 'navbar-end' }, [ + Button({ class: 'btn btn-ghost btn-circle' }, '🔔') + ]) + ]), + () => isOpen() ? Div({ class: 'flex flex-col gap-2 p-4 bg-base-200 rounded-box mt-2' }, [ + Button({ class: 'btn btn-ghost justify-start' }, 'Home'), + Button({ class: 'btn btn-ghost justify-start' }, 'About'), + Button({ class: 'btn btn-ghost justify-start' }, 'Services'), + Button({ class: 'btn btn-ghost justify-start' }, 'Contact') + ]) : null + ]); +}; +$mount(ResponsiveDemo, '#demo-responsive'); +``` + +### With Brand and Actions + +
+
+

Live Demo

+
+
+
+ +```javascript +const BrandDemo = () => { + return Navbar({ class: 'rounded-box bg-primary text-primary-content' }, [ + Div({ class: 'navbar-start' }, [ + Span({ class: 'text-xl font-bold' }, 'Brand') + ]), + Div({ class: 'navbar-center hidden lg:flex' }, [ + Div({ class: 'menu menu-horizontal px-1' }, [ + Span({ class: 'text-sm' }, 'Features'), + Span({ class: 'text-sm' }, 'Pricing'), + Span({ class: 'text-sm' }, 'About') + ]) + ]), + Div({ class: 'navbar-end' }, [ + Button({ class: 'btn btn-ghost btn-sm' }, 'Login'), + Button({ class: 'btn btn-outline btn-sm ml-2' }, 'Sign Up') + ]) + ]); +}; +$mount(BrandDemo, '#demo-brand'); +``` + +### All Variants + +
+
+

Live Demo

+
+
+
+ +```javascript +const VariantsDemo = () => { + return Div({ class: 'flex flex-col gap-4' }, [ + Div({ class: 'text-sm font-bold' }, 'Default Navbar'), + Navbar({ class: 'rounded-box' }, [ + Div({ class: 'navbar-start' }, [Span({}, 'Start')]), + Div({ class: 'navbar-center' }, [Span({}, 'Center')]), + Div({ class: 'navbar-end' }, [Span({}, 'End')]) + ]), + + Div({ class: 'text-sm font-bold mt-2' }, 'With Shadow'), + Navbar({ class: 'rounded-box shadow-lg' }, [ + Div({ class: 'navbar-start' }, [Span({}, 'Logo')]), + Div({ class: 'navbar-end' }, [Button({ class: 'btn btn-sm' }, 'Button')]) + ]), + + Div({ class: 'text-sm font-bold mt-2' }, 'With Background'), + Navbar({ class: 'rounded-box bg-base-300' }, [ + Div({ class: 'navbar-start' }, [Span({ class: 'font-bold' }, 'Colored')]), + Div({ class: 'navbar-end' }, [Span({ class: 'text-sm' }, 'Info')]) + ]) + ]); +}; +$mount(VariantsDemo, '#demo-variants'); +``` + + diff --git a/docs/components/tabs.md b/docs/components/tabs.md new file mode 100644 index 0000000..2a58797 --- /dev/null +++ b/docs/components/tabs.md @@ -0,0 +1,677 @@ +# Tabs + +Tabs component for organizing content into separate panels with tab navigation. + +## Tag + +`Tabs` + +## Props + +| Prop | Type | Default | Description | +| :----------- | :-------------------------------------- | :---------- | :----------------------------------------------- | +| `items` | `Array \| Signal` | `[]` | Array of tab items | +| `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) | + +### TabItem Structure + +| Property | Type | Description | +| :---------- | :--------------------------- | :----------------------------------------------- | +| `label` | `string \| VNode` | Tab button label | +| `content` | `VNode \| function` | Content to display when tab is active | +| `active` | `boolean \| Signal` | Whether this tab is active (only one per group) | +| `disabled` | `boolean` | Whether tab is disabled | +| `tip` | `string` | Tooltip text for the tab | +| `onclick` | `function` | Click handler (optional, overrides default) | + +## Live Examples + +### Basic Tabs + +
+
+

Live Demo

+
+
+
+ +```javascript +const BasicDemo = () => { + const activeTab = $('tab1'); + + return Tabs({ + items: [ + { + label: 'Tab 1', + active: () => activeTab() === 'tab1', + onclick: () => activeTab('tab1'), + content: Div({ class: 'p-4' }, 'Content for Tab 1') + }, + { + label: 'Tab 2', + active: () => activeTab() === 'tab2', + onclick: () => activeTab('tab2'), + content: Div({ class: 'p-4' }, 'Content for Tab 2') + }, + { + label: 'Tab 3', + active: () => activeTab() === 'tab3', + onclick: () => activeTab('tab3'), + content: Div({ class: 'p-4' }, 'Content for Tab 3') + } + ] + }); +}; +$mount(BasicDemo, '#demo-basic'); +``` + +### With Icons + +
+
+

Live Demo

+
+
+
+ +```javascript +const IconsDemo = () => { + const activeTab = $('home'); + + return Tabs({ + items: [ + { + label: Span({ class: 'flex items-center gap-2' }, ['🏠', 'Home']), + active: () => activeTab() === 'home', + onclick: () => activeTab('home'), + content: Div({ class: 'p-4' }, 'Welcome to the Home tab!') + }, + { + label: Span({ class: 'flex items-center gap-2' }, ['⭐', 'Favorites']), + active: () => activeTab() === 'favorites', + onclick: () => activeTab('favorites'), + content: Div({ class: 'p-4' }, 'Your favorite items appear here.') + }, + { + label: Span({ class: 'flex items-center gap-2' }, ['⚙️', 'Settings']), + active: () => activeTab() === 'settings', + onclick: () => activeTab('settings'), + content: Div({ class: 'p-4' }, 'Configure your preferences.') + } + ] + }); +}; +$mount(IconsDemo, '#demo-icons'); +``` + +### With Tooltips + +
+
+

Live Demo

+
+
+
+ +```javascript +const TooltipsDemo = () => { + const activeTab = $('profile'); + + return Tabs({ + items: [ + { + label: 'Profile', + tip: 'View your profile information', + active: () => activeTab() === 'profile', + onclick: () => activeTab('profile'), + content: Div({ class: 'p-4' }, 'Profile information here.') + }, + { + label: 'Settings', + tip: 'Adjust your preferences', + active: () => activeTab() === 'settings', + onclick: () => activeTab('settings'), + content: Div({ class: 'p-4' }, 'Settings configuration.') + }, + { + label: 'Notifications', + tip: 'Manage notifications', + active: () => activeTab() === 'notifications', + onclick: () => activeTab('notifications'), + content: Div({ class: 'p-4' }, 'Notification settings.') + } + ] + }); +}; +$mount(TooltipsDemo, '#demo-tooltips'); +``` + +### Disabled Tab + +
+
+

Live Demo

+
+
+
+ +```javascript +const DisabledDemo = () => { + const activeTab = $('basic'); + + return Tabs({ + items: [ + { + label: 'Basic', + active: () => activeTab() === 'basic', + onclick: () => activeTab('basic'), + content: Div({ class: 'p-4' }, 'Basic features available.') + }, + { + label: 'Premium', + disabled: true, + tip: 'Upgrade to access', + content: Div({ class: 'p-4' }, 'Premium content (locked)') + }, + { + label: 'Pro', + disabled: true, + tip: 'Coming soon', + content: Div({ class: 'p-4' }, 'Pro features (coming soon)') + } + ] + }); +}; +$mount(DisabledDemo, '#demo-disabled'); +``` + +### Reactive Content + +
+
+

Live Demo

+
+
+
+ +```javascript +const ReactiveDemo = () => { + const activeTab = $('counter'); + const count = $(0); + + return Tabs({ + items: [ + { + label: 'Counter', + active: () => activeTab() === 'counter', + onclick: () => activeTab('counter'), + content: Div({ class: 'p-4 text-center' }, [ + Div({ class: 'text-4xl font-bold mb-4' }, () => count()), + Button({ + class: 'btn btn-primary', + onclick: () => count(count() + 1) + }, 'Increment') + ]) + }, + { + label: 'Timer', + active: () => activeTab() === 'timer', + onclick: () => activeTab('timer'), + content: Div({ class: 'p-4' }, () => `Current time: ${new Date().toLocaleTimeString()}`) + }, + { + label: 'Status', + active: () => activeTab() === 'status', + onclick: () => activeTab('status'), + content: Div({ class: 'p-4' }, () => `Counter value: ${count()}, Last updated: ${new Date().toLocaleTimeString()}`) + } + ] + }); +}; +$mount(ReactiveDemo, '#demo-reactive'); +``` + +### Form Tabs + +
+
+

Live Demo

+
+
+
+ +```javascript +const FormTabs = () => { + const activeTab = $('personal'); + const formData = $({ + name: '', + email: '', + address: '', + city: '', + notifications: true, + newsletter: false + }); + + const updateField = (field, value) => { + formData({ ...formData(), [field]: value }); + }; + + const handleSubmit = () => { + Toast('Form submitted!', 'alert-success', 2000); + console.log(formData()); + }; + + return Div({ class: 'flex flex-col gap-4' }, [ + Tabs({ + items: [ + { + label: 'Personal Info', + active: () => activeTab() === 'personal', + onclick: () => activeTab('personal'), + content: Div({ class: 'p-4 space-y-4' }, [ + Input({ + label: 'Name', + value: () => formData().name, + placeholder: 'Enter your name', + oninput: (e) => updateField('name', e.target.value) + }), + Input({ + label: 'Email', + type: 'email', + value: () => formData().email, + placeholder: 'email@example.com', + oninput: (e) => updateField('email', e.target.value) + }) + ]) + }, + { + label: 'Address', + active: () => activeTab() === 'address', + onclick: () => activeTab('address'), + content: Div({ class: 'p-4 space-y-4' }, [ + Input({ + label: 'Address', + value: () => formData().address, + placeholder: 'Street address', + oninput: (e) => updateField('address', e.target.value) + }), + Input({ + label: 'City', + value: () => formData().city, + placeholder: 'City', + oninput: (e) => updateField('city', e.target.value) + }) + ]) + }, + { + label: 'Preferences', + active: () => activeTab() === 'prefs', + onclick: () => activeTab('prefs'), + content: Div({ class: 'p-4 space-y-4' }, [ + Checkbox({ + label: 'Email notifications', + value: () => formData().notifications, + onclick: () => updateField('notifications', !formData().notifications) + }), + Checkbox({ + label: 'Newsletter subscription', + value: () => formData().newsletter, + onclick: () => updateField('newsletter', !formData().newsletter) + }) + ]) + } + ] + }), + Div({ class: 'flex justify-end mt-4' }, [ + Button({ + class: 'btn btn-primary', + onclick: handleSubmit + }, 'Submit') + ]) + ]); +}; +$mount(FormTabs, '#demo-form'); +``` + +### All Variants + +
+
+

Live Demo

+
+
+
+ +```javascript +const VariantsDemo = () => { + const items = [ + { label: 'Tab 1', content: 'Content 1' }, + { label: 'Tab 2', content: 'Content 2' }, + { label: 'Tab 3', content: 'Content 3' } + ].map((tab, idx) => ({ + ...tab, + active: () => idx === 0, + content: Div({ class: 'p-4' }, tab.content) + })); + + return Div({ class: 'flex flex-col gap-6' }, [ + Div({ class: 'text-sm font-bold' }, 'Default Tabs'), + Tabs({ items }), + + Div({ class: 'text-sm font-bold mt-4' }, 'Boxed Tabs'), + Tabs({ items, class: 'tabs-box' }), + + Div({ class: 'text-sm font-bold mt-4' }, 'Lifted Tabs'), + Tabs({ items, class: 'tabs-lifted' }) + ]); +}; +$mount(VariantsDemo, '#demo-variants'); +``` + + diff --git a/docs/components/tooltip.md b/docs/components/tooltip.md new file mode 100644 index 0000000..053960b --- /dev/null +++ b/docs/components/tooltip.md @@ -0,0 +1,554 @@ +# Tooltip + +Tooltip component for displaying helpful hints and additional information on hover. + +## Tag + +`Tooltip` + +## Props + +| Prop | Type | Default | Description | +| :----------- | :--------------------------- | :---------- | :----------------------------------------------- | +| `tip` | `string \| VNode \| Signal` | `-` | Tooltip content to display on hover | +| `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) | +| `children` | `VNode` | `-` | Element to attach the tooltip to | + +## Live Examples + +### Basic Tooltip + +
+
+

Live Demo

+
+
+
+ +```javascript +const BasicDemo = () => { + return Div({ class: 'flex flex-wrap gap-4 justify-center' }, [ + Tooltip({ tip: 'This is a tooltip' }, [ + Button({ class: 'btn btn-primary' }, 'Hover me') + ]), + Tooltip({ tip: 'Tooltips can be placed on any element' }, [ + Span({ class: 'text-sm cursor-help border-b border-dashed' }, 'Help text') + ]), + Tooltip({ tip: 'Icons can also have tooltips' }, [ + Icons.iconInfo + ]) + ]); +}; +$mount(BasicDemo, '#demo-basic'); +``` + +### Tooltip Positions + +
+
+

Live Demo

+
+
+
+ +```javascript +const PositionsDemo = () => { + return Div({ class: 'flex flex-wrap gap-8 justify-center' }, [ + Tooltip({ tip: 'Top tooltip', class: 'tooltip-top' }, [ + Button({ class: 'btn btn-sm' }, 'Top') + ]), + Tooltip({ tip: 'Bottom tooltip', class: 'tooltip-bottom' }, [ + Button({ class: 'btn btn-sm' }, 'Bottom') + ]), + Tooltip({ tip: 'Left tooltip', class: 'tooltip-left' }, [ + Button({ class: 'btn btn-sm' }, 'Left') + ]), + Tooltip({ tip: 'Right tooltip', class: 'tooltip-right' }, [ + Button({ class: 'btn btn-sm' }, 'Right') + ]) + ]); +}; +$mount(PositionsDemo, '#demo-positions'); +``` + +### Tooltip with Icons + +
+
+

Live Demo

+
+
+
+ +```javascript +const IconsDemo = () => { + return Div({ class: 'flex flex-wrap gap-8 justify-center' }, [ + Tooltip({ tip: 'Save document' }, [ + Button({ class: 'btn btn-ghost btn-circle' }, '💾') + ]), + Tooltip({ tip: 'Edit item' }, [ + Button({ class: 'btn btn-ghost btn-circle' }, '✏️') + ]), + Tooltip({ tip: 'Delete permanently' }, [ + Button({ class: 'btn btn-ghost btn-circle text-error' }, '🗑️') + ]), + Tooltip({ tip: 'Settings' }, [ + Button({ class: 'btn btn-ghost btn-circle' }, '⚙️') + ]) + ]); +}; +$mount(IconsDemo, '#demo-icons'); +``` + +### Form Field Tooltips + +
+
+

Live Demo

+
+
+
+ +```javascript +const FormDemo = () => { + const username = $(''); + const email = $(''); + + return Div({ class: 'flex flex-col gap-4 max-w-md mx-auto' }, [ + Div({ class: 'flex items-center gap-2' }, [ + Input({ + label: 'Username', + value: username, + placeholder: 'Choose a username', + oninput: (e) => username(e.target.value) + }), + Tooltip({ tip: 'Must be at least 3 characters, letters and numbers only' }, [ + Span({ class: 'cursor-help text-info' }, '?') + ]) + ]), + Div({ class: 'flex items-center gap-2' }, [ + Input({ + label: 'Email', + type: 'email', + value: email, + placeholder: 'Enter your email', + oninput: (e) => email(e.target.value) + }), + Tooltip({ tip: 'We\'ll never share your email with anyone' }, [ + Span({ class: 'cursor-help text-info' }, '?') + ]) + ]) + ]); +}; +$mount(FormDemo, '#demo-form'); +``` + +### Interactive Tooltip + +
+
+

Live Demo

+
+
+
+ +```javascript +const InteractiveDemo = () => { + const showTip = $(false); + const tooltipText = $('Hover over the button!'); + + const updateTooltip = (text) => { + tooltipText(text); + setTimeout(() => { + tooltipText('Hover over the button!'); + }, 2000); + }; + + return Div({ class: 'flex flex-col gap-4 items-center' }, [ + Tooltip({ tip: () => tooltipText() }, [ + Button({ + class: 'btn btn-primary btn-lg', + onclick: () => Toast('Button clicked!', 'alert-info', 2000) + }, 'Interactive Button') + ]), + Div({ class: 'flex gap-2 flex-wrap justify-center mt-4' }, [ + Button({ + class: 'btn btn-xs', + onclick: () => updateTooltip('You clicked the button!') + }, 'Change Tooltip'), + Button({ + class: 'btn btn-xs', + onclick: () => updateTooltip('Try hovering now!') + }, 'Change Again') + ]) + ]); +}; +$mount(InteractiveDemo, '#demo-interactive'); +``` + +### Rich Tooltip Content + +
+
+

Live Demo

+
+
+
+ +```javascript +const RichDemo = () => { + return Div({ class: 'flex flex-wrap gap-4 justify-center' }, [ + Tooltip({ + tip: Div({ class: 'text-left p-1' }, [ + Div({ class: 'font-bold' }, 'User Info'), + Div({ class: 'text-xs' }, 'John Doe'), + Div({ class: 'text-xs' }, 'john@example.com'), + Div({ class: 'badge badge-xs badge-primary mt-1' }, 'Admin') + ]) + }, [ + Button({ class: 'btn btn-outline' }, 'User Profile') + ]), + Tooltip({ + tip: Div({ class: 'text-left p-1' }, [ + Div({ class: 'font-bold flex items-center gap-1' }, [ + Icons.iconWarning, + Span({}, 'System Status') + ]), + Div({ class: 'text-xs' }, 'All systems operational'), + Div({ class: 'text-xs text-success' }, '✓ 99.9% uptime') + ]) + }, [ + Button({ class: 'btn btn-outline' }, 'System Status') + ]) + ]); +}; +$mount(RichDemo, '#demo-rich'); +``` + +### Color Variants + +
+
+

Live Demo

+
+
+
+ +```javascript +const ColorsDemo = () => { + return Div({ class: 'flex flex-wrap gap-4 justify-center' }, [ + Tooltip({ tip: 'Primary tooltip', class: 'tooltip-primary' }, [ + Button({ class: 'btn btn-primary btn-sm' }, 'Primary') + ]), + Tooltip({ tip: 'Secondary tooltip', class: 'tooltip-secondary' }, [ + Button({ class: 'btn btn-secondary btn-sm' }, 'Secondary') + ]), + Tooltip({ tip: 'Accent tooltip', class: 'tooltip-accent' }, [ + Button({ class: 'btn btn-accent btn-sm' }, 'Accent') + ]), + Tooltip({ tip: 'Info tooltip', class: 'tooltip-info' }, [ + Button({ class: 'btn btn-info btn-sm' }, 'Info') + ]), + Tooltip({ tip: 'Success tooltip', class: 'tooltip-success' }, [ + Button({ class: 'btn btn-success btn-sm' }, 'Success') + ]), + Tooltip({ tip: 'Warning tooltip', class: 'tooltip-warning' }, [ + Button({ class: 'btn btn-warning btn-sm' }, 'Warning') + ]), + Tooltip({ tip: 'Error tooltip', class: 'tooltip-error' }, [ + Button({ class: 'btn btn-error btn-sm' }, 'Error') + ]) + ]); +}; +$mount(ColorsDemo, '#demo-colors'); +``` + +### All Tooltip Positions + +
+
+

Live Demo

+
+
+
+ +```javascript +const AllPositionsDemo = () => { + return Div({ class: 'grid grid-cols-3 gap-4 justify-items-center' }, [ + Div({ class: 'col-start-2' }, [ + Tooltip({ tip: 'Top tooltip', class: 'tooltip-top' }, [ + Button({ class: 'btn btn-sm w-24' }, 'Top') + ]) + ]), + Div({ class: 'col-start-1 row-start-2' }, [ + Tooltip({ tip: 'Left tooltip', class: 'tooltip-left' }, [ + Button({ class: 'btn btn-sm w-24' }, 'Left') + ]) + ]), + Div({ class: 'col-start-2 row-start-2' }, [ + Tooltip({ tip: 'Center tooltip', class: 'tooltip' }, [ + Button({ class: 'btn btn-sm w-24' }, 'Center') + ]) + ]), + Div({ class: 'col-start-3 row-start-2' }, [ + Tooltip({ tip: 'Right tooltip', class: 'tooltip-right' }, [ + Button({ class: 'btn btn-sm w-24' }, 'Right') + ]) + ]), + Div({ class: 'col-start-2 row-start-3' }, [ + Tooltip({ tip: 'Bottom tooltip', class: 'tooltip-bottom' }, [ + Button({ class: 'btn btn-sm w-24' }, 'Bottom') + ]) + ]) + ]); +}; +$mount(AllPositionsDemo, '#demo-all-positions'); +``` + + diff --git a/docs/index.html b/docs/index.html index c7775bd..d204656 100644 --- a/docs/index.html +++ b/docs/index.html @@ -40,8 +40,10 @@ - - + + + + diff --git a/docs/sigpro-ui.umd.min.js b/docs/sigpro-ui.umd.min.js new file mode 100644 index 0000000..65f7fb1 --- /dev/null +++ b/docs/sigpro-ui.umd.min.js @@ -0,0 +1 @@ +var SigProUI=function(t,e){"use strict";const l=t=>"function"==typeof t?t():t,a=(t,e)=>"function"==typeof e?()=>`${t} ${e()||""}`.trim():`${t} ${e||""}`.trim();var o=Object.freeze({__proto__:null,joinClass:a,val:l});const n=(t,l)=>{const{title:o,name:n,open:s,...A}=t;return e.$html("div",{...A,class:a("collapse collapse-arrow bg-base-200 mb-2",t.class)},[e.$html("input",{type:n?"radio":"checkbox",name:n,checked:s}),e.$html("div",{class:"collapse-title text-xl font-medium"},o),e.$html("div",{class:"collapse-content"},l)])};var s=Object.freeze({__proto__:null,Accordion:n});const A="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADjSURBVDiN3dJNSgNBEAXgz4DZeAAVJ9tko2St3kaIFxAVt4KZeAD1GKKi7vQSydI/yHgALxAXU02GxniAFBR0v1ev+3V1sZSxjxtM8BM5wTX2/hNu4gFvOMI21iJ3cIwP3GMjF/dQ4RyraOMS34GPAmvjIrBeEnfwjoPGgSM8ooh8QtngB6Ep4BWnmaMqkY1LqqzmDC8tzNDK3/RHzLL9SloUYWfQIMuw3Yl8xrDBH6qbvZWALqbqBqVmlWF7GuKEDwPr5hbXcYdPnKBv/o39wL5wG7ULY1c9NGPzQRrjKrhli1/02zEjWyWMBwAAAABJRU5ErkJggg==",c="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAEDSURBVDiN1dK/K8VhFAbwD+VLGSxKcu9guSQ/Zils/gNkuaX4BxRZDTdklYU/QAaDlEVGGwu2Kz/uVbKJzWDwfuv1+jHz1Km3c85znuf0Hv4jxnD2W8MItnCJ5xAX2MQcHsOQL+jEAapYQD9aQwxiDy+B3JKSe1DHCpqQYQ0PeMJOpDyAmyAAirjGbDRwFYcoYCZSzjGP+8B1gqXEUT2QxyPlqaRnGceNeENzUswwil1MBocbSU9DCAXUUI6K25HtIo5QSVaooitP9OEO65iIbE+HXSvBVRbeNZQSR9pxGil3o83HNw5hEbfYR0dKFki5ci+u8OrzIQ1/R8xx7ocL+9t4B0HPOVXjoptxAAAAAElFTkSuQmCC",r="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABcSURBVDiN3dIxDoAwCIXhL563g3bSm+hlq4O6GFNbO+k/EV54QIDfsSBk9IA5ZxCQEG+0eGi5BqDHivEhV2xSXXwy2EdOR3xLV+ta0/26wvSm+KTYpPmMzY/0QTZeZR2f+FxhRQAAAABJRU5ErkJggg==",i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAACLSURBVDiN7dO9CQJBFEXhb38K0FwQrMNEVpuwB0NjrcYabECsQk0sQ1mTF4zIjrgmBh54MMx998AEwzOrmC5e8gJjbDHCJO7PHYI0v2JT4Ig9DljGwq5DkOZTLOCOMoIhBpknpHmFWx3ldaaUo6oTc2/ab7rl+508f8GvCC5oenTn4tM1cWg/nBNmD4fBH/Kfvt2TAAAAAElFTkSuQmCC",d="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAWQAAAFkBqp2phgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAACQSURBVDiN7dKxDcJQDATQJ0YgXQQ1bAgDEIZBETPQwjakIjRQ8CMSyR8SiZKTrvHZd/r+JsYSNZrEI1ZR4ywzfElcJ55xwiITOECNTVDf4jDGoEEZ1Etcxxg8pmjRDiahb7BH20uKKPVUkVmL+YjQArdI+PT2bO9Pd/A34O71Rd9QeN/LAFUSckfUscWuG3oCgP8nrDH6T5AAAAAASUVORK5CYII=",m="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADFSURBVDiN7dCxSoIBFAXgr1BbgmgSB5ubxKAHaAkcgnBpySVaDET3WhzcpQfoHZojawgX0ZZcfAWDSDdBoeUKP/8ojZ7tnnPv4dzDFv+KZzwl5jf84B354C4wwjdeUV4vl7DCEsXgxmhigDpOMcMVjoKr7cTyI/ZxiE90wmCB4zi+RRatZOxd7OEavxHtBmvjIV5wH2a59N8ZXIZQisMCzkL/wgGq6EYffXzgHHNo4y5h+oBGlLjEBJVUiVP0cJJOtMUG+APtfyYzbH7eVgAAAABJRU5ErkJggg==",u="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAB2AAAAdgFOeyYIAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAMxJREFUOI3t0bFKwlEUBvBfmmBEr1APIDZJ9AJJQyAIvkGP0C4uQruza+DUmuIc9AC9gBG4Nmpkw/8IB3Vw1w8u95zvnvPde77LEeUUV9HAF67QRA2nmMf5A+o4x3cWOsMYy8j7WMX6jaYbLBL/mAWe8RcHm1ihs8G94gVKQQzwlAouMcQo8p/Y28HdYpYFZmsi0MVdxD1MdrxsC500wijdvgtbI1AYtDbxMwkuFAZmE1uYwkkSqOIaHyHcxEU0vUXNPSqKr37fZ6xDwD9DPS0OyHjQHQAAAABJRU5ErkJggg==",p="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAC4SURBVDiNxdIxagJRFIXhLzLFBNJYaJslSEylWOhq3IorMGQ16SyjYCFiZWU5pTaDFvOUyTAZ8RHID69555577oXLf/OEGaY4R3g/4IhORHg3eOXYYvSAeRQ8OWQYYoNPvDQYnxUr7zBB1grCAv3QbIlxjXmAb7Txhq+rkFUKq9NUU8vcJiizwDtOWGEdmvTKqT+61H0GXsP7jSxpEGF/R1e3wkO0FBeVRnhTSBTneBB3yvOI4D/mAnvrIwKM5s4AAAAAAElFTkSuQmCC",h="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAnXAAAJ1wGxbhe3AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAASVJREFUOI190r0uhFEQBuBnVxaF2PUTCkFchV0SV6BQi0rEbShFlCqNktJP0Iqf3i3YVSlXVEQozojP8e2+ySSTed+ZMzNnKnpjCFPhv+C9j/YPlnCBV3TCujhHq19iFftoYxOjBa4esTb2QvsP+7jFWJ9HxnEXRf5gGU9Z8gKucBl+sUgHTahE8AJnOCoIT/AcmhmsF7gtrGINBqWFFWcmLXMUhzjIuEbk1GA+2i/DNh4wUsK1MVfFV2GUHJO4xlsPHr8j1Eu44bAcDek2agP4lDZaxWMm3MEKbrL4hjT/8U+gJc00nglnw4qYkL5xMW9rTzqSvEiefI/dMrIaRTrSPzcKXCNinUguPeUfNKWj6kqH9Bz+aVnbvb6PtKTp8F/wUSb6Bu5YN5n7ff0kAAAAAElFTkSuQmCC",b="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAnXAAAJ1wGxbhe3AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAQtJREFUOI2F0jFOAlEQBuAPImoFqyTa6TEEbfUihruYDYfwCAg3UDsTY20na0VjgqUWWuxgHsuy/skk82bmn/fPm9eyHXs4Cn+Br4baNZxjhk8UYUtMMWwitjHGHNfoJrlexObIo3YDY9zjoOGSQzxEkzVc4O0fctqkwCANzkJiE9LmI9ytDrvKB+tWGQnylIAsOB04VcrfdluO55CeYo6THfygVUne4jX8S1zho1LTDu7fCL2KxCe8oF8zUqb8G51VYGrzEffD6jDCJA0MY6bqnHXoK9d4Vk3kyk/S1KSPR9zUJdvRpAiJWZLLIlYEufYrrzBQ7nyJ97ClcuYN2dX1pejgOPwFvuuKfgHXiDR+HL1j1AAAAABJRU5ErkJggg==",g="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAnXAAAJ1wGxbhe3AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAARZJREFUOI2V0j1KQ1EQBeDPp4lWRiMoKVyAK9AoiLgJGytxD9oJNhKyDyvBnw2IugC3YGKVRk1KRbR48yC5vjzwwIHL3DPnzp2ZGdMxj9U4D/BZoZ3ANu4wQj84xC3aVYkZuujhCItjd42I9dAJ7R908YDlikeaeAyTCezgpST5IJia9LFVlA0nOMd7It4IjuMttKeFQR17uKooPcUV9lHL0ArX0T8MPqLa1hx+MDNFWDX7LHLV4/VGiWghmGJJvhu1WXzLO5rhORGeYRf3SfwQNVwWgbZ8SZqJcD04jhX5GDfTsjryJUlN0uQnXJRdZmHSx7H8nwWWItaP5NJVLrCFG3mTXoNDXJeVPW185E1ai/MAX2WiX9S3NSPYbj+uAAAAAElFTkSuQmCC",f="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAnXAAAJ1wGxbhe3AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAARJJREFUOI2l0r8uRFEQBvAfu9glwUYiUaxHUEl0VDpKeq+wpZBINAqFRHgTKg0tCSqVhmKDEM1u/Esodm725rq7iC+ZzMnM982ZmXP4JwpdchWsYBrXeMkj9XQQV3GEi+BMYR63v+mqiDPUUrEaTiP3I1ZxEOcySnE+jFxXVPEQPimWiCYzOdCbKbCFPe1Z+8PgBvvBycVMCIdSsY2wBEPBmcnrYBtraKRib2EJGljHjswLLuI8Z6SS9hLTl15iIR08wZLv2AzLYjk0YATP8n9lVWbrgUJohosYxCdG8Zghdvp5ldCUi6hrPd0VjvGEVzTxEYLkogGMYQ67uEtvcgKzGA8y9IV/D9/Evdb89Q7d/Q1fB8U0mpUmzV0AAAAASUVORK5CYII=",$="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABfSURBVDiNY2AY8oCZSHWxDAwMEgwMDHfJsaSAgYHhH9QQsjT/Z2BgKKe75gQGiLMLCSlkwiHOSI6t6ADmhYoBN6SIARIeidgkiUlIxxkYGB4xMDB8YmBguE6JSwYpAACvLRHTKwPjZgAAAABJRU5ErkJggg==",v="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABNSURBVDiN3dAxCoAwFATRh3fU2oAHiDbi5Y1F2jT+gKLbzyy7/DYjUo8g4cTWI8koOF6XrOqc5ifDDVGJthfsj8OLujtHYJgwR+GP5QKMxA9/SolDQgAAAABJRU5ErkJggg==",B="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABlSURBVDiN3ZLBDUBAEEUfmtCchA5woUMlOO1FCQrAwbqwf8eFhHd7mfzJn2Tg82TGvABywAmPUgOLD4XcDK9AJ/y5cOlrNsIvpCdPDL/FUbkX/t6Slv3+SjgQf6QBmIAZGAP+FzZJViOd89x8pAAAAABJRU5ErkJggg==",w="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABmSURBVDiN3dGxCoAgEMbxfz1dL1BTREJzmUv08trgDYcg6VCD3/YD7zvkoLmMgFEegLmmwAAecOJVvNeUWCAAt7IHjt9LThkyiRf9qC8oCom70u0BuDL+bngj/tNm/JqJePucW8wDvGYdzT0nMUkAAAAASUVORK5CYII=",x="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADNSURBVDiNndOxTgJRFIThz41ZDMFKqH0DLSRSq4lQ0RifUcMzUJlYQKjtLcHVSimBggPRNSzs/sk0kzPnTHEvxZyHKnGJD3yhXSWcYRnKwvvH0Y7wEG/4wQI1XOEek6LLF3FtiDoGoXp4WcxsSXILHjFCH/Nf/jy8ER6KGuTZNNhJvkFpEpygUyHbRi1BFy8VFryilyANlSVFerxn6N36IRVyG0PNEtdbkbmBU8zwdOCSJp4xRWNj3sWS5YGaRvM/f6GBa5ztafCJMb5hBQQ/MMwXLnnZAAAAAElFTkSuQmCC";var y=Object.freeze({__proto__:null,icon123:u,iconAbc:m,iconCalendar:i,iconClose:r,iconError:g,iconHide:c,iconInfo:h,iconLLeft:B,iconLeft:$,iconLock:d,iconMail:p,iconRRight:w,iconRight:v,iconShow:A,iconSuccess:b,iconUpload:x,iconWarning:f});const S=(t,a)=>{const{type:o="info",soft:n=!0,...s}=t,A={info:h,success:b,warning:f,error:g},c=a||t.message;return e.$html("div",{...s,role:"alert",class:()=>`alert ${(()=>{const t=l(o);return{info:"alert-info",success:"alert-success",warning:"alert-warning",error:"alert-error"}[t]||t})()} ${l(n)?"alert-soft":""} ${t.class||""}`},[e.$html("img",{src:A[l(o)]||A.info,class:"w-4 h-4 object-contain",alt:l(o)}),e.$html("div",{class:"flex-1"},[e.$html("span",{},["function"==typeof c?c():c])]),t.actions?e.$html("div",{class:"flex-none"},["function"==typeof t.actions?t.actions():t.actions]):null])};var C=Object.freeze({__proto__:null,Alert:S});const U={es:{close:"Cerrar",confirm:"Confirmar",cancel:"Cancelar",search:"Buscar...",loading:"Cargando...",nodata:"Sin datos"},en:{close:"Close",confirm:"Confirm",cancel:"Cancel",search:"Search...",loading:"Loading...",nodata:"No data"}},k=e.$("es"),R=t=>()=>U[k()][t]||t,D=t=>{const{label:o,tip:n,value:s,error:r,isSearch:h,icon:b,type:g="text",...f}=t,$="password"===g,v=e.$(!1),B={text:m,password:d,date:i,number:u,email:p},w=e.$html("input",{...f,type:()=>$?v()?"text":"password":g,placeholder:t.placeholder||o||(h?R("search")():" "),class:a("grow order-2 focus:outline-none",t.class),value:s,oninput:e=>t.oninput?.(e),disabled:()=>l(t.disabled)}),x=b||(B[g]?e.$html("img",{src:B[g],class:"opacity-50",alt:g}):null);return e.$html("label",{class:()=>a("input input-bordered floating-label flex items-center gap-2 w-full relative",l(r)?"input-error":"")},[x?e.$html("div",{class:"order-1 shrink-0"},x):null,o?e.$html("span",{class:"text-base-content/60 order-0"},o):null,w,$?e.$html("button",{type:"button",class:"order-3 btn btn-ghost btn-xs btn-circle opacity-50 hover:opacity-100",onclick:t=>{t.preventDefault(),v(!v())}},()=>e.$html("img",{class:"w-5 h-5",src:v()?A:c})):null,n?e.$html("div",{class:"tooltip tooltip-left order-4","data-tip":n},e.$html("span",{class:"badge badge-ghost badge-xs cursor-help"},"?")):null,()=>l(r)?e.$html("span",{class:"text-error text-[10px] absolute -bottom-5 left-2"},l(r)):null])};var j=Object.freeze({__proto__:null,Input:D});const _=t=>{const{options:a=[],value:o,onSelect:n,label:s,placeholder:A,...c}=t,r=e.$(l(o)||""),i=e.$(!1),d=e.$(-1),m=e.$(()=>{const t=r().toLowerCase(),e=l(a)||[];return t?e.filter(e=>("string"==typeof e?e:e.label).toLowerCase().includes(t)):e}),u=t=>{const e="string"==typeof t?t:t.value,l="string"==typeof t?t:t.label;r(l),"function"==typeof o&&o(e),n?.(t),i(!1),d(-1)};return e.$html("div",{class:"relative w-full"},[D({label:s,placeholder:A||R("search")(),value:r,onfocus:()=>i(!0),onblur:()=>setTimeout(()=>i(!1),150),onkeydown:t=>{const e=m();"ArrowDown"===t.key?(t.preventDefault(),i(!0),d(Math.min(d()+1,e.length-1))):"ArrowUp"===t.key?(t.preventDefault(),d(Math.max(d()-1,0))):"Enter"===t.key&&d()>=0?(t.preventDefault(),u(e[d()])):"Escape"===t.key&&i(!1)},oninput:t=>{const e=t.target.value;r(e),"function"==typeof o&&o(e),i(!0),d(-1)},...c}),e.$html("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",style:()=>i()&&m().length?"display:block":"display:none"},[e.$for(m,(t,l)=>e.$html("li",{},[e.$html("a",{class:()=>"block w-full "+(d()===l?"active bg-primary text-primary-content":""),onclick:()=>u(t),onmouseenter:()=>d(l)},"string"==typeof t?t:t.label)]),(t,e)=>("string"==typeof t?t:t.value)+e),()=>m().length?null:e.$html("li",{class:"p-2 text-center opacity-50"},"No results")])])};const z=(t,l)=>e.$html("span",{...t,class:a("badge",t.class)},l);const E=(t,o)=>{const{badge:n,badgeClass:s,tooltip:A,icon:c,loading:r,...i}=t;let d=e.$html("button",{...i,class:a("btn",t.class),disabled:()=>l(r)||l(t.disabled)},[()=>l(r)?e.$html("span",{class:"loading loading-spinner"}):null,c?e.$html("span",{class:"mr-1"},c):null,o]);return n&&(d=e.$html("div",{class:"indicator"},[e.$html("span",{class:a("indicator-item badge",s||"badge-secondary")},n),d])),A?e.$html("div",{class:"tooltip","data-tip":A},d):d};const I=t=>{const{value:a,tooltip:o,toggle:n,label:s,...A}=t,c=e.$html("input",{...A,type:"checkbox",class:()=>l(n)?"toggle":"checkbox",checked:a}),r=e.$html("label",{class:"label cursor-pointer justify-start gap-3"},[c,s?e.$html("span",{class:"label-text"},s):null]);return o?e.$html("div",{class:"tooltip","data-tip":o},r):r};const Y=t=>{const{value:a,label:o,...n}=t,s=e.$(!1),A=["#000","#1A1A1A","#333","#4D4D4D","#666","#808080","#B3B3B3","#FFF","#450a0a","#7f1d1d","#991b1b","#b91c1c","#dc2626","#ef4444","#f87171","#fca5a5","#431407","#7c2d12","#9a3412","#c2410c","#ea580c","#f97316","#fb923c","#ffedd5","#713f12","#a16207","#ca8a04","#eab308","#facc15","#fde047","#fef08a","#fff9c4","#064e3b","#065f46","#059669","#10b981","#34d399","#4ade80","#84cc16","#d9f99d","#082f49","#075985","#0284c7","#0ea5e9","#38bdf8","#7dd3fc","#22d3ee","#cffafe","#1e1b4b","#312e81","#4338ca","#4f46e5","#6366f1","#818cf8","#a5b4fc","#e0e7ff","#2e1065","#4c1d95","#6d28d9","#7c3aed","#8b5cf6","#a855f7","#d946ef","#fae8ff"],c=()=>l(a)||"#000000";return e.$html("div",{class:"relative w-fit"},[e.$html("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",onclick:t=>{t.stopPropagation(),s(!s())},...n},[e.$html("div",{class:"size-5 rounded-sm shadow-inner border border-black/10 shrink-0",style:()=>`background-color: ${c()}`}),o?e.$html("span",{class:"opacity-80"},o):null]),e.$if(s,()=>e.$html("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",onclick:t=>t.stopPropagation()},[e.$html("div",{class:"grid grid-cols-8 gap-1"},A.map(t=>e.$html("button",{type:"button",style:`background-color: ${t}`,class:()=>"size-6 rounded-sm cursor-pointer transition-all hover:scale-125 hover:z-10 active:scale-95 outline-none border border-black/5 \n "+(c().toLowerCase()===t.toLowerCase()?"ring-2 ring-offset-1 ring-primary z-10 scale-110":""),onclick:()=>{"function"==typeof a&&a(t),s(!1)}})))])),e.$if(s,()=>e.$html("div",{class:"fixed inset-0 z-[100]",onclick:()=>s(!1)}))])};const V=t=>{const{value:a,range:o,label:n,placeholder:s,hour:A=!1,...c}=t,r=e.$(!1),d=e.$(new Date),m=e.$(null),u=e.$(0),p=e.$(0),h=()=>!0===l(o),b=new Date,g=`${b.getFullYear()}-${String(b.getMonth()+1).padStart(2,"0")}-${String(b.getDate()).padStart(2,"0")}`,f=t=>`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")}`,x=t=>{const e=f(t),o=l(a);if(h())if(!o?.start||o.start&&o.end)"function"==typeof a&&a({start:e,end:null,...A&&{startHour:u()}});else{const t=o.start;if("function"==typeof a){const l=e{const t=l(a);if(!t)return"";if("string"==typeof t)return A&&t.includes("T")?t.replace("T"," "):t;if(t.start&&t.end){return`${A&&t.startHour?`${t.start} ${String(t.startHour).padStart(2,"0")}:00`:t.start} - ${A&&t.endHour?`${t.end} ${String(t.endHour).padStart(2,"0")}:00`:t.end}`}if(t.start){return`${A&&t.startHour?`${t.start} ${String(t.startHour).padStart(2,"0")}:00`:t.start}...`}return""}),S=t=>{const e=d();d(new Date(e.getFullYear(),e.getMonth()+t,1))},C=t=>{const e=d();d(new Date(e.getFullYear()+t,e.getMonth(),1))},U=({value:t,onChange:a})=>e.$html("div",{class:"flex-1"},[e.$html("div",{class:"flex gap-2 items-center"},[e.$html("input",{type:"range",min:0,max:23,value:t,class:"range range-xs flex-1",oninput:t=>{const e=parseInt(t.target.value);a(e)}}),e.$html("span",{class:"text-sm font-mono min-w-[48px] text-center"},()=>String(l(t)).padStart(2,"0")+":00")])]);return e.$html("div",{class:"relative w-full"},[D({label:n,placeholder:s||(h()?"Seleccionar rango...":"Seleccionar fecha..."),value:y,readonly:!0,icon:e.$html("img",{src:i,class:"opacity-40"}),onclick:t=>{t.stopPropagation(),r(!r())},...c}),e.$if(r,()=>e.$html("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",onclick:t=>t.stopPropagation()},[e.$html("div",{class:"flex justify-between items-center mb-4 gap-1"},[e.$html("div",{class:"flex gap-0.5"},[e.$html("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>C(-1)},e.$html("img",{src:B,class:"opacity-40"})),e.$html("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>S(-1)},e.$html("img",{src:$,class:"opacity-40"}))]),e.$html("span",{class:"font-bold uppercase flex-1 text-center"},[()=>d().toLocaleString("es-ES",{month:"short",year:"numeric"})]),e.$html("div",{class:"flex gap-0.5"},[e.$html("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>S(1)},e.$html("img",{src:v,class:"opacity-40"})),e.$html("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>C(1)},e.$html("img",{src:w,class:"opacity-40"}))])]),e.$html("div",{class:"grid grid-cols-7 gap-1",onmouseleave:()=>m(null)},[...["L","M","X","J","V","S","D"].map(t=>e.$html("div",{class:"text-[10px] opacity-40 font-bold text-center"},t)),()=>{const t=d(),o=t.getFullYear(),n=t.getMonth(),s=new Date(o,n,1).getDay(),A=0===s?6:s-1,c=new Date(o,n+1,0).getDate(),r=[];for(let t=0;t{const t=l(a),e=m(),o="string"==typeof t?t.split("T")[0]===A:t?.start===A,n=t?.end===A;let s=!1;if(h()&&t?.start){const l=t.start;!t.end&&e?s=A>l&&A<=e||A=e:t.end&&(s=A>l&&A{h()&&m(A)},onclick:()=>x(s)},[t.toString()]))}return r}]),A?e.$html("div",{class:"mt-3 pt-2 border-t border-base-300"},[h()?e.$html("div",{class:"flex gap-4"},[U({value:u,onChange:t=>{u(t);const e=l(a);e?.start&&a({...e,startHour:t})}}),U({value:p,onChange:t=>{p(t);const e=l(a);e?.end&&a({...e,endHour:t})}})]):U({value:u,onChange:t=>{u(t);const e=l(a);e&&"string"==typeof e&&e.includes("-")&&a(e.split("T")[0]+"T"+String(t).padStart(2,"0")+":00:00")}})]):null])),e.$if(r,()=>e.$html("div",{class:"fixed inset-0 z-[90]",onclick:()=>r(!1)}))])};const H=t=>e.$html("div",{class:a("drawer",t.class)},[e.$html("input",{id:t.id,type:"checkbox",class:"drawer-toggle",checked:t.open}),e.$html("div",{class:"drawer-content"},t.content),e.$html("div",{class:"drawer-side"},[e.$html("label",{for:t.id,class:"drawer-overlay",onclick:()=>t.open?.(!1)}),e.$html("div",{class:"min-h-full bg-base-200 w-80"},t.side)])]);const O=(t,a)=>{const{label:o,icon:n,items:s,...A}=t;return e.$html("div",{...A,class:()=>`dropdown ${l(t.class)||""}`},[e.$html("div",{tabindex:0,role:"button",class:"btn m-1 flex items-center gap-2"},[n?"function"==typeof n?n():n:null,o?"function"==typeof o?o():o:null]),(()=>{if(s){const t="function"==typeof s?s:()=>s;return e.$html("ul",{tabindex:0,class:"dropdown-content z-[50] menu p-2 shadow bg-base-100 rounded-box w-52 border border-base-300"},[e.$for(t,t=>e.$html("li",{},[e.$html("a",{class:t.class||"",onclick:e=>{t.onclick&&t.onclick(e),document.activeElement&&document.activeElement.blur()}},[t.icon?e.$html("span",{},t.icon):null,e.$html("span",{},t.label)])]))])}return e.$html("div",{tabindex:0,class:"dropdown-content z-[50] p-2 shadow bg-base-100 rounded-box min-w-max border border-base-300"},["function"==typeof a?a():a])})()])};const F=t=>{const{icon:a,label:o,actions:n=[],position:s="bottom-6 right-6",class:A="",...c}=t;return e.$html("div",{...c,class:`fab absolute ${s} flex flex-col-reverse items-end gap-3 z-[100] ${A}`},[e.$html("div",{tabindex:0,role:"button",class:"btn btn-lg btn-circle btn-primary shadow-2xl"},[a?"function"==typeof a?a():a:null,!a&&o?o:null]),...l(n).map(t=>e.$html("div",{class:"flex items-center gap-3 transition-all duration-300"},[t.label?e.$html("span",{class:"badge badge-ghost shadow-sm whitespace-nowrap"},t.label):null,e.$html("button",{type:"button",class:`btn btn-circle shadow-lg ${t.class||""}`,onclick:e=>{e.stopPropagation(),t.onclick?.(e)}},[t.icon?"function"==typeof t.icon?t.icon():t.icon:t.text||""])]))])};const Q=(t,o)=>e.$html("fieldset",{...t,class:a("fieldset bg-base-200 border border-base-300 p-4 rounded-lg",t.class)},[()=>{const a=l(t.legend);return a?e.$html("legend",{class:"fieldset-legend font-bold"},[a]):null},o]);const N=t=>{const{tooltip:l,max:a=2,accept:o="*",onSelect:n}=t,s=e.$([]),A=e.$(!1),c=e.$(null),i=1024*a*1024,d=t=>{const e=Array.from(t);c(null);e.find(t=>t.size>i)?c(`Máx ${a}MB`):(s([...s(),...e]),n?.(s()))};return e.$html("fieldset",{class:"fieldset w-full p-0"},[e.$html("div",{class:()=>"w-full "+(l?"tooltip tooltip-top before:z-50 after:z-50":""),"data-tip":l},[e.$html("label",{class:()=>`\n relative flex items-center justify-between w-full h-12 px-4\n border-2 border-dashed rounded-lg cursor-pointer\n transition-all duration-200\n ${A()?"border-primary bg-primary/10":"border-base-content/20 bg-base-100 hover:bg-base-200"}\n `,ondragover:t=>{t.preventDefault(),A(!0)},ondragleave:()=>A(!1),ondrop:t=>{t.preventDefault(),A(!1),d(t.dataTransfer.files)}},[e.$html("div",{class:"flex items-center gap-3 w-full"},[e.$html("img",{src:x,class:"w-5 h-5 opacity-50 shrink-0"}),e.$html("span",{class:"text-sm opacity-70 truncate grow text-left"},"Arrastra o selecciona archivos..."),e.$html("span",{class:"text-[10px] opacity-40 shrink-0"},`Máx ${a}MB`)]),e.$html("input",{type:"file",multiple:!0,accept:o,class:"hidden",onchange:t=>d(t.target.files)})])]),()=>c()?e.$html("span",{class:"text-[10px] text-error mt-1 px-1 font-medium"},c()):null,e.$if(()=>s().length>0,()=>e.$html("ul",{class:"mt-2 space-y-1"},[e.$for(s,(t,l)=>e.$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"},[e.$html("div",{class:"flex items-center gap-2 truncate"},[e.$html("span",{class:"opacity-50"},"📄"),e.$html("span",{class:"truncate font-medium max-w-[200px]"},t.name),e.$html("span",{class:"text-[9px] opacity-40"},`(${(t.size/1024).toFixed(0)} KB)`)]),e.$html("button",{type:"button",class:"btn btn-ghost btn-xs btn-circle",onclick:t=>{t.preventDefault(),t.stopPropagation(),(t=>{const e=s().filter((e,l)=>l!==t);s(e),n?.(e)})(l)}},[e.$html("img",{src:r,class:"w-3 h-3 opacity-70"})])]),t=>t.name+t.lastModified)]))])};const L=(t,l)=>e.$html("div",{class:a("indicator",t.class)},[l,e.$html("span",{class:a("indicator-item badge",t.badgeClass)},t.badge)]);const T=t=>{const{items:o,header:n,render:s,keyFn:A=(t,e)=>e,class:c,...r}=t,i=e.$for(o,(t,l)=>e.$html("li",{class:"list-row"},[s(t,l)]),A);return e.$html("ul",{...r,class:a("list bg-base-100 rounded-box shadow-md",c)},n?[e.$if(n,()=>e.$html("li",{class:"p-4 pb-2 text-xs opacity-60"},[l(n)])),i]:i)};const G=t=>e.$if(t.$show,()=>e.$html("div",{class:"fixed inset-0 z-[100] flex items-center justify-center backdrop-blur-sm bg-base-100/30"},[e.$html("span",{class:"loading loading-spinner loading-lg text-primary"})]));const M=t=>{const o=t=>e.$for(()=>t||[],t=>e.$html("li",{},[t.children?e.$html("details",{open:t.open},[e.$html("summary",{},[t.icon&&e.$html("span",{class:"mr-2"},t.icon),t.label]),e.$html("ul",{},o(t.children))]):e.$html("a",{class:()=>l(t.active)?"active":"",onclick:t.onclick},[t.icon&&e.$html("span",{class:"mr-2"},t.icon),t.label])]),(t,e)=>t.label||e);return e.$html("ul",{...t,class:a("menu bg-base-200 rounded-box",t.class)},o(t.items))};const J=(t,l)=>{const{title:a,buttons:o,open:n,...s}=t,A={current:null};e.$watch(()=>{const t=A.current;t&&(n()?t.open||t.showModal():t.open&&t.close())});const c=t=>{t&&t.preventDefault&&t.preventDefault(),n(!1)};return e.$html("dialog",{...s,ref:A,class:"modal",oncancel:()=>n(!1)},[e.$html("div",{class:"modal-box"},[a?e.$html("h3",{class:"text-lg font-bold mb-4"},a):null,e.$html("div",{class:"py-2"},["function"==typeof l?l():l]),e.$html("div",{class:"modal-action flex gap-2"},[...(Array.isArray(o)?o:[o]).filter(Boolean),E({type:"button",onclick:c},R("close")())])]),e.$html("form",{method:"dialog",class:"modal-backdrop",onsubmit:c},[e.$html("button",{},"close")])])};const K=(t,l)=>e.$html("div",{...t,class:a("navbar bg-base-100 shadow-sm px-4",t.class)},l);const P=t=>{const{label:o,tooltip:n,value:s,inputValue:A,name:c,...r}=t,i=e.$html("input",{...r,type:"radio",name:c,class:a("radio",t.class),checked:()=>l(s)===A,onclick:()=>{"function"==typeof s&&s(A)}});return o||n?e.$html("label",{class:"label cursor-pointer justify-start gap-3"},[i,o?e.$html("span",{class:"label-text"},o):null]):i};const X=t=>{const{label:o,tooltip:n,value:s,...A}=t,c=e.$html("input",{...A,type:"range",class:a("range",t.class),value:s,disabled:()=>l(t.disabled)});if(!o&&!n)return c;const r=e.$html("div",{class:"flex flex-col gap-2"},[o?e.$html("span",{class:"label-text"},o):null,c]);return n?e.$html("div",{class:"tooltip","data-tip":n},r):r};const Z=t=>{const{value:a,count:o=5,mask:n="mask-star",readonly:s=!1,onchange:A,...c}=t,r=`rating-${Math.random().toString(36).slice(2,7)}`;return e.$html("div",{...c,class:()=>`rating ${l(s)?"pointer-events-none":""} ${t.class||""}`},Array.from({length:l(o)},(t,o)=>{const c=o+1;return e.$html("input",{type:"radio",name:r,class:`mask ${n}`,checked:()=>Math.round(l(a))===c,onchange:()=>{l(s)||("function"==typeof A?A(c):"function"==typeof a&&a(c))}})}))};const W=t=>{const{label:o,options:n,value:s,...A}=t,c=e.$html("select",{...A,class:a("select select-bordered w-full",t.class),value:s},e.$for(()=>l(n)||[],t=>e.$html("option",{value:t.value,$selected:()=>String(l(s))===String(t.value)},t.label),t=>t.value));return o?e.$html("label",{class:"fieldset-label flex flex-col gap-1"},[e.$html("span",{},o),c]):c};const q=(t,l)=>e.$html("div",{...t,class:a("stack",t.class)},l);const tt=t=>e.$html("div",{...t,class:a("stat",t.class)},[t.icon&&e.$html("div",{class:"stat-figure text-secondary"},t.icon),t.label&&e.$html("div",{class:"stat-title"},t.label),e.$html("div",{class:"stat-value"},()=>l(t.value)??t.value),t.desc&&e.$html("div",{class:"stat-desc"},t.desc)]);const et=t=>e.$html("label",{class:a("swap",t.class)},[e.$html("input",{type:"checkbox",checked:t.value}),e.$html("div",{class:"swap-on"},t.on),e.$html("div",{class:"swap-off"},t.off)]);const lt=t=>{const{items:o=[],columns:n=[],keyFn:s,zebra:A=!1,pinRows:c=!1,empty:r=R("nodata")(),...i}=t;return e.$html("div",{class:"overflow-x-auto w-full bg-base-100 rounded-box border border-base-300"},[e.$html("table",{...i,class:()=>a("table",`${l(A)?"table-zebra":""} ${l(c)?"table-pin-rows":""} ${t.class||""}`)},[e.$html("thead",{},[e.$html("tr",{},n.map(t=>e.$html("th",{class:t.class||""},t.label)))]),e.$html("tbody",{},[e.$for(o,(t,a)=>e.$html("tr",{class:"hover"},n.map(o=>e.$html("td",{class:o.class||""},[()=>{if(o.render)return o.render(t,a);const e=t[o.key];return l(e)}]))),s||((t,e)=>t.id||e)),e.$if(()=>0===l(o).length,()=>e.$html("tr",{},[e.$html("td",{colspan:n.length,class:"text-center p-10 opacity-50"},[l(r)])]))]),e.$if(()=>n.some(t=>t.footer),()=>e.$html("tfoot",{},[e.$html("tr",{},n.map(t=>e.$html("th",{},t.footer||"")))]))])])};const at=t=>{const{items:o,...n}=t,s="function"==typeof o?o:()=>o||[];return e.$html("div",{...n,class:"flex flex-col gap-4 w-full"},[e.$html("div",{role:"tablist",class:a("tabs tabs-box",t.class)},e.$for(s,t=>e.$html("a",{role:"tab",class:()=>a("tab",l(t.active)&&"tab-active",l(t.disabled),t.tip),"data-tip":t.tip,onclick:e=>!l(t.disabled)&&t.onclick?.(e)},t.label),t=>t.label)),()=>{const t=s().find(t=>l(t.active));if(!t)return null;const a=l(t.content);return e.$html("div",{class:"p-4"},["function"==typeof a?a():a])}])};const ot=t=>{const{items:a=[],vertical:o=!0,compact:n=!1,...s}=t,A={info:h,success:b,warning:f,error:g};return e.$html("ul",{...s,class:()=>`timeline ${l(o)?"timeline-vertical":"timeline-horizontal"} ${l(n)?"timeline-compact":""} ${t.class||""}`},[e.$for(a,(t,o)=>{const n=0===o,s=o===l(a).length-1,c=t.type||"success",r=t=>"function"==typeof t?t():t;return e.$html("li",{class:"flex-1"},[n?null:e.$html("hr",{class:t.completed?"bg-primary":""}),e.$html("div",{class:"timeline-start"},[r(t.title)]),e.$html("div",{class:"timeline-middle"},[e.$html("img",{src:A[c]||t.icon||A.success,class:"w-4 h-4 object-contain mx-1",alt:c})]),e.$html("div",{class:"timeline-end timeline-box shadow-sm"},[r(t.detail)]),s?null:e.$html("hr",{class:t.completed?"bg-primary":""})])},(t,e)=>t.id||e)])};const nt=(t,l="alert-success",a=3500)=>{let o=document.getElementById("sigpro-toast-container");o||(o=e.$html("div",{id:"sigpro-toast-container",class:"fixed top-0 right-0 z-[9999] p-4 flex flex-col gap-2 pointer-events-none"}),document.body.appendChild(o));const n=e.$html("div",{style:"display: contents"});let s;o.appendChild(n);const A=()=>{clearTimeout(s);const t=n.firstElementChild;t&&!t.classList.contains("opacity-0")?(t.classList.add("translate-x-full","opacity-0"),setTimeout(()=>{c.destroy(),n.remove(),o.hasChildNodes()||o.remove()},300)):(c.destroy(),n.remove())},c=e.$mount(()=>{const a=e.$html("div",{class:`alert alert-soft ${l} shadow-lg transition-all duration-300 translate-x-10 opacity-0 pointer-events-auto`},[e.$html("span",{},["function"==typeof t?t():t]),E({class:"btn-xs btn-circle btn-ghost",onclick:A},"✕")]);return requestAnimationFrame(()=>a.classList.remove("translate-x-10","opacity-0")),a},n);return a>0&&(s=setTimeout(A,a)),A};const st=(t,l)=>e.$html("div",{...t,class:a("tooltip",t.class),"data-tip":t.tip},l);const At={...s,...C,...Object.freeze({__proto__:null,Autocomplete:_}),...Object.freeze({__proto__:null,Badge:z}),...Object.freeze({__proto__:null,Button:E}),...Object.freeze({__proto__:null,Checkbox:I}),...Object.freeze({__proto__:null,Colorpicker:Y}),...Object.freeze({__proto__:null,Datepicker:V}),...Object.freeze({__proto__:null,Drawer:H}),...Object.freeze({__proto__:null,Dropdown:O}),...Object.freeze({__proto__:null,Fab:F}),...Object.freeze({__proto__:null,Fieldset:Q}),...Object.freeze({__proto__:null,Fileinput:N}),...Object.freeze({__proto__:null,Indicator:L}),...j,...Object.freeze({__proto__:null,List:T}),...Object.freeze({__proto__:null,Loading:G}),...Object.freeze({__proto__:null,Menu:M}),...Object.freeze({__proto__:null,Modal:J}),...Object.freeze({__proto__:null,Navbar:K}),...Object.freeze({__proto__:null,Radio:P}),...Object.freeze({__proto__:null,Range:X}),...Object.freeze({__proto__:null,Rating:Z}),...Object.freeze({__proto__:null,Select:W}),...Object.freeze({__proto__:null,Stack:q}),...Object.freeze({__proto__:null,Stat:tt}),...Object.freeze({__proto__:null,Swap:et}),...Object.freeze({__proto__:null,Table:lt}),...Object.freeze({__proto__:null,Tabs:at}),...Object.freeze({__proto__:null,Timeline:ot}),...Object.freeze({__proto__:null,Toast:nt}),...Object.freeze({__proto__:null,Tooltip:st})};var ct={...At,install:(t=window)=>{Object.entries(At).forEach(([e,l])=>{t[e]=l}),console.log("🚀 SigproUI")}},rt=Object.freeze({__proto__:null,Accordion:n,Alert:S,Autocomplete:_,Badge:z,Button:E,Checkbox:I,Colorpicker:Y,Datepicker:V,Drawer:H,Dropdown:O,Fab:F,Fieldset:Q,Fileinput:N,Indicator:L,Input:D,List:T,Loading:G,Menu:M,Modal:J,Navbar:K,Radio:P,Range:X,Rating:Z,Select:W,Stack:q,Stat:tt,Swap:et,Table:lt,Tabs:at,Timeline:ot,Toast:nt,Tooltip:st,default:ct});const it={...rt,Icons:y,Utils:o,tt:R,install:(t=("undefined"!=typeof window?window:{}))=>{Object.entries(rt).forEach(([e,l])=>{t[e]=l}),t.Icons=y,t.Utils=o,t.tt=R,console.log("🌟 SigproUI")}};return"undefined"!=typeof window&&it.install(window),t.Accordion=n,t.Alert=S,t.Autocomplete=_,t.Badge=z,t.Button=E,t.Checkbox=I,t.Colorpicker=Y,t.Datepicker=V,t.Drawer=H,t.Dropdown=O,t.Fab=F,t.Fieldset=Q,t.Fileinput=N,t.Indicator=L,t.Input=D,t.List=T,t.Loading=G,t.Menu=M,t.Modal=J,t.Navbar=K,t.Radio=P,t.Range=X,t.Rating=Z,t.Select=W,t.Stack=q,t.Stat=tt,t.Swap=et,t.Table=lt,t.Tabs=at,t.Timeline=ot,t.Toast=nt,t.Tooltip=st,t.default=it,t.icon123=u,t.iconAbc=m,t.iconCalendar=i,t.iconClose=r,t.iconError=g,t.iconHide=c,t.iconInfo=h,t.iconLLeft=B,t.iconLeft=$,t.iconLock=d,t.iconMail=p,t.iconRRight=w,t.iconRight=v,t.iconShow=A,t.iconSuccess=b,t.iconUpload=x,t.iconWarning=f,t.joinClass=a,t.tt=R,t.val=l,Object.defineProperty(t,"__esModule",{value:!0}),t}({},SigPro); diff --git a/docs/sigpro.min.js b/docs/sigpro.min.js new file mode 100644 index 0000000..044c32b --- /dev/null +++ b/docs/sigpro.min.js @@ -0,0 +1 @@ +(()=>{var{defineProperty:D,getOwnPropertyNames:$,getOwnPropertyDescriptor:w}=Object,k=Object.prototype.hasOwnProperty;var N=new WeakMap,y=(K)=>{var J=N.get(K),Z;if(J)return J;if(J=D({},"__esModule",{value:!0}),K&&typeof K==="object"||typeof K==="function")$(K).map((q)=>!k.call(J,q)&&D(J,q,{get:()=>K[q],enumerable:!(Z=w(K,q))||Z.enumerable}));return N.set(K,J),J};var g=(K,J)=>{for(var Z in J)D(K,Z,{get:J[Z],enumerable:!0,configurable:!0,set:(q)=>J[Z]=()=>q})};var m={};g(m,{$watch:()=>L,$router:()=>Q,$mount:()=>E,$if:()=>T,$html:()=>x,$for:()=>O,$:()=>_});var U=null,I=null,P=new Set,C=!1,M=new WeakMap,v=()=>{if(C)return;C=!0;while(P.size>0){let K=Array.from(P).sort((J,Z)=>(J.depth||0)-(Z.depth||0));P.clear();for(let J of K)if(!J._deleted)J()}C=!1},b=(K)=>{if(U&&!U._deleted)K.add(U),U._deps.add(K)},S=(K)=>{for(let J of K){if(J===U||J._deleted)continue;if(J._isComputed){if(J.markDirty(),J._subs)S(J._subs)}else P.add(J)}if(!C)queueMicrotask(v)},V=(K)=>{if(K._cleanups)K._cleanups.forEach((J)=>J()),K._cleanups.clear();K.childNodes?.forEach(V)},F=(K)=>{let J=new Set,Z=I,q=document.createElement("div");q.style.display="contents",I={cleanups:J};try{let W=K({onCleanup:(j)=>J.add(j)}),Y=(j)=>{if(!j)return;if(j._isRuntime)J.add(j.destroy),q.appendChild(j.container);else if(Array.isArray(j))j.forEach(Y);else q.appendChild(j instanceof Node?j:document.createTextNode(String(j)))};Y(W)}finally{I=Z}return{_isRuntime:!0,container:q,destroy:()=>{J.forEach((W)=>W()),V(q),q.remove()}}},_=(K,J=null)=>{if(typeof K==="function"){let W=new Set,Y,j=!0,X=()=>{if(X._deleted)return;X._deps.forEach((G)=>G.delete(X)),X._deps.clear();let z=U;U=X;try{let G=K();if(!Object.is(Y,G)||j)Y=G,j=!1,S(W)}finally{U=z}};if(X._deps=new Set,X._isComputed=!0,X._subs=W,X._deleted=!1,X.markDirty=()=>j=!0,X.stop=()=>{X._deleted=!0,X._deps.forEach((z)=>z.delete(X)),W.clear()},I)I.cleanups.add(X.stop);return()=>{if(j)X();return b(W),Y}}let Z=K;if(J)try{let W=localStorage.getItem(J);if(W!==null)Z=JSON.parse(W)}catch(W){console.warn("SigPro: LocalStorage locked",W)}let q=new Set;return(...W)=>{if(W.length){let Y=typeof W[0]==="function"?W[0](Z):W[0];if(!Object.is(Z,Y)){if(Z=Y,J)localStorage.setItem(J,JSON.stringify(Z));S(q)}}return b(q),Z}},L=(K,J)=>{let Z=Array.isArray(K),q=Z?J:K,W=Z?K:null;if(typeof q!=="function")return()=>{};let Y=I,j=()=>{if(j._deleted)return;j._deps.forEach((G)=>G.delete(j)),j._deps.clear(),j._cleanups.forEach((G)=>G()),j._cleanups.clear();let X=U,z=I;U=j,I={cleanups:j._cleanups},j.depth=X?X.depth+1:0;try{if(Z)U=null,q(),U=j,W.forEach((G)=>typeof G==="function"&&G());else q()}finally{U=X,I=z}};if(j._deps=new Set,j._cleanups=new Set,j._deleted=!1,j.stop=()=>{if(j._deleted)return;if(j._deleted=!0,P.delete(j),j._deps.forEach((X)=>X.delete(j)),j._cleanups.forEach((X)=>X()),Y)Y.cleanups.delete(j.stop)},Y)Y.cleanups.add(j.stop);return j(),j.stop},x=(K,J={},Z=[])=>{if(J instanceof Node||Array.isArray(J)||typeof J!=="object")Z=J,J={};let q=document.createElement(K),W=(j,X)=>(j==="src"||j==="href")&&String(X).toLowerCase().includes("javascript:")?"#":X;q._cleanups=new Set;for(let[j,X]of Object.entries(J)){if(j==="ref"){typeof X==="function"?X(q):X.current=q;continue}let z=typeof X==="function";if(["INPUT","TEXTAREA","SELECT"].includes(q.tagName)&&(j==="value"||j==="checked")&&z){q._cleanups.add(L(()=>{let H=X();if(q[j]!==H)q[j]=H}));let B=j==="checked"?"change":"input",A=(H)=>X(H.target[j]);q.addEventListener(B,A),q._cleanups.add(()=>q.removeEventListener(B,A))}else if(j.startsWith("on")){let B=j.slice(2).toLowerCase().split(".")[0],A=(H)=>X(H);q.addEventListener(B,A),q._cleanups.add(()=>q.removeEventListener(B,A))}else if(z)q._cleanups.add(L(()=>{let B=W(j,X());if(j==="class")q.className=B||"";else B==null?q.removeAttribute(j):q.setAttribute(j,B)}));else q.setAttribute(j,W(j,X))}let Y=(j)=>{if(Array.isArray(j))return j.forEach(Y);if(typeof j==="function"){let X=document.createTextNode("");q.appendChild(X);let z=[];q._cleanups.add(L(()=>{let G=j(),R=(Array.isArray(G)?G:[G]).map((B)=>B?._isRuntime?B.container:B instanceof Node?B:document.createTextNode(B??""));z.forEach((B)=>{V(B),B.remove()}),R.forEach((B)=>X.parentNode?.insertBefore(B,X)),z=R}))}else q.appendChild(j instanceof Node?j:document.createTextNode(j??""))};return Y(Z),q},T=(K,J,Z=null)=>{let q=document.createTextNode(""),W=x("div",{style:"display:contents"},[q]),Y=null,j=null;return L(()=>{let X=!!(typeof K==="function"?K():K);if(X!==j){if(j=X,Y)Y.destroy();let z=X?J:Z;if(z)Y=F(()=>typeof z==="function"?z():z),W.insertBefore(Y.container,q)}}),W};T.not=(K,J,Z)=>T(()=>!(typeof K==="function"?K():K),J,Z);var O=(K,J,Z)=>{let q=document.createTextNode(""),W=x("div",{style:"display:contents"},[q]),Y=new Map;return L(()=>{let j=(typeof K==="function"?K():K)||[],X=new Map,z=[];for(let R=0;RJ(B,R));else Y.delete(A);X.set(A,H),z.push(A)}Y.forEach((R)=>{R.destroy(),R.container.remove()});let G=q;for(let R=z.length-1;R>=0;R--){let B=X.get(z[R]);if(B.container.nextSibling!==G)W.insertBefore(B.container,G);G=B.container}Y=X}),W},Q=(K)=>{let J=_(window.location.hash.replace(/^#/,"")||"/");window.addEventListener("hashchange",()=>J(window.location.hash.replace(/^#/,"")||"/"));let Z=x("div",{class:"router-outlet"}),q=null;return L([J],async()=>{let W=J(),Y=K.find((j)=>{let X=j.path.split("/").filter(Boolean),z=W.split("/").filter(Boolean);return X.length===z.length&&X.every((G,R)=>G.startsWith(":")||G===z[R])})||K.find((j)=>j.path==="*");if(Y){let j=Y.component;if(typeof j==="function"&&j.toString().includes("import"))j=(await j()).default||await j();let X={};if(Y.path.split("/").filter(Boolean).forEach((z,G)=>{if(z.startsWith(":"))X[z.slice(1)]=W.split("/").filter(Boolean)[G]}),q)q.destroy();if(Q.params)Q.params(X);q=F(()=>{try{return typeof j==="function"?j(X):j}catch(z){return x("div",{class:"p-4 text-error"},"Error loading view")}}),Z.appendChild(q.container)}}),Z};Q.params=_({});Q.to=(K)=>window.location.hash=K.replace(/^#?\/?/,"#/");Q.back=()=>window.history.back();Q.path=()=>window.location.hash.replace(/^#/,"")||"/";var E=(K,J)=>{let Z=typeof J==="string"?document.querySelector(J):J;if(!Z)return;if(M.has(Z))M.get(Z).destroy();let q=F(typeof K==="function"?K:()=>K);return Z.replaceChildren(q.container),M.set(Z,q),q},h={$:_,$watch:L,$html:x,$if:T,$for:O,$router:Q,$mount:E};if(typeof window<"u")((J)=>{Object.keys(J).forEach((q)=>{window[q]=J[q]}),"div span p h1 h2 h3 h4 h5 h6 br hr section article aside nav main header footer address ul ol li dl dt dd a em strong small i b u mark time sub sup pre code blockquote details summary dialog form label input textarea select button option fieldset legend table thead tbody tfoot tr th td caption img video audio canvas svg iframe picture source progress meter".split(/\s+/).forEach((q)=>{let W=q.charAt(0).toUpperCase()+q.slice(1);if(!(W in window))window[W]=(Y,j)=>x(q,Y,j)}),window.SigPro=Object.freeze(J)})(h);})(); diff --git a/rollup.config.js b/rollup.config.js index 943ad74..5d87514 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -45,5 +45,18 @@ export default [ }, plugins: [terser()] } + }, + { + input: './index.js', + external: ['sigpro'], + output: { + file: './docs/sigpro-ui.umd.min.js', + format: 'iife', + name: 'SigProUI', + globals: { + sigpro: 'SigPro' + }, + plugins: [terser()] + } } ]; \ No newline at end of file diff --git a/src/components/Dropdown.js b/src/components/Dropdown.js index b12d108..fdbbf60 100644 --- a/src/components/Dropdown.js +++ b/src/components/Dropdown.js @@ -1,37 +1,53 @@ -import { $html } from "sigpro"; +import { $html, $for } from "sigpro"; import { val } from "../core/utils.js"; -/** DROPDOWN */ export const Dropdown = (props, children) => { - const { label, icon, ...rest } = props; + const { label, icon, items, ...rest } = props; - return $html( - "div", - { - ...rest, - class: () => `dropdown ${val(props.class) || props.class || ""}`, - }, - [ - $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 - ], - ), - $html( - "ul", - { - tabindex: 0, - class: "dropdown-content z-[50] menu p-2 shadow bg-base-100 rounded-box min-w-max border border-base-300", - }, - [typeof children === "function" ? children() : children], - ), - ], - ); -}; + 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) => + $html("li", {}, [ + $html("a", { + class: item.class || "", + onclick: (e) => { + if (item.onclick) item.onclick(e); + if (document.activeElement) document.activeElement.blur(); + } + }, [ + 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: () => `dropdown ${val(props.class) || ""}`, + }, [ + $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() + ]); +}; \ No newline at end of file diff --git a/src/components/Fab.js b/src/components/Fab.js index 5fa655e..da09437 100644 --- a/src/components/Fab.js +++ b/src/components/Fab.js @@ -3,18 +3,15 @@ import { val } from "../core/utils.js"; /** FAB (Floating Action Button) */ export const Fab = (props) => { - const { icon, label, actions = [], position = "bottom-6 right-6", ...rest } = props; + const { icon, label, actions = [], position = "bottom-6 right-6", class: className = "", ...rest } = props; return $html( "div", { ...rest, - class: () => `fab fixed ${val(position)} flex flex-col-reverse items-end gap-3 z-[100] ${ - props.class || "" - }`, + class: `fab absolute ${position} flex flex-col-reverse items-end gap-3 z-[100] ${className}`, }, [ - // Botón principal $html( "div", { @@ -28,7 +25,6 @@ export const Fab = (props) => { ], ), - // Acciones secundarias (se despliegan hacia arriba) ...val(actions).map((act) => $html("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, @@ -48,4 +44,4 @@ export const Fab = (props) => { ), ], ); -}; +}; \ No newline at end of file