Button
A flexible button component with multiple variants, sizes, loading states, and CMS integration support.
Basic Usage
Loading...
Installation
pnpm add @corew500/uiUsage
import { Button } from "@corew500/ui/button"
<Button>Click me</Button>Variants
Six visual variants for different contexts and emphasis levels.
Loading...
Sizes
Loading...
With Icons
Use iconStart and iconEnd props for consistent icon placement and sizing.
Loading...
Loading State
Set loading to show a spinner and disable the button. The spinner replaces iconStart.
Loading...
Glow Effect
Add an animated gradient underline on hover with the glow prop. Colors are controlled by design tokens (--glow-color-start, --glow-color-end).
Loading...
As Link
Use the render prop to compose Button with Next.js Link or any anchor element.
Loading...
CMS Integration
Loading...
Payload Block Example
// In your Payload CMS block config
import { buttonFields } from "@corew500/cms-payload"
export const HeroBlock = {
slug: "hero",
fields: [
{ name: "title", type: "text", localized: true },
{ name: "subtitle", type: "text", localized: true },
// Adds: ctaLabel, ctaVariant, ctaSize, ctaIcon, ctaIconPosition, ctaLink
...buttonFields("cta"),
],
}Rendering with Icons
import { Button } from "@corew500/ui/button"
import { getIcon } from "@corew500/cms-payload"
import Link from "next/link"
export function HeroBlock({ data }) {
// Get the icon component from CMS selection
const Icon = getIcon(data.ctaIcon)
return (
<section>
<h1>{data.title}</h1>
<p>{data.subtitle}</p>
<Button
variant={data.ctaVariant}
size={data.ctaSize}
iconStart={data.ctaIconPosition === "start" && Icon ? <Icon /> : undefined}
iconEnd={data.ctaIconPosition === "end" && Icon ? <Icon /> : undefined}
render={<Link href={data.ctaHref} />}
>
{data.ctaLabel}
</Button>
</section>
)
}API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| loading | enum | false | Show loading spinner and disable the button. When true, replaces iconStart with a spinner and sets aria-busy. |
| iconStart | enum | — | Icon to display at the start (left) of the button text. Automatically hidden when loading is true. |
| iconEnd | enum | — | Icon to display at the end (right) of the button text. Remains visible during loading state. |
| animated | enum | true | Enable hover scale and active press micro-interactions. Uses motion-safe media query to respect user preferences. |
| fullWidth | enum | false | Make the button expand to fill its container width. |
| glow | enum | false | Enable animated gradient glow effect on hover. Adds decorative gradient lines below the button. |
| focusableWhenDisabled | enum | false | Whether the button should be focusable when disabled. |
| nativeButton | enum | true | Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (e.g. `<div>`). |
| style | enum | — | Style applied to the element, or a function that returns a style object based on the component’s state. |
| className | enum | — | CSS class applied to the element, or a function that returns a class based on the component’s state. |
| render | enum | — | Allows you to replace the component’s HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
| variant | enum | default | — |
| size | enum | default | — |
Accessibility
Keyboard Navigation
- Supports keyboard navigation (Enter/Space to activate)
- Disabled state removes from tab order and announces as disabled
- Focus ring visible for keyboard navigation
Screen Readers
- Sets `aria-busy="true"` during loading state
Additional
- - Uses native button semantics via Base UI primitive
Localization
Translatable Content
- - Pass translated strings as children
- Loading text should be localized when using loading state with children