neobrutalism
components
ui

button

A clickable button element with various styles and sizes in neobrutalism design.

button
brutalist
interactive
action
control
View Docs

Source Code

Files
button.tsx
1"use client";
2
3import { Slot } from "@radix-ui/react-slot";
4import { type VariantProps, cva } from "class-variance-authority";
5import * as React from "react";
6
7// Utility function for class name merging
8const cn = (...classes: any[]) => classes.filter(Boolean).join(" ");
9
10const buttonVariants = cva(
11  "inline-flex items-center justify-center whitespace-nowrap rounded-base text-sm font-base ring-offset-white transition-all gap-2 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-black focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
12  {
13    variants: {
14      variant: {
15        default:
16          "text-mtext bg-main border-2 border-border shadow-shadow hover:translate-x-boxShadowX hover:translate-y-boxShadowY hover:shadow-none",
17        noShadow: "text-mtext bg-main border-2 border-border",
18        neutral:
19          "bg-bw text-text border-2 border-border shadow-shadow hover:translate-x-boxShadowX hover:translate-y-boxShadowY hover:shadow-none",
20        reverse:
21          "text-mtext bg-main border-2 border-border hover:translate-x-reverseBoxShadowX hover:translate-y-reverseBoxShadowY hover:shadow-shadow",
22      },
23      size: {
24        default: "h-10 px-4 py-2",
25        sm: "h-9 px-3",
26        lg: "h-11 px-8",
27        icon: "h-10 w-10",
28      },
29    },
30    defaultVariants: {
31      variant: "default",
32      size: "default",
33    },
34  }
35);
36
37export interface ButtonProps
38  extends React.ButtonHTMLAttributes<HTMLButtonElement>,
39    VariantProps<typeof buttonVariants> {
40  asChild?: boolean;
41}
42
43const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
44  ({ className, variant, size, asChild = false, ...props }, ref) => {
45    const Comp = asChild ? Slot : "button";
46    return (
47      <Comp
48        className={cn(buttonVariants({ variant, size, className }))}
49        ref={ref}
50        {...props}
51      />
52    );
53  }
54);
55Button.displayName = "Button";
56
57export { Button, buttonVariants };
58