KKiotaPay UI
Browse documentation

Button

An action button in three variants. Give it an href and it becomes a link, styled identically.

Installation

pnpm dlx shadcn@latest add https://kiotapay-ui-staging.staging.kiotapay.com/r/button.json

Installs components/custom/button.tsx. This is separate from the shadcn button primitive, which stays available at @/components/ui/button for anywhere you need its full variant and size range.

Usage

import { Button } from '@/components/custom/button'

export function PayoutActions() {
  return (
    <div className="flex gap-2">
      <Button onClick={approve}>Approve</Button>
      <Button variant="danger" onClick={reverse}>
        Reverse
      </Button>
      <Button href="/payouts" variant="outline">
        Back to payouts
      </Button>
    </div>
  )
}

Props

Extends React.ComponentProps<'button'>.

PropTypeDefaultDescription
variant'primary' | 'outline' | 'danger''primary'Visual weight.
hrefstring—Renders a next/link anchor instead of a button.
replaceboolean—Replace the history entry instead of pushing. Link only.
scrollboolean—Scroll to the top after navigating. Link only.
prefetchboolean | null—Prefetch behaviour. Link only.
targetstring—'_blank' also sets rel="noopener noreferrer".

href and disabled together render a real disabled <button>, because an anchor cannot be disabled — removing its href to fake it also removes it from the tab order without telling anyone why.

Behaviour notes

A link is one element, not two. With href, the anchor itself carries the button styling. Wrapping a <button> inside an <a> is invalid HTML, and browsers recover from it by hoisting the button out of the anchor — the result looks right and loses the keyboard activation and accessible role the markup appeared to have.

No implicit type. The type attribute is passed through untouched, so a button inside a form still submits it. Pass type="button" on anything that should not.

App Router only for the link props. as, shallow and passHref are Pages Router APIs and are not accepted — they were silently inert in App Router projects.