Files
sigpro-ui/docs/demo.md
natxocc e6b172efa1
All checks were successful
Deploy Docs to Synology / deploy (push) Successful in 3s
Independent sigpro vs sigpro-ui
2026-05-04 16:39:57 +02:00

22 KiB
Raw Blame History

SigPro Demo Comprehensive Examples


Accordion

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

mount(
  Alert({ class: "alert-info" }, [
    span({ class: "icon-[lucide--info] text-lg" }),
    span({}, "You have 2 new messages"),
  ]),
  "#demo-alert",
);

Autocomplete

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

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

mount(
  div({ class: "flex gap-2" }, [
    Badge({}, "New"),
    Badge({ class: "badge-outline" }, "Sale"),
    Badge({ class: "badge-error" }, "Deleted"),
  ]),
  "#demo-badge",
);

Breadcrumbs

mount(
  Breadcrumbs({}, [
    ul({}, [
      li({}, a({ href: "#" }, "Home")),
      li({}, a({ href: "#" }, "Docs")),
      li({}, span({ class: "font-bold" }, "Components")),
    ]),
  ]),
  "#demo-breadcrumbs",
);

Button

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

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

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",
);

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

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

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

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

const dateRange = $("");

mount(
  Datepicker({
    value: dateRange,
    range: true,
    hour: true,
    placeholder: "Select a date range",
    onChange: (val) => console.log("Date:", val),
  }),
  "#demo-datepicker",
);

Divider

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

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

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({ class: "dropdown-bottom dropdown-end" }, [
      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)

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

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

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

const files = $([]);

mount(
  Fileinput({
    max: 5,
    accept: "image/*,.pdf",
    onselect: (selectedFiles) => console.log("Files:", selectedFiles),
    value: files,
  }),
  "#demo-fileinput",
);

Icon

mount(
  div({ class: "flex gap-4 text-xl" }, [
    Icon({},"icon-[lucide--home]"),
    Icon({},"icon-[lucide--settings]"),
    "❤️", // emoji fallback
  ]),
  "#demo-icon",
);

Indicator

mount(
  Indicator({ value: "3" }, [
    Button({ class: "btn-circle" }, Icon({},"icon-[lucide--bell]")),
  ]),
  "#demo-indicator",
);

Input

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

mount(
  p({}, ["Press ", Kbd({}, "Ctrl"), " + ", Kbd({}, "S"), " to save"]),
  "#demo-kbd",
);

List & ListRows

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

mount(Loading({ class: "loading-lg text-primary" }), "#demo-loading");

Menu

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

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

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

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

const radialVal = $(70);

mount(
  Radial({ value: radialVal, class: "text-primary" }, () => `${radialVal()}%`),
  "#demo-radial",
);

Radio

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

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

const stars = $(3);

mount(
  Rating({}, [
    RatingItems({
      count: 5,
      value: stars,
      name: "demo-rating",
      class: "mask-star-2",
    }),
  ]),
  "#demo-rating",
);

Select

const choice = $("css");

mount(
  Select({
    items: ["HTML", "CSS", "JavaScript"],
    placeholder: "Pick a language",
    value: choice,
    float: true,
    label: "Tech",
  }),
  "#demo-select",
);

Skeleton & SkeletonText

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

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

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

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)

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

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

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

const bio = $("");

mount(
  Textarea({ class: "w-80", placeholder: "Write something...", value: bio }),
  "#demo-textarea",
);

Textrotate

mount(
  Textrotate({ class: "text-2xl font-bold" }, [
    span({}, "Hello"),
    span({}, "Bonjour"),
    span({}, "Hola"),
  ]),
  "#demo-textrotate",
);

Timeline

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

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

const toggleActive = $(false);

mount(
  Toggle({
    checked: toggleActive,
    onchange: (e) => toggleActive(e.target.checked),
    class: "toggle-primary",
  }),
  "#demo-toggle",
);

Tooltip

mount(
  Tooltip(
    { tip: "Save changes", class: "tooltip-right tooltip-primary" },
    Button({ class: "btn" }, "Save"),
  ),
  "#demo-tooltip",
);