Docs Updated
This commit is contained in:
@@ -8,12 +8,31 @@ Indicator component for adding badges, status markers, or notifications to eleme
|
||||
|
||||
## Props
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| :----------- | :--------------------------- | :---------- | :----------------------------------------------- |
|
||||
| `badge` | `string \| VNode \| Signal` | `-` | Content to display as indicator |
|
||||
| `badgeClass` | `string` | `''` | Additional CSS classes for the badge |
|
||||
| `class` | `string` | `''` | Additional CSS classes for the container |
|
||||
| `children` | `VNode` | `-` | Element to attach the indicator to |
|
||||
| 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](https://daisyui.com/components/indicator) – Full reference for CSS classes.
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
Indicator({ value: "3", class: "badge-primary" },
|
||||
Button({ class: "btn" }, "Notifications")
|
||||
);
|
||||
```
|
||||
|
||||
## Live Examples
|
||||
|
||||
@@ -29,15 +48,15 @@ Indicator component for adding badges, status markers, or notifications to eleme
|
||||
```javascript
|
||||
const BasicDemo = () => {
|
||||
return Div({ class: 'flex flex-wrap gap-8 justify-center' }, [
|
||||
Indicator({ value: '3', ui: 'badge-primary' }, [
|
||||
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+', ui: 'badge-secondary' }, [
|
||||
),
|
||||
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', ui: 'badge-accent' }, [
|
||||
),
|
||||
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');
|
||||
@@ -55,21 +74,21 @@ $mount(BasicDemo, '#demo-basic');
|
||||
```javascript
|
||||
const StatusDemo = () => {
|
||||
return Div({ class: 'flex flex-wrap gap-8 justify-center' }, [
|
||||
Indicator({ value: '●', ui: 'badge-success badge-xs' }, [
|
||||
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: '●', ui: 'badge-warning badge-xs' }, [
|
||||
),
|
||||
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: '●', ui: 'badge-error badge-xs' }, [
|
||||
),
|
||||
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');
|
||||
@@ -90,14 +109,14 @@ const ReactiveDemo = () => {
|
||||
|
||||
return Div({ class: 'flex flex-col gap-4 items-center' }, [
|
||||
Indicator({
|
||||
badge: () => count() > 0 ? count() : null,
|
||||
badgeClass: 'badge-primary'
|
||||
}, [
|
||||
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',
|
||||
@@ -145,11 +164,11 @@ const CartDemo = () => {
|
||||
return Div({ class: 'flex flex-col gap-4' }, [
|
||||
Div({ class: 'flex justify-between items-center' }, [
|
||||
Indicator({
|
||||
badge: () => cart().length,
|
||||
badgeClass: 'badge-primary'
|
||||
}, [
|
||||
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
|
||||
@@ -202,11 +221,11 @@ const InboxDemo = () => {
|
||||
return Div({ class: 'flex flex-col gap-4' }, [
|
||||
Div({ class: 'flex justify-between items-center' }, [
|
||||
Indicator({
|
||||
badge: () => unread(),
|
||||
badgeClass: 'badge-primary'
|
||||
}, [
|
||||
value: () => unread(),
|
||||
class: 'badge-primary'
|
||||
},
|
||||
Span({ class: 'text-lg font-bold' }, 'Inbox')
|
||||
]),
|
||||
),
|
||||
Button({
|
||||
class: 'btn btn-sm btn-ghost',
|
||||
onclick: () => {
|
||||
@@ -231,47 +250,6 @@ const InboxDemo = () => {
|
||||
$mount(InboxDemo, '#demo-inbox');
|
||||
```
|
||||
|
||||
### Custom Position
|
||||
|
||||
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title text-sm uppercase opacity-50 mb-4">Live Demo</h3>
|
||||
<div id="demo-positions" class="bg-base-100 p-6 rounded-xl border border-base-300 flex flex-wrap gap-8 justify-center"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
```javascript
|
||||
const PositionsDemo = () => {
|
||||
return Div({ class: 'flex flex-wrap gap-8 justify-center' }, [
|
||||
Div({ class: 'text-center' }, [
|
||||
Div({ class: 'text-xs mb-2' }, 'Top-Left'),
|
||||
Indicator({ badge: '●', badgeClass: 'badge-success badge-xs' }, [
|
||||
Div({ class: 'w-12 h-12 bg-base-300 rounded-lg' })
|
||||
])
|
||||
]),
|
||||
Div({ class: 'text-center' }, [
|
||||
Div({ class: 'text-xs mb-2' }, 'Top-Right'),
|
||||
Indicator({ badge: '●', badgeClass: 'badge-success badge-xs' }, [
|
||||
Div({ class: 'w-12 h-12 bg-base-300 rounded-lg' })
|
||||
])
|
||||
]),
|
||||
Div({ class: 'text-center' }, [
|
||||
Div({ class: 'text-xs mb-2' }, 'Bottom-Left'),
|
||||
Indicator({ badge: '●', badgeClass: 'badge-success badge-xs' }, [
|
||||
Div({ class: 'w-12 h-12 bg-base-300 rounded-lg' })
|
||||
])
|
||||
]),
|
||||
Div({ class: 'text-center' }, [
|
||||
Div({ class: 'text-xs mb-2' }, 'Bottom-Right'),
|
||||
Indicator({ badge: '●', badgeClass: 'badge-success badge-xs' }, [
|
||||
Div({ class: 'w-12 h-12 bg-base-300 rounded-lg' })
|
||||
])
|
||||
])
|
||||
]);
|
||||
};
|
||||
$mount(PositionsDemo, '#demo-positions');
|
||||
```
|
||||
|
||||
### All Variants
|
||||
|
||||
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
||||
@@ -284,273 +262,21 @@ $mount(PositionsDemo, '#demo-positions');
|
||||
```javascript
|
||||
const VariantsDemo = () => {
|
||||
return Div({ class: 'flex flex-wrap gap-8 justify-center' }, [
|
||||
Indicator({ badge: '3', badgeClass: 'badge-primary badge-sm' }, [
|
||||
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({ badge: '99+', badgeClass: 'badge-secondary badge-md' }, [
|
||||
),
|
||||
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({ badge: '●', badgeClass: 'badge-success badge-xs' }, [
|
||||
),
|
||||
Indicator({ value: '●', class: 'badge-success badge-xs' },
|
||||
Div({ class: 'avatar' }, [
|
||||
Div({ class: 'w-10 h-10 rounded-full bg-primary' })
|
||||
])
|
||||
]),
|
||||
Indicator({ badge: '!', badgeClass: 'badge-error badge-sm' }, [
|
||||
),
|
||||
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');
|
||||
```
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
const initIndicatorExamples = () => {
|
||||
|
||||
// 1. Basic Indicator
|
||||
const basicTarget = document.querySelector('#demo-basic');
|
||||
if (basicTarget && !basicTarget.hasChildNodes()) {
|
||||
const BasicDemo = () => {
|
||||
return Div({ class: 'flex flex-wrap gap-8 justify-center' }, [
|
||||
Indicator({ badge: '3', badgeClass: 'badge-primary' }, [
|
||||
Div({ class: 'w-16 h-16 bg-base-300 rounded-lg flex items-center justify-center' }, '📦')
|
||||
]),
|
||||
Indicator({ badge: '99+', badgeClass: 'badge-secondary' }, [
|
||||
Div({ class: 'w-16 h-16 bg-base-300 rounded-lg flex items-center justify-center' }, '🔔')
|
||||
]),
|
||||
Indicator({ badge: 'New', badgeClass: 'badge-accent' }, [
|
||||
Div({ class: 'w-16 h-16 bg-base-300 rounded-lg flex items-center justify-center' }, '✨')
|
||||
])
|
||||
]);
|
||||
};
|
||||
$mount(BasicDemo, basicTarget);
|
||||
}
|
||||
|
||||
// 2. Online Status Indicator
|
||||
const statusTarget = document.querySelector('#demo-status');
|
||||
if (statusTarget && !statusTarget.hasChildNodes()) {
|
||||
const StatusDemo = () => {
|
||||
return Div({ class: 'flex flex-wrap gap-8 justify-center' }, [
|
||||
Indicator({ badge: '●', badgeClass: '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({ badge: '●', badgeClass: '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({ badge: '●', badgeClass: '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, statusTarget);
|
||||
}
|
||||
|
||||
// 3. Reactive Counter
|
||||
const reactiveTarget = document.querySelector('#demo-reactive');
|
||||
if (reactiveTarget && !reactiveTarget.hasChildNodes()) {
|
||||
const ReactiveDemo = () => {
|
||||
const count = $(0);
|
||||
|
||||
return Div({ class: 'flex flex-col gap-4 items-center' }, [
|
||||
Indicator({
|
||||
badge: () => count() > 0 ? count() : null,
|
||||
badgeClass: '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, reactiveTarget);
|
||||
}
|
||||
|
||||
// 4. Shopping Cart
|
||||
const cartTarget = document.querySelector('#demo-cart');
|
||||
if (cartTarget && !cartTarget.hasChildNodes()) {
|
||||
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({
|
||||
badge: () => cart().length,
|
||||
badgeClass: '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, cartTarget);
|
||||
}
|
||||
|
||||
// 5. Email Inbox
|
||||
const inboxTarget = document.querySelector('#demo-inbox');
|
||||
if (inboxTarget && !inboxTarget.hasChildNodes()) {
|
||||
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({
|
||||
badge: () => unread(),
|
||||
badgeClass: '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, inboxTarget);
|
||||
}
|
||||
|
||||
// 6. Custom Position
|
||||
const positionsTarget = document.querySelector('#demo-positions');
|
||||
if (positionsTarget && !positionsTarget.hasChildNodes()) {
|
||||
const PositionsDemo = () => {
|
||||
return Div({ class: 'flex flex-wrap gap-8 justify-center' }, [
|
||||
Div({ class: 'text-center' }, [
|
||||
Div({ class: 'text-xs mb-2' }, 'Top-Left'),
|
||||
Indicator({ badge: '●', badgeClass: 'badge-success badge-xs' }, [
|
||||
Div({ class: 'w-12 h-12 bg-base-300 rounded-lg' })
|
||||
])
|
||||
]),
|
||||
Div({ class: 'text-center' }, [
|
||||
Div({ class: 'text-xs mb-2' }, 'Top-Right'),
|
||||
Indicator({ badge: '●', badgeClass: 'badge-success badge-xs' }, [
|
||||
Div({ class: 'w-12 h-12 bg-base-300 rounded-lg' })
|
||||
])
|
||||
]),
|
||||
Div({ class: 'text-center' }, [
|
||||
Div({ class: 'text-xs mb-2' }, 'Bottom-Left'),
|
||||
Indicator({ badge: '●', badgeClass: 'badge-success badge-xs' }, [
|
||||
Div({ class: 'w-12 h-12 bg-base-300 rounded-lg' })
|
||||
])
|
||||
]),
|
||||
Div({ class: 'text-center' }, [
|
||||
Div({ class: 'text-xs mb-2' }, 'Bottom-Right'),
|
||||
Indicator({ badge: '●', badgeClass: 'badge-success badge-xs' }, [
|
||||
Div({ class: 'w-12 h-12 bg-base-300 rounded-lg' })
|
||||
])
|
||||
])
|
||||
]);
|
||||
};
|
||||
$mount(PositionsDemo, positionsTarget);
|
||||
}
|
||||
|
||||
// 7. All Variants
|
||||
const variantsTarget = document.querySelector('#demo-variants');
|
||||
if (variantsTarget && !variantsTarget.hasChildNodes()) {
|
||||
const VariantsDemo = () => {
|
||||
return Div({ class: 'flex flex-wrap gap-8 justify-center' }, [
|
||||
Indicator({ badge: '3', badgeClass: 'badge-primary badge-sm' }, [
|
||||
Div({ class: 'w-12 h-12 bg-base-300 rounded-lg flex items-center justify-center' }, '📧')
|
||||
]),
|
||||
Indicator({ badge: '99+', badgeClass: 'badge-secondary badge-md' }, [
|
||||
Div({ class: 'w-12 h-12 bg-base-300 rounded-lg flex items-center justify-center' }, '🔔')
|
||||
]),
|
||||
Indicator({ badge: '●', badgeClass: 'badge-success badge-xs' }, [
|
||||
Div({ class: 'avatar' }, [
|
||||
Div({ class: 'w-10 h-10 rounded-full bg-primary' })
|
||||
])
|
||||
]),
|
||||
Indicator({ badge: '!', badgeClass: 'badge-error badge-sm' }, [
|
||||
Div({ class: 'w-12 h-12 bg-base-300 rounded-lg flex items-center justify-center' }, '⚠️')
|
||||
])
|
||||
]);
|
||||
};
|
||||
$mount(VariantsDemo, variantsTarget);
|
||||
}
|
||||
};
|
||||
|
||||
initIndicatorExamples();
|
||||
|
||||
if (window.$docsify) {
|
||||
window.$docsify.plugins = [].concat(window.$docsify.plugins || [], (hook) => {
|
||||
hook.doneEach(initIndicatorExamples);
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
```
|
||||
Reference in New Issue
Block a user