20 KiB
20 KiB
Timeline
Timeline component for displaying chronological events, steps, or progress with customizable icons and content.
Tag
Timeline
Props
| Prop | Type | Default | Description |
|---|---|---|---|
items |
Array<TimelineItem> | Signal |
[] |
Timeline items to display |
vertical |
boolean | Signal<boolean> |
true |
Vertical or horizontal orientation |
compact |
boolean | Signal<boolean> |
false |
Compact mode with less padding |
class |
string |
'' |
Additional CSS classes (DaisyUI + Tailwind) |
TimelineItem Structure
| Property | Type | Description |
|---|---|---|
title |
string | VNode | Signal |
Event title or main text |
detail |
string | VNode | Signal |
Additional details or description |
icon |
string | VNode |
Custom icon (overrides type) |
type |
string |
Type: 'success', 'warning', 'error', 'info' |
completed |
boolean |
Whether event is completed (affects connector) |
Live Examples
Basic Timeline
Live Demo
const BasicDemo = () => {
const events = [
{ title: 'Project Started', detail: 'Initial planning and setup', type: 'info', completed: true },
{ title: 'Design Phase', detail: 'UI/UX design completed', type: 'success', completed: true },
{ title: 'Development', detail: 'Core features implemented', type: 'warning', completed: false },
{ title: 'Testing', detail: 'Quality assurance', type: 'info', completed: false },
{ title: 'Launch', detail: 'Production deployment', type: 'success', completed: false }
];
return Timeline({ items: events });
};
Mount(BasicDemo, '#demo-basic');
Horizontal Timeline
Live Demo
const HorizontalDemo = () => {
const steps = [
{ title: 'Step 1', detail: 'Requirements', type: 'success', completed: true },
{ title: 'Step 2', detail: 'Design', type: 'success', completed: true },
{ title: 'Step 3', detail: 'Development', type: 'warning', completed: false },
{ title: 'Step 4', detail: 'Testing', type: 'info', completed: false },
{ title: 'Step 5', detail: 'Deploy', type: 'info', completed: false }
];
return Timeline({
items: steps,
vertical: false,
class: 'min-w-[600px]'
});
};
Mount(HorizontalDemo, '#demo-horizontal');
Compact Timeline
Live Demo
const CompactDemo = () => {
const activities = [
{ title: 'User login', detail: '10:30 AM', type: 'success', completed: true },
{ title: 'Viewed dashboard', detail: '10:32 AM', type: 'info', completed: true },
{ title: 'Updated profile', detail: '10:45 AM', type: 'success', completed: true },
{ title: 'Made purchase', detail: '11:00 AM', type: 'warning', completed: false }
];
return Timeline({
items: activities,
compact: true
});
};
Mount(CompactDemo, '#demo-compact');
Custom Icons
Live Demo
const IconsDemo = () => {
const milestones = [
{ title: 'Kickoff', detail: 'Project kickoff meeting', icon: Icons.iconInfo, completed: true },
{ title: 'MVP', detail: 'Minimum viable product', icon: Icons.iconSuccess, completed: true },
{ title: 'Beta', detail: 'Beta release', icon: Icons.iconWarning, completed: false },
{ title: 'Launch', detail: 'Public launch', icon: Icons.iconShow, completed: false }
];
return Timeline({ items: milestones });
};
Mount(IconsDemo, '#demo-icons');
Reactive Timeline
Live Demo
const ReactiveDemo = () => {
const currentStep = $(2);
const steps = [
{ title: 'Order Placed', detail: 'Your order has been confirmed', type: 'success', completed: true },
{ title: 'Processing', detail: 'Payment verified, preparing shipment', type: 'success', completed: currentStep() > 1 },
{ title: 'Shipped', detail: 'Package on the way', type: 'warning', completed: currentStep() > 2 },
{ title: 'Delivered', detail: 'Arriving soon', type: 'info', completed: currentStep() > 3 }
];
const items = () => steps.map((step, idx) => ({
...step,
completed: idx < currentStep()
}));
const nextStep = () => {
if (currentStep() < steps.length) {
currentStep(currentStep() + 1);
Toast(`Step ${currentStep()}: ${steps[currentStep() - 1].title}`, 'alert-info', 1500);
}
};
const reset = () => {
currentStep(0);
Toast('Order tracking reset', 'alert-warning', 1500);
};
return Div({ class: 'flex flex-col gap-4' }, [
Timeline({ items: items }),
Div({ class: 'flex gap-2 justify-center mt-4' }, [
Button({
class: 'btn btn-primary btn-sm',
onclick: nextStep,
disabled: () => currentStep() >= steps.length
}, 'Next Step'),
Button({
class: 'btn btn-ghost btn-sm',
onclick: reset
}, 'Reset')
])
]);
};
Mount(ReactiveDemo, '#demo-reactive');
Order Status Tracker
Live Demo
const OrderDemo = () => {
const status = $('shipped');
const statusMap = {
pending: { title: 'Order Pending', detail: 'Awaiting confirmation', completed: false, type: 'warning' },
confirmed: { title: 'Order Confirmed', detail: 'Payment received', completed: false, type: 'info' },
processing: { title: 'Processing', detail: 'Preparing your order', completed: false, type: 'info' },
shipped: { title: 'Shipped', detail: 'Package in transit', completed: false, type: 'info' },
delivered: { title: 'Delivered', detail: 'Order completed', completed: false, type: 'success' }
};
const statusOrder = ['pending', 'confirmed', 'processing', 'shipped', 'delivered'];
const currentIndex = statusOrder.indexOf(status());
const items = statusOrder.map((key, idx) => ({
...statusMap[key],
completed: idx < currentIndex
}));
return Div({ class: 'flex flex-col gap-4' }, [
Timeline({ items, compact: true }),
Div({ class: 'flex gap-2 justify-center flex-wrap mt-4' }, statusOrder.map(s =>
Button({
class: `btn btn-xs ${status() === s ? 'btn-primary' : 'btn-ghost'}`,
onclick: () => status(s)
}, statusMap[s].title)
))
]);
};
Mount(OrderDemo, '#demo-order');
Company History
Live Demo
const HistoryDemo = () => {
const milestones = [
{
title: '2015 - Founded',
detail: 'Company started with 3 employees in a small office',
type: 'success',
completed: true
},
{
title: '2017 - First Product',
detail: 'Launched our first software product to market',
type: 'success',
completed: true
},
{
title: '2019 - Series A',
detail: 'Raised $5M in funding, expanded team to 50',
type: 'success',
completed: true
},
{
title: '2022 - Global Expansion',
detail: 'Opened offices in Europe and Asia',
type: 'info',
completed: true
},
{
title: '2024 - AI Integration',
detail: 'Launched AI-powered features',
type: 'warning',
completed: false
},
{
title: '2026 - Future Goals',
detail: 'Aiming for market leadership',
type: 'info',
completed: false
}
];
return Timeline({ items: milestones });
};
Mount(HistoryDemo, '#demo-history');
All Variants
Live Demo
const VariantsDemo = () => {
const sampleItems = [
{ title: 'Event 1', detail: 'Description here', type: 'success', completed: true },
{ title: 'Event 2', detail: 'Description here', type: 'warning', completed: false },
{ title: 'Event 3', detail: 'Description here', type: 'info', completed: false }
];
return Div({ class: 'flex flex-col gap-8' }, [
Div({ class: 'text-sm font-bold' }, 'Vertical Timeline'),
Timeline({ items: sampleItems }),
Div({ class: 'text-sm font-bold mt-4' }, 'Horizontal Timeline'),
Timeline({ items: sampleItems, vertical: false, class: 'min-w-[500px]' }),
Div({ class: 'text-sm font-bold mt-4' }, 'Compact Timeline'),
Timeline({ items: sampleItems, compact: true })
]);
};
Mount(VariantsDemo, '#demo-variants');