1120 lines
23 KiB
Markdown
1120 lines
23 KiB
Markdown
# SigPro Demo – Atomic Components
|
||
|
||
---
|
||
|
||
## Accordion
|
||
|
||
<div id="demo-accordion"></div>
|
||
|
||
```js
|
||
const accName = "demo-acc";
|
||
|
||
mount(
|
||
div({ class: "space-y-2" }, [
|
||
Accordion({ class: "collapse-arrow bg-base-100 border border-base-300" }, [
|
||
AccordionRadio({ name: accName, checked: true }),
|
||
AccordionTitle({}, "What is SigPro?"),
|
||
AccordionContent({}, "A lightweight UI library built on DaisyUI and a fine‑grained reactivity system."),
|
||
]),
|
||
Accordion({ class: "collapse-arrow bg-base-100 border border-base-300" }, [
|
||
AccordionRadio({ name: accName }),
|
||
AccordionTitle({}, "Why use it?"),
|
||
AccordionContent({}, "No build step, minimal boilerplate, and all components are just functions."),
|
||
]),
|
||
Accordion({ class: "collapse-arrow bg-base-100 border border-base-300" }, [
|
||
AccordionRadio({ name: accName }),
|
||
AccordionTitle({}, "Browser support?"),
|
||
AccordionContent({}, "All modern browsers that support ES2020+"),
|
||
]),
|
||
]),
|
||
"#demo-accordion"
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
## Alert
|
||
|
||
<div id="demo-alert"></div>
|
||
|
||
```js
|
||
mount(
|
||
Alert({ class: "alert-info" }, [
|
||
Icon({}, "icon-[lucide--info]"),
|
||
span({}, "You have 2 new messages"),
|
||
]),
|
||
"#demo-alert"
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
## Autocomplete
|
||
|
||
<div id="demo-autocomplete"></div>
|
||
|
||
```js
|
||
const fruitQuery = $("");
|
||
const fruitResults = $([]);
|
||
const fruits = ["Apple", "Banana", "Orange", "Mango", "Carrot", "Broccoli", "Spinach", "Potato"];
|
||
Filter(fruitQuery, fruits, fruitResults);
|
||
|
||
const colorQuery = $("");
|
||
const colorResults = $([]);
|
||
const colors = ["Red", "Blue", "Green", "Yellow", "Black", "White", "Purple", "Cyan"];
|
||
Filter(colorQuery, colors, colorResults);
|
||
|
||
const autocompleteCombo = (query, results, placeholder) =>
|
||
Combo({ class: "p-2 bg-base-100 rounded-box shadow-xl max-h-60 overflow-y-auto border border-base-300 z-50" },
|
||
LabelInput({}, [
|
||
Icon({}, "icon-[lucide--search]"),
|
||
Input({ placeholder, value: query, oninput: (e) => query(e.target.value) })
|
||
]),
|
||
{ content: Menu({ class: "flex-col flex-nowrap w-full p-0" },
|
||
each(results, (item) =>
|
||
MenuItem({ label: item, onclick: () => { query(item); hide() } })
|
||
)
|
||
)}
|
||
);
|
||
|
||
mount(
|
||
div({ class: "flex flex-col gap-10" }, [
|
||
div({}, [
|
||
h3({ class: "font-bold mb-2" }, "Fruits:"),
|
||
autocompleteCombo(fruitQuery, fruitResults, "Search fruit..."),
|
||
span({ class: "text-xs" }, () => `Signal: ${fruitQuery()}`),
|
||
]),
|
||
div({}, [
|
||
h3({ class: "font-bold mb-2" }, "Colors:"),
|
||
autocompleteCombo(colorQuery, colorResults, "Search color..."),
|
||
span({ class: "text-xs" }, () => `Signal: ${colorQuery()}`),
|
||
]),
|
||
]),
|
||
"#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" }, [
|
||
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"),
|
||
]),
|
||
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" }, [
|
||
Combo({ class: "p-0" },
|
||
LabelInput({ class: "flex items-center gap-2 cursor-pointer" }, [
|
||
div({ class: "size-5 rounded-sm", style: () => `background-color: ${color() || "#000"}` }),
|
||
span({ class: () => `grow text-left truncate ${!color() ? "opacity-50" : ""}` }, () => color() || "Pick a color"),
|
||
() => color() ? span({ class: "btn-ghost btn-xs btn-circle -mr-2", onmousedown: (e) => { e.stopPropagation(); color(null); } }, Icon({}, "icon-[lucide--x]")) : null
|
||
]),
|
||
{ content: ColorPalette({ value: color, onchange: (c) => { color(c); hide(); } }) }
|
||
),
|
||
p({}, () => `Selected: ${color()}`),
|
||
]),
|
||
"#demo-colorpicker"
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
## Datepicker
|
||
|
||
<div id="demo-datepicker"></div>
|
||
|
||
```js
|
||
const dateRange = $(null);
|
||
const displayRange = $(() => {
|
||
const v = dateRange();
|
||
if (!v) return "";
|
||
if (typeof v === "string") return v;
|
||
if (v.start && v.end) return `${v.start} - ${v.end}`;
|
||
if (v.start) return `${v.start}...`;
|
||
return "";
|
||
});
|
||
|
||
mount(
|
||
Combo({ class: "p-0" },
|
||
LabelInput({ class: "flex items-center gap-2 cursor-pointer" }, [
|
||
Icon({}, "icon-[lucide--calendar]"),
|
||
span({ class: () => `grow text-left truncate ${!displayRange() ? "opacity-50" : ""}` }, () => displayRange() || "Select date range"),
|
||
() => displayRange() ? span({ class: "btn-ghost btn-xs btn-circle -mr-2", onmousedown: (e) => { e.stopPropagation(); dateRange(null); } }, Icon({}, "icon-[lucide--x]")) : null
|
||
]),
|
||
{ content: Calendar({ value: dateRange, range: true, hour: true, onChange: (v) => { dateRange(v); if (v?.end) hide(); } }) }
|
||
),
|
||
"#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({ class: () => leftOpen() ? "drawer-open" : "" }, [
|
||
DrawerToggle({ id: "left-drawer", checked: leftOpen }),
|
||
DrawerContent({}, [
|
||
Drawer({ class: () => `drawer-end ${rightOpen() ? "drawer-open" : ""}` }, [
|
||
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({}, [
|
||
MenuItem({ label: "Edit", onclick: () => hide() }),
|
||
MenuItem({ label: "Delete", onclick: () => hide() }),
|
||
MenuItem({ label: "Archive", onclick: () => hide() }),
|
||
]),
|
||
]),
|
||
]),
|
||
Dropdown({ class: "dropdown-bottom dropdown-end" }, [
|
||
DropdownButton({}, "More"),
|
||
DropdownContent({ class: "menu bg-base-100 rounded-box w-40 p-2 shadow" },
|
||
Menu({}, [
|
||
MenuItem({ label: "Profile", onclick: (e) => { e.preventDefault(); hide(); } }),
|
||
MenuItem({ label: "Logout", onclick: (e) => { e.preventDefault(); hide(); } }),
|
||
])
|
||
),
|
||
]),
|
||
]),
|
||
"#demo-dropdown"
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
## Fab
|
||
|
||
<div id="demo-fab"></div>
|
||
|
||
```js
|
||
mount(
|
||
Fab({ icon: "R", class: "btn-lg btn-circle btn-secondary" }, [
|
||
Button({}, "C"),
|
||
Button({}, "B"),
|
||
Button({}, "A"),
|
||
]),
|
||
"#demo-fab"
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
## Fieldset
|
||
|
||
<div id="demo-fieldset"></div>
|
||
|
||
```js
|
||
mount(
|
||
div({ class: "flex gap-4" }, [
|
||
Fieldset({ class: "bg-base-200 border-base-300 rounded-box w-xs border gap-3 p-4", label: "Personal Info" }, [
|
||
LabelFloating({}, [
|
||
span({}, "Name"),
|
||
Input({ placeholder: "", value: $("") }),
|
||
]),
|
||
LabelFloating({}, [
|
||
span({}, "Country"),
|
||
Select({}, [
|
||
SelectOption({}, "Spain"),
|
||
SelectOption({}, "France"),
|
||
SelectOption({}, "Italy"),
|
||
]),
|
||
]),
|
||
]),
|
||
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 = $([]);
|
||
const drag = $(false);
|
||
const error = $(null);
|
||
const maxMB = 5;
|
||
|
||
const processFiles = (fileList) => {
|
||
const arr = [...fileList];
|
||
if (arr.some(f => f.size > maxMB * (1 << 20))) return error(`Max ${maxMB}MB`);
|
||
error(null);
|
||
files([...files(), ...arr]);
|
||
};
|
||
|
||
mount(
|
||
div({ class: "w-full" }, [
|
||
FileDrag({
|
||
drag: drag(),
|
||
ondrag: (v) => drag(v),
|
||
ondrop: processFiles
|
||
}, [
|
||
div({ class: "flex items-center gap-3 w-full text-sm opacity-70" }, [
|
||
Icon({}, "icon-[lucide--upload]"),
|
||
span({ class: "grow truncate" }, "Upload files"),
|
||
span({ class: "text-[10px] opacity-40" }, maxMB + "MB"),
|
||
]),
|
||
FileInput({ onchange: processFiles }),
|
||
]),
|
||
() => error() && FileError({ message: error() }),
|
||
() => files().length > 0 && FilePreview({
|
||
files: files(),
|
||
onremove: (i) => files(files().filter((_, j) => j !== i))
|
||
}),
|
||
]),
|
||
"#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]"),
|
||
"❤️",
|
||
]),
|
||
"#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" }, [
|
||
LabelFloating({}, [
|
||
span({}, "Username"),
|
||
div({ class: "input" }, [
|
||
Icon({}, "icon-[lucide--user]"),
|
||
Input({ class: "grow border-none", placeholder: "", value: username }),
|
||
]),
|
||
]),
|
||
LabelFloating({}, [
|
||
span({}, "Password"),
|
||
div({ class: "input" }, [
|
||
Icon({}, "icon-[lucide--lock]"),
|
||
InputPass({ class: "grow border-none", placeholder: "", value: password }),
|
||
]),
|
||
]),
|
||
]),
|
||
"#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(
|
||
div({ class: "flex flex-col gap-4" }, [
|
||
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"),
|
||
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
|
||
mount(
|
||
Menu({ class: "w-56 bg-base-200 rounded-box" }, [
|
||
MenuItem({ label: "Dashboard", onclick: () => hide() }),
|
||
li({}, details({ open: true }, [
|
||
summary({}, "Settings"),
|
||
Menu({}, [
|
||
MenuItem({ label: "Profile", onclick: () => hide() }),
|
||
MenuItem({ label: "Account", onclick: () => hide() }),
|
||
]),
|
||
])),
|
||
MenuItem({ label: "Logout", onclick: () => alert("Logout") }),
|
||
]),
|
||
"#demo-menu"
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
## Modal
|
||
|
||
<div id="demo-modal"></div>
|
||
|
||
```js
|
||
const modalRef = { current: null };
|
||
|
||
mount(
|
||
div({}, [
|
||
Button({ class: "btn", onclick: () => modalRef.current?.showModal() }, "Open modal"),
|
||
Modal({ ref: (el) => modalRef.current = el }, [
|
||
ModalBox({}, [
|
||
h3({ class: "text-lg font-bold" }, "Congratulations!"),
|
||
p({ class: "py-4" }, "You have successfully created a reactive DaisyUI modal with SigPro."),
|
||
ModalAction({}, [
|
||
form({ method: "dialog" }, [
|
||
Button({}, "Close"),
|
||
]),
|
||
]),
|
||
]),
|
||
ModalBackdrop(),
|
||
]),
|
||
]),
|
||
"#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(
|
||
LabelFloating({}, [
|
||
span({}, "Tech"),
|
||
LabelSelect({}, [
|
||
Select({ value: choice, onchange: (e) => choice(e.target.value) }, [
|
||
SelectOption({ value: "" }, "Pick a language"),
|
||
SelectOption({ value: "html" }, "HTML"),
|
||
SelectOption({ value: "css" }, "CSS"),
|
||
SelectOption({ value: "js" }, "JavaScript"),
|
||
]),
|
||
]),
|
||
]),
|
||
"#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({}, [
|
||
StatTitle({}, "Downloads"),
|
||
StatValue({}, "1,200"),
|
||
StatDesc({}, "↑ 21% from last month"),
|
||
]),
|
||
Stat({}, [
|
||
StatTitle({}, "New Users"),
|
||
StatValue({}, "450"),
|
||
StatDesc({}, "↑ 14% from last month"),
|
||
]),
|
||
Stat({}, [
|
||
StatTitle({}, "Revenue"),
|
||
StatValue({}, "$89k"),
|
||
StatDesc({}, "↓ 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({}, Icon({}, "icon-[lucide--moon]")),
|
||
SwapOff({}, Icon({}, "icon-[lucide--sun]")),
|
||
]),
|
||
"#demo-swap"
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
## Table
|
||
|
||
<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" },
|
||
]);
|
||
|
||
mount(
|
||
Table({ class: "w-full" }, [
|
||
TableHead({}, TableRow({}, [
|
||
TableTh({}, "Name"),
|
||
TableTh({}, "Role"),
|
||
TableTh({}, "Action"),
|
||
])),
|
||
TableBody({},
|
||
each(tableData, (item) =>
|
||
TableRow({}, [
|
||
TableTd({ class: "font-bold" }, item.name),
|
||
TableTd({}, item.role),
|
||
TableTd({}, Button({ class: "btn-xs", onclick: () => alert(`Edit ${item.name}`) }, "Edit")),
|
||
])
|
||
)
|
||
),
|
||
]),
|
||
"#demo-table"
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
## Tabs
|
||
|
||
<div id="demo-tabs"></div>
|
||
|
||
```js
|
||
const tabsSignal = $([
|
||
{ label: "Tab A", content: "Content of tab A", open: true },
|
||
{ label: "Tab B", content: "Content of tab B", closable: true },
|
||
{ label: "Tab C", content: "Content of tab C" },
|
||
]);
|
||
|
||
mount(
|
||
Tabs({ class: "tabs-box" },
|
||
each(tabsSignal, (tab, i) =>
|
||
Tab({
|
||
name: "demo-tabs",
|
||
label: tab.label,
|
||
content: tab.content,
|
||
checked: tab.open || false,
|
||
tabs: tabsSignal,
|
||
index: i,
|
||
closable: tab.closable || false,
|
||
})
|
||
)
|
||
),
|
||
"#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({ class: "timeline-vertical" }, [
|
||
li({}, [
|
||
div({ class: "timeline-start" }, "2024"),
|
||
div({ class: "timeline-middle" }, Icon({}, "icon-[lucide--check]")),
|
||
div({ class: "timeline-end timeline-box" }, "Project started"),
|
||
]),
|
||
li({}, [
|
||
div({ class: "timeline-start" }, "2025"),
|
||
div({ class: "timeline-middle" }, Icon({}, "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" }, [
|
||
Icon({}, "icon-[lucide--check]"),
|
||
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"
|
||
);
|
||
```
|