CRATE // NEXTUI

Button

Kraft-paper button with primary, secondary, ghost, and accent variants in three sizes. Archivo Black labels, warm cardboard palette. Renders as a Next.js Link when an href is provided.

$npx @voltenworks/shipui add button --theme crate
Or install the base component for free:
Live Preview
Open full demo
voltenworks.com/shipui/crate/demo/components#01-button
Usage
TSX
<Button variant="primary" size="md">Start your subscription</Button>
Variants
<Button variant="primary">Start your subscription</Button>
<Button variant="secondary">Learn more</Button>
<Button variant="ghost">Cancel</Button>
<Button variant="accent">Order now</Button>
<Button variant="primary" size="sm">Add to box</Button>
<Button variant="primary" size="lg">Subscribe</Button>
Source
TSX
import Link from 'next/link'
import { cn } from '@/lib/utils'

type Variant = 'primary' | 'secondary' | 'ghost' | 'accent'
type Size    = 'sm' | 'md' | 'lg'

interface ButtonBase {
  variant?:   Variant
  size?:      Size
  className?: string
  children:   React.ReactNode
}

interface ButtonAsButton extends ButtonBase {
  href?: undefined
  onClick?: () => void
  type?: 'button' | 'submit'
}

interface ButtonAsLink extends ButtonBase {
  href: string
  onClick?: undefined
  type?: undefined
}

type ButtonProps = ButtonAsButton | ButtonAsLink

const variantClass: Record<Variant, string> = {
  primary:   'btn-primary',
  secondary: 'btn-secondary',
  ghost:     'btn-ghost',
  accent:    'btn-accent',
}

const sizeClass: Record<Size, string> = {
  sm: 'btn-sm',
  md: 'btn-md',
  lg: 'btn-lg',
}

export function Button({
  variant = 'primary',
  size = 'md',
  className,
  children,
  ...rest
}: ButtonProps): React.JSX.Element {
  const classes = cn(variantClass[variant], sizeClass[size], className)

  if ('href' in rest && rest.href) {
    return (
      <Link href={rest.href} className={classes}>
        {children}
      </Link>
    )
  }

  const { onClick, type } = rest as ButtonAsButton
  return (
    <button type={type ?? 'button'} onClick={onClick} className={classes}>
      {children}
    </button>
  )
}
Preview in theme demoGet full theme, $29
Works withNext.js 15React 19Tailwind v4TypeScript 5
More from CRATE // NEXT
CRATE // NEXTUI

Badge

Artisanal badge with accent, ink, kraft, stamp, and faded variants. Uppercase tracking on warm cardboard surfaces.

CRATE // NEXTUI

Text

Polymorphic text component with body, caption, label, and code variants. Archivo Black for display, DM Sans for body.

CRATE // NEXTUI

Card

Origin card with shipping label aesthetic, tape motif, dashed borders, and slight rotation transform. Displays weight, roast, origin, and date fields.