import type { VariantProps } from "class-variance-authority"
import { PlusIcon } from "lucide-react"
import { Button as Button3D } from "@/components/ui/buttons/button-3d"
import { Button as ButtonBold } from "@/components/ui/buttons/button-bold"
import { Button as ButtonBoldSkewed } from "@/components/ui/buttons/button-bold-skewed"
import { Button as ButtonClipped } from "@/components/ui/buttons/button-clipped"
import {
Button as ButtonDefault,
buttonVariants,
} from "@/components/ui/buttons/button-default"
import { Button as ButtonGradient } from "@/components/ui/buttons/button-gradient"
import { Button as ButtonShadow } from "@/components/ui/buttons/button-shadow"
import { Button as ButtonStrongOutline } from "@/components/ui/buttons/button-strong-outline"
type ButtonVariant = NonNullable<VariantProps<typeof buttonVariants>["variant"]>
type ButtonSize = NonNullable<VariantProps<typeof buttonVariants>["size"]>
const BUTTON_STYLES = [
{ label: "Default", Button: ButtonDefault, source: "button-default.tsx" },
{ label: "Bold", Button: ButtonBold, source: "button-bold.tsx" },
{ label: "3D", Button: Button3D, source: "button-3d.tsx" },
{ label: "Gradient", Button: ButtonGradient, source: "button-gradient.tsx" },
{ label: "Shadow", Button: ButtonShadow, source: "button-shadow.tsx" },
{ label: "Clipped", Button: ButtonClipped, source: "button-clipped.tsx" },
{
label: "Strong Outline",
Button: ButtonStrongOutline,
source: "button-strong-outline.tsx",
},
{
label: "Bold Skewed",
Button: ButtonBoldSkewed,
source: "button-bold-skewed.tsx",
},
] as const
const VARIANTS = [
"default",
"outline",
"secondary",
"destructive",
"ghost",
"link",
] as const satisfies readonly ButtonVariant[]
const SIZES = [
{ label: "default", size: "default" },
{ label: "xs", size: "xs" },
{ label: "sm", size: "sm" },
{ label: "lg", size: "lg" },
{ label: "icon", size: "icon", iconOnly: true },
{ label: "icon-xs", size: "icon-xs", iconOnly: true },
{ label: "icon-sm", size: "icon-sm", iconOnly: true },
{ label: "icon-lg", size: "icon-lg", iconOnly: true },
] as const satisfies readonly {
label: string
size: ButtonSize
iconOnly?: boolean
}[]
export function ButtonShowcase() {
return (
<section
className="bg-background"
aria-labelledby="button-showcase-heading"
>
<div className="wrapper py-16 sm:py-24">
<div className="tagline">Buttons</div>
<h1 id="button-showcase-heading" className="heading-lg mb-3">
Button styles
</h1>
<p className="paragraph mb-14 max-w-2xl">
Standalone button files paired with each color and size variant. Ghost
and link variants stay flat across elevated styles.
</p>
<div className="flex flex-col gap-16">
{BUTTON_STYLES.map(({ label: styleLabel, Button, source }) => (
<div key={source}>
<h2 className="heading-sm mb-2">{styleLabel}</h2>
<p className="paragraph-sm mb-6 font-mono text-xs">{source}</p>
<div className="flex flex-col gap-8">
<div>
<h3 className="font-mono text-xs text-muted-foreground uppercase">
Variants
</h3>
<div className="mt-3 flex flex-wrap gap-8">
{VARIANTS.map((variant) => (
<div
key={variant}
className="flex min-w-[7.5rem] flex-col items-center gap-3"
>
<Button variant={variant}>Button</Button>
<span className="font-mono text-xs text-muted-foreground">
{variant}
</span>
</div>
))}
</div>
</div>
<div>
<h3 className="font-mono text-xs text-muted-foreground uppercase">
Sizes
</h3>
<div className="mt-3 flex flex-wrap items-end gap-8">
{SIZES.map((sizeConfig) => {
const { label, size } = sizeConfig
const iconOnly =
"iconOnly" in sizeConfig && sizeConfig.iconOnly
return (
<div
key={size}
className="flex min-w-[7.5rem] flex-col items-center gap-3"
>
<Button
size={size}
aria-label={
iconOnly
? `${styleLabel} ${label} button size`
: undefined
}
>
{iconOnly ? <PlusIcon aria-hidden /> : "Button"}
</Button>
<span className="font-mono text-xs text-muted-foreground">
{label}
</span>
</div>
)
})}
</div>
</div>
</div>
</div>
))}
</div>
</div>
</section>
)
}