Ballmac UI home

Button

A button with six variants, three sizes, a pill shape and a built-in loading state. buttonVariants() styles links the same way.

7/7 checksv1.0.4Updated Oct 12, 2026Ships with a test
What changed
  1. 1.0.4 Oct 12, 2026Every size honours the platform feel's smallest touch target (--bm-target-min): 44 px under the iOS feel, no change otherwise.
  2. 1.0.3 Oct 12, 2026A loading button keeps its label in the accessibility tree (opacity instead of visibility), so a busy button still has a name.
  3. 1.0.2 Oct 11, 2026Control heights, menu and sidebar row sizes, press dimming and frosted surfaces follow the platform feel tokens (--bm-control-h, --bm-menu-*, --bm-sidebar-*, --bm-material-*). Unchanged without a feel.
  4. 1.0.1 Oct 11, 2026Hover lift and press depth follow the theme's --bm-lift and --bm-hover tokens. Unchanged by default.
  5. 1.0.0 Sep 28, 2026First release.

Update without losing your edits

Installation

The default, and what a Radix-style project installs.

$ pnpm dlx shadcn@latest add @ballmac/button

Usage

import { Button } from "@/components/ballmac/button"

The full example is in the Code tab above.

Examples

Variants

Loading

API reference

PropTypeDefault
asChild

Render the child element (for example a link) with button styles.

booleanfalse
loading

Shows a spinner, sets aria-busy and blocks clicks.

booleanfalse
variant"default" | "secondary" | "outline" | "ghost" | "link" | "destructive""default"
size"sm" | "default" | "lg" | "icon" | "icon-sm""default"
shape"default" | "pill""default"

Also accepts the standard attributes of its root element.

Accessibility

KeyAction
Enter / SpaceActivates the button
TabMoves focus to the button

Quality scorecard

7/7

Every applicable check passes

Measured in Chromium 153.0.8010.12 on October 19, 2026, on version 1.0.4, across 3 examples.

How we measure
  • Passed: Accessibility scan

    No serious or critical issues in light and dark, on a phone and a desktop (axe-core 4.13.0, WCAG 2.1 AA and best-practice rules).

  • Passed: Small screens

    No sideways scrolling at 360, 390 or 1280 px wide.

  • Passed: Reduced motion

    No endless animation to begin with.

  • Passed: Right to left

    Mirrors correctly in Arabic, Hebrew, Persian and Urdu layouts (0% of elements off the mirror, limit 15%).

  • Passed: Clean console

    No console errors or React hydration errors while loading.

  • Passed: Keyboard

    9 tab stops, each showing a visible change when it takes focus. 2 documented keys.

  • Not applicable: Loading, empty and error

    Does not show data or take submissions.

  • Passed: Automated tests

    Covered by button.test.tsx.

  • For information: Footprint

    1.6 KB of source (gzip) in 1 file. Installs radix-ui, class-variance-authority.

Automated checks find a subset of problems and do not replace testing with a screen reader and a keyboard in your own app. What they miss.

Use with AI

The base action control. Use variant for emphasis, size for density, and loading while an async action runs. With the shadcn MCP server set up (guide), ask your agent:

Add the Ballmac UI Button (@ballmac/button) to this project with the shadcn MCP, then use it where it fits.

Use it for

  • Primary and secondary actions
  • Form submit buttons
  • Links that should look like buttons (className={buttonVariants()} on an <a>)

Not for

  • Navigation inside running text (use a link)
  • Toggling state (use a switch or toggle)

Registry JSON: https://ui.ballmac.com/r/button.json

Credits

Based on shadcn/ui Button, adapted by Ballmac. Free to use in personal and commercial projects.

Registry
shadcn/utils

Ballmac UI Pro

Need the whole screen, not one piece?

311 premium blocks (dashboards, settings, calendars, mail, shops, onboarding), a private shadcn registry and Figma tokens. Blocks that show data come with loading, empty and error states built in.

Not ready? Try three Pro blocks free

Leave your email and the blocks appear right here, ready to copy. Yours to use in any project.