-

Button

PreviousNext

Action buttons for ZGI agent consoles, workflow builders, forms, and destructive operations.

Installation

pnpm
pnpm dlx shadcn@latest add https://ui.zgi.ai/r/button.json
npm
pnpm dlx shadcn@latest add https://ui.zgi.ai/r/button.json
yarn
yarn dlx shadcn@latest add https://ui.zgi.ai/r/button.json

Component

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 "@/lib/utils"

const buttonVariants = cva(
  "inline-flex items-center justify-center gap-1.5 whitespace-nowrap rounded-[4px] text-sm font-medium transition-colors disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[2px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground hover:bg-primary/90",
        destructive:
          "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
        outline:
          "border bg-background hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
        secondary:
          "bg-secondary text-secondary-foreground hover:bg-secondary/80",
        soft: "bg-primary/10 text-primary hover:bg-primary/15",
        ghost:
          "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
        link: "text-primary underline-offset-4 hover:underline",
      },
      size: {
        default: "h-8 px-3.5 has-[>svg]:px-3",
        sm: "h-7 px-2.5 text-xs has-[>svg]:px-2",
        lg: "h-9 px-4 has-[>svg]:px-3.5",
        icon: "size-8",
      },
    },
    defaultVariants: {
      variant: "default",
      size: "default",
    },
  }
)

function Button({
  className,
  variant,
  size,
  asChild = false,
  ...props
}: React.ComponentProps<"button"> &
  VariantProps<typeof buttonVariants> & {
    asChild?: boolean
  }) {
  const Comp = asChild ? Slot : "button"

  return (
    <Comp
      data-slot="button"
      className={cn(buttonVariants({ variant, size, className }))}
      {...props}
    />
  )
}

export { Button, buttonVariants }

Usage

import { Button } from "@/components/ui/button"
export function Example() {
  return (
    <Button>
      Deploy agent
    </Button>
  )
}

Variants

Use default for the primary action in a surface. Use secondary and outline for supporting actions. Use ghost for low-emphasis toolbar actions, link for inline navigation, and destructive only for irreversible operations.

<Button>Deploy</Button>
<Button variant="secondary">Configure</Button>
<Button variant="outline">Copy API key</Button>
<Button variant="soft">Run agent</Button>
<Button variant="ghost">View logs</Button>
<Button variant="destructive">Revoke key</Button>

Design Guidelines

ZGI buttons use a restrained console style: 4px radius, compact height, clear hierarchy, and one primary action per surface. Keep buttons operational rather than decorative.

Radius

Use 4px for all button sizes. This keeps actions crisp and stable inside agent consoles, tables, sidebars, and dense workflow panels.

Sizing

SizeHeightUsage
sm28pxDense tables, inline rows, compact sidebars.
default32pxStandard console actions.
lg36pxPrimary action in an empty state or setup flow.
icon32pxToolbar actions and compact command groups.

Colors

VariantUsage
defaultPrimary ZGI Blue action, such as deploy, run, save, or confirm.
secondaryNeutral supporting action inside the same panel.
outlineUtility actions such as copy, rotate, sync, or configure.
softLow-intensity ZGI Blue action for hints, empty states, and secondary agent actions.
ghostToolbar and inline panel actions with low emphasis.
destructiveRevoke, delete, disconnect, or irreversible operations.
linkText-level navigation, never the main action.

Hierarchy

Use only one default button in a local decision area. Put secondary actions to the right or after it, and keep destructive actions visually separated when possible.

Props

PropTypeDefault
variant"default" | "destructive" | "outline" | "secondary" | "soft" | "ghost" | "link""default"
size"default" | "sm" | "lg" | "icon""default"
asChildbooleanfalse