84 lines
1.9 KiB
Svelte
84 lines
1.9 KiB
Svelte
<!--
|
|
Component: Badge
|
|
Pill badge with border and optional status dot.
|
|
-->
|
|
<script lang="ts">
|
|
import { cn } from '$shared/shadcn/utils/shadcn-utils';
|
|
import {
|
|
type LabelSize,
|
|
labelSizeConfig,
|
|
} from '$shared/ui/Label/config';
|
|
import type { Snippet } from 'svelte';
|
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
|
|
type BadgeVariant = 'default' | 'accent' | 'success' | 'warning' | 'info';
|
|
|
|
const badgeVariantConfig: Record<BadgeVariant, string> = {
|
|
default: 'border-black/10 dark:border-white/10 text-neutral-500',
|
|
accent: 'bg-brand/10 border-brand/20 text-brand',
|
|
success: 'bg-green-500/10 border-green-500/20 text-green-600 dark:text-green-400',
|
|
warning: 'bg-yellow-500/10 border-yellow-500/20 text-yellow-600 dark:text-yellow-400',
|
|
info: 'bg-blue-500/10 border-blue-500/20 text-blue-600 dark:text-blue-400',
|
|
};
|
|
|
|
interface Props extends HTMLAttributes<HTMLSpanElement> {
|
|
/**
|
|
* Visual variant
|
|
* @default 'default'
|
|
*/
|
|
variant?: BadgeVariant;
|
|
/**
|
|
* Badge size
|
|
* @default 'xs'
|
|
*/
|
|
size?: LabelSize;
|
|
/**
|
|
* Show status dot
|
|
* @default false
|
|
*/
|
|
dot?: boolean;
|
|
/**
|
|
* Prevent text wrapping
|
|
* @default false
|
|
*/
|
|
nowrap?: boolean;
|
|
/**
|
|
* Content snippet
|
|
*/
|
|
children?: Snippet;
|
|
/**
|
|
* CSS classes
|
|
*/
|
|
class?: string;
|
|
}
|
|
|
|
let {
|
|
variant = 'default',
|
|
size = 'xs',
|
|
dot = false,
|
|
nowrap = false,
|
|
children,
|
|
class: className,
|
|
...rest
|
|
}: Props = $props();
|
|
</script>
|
|
|
|
<span
|
|
class={cn(
|
|
'inline-flex items-center gap-1 px-2 py-0.5 border rounded-full',
|
|
'font-mono uppercase tracking-wide',
|
|
labelSizeConfig[size],
|
|
badgeVariantConfig[variant],
|
|
nowrap && 'text-nowrap',
|
|
className,
|
|
)}
|
|
{...rest}
|
|
>
|
|
{#if dot}
|
|
<span class="w-1 h-1 rounded-full bg-current"></span>
|
|
{/if}
|
|
{#if children}
|
|
{@render children()}
|
|
{/if}
|
|
</span>
|