moduix-react
itembadgesource: ok · hit
Badge
moduix React Badge component.
npx shadcn add "https://moduix.dev/r/react/badge.json"free
No selection tags yet — empty means no evidence, not lack of support.
Dependencies
Bundle weight · lightui-primitives@ark-ui/react
Registry dependencies
@moduix-react/foundation
Files3 · source cached 10/14/2026, 1:27:12 PM
src/components/badge/Badge.tsx
import type { HTMLArkProps } from '@ark-ui/react/factory';
import { ark } from '@ark-ui/react/factory';
import { clsx } from 'clsx';
import { forwardRef, type ComponentRef } from 'react';
import styles from './Badge.module.css';
type BadgeRootProps = HTMLArkProps<'span'> & {
variant?: 'default' | 'secondary' | 'destructive' | 'outline' | 'ghost' | 'link';
};
const BadgeLabel = forwardRef<ComponentRef<typeof ark.span>, HTMLArkProps<'span'>>(
function BadgeLabel({ className, ...props }, ref) {
return (
<ark.span
ref={ref}
{...props}
data-scope="badge"
data-part="label"
data-slot="badge-label"
className={clsx(styles.label, className)}
/>
);
},
);
const Badge = forwardRef<ComponentRef<typeof ark.span>, BadgeRootProps>(function Badge(
{ className, variant = 'default', ...props },
ref,
) {
return (
<ark.span
ref={ref}
{...props}
data-scope="badge"
data-part="root"
data-slot="badge-root"
data-variant={variant}
className={clsx(styles.root, className)}
/>
);
});
const BadgeDot = forwardRef<ComponentRef<typeof ark.span>, HTMLArkProps<'span'>>(function BadgeDot(
{ className, ...props },
ref,
) {
return (
<ark.span
ref={ref}
{...props}
data-scope="badge"
data-part="dot"
data-slot="badge-dot"
aria-hidden="true"
className={clsx(styles.dot, className)}
/>
);
});
export { Badge, BadgeDot, BadgeLabel };src/components/badge/Badge.module.css
@layer moduix.components {
.root {
display: inline-flex;
width: fit-content;
max-width: 100%;
min-width: 0;
box-sizing: border-box;
align-items: center;
justify-content: center;
gap: var(--moduix-badge-gap, var(--moduix-spacing-1-5));
overflow: hidden;
border: var(--moduix-badge-border-width, var(--moduix-border-width-sm)) solid
var(--moduix-badge-border-color, var(--moduix-badge-default-border-color, transparent));
border-radius: var(--moduix-badge-radius, var(--moduix-radius-full));
padding-block: var(--moduix-badge-padding-y, 0);
padding-inline: var(--moduix-badge-padding-x, var(--moduix-spacing-2-5));
background-color: var(
--moduix-badge-bg,
var(--moduix-badge-default-bg, var(--moduix-color-primary))
);
color: var(
--moduix-badge-color,
var(--moduix-badge-default-color, var(--moduix-color-primary-foreground))
);
font-size: var(--moduix-badge-font-size, var(--moduix-text-xs));
font-weight: var(--moduix-badge-font-weight, var(--moduix-weight-medium));
font-variant-numeric: tabular-nums;
line-height: var(--moduix-badge-line-height, var(--moduix-line-height-text-xs));
min-height: var(--moduix-badge-height, 1.25rem);
user-select: none;
white-space: nowrap;
text-decoration: none;
vertical-align: middle;
transition:
color var(--moduix-badge-transition, var(--moduix-transition-default)),
background-color var(--moduix-badge-transition, var(--moduix-transition-default)),
border-color var(--moduix-badge-transition, var(--moduix-transition-default)),
opacity var(--moduix-badge-transition, var(--moduix-transition-default));
&:focus-visible {
outline: var(
--moduix-badge-focus-ring-width,
var(--moduix-focus-ring-width, var(--moduix-border-width-md))
)
solid var(--moduix-badge-focus-ring-color, var(--moduix-color-ring));
outline-offset: var(--moduix-badge-focus-ring-offset, var(--moduix-focus-ring-offset));
}
&:is(a) {
cursor: pointer;
&:is(
[data-variant='default'],
[data-variant='secondary'],
[data-variant='destructive']
):hover {
opacity: var(--moduix-badge-opacity-hover, var(--moduix-opacity-hover));
}
&[data-variant='outline']:hover {
border-color: var(
--moduix-badge-border-color,
var(--moduix-badge-outline-border-color-hover, var(--moduix-color-primary))
);
color: var(
--moduix-badge-color,
var(--moduix-badge-outline-color-hover, var(--moduix-color-primary))
);
}
&[data-variant='ghost']:hover {
border-color: var(
--moduix-badge-border-color,
var(--moduix-badge-ghost-border-color-hover, var(--moduix-color-primary))
);
color: var(
--moduix-badge-color,
var(--moduix-badge-ghost-color-hover, var(--moduix-color-primary))
);
}
&[data-variant='link']:hover {
text-decoration-color: currentColor;
}
}
& > svg {
width: var(--moduix-badge-icon-size, var(--moduix-spacing-3));
height: var(--moduix-badge-icon-size, var(--moduix-spacing-3));
flex-shrink: 0;
pointer-events: none;
}
&[data-variant='secondary'] {
border-color: var(
--moduix-badge-border-color,
var(--moduix-badge-secondary-border-color, transparent)
);
background-color: var(
--moduix-badge-bg,
var(--moduix-badge-secondary-bg, var(--moduix-color-secondary))
);
color: var(
--moduix-badge-color,
var(--moduix-badge-secondary-color, var(--moduix-color-secondary-foreground))
);
}
&[data-variant='destructive'] {
border-color: var(
--moduix-badge-border-color,
var(--moduix-badge-destructive-border-color, transparent)
);
background-color: var(
--moduix-badge-bg,
var(--moduix-badge-destructive-bg, var(--moduix-color-destructive))
);
color: var(
--moduix-badge-color,
var(--moduix-badge-destructive-color, var(--moduix-color-destructive-foreground))
);
}
&[data-variant='outline'] {
border-color: var(
--moduix-badge-border-color,
var(--moduix-badge-outline-border-color, var(--moduix-color-border))
);
background-color: var(--moduix-badge-bg, var(--moduix-badge-outline-bg, transparent));
color: var(
--moduix-badge-color,
var(--moduix-badge-outline-color, var(--moduix-color-foreground))
);
}
&[data-variant='ghost'] {
border-color: var(
--moduix-badge-border-color,
var(--moduix-badge-ghost-border-color, transparent)
);
background-color: var(--moduix-badge-bg, var(--moduix-badge-ghost-bg, transparent));
color: var(
--moduix-badge-color,
var(--moduix-badge-ghost-color, var(--moduix-color-foreground))
);
}
&[data-variant='link'] {
min-height: auto;
border-radius: 0;
padding-block: 0.125em;
padding-inline: 0;
border-color: var(
--moduix-badge-border-color,
var(--moduix-badge-link-border-color, transparent)
);
background-color: var(--moduix-badge-bg, var(--moduix-badge-link-bg, transparent));
color: var(--moduix-badge-color, var(--moduix-badge-link-color, var(--moduix-color-primary)));
text-decoration: underline;
text-decoration-color: color-mix(in oklab, currentColor 55%, transparent);
text-underline-offset: var(--moduix-badge-link-underline-offset, 0.15em);
text-decoration-thickness: from-font;
}
}
.dot {
width: var(--moduix-badge-dot-size, var(--moduix-spacing-1-5));
height: var(--moduix-badge-dot-size, var(--moduix-spacing-1-5));
flex-shrink: 0;
border-radius: 50%;
background-color: currentColor;
}
.label {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
}
}src/components/badge/index.ts
export * from './Badge.js';