Button
Primary action trigger with variants and states.
Button Examples
M3-ish button with variants, sizes, optional icon, ripple effect, loading state, and optional fixed positioning.
Basic usage
Use it as a regular button. Add `onClick` for interaction.
Live preview
Basic
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";
export default function Example() {
return (
<Button variant="primary" ripple onClick={() => console.log("clicked")}>
Click
</Button>
);
}Live preview
Click counter (controlled state)
import { useState } from "react";
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";
export default function Example() {
const [count, setCount] = useState(0);
return (
<div style={{ display: "flex", flexWrap: "wrap", gap: 12, alignItems: "center" }}>
<Button variant="primary" ripple onClick={() => setCount((v) => v + 1)}>
Clicked: {count}
</Button>
<Button variant="transparent" outline onClick={() => setCount(0)}>
Reset
</Button>
</div>
);
}Variants
Change the visual tone with `variant`.
Live preview
All variants
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";
export default function Example() {
return (
<div style={{ display: "flex", flexWrap: "wrap", gap: 12 }}>
<Button variant="primary">Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="tertiary">Tertiary</Button>
<Button variant="success">Success</Button>
<Button variant="warning">Warning</Button>
<Button variant="danger">Danger</Button>
<Button variant="info">Info</Button>
<Button variant="transparent" outline>Transparent</Button>
</div>
);
}Live preview
Outline + ripple
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";
export default function Example() {
return (
<div style={{ display: "flex", flexWrap: "wrap", gap: 12 }}>
<Button variant="primary" outline ripple>Primary</Button>
<Button variant="secondary" outline ripple>Secondary</Button>
<Button variant="danger" outline ripple>Danger</Button>
</div>
);
}Sizes and shapes
Use `size` and `variantRadio` to control scale and radius/shape.
Live preview
Sizes
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";
export default function Example() {
return (
<div style={{ display: "flex", gap: 12, flexWrap: "wrap" }}>
<Button size="small" variant="primary">Small</Button>
<Button size="medium" variant="primary">Medium</Button>
<Button size="large" variant="primary">Large</Button>
</div>
);
}Live preview
Radius levels + aliases
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";
export default function Example() {
return (
<div style={{ display: "grid", gap: 12 }}>
<div style={{ display: "flex", flexWrap: "wrap", gap: 12 }}>
<Button variant="secondary" variantRadio="none">none</Button>
<Button variant="secondary" variantRadio="xs">xs</Button>
<Button variant="secondary" variantRadio="sm">sm</Button>
<Button variant="secondary" variantRadio="md">md</Button>
<Button variant="secondary" variantRadio="lg">lg</Button>
<Button variant="secondary" variantRadio="xl">xl</Button>
<Button variant="secondary" variantRadio="full">full</Button>
</div>
<div style={{ display: "flex", flexWrap: "wrap", gap: 12 }}>
<Button variant="tertiary" variantRadio="square">square</Button>
<Button variant="tertiary" variantRadio="rounded">rounded</Button>
<Button variant="tertiary" variantRadio="pill">pill</Button>
</div>
</div>
);
}Icons
Use `iconContent` to render an icon next to the label. Combine with `iconPosition` and `iconSize`.
Live preview
Icon component
import Icon from "@/packages/ui/src/_components/icon/Icon";
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";
export default function Example() {
return (
<div style={{ display: "flex", flexWrap: "wrap", gap: 12 }}>
<Button
variant="info"
ripple
iconPosition="left"
iconSize="small"
iconContent={<Icon name="home" size="small" />}
>
Home
</Button>
<Button
variant="warning"
outline
iconPosition="right"
iconSize="medium"
iconContent={<Icon name="east" style="rounded" />}
>
Next
</Button>
<Button
variant="success"
iconPosition="left"
iconSize="medium"
iconContent={<Icon name="check" />}
>
Done
</Button>
</div>
);
}Live preview
String icons
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";
export default function Example() {
return (
<div style={{ display: "flex", gap: 12, flexWrap: "wrap" }}>
<Button iconContent="⭐">Star</Button>
<Button iconContent="🔥">Hot</Button>
</div>
);
}Live preview
Icon-only button (accessibility)
import Icon from "@/packages/ui/src/_components/icon/Icon";
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";
export default function Example() {
return (
<div style={{ display: "flex", gap: 12, flexWrap: "wrap" }}>
<Button
variant="transparent"
outline
ripple
ariaLabel="Search"
iconContent={<Icon name="search" />}
/>
<Button
variant="transparent"
outline
ripple
ariaLabel="Settings"
iconContent={<Icon name="settings" />}
/>
</div>
);
}States and layout
Loading, disabled, full width, and forced dimensions.
Live preview
Loading (and disable other actions)
import { useState } from "react";
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";
export default function Example() {
const [loading, setLoading] = useState(false);
return (
<div style={{ display: "flex", flexWrap: "wrap", gap: 12 }}>
<Button
variant="secondary"
ripple
loading={loading}
onClick={() => setLoading(true)}
>
Save
</Button>
<Button
variant="danger"
outline
ripple
disabled={loading}
onClick={() => setLoading(false)}
>
Cancel
</Button>
</div>
);
}Live preview
Disabled
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";
export default function Example() {
return (
<div style={{ display: "flex", gap: 12, flexWrap: "wrap" }}>
<Button variant="primary" disabled>Disabled</Button>
<Button variant="secondary" outline disabled>Disabled outline</Button>
</div>
);
}Live preview
Full width + forced sizes
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";
export default function Example() {
return (
<div style={{ display: "grid", gap: 12, width: 320 }}>
<Button variant="primary" fullWidth>Full width</Button>
<Button variant="info" forceWidth="200px" forceHeight="44px">200px × 44px</Button>
</div>
);
}Live preview
Custom styles and extra classes
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";
export default function Example() {
return (
<div style={{ display: "flex", gap: 12, flexWrap: "wrap" }}>
<Button
variant="tertiary"
className="my-extra-class"
customStyles={{ backgroundColor: "pink", padding: "12px 20px" }}
>
Custom styles
</Button>
<Button defaultButton>Default button</Button>
</div>
);
}Fixed positioning (FAB-style)
Use `isFixed` and `fixedPosition` for floating action buttons. For docs, only code is shown to avoid interfering with the page layout.
• Tip: for icon-only FABs, always set `ariaLabel`.
• Combine with `variantRadio='full'` for a circular shape.
Four corners
import Icon from "@/_components/icon/Icon";
import { Button } from "@/_components/buttons_variants/buttons/Button";
export default function Example() {
return (
<>
<Button
variant="primary"
variantRadio="full"
size="large"
isFixed
fixedPosition="up-left"
ariaLabel="Create"
iconContent={<Icon name="add" size="large" style="rounded" />}
ripple
/>
<Button
variant="secondary"
variantRadio="full"
size="large"
isFixed
fixedPosition="up-right"
ariaLabel="Search"
iconContent={<Icon name="search" size="large" style="rounded" />}
ripple
/>
<Button
variant="tertiary"
variantRadio="xl"
size="large"
isFixed
fixedPosition="down-left"
iconPosition="left"
iconContent={<Icon name="edit" size="medium" style="rounded" />}
ripple
>
Edit
</Button>
<Button
variant="success"
variantRadio="xl"
size="large"
isFixed
fixedPosition="down-right"
iconPosition="left"
iconContent={<Icon name="chat" size="medium" style="rounded" />}
ripple
>
New
</Button>
</>
);
}On this page
Button Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| size | "small" | "medium" | "large" | No | undefined | Visual size preset. |
| variant | "primary" | "secondary" | "tertiary" | "success" | "warning" | "danger" | "info" | "transparent" | No | undefined | Visual tone/variant. |
| variantRadio | "none" | "xs" | "sm" | "md" | "lg" | "xl" | "full" | "square" | "rounded" | "pill" | No | undefined | Radius/shape preset (maps to `cssnt-button--radius-*` / `cssnt-button--shape-*`). |
| outline | boolean | No | false | Enables outline styling class. |
| ripple | boolean | No | false | Enables ripple effect on pointer down (disabled while loading or disabled). |
| loading | boolean | No | false | When true, renders a spinner and hides label/icon. |
| disabled | boolean | No | false | Adds a disabled styling class and disables ripple. |
| fullWidth | boolean | No | false | Adds a full-width styling class. |
| iconContent | React.ReactNode | string | No | undefined | Optional icon rendered next to the label (or as icon-only when no children). |
| iconPosition | "left" | "right" | No | undefined | Icon placement (CSS class). |
| iconSize | "small" | "medium" | "large" | No | undefined | Icon wrapper size class. |
| forceHeight | string | No | undefined | Forces button min/max height (e.g. "40px"). |
| forceWidth | string | No | undefined | Forces button min/max width (e.g. "160px"). |
| isFixed | boolean | No | false | Enables fixed-position mode (adds `cssnt-button--is-fixed`). |
| fixedPosition | "up-right" | "down-right" | "up-left" | "down-left" | No | undefined | Fixed-position placement preset. |
| defaultButton | boolean | No | false | Enables a reset/default style (useful for drop-in compatibility). |
| ariaLabel | string | No | undefined | Accessibility label (recommended for icon-only buttons). |
| customStyles | React.CSSProperties | No | undefined | Inline styles applied to the root element. |
| className | string | No | undefined | Extra classes appended to the root element. |
| children | React.ReactNode | No | undefined | Button label/content. |
| onClick | (event: React.MouseEvent<HTMLButtonElement>) => void | No | undefined | Click handler. |