Files
sigpro-ui/docs/demo_layout.md
natxocc 910c6ab3c7
All checks were successful
Deploy Docs to Synology / deploy (push) Successful in 4s
Before repair nav components
2026-04-25 11:24:39 +02:00

5.2 KiB
Raw Blame History

Layout

Accordion

const accItems = $([
  { title: 'What is SigPro?', content: 'A lightweight UI library built on DaisyUI and a finegrained reactivity system.' },
  { 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' }, [
    // Example 1: radio type with arrow variant
    Accordion({
      variant: 'arrow',
      items: [
        { title: 'Radio with arrow', content: 'This uses collapsearrow' },
        { title: 'Open by default', content: 'This one is open', open: true },
        'Simple string item (no content)'
      ]
    }),
    // Example 2: details type with plus variant
    Accordion({
      type: 'details',
      variant: 'plus',
      items: [
        { title: 'Details with plus', content: 'Uses the native <details> element' },
        { title: 'Another detail', content: 'Accordion style but with plus icon' }
      ]
    }),
    // Example 3: reactive items (signal)
    Accordion({ items: accItems })
  ]),
  '#demo-accordion'
);

Drawer

const drawerOpen = $(false);

mount(
  div({}, [
    Button({ class: 'btn', onclick: () => drawerOpen(true) }, 'Open Drawer'),
    Drawer({ open: drawerOpen, side: Menu({ items: [
      { label: 'Dashboard', onclick: () => drawerOpen(false) },
      { label: 'Settings' },
      { label: 'Help' }
    ]}) }, [
      div({ class: 'p-4' }, [
        h3({ class: 'text-lg font-bold' }, 'Main Content'),
        p({}, 'This is the main page. Click the button above to open the drawer.')
      ])
    ])
  ]),
  '#demo-drawer'
);

Dropdown

mount(
  div({ class: 'flex gap-4' }, [
    // Example 1: automatic items
    Dropdown({
      trigger: 'Options',
      items: [
        { label: 'Edit', onclick: () => console.log('Edit') },
        { label: 'Delete', onclick: () => console.log('Delete') },
        { label: 'Archive' }
      ]
    }),
    // Example 2: custom children (manual)
    Dropdown({ trigger: 'More' }, [
      h('ul', { class: 'menu dropdown-content bg-base-100 rounded-box w-40 p-2 shadow' }, [
        li({}, a({}, 'Profile')),
        li({}, a({}, 'Logout'))
      ])
    ])
  ]),
  '#demo-dropdown'
);

Fab

mount(
  div({ class: 'flex gap-4' }, [
    Fab({ class: 'fab-bottom-left' }, span({ class: 'icon-[lucide--plus]' })),
    Fab({ class: 'fab-top-right', style: 'position:relative' }, span({ class: 'icon-[lucide--settings]' }))
  ]),
  '#demo-fab'
);

Fieldset

mount(
  div({ class: 'flex gap-4' }, [
    Fieldset({ legend: 'Personal Info' }, [
      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' }, [
      div({}, 'Any content without legend')
    ])
  ]),
  '#demo-fieldset'
);

Menu

const menuItems = $([
  { label: 'Home' },
  { label: 'Products', children: [
    { label: 'Laptops' },
    { label: 'Phones' }
  ]},
  { label: 'About', onclick: () => console.log('About clicked') }
]);

mount(
  div({ class: 'flex gap-4' }, [
    // Example 1: automatic from items (signal)
    Menu({ items: menuItems, class: 'menu-vertical' }),
    // Example 2: manual children
    Menu({ class: 'menu-horizontal bg-base-200 rounded-box' }, [
      li({}, a({}, 'One')),
      li({}, a({}, 'Two'))
    ])
  ]),
  '#demo-menu'
);

Navbar

mount(
  Navbar({ class: 'bg-base-200 rounded-box' }, [
    div({ class: 'flex-1' },
      a({ class: 'btn btn-ghost text-xl' }, 'SigPro')
    ),
    div({ class: 'flex-none gap-2' }, [
      Button({ class: 'btn btn-ghost' }, 'Login'),
      Button({ class: 'btn btn-primary' }, 'Sign up')
    ])
  ]),
  '#demo-navbar'
);

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(
  div({ class: 'flex flex-col gap-4' }, [
    // Example 1: reactive tabs with closable
    Tabs({
      items: tabsData,
      activeIndex: activeTab,
      class: "tabs-box",
      onClose: (idx) => {
        const newTabs = tabsData().filter((_, i) => i !== idx);
        tabsData(newTabs);
        if (activeTab() >= newTabs.length) activeTab(Math.max(0, newTabs.length - 1));
      }
    }),
    // Example 2: manual tabs with custom content
    Tabs({}, [
      a({ class: () => `tab ${activeTab() === 0 ? 'tab-active' : ''}`, onclick: () => activeTab(0) }, 'Manual A'),
      a({ class: () => `tab ${activeTab() === 1 ? 'tab-active' : ''}`, onclick: () => activeTab(1) }, 'Manual B'),
      div({ class: 'tab-content', style: () => `display:${activeTab() === 0 ? 'block' : 'none'}` }, 'Content for manual A'),
      div({ class: 'tab-content', style: () => `display:${activeTab() === 1 ? 'block' : 'none'}` }, 'Content for manual B')
    ])
  ]),
  '#demo-tabs'
);