@@ -0,0 +1,45 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import Icon from '@/components/site/icon';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
const tones = {
|
||||
neutral:
|
||||
'border-outline-variant/60 bg-surface-container-high text-on-surface-variant',
|
||||
brand: 'border-primary/40 bg-primary-container/10 text-primary dark:bg-primary-container/25 dark:text-highlight',
|
||||
} as const;
|
||||
|
||||
type PillProps = {
|
||||
tone?: keyof typeof tones;
|
||||
icon?: string;
|
||||
/** Show a pulsing status dot instead of an icon. */
|
||||
pulse?: boolean;
|
||||
className?: string;
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
export default function Pill({
|
||||
tone = 'neutral',
|
||||
icon,
|
||||
pulse = false,
|
||||
className,
|
||||
children,
|
||||
}: PillProps) {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'inline-flex items-center gap-2 self-start rounded-full border px-3.5 py-1.5 font-mono text-xs font-semibold',
|
||||
tones[tone],
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{pulse && (
|
||||
<span className="relative flex h-2.5 w-2.5">
|
||||
<span className="bg-primary absolute inline-flex h-full w-full animate-ping rounded-full opacity-75" />
|
||||
<span className="bg-primary relative inline-flex h-2.5 w-2.5 rounded-full" />
|
||||
</span>
|
||||
)}
|
||||
{icon && <Icon name={icon} className="text-primary text-base" />}
|
||||
<span>{children}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user