Button
The primary action surface — solid, ghost and inverse, with a loading state and an arrow that leans into the hover.
Live — this one is real
Usage
import { Button, ButtonLink } from "mizu-ui";
export function Actions() {
return (
<div
style={{
display: "flex",
flexWrap: "wrap",
gap: 12,
alignItems: "center",
}}
>
<Button variant="solid">Continue</Button>
<Button variant="ghost" size="sm">
Cancel
</Button>
<Button loading>Saving</Button>
<ButtonLink href="/next">Next page</ButtonLink>
</div>
);
}
Source & setup
Add this component to your project with the shadcn CLI. The command copies its source into your configured UI directory, with base.css, Mizu’s tokens, and the stylesheets that hold its rules. Each rule lives in one stylesheet, so components you add together never repeat CSS. In a project without a components.json, run npx shadcn@latest init 0xuser64bit/mizu/preset first: plain init installs shadcn’s theme into your global CSS. Then load the fonts.
npx shadcn@latest add 0xuser64bit/mizu/buttonEvery component imports from its own path, its name in kebab case. To paste the example, replace its mizu-ui import with:
import { Button, ButtonLink } from "@/components/ui/mizu/button";For npm imports, import mizu-ui/styles.css once. Fonts are optional via mizu-ui/fonts.css. Override --mizu-* tokens or use className for local styling. Uses native React and CSS; install the package peers for root imports. A Client Component: its source starts with “use client”.
Inspect ui/Button.tsx
Source is included in the npm package under src/ui/Button.tsx.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "solid" | "ghost" | "inverse" | "solid" | Surface treatment. Inverse is for use on accent fills. |
| size | "md" | "sm" | "md" | Padding and type scale. |
| loading | boolean | false | Preserves the action label, adds a diamond spinner and disables the button. |
| arrow | boolean | true | Show the corner arrow that translates on hover. |
| label | string | — | ButtonLink only — sets aria-label. Use it only when the link has no text of its own; a label that differs from the visible text hides that text from speech input and screen readers. |
Accessibility
Renders a real <button> / <a>. Disabled states use the disabled attribute; loading is conveyed through role=status on the spinner.
Motion
Arrow translates 2px on hover with expo easing. Loading retains the label and replaces the arrow.