163 lines
6.2 KiB
Plaintext
163 lines
6.2 KiB
Plaintext
---
|
|
import { Icon } from 'astro-icon/components'
|
|
import { tv, type VariantProps } from 'tailwind-variants'
|
|
|
|
import type { Polymorphic } from 'astro/types'
|
|
|
|
const badge = tv({
|
|
slots: {
|
|
base: 'inline-flex h-4 items-center justify-center gap-0.75 rounded-full px-1.25 text-[10px] font-medium',
|
|
icon: 'size-3 shrink-0',
|
|
text: 'mx-0.25 overflow-hidden text-ellipsis whitespace-nowrap',
|
|
},
|
|
variants: {
|
|
color: {
|
|
red: '',
|
|
orange: '',
|
|
amber: '',
|
|
yellow: '',
|
|
lime: '',
|
|
green: '',
|
|
emerald: '',
|
|
teal: '',
|
|
cyan: '',
|
|
sky: '',
|
|
blue: '',
|
|
indigo: '',
|
|
violet: '',
|
|
purple: '',
|
|
fuchsia: '',
|
|
pink: '',
|
|
rose: '',
|
|
slate: '',
|
|
gray: '',
|
|
zinc: '',
|
|
neutral: '',
|
|
stone: '',
|
|
white: '',
|
|
black: '',
|
|
},
|
|
variant: {
|
|
solid: '',
|
|
faded: '',
|
|
},
|
|
},
|
|
compoundVariants: [
|
|
// Red
|
|
{ color: 'red', variant: 'solid', class: { base: 'bg-red-500 text-white' } },
|
|
{ color: 'red', variant: 'faded', class: { base: 'bg-red-500/30 text-red-300' } },
|
|
// Orange
|
|
{ color: 'orange', variant: 'solid', class: { base: 'bg-orange-500 text-white' } },
|
|
{ color: 'orange', variant: 'faded', class: { base: 'bg-orange-500/30 text-orange-300' } },
|
|
// Amber
|
|
{ color: 'amber', variant: 'solid', class: { base: 'bg-amber-500 text-black' } },
|
|
{ color: 'amber', variant: 'faded', class: { base: 'bg-amber-500/30 text-amber-300' } },
|
|
// Yellow
|
|
{ color: 'yellow', variant: 'solid', class: { base: 'bg-yellow-500 text-black' } },
|
|
{ color: 'yellow', variant: 'faded', class: { base: 'bg-yellow-500/30 text-yellow-300' } },
|
|
// Lime
|
|
{ color: 'lime', variant: 'solid', class: { base: 'bg-lime-500 text-black' } },
|
|
{ color: 'lime', variant: 'faded', class: { base: 'bg-lime-500/30 text-lime-300' } },
|
|
// Green
|
|
{ color: 'green', variant: 'solid', class: { base: 'bg-green-500 text-black' } },
|
|
{ color: 'green', variant: 'faded', class: { base: 'bg-green-500/30 text-green-300' } },
|
|
// Emerald
|
|
{ color: 'emerald', variant: 'solid', class: { base: 'bg-emerald-500 text-white' } },
|
|
{ color: 'emerald', variant: 'faded', class: { base: 'bg-emerald-500/30 text-emerald-300' } },
|
|
// Teal
|
|
{ color: 'teal', variant: 'solid', class: { base: 'bg-teal-500 text-white' } },
|
|
{ color: 'teal', variant: 'faded', class: { base: 'bg-teal-500/30 text-teal-300' } },
|
|
// Cyan
|
|
{ color: 'cyan', variant: 'solid', class: { base: 'bg-cyan-500 text-white' } },
|
|
{ color: 'cyan', variant: 'faded', class: { base: 'bg-cyan-500/30 text-cyan-300' } },
|
|
// Sky
|
|
{ color: 'sky', variant: 'solid', class: { base: 'bg-sky-500 text-white' } },
|
|
{ color: 'sky', variant: 'faded', class: { base: 'bg-sky-500/30 text-sky-300' } },
|
|
// Blue
|
|
{ color: 'blue', variant: 'solid', class: { base: 'bg-blue-500 text-white' } },
|
|
{ color: 'blue', variant: 'faded', class: { base: 'bg-blue-500/30 text-blue-300' } },
|
|
// Indigo
|
|
{ color: 'indigo', variant: 'solid', class: { base: 'bg-indigo-500 text-white' } },
|
|
{ color: 'indigo', variant: 'faded', class: { base: 'bg-indigo-500/30 text-indigo-300' } },
|
|
// Violet
|
|
{ color: 'violet', variant: 'solid', class: { base: 'bg-violet-500 text-white' } },
|
|
{ color: 'violet', variant: 'faded', class: { base: 'bg-violet-500/30 text-violet-300' } },
|
|
// Purple
|
|
{ color: 'purple', variant: 'solid', class: { base: 'bg-purple-500 text-white' } },
|
|
{ color: 'purple', variant: 'faded', class: { base: 'bg-purple-500/30 text-purple-300' } },
|
|
// Fuchsia
|
|
{ color: 'fuchsia', variant: 'solid', class: { base: 'bg-fuchsia-500 text-white' } },
|
|
{ color: 'fuchsia', variant: 'faded', class: { base: 'bg-fuchsia-500/30 text-fuchsia-300' } },
|
|
// Pink
|
|
{ color: 'pink', variant: 'solid', class: { base: 'bg-pink-500 text-white' } },
|
|
{ color: 'pink', variant: 'faded', class: { base: 'bg-pink-500/30 text-pink-300' } },
|
|
// Rose
|
|
{ color: 'rose', variant: 'solid', class: { base: 'bg-rose-500 text-white' } },
|
|
{ color: 'rose', variant: 'faded', class: { base: 'bg-rose-500/30 text-rose-300' } },
|
|
// Slate
|
|
{ color: 'slate', variant: 'solid', class: { base: 'bg-slate-500 text-white' } },
|
|
{ color: 'slate', variant: 'faded', class: { base: 'bg-slate-500/30 text-slate-300' } },
|
|
// Gray
|
|
{ color: 'gray', variant: 'solid', class: { base: 'bg-gray-500 text-white' } },
|
|
{ color: 'gray', variant: 'faded', class: { base: 'bg-gray-500/30 text-gray-300' } },
|
|
// Zinc
|
|
{ color: 'zinc', variant: 'solid', class: { base: 'bg-zinc-500 text-white' } },
|
|
{ color: 'zinc', variant: 'faded', class: { base: 'bg-zinc-500/30 text-zinc-300' } },
|
|
// Neutral
|
|
{ color: 'neutral', variant: 'solid', class: { base: 'bg-neutral-500 text-white' } },
|
|
{ color: 'neutral', variant: 'faded', class: { base: 'bg-neutral-500/30 text-neutral-300' } },
|
|
// Stone
|
|
{ color: 'stone', variant: 'solid', class: { base: 'bg-stone-500 text-white' } },
|
|
{ color: 'stone', variant: 'faded', class: { base: 'bg-stone-500/30 text-stone-300' } },
|
|
// White
|
|
{ color: 'white', variant: 'solid', class: { base: 'bg-white text-black' } },
|
|
{ color: 'white', variant: 'faded', class: { base: 'bg-white-500/30 text-white-300' } },
|
|
// Black
|
|
{ color: 'black', variant: 'solid', class: { base: 'bg-black text-white' } },
|
|
{ color: 'black', variant: 'faded', class: { base: 'bg-black-500/30 text-black-300' } },
|
|
],
|
|
defaultVariants: {
|
|
color: 'gray',
|
|
variant: 'solid',
|
|
},
|
|
})
|
|
|
|
type Props<Tag extends 'a' | 'div' | 'li' = 'div'> = Polymorphic<
|
|
VariantProps<typeof badge> & {
|
|
as: Tag
|
|
icon?: string
|
|
text: string
|
|
inlineIcon?: boolean
|
|
classNames?: {
|
|
icon?: string
|
|
text?: string
|
|
}
|
|
}
|
|
>
|
|
|
|
const {
|
|
as: Tag = 'div',
|
|
icon: iconName,
|
|
text: textContent,
|
|
inlineIcon,
|
|
classNames,
|
|
|
|
color,
|
|
variant,
|
|
|
|
class: className,
|
|
...props
|
|
} = Astro.props
|
|
|
|
const { base, icon: iconSlot, text: textSlot } = badge({ color, variant })
|
|
---
|
|
|
|
<Tag {...props} class={base({ class: className })}>
|
|
{
|
|
!!iconName && (
|
|
<Icon name={iconName} class={iconSlot({ class: classNames?.icon })} is:inline={inlineIcon} />
|
|
)
|
|
}
|
|
<span class={textSlot({ class: classNames?.text })}>{textContent}</span>
|
|
</Tag>
|