All checks were successful
Deploy Docs to Synology / deploy (push) Successful in 3s
9.3 KiB
9.3 KiB
Indicator
Indicator component for adding badges, status markers, or notifications to elements. Perfect for showing counts, online status, or alerts.
Tag
Indicator
Props
| Prop | Type | Default | Description |
|---|---|---|---|
value |
string | VNode | Signal |
- |
Content to display as indicator |
class |
string |
'' |
Additional CSS classes for the badge |
children |
VNode |
- |
Element to attach the indicator to |
Styling
Indicator uses daisyUI Indicator and Badge classes:
| Category | Keywords | Description |
|---|---|---|
| Position | indicator-start, indicator-end, indicator-top, indicator-bottom |
Indicator position (default: top-end) |
| Badge Color | badge-primary, badge-secondary, badge-accent, badge-info, badge-success, badge-warning, badge-error |
Badge visual variants |
| Badge Size | badge-xs, badge-sm, badge-md, badge-lg |
Badge scale |
For further details, check the daisyUI Indicator Documentation – Full reference for CSS classes.
Example
Indicator({ value: "3", class: "badge-primary" },
button({ class: "btn" }, "Notifications")
);
Live Examples
Basic Indicator
Live Demo
const BasicDemo = () => {
return div({ class: 'flex flex-wrap gap-8 justify-center' }, [
Indicator({ value: '3', class: 'badge-primary' },
div({ class: 'w-16 h-16 bg-base-300 rounded-lg flex items-center justify-center' }, '📦')
),
Indicator({ value: '99+', class: 'badge-secondary' },
div({ class: 'w-16 h-16 bg-base-300 rounded-lg flex items-center justify-center' }, '🔔')
),
Indicator({ value: 'New', class: 'badge-accent' },
div({ class: 'w-16 h-16 bg-base-300 rounded-lg flex items-center justify-center' }, '✨')
)
]);
};
mount(BasicDemo, '#demo-basic');
Online Status Indicator
Live Demo
const StatusDemo = () => {
return div({ class: 'flex flex-wrap gap-8 justify-center' }, [
Indicator({ value: '●', class: 'badge-success badge-xs' },
div({ class: 'avatar placeholder' }, [
div({ class: 'bg-neutral text-neutral-content rounded-full w-12 h-12 flex items-center justify-center' }, 'JD')
])
),
Indicator({ value: '●', class: 'badge-warning badge-xs' },
div({ class: 'avatar placeholder' }, [
div({ class: 'bg-neutral text-neutral-content rounded-full w-12 h-12 flex items-center justify-center' }, 'JS')
])
),
Indicator({ value: '●', class: 'badge-error badge-xs' },
div({ class: 'avatar placeholder' }, [
div({ class: 'bg-neutral text-neutral-content rounded-full w-12 h-12 flex items-center justify-center' }, 'BC')
])
)
]);
};
mount(StatusDemo, '#demo-status');
Reactive Counter
Live Demo
const ReactiveDemo = () => {
const count = $(0);
return div({ class: 'flex flex-col gap-4 items-center' }, [
Indicator({
value: () => count() > 0 ? count() : null,
class: 'badge-primary'
},
button({
class: 'btn btn-lg btn-primary',
onclick: () => count(count() + 1)
}, 'Notifications')
),
div({ class: 'flex gap-2' }, [
button({
class: 'btn btn-sm',
onclick: () => count(Math.max(0, count() - 1))
}, 'Decrease'),
button({
class: 'btn btn-sm btn-ghost',
onclick: () => count(0)
}, 'Clear')
])
]);
};
mount(ReactiveDemo, '#demo-reactive');
Shopping Cart
Live Demo
const CartDemo = () => {
const cart = $([
{ id: 1, name: 'Product 1', price: 29 },
{ id: 2, name: 'Product 2', price: 49 }
]);
const addItem = () => {
const newId = Math.max(...cart().map(i => i.id), 0) + 1;
cart([...cart(), { id: newId, name: `Product ${newId}`, price: Math.floor(Math.random() * 100) + 10 }]);
Toast('Item added to cart', 'alert-success', 1500);
};
const removeItem = (id) => {
cart(cart().filter(item => item.id !== id));
Toast('Item removed', 'alert-info', 1500);
};
const total = () => cart().reduce((sum, item) => sum + item.price, 0);
return div({ class: 'flex flex-col gap-4' }, [
div({ class: 'flex justify-between items-center' }, [
Indicator({
value: () => cart().length,
class: 'badge-primary'
},
button({ class: 'btn', onclick: addItem }, '🛒 Add to Cart')
),
span({ class: 'text-lg font-bold' }, () => `Total: $${total()}`)
]),
() => cart().length === 0
? div({ class: 'alert alert-soft text-center' }, 'Cart is empty')
: div({ class: 'flex flex-col gap-2' }, cart().map(item =>
div({ class: 'flex justify-between items-center p-2 bg-base-200 rounded-lg' }, [
span({}, item.name),
div({ class: 'flex gap-2 items-center' }, [
span({ class: 'text-sm font-bold' }, `$${item.price}`),
button({
class: 'btn btn-xs btn-ghost btn-circle',
onclick: () => removeItem(item.id)
}, '✕')
])
])
))
]);
};
mount(CartDemo, '#demo-cart');
Email Inbox
Live Demo
const InboxDemo = () => {
const unread = $(3);
const messages = $([
{ id: 1, from: 'john@example.com', subject: 'Meeting tomorrow', read: false },
{ id: 2, from: 'jane@example.com', subject: 'Project update', read: false },
{ id: 3, from: 'bob@example.com', subject: 'Question about design', read: false },
{ id: 4, from: 'alice@example.com', subject: 'Weekly report', read: true }
]);
const markAsRead = (id) => {
const msg = messages().find(m => m.id === id);
if (!msg.read) {
msg.read = true;
messages([...messages()]);
unread(unread() - 1);
}
};
return div({ class: 'flex flex-col gap-4' }, [
div({ class: 'flex justify-between items-center' }, [
Indicator({
value: () => unread(),
class: 'badge-primary'
},
span({ class: 'text-lg font-bold' }, 'Inbox')
),
button({
class: 'btn btn-sm btn-ghost',
onclick: () => {
messages().forEach(m => m.read = true);
messages([...messages()]);
unread(0);
}
}, 'Mark all read')
]),
div({ class: 'flex flex-col gap-2' }, () => messages().map(msg =>
div({
class: `p-3 rounded-lg cursor-pointer transition-all ${msg.read ? 'bg-base-200 opacity-60' : 'bg-primary/10 border-l-4 border-primary'}`,
onclick: () => markAsRead(msg.id)
}, [
div({ class: 'font-medium' }, msg.from),
div({ class: 'text-sm' }, msg.subject),
!msg.read && span({ class: 'badge badge-xs badge-primary mt-1' }, 'New')
])
))
]);
};
mount(InboxDemo, '#demo-inbox');
All Variants
Live Demo
const VariantsDemo = () => {
return div({ class: 'flex flex-wrap gap-8 justify-center' }, [
Indicator({ value: '3', class: 'badge-primary badge-sm' },
div({ class: 'w-12 h-12 bg-base-300 rounded-lg flex items-center justify-center' }, '📧')
),
Indicator({ value: '99+', class: 'badge-secondary badge-md' },
div({ class: 'w-12 h-12 bg-base-300 rounded-lg flex items-center justify-center' }, '🔔')
),
Indicator({ value: '●', class: 'badge-success badge-xs' },
div({ class: 'avatar' }, [
div({ class: 'w-10 h-10 rounded-full bg-primary' })
])
),
Indicator({ value: '!', class: 'badge-error badge-sm' },
div({ class: 'w-12 h-12 bg-base-300 rounded-lg flex items-center justify-center' }, '⚠️')
)
]);
};
mount(VariantsDemo, '#demo-variants');