mirror of
https://github.com/Since-3/since3-website.git
synced 2026-10-12 21:41:16 +00:00
72 lines
2.6 KiB
TypeScript
72 lines
2.6 KiB
TypeScript
import { Button as ButtonPrimitive } from "@base-ui/react/button"
|
|
import { cva, type VariantProps } from "class-variance-authority"
|
|
import { ArrowRight } from "lucide-react"
|
|
|
|
import { cn } from "@/lib/utils"
|
|
|
|
const buttonVariants = cva(
|
|
"group/button relative inline-flex shrink-0 items-center justify-center rounded-full border font-medium whitespace-nowrap transition-[background-color,border-color,color,scale] duration-200 ease-out select-none active:not-aria-[haspopup]:scale-[0.97] disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
{
|
|
variants: {
|
|
variant: {
|
|
// Black on light, white on dark
|
|
solid:
|
|
"border-transparent bg-fg text-bg hover:bg-ink-800 dark:hover:bg-ink-200",
|
|
// Hairline only
|
|
outline:
|
|
"border-fg/20 bg-transparent text-fg hover:border-fg/60 aria-expanded:border-fg/60",
|
|
// Only on top of glass surfaces or dark sections
|
|
glass:
|
|
"border-white/15 bg-white/10 text-white backdrop-blur-md hover:bg-white/20",
|
|
ghost: "border-transparent text-fg hover:bg-fg/5 aria-expanded:bg-fg/5",
|
|
link: "rounded-none border-transparent px-0 text-fg underline-offset-4 hover:underline",
|
|
},
|
|
size: {
|
|
default: "h-11 gap-2 px-5 text-[0.9375rem]",
|
|
sm: "h-9 gap-1.5 px-4 text-sm",
|
|
lg: "h-13 gap-2 px-7 text-base",
|
|
icon: "size-10",
|
|
"icon-sm": "size-8",
|
|
},
|
|
},
|
|
defaultVariants: {
|
|
variant: "solid",
|
|
size: "default",
|
|
},
|
|
}
|
|
)
|
|
|
|
function Button({
|
|
className,
|
|
variant = "solid",
|
|
size = "default",
|
|
...props
|
|
}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {
|
|
return (
|
|
<ButtonPrimitive
|
|
data-slot="button"
|
|
className={cn(buttonVariants({ variant, size, className }))}
|
|
{...props}
|
|
/>
|
|
)
|
|
}
|
|
|
|
/**
|
|
* The arrow is not part of the label: it appears on hover only.
|
|
* Place it as the last child of a button or a link styled with `buttonVariants`.
|
|
*/
|
|
function ButtonArrow({ className }: { className?: string }) {
|
|
return (
|
|
<span
|
|
aria-hidden="true"
|
|
className={cn(
|
|
"-ml-2 grid w-0 overflow-hidden opacity-0 transition-[width,margin,opacity] duration-200 ease-out group-hover/button:ml-0 group-hover/button:w-4 group-hover/button:opacity-100 group-focus-visible/button:ml-0 group-focus-visible/button:w-4 group-focus-visible/button:opacity-100",
|
|
className
|
|
)}
|
|
>
|
|
<ArrowRight className="size-4" />
|
|
</span>
|
|
)
|
|
}
|
|
|
|
export { Button, ButtonArrow, buttonVariants }
|