538 lines
18 KiB
Markdown
538 lines
18 KiB
Markdown
# Badge
|
|
|
|
Badge component for displaying counts, labels, and status indicators with DaisyUI styling.
|
|
|
|
## Tag
|
|
|
|
`Badge`
|
|
|
|
## Props
|
|
|
|
| Prop | Type | Default | Description |
|
|
| :----------- | :--------------------------- | :---------- | :----------------------------------------------- |
|
|
| `class` | `string` | `''` | Additional CSS classes (DaisyUI badge variants) |
|
|
| `children` | `string \| VNode` | `-` | Badge content |
|
|
|
|
## Live Examples
|
|
|
|
### Basic Badge
|
|
|
|
<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-basic" class="bg-base-100 p-6 rounded-xl border border-base-300 flex flex-wrap gap-2"></div>
|
|
</div>
|
|
</div>
|
|
|
|
```javascript
|
|
const BasicDemo = () => {
|
|
return Div({ class: 'flex flex-wrap gap-2' }, [
|
|
Badge({}, 'Default'),
|
|
Badge({ class: 'badge-primary' }, 'Primary'),
|
|
Badge({ class: 'badge-secondary' }, 'Secondary'),
|
|
Badge({ class: 'badge-accent' }, 'Accent'),
|
|
Badge({ class: 'badge-info' }, 'Info'),
|
|
Badge({ class: 'badge-success' }, 'Success'),
|
|
Badge({ class: 'badge-warning' }, 'Warning'),
|
|
Badge({ class: 'badge-error' }, 'Error')
|
|
]);
|
|
};
|
|
$mount(BasicDemo, '#demo-basic');
|
|
```
|
|
|
|
### Badge Sizes
|
|
|
|
<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-sizes" class="bg-base-100 p-6 rounded-xl border border-base-300 flex flex-wrap gap-2 items-center"></div>
|
|
</div>
|
|
</div>
|
|
|
|
```javascript
|
|
const SizesDemo = () => {
|
|
return Div({ class: 'flex flex-wrap gap-2 items-center' }, [
|
|
Badge({ class: 'badge-xs' }, 'Extra Small'),
|
|
Badge({ class: 'badge-sm' }, 'Small'),
|
|
Badge({}, 'Default'),
|
|
Badge({ class: 'badge-md' }, 'Medium'),
|
|
Badge({ class: 'badge-lg' }, 'Large')
|
|
]);
|
|
};
|
|
$mount(SizesDemo, '#demo-sizes');
|
|
```
|
|
|
|
### Outline Badges
|
|
|
|
<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-outline" class="bg-base-100 p-6 rounded-xl border border-base-300 flex flex-wrap gap-2"></div>
|
|
</div>
|
|
</div>
|
|
|
|
```javascript
|
|
const OutlineDemo = () => {
|
|
return Div({ class: 'flex flex-wrap gap-2' }, [
|
|
Badge({ class: 'badge-outline' }, 'Default'),
|
|
Badge({ class: 'badge-outline badge-primary' }, 'Primary'),
|
|
Badge({ class: 'badge-outline badge-secondary' }, 'Secondary'),
|
|
Badge({ class: 'badge-outline badge-accent' }, 'Accent'),
|
|
Badge({ class: 'badge-outline badge-info' }, 'Info'),
|
|
Badge({ class: 'badge-outline badge-success' }, 'Success'),
|
|
Badge({ class: 'badge-outline badge-warning' }, 'Warning'),
|
|
Badge({ class: 'badge-outline badge-error' }, 'Error')
|
|
]);
|
|
};
|
|
$mount(OutlineDemo, '#demo-outline');
|
|
```
|
|
|
|
### Ghost Badges
|
|
|
|
<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-ghost" class="bg-base-100 p-6 rounded-xl border border-base-300 flex flex-wrap gap-2"></div>
|
|
</div>
|
|
</div>
|
|
|
|
```javascript
|
|
const GhostDemo = () => {
|
|
return Div({ class: 'flex flex-wrap gap-2' }, [
|
|
Badge({ class: 'badge-ghost' }, 'Default'),
|
|
Badge({ class: 'badge-ghost badge-primary' }, 'Primary'),
|
|
Badge({ class: 'badge-ghost badge-secondary' }, 'Secondary'),
|
|
Badge({ class: 'badge-ghost badge-accent' }, 'Accent'),
|
|
Badge({ class: 'badge-ghost badge-info' }, 'Info'),
|
|
Badge({ class: 'badge-ghost badge-success' }, 'Success'),
|
|
Badge({ class: 'badge-ghost badge-warning' }, 'Warning'),
|
|
Badge({ class: 'badge-ghost badge-error' }, 'Error')
|
|
]);
|
|
};
|
|
$mount(GhostDemo, '#demo-ghost');
|
|
```
|
|
|
|
### With Icons
|
|
|
|
<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-icons" class="bg-base-100 p-6 rounded-xl border border-base-300 flex flex-wrap gap-2"></div>
|
|
</div>
|
|
</div>
|
|
|
|
```javascript
|
|
const IconsDemo = () => {
|
|
return Div({ class: 'flex flex-wrap gap-2' }, [
|
|
Badge({ class: 'gap-1' }, [
|
|
Icons.iconSuccess,
|
|
Span({}, 'Success')
|
|
]),
|
|
Badge({ class: 'gap-1 badge-warning' }, [
|
|
Icons.iconWarning,
|
|
Span({}, 'Warning')
|
|
]),
|
|
Badge({ class: 'gap-1 badge-error' }, [
|
|
Icons.iconError,
|
|
Span({}, 'Error')
|
|
]),
|
|
Badge({ class: 'gap-1 badge-info' }, [
|
|
Icons.iconInfo,
|
|
Span({}, 'Info')
|
|
]),
|
|
Badge({ class: 'gap-1' }, [
|
|
Span({}, '★'),
|
|
Span({}, '4.5')
|
|
])
|
|
]);
|
|
};
|
|
$mount(IconsDemo, '#demo-icons');
|
|
```
|
|
|
|
### Status Badges
|
|
|
|
<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-status" class="bg-base-100 p-6 rounded-xl border border-base-300 flex flex-col gap-4"></div>
|
|
</div>
|
|
</div>
|
|
|
|
```javascript
|
|
const StatusDemo = () => {
|
|
const statuses = [
|
|
{ label: 'Active', class: 'badge-success' },
|
|
{ label: 'Pending', class: 'badge-warning' },
|
|
{ label: 'Completed', class: 'badge-info' },
|
|
{ label: 'Failed', class: 'badge-error' },
|
|
{ label: 'Archived', class: 'badge-ghost' }
|
|
];
|
|
|
|
return Div({ class: 'flex flex-col gap-2' }, [
|
|
Div({ class: 'text-sm font-bold mb-2' }, 'Order Status'),
|
|
Div({ class: 'flex flex-wrap gap-2' }, statuses.map(status =>
|
|
Badge({ class: status.class }, status.label)
|
|
))
|
|
]);
|
|
};
|
|
$mount(StatusDemo, '#demo-status');
|
|
```
|
|
|
|
### Count Badges
|
|
|
|
<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-count" class="bg-base-100 p-6 rounded-xl border border-base-300 flex flex-wrap gap-4 items-center"></div>
|
|
</div>
|
|
</div>
|
|
|
|
```javascript
|
|
const CountDemo = () => {
|
|
const notifications = $(3);
|
|
const messages = $(5);
|
|
const updates = $(0);
|
|
|
|
return Div({ class: 'flex flex-wrap gap-6' }, [
|
|
Div({ class: 'flex items-center gap-2' }, [
|
|
Span({}, 'Notifications'),
|
|
Badge({ class: 'badge-primary' }, () => notifications())
|
|
]),
|
|
Div({ class: 'flex items-center gap-2' }, [
|
|
Span({}, 'Messages'),
|
|
Badge({ class: 'badge-secondary' }, () => messages())
|
|
]),
|
|
Div({ class: 'flex items-center gap-2' }, [
|
|
Span({}, 'Updates'),
|
|
Badge({ class: 'badge-ghost' }, () => updates() || '0')
|
|
])
|
|
]);
|
|
};
|
|
$mount(CountDemo, '#demo-count');
|
|
```
|
|
|
|
### Interactive Badge
|
|
|
|
<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-interactive" class="bg-base-100 p-6 rounded-xl border border-base-300"></div>
|
|
</div>
|
|
</div>
|
|
|
|
```javascript
|
|
const InteractiveDemo = () => {
|
|
const count = $(0);
|
|
|
|
return Div({ class: 'flex flex-col gap-4 items-center' }, [
|
|
Div({ class: 'flex items-center gap-4' }, [
|
|
Button({ class: 'btn btn-sm', onclick: () => count(count() - 1) }, '-'),
|
|
Badge({ class: 'badge-primary text-lg min-w-[4rem] justify-center' }, () => count()),
|
|
Button({ class: 'btn btn-sm', onclick: () => count(count() + 1) }, '+')
|
|
]),
|
|
Button({
|
|
class: 'btn btn-ghost btn-sm',
|
|
onclick: () => count(0)
|
|
}, 'Reset')
|
|
]);
|
|
};
|
|
$mount(InteractiveDemo, '#demo-interactive');
|
|
```
|
|
|
|
### All Variants
|
|
|
|
<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-variants" class="bg-base-100 p-6 rounded-xl border border-base-300 flex flex-col gap-4"></div>
|
|
</div>
|
|
</div>
|
|
|
|
```javascript
|
|
const VariantsDemo = () => {
|
|
return Div({ class: 'flex flex-col gap-6' }, [
|
|
Div({ class: 'flex flex-wrap gap-2' }, [
|
|
Badge({ class: 'badge-xs' }, 'XS'),
|
|
Badge({ class: 'badge-sm' }, 'SM'),
|
|
Badge({}, 'MD'),
|
|
Badge({ class: 'badge-lg' }, 'LG')
|
|
]),
|
|
Div({ class: 'flex flex-wrap gap-2' }, [
|
|
Badge({ class: 'badge-primary badge-sm' }, 'Primary'),
|
|
Badge({ class: 'badge-secondary badge-sm' }, 'Secondary'),
|
|
Badge({ class: 'badge-accent badge-sm' }, 'Accent')
|
|
]),
|
|
Div({ class: 'flex flex-wrap gap-2' }, [
|
|
Badge({ class: 'badge-outline badge-primary' }, 'Outline'),
|
|
Badge({ class: 'badge-ghost badge-primary' }, 'Ghost')
|
|
])
|
|
]);
|
|
};
|
|
$mount(VariantsDemo, '#demo-variants');
|
|
```
|
|
|
|
### Inline with Text
|
|
|
|
<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-inline" class="bg-base-100 p-6 rounded-xl border border-base-300"></div>
|
|
</div>
|
|
</div>
|
|
|
|
```javascript
|
|
const InlineDemo = () => {
|
|
return Div({ class: 'space-y-2' }, [
|
|
Div({ class: 'text-sm' }, [
|
|
'Your order is ',
|
|
Badge({ class: 'badge-success badge-sm' }, 'Confirmed'),
|
|
' and will be shipped soon.'
|
|
]),
|
|
Div({ class: 'text-sm' }, [
|
|
'This feature is ',
|
|
Badge({ class: 'badge-warning badge-sm' }, 'Beta'),
|
|
' and may change.'
|
|
]),
|
|
Div({ class: 'text-sm' }, [
|
|
'Version ',
|
|
Badge({ class: 'badge-info badge-xs' }, 'v2.1.0'),
|
|
' released on March 2026'
|
|
])
|
|
]);
|
|
};
|
|
$mount(InlineDemo, '#demo-inline');
|
|
```
|
|
|
|
<script>
|
|
(function() {
|
|
const initBadgeExamples = () => {
|
|
|
|
// 1. Basic Badge
|
|
const basicTarget = document.querySelector('#demo-basic');
|
|
if (basicTarget && !basicTarget.hasChildNodes()) {
|
|
const BasicDemo = () => {
|
|
return Div({ class: 'flex flex-wrap gap-2' }, [
|
|
Badge({}, 'Default'),
|
|
Badge({ class: 'badge-primary' }, 'Primary'),
|
|
Badge({ class: 'badge-secondary' }, 'Secondary'),
|
|
Badge({ class: 'badge-accent' }, 'Accent'),
|
|
Badge({ class: 'badge-info' }, 'Info'),
|
|
Badge({ class: 'badge-success' }, 'Success'),
|
|
Badge({ class: 'badge-warning' }, 'Warning'),
|
|
Badge({ class: 'badge-error' }, 'Error')
|
|
]);
|
|
};
|
|
$mount(BasicDemo, basicTarget);
|
|
}
|
|
|
|
// 2. Badge Sizes
|
|
const sizesTarget = document.querySelector('#demo-sizes');
|
|
if (sizesTarget && !sizesTarget.hasChildNodes()) {
|
|
const SizesDemo = () => {
|
|
return Div({ class: 'flex flex-wrap gap-2 items-center' }, [
|
|
Badge({ class: 'badge-xs' }, 'Extra Small'),
|
|
Badge({ class: 'badge-sm' }, 'Small'),
|
|
Badge({}, 'Default'),
|
|
Badge({ class: 'badge-md' }, 'Medium'),
|
|
Badge({ class: 'badge-lg' }, 'Large')
|
|
]);
|
|
};
|
|
$mount(SizesDemo, sizesTarget);
|
|
}
|
|
|
|
// 3. Outline Badges
|
|
const outlineTarget = document.querySelector('#demo-outline');
|
|
if (outlineTarget && !outlineTarget.hasChildNodes()) {
|
|
const OutlineDemo = () => {
|
|
return Div({ class: 'flex flex-wrap gap-2' }, [
|
|
Badge({ class: 'badge-outline' }, 'Default'),
|
|
Badge({ class: 'badge-outline badge-primary' }, 'Primary'),
|
|
Badge({ class: 'badge-outline badge-secondary' }, 'Secondary'),
|
|
Badge({ class: 'badge-outline badge-accent' }, 'Accent'),
|
|
Badge({ class: 'badge-outline badge-info' }, 'Info'),
|
|
Badge({ class: 'badge-outline badge-success' }, 'Success'),
|
|
Badge({ class: 'badge-outline badge-warning' }, 'Warning'),
|
|
Badge({ class: 'badge-outline badge-error' }, 'Error')
|
|
]);
|
|
};
|
|
$mount(OutlineDemo, outlineTarget);
|
|
}
|
|
|
|
// 4. Ghost Badges
|
|
const ghostTarget = document.querySelector('#demo-ghost');
|
|
if (ghostTarget && !ghostTarget.hasChildNodes()) {
|
|
const GhostDemo = () => {
|
|
return Div({ class: 'flex flex-wrap gap-2' }, [
|
|
Badge({ class: 'badge-ghost' }, 'Default'),
|
|
Badge({ class: 'badge-ghost badge-primary' }, 'Primary'),
|
|
Badge({ class: 'badge-ghost badge-secondary' }, 'Secondary'),
|
|
Badge({ class: 'badge-ghost badge-accent' }, 'Accent'),
|
|
Badge({ class: 'badge-ghost badge-info' }, 'Info'),
|
|
Badge({ class: 'badge-ghost badge-success' }, 'Success'),
|
|
Badge({ class: 'badge-ghost badge-warning' }, 'Warning'),
|
|
Badge({ class: 'badge-ghost badge-error' }, 'Error')
|
|
]);
|
|
};
|
|
$mount(GhostDemo, ghostTarget);
|
|
}
|
|
|
|
// 5. With Icons
|
|
const iconsTarget = document.querySelector('#demo-icons');
|
|
if (iconsTarget && !iconsTarget.hasChildNodes()) {
|
|
const IconsDemo = () => {
|
|
return Div({ class: 'flex flex-wrap gap-2' }, [
|
|
Badge({ class: 'gap-1' }, [
|
|
Img({src: Icons.iconSuccess}),
|
|
Span({}, 'Success')
|
|
]),
|
|
Badge({ class: 'gap-1 badge-warning' }, [
|
|
Img({src: Icons.iconWarning}),
|
|
Span({}, 'Warning')
|
|
]),
|
|
Badge({ class: 'gap-1 badge-error' }, [
|
|
Img({src: Icons.iconError}),
|
|
Span({}, 'Error')
|
|
]),
|
|
Badge({ class: 'gap-1 badge-info' }, [
|
|
Img({src: Icons.iconInfo}),
|
|
Span({}, 'Info')
|
|
]),
|
|
Badge({ class: 'gap-1' }, [
|
|
Span({}, '★'),
|
|
Span({}, '4.5')
|
|
])
|
|
]);
|
|
};
|
|
$mount(IconsDemo, iconsTarget);
|
|
}
|
|
|
|
// 6. Status Badges
|
|
const statusTarget = document.querySelector('#demo-status');
|
|
if (statusTarget && !statusTarget.hasChildNodes()) {
|
|
const StatusDemo = () => {
|
|
const statuses = [
|
|
{ label: 'Active', class: 'badge-success' },
|
|
{ label: 'Pending', class: 'badge-warning' },
|
|
{ label: 'Completed', class: 'badge-info' },
|
|
{ label: 'Failed', class: 'badge-error' },
|
|
{ label: 'Archived', class: 'badge-ghost' }
|
|
];
|
|
|
|
return Div({ class: 'flex flex-col gap-2' }, [
|
|
Div({ class: 'text-sm font-bold mb-2' }, 'Order Status'),
|
|
Div({ class: 'flex flex-wrap gap-2' }, statuses.map(status =>
|
|
Badge({ class: status.class }, status.label)
|
|
))
|
|
]);
|
|
};
|
|
$mount(StatusDemo, statusTarget);
|
|
}
|
|
|
|
// 7. Count Badges
|
|
const countTarget = document.querySelector('#demo-count');
|
|
if (countTarget && !countTarget.hasChildNodes()) {
|
|
const CountDemo = () => {
|
|
const notifications = $(3);
|
|
const messages = $(5);
|
|
const updates = $(0);
|
|
|
|
return Div({ class: 'flex flex-wrap gap-6' }, [
|
|
Div({ class: 'flex items-center gap-2' }, [
|
|
Span({}, 'Notifications'),
|
|
Badge({ class: 'badge-primary' }, () => notifications())
|
|
]),
|
|
Div({ class: 'flex items-center gap-2' }, [
|
|
Span({}, 'Messages'),
|
|
Badge({ class: 'badge-secondary' }, () => messages())
|
|
]),
|
|
Div({ class: 'flex items-center gap-2' }, [
|
|
Span({}, 'Updates'),
|
|
Badge({ class: 'badge-ghost' }, () => updates() || '0')
|
|
])
|
|
]);
|
|
};
|
|
$mount(CountDemo, countTarget);
|
|
}
|
|
|
|
// 8. Interactive Badge
|
|
const interactiveTarget = document.querySelector('#demo-interactive');
|
|
if (interactiveTarget && !interactiveTarget.hasChildNodes()) {
|
|
const InteractiveDemo = () => {
|
|
const count = $(0);
|
|
|
|
return Div({ class: 'flex flex-col gap-4 items-center' }, [
|
|
Div({ class: 'flex items-center gap-4' }, [
|
|
Button({ class: 'btn btn-sm', onclick: () => count(count() - 1) }, '-'),
|
|
Badge({ class: 'badge-primary text-lg min-w-[4rem] justify-center' }, () => count()),
|
|
Button({ class: 'btn btn-sm', onclick: () => count(count() + 1) }, '+')
|
|
]),
|
|
Button({
|
|
class: 'btn btn-ghost btn-sm',
|
|
onclick: () => count(0)
|
|
}, 'Reset')
|
|
]);
|
|
};
|
|
$mount(InteractiveDemo, interactiveTarget);
|
|
}
|
|
|
|
// 9. All Variants
|
|
const variantsTarget = document.querySelector('#demo-variants');
|
|
if (variantsTarget && !variantsTarget.hasChildNodes()) {
|
|
const VariantsDemo = () => {
|
|
return Div({ class: 'flex flex-col gap-6' }, [
|
|
Div({ class: 'flex flex-wrap gap-2' }, [
|
|
Badge({ class: 'badge-xs' }, 'XS'),
|
|
Badge({ class: 'badge-sm' }, 'SM'),
|
|
Badge({}, 'MD'),
|
|
Badge({ class: 'badge-lg' }, 'LG')
|
|
]),
|
|
Div({ class: 'flex flex-wrap gap-2' }, [
|
|
Badge({ class: 'badge-primary badge-sm' }, 'Primary'),
|
|
Badge({ class: 'badge-secondary badge-sm' }, 'Secondary'),
|
|
Badge({ class: 'badge-accent badge-sm' }, 'Accent')
|
|
]),
|
|
Div({ class: 'flex flex-wrap gap-2' }, [
|
|
Badge({ class: 'badge-outline badge-primary' }, 'Outline'),
|
|
Badge({ class: 'badge-ghost badge-primary' }, 'Ghost')
|
|
])
|
|
]);
|
|
};
|
|
$mount(VariantsDemo, variantsTarget);
|
|
}
|
|
|
|
// 10. Inline with Text
|
|
const inlineTarget = document.querySelector('#demo-inline');
|
|
if (inlineTarget && !inlineTarget.hasChildNodes()) {
|
|
const InlineDemo = () => {
|
|
return Div({ class: 'space-y-2' }, [
|
|
Div({ class: 'text-sm' }, [
|
|
'Your order is ',
|
|
Badge({ class: 'badge-success badge-sm' }, 'Confirmed'),
|
|
' and will be shipped soon.'
|
|
]),
|
|
Div({ class: 'text-sm' }, [
|
|
'This feature is ',
|
|
Badge({ class: 'badge-warning badge-sm' }, 'Beta'),
|
|
' and may change.'
|
|
]),
|
|
Div({ class: 'text-sm' }, [
|
|
'Version ',
|
|
Badge({ class: 'badge-info badge-xs' }, 'v2.1.0'),
|
|
' released on March 2026'
|
|
])
|
|
]);
|
|
};
|
|
$mount(InlineDemo, inlineTarget);
|
|
}
|
|
};
|
|
|
|
initBadgeExamples();
|
|
|
|
if (window.$docsify) {
|
|
window.$docsify.plugins = [].concat(window.$docsify.plugins || [], (hook) => {
|
|
hook.doneEach(initBadgeExamples);
|
|
});
|
|
}
|
|
})();
|
|
</script>
|