Before repair nav components
All checks were successful
Deploy Docs to Synology / deploy (push) Successful in 4s
All checks were successful
Deploy Docs to Synology / deploy (push) Successful in 4s
This commit is contained in:
@@ -5,41 +5,8 @@
|
||||
* **Introduction**
|
||||
* [Installation](install.md)
|
||||
* [Quick Reference](quick.md)
|
||||
|
||||
* **Forms & Inputs**
|
||||
* [Autocomplete](components/autocomplete.md)
|
||||
* [Button](components/button.md)
|
||||
* [Checkbox](components/checkbox.md)
|
||||
* [Colorpicker](components/colorpicker.md)
|
||||
* [Datepicker](components/datepicker.md)
|
||||
* [Input](components/input.md)
|
||||
* [Radio](components/radio.md)
|
||||
* [Range](components/range.md)
|
||||
* [Rating](components/rating.md)
|
||||
* [Select](components/select.md)
|
||||
* [Swap](components/swap.md)
|
||||
|
||||
* **Data Display**
|
||||
* [Badge](components/badge.md)
|
||||
* [Indicator](components/indicator.md)
|
||||
* [List](components/list.md)
|
||||
* [Stack](components/stack.md)
|
||||
* [Stat](components/stat.md)
|
||||
* [Table](components/table.md)
|
||||
* [Timeline](components/timeline.md)
|
||||
|
||||
* **Feedback & Overlays**
|
||||
* [Alert](components/alert.md)
|
||||
* [Modal](components/modal.md)
|
||||
* [Toast](components/toast.md)
|
||||
* [Tooltip](components/tooltip.md)
|
||||
|
||||
* **Navigation & Layout**
|
||||
* [Accordion](components/accordion.md)
|
||||
* [Drawer](components/drawer.md)
|
||||
* [Dropdown](components/dropdown.md)
|
||||
* [Fab](components/fab.md)
|
||||
* [Fieldset](components/fieldset.md)
|
||||
* [Menu](components/menu.md)
|
||||
* [Navbar](components/navbar.md)
|
||||
* [Tabs](components/tabs.md)
|
||||
* [Forms & Inputs](demo_forms.md)
|
||||
* [Data & Dysplay](demo_display.md)
|
||||
* [Feedback & Overlays](demo_overlay.md)
|
||||
* [Navigation & Layout](demo_layout.md)
|
||||
* [WYSIWYG Editor](demo_editor.md)
|
||||
@@ -8,51 +8,108 @@
|
||||
</div>
|
||||
|
||||
```js
|
||||
const paises = [
|
||||
"España",
|
||||
"México",
|
||||
"Argentina",
|
||||
"Colombia",
|
||||
"Chile",
|
||||
"Perú",
|
||||
"Venezuela",
|
||||
{ label: "Estados Unidos", value: "US" },
|
||||
{ label: "Canadá", value: "CA" },
|
||||
{ label: "Reino Unido", value: "UK" },
|
||||
];
|
||||
// const App = () => {
|
||||
// const selected = $('');
|
||||
// const filterType = $('all');
|
||||
|
||||
// const allItems = {
|
||||
// fruits: ['Apple', 'Banana', 'Orange', 'Mango'],
|
||||
// vegetables: ['Carrot', 'Broccoli', 'Spinach', 'Potato'],
|
||||
// all: ['Apple', 'Banana', 'Orange', 'Mango', 'Carrot', 'Broccoli', 'Spinach', 'Potato']
|
||||
// };
|
||||
|
||||
// return div({ class: 'flex flex-col gap-4 w-full' }, [
|
||||
// Select({
|
||||
// items: [
|
||||
// { value: 'all', label: 'All items' },
|
||||
// { value: 'fruits', label: 'Fruits' },
|
||||
// { value: 'vegetables', label: 'Vegetables' }
|
||||
// ],
|
||||
// value: filterType,
|
||||
// onchange: (e) => filterType(e.target.value)
|
||||
// },
|
||||
// ),
|
||||
// Autocomplete({
|
||||
// items: () => allItems[filterType()],
|
||||
// value: selected,
|
||||
// onselect: (value) => selected(value)
|
||||
// })
|
||||
// ]);
|
||||
// };
|
||||
|
||||
|
||||
const App = () => {
|
||||
const password = $("");
|
||||
const selected = $('');
|
||||
|
||||
const countries = [
|
||||
'España', 'México', 'Argentina', 'Colombia', 'Chile',
|
||||
{ label: 'Estados Unidos', value: 'US' },
|
||||
{ label: 'Canadá', value: 'CA' },
|
||||
];
|
||||
|
||||
// Lógica de validación sencilla
|
||||
const requirements = [
|
||||
{ label: "Mínimo 8 caracteres", check: () => password().length >= 8 },
|
||||
{ label: "Incluye un número", check: () => /\d/.test(password()) },
|
||||
{ label: "Símbolo especial", check: () => /[^A-Za-z0-9]/.test(password()) }
|
||||
{ label: "Símbolo especial", check: () => /[^A-Za-z0-9]/.test(password()) },
|
||||
];
|
||||
|
||||
const paisSelected = $("");
|
||||
return div({ class: "p-10 max-w-md" }, [
|
||||
Autocomplete({
|
||||
label: 'País',
|
||||
float: true,
|
||||
placeholder: 'Escribe para buscar...',
|
||||
items: countries,
|
||||
value: selected,
|
||||
onselect: (item) => console.log('Seleccionado:', item),
|
||||
}),
|
||||
|
||||
h('p', { class: 'text-sm opacity-70' }, () =>
|
||||
`Valor actual: ${selected() || 'ninguno'}`
|
||||
),
|
||||
Input({
|
||||
type: "password",
|
||||
value: password,
|
||||
class: "input-warning",
|
||||
rule: "[0-9]*",
|
||||
hint: "Debes escribir numeros del 0 al 9",
|
||||
oninput: (e) => password(e.target.value),
|
||||
label: "Pass",
|
||||
float: true,
|
||||
left: span({ class: "icon-[lucide--lock] mr-2" }),
|
||||
// El contenido que se animará con fx() dentro del Input
|
||||
content: div({ class: "mt-2 p-4 bg-base-200 rounded-lg shadow-xl border border-base-300" }, [
|
||||
span({ class: "text-xs font-bold uppercase opacity-50" }, "Seguridad:"),
|
||||
ul({ class: "mt-2 space-y-1" },
|
||||
requirements.map(req => h('li', {
|
||||
class: () => `flex items-center text-sm ${req.check() ? 'text-success' : 'text-error opacity-50'}`
|
||||
}, [
|
||||
span({ class: () => `mr-2 ${req.check() ? 'icon-[lucide--check]' : 'icon-[lucide--x]'}` }),
|
||||
req.label
|
||||
]))
|
||||
)
|
||||
])
|
||||
})
|
||||
content: div(
|
||||
{
|
||||
class:
|
||||
"mt-2 p-4 bg-base-200 rounded-lg shadow-xl border border-base-300",
|
||||
},
|
||||
[
|
||||
span(
|
||||
{ class: "text-xs font-bold uppercase opacity-50" },
|
||||
"Seguridad:",
|
||||
),
|
||||
ul(
|
||||
{ class: "mt-2 space-y-1" },
|
||||
requirements.map((req) =>
|
||||
h(
|
||||
"li",
|
||||
{
|
||||
class: () =>
|
||||
`flex items-center text-sm ${req.check() ? "text-success" : "text-error opacity-50"}`,
|
||||
},
|
||||
[
|
||||
span({
|
||||
class: () =>
|
||||
`mr-2 ${req.check() ? "icon-[lucide--check]" : "icon-[lucide--x]"}`,
|
||||
}),
|
||||
req.label,
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
}),
|
||||
]);
|
||||
};
|
||||
|
||||
|
||||
100
docs/demo_display.md
Normal file
100
docs/demo_display.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# Display
|
||||
|
||||
## Badge
|
||||
<div id="demo-badge"></div>
|
||||
|
||||
```js
|
||||
mount(
|
||||
Badge({ class: 'badge-primary' }, 'New'),
|
||||
'#demo-badge'
|
||||
);
|
||||
```
|
||||
|
||||
## Indicator
|
||||
<div id="demo-indicator"></div>
|
||||
|
||||
```js
|
||||
mount(
|
||||
Indicator({ value: '5' },
|
||||
Button({ class: 'btn btn-sm' }, 'Notifications')
|
||||
),
|
||||
'#demo-indicator'
|
||||
);
|
||||
```
|
||||
|
||||
## Stack
|
||||
<div id="demo-stack"></div>
|
||||
|
||||
```js
|
||||
mount(
|
||||
Stack({ class: 'w-32 h-20' }, [
|
||||
div({ class: 'bg-primary text-primary-content p-2' }, 'Top'),
|
||||
div({ class: 'bg-secondary text-secondary-content p-2' }, 'Bottom')
|
||||
]),
|
||||
'#demo-stack'
|
||||
);
|
||||
```
|
||||
|
||||
## Stat
|
||||
<div id="demo-stat"></div>
|
||||
|
||||
```js
|
||||
// Stat is a simple wrapper for the DaisyUI stat component
|
||||
const Stat = (p, c) => div({ ...p, class: cls('stat', p.class) }, c)
|
||||
|
||||
mount(
|
||||
div({ class: 'stats shadow' },
|
||||
Stat({ class: 'stat' }, [
|
||||
div({ class: 'stat-title' }, 'Total Downloads'),
|
||||
div({ class: 'stat-value' }, '12.5K'),
|
||||
div({ class: 'stat-desc' }, '21% more than last month')
|
||||
])
|
||||
),
|
||||
'#demo-stat'
|
||||
)
|
||||
```
|
||||
|
||||
## Table
|
||||
<div id="demo-table"></div>
|
||||
|
||||
```js
|
||||
const users = [
|
||||
{ id: 1, name: 'Alice', role: 'Admin' },
|
||||
{ id: 2, name: 'Bob', role: 'Editor' },
|
||||
{ id: 3, name: 'Charlie', role: 'Viewer' }
|
||||
];
|
||||
|
||||
mount(
|
||||
Table({
|
||||
items: users,
|
||||
columns: [
|
||||
{ key: 'name', label: 'Name' },
|
||||
{ key: 'role', label: 'Role' },
|
||||
{ render: (it) => Button({ class: 'btn-xs' }, 'Edit') }
|
||||
],
|
||||
class: 'table-zebra'
|
||||
}),
|
||||
'#demo-table'
|
||||
);
|
||||
```
|
||||
|
||||
## 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'
|
||||
);
|
||||
```
|
||||
19
docs/demo_editor.md
Normal file
19
docs/demo_editor.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Editor
|
||||
<div id="demo-editor"></div>
|
||||
|
||||
<div id="demo-editor-output" class="mt-4 p-4 border border-base-300 rounded-box bg-base-200"></div>
|
||||
|
||||
```js
|
||||
const content = $('<p><strong>Hello</strong> world!</p>');
|
||||
|
||||
mount(
|
||||
div({ class: 'flex flex-col gap-4' }, [
|
||||
Editor({
|
||||
value: content,
|
||||
placeholder: 'Escribe tu historia…',
|
||||
class: 'max-w-2xl'
|
||||
})
|
||||
]),
|
||||
'#demo-editor'
|
||||
);
|
||||
```
|
||||
181
docs/demo_forms.md
Normal file
181
docs/demo_forms.md
Normal file
@@ -0,0 +1,181 @@
|
||||
# Forms
|
||||
|
||||
## Autocomplete
|
||||
<div id="demo-autocomplete"></div>
|
||||
|
||||
```js
|
||||
const selected = $('');
|
||||
const items = ['Apple', 'Banana', 'Orange', 'Mango', 'Carrot', 'Broccoli', 'Spinach', 'Potato'];
|
||||
|
||||
mount(
|
||||
Autocomplete({
|
||||
items,
|
||||
value: selected,
|
||||
placeholder: 'Search...',
|
||||
onselect: (val) => console.log('Selected:', val)
|
||||
}),
|
||||
'#demo-autocomplete'
|
||||
);
|
||||
```
|
||||
|
||||
## Button
|
||||
<div id="demo-button"></div>
|
||||
|
||||
```js
|
||||
const count = $(0);
|
||||
|
||||
mount(
|
||||
Button({
|
||||
class: 'btn-primary',
|
||||
onclick: () => count(count() + 1)
|
||||
}, () => `Clicked ${count()} times`),
|
||||
'#demo-button'
|
||||
);
|
||||
```
|
||||
|
||||
## 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')
|
||||
]),
|
||||
'#demo-checkbox'
|
||||
);
|
||||
```
|
||||
|
||||
## Colorpicker
|
||||
<div id="demo-colorpicker"></div>
|
||||
|
||||
```js
|
||||
const color = $('');
|
||||
|
||||
mount(
|
||||
Colorpicker({
|
||||
value: color,
|
||||
label: 'Pick a color',
|
||||
onchange: (c) => console.log('Color:', c)
|
||||
}),
|
||||
'#demo-colorpicker'
|
||||
);
|
||||
```
|
||||
|
||||
## Datepicker
|
||||
<div id="demo-datepicker"></div>
|
||||
|
||||
```js
|
||||
const date = $('');
|
||||
|
||||
mount(
|
||||
Datepicker({
|
||||
value: date,
|
||||
placeholder: 'Select date',
|
||||
onChange: (val) => console.log('Date:', val)
|
||||
}),
|
||||
'#demo-datepicker'
|
||||
);
|
||||
```
|
||||
|
||||
## Input
|
||||
<div id="demo-input"></div>
|
||||
|
||||
```js
|
||||
const text = $('');
|
||||
|
||||
mount(
|
||||
Input({
|
||||
type: 'text',
|
||||
label: 'Username',
|
||||
float: true,
|
||||
value: text,
|
||||
left: Icon('icon-[lucide--user]')
|
||||
}),
|
||||
'#demo-input'
|
||||
);
|
||||
```
|
||||
|
||||
## Radio
|
||||
<div id="demo-radio"></div>
|
||||
|
||||
```js
|
||||
const option = $('');
|
||||
|
||||
mount(
|
||||
div({ class: 'flex gap-2' }, [
|
||||
Radio({ name: 'option', value: 'a', checked: () => option() === 'a', onchange: () => option('a') }),
|
||||
Radio({ name: 'option', value: 'b', checked: () => option() === 'b', onchange: () => option('b') }),
|
||||
]),
|
||||
'#demo-radio'
|
||||
);
|
||||
```
|
||||
|
||||
## Range
|
||||
<div id="demo-range"></div>
|
||||
|
||||
```js
|
||||
const rangeValue = $(50);
|
||||
|
||||
mount(
|
||||
div({ class: 'flex flex-col gap-2' }, [
|
||||
Range({ min: 0, max: 100, value: rangeValue, oninput: (e) => rangeValue(+e.target.value) }),
|
||||
span({}, () => `Value: ${rangeValue()}`)
|
||||
]),
|
||||
'#demo-range'
|
||||
);
|
||||
```
|
||||
|
||||
## Rating
|
||||
<div id="demo-rating"></div>
|
||||
|
||||
```js
|
||||
const stars = $('');
|
||||
|
||||
mount(
|
||||
Rating({
|
||||
value: stars,
|
||||
count: 5,
|
||||
mask: 'mask-star',
|
||||
onchange: (v) => console.log('Rated:', v)
|
||||
}),
|
||||
'#demo-rating'
|
||||
);
|
||||
```
|
||||
|
||||
## Select
|
||||
<div id="demo-select"></div>
|
||||
|
||||
```js
|
||||
const choice = $('');
|
||||
|
||||
mount(
|
||||
Select({
|
||||
items: ['Option 1', 'Option 2', 'Option 3'],
|
||||
placeholder: 'Choose...',
|
||||
value: choice,
|
||||
}),
|
||||
'#demo-select'
|
||||
);
|
||||
```
|
||||
|
||||
## Swap
|
||||
<div id="demo-swap"></div>
|
||||
|
||||
```js
|
||||
const swapOn = $(false);
|
||||
|
||||
mount(
|
||||
Swap({
|
||||
value: swapOn,
|
||||
on: span({ class: 'text-success' }, 'ON'),
|
||||
off: span({ class: 'text-error' }, 'OFF'),
|
||||
}),
|
||||
'#demo-swap'
|
||||
);
|
||||
```
|
||||
201
docs/demo_layout.md
Normal file
201
docs/demo_layout.md
Normal file
@@ -0,0 +1,201 @@
|
||||
# Layout
|
||||
|
||||
## Accordion
|
||||
<div id="demo-accordion"></div>
|
||||
|
||||
```js
|
||||
const accItems = $([
|
||||
{ title: 'What is SigPro?', content: 'A lightweight UI library built on DaisyUI and a fine‑grained 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 collapse‑arrow' },
|
||||
{ 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
|
||||
<div id="demo-drawer"></div>
|
||||
|
||||
```js
|
||||
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
|
||||
<div id="demo-dropdown"></div>
|
||||
|
||||
```js
|
||||
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
|
||||
<div id="demo-fab"></div>
|
||||
|
||||
```js
|
||||
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
|
||||
<div id="demo-fieldset"></div>
|
||||
|
||||
```js
|
||||
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
|
||||
<div id="demo-menu"></div>
|
||||
|
||||
```js
|
||||
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
|
||||
<div id="demo-navbar"></div>
|
||||
|
||||
```js
|
||||
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
|
||||
<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(
|
||||
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'
|
||||
);
|
||||
```
|
||||
84
docs/demo_overlay.md
Normal file
84
docs/demo_overlay.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# Overlays
|
||||
|
||||
## Alert
|
||||
<div id="demo-alert"></div>
|
||||
|
||||
```js
|
||||
mount(
|
||||
Alert({ class: 'alert-success' }, [
|
||||
span({}, 'Operation completed successfully!'),
|
||||
Button({ class: 'btn-sm' }, 'Undo')
|
||||
]),
|
||||
'#demo-alert'
|
||||
);
|
||||
```
|
||||
|
||||
## Modal
|
||||
<div id="demo-modal"></div>
|
||||
|
||||
```js
|
||||
const modalOpen = $(false);
|
||||
|
||||
mount(
|
||||
div({ class: 'flex flex-col items-start gap-2' }, [
|
||||
Button({
|
||||
class: 'btn',
|
||||
onclick: () => modalOpen(true)
|
||||
}, 'Abrir 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'
|
||||
);
|
||||
```
|
||||
|
||||
## 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 successfully')
|
||||
]),
|
||||
'alert-success'
|
||||
) }, 'With icon'),
|
||||
Button({ class: 'btn', onclick: () => Toast(
|
||||
h('div', { class: 'flex flex-col' }, [
|
||||
h('strong', {}, '¡ATTENTION!'),
|
||||
h('span', {}, 'Error saving!'),
|
||||
h('button', { class: 'btn btn-xs mt-1', onclick: () => console.log('retry') }, 'Retry')
|
||||
]),
|
||||
'alert-warning',
|
||||
7000
|
||||
) }, 'Complex')
|
||||
]),
|
||||
'#demo-toast'
|
||||
);
|
||||
```
|
||||
|
||||
## Tooltip
|
||||
<div id="demo-tooltip"></div>
|
||||
|
||||
```js
|
||||
mount(
|
||||
Tooltip({ tip: 'Click to save', class: 'tooltip-right' },
|
||||
Button({ class: 'btn' }, 'Save')
|
||||
),
|
||||
'#demo-tooltip'
|
||||
);
|
||||
```
|
||||
@@ -30,6 +30,7 @@
|
||||
repo: "",
|
||||
loadSidebar: true,
|
||||
sidebarDisplayLevel: 1,
|
||||
subMaxLevel: 3,
|
||||
executeScript: true,
|
||||
copyCode: {
|
||||
buttonText:
|
||||
@@ -38,26 +39,24 @@
|
||||
successText:
|
||||
'<svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="20 6 9 17 4 12"></polyline></svg>',
|
||||
},
|
||||
search: {
|
||||
placeholder: "Type to search",
|
||||
noData: "No Results!",
|
||||
depth: 3,
|
||||
hideOtherSidebarContent: true,
|
||||
},
|
||||
plugins: [
|
||||
function (hook, vm) {
|
||||
hook.doneEach(function () {
|
||||
// Seleccionamos solo los bloques marcados con ```js
|
||||
const codeBlocks = document.querySelectorAll(
|
||||
'pre[data-lang="js"] code',
|
||||
);
|
||||
|
||||
codeBlocks.forEach((code) => {
|
||||
try {
|
||||
// Usamos un bloque anónimo para evitar colisiones de variables const/let
|
||||
// si el usuario ejecuta el mismo código varias veces.
|
||||
const scriptContent = `(function() {
|
||||
${code.innerText}
|
||||
})();`;
|
||||
|
||||
const scriptContent = `(function() { ${code.innerText} })();`;
|
||||
const runDemo = new Function(scriptContent);
|
||||
runDemo();
|
||||
} catch (err) {
|
||||
// Un error común es que el bloque de código esté vacío o mal formado
|
||||
console.error("Error ejecutando demo de SigPro:", err);
|
||||
}
|
||||
});
|
||||
@@ -66,7 +65,7 @@
|
||||
],
|
||||
};
|
||||
</script>
|
||||
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify@4.13.0/lib/docsify.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify-copy-code/dist/docsify-copy-code.min.js"></script>
|
||||
<script src="./sigpro-ui.min.js"></script>
|
||||
|
||||
743
docs/quick.md
743
docs/quick.md
@@ -1,227 +1,610 @@
|
||||
# SigPro-UI Quick Reference
|
||||
# SigPro Components – Quick Reference
|
||||
|
||||
**Status:** Active / WIP
|
||||
All simple components use the pattern `ComponentName(props, children?)` and accept any additional HTML attributes.
|
||||
|
||||
## Accordion
|
||||
`Accordion(props)`
|
||||
|
||||
## Global Initialization
|
||||
|
||||
```javascript
|
||||
import "sigpro-ui";
|
||||
import "sigpro-ui/css";
|
||||
|
||||
// All components (Button, Input, Table, Toast, etc.) are now globally available.
|
||||
```
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `items` | array \| signal | `[]` | Array of items. Each item: `{ title, content?, open? }` or a string. |
|
||||
| `type` | `'radio'` \| `'details'` | `'radio'` | Collapse mode |
|
||||
| `variant` | string | `''` | `'arrow'` or `'plus'` for an icon variant |
|
||||
| `name` | string | auto‑generated | Group name for radio inputs |
|
||||
| `class` | string | - | Extra classes merged with `collapse` |
|
||||
|
||||
---
|
||||
|
||||
## Core Components
|
||||
## Alert
|
||||
`Alert(props, children)`
|
||||
|
||||
| Component | Purpose | Basic Example |
|
||||
| :--- | :--- | :--- |
|
||||
| **Button** | Styled button with DaisyUI | `button({ class: "btn-primary" }, "Submit")` |
|
||||
| **Input** | Reactive text field with validation | `input({ value: $name, validate: (v) => !v ? "Required" : "" })` |
|
||||
| **Select** | Dropdown selection menu | `Select({ options: ["Admin", "User"], value: $role })` |
|
||||
| **Checkbox** | Binary toggle (boolean) | `Checkbox({ label: "Active", checked: $isActive })` |
|
||||
| **Table** | Data grid with column rendering | `Table({ items: $data, columns: [...] })` |
|
||||
| **Modal** | Overlay dialog controlled by a Signal | `Modal({ open: $show, title: "Alert" }, "Message")` |
|
||||
| **Badge** | Small status indicator or tag | `Badge({ class: "badge-outline" }, "Beta")` |
|
||||
| **Alert** | Contextual notification | `Alert({ type: "info" }, "Update available")` |
|
||||
| **Dropdown** | Contextual overlay menu | `Dropdown({ label: "Menu" }, [Link1, Link2])` |
|
||||
| **Tabs** | Reactive tab-based navigation | `Tabs({ items: ["Home", "Settings"], active: $index })` |
|
||||
| **Stat** | Statistical data block (KPIs) | `Stat({ label: "Sales", value: "$400" })` |
|
||||
| **Toast** | Temporary floating notification | `Toast("Done!", "alert-success", 3000)` |
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `alert` |
|
||||
|
||||
---
|
||||
|
||||
## Forms & Inputs
|
||||
## Autocomplete
|
||||
`Autocomplete(props)`
|
||||
|
||||
| Component | Description | Example |
|
||||
| :--- | :--- | :--- |
|
||||
| **Input** | Text input with floating label, validation, password toggle | `input({ label: "Email", type: "email", value: $email, validate: validateEmail })` |
|
||||
| **Select** | Dropdown selector | `Select({ label: "Role", options: ["Admin", "User"], value: $role })` |
|
||||
| **Autocomplete** | Searchable dropdown with filtering | `autocomplete({ label: "Country", options: countryList, value: $country })` |
|
||||
| **Datepicker** | Date picker (single or range mode) | `Datepicker({ label: "Date", value: $date, range: false })` |
|
||||
| **Colorpicker** | Visual color picker with palette | `Colorpicker({ label: "Theme", value: $color })` |
|
||||
| **Checkbox** | Checkbox or toggle switch | `Checkbox({ label: "Remember me", value: $remember })` |
|
||||
| **Radio** | Radio button | `Radio({ label: "Option 1", value: $selected, name: "group" })` |
|
||||
| **Range** | Slider control | `Range({ label: "Volume", min: 0, max: 100, value: $volume })` |
|
||||
| **Rating** | Star rating component | `Rating({ value: $stars, count: 5 })` |
|
||||
| **Swap** | Toggle between two states (sun/moon) | `Swap({ on: "🌞", off: "🌙", value: $isDark })` |
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `items` | array \| signal | `[]` | Autocomplete items |
|
||||
| `value` | signal | - | Selected value |
|
||||
| `onselect` | function | - | Called when an item is selected |
|
||||
| `placeholder` | string | `'Buscar...'` | Input placeholder |
|
||||
| `class` | string | - | Extra classes |
|
||||
| `...props` | | | All other props are passed to the internal `Input` |
|
||||
|
||||
---
|
||||
|
||||
## Input Validation
|
||||
## Badge
|
||||
`Badge(props, children)`
|
||||
|
||||
The `Input` component supports real-time validation via the `validate` prop:
|
||||
|
||||
```javascript
|
||||
const email = $('');
|
||||
|
||||
input({
|
||||
type: 'email',
|
||||
value: email,
|
||||
placeholder: 'Enter your email',
|
||||
icon: 'icon-[lucide--mail]',
|
||||
validate: (value) => {
|
||||
if (!value) return '';
|
||||
if (!value.includes('@')) return 'Email must contain @';
|
||||
if (!value.includes('.')) return 'Email must contain .';
|
||||
return '';
|
||||
},
|
||||
oninput: (e) => email(e.target.value)
|
||||
})
|
||||
```
|
||||
|
||||
**How it works:**
|
||||
- Returns `''` or `null` → no error
|
||||
- Returns a string → shows error message and adds `input-error` class
|
||||
- Validates on every keystroke
|
||||
- No external state needed for error messages
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `badge` |
|
||||
|
||||
---
|
||||
|
||||
## Data Display
|
||||
## Button
|
||||
`Button(props, children)`
|
||||
|
||||
| Component | Description | Example |
|
||||
| :--- | :--- | :--- |
|
||||
| **Table** | Reactive data grid with columns | `Table({ items: $users, columns: [{ label: "Name", key: "name" }] })` |
|
||||
| **List** | Vertical list with custom rendering | `List({ items: $items, render: (item) => item.name })` |
|
||||
| **Badge** | Small status indicators | `Badge({ class: "badge-primary" }, "New")` |
|
||||
| **Stat** | Statistical data blocks (KPIs) | `Stat({ label: "Total", value: "1.2k", desc: "Monthly" })` |
|
||||
| **Timeline** | Vertical/horizontal timeline | `Timeline({ items: [{ title: "Step 1", detail: "Completed" }] })` |
|
||||
| **Stack** | Stacked elements | `Stack({}, [Card1, Card2, Card3])` |
|
||||
| **Indicator** | Badge on corner of element | `Indicator({ value: () => count() }, button(...))` |
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `button` |
|
||||
| `disabled` | boolean | - | Standard HTML attribute |
|
||||
| *any* | | | All other standard `<button>` attributes |
|
||||
|
||||
---
|
||||
|
||||
## Feedback & Overlays
|
||||
## Calendar
|
||||
`Calendar(props)`
|
||||
|
||||
| Component | Description | Example |
|
||||
| :--- | :--- | :--- |
|
||||
| **Alert** | Inline contextual notification | `Alert({ type: "success" }, "Changes saved!")` |
|
||||
| **Modal** | Dialog overlay | `Modal({ open: $isOpen, title: "Confirm" }, "Are you sure?")` |
|
||||
| **Toast** | Floating notification (auto-stacking) | `Toast("Action completed", "alert-info", 3000)` |
|
||||
| **Tooltip** | Hover tooltip wrapper | `Tooltip({ tip: "Help text", ui: "tooltip-top" }, button(...))` |
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `value` | signal \| string \| object | - | Selected date(s) |
|
||||
| `range` | signal \| boolean | `false` | Enable range mode |
|
||||
| `hour` | boolean | `false` | Show hour sliders |
|
||||
| `onChange` | function | - | Called when selection changes |
|
||||
| `class` | string | - | Extra classes |
|
||||
|
||||
---
|
||||
|
||||
## Navigation & Layout
|
||||
## Card
|
||||
`Card(props, children)`
|
||||
|
||||
| Component | Description | Example |
|
||||
| :--- | :--- | :--- |
|
||||
| **Navbar** | Top navigation bar | `Navbar({}, [Logo, Menu, Avatar])` |
|
||||
| **Menu** | Vertical navigation menu | `Menu({ items: [{ label: "Home", onclick: goHome }] })` |
|
||||
| **Drawer** | Side drawer (off-canvas) | `Drawer({ id: "my-drawer", open: $isOpen, content: Main, side: SideMenu })` |
|
||||
| **Tabs** | Content switching | `Tabs({ items: [{ label: "Tab1", content: Panel1 }] })` |
|
||||
| **Accordion** | Collapsible sections | `Accordion({ title: "Details" }, "Hidden content")` |
|
||||
| **Dropdown** | Contextual menus | `Dropdown({ label: "Options" }, [MenuLink("Edit")])` |
|
||||
| **Fieldset** | Form grouping with legend | `Fieldset({ legend: "Personal Info" }, [input(...)])` |
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `card` |
|
||||
|
||||
---
|
||||
|
||||
## Interaction & Utilities
|
||||
## CardActions
|
||||
`CardActions(props, children)`
|
||||
|
||||
| Component | Description | Example |
|
||||
| :--- | :--- | :--- |
|
||||
| **Fab** | Floating Action Button with actions | `Fab({ icon: "+", actions: [{ label: "Add", onclick: add }] })` |
|
||||
| **Indicator** | Badge indicator wrapper | `Indicator({ value: () => unread() }, button(...))` |
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `card-actions` |
|
||||
|
||||
---
|
||||
|
||||
## Internationalization (i18n)
|
||||
## CardBody
|
||||
`CardBody(props, children)`
|
||||
|
||||
Built-in locale system with Spanish and English support.
|
||||
|
||||
```javascript
|
||||
// Set global UI language
|
||||
Locale("en");
|
||||
|
||||
// Get translated string (returns a reactive signal)
|
||||
const closeText = tt("close"); // "Close" or "Cerrar"
|
||||
|
||||
```
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `card-body` |
|
||||
|
||||
---
|
||||
|
||||
## Implementation Notes
|
||||
## CardTitle
|
||||
`CardTitle(props, children)`
|
||||
|
||||
1. **Atomic Reactivity**: Components accepting `value` or `checked` bind directly to **SigPro Signals**. Updates happen instantly without full page re-renders.
|
||||
|
||||
2. **DaisyUI v5**: Pass any daisyUI styling via the `class` attribute.
|
||||
|
||||
```javascript
|
||||
button({ class: "btn-primary btn-sm rounded-full shadow-lg" }, "Click")
|
||||
```
|
||||
|
||||
3. **Zero Imports (Global Mode)**: After calling `UI()`, all components are attached to `window`. No manual imports needed.
|
||||
|
||||
4. **Self-Cleaning**: Components internally manage `_cleanups` to destroy observers and event listeners when removed from the DOM.
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `card-title` |
|
||||
|
||||
---
|
||||
|
||||
## Advanced Examples
|
||||
## Carousel
|
||||
`Carousel(props, children)`
|
||||
|
||||
### Reactive Form with Validation
|
||||
|
||||
```javascript
|
||||
const name = $("");
|
||||
|
||||
input({
|
||||
value: name,
|
||||
placeholder: "Name",
|
||||
validate: (value) => {
|
||||
if (!value) return "Name is required";
|
||||
if (value.length < 3) return "Name too short";
|
||||
return "";
|
||||
},
|
||||
oninput: (e) => name(e.target.value)
|
||||
})
|
||||
```
|
||||
|
||||
### API Request Pattern
|
||||
|
||||
```javascript
|
||||
const userId = $("123");
|
||||
const userData = $(null);
|
||||
|
||||
watch(userId, async (id) => {
|
||||
loading(true);
|
||||
userData(await fetch(`/api/user/${id}`).then(r => r.json()));
|
||||
loading(false);
|
||||
});
|
||||
|
||||
// In template
|
||||
when(() => userData(), () => Alert({ type: "success" }, userData()?.name))
|
||||
```
|
||||
|
||||
### Modal with Confirm Action
|
||||
|
||||
```javascript
|
||||
const showModal = $(false);
|
||||
|
||||
Modal({
|
||||
open: showModal,
|
||||
title: "Delete Item",
|
||||
buttons: [
|
||||
button({ class: "btn-error", onclick: () => { deleteItem(); showModal(false); } }, "Delete")
|
||||
]
|
||||
}, "Are you sure you want to delete this item?");
|
||||
```
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `carousel` |
|
||||
|
||||
---
|
||||
|
||||
## Component Props Quick Reference
|
||||
## CarouselItem
|
||||
`CarouselItem(props, children)`
|
||||
|
||||
| Component | Key Props |
|
||||
| :--- | :--- |
|
||||
| `Button` | `class`, `disabled`, `loading`, `icon` |
|
||||
| `Input` | `value`, `validate`, `type`, `placeholder`, `icon`, `disabled` |
|
||||
| `Select` | `label`, `options`, `value`, `disabled` |
|
||||
| `Modal` | `open`, `title`, `buttons` |
|
||||
| `Table` | `items`, `columns`, `zebra`, `pinRows`, `empty` |
|
||||
| `Alert` | `type` (info/success/warning/error), `soft`, `actions` |
|
||||
| `Toast` | `message`, `type`, `duration` |
|
||||
| `Datepicker` | `value`, `range`, `label`, `placeholder` |
|
||||
| `Autocomplete` | `options`, `value`, `onselect`, `label` |
|
||||
| `Indicator` | `value` (function that returns number/string) |
|
||||
| `Tooltip` | `tip`, `ui` (tooltip-top/bottom/left/right) |
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `carousel-item` |
|
||||
|
||||
---
|
||||
|
||||
## Chat
|
||||
`Chat(props, children)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `chat` |
|
||||
|
||||
---
|
||||
|
||||
## ChatBubble
|
||||
`ChatBubble(props, children)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `chat-bubble` |
|
||||
|
||||
---
|
||||
|
||||
## ChatFooter
|
||||
`ChatFooter(props, children)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `chat-footer` |
|
||||
|
||||
---
|
||||
|
||||
## ChatHeader
|
||||
`ChatHeader(props, children)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `chat-header` |
|
||||
|
||||
---
|
||||
|
||||
## ChatImage
|
||||
`ChatImage(props, children)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `chat-image avatar` |
|
||||
| *(children)* | string \| node | - | If a string, used as `src` of an `<img>` inside a rounded `div`; otherwise passed as content. |
|
||||
|
||||
---
|
||||
|
||||
## Checkbox
|
||||
`Checkbox(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `checkbox` |
|
||||
| `checked` | boolean \| signal | - | Checked state (can be a signal) |
|
||||
| `onchange` | function | - | Change handler |
|
||||
| *any* | | | All standard `<input>` attributes |
|
||||
|
||||
---
|
||||
|
||||
## Colorpicker
|
||||
`Colorpicker(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `value` | signal \| string | `'#000000'` | Selected color |
|
||||
| `label` | string | - | Optional label inside the trigger |
|
||||
| `onchange` | function | - | Called when a color is picked (if `value` is not a signal) |
|
||||
| `class` | string | - | Extra classes |
|
||||
|
||||
---
|
||||
|
||||
## Datepicker
|
||||
`Datepicker(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `value` | signal | - | Selected date(s) |
|
||||
| `range` | signal \| boolean | `false` | Range mode |
|
||||
| `hour` | boolean | `false` | Enable hour selection |
|
||||
| `onChange` | function | - | Change handler (if `value` is not a signal) |
|
||||
| `placeholder` | string | auto | Placeholder text |
|
||||
| `class` | string | - | Extra classes |
|
||||
|
||||
---
|
||||
|
||||
## Divider
|
||||
`Divider(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `divider` |
|
||||
|
||||
---
|
||||
|
||||
## Drawer
|
||||
`Drawer(props, children)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `open` | signal \| boolean | - | Drawer open state |
|
||||
| `side` | node \| signal | - | Sidebar content (can be a signal) |
|
||||
| `id` | string | auto‑generated | Drawer ID |
|
||||
| `class` | string | - | Extra classes |
|
||||
|
||||
**children** – Main content (`.drawer-content`).
|
||||
|
||||
---
|
||||
|
||||
## Dropdown
|
||||
`Dropdown(props, children?)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `trigger` | node | `'Dropdown'` | Summary content |
|
||||
| `items` | array \| signal | - | Dropdown items: `{ label, onclick? }` |
|
||||
| `class` | string | - | Extra classes merged with `dropdown` |
|
||||
|
||||
If `children` is provided, it replaces the auto‑generated menu.
|
||||
|
||||
---
|
||||
|
||||
## Fab
|
||||
`Fab(props, children)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `fab` |
|
||||
|
||||
---
|
||||
|
||||
## Fieldset
|
||||
`Fieldset(props, children)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `legend` | string | - | Legend text (rendered as `<legend>`) |
|
||||
| `class` | string | - | Extra classes merged with `fieldset` |
|
||||
|
||||
---
|
||||
|
||||
## Fileinput
|
||||
`Fileinput(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `max` | number | `2` | Max file size in MB |
|
||||
| `accept` | string | `'*'` | Accepted file types |
|
||||
| `onselect` | function | - | Called when files change (receives array) |
|
||||
| `value` | signal | - | Alternative to `onselect` for signal binding |
|
||||
| `class` | string | - | Extra classes |
|
||||
|
||||
---
|
||||
|
||||
## Icon
|
||||
`Icon(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | If the value starts with `icon-`, used as class; otherwise becomes content |
|
||||
|
||||
---
|
||||
|
||||
## Indicator
|
||||
`Indicator(props, children)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `value` | node | - | Content of the indicator badge |
|
||||
| `class` | string | - | Extra classes merged with `indicator` |
|
||||
|
||||
---
|
||||
|
||||
## Input
|
||||
`Input(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `label` | string | - | Label text |
|
||||
| `float` | boolean | `false` | Floating label |
|
||||
| `left` | node | - | Element on the left |
|
||||
| `right` | node | - | Element on the right |
|
||||
| `hint` | string | - | Validation hint |
|
||||
| `content` | node \| function | - | Content shown when focused (can be a function receiving `isFocused`) |
|
||||
| `rule` | string | - | Validation pattern |
|
||||
| `type` | string | `'text'` | Input type (`text`, `password`, etc.) |
|
||||
| `value` | signal \| string | - | Input value |
|
||||
| `class` | string | - | Extra classes |
|
||||
| *any* | | | All other props are passed to the `<input>` |
|
||||
|
||||
---
|
||||
|
||||
## Kbd
|
||||
`Kbd(props, children)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `kbd` |
|
||||
|
||||
---
|
||||
|
||||
## LabelFloat
|
||||
`LabelFloat(props, children)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `floating-label` |
|
||||
|
||||
---
|
||||
|
||||
## LabelInput
|
||||
`LabelInput(props, children)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `input` |
|
||||
|
||||
---
|
||||
|
||||
## LabelSelect
|
||||
`LabelSelect(props, children)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `select` |
|
||||
|
||||
---
|
||||
|
||||
## Loading
|
||||
`Loading(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `loading loading-spinner` |
|
||||
|
||||
---
|
||||
|
||||
## Menu
|
||||
`Menu(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `items` | array \| signal | `[]` | Menu items: `{ label, href?, onclick?, children? }` |
|
||||
| `keyFn` | function | `(it, idx) => it?.id ?? idx` | Key function for reactivity |
|
||||
| `class` | string | - | Extra classes |
|
||||
|
||||
If `children` is provided, manual mode.
|
||||
|
||||
---
|
||||
|
||||
## Navbar
|
||||
`Navbar(props, children)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `navbar` |
|
||||
|
||||
---
|
||||
|
||||
## Progress
|
||||
`Progress(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `progress` |
|
||||
|
||||
---
|
||||
|
||||
## Radial
|
||||
`Radial(props, children)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `value` | number | `0` | Progress value (sets CSS `--value` and default text) |
|
||||
| `style` | string | - | Additional inline styles appended to the defaults |
|
||||
| `class` | string | - | Extra classes merged with `radial-progress` |
|
||||
|
||||
---
|
||||
|
||||
## Radio
|
||||
`Radio(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `radio` |
|
||||
| `checked` | boolean | - | Checked state |
|
||||
| `onchange` | function | - | Change handler |
|
||||
|
||||
---
|
||||
|
||||
## Range
|
||||
`Range(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `range` |
|
||||
| `min` | number | - | Standard range attribute |
|
||||
| `max` | number | - | Standard range attribute |
|
||||
| `value` | number | - | Standard range attribute |
|
||||
|
||||
---
|
||||
|
||||
## Rating
|
||||
`Rating(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `value` | number \| signal | - | Selected rating |
|
||||
| `count` | number | `5` | Number of stars |
|
||||
| `mask` | string | `'mask-star'` | Shape class (e.g., `'mask-heart'`) |
|
||||
| `onchange` | function | - | Called when a star is clicked |
|
||||
| `class` | string | - | Extra classes |
|
||||
|
||||
---
|
||||
|
||||
## Select
|
||||
`Select(props, children?)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `items` | array \| signal | - | Options list |
|
||||
| `placeholder` | string | - | Placeholder option text |
|
||||
| `placeholderDisabled` | boolean | `true` | Whether the placeholder is disabled |
|
||||
| `label` | string | - | Label text |
|
||||
| `float` | boolean | `false` | Floating label style |
|
||||
| `left` | node | - | Element left of select |
|
||||
| `right` | node | - | Element right of select |
|
||||
| `hint` | string | - | Validation hint |
|
||||
| `value` | signal \| string | - | Selected value |
|
||||
| `keyFn` | function | auto | Key function for reactivity |
|
||||
| `class` | string | - | Extra classes |
|
||||
|
||||
If `children` is provided, manual mode.
|
||||
|
||||
---
|
||||
|
||||
## Skeleton
|
||||
`Skeleton(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `skeleton` |
|
||||
|
||||
---
|
||||
|
||||
## SkeletonText
|
||||
`SkeletonText(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `skeleton skeleton-text` |
|
||||
|
||||
---
|
||||
|
||||
## Stack
|
||||
`Stack(props, children)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `stack` |
|
||||
|
||||
---
|
||||
|
||||
## Step
|
||||
`Step(props, children)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `dataContent` | string | - | Value for the `data-content` attribute |
|
||||
| `class` | string | - | Extra classes merged with `step` |
|
||||
|
||||
---
|
||||
|
||||
## Steps
|
||||
`Steps(props, children)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `steps` |
|
||||
|
||||
---
|
||||
|
||||
## Swap
|
||||
`Swap(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `value` | signal \| boolean | - | Checked state (can be a signal) |
|
||||
| `on` | node | - | Content for the “on” state |
|
||||
| `off` | node | - | Content for the “off” state |
|
||||
| `class` | string | - | Extra classes merged with `swap` |
|
||||
|
||||
---
|
||||
|
||||
## Table
|
||||
`Table(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `items` | array \| signal | `[]` | Data rows |
|
||||
| `columns` | array | `[]` | Column definitions: `{ key?, label?, class?, render? }` |
|
||||
| `header` | boolean | `true` | Show header row |
|
||||
| `keyFn` | function | `(item, idx) => item?.id ?? idx` | Key function for reactivity |
|
||||
| `class` | string | - | Extra classes |
|
||||
|
||||
If `children` is provided, manual mode (ignores `items`).
|
||||
|
||||
---
|
||||
|
||||
## Tabs
|
||||
`Tabs(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `items` | array \| signal | `[]` | Tab items: `{ label, content, closable?, class?, contentClass?, onclick? }` |
|
||||
| `activeIndex` | signal | - | Index of the active tab |
|
||||
| `onClose` | function | - | Called when a closable tab is closed: `(idx, item)` |
|
||||
| `class` | string | - | Extra classes |
|
||||
|
||||
If `children` is provided, manual mode.
|
||||
|
||||
---
|
||||
|
||||
## TextRotate
|
||||
`TextRotate(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `words` | array \| string | - | Array of words or comma‑separated string |
|
||||
| `class` | string | - | Extra classes merged with `text-rotate` |
|
||||
|
||||
---
|
||||
|
||||
## Textarea
|
||||
`Textarea(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `textarea` |
|
||||
| *any* | | | All standard `<textarea>` attributes |
|
||||
|
||||
---
|
||||
|
||||
## Timeline
|
||||
`Timeline(props, children)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `vertical` | boolean | `true` | If `false`, horizontal layout |
|
||||
| `compact` | boolean | `false` | Compact mode |
|
||||
| `class` | string | - | Extra classes merged with `timeline` |
|
||||
|
||||
---
|
||||
|
||||
## Toast
|
||||
`Toast(message, type?, duration?)`
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `message` | string \| signal | - | Toast text |
|
||||
| `type` | string | `'alert-success'` | Alert type class |
|
||||
| `duration` | number | `3500` | Auto‑close time in ms (0 for manual close) |
|
||||
|
||||
Returns a `close` function.
|
||||
|
||||
---
|
||||
|
||||
## Toggle
|
||||
`Toggle(props)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `class` | string | - | Extra classes merged with `toggle` |
|
||||
| `checked` | boolean \| signal | - | Checked state |
|
||||
| `onchange` | function | - | Change handler |
|
||||
|
||||
---
|
||||
|
||||
## Tooltip
|
||||
`Tooltip(props, children)`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `tip` | string | - | Tooltip text (sets `data-tip`) |
|
||||
| `class` | string | - | Extra classes merged with `tooltip` |
|
||||
2
docs/sigpro-ui.min.css
vendored
2
docs/sigpro-ui.min.css
vendored
File diff suppressed because one or more lines are too long
2
docs/sigpro-ui.min.js
vendored
2
docs/sigpro-ui.min.js
vendored
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user