OPtimized components
All checks were successful
Deploy Docs to Synology / deploy (push) Successful in 4s

This commit is contained in:
2026-04-26 23:33:55 +02:00
parent 971133d430
commit e3e5082247
15 changed files with 438 additions and 755 deletions

View File

@@ -11,7 +11,6 @@ export const rand = (r) => `${r}-${Math.random().toString(36).slice(2, 9)}`
export const close = () => document.activeElement?.blur()
export const listKey = (items, isOpen) => {
const cursor = $(-1);
watch(() => { if (!get(isOpen)) cursor(-1) });
const onKey = (e, select) => {
const list = get(items), i = cursor(), len = list.length;
if (!len) return;
@@ -19,7 +18,7 @@ export const listKey = (items, isOpen) => {
k === 'ArrowDown' ? (e.preventDefault(), isOpen(true), cursor(Math.min(i + 1, len - 1))) :
k === 'ArrowUp' ? (e.preventDefault(), cursor(Math.max(i - 1, 0))) :
k === 'Enter' ? (i >= 0 && (e.preventDefault(), select(list[i]))) :
k === 'Escape' ? isOpen(false) : null;
k === 'Escape' ? (isOpen(false), cursor(-1)) : null;
};
return { cursor, onKey };
};
@@ -62,7 +61,7 @@ export const Autocomplete = ({ items, value, onselect, placeholder = 'Buscar...'
isOpen(true);
},
onfocus: () => isOpen(true),
onblur: () => setTimeout(() => isOpen(false), 150),
onblur: () => setTimeout(() => { isOpen(false); cursor(-1); }, 150),
onkeydown: (e) => onKey(e, pick)
}),
when(isOpen, () =>
@@ -179,14 +178,10 @@ export const Calendar = (p) => {
) : null
])
}
export const Card = (p, c) => {
if (!p.title && !p.body && !p.actions && !c) return h('div', { ...p, class: cls('card', p.class) }, c)
return h('div', { ...p, class: cls('card', p.class) }, [
p.title && h('div', { class: cls('card-title', p.titleClass) }, p.title),
(p.body || c) && h('div', { class: cls('card-body', p.bodyClass) }, p.body || c),
p.actions && h('div', { class: cls('card-actions', p.actionsClass) }, p.actions)
].filter(Boolean))
}
export const Card = (p, c) => h('div', { ...p, class: cls('card', p.class) }, c);
export const CardTitle = (p, c) => h('div', { ...p, class: cls('card-title', p.class) }, c);
export const CardBody = (p, c) => h('div', { ...p, class: cls('card-body', p.class) }, c);
export const CardActions = (p, c) => h('div', { ...p, class: cls('card-actions', p.class) }, c);
export const Carousel = (p, c) => h("div", { ...p, class: cls("carousel", p.class) }, c);
export const CarouselItem = (p, c) => h("div", { ...p, class: cls("carousel-item", p.class) }, c);
export const Chat = (p, c) => h("div", { ...p, class: cls("chat", p.class) }, c);
@@ -286,20 +281,15 @@ export const Datepicker = (p) => {
])
])
}
export const Drawer = (p, c) => {
const id = p.id || rand("drawer")
return h('div', { class: cls('drawer', p.class) }, [
h('input', { id, type: 'checkbox', class: 'drawer-toggle', checked: () => get(p.open), onchange: (e) => isFn(p.open) && p.open(e.target.checked) }),
h('div', { class: 'drawer-side' }, [h('label', { for: id, class: 'drawer-overlay', onclick: () => isFn(p.open) && p.open(false) }), h('div', { class: 'min-h-full bg-base-200 w-80 p-4' }, () => get(p.side))]),
h('div', { class: 'drawer-content' }, c)])
}
export const Drawer = (p, c) => div({ ...p, class: cls('drawer', p.class) }, c)
export const DrawerToggle = (p) => input({ ...p, type: 'checkbox', class: 'drawer-toggle', checked: () => get(p.checked), onchange: (e) => isFn(p.checked) && p.checked(e.target.checked) })
export const DrawerContent = (p, c) => div({ ...p, class: cls('drawer-content', p.class) }, c)
export const DrawerSide = (p, c) => div({ ...p, class: cls('drawer-side', p.class) }, c)
export const DrawerOverlay = (p) => label({ ...p, for: p.for, class: cls('drawer-overlay', p.class) })
export const Divider = (p) => h("div", { ...p, class: cls("divider", p.class) });
export const Dropdown = (p, c) => {
return h('div', { ...p, class: cls('dropdown', p.class) }, [
h('div', { tabindex: '0', role: 'button', class: cls('btn', p.buttonClass) }, p.label),
h('div', { tabindex: '-1', class: 'dropdown-content' }, c)
])
}
export const Dropdown = (p, c) => (h('div', { ...p, class: cls('dropdown', p.class) }, c));
export const DropdownButton = (p, c) => (h('div', { ...p, tabindex: '0', role: 'button', class: cls('btn', p.class) }, c));
export const DropdownContent = (p, c) => (h('div', { ...p, tabindex: '0', class: cls('dropdown-content', p.class) }, c));
export const Fab = (p, c) => h("div", { class: "fab" }, [h('div', { tabindex: "0", role: "button", class: cls('btn', p.class) }, Icon(p.icon)), c]);
export const Fieldset = (p, c) => h("fieldset", { class: cls("fieldset", p.class) }, [h("legend", { class: "fieldset-legend" }, p.label), c])
export const Fileinput = (p) => {
@@ -380,7 +370,6 @@ export const Input = (p) => {
const inputType = () => isPassword
? (get(showPassword) ? 'text' : 'password')
: (p.type || 'text');
return h("div", {
class: "input-container",
onfocusin: () => isFocused(true),
@@ -395,10 +384,10 @@ export const Input = (p) => {
label && !float ? h('span', { class: 'label' }, label) : null,
left ?? null,
h('input', { ...rest, type: inputType, class: 'grow', pattern: pattern, placeholder: placeholder || label || ' ', value: value }), right ?? null,
isPassword ? h('label', { class: 'swap swap-rotate ml-2' }, [
h('input', { type: 'checkbox', onchange: (e) => showPassword(e.target.checked) }),
h('span', { class: 'swap-on icon-[lucide--eye]' }),
h('span', { class: 'swap-off icon-[lucide--eye-off]' })
isPassword ? Swap({ class: 'ml-2' }, [
SwapToggle({ value: showPassword, class: "swap-rotate" }),
SwapOn({}, Icon('icon-[lucide--eye]')),
SwapOff({}, Icon('icon-[lucide--eye-off]')),
]) : null
]),
hint ? h('div', { class: "validator-hint" }, hint) : null,
@@ -524,30 +513,24 @@ export const SkeletonText = (p) => h("span", { ...p, class: cls("skeleton skelet
export const Stack = (p, c) => h("div", { ...p, class: cls("stack", p.class) }, c);
export const Steps = (p, c) => h("ul", { ...p, class: cls("steps", p.class) }, c);
export const Step = (p, c) => h("li", { ...p, class: cls("step", p.class), "data-content": p.dataContent }, c);
export const Swap = (p) => h("label", { ...p, class: cls("swap", p.class) }, [
h("input", { type: "checkbox", checked: () => get(p.value), onchange: (e) => isFn(p.value) && p.value(e.target.checked) }),
h("div", { class: "swap-on" }, p.on),
h("div", { class: "swap-off" }, p.off)
]);
export const Table = (p) => {
if (p.children !== undefined) return h('table', { class: cls('table', p.class), ...p }, p.children)
const { items, columns = [], header = true, keyFn, ...rest } = p
const hd = header !== false && columns.some(c => c.label) ? h('thead', {}, h('tr', {}, columns.map(c => h('th', { class: c.class }, c.label)))) : null
const bd = h('tbody', {}, each(
() => get(items) || [],
(it, idx) => h('tr', {}, columns.map(c => {
const v = c.render ? c.render(it, idx) : it[c.key]
return h('td', { class: c.class }, v)
}))
))
return h('table', { class: cls('table', rest.class), ...rest }, [hd, bd])
export const Swap = (p, c) => h('label', { ...p, class: cls('swap', p.class) }, c)
export const SwapToggle = (p) => h('input', { type: 'checkbox', checked: () => get(p.value), onchange: (e) => isFn(p.value) && p.value(e.target.checked), class: p.class })
export const SwapOn = (p, c) => h('div', { ...p, class: cls('swap-on', p.class) }, c)
export const SwapOff = (p, c) => h('div', { ...p, class: cls('swap-off', p.class) }, c)
export const Table = (p, c) => h('table', { ...p, class: cls('table', p.class) }, c)
export const TableItems = ({ items, columns = [], header = true }) => {
const head = header !== false && columns.some(c => c.label) ? h('thead', {}, h('tr', {}, columns.map(c => h('th', { class: c.class }, c.label)))) : null
const body = h('tbody', {}, () => {
const list = get(items) || []
return list.map((it, idx) => h('tr', {}, columns.map(c => { const v = c.render ? c.render(it, idx) : it[c.key]; return h('td', { class: c.class }, v) })))
})
return [head, body].filter(Boolean)
}
export const Tabs = (p, c) => {
if (!p.items) {
const { class: className, ...rest } = p
return h('div', { ...rest, class: cls('tabs', className) }, c)
}
const { items, activeIndex, onClose, class: className, ...rest } = p
const get = x => (isFn(x) ? x() : x)
const closeH = onClose || (isFn(items) ? (idx, item) => {
@@ -580,10 +563,7 @@ export const Tabs = (p, c) => {
})
}
export const Textarea = (p) => h("textarea", { ...p, class: cls("textarea", p.class) });
export const TextRotate = (p) => {
const words = Array.isArray(p.words) ? p.words : (typeof p.words === 'string' ? p.words.split(',') : []);
return h("span", { ...p, class: cls("text-rotate", p.class) }, h("span", {}, words.map(w => h("span", {}, w))));
};
export const Textrotate = (p, c) => h('span', { ...p, class: cls('text-rotate', p.class) }, c)
export const Timeline = (p, c) => h("ul", { ...p, class: cls("timeline", p.class) }, c);
export const Toast = (message, type = "alert-success", duration = 3500) => {
let container = document.getElementById("sigpro-toast-container");