Docs Updated
This commit is contained in:
@@ -8,15 +8,38 @@ Data table component with sorting, pagination, zebra stripes, pin rows, and cust
|
||||
|
||||
## Props
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| :----------- | :-------------------------------------- | :--------------- | :----------------------------------------------- |
|
||||
| `items` | `Array \| Signal<Array>` | `[]` | Data array to display |
|
||||
| `columns` | `Array<{label: string, key?: string, render?: function, class?: string, footer?: string}>` | `[]` | Column definitions |
|
||||
| `keyFn` | `function` | `(item, idx) => idx` | Unique key function for rows |
|
||||
| `zebra` | `boolean \| Signal<boolean>` | `false` | Enable zebra striping |
|
||||
| `pinRows` | `boolean \| Signal<boolean>` | `false` | Pin header rows on scroll |
|
||||
| `empty` | `string \| VNode` | `'No data'` | Content to show when no data |
|
||||
| `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) |
|
||||
| Prop | Type | Default | Description |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| `items` | `Array \| Signal<Array>` | `[]` | Data array to display |
|
||||
| `columns` | `Array<Column>` | `[]` | Column definitions |
|
||||
| `keyFn` | `function` | `(item, idx) => idx` | Unique key function for rows |
|
||||
| `zebra` | `boolean \| Signal<boolean>` | `false` | Enable zebra striping |
|
||||
| `pinRows` | `boolean \| Signal<boolean>` | `false` | Pin header rows on scroll |
|
||||
| `empty` | `string \| VNode` | `'No data'` | Content to show when no data |
|
||||
| `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) |
|
||||
|
||||
### Column Structure
|
||||
|
||||
| Property | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `label` | `string` | Column header text |
|
||||
| `key` | `string` | Property key to display from item |
|
||||
| `render` | `function(item, index)` | Custom render function for cell content |
|
||||
| `class` | `string` | Additional CSS classes for column cells |
|
||||
| `footer` | `string \| VNode` | Footer content for the column |
|
||||
|
||||
## Styling
|
||||
|
||||
Table supports all **daisyUI Table classes**:
|
||||
|
||||
| Category | Keywords | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| Base | `table` | Base table styling |
|
||||
| Variant | `table-zebra` | Zebra striping |
|
||||
| Size | `table-xs`, `table-sm`, `table-md`, `table-lg`, `table-xl` | Table scale |
|
||||
| Feature | `table-pin-rows`, `table-pin-cols` | Pin headers/columns |
|
||||
|
||||
> For further details, check the [daisyUI Table Documentation](https://daisyui.com/components/table) – Full reference for CSS classes.
|
||||
|
||||
## Live Examples
|
||||
|
||||
@@ -194,8 +217,8 @@ const EmptyDemo = () => {
|
||||
{ label: 'ID', key: 'id' },
|
||||
{ label: 'Name', key: 'name' }
|
||||
],
|
||||
empty: Div({ class: 'flex flex-col items-center gap-2' }, [
|
||||
Icons.iconInfo,
|
||||
empty: Div({ class: 'flex flex-col items-center gap-2 p-4' }, [
|
||||
Span({ class: 'text-2xl' }, '📭'),
|
||||
Span({}, 'No records found')
|
||||
])
|
||||
});
|
||||
@@ -386,331 +409,4 @@ const VariantsDemo = () => {
|
||||
]);
|
||||
};
|
||||
$mount(VariantsDemo, '#demo-variants');
|
||||
```
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
const initTableExamples = () => {
|
||||
|
||||
// 1. Basic Table
|
||||
const basicTarget = document.querySelector('#demo-basic');
|
||||
if (basicTarget && !basicTarget.hasChildNodes()) {
|
||||
const BasicDemo = () => {
|
||||
const users = [
|
||||
{ id: 1, name: 'John Doe', email: 'john@example.com', role: 'Admin' },
|
||||
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', role: 'User' },
|
||||
{ id: 3, name: 'Bob Johnson', email: 'bob@example.com', role: 'Editor' }
|
||||
];
|
||||
|
||||
return Table({
|
||||
items: users,
|
||||
columns: [
|
||||
{ label: 'ID', key: 'id' },
|
||||
{ label: 'Name', key: 'name' },
|
||||
{ label: 'Email', key: 'email' },
|
||||
{ label: 'Role', key: 'role' }
|
||||
]
|
||||
});
|
||||
};
|
||||
$mount(BasicDemo, basicTarget);
|
||||
}
|
||||
|
||||
// 2. With Zebra Stripes
|
||||
const zebraTarget = document.querySelector('#demo-zebra');
|
||||
if (zebraTarget && !zebraTarget.hasChildNodes()) {
|
||||
const ZebraDemo = () => {
|
||||
const products = [
|
||||
{ id: 1, name: 'Laptop', price: '$999', stock: 15 },
|
||||
{ id: 2, name: 'Mouse', price: '$29', stock: 42 },
|
||||
{ id: 3, name: 'Keyboard', price: '$79', stock: 28 },
|
||||
{ id: 4, name: 'Monitor', price: '$299', stock: 12 }
|
||||
];
|
||||
|
||||
return Table({
|
||||
items: products,
|
||||
columns: [
|
||||
{ label: 'Product', key: 'name' },
|
||||
{ label: 'Price', key: 'price' },
|
||||
{ label: 'Stock', key: 'stock' }
|
||||
],
|
||||
zebra: true
|
||||
});
|
||||
};
|
||||
$mount(ZebraDemo, zebraTarget);
|
||||
}
|
||||
|
||||
// 3. With Custom Cell Rendering
|
||||
const customTarget = document.querySelector('#demo-custom');
|
||||
if (customTarget && !customTarget.hasChildNodes()) {
|
||||
const CustomDemo = () => {
|
||||
const orders = [
|
||||
{ id: 101, customer: 'Alice', amount: 250, status: 'completed' },
|
||||
{ id: 102, customer: 'Bob', amount: 89, status: 'pending' },
|
||||
{ id: 103, customer: 'Charlie', amount: 450, status: 'shipped' }
|
||||
];
|
||||
|
||||
return Table({
|
||||
items: orders,
|
||||
columns: [
|
||||
{ label: 'Order ID', key: 'id' },
|
||||
{ label: 'Customer', key: 'customer' },
|
||||
{
|
||||
label: 'Amount',
|
||||
key: 'amount',
|
||||
render: (item) => `$${item.amount}`
|
||||
},
|
||||
{
|
||||
label: 'Status',
|
||||
key: 'status',
|
||||
render: (item) => {
|
||||
const statusClass = {
|
||||
completed: 'badge badge-success',
|
||||
pending: 'badge badge-warning',
|
||||
shipped: 'badge badge-info'
|
||||
};
|
||||
return Span({ class: statusClass[item.status] }, item.status);
|
||||
}
|
||||
}
|
||||
],
|
||||
zebra: true
|
||||
});
|
||||
};
|
||||
$mount(CustomDemo, customTarget);
|
||||
}
|
||||
|
||||
// 4. With Footers
|
||||
const footerTarget = document.querySelector('#demo-footer');
|
||||
if (footerTarget && !footerTarget.hasChildNodes()) {
|
||||
const FooterDemo = () => {
|
||||
const sales = [
|
||||
{ month: 'January', revenue: 12500, expenses: 8900 },
|
||||
{ month: 'February', revenue: 14200, expenses: 9200 },
|
||||
{ month: 'March', revenue: 16800, expenses: 10100 }
|
||||
];
|
||||
|
||||
const totalRevenue = sales.reduce((sum, item) => sum + item.revenue, 0);
|
||||
const totalExpenses = sales.reduce((sum, item) => sum + item.expenses, 0);
|
||||
|
||||
return Table({
|
||||
items: sales,
|
||||
columns: [
|
||||
{ label: 'Month', key: 'month' },
|
||||
{
|
||||
label: 'Revenue',
|
||||
key: 'revenue',
|
||||
render: (item) => `$${item.revenue.toLocaleString()}`,
|
||||
footer: `Total: $${totalRevenue.toLocaleString()}`
|
||||
},
|
||||
{
|
||||
label: 'Expenses',
|
||||
key: 'expenses',
|
||||
render: (item) => `$${item.expenses.toLocaleString()}`,
|
||||
footer: `Total: $${totalExpenses.toLocaleString()}`
|
||||
},
|
||||
{
|
||||
label: 'Profit',
|
||||
render: (item) => `$${(item.revenue - item.expenses).toLocaleString()}`,
|
||||
footer: `$${(totalRevenue - totalExpenses).toLocaleString()}`
|
||||
}
|
||||
],
|
||||
zebra: true
|
||||
});
|
||||
};
|
||||
$mount(FooterDemo, footerTarget);
|
||||
}
|
||||
|
||||
// 5. Empty State
|
||||
const emptyTarget = document.querySelector('#demo-empty');
|
||||
if (emptyTarget && !emptyTarget.hasChildNodes()) {
|
||||
const EmptyDemo = () => {
|
||||
const emptyList = [];
|
||||
|
||||
return Table({
|
||||
items: emptyList,
|
||||
columns: [
|
||||
{ label: 'ID', key: 'id' },
|
||||
{ label: 'Name', key: 'name' }
|
||||
],
|
||||
empty: Div({ class: 'flex flex-col items-center gap-2' }, [
|
||||
Icons.iconInfo,
|
||||
Span({}, 'No records found')
|
||||
])
|
||||
});
|
||||
};
|
||||
$mount(EmptyDemo, emptyTarget);
|
||||
}
|
||||
|
||||
// 6. Reactive Data
|
||||
const reactiveTarget = document.querySelector('#demo-reactive');
|
||||
if (reactiveTarget && !reactiveTarget.hasChildNodes()) {
|
||||
const ReactiveDemo = () => {
|
||||
const filter = $('all');
|
||||
const tasks = $([
|
||||
{ id: 1, title: 'Complete documentation', completed: true },
|
||||
{ id: 2, title: 'Review pull requests', completed: false },
|
||||
{ id: 3, title: 'Deploy to production', completed: false },
|
||||
{ id: 4, title: 'Update dependencies', completed: true }
|
||||
]);
|
||||
|
||||
const filteredTasks = () => {
|
||||
if (filter() === 'completed') {
|
||||
return tasks().filter(t => t.completed);
|
||||
} else if (filter() === 'pending') {
|
||||
return tasks().filter(t => !t.completed);
|
||||
}
|
||||
return tasks();
|
||||
};
|
||||
|
||||
const addTask = () => {
|
||||
const newId = Math.max(...tasks().map(t => t.id), 0) + 1;
|
||||
tasks([...tasks(), { id: newId, title: `Task ${newId}`, completed: false }]);
|
||||
};
|
||||
|
||||
return Div({ class: 'flex flex-col gap-4' }, [
|
||||
Div({ class: 'flex gap-2' }, [
|
||||
Button({
|
||||
class: 'btn btn-sm',
|
||||
onclick: () => filter('all')
|
||||
}, 'All'),
|
||||
Button({
|
||||
class: 'btn btn-sm',
|
||||
onclick: () => filter('completed')
|
||||
}, 'Completed'),
|
||||
Button({
|
||||
class: 'btn btn-sm',
|
||||
onclick: () => filter('pending')
|
||||
}, 'Pending'),
|
||||
Button({
|
||||
class: 'btn btn-sm btn-primary',
|
||||
onclick: addTask
|
||||
}, 'Add Task')
|
||||
]),
|
||||
Table({
|
||||
items: filteredTasks,
|
||||
columns: [
|
||||
{ label: 'ID', key: 'id' },
|
||||
{ label: 'Title', key: 'title' },
|
||||
{
|
||||
label: 'Status',
|
||||
render: (item) => item.completed
|
||||
? Span({ class: 'badge badge-success' }, '✓ Done')
|
||||
: Span({ class: 'badge badge-warning' }, '○ Pending')
|
||||
}
|
||||
],
|
||||
zebra: true
|
||||
})
|
||||
]);
|
||||
};
|
||||
$mount(ReactiveDemo, reactiveTarget);
|
||||
}
|
||||
|
||||
// 7. With Actions
|
||||
const actionsTarget = document.querySelector('#demo-actions');
|
||||
if (actionsTarget && !actionsTarget.hasChildNodes()) {
|
||||
const ActionsDemo = () => {
|
||||
const users = $([
|
||||
{ id: 1, name: 'John Doe', email: 'john@example.com', active: true },
|
||||
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', active: false },
|
||||
{ id: 3, name: 'Bob Johnson', email: 'bob@example.com', active: true }
|
||||
]);
|
||||
|
||||
const deleteUser = (id) => {
|
||||
users(users().filter(u => u.id !== id));
|
||||
Toast('User deleted', 'alert-info', 2000);
|
||||
};
|
||||
|
||||
const toggleActive = (id) => {
|
||||
users(users().map(u =>
|
||||
u.id === id ? { ...u, active: !u.active } : u
|
||||
));
|
||||
};
|
||||
|
||||
return Table({
|
||||
items: users,
|
||||
columns: [
|
||||
{ label: 'ID', key: 'id' },
|
||||
{ label: 'Name', key: 'name' },
|
||||
{ label: 'Email', key: 'email' },
|
||||
{
|
||||
label: 'Status',
|
||||
render: (item) => item.active
|
||||
? Span({ class: 'badge badge-success' }, 'Active')
|
||||
: Span({ class: 'badge badge-ghost' }, 'Inactive')
|
||||
},
|
||||
{
|
||||
label: 'Actions',
|
||||
render: (item) => Div({ class: 'flex gap-1' }, [
|
||||
Button({
|
||||
class: 'btn btn-xs btn-ghost',
|
||||
onclick: () => toggleActive(item.id)
|
||||
}, item.active ? 'Deactivate' : 'Activate'),
|
||||
Button({
|
||||
class: 'btn btn-xs btn-error',
|
||||
onclick: () => deleteUser(item.id)
|
||||
}, 'Delete')
|
||||
])
|
||||
}
|
||||
],
|
||||
zebra: true
|
||||
});
|
||||
};
|
||||
$mount(ActionsDemo, actionsTarget);
|
||||
}
|
||||
|
||||
// 8. All Variants
|
||||
const variantsTarget = document.querySelector('#demo-variants');
|
||||
if (variantsTarget && !variantsTarget.hasChildNodes()) {
|
||||
const VariantsDemo = () => {
|
||||
const data = [
|
||||
{ id: 1, name: 'Item 1', value: 100 },
|
||||
{ id: 2, name: 'Item 2', value: 200 },
|
||||
{ id: 3, name: 'Item 3', value: 300 }
|
||||
];
|
||||
|
||||
return Div({ class: 'flex flex-col gap-6' }, [
|
||||
Div({ class: 'text-sm font-bold' }, 'Default Table'),
|
||||
Table({
|
||||
items: data,
|
||||
columns: [
|
||||
{ label: 'ID', key: 'id' },
|
||||
{ label: 'Name', key: 'name' },
|
||||
{ label: 'Value', key: 'value' }
|
||||
]
|
||||
}),
|
||||
|
||||
Div({ class: 'text-sm font-bold mt-4' }, 'Zebra Stripes'),
|
||||
Table({
|
||||
items: data,
|
||||
columns: [
|
||||
{ label: 'ID', key: 'id' },
|
||||
{ label: 'Name', key: 'name' },
|
||||
{ label: 'Value', key: 'value' }
|
||||
],
|
||||
zebra: true
|
||||
}),
|
||||
|
||||
Div({ class: 'text-sm font-bold mt-4' }, 'Compact Table'),
|
||||
Table({
|
||||
items: data,
|
||||
columns: [
|
||||
{ label: 'ID', key: 'id' },
|
||||
{ label: 'Name', key: 'name' },
|
||||
{ label: 'Value', key: 'value' }
|
||||
],
|
||||
class: 'table-compact'
|
||||
})
|
||||
]);
|
||||
};
|
||||
$mount(VariantsDemo, variantsTarget);
|
||||
}
|
||||
};
|
||||
|
||||
initTableExamples();
|
||||
|
||||
if (window.$docsify) {
|
||||
window.$docsify.plugins = [].concat(window.$docsify.plugins || [], (hook) => {
|
||||
hook.doneEach(initTableExamples);
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
```
|
||||
Reference in New Issue
Block a user