avertra-ui
uibuttonsource: ok · hit
Button
A reusable button component.
npx shadcn add "https://micomponents.micustomer.io/r/button.json"free
No selection tags yet — empty means no evidence, not lack of support.
Files1 · source cached 10/9/2026, 11:05:30 PM
src/components/ui/button.tsx
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/stories/lib/utils";
const buttonVariants = cva(
"p-3 rounded-sm inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium transition-all disabled:pointer-events-none disabled:bg-[#F3F4F5] disabled:text-[#A6ADB5] disabled:border-0 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive rounded-sm w-full sm:w-auto",
{
variants: {
variant: {
primary:
"bg-primary text-primary-foreground hover:bg-primary/90 focus:outline-3 focus:outline-offset-0 focus:outline-secondary",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/90 focus:outline-3 focus:outline-offset-0 focus:outline-primary",
tertiary:
"bg-tertiary text-tertiary-foreground hover:bg-tertiary/90 focus:outline-3 focus:outline-offset-0 focus:outline-secondary",
accent1:
"bg-accent1 text-accent1-foreground hover:bg-accent1/90 focus:outline-3 focus:outline-offset-0 focus:outline-secondary",
accent2:
"bg-accent2 text-accent2-foreground hover:bg-accent2/90 focus:outline-3 focus:outline-offset-0 focus:outline-secondary",
success:
"bg-success text-success-foreground hover:bg-success/90 focus:outline-3 focus:outline-offset-0 focus:outline-secondary",
warning:
"bg-warning text-warning-foreground hover:bg-warning/90 focus:outline-3 focus:outline-offset-0 focus:outline-secondary",
error:
"bg-error text-error-foreground hover:bg-error/90 focus:outline-3 focus:outline-offset-0 focus:outline-secondary",
white:
"bg-white text-black hover:bg-gray-200 focus:outline-3 focus:outline-offset-0 focus:outline-secondary",
black:
"bg-black text-white hover:bg-gray-900 focus:outline-3 focus:outline-offset-0 focus:outline-secondary",
},
size: {
micro: "h-6",
xs: "h-7 ",
sm: "h-9 ",
md: "h-11 ",
lg: "h-12 ",
xl: "h-14 ",
},
stylebtn: {
filled: "",
outlined: "bg-transparent border bg-transparent hover:bg-transparent",
text: "bg-transparent border-0 hover:underline hover:bg-transparent",
},
},
compoundVariants: [
{
stylebtn: "outlined",
variant: "primary",
className:
"text-primary border-primary hover:border-primary/80 hover:text-primary/80",
},
{
stylebtn: "outlined",
variant: "secondary",
className:
"text-secondary border-secondary hover:border-secondary/80 hover:text-secondary/80",
},
{
stylebtn: "outlined",
variant: "tertiary",
className:
"text-tertiary border-tertiary hover:border-tertiary/80 hover:text-tertiary/80",
},
{
stylebtn: "outlined",
variant: "accent1",
className:
"text-accent1 border-accent1 hover:border-accent1/80 hover:text-accent1/80",
},
{
stylebtn: "outlined",
variant: "accent2",
className:
"text-accent2 border-accent2 hover:border-accent2/80 hover:text-accent2/80",
},
{
stylebtn: "outlined",
variant: "success",
className:
"text-success border-success hover:border--success/80 hover:text-success/80",
},
{
stylebtn: "outlined",
variant: "warning",
className:
"text-warning border-warning hover:border-warning/80 hover:text-warning/80",
},
{
stylebtn: "outlined",
variant: "error",
className:
"text-error border-error hover:border-error/80 hover:text-error/80",
},
{
stylebtn: "outlined",
variant: "white",
className:
"text-white border-white hover:border-gray-200/80 hover:text-gray-200/80",
},
{
stylebtn: "outlined",
variant: "black",
className:
"text-black border-black hover:border-gray-900/50 hover:text-gray-900/50",
},
{
stylebtn: "text",
variant: "primary",
className: "text-primary hover:text-primary/80 ",
},
{
stylebtn: "text",
variant: "secondary",
className: "text-secondary hover:text-secondary/80",
},
{
stylebtn: "text",
variant: "tertiary",
className: "text-tertiary hover:text-tertiary/80",
},
{
stylebtn: "text",
variant: "accent1",
className: "text-accent1 hover:text-accent1/80",
},
{
stylebtn: "text",
variant: "accent2",
className: "text-accent2 hover:text-accent2/80",
},
{
stylebtn: "text",
variant: "success",
className: "text-success hover:text-success/80",
},
{
stylebtn: "text",
variant: "warning",
className: "text-warning hover:text-warning/80",
},
{
stylebtn: "text",
variant: "error",
className: "text-error hover:text-error/80",
},
{
stylebtn: "text",
variant: "white",
className: "text-white hover:text-gray-200/80",
},
{
stylebtn: "text",
variant: "black",
className: "text-black hover:text-gray-900/50",
},
],
defaultVariants: {
variant: "primary",
size: "md",
stylebtn: "filled",
},
},
);
interface ButtonProps
extends
React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
iconBefore?: React.ReactNode;
iconAfter?: React.ReactNode;
label?: string;
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
(
{
className,
variant,
size,
stylebtn,
asChild = false,
iconBefore,
iconAfter,
children,
label,
...props
},
ref,
) => {
const Comp = asChild ? Slot : "button";
return (
<Comp
ref={ref}
data-slot="button"
className={cn(buttonVariants({ stylebtn, size, variant, className }))}
{...props}
>
{iconBefore && <span className="flex items-center">{iconBefore}</span>}
{children}
{label}
{iconAfter && <span className="flex items-center">{iconAfter}</span>}
</Comp>
);
},
);
Button.displayName = "Button";
export { Button, buttonVariants };