Files
sigpro-ui/docs/demo.md
natxocc 97f481e22f
All checks were successful
Deploy Docs to Synology / deploy (push) Successful in 4s
Autocomplete works with array and objects
2026-05-02 20:52:35 +02:00

1246 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SigPro Demo Comprehensive Examples
---
## Accordion
<div id="demo-accordion"></div>
```js
const accItems = $([
{
title: "What is SigPro?",
content:
"A lightweight UI library built on DaisyUI and a finegrained reactivity system.",
open: true,
},
{
title: "Why use it?",
content:
"No build step, minimal boilerplate, and all components are just JavaScript functions.",
},
{
title: "Browser support?",
content: "All modern browsers that support ES2020+",
},
]);
mount(
div({ class: "flex flex-col gap-8" }, [
Accordion({
items: accItems,
class: "collapse-arrow bg-base-100 border border-base-300",
}),
]),
"#demo-accordion",
);
```
---
## Alert
<div id="demo-alert"></div>
```js
mount(
Alert({ class: "alert-info" }, [
span({ class: "icon-[lucide--info] text-lg" }),
span({}, "You have 2 new messages"),
]),
"#demo-alert",
);
```
---
## Autocomplete
<div id="demo-autocomplete"></div>
```js
const selectedFruit = $("");
const fruitItems = [
{ label: "Apple", value: "apple" },
{ label: "Banana", value: "banana" },
{ label: "Orange", value: "orange" },
{ label: "Mango", value: "mango" },
{ label: "Carrot", value: "carrot" },
{ label: "Broccoli", value: "broccoli" },
{ label: "Spinach", value: "spinach" },
{ label: "Potato", value: "potato" },
];
const selectedColor = $("");
const colorItems = ["Red", "Blue", "Green", "Yellow", "Black", "White", "Purple", "Cyan"];
mount(
h('div', { class: 'p-8 flex flex-col gap-10' }, [
h('div', {}, [
h('h3', { class: 'font-bold mb-2' }, 'Objetos:'),
Autocomplete({
items: fruitItems,
value: selectedFruit,
placeholder: "Search fruit...",
onselect: (v) => console.log("Obj:", v)
}),
h('span', { class: 'text-xs' }, () => `Signal: ${selectedFruit()}`)
]),
h('div', {}, [
h('h3', { class: 'font-bold mb-2' }, 'Array Plano:'),
Autocomplete({
items: colorItems,
value: selectedColor,
placeholder: "Search color...",
onselect: (v) => console.log("Str:", v)
}),
h('span', { class: 'text-xs' }, () => `Signal: ${selectedColor()}`)
])
]),
"#demo-autocomplete"
);
```
---
## Avatar & AvatarGroup
<div id="demo-avatar"></div>
```js
mount(
div({ class: "flex flex-col gap-4" }, [
Avatar(
{ class: "w-24 rounded-full" },
img({
src: "https://img.daisyui.com/images/profile/demo/kenobee@192.webp",
}),
),
AvatarGroup({}, [
Avatar(
{ class: "w-12" },
img({
src: "https://img.daisyui.com/images/profile/demo/kenobee@192.webp",
}),
),
Avatar(
{ class: "w-12" },
img({
src: "https://img.daisyui.com/images/profile/demo/anakeen@192.webp",
}),
),
Avatar(
{ class: "w-12" },
img({
src: "https://img.daisyui.com/images/profile/demo/kenobee@192.webp",
}),
),
]),
]),
"#demo-avatar",
);
```
---
## Badge
<div id="demo-badge"></div>
```js
mount(
div({ class: "flex gap-2" }, [
Badge({}, "New"),
Badge({ class: "badge-outline" }, "Sale"),
Badge({ class: "badge-error" }, "Deleted"),
]),
"#demo-badge",
);
```
---
## Breadcrumbs
<div id="demo-breadcrumbs"></div>
```js
mount(
Breadcrumbs({}, [
ul({}, [
li({}, a({ href: "#" }, "Home")),
li({}, a({ href: "#" }, "Docs")),
li({}, span({ class: "font-bold" }, "Components")),
]),
]),
"#demo-breadcrumbs",
);
```
---
## Button
<div id="demo-button"></div>
```js
const count = $(0);
mount(
div({ class: "flex gap-2 items-center" }, [
Button(
{
class: "btn-primary",
onclick: () => count(count() + 1),
},
() => `Clicked ${count()} times`,
),
Button({ class: "btn-outline", disabled: true }, "Disabled"),
]),
"#demo-button",
);
```
---
## Calendar
<div id="demo-calendar"></div>
```js
const calendarRange = $({
start: "2026-04-01",
end: "2026-04-15",
startHour: 9,
endHour: 18,
});
mount(
Calendar({
value: calendarRange,
range: true,
hour: true,
onChange: (val) => console.log("Range:", val),
}),
"#demo-calendar",
);
```
---
## Card, CardTitle, CardBody & CardActions
<div id="demo-card"></div>
```js
mount(
Card({ class: "w-80 bg-base-100 shadow-xl" }, [
CardBody({}, [
CardTitle({}, "Card Title"),
p({}, "This is a card with title, body and actions."),
CardActions({ class: "justify-end" }, [
Button({ class: "btn-primary btn-sm" }, "Buy"),
]),
]),
]),
"#demo-card",
);
```
---
## Carousel & CarouselItem
<div id="demo-carousel"></div>
```js
mount(
Carousel({ class: "carousel-vertical rounded-box h-96" }, [
CarouselItem(
{ class: "h-full" },
img({
src: "https://img.daisyui.com/images/stock/photo-1559703248-dcaaec9fab78.webp",
}),
),
CarouselItem(
{ class: "h-full" },
img({
src: "https://img.daisyui.com/images/stock/photo-1565098772267-60af42b81ef2.webp",
}),
),
CarouselItem(
{ class: "h-full" },
img({
src: "https://img.daisyui.com/images/stock/photo-1572635148818-ef6fd45eb394.webp",
}),
),
]),
"#demo-carousel",
);
```
---
## Chat, ChatImage, ChatHeader, ChatBubble & ChatFooter
<div id="demo-chat"></div>
```js
mount(
div({ class: "flex flex-col gap-4" }, [
// Left side
Chat({ class: "chat-start" }, [
ChatImage(
{},
img({
src: "https://img.daisyui.com/images/profile/demo/kenobee@192.webp",
alt: "Obi-Wan",
}),
),
ChatHeader({}, [
"Obi-Wan Kenobi",
time({ class: "text-xs opacity-50" }, "12:45"),
]),
ChatBubble({}, "You were the Chosen One!"),
ChatFooter({ class: "opacity-50" }, "Delivered"),
]),
// Right side
Chat({ class: "chat-end" }, [
ChatImage(
{},
img({
src: "https://img.daisyui.com/images/profile/demo/anakeen@192.webp",
alt: "Anakin",
}),
),
ChatHeader({}, [
"Anakin",
time({ class: "text-xs opacity-50" }, "12:46"),
]),
ChatBubble({}, "I hate you!"),
ChatFooter({ class: "opacity-50" }, "Seen at 12:46"),
]),
]),
"#demo-chat",
);
```
---
## Checkbox
<div id="demo-checkbox"></div>
```js
const checked = $(false);
mount(
div({ class: "flex items-center gap-2" }, [
Checkbox({
checked,
onchange: (e) => checked(e.target.checked),
}),
span({}, () => `Accept terms (${checked() ? "Yes" : "No"})`),
]),
"#demo-checkbox",
);
```
---
## Colorpicker & ColorPalette
<div id="demo-colorpicker"></div>
```js
const color = $("#000000");
mount(
div({ class: "flex flex-col gap-4" }, [
Colorpicker({
value: color,
label: "Pick a color",
onchange: (c) => console.log("Color:", c),
}),
p({}, () => `Selected: ${color()}`),
ColorPalette({
value: color,
onchange: (c) => color(c),
}),
]),
"#demo-colorpicker",
);
```
---
## Datepicker
<div id="demo-datepicker"></div>
```js
const dateRange = $("");
mount(
Datepicker({
value: dateRange,
range: true,
hour: true,
placeholder: "Select a date range",
onChange: (val) => console.log("Date:", val),
}),
"#demo-datepicker",
);
```
---
## Divider
<div id="demo-divider"></div>
```js
mount(
div({ class: "flex flex-col gap-2" }, [
p(
{ class: "card bg-base-300 rounded-box grid h-20 place-items-center" },
"Above",
),
Divider({}, "OR"),
p(
{ class: "card bg-base-300 rounded-box grid h-20 place-items-center" },
"Below",
),
]),
"#demo-divider",
);
```
---
## Drawer
<div id="demo-drawer"></div>
```js
const leftOpen = $(false);
const rightOpen = $(false);
mount(
Drawer({ open: leftOpen }, [
DrawerToggle({ id: "left-drawer", checked: leftOpen }),
DrawerContent({}, [
Drawer({ open: rightOpen, class: "drawer-end" }, [
DrawerToggle({ id: "right-drawer", checked: rightOpen }),
DrawerContent({}, [
div({ class: "p-4" }, [
h3({ class: "text-lg font-bold" }, "Central Panel"),
label({ for: "left-drawer", class: "btn" }, "Open Left"),
label({ for: "right-drawer", class: "btn ml-2" }, "Open Right"),
p({}, "Main Content..."),
]),
]),
DrawerSide({}, [
DrawerOverlay({ for: "right-drawer" }),
div(
{ class: "min-h-full bg-base-200 w-60 p-4" },
h4({ class: "font-semibold" }, "Right Menu"),
),
]),
]),
]),
DrawerSide({}, [
DrawerOverlay({ for: "left-drawer" }),
div(
{ class: "min-h-full bg-base-200 w-60 p-4" },
h4({ class: "font-semibold" }, "Left Menu"),
),
]),
]),
"#demo-drawer",
);
```
---
## Dropdown, DropdownButton & DropdownContent
<div id="demo-dropdown"></div>
```js
mount(
div({ class: "flex gap-4" }, [
Dropdown({}, [
DropdownButton({}, "Options"),
DropdownContent(
{ class: "menu bg-base-100 rounded-box w-52 p-2 shadow" },
[
Menu({
items: [
{ label: "Edit", onclick: () => hide() },
{ label: "Delete", onclick: () => hide() },
{ label: "Archive" },
],
}),
],
),
]),
Dropdown({}, [
DropdownButton({}, "More"),
DropdownContent(
{ class: "menu bg-base-100 rounded-box w-40 p-2 shadow" },
ul({}, [
li(
{},
a(
{
href: "#",
onclick: (e) => {
e.preventDefault();
hide();
},
},
"Profile",
),
),
li(
{},
a(
{
href: "#",
onclick: (e) => {
e.preventDefault();
hide();
},
},
"Logout",
),
),
]),
),
]),
]),
"#demo-dropdown",
);
```
---
## Editor (Rich Text)
<div id="demo-editor"></div>
```js
const htmlContent = $("<p><strong>Hello</strong> <em>world</em>!</p>");
mount(
Editor({
value: htmlContent,
onchange: (html) => console.log("Content updated"),
class: "max-w-2xl",
}),
"#demo-editor",
);
```
---
## Fab
<div id="demo-fab"></div>
```js
mount(
div({ class: "flex gap-4" }, [
Fab({ class: "btn-lg btn-circle btn-secondary", icon: "R" }, [
Button({}, "C"),
Button({}, "B"),
Button({}, "A"),
]),
]),
"#demo-fab",
);
```
---
## Fieldset
<div id="demo-fieldset"></div>
```js
mount(
div({ class: "flex gap-4 bg" }, [
Fieldset(
{
label: "Personal Info",
class: "bg-base-200 border-base-300 rounded-box w-xs border gap-3 p-4",
},
[
Input({ label: "Name", float: true, value: $("") }),
Select({
label: "Country",
float: true,
items: ["Spain", "France", "Italy"],
value: $(""),
}),
],
),
Fieldset({ class: "bg-base-200 p-4 rounded-box", label: "Any content" }, [
div({}, "Any content"),
]),
]),
"#demo-fieldset",
);
```
---
## Fileinput
<div id="demo-fileinput"></div>
```js
const files = $([]);
mount(
Fileinput({
max: 5,
accept: "image/*,.pdf",
onselect: (selectedFiles) => console.log("Files:", selectedFiles),
value: files,
}),
"#demo-fileinput",
);
```
---
## Icon
<div id="demo-icon"></div>
```js
mount(
div({ class: "flex gap-4 text-xl" }, [
Icon("icon-[lucide--home]"),
Icon("icon-[lucide--settings]"),
Icon("❤️"), // emoji fallback
]),
"#demo-icon",
);
```
---
## Indicator
<div id="demo-indicator"></div>
```js
mount(
Indicator({ value: "3" }, [
Button({ class: "btn-circle" }, Icon("icon-[lucide--bell]")),
]),
"#demo-indicator",
);
```
---
## Input
<div id="demo-input"></div>
```js
const username = $("");
const password = $("");
mount(
div({ class: "flex flex-col gap-4 w-80" }, [
Input({
label: "Username",
float: true,
value: username,
left: Icon("icon-[lucide--user]"),
}),
Input({
type: "password",
label: "Password",
float: true,
value: password,
left: Icon("icon-[lucide--lock]"),
}),
]),
"#demo-input",
);
```
---
## Kbd
<div id="demo-kbd"></div>
```js
mount(
p({}, ["Press ", Kbd({}, "Ctrl"), " + ", Kbd({}, "S"), " to save"]),
"#demo-kbd",
);
```
---
## List & ListRows
<div id="demo-list"></div>
```js
const people = $([
{ name: "Alice", online: true },
{ name: "Bob", online: false },
]);
mount(
[
List({ class: "bg-base-100 rounded-box shadow-md" }, [
each(people, (p) =>
li({ class: "list-row" }, [
Badge({ class: p.online ? "badge-success" : "badge-ghost" }),
p.name,
]),
),
]),
Divider({}, "OR"),
// _(Alternatively, using `ListRows`:)_
List({ class: "bg-base-100 rounded-box shadow-md" }, [
ListRows({
items: people,
render: (p) => [
Badge({ class: p.online ? "badge-success" : "badge-ghost" }),
p.name,
],
}),
]),
],
"#demo-list",
);
```
---
## Loading
<div id="demo-loading"></div>
```js
mount(Loading({ class: "loading-lg text-primary" }), "#demo-loading");
```
---
## Menu
<div id="demo-menu"></div>
```js
const menuItems = $([
{ label: "Dashboard", href: "#" },
{ label: "Settings", children: [{ label: "Profile" }, { label: "Account" }] },
{ label: "Logout", onclick: () => alert("Logout") },
]);
mount(
Menu({ items: menuItems, class: "w-56 bg-base-200 rounded-box" }),
"#demo-menu",
);
```
---
## Modal
<div id="demo-modal"></div>
```js
const modalOpen = $(false);
mount(
div({}, [
Button({ class: "btn", onclick: () => modalOpen(true) }, "Open modal"),
Modal(
{
open: modalOpen,
title: "Congratulations!",
backdrop: true,
actions: [
form(
{ method: "dialog" },
Button({ class: "btn", onclick: () => modalOpen(false) }, "Close"),
),
],
},
[
p(
{},
"You have successfully created a reactive DaisyUI modal with SigPro.",
),
],
),
]),
"#demo-modal",
);
```
---
## Navbar
<div id="demo-navbar"></div>
```js
mount(
Navbar({ class: "bg-base-300 rounded-box" }, [
div({ class: "flex-1" }, a({ class: "btn btn-ghost text-xl" }, "SigPro")),
div(
{ class: "flex-none" },
Button({ class: "btn-square btn-ghost" }, Icon("icon-[lucide--menu]")),
),
]),
"#demo-navbar",
);
```
---
## Progress
<div id="demo-progress"></div>
```js
const progressVal = $(35);
mount(
div({ class: "flex flex-col gap-2" }, [
span({}, () => `${progressVal()}%`),
Progress({
value: progressVal,
max: 100,
class: "w-56"
}),
]),
"#demo-progress",
);
```
---
## Radial Progress
<div id="demo-radial"></div>
```js
const radialVal = $(70);
mount(
Radial({ value: radialVal, class: "text-primary" }, () => `${radialVal()}%`),
"#demo-radial",
);
```
---
## Radio
<div id="demo-radio"></div>
```js
const option = $("a");
mount(
div({ class: "flex gap-4" }, [
label({ class: "flex items-center gap-2" }, [
Radio({
name: "demo-radio",
value: "a",
checked: () => option() === "a",
onchange: () => option("a"),
}),
"Option A",
]),
label({ class: "flex items-center gap-2" }, [
Radio({
name: "demo-radio",
value: "b",
checked: () => option() === "b",
onchange: () => option("b"),
}),
"Option B",
]),
]),
"#demo-radio",
);
```
---
## Range
<div id="demo-range"></div>
```js
const rangeValue = $(25);
mount(
div({ class: "flex flex-col gap-2 w-60" }, [
Range({ min: 0, max: 100, value: rangeValue, class: "range-sm" }),
span({}, () => `Value: ${rangeValue()}`),
]),
"#demo-range",
);
```
---
## Rating & RatingItems
<div id="demo-rating"></div>
```js
const stars = $(3);
mount(
Rating({}, [
RatingItems({
count: 5,
value: stars,
name: "demo-rating",
class: "mask-star-2",
}),
]),
"#demo-rating",
);
```
---
## Select
<div id="demo-select"></div>
```js
const choice = $("css");
mount(
Select({
items: ["HTML", "CSS", "JavaScript"],
placeholder: "Pick a language",
value: choice,
float: true,
label: "Tech",
}),
"#demo-select",
);
```
---
## Skeleton & SkeletonText
<div id="demo-skeleton"></div>
```js
mount(
div({ class: "flex flex-col gap-4 w-52" }, [
Skeleton({ class: "h-32" }),
SkeletonText({ class: "h-4" }),
SkeletonText({ class: "h-4 w-3/4" }),
]),
"#demo-skeleton",
);
```
---
## Stack
<div id="demo-stack"></div>
```js
mount(
Stack({ class: "w-48" }, [
img({
src: "https://img.daisyui.com/images/stock/photo-1572635148818-ef6fd45eb394.webp",
class: "rounded-box",
}),
img({
src: "https://img.daisyui.com/images/stock/photo-1565098772267-60af42b81ef2.webp",
class: "rounded-box",
}),
img({
src: "https://img.daisyui.com/images/stock/photo-1559703248-dcaaec9fab78.webp",
class: "rounded-box",
}),
]),
"#demo-stack",
);
```
---
## Stats & Stat
<div id="demo-stats"></div>
```js
mount(
Stats({ class: "w-full" }, [
Stat({ title: "Downloads", value: "1,200", desc: "↑ 21% from last month" }),
Stat({ title: "New Users", value: "450", desc: "↑ 14% from last month" }),
Stat({ title: "Revenue", value: "$89k", desc: "↓ 1% from last month" }),
]),
"#demo-stats",
);
```
---
## Steps & Step
<div id="demo-steps"></div>
```js
mount(
Steps({ class: "steps-horizontal w-full" }, [
Step({ dataContent: "1", class: "step-primary" }, "Register"),
Step({ dataContent: "2", class: "step-primary" }, "Choose plan"),
Step({ dataContent: "3" }, "Purchase"),
Step({ dataContent: "4" }, "Enjoy"),
]),
"#demo-steps",
);
```
---
## Swap (Toggle)
<div id="demo-swap"></div>
```js
const isDark = $(false);
mount(
Swap({ class: "text-2xl" }, [
SwapToggle({ value: isDark, class: "swap-rotate" }),
SwapOn({}, span({ class: "icon-[lucide--moon]" })),
SwapOff({}, span({ class: "icon-[lucide--sun]" })),
]),
"#demo-swap",
);
```
---
## Table & TableItems
<div id="demo-table"></div>
```js
const tableData = $([
{ id: 1, name: "Alice", role: "Admin" },
{ id: 2, name: "Bob", role: "User" },
{ id: 3, name: "Charlie", role: "User" },
]);
const columns = [
{ key: "name", label: "Name", class: "font-bold" },
{ key: "role", label: "Role" },
{
label: "Action",
render: (item) =>
Button(
{ class: "btn-xs", onclick: () => alert(`Edit ${item.name}`) },
"Edit",
),
},
];
mount(
Table({ class: "w-full" }, TableItems({ items: tableData, columns })),
"#demo-table",
);
```
---
## Tabs
<div id="demo-tabs"></div>
```js
const activeTab = $(0);
const tabsData = $([
{ label: "Tab A", content: "Content of tab A" },
{ label: "Tab B", content: "Content of tab B", closable: true },
{ label: "Tab C", content: "Content of tab C" },
]);
mount(
Tabs({ class: "tabs-box", items: tabsData, activeIndex: activeTab }),
"#demo-tabs",
);
```
---
## Textarea
<div id="demo-textarea"></div>
```js
const bio = $("");
mount(
Textarea({ class: "w-80", placeholder: "Write something...", value: bio }),
"#demo-textarea",
);
```
---
## Textrotate
<div id="demo-textrotate"></div>
```js
mount(
Textrotate({ class: "text-2xl font-bold" }, [
span({}, "Hello"),
span({}, "Bonjour"),
span({}, "Hola"),
]),
"#demo-textrotate",
);
```
---
## Timeline
<div id="demo-timeline"></div>
```js
mount(
Timeline({ vertical: true }, [
li({}, [
div({ class: "timeline-start" }, "2024"),
div(
{ class: "timeline-middle" },
span({ class: "icon-[lucide--check]" }),
),
div({ class: "timeline-end timeline-box" }, "Project started"),
]),
li({}, [
div({ class: "timeline-start" }, "2025"),
div(
{ class: "timeline-middle" },
span({ class: "icon-[lucide--clock]" }),
),
div({ class: "timeline-end timeline-box" }, "First prototype"),
]),
]),
"#demo-timeline",
);
```
---
## Toast
<div id="demo-toast"></div>
```js
mount(
div({ class: "flex flex-wrap gap-2" }, [
Button({ class: "btn", onclick: () => Toast("File saved!") }, "Simple"),
Button(
{ class: "btn", onclick: () => Toast("Error!", "alert-error", 5000) },
"Error (5s)",
),
Button(
{
class: "btn",
onclick: () =>
Toast(
div({ class: "flex items-center gap-2" }, [
span({ class: "icon-[lucide--check] text-lg" }),
span({}, "Report generated"),
]),
"alert-success",
),
},
"With icon",
),
Button(
{
class: "btn",
onclick: () =>
Toast(
div({ class: "flex flex-col" }, [
strong({}, "ATTENTION!"),
span({}, "Error saving!"),
button(
{
class: "btn btn-xs mt-1",
onclick: () => console.log("Retry"),
},
"Retry",
),
]),
"alert-warning",
7000,
),
},
"Complex",
),
]),
"#demo-toast",
);
```
---
## Toggle
<div id="demo-toggle"></div>
```js
const toggleActive = $(false);
mount(
Toggle({
checked: toggleActive,
onchange: (e) => toggleActive(e.target.checked),
class: "toggle-primary",
}),
"#demo-toggle",
);
```
---
## Tooltip
<div id="demo-tooltip"></div>
```js
mount(
Tooltip(
{ tip: "Save changes", class: "tooltip-right tooltip-primary" },
Button({ class: "btn" }, "Save"),
),
"#demo-tooltip",
);
```