RETRO // NEXTUI

Button

Arcade-styled button with neon green, magenta, cyan, and yellow variants in three sizes. Renders as a Next.js Link when an href is provided.

$npx @voltenworks/shipui add button --theme retro
Or install the base component for free:
Live Preview
Open full demo
voltenworks.com/shipui/retro/demo/components#01-button
Usage
TSX
<Button variant="primary" size="lg">INSERT COIN</Button>
Variants
<Button variant="primary">INSERT COIN</Button>
<Button variant="secondary">HIGH SCORES</Button>
<Button variant="ghost">SETTINGS</Button>
<Button variant="primary" size="sm">START</Button>
<Button variant="primary" size="lg">PLAY NOW</Button>
Source
TSX
import Link from 'next/link'
import { cn } from '@/lib/utils'

interface ButtonBaseProps {
  variant?:   'primary' | 'secondary' | 'ghost'
  size?:      'sm' | 'md' | 'lg'
  className?: string
  children:   React.ReactNode
}

type ButtonAsButton = ButtonBaseProps &
  Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, keyof ButtonBaseProps> & {
    href?: never
  }

type ButtonAsLink = ButtonBaseProps & {
  href: string
}

type ButtonProps = ButtonAsButton | ButtonAsLink

const SIZE_CLASSES: Record<NonNullable<ButtonBaseProps['size']>, string> = {
  sm: 'btn-sm',
  md: 'btn-md',
  lg: 'btn-lg',
}

const VARIANT_CLASSES: Record<NonNullable<ButtonBaseProps['variant']>, string> = {
  primary:   'btn-primary',
  secondary: 'btn-secondary',
  ghost:     'btn-ghost',
}

export function Button({
  children,
  variant = 'primary',
  size    = 'md',
  className,
  ...props
}: ButtonProps): React.JSX.Element {
  const classes = cn('btn-base', SIZE_CLASSES[size], VARIANT_CLASSES[variant], className)

  if ('href' in props && props.href !== undefined) {
    const { href, ...linkProps } = props
    return (
      <Link href={href} className={classes} {...linkProps}>
        {children}
      </Link>
    )
  }

  const { type = 'button', ...buttonProps } = props as React.ButtonHTMLAttributes<HTMLButtonElement>
  return (
    <button type={type} className={classes} {...buttonProps}>
      {children}
    </button>
  )
}
Preview in theme demoGet full theme, $29
Works withNext.js 15React 19Tailwind v4TypeScript 5
More from RETRO // NEXT
RETRO // NEXTUI

Badge

Neon-glow badge with magenta, cyan, yellow, and green color variants. Used for category tags and status labels in the arcade aesthetic.

RETRO // NEXTUI

Card

Game-card component with neon-colored icon, tag, title, description, and a five-star rating display. Supports a "coming soon" locked overlay state.

RETRO // NEXTUI

PixelCharacter

SVG pixel-art sprite with three variants: hero (neon green), ghost (magenta), and coin (yellow). Supports a CSS float animation and configurable size.

RETRO // NEXTUI

ScoreBoard

High-scores leaderboard that renders as a table on desktop and as stacked cards on mobile. Highlights ranks 1-3 with distinct neon color classes.

RETRO // NEXTUI

SectionHeader

Section heading block with a numbered label, a two-part heading where the last word is accented in neon, and an optional subtitle. Supports left or center alignment.

RETRO // NEXTUI

StatBlock

Single-stat display with a large pixel-font value in neon cyan and a label below. Wrapped in a pixel-border container for the arcade aesthetic.

RETRO // NEXTUI

Text

Polymorphic text primitive with body, caption, label, and code variants styled for the RETRO dark arcade palette.