# SigPro Demo – Atomic Components --- ## Accordion
```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
```js mount( Alert({ class: "alert-info" }, [ Icon({}, "icon-[lucide--info]"), span({}, "You have 2 new messages"), ]), "#demo-alert" ); ``` --- ## Autocomplete
```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
```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
```js mount( div({ class: "flex gap-2" }, [ Badge({}, "New"), Badge({ class: "badge-outline" }, "Sale"), Badge({ class: "badge-error" }, "Deleted"), ]), "#demo-badge" ); ``` --- ## Breadcrumbs
```js mount( Breadcrumbs({}, [ ul({}, [ li({}, a({ href: "#" }, "Home")), li({}, a({ href: "#" }, "Docs")), li({}, span({ class: "font-bold" }, "Components")), ]), ]), "#demo-breadcrumbs" ); ``` --- ## Button
```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
```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
```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 ```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
```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
```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
```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
```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
```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
```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
```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
```js mount( Fab({ icon: "R", class: "btn-lg btn-circle btn-secondary" }, [ Button({}, "C"), Button({}, "B"), Button({}, "A"), ]), "#demo-fab" ); ``` --- ## Fieldset
```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
```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
```js mount( div({ class: "flex gap-4 text-xl" }, [ Icon({}, "icon-[lucide--home]"), Icon({}, "icon-[lucide--settings]"), "❤️", ]), "#demo-icon" ); ``` --- ## Indicator
```js mount( Indicator({ value: "3" }, [ Button({ class: "btn-circle" }, Icon({}, "icon-[lucide--bell]")), ]), "#demo-indicator" ); ``` --- ## Input
```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
```js mount( p({}, ["Press ", Kbd({}, "Ctrl"), " + ", Kbd({}, "S"), " to save"]), "#demo-kbd" ); ``` --- ## List & ListRows
```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
```js mount(Loading({ class: "loading-lg text-primary" }), "#demo-loading"); ``` --- ## Menu
```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
```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
```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
```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
```js const radialVal = $(70); mount( Radial({ value: radialVal, class: "text-primary" }, () => `${radialVal()}%`), "#demo-radial" ); ``` --- ## Radio
```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
```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
```js const stars = $(3); mount( Rating({}, [ RatingItems({ count: 5, value: stars, name: "demo-rating", class: "mask-star-2" }), ]), "#demo-rating" ); ``` --- ## Select
```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
```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
```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
```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
```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)
```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
```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
```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
```js const bio = $(""); mount( Textarea({ class: "w-80", placeholder: "Write something...", value: bio }), "#demo-textarea" ); ``` --- ## Textrotate
```js mount( Textrotate({ class: "text-2xl font-bold" }, [ span({}, "Hello"), span({}, "Bonjour"), span({}, "Hola"), ]), "#demo-textrotate" ); ``` --- ## Timeline
```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
```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
```js const toggleActive = $(false); mount( Toggle({ checked: toggleActive, onchange: (e) => toggleActive(e.target.checked), class: "toggle-primary", }), "#demo-toggle" ); ``` --- ## Tooltip
```js mount( Tooltip({ tip: "Save changes", class: "tooltip-right tooltip-primary" }, Button({ class: "btn" }, "Save") ), "#demo-tooltip" ); ```