---
name: button-usage
description: >
Use after component-usage-ux when an app needs @techsio/ui-kit Button for
actions, including correct variant, theme, size, loading state, icon props,
and token-first styling rules.
metadata:
type: "core"
library: "@techsio/ui-kit"
library_version: "0.3.2"
component: "Button"
component_version: "0.3.2"
requires: "component-usage-ux app-token-overrides ux-guidelines"
sources: "libs/ui/src/atoms/button.tsx libs/ui/src/tokens/components/atoms/_button.css libs/ui/stories/atoms/button.stories.tsx libs/ui/src/atoms/button.figma.ts"
---
# @techsio/ui-kit Button Usage
Use Button for in-place actions. Use `LinkButton` for navigation that should
look like a button.
## UX/UI guidelines
House rules come from the `ux-guidelines` skill (writing, formatting, states,
where actions and feedback live). This section applies them to `Button`.
**Use it when**
- Any action that changes state on the current page: save, create, delete, open a dialog, apply filters.
- Form submission and dialog/drawer footers.
- Page-level commands in the page header (`New product`).
**Use something else when**
| Need | Use instead |
| --- | --- |
| Navigate to a URL, styled as a button | LinkButton |
| Inline navigation in text | Link |
| Compact repeated icon action | ActionIcon |
| More than three related commands | Menu behind one Button |
| Toggle a setting on/off | Switch |
**Do**
- One `variant="primary"` per surface; secondary actions use `secondary` / `outlined` / `borderless`.
- Order groups `[Cancel] [Primary]` — primary last, at the end of the container (ux-guidelines/feedback-and-actions).
- Use `variant="danger"` only for destructive actions and keep them away from Save.
- Show progress with `isLoading` + `loadingText` (`Saving…`) on the button that started the action.
- Add an `icon` only when it speeds recognition (`+` for New, trash for Delete); keep the text.
**Don't**
- Use `OK`, `Yes`, `Submit`, `Confirm` or `Click here` as labels.
- Put two primary buttons side by side.
- Disable a submit button when the user can't see why (ux-guidelines/states#disabled).
- Fake a link with `onClick={() => router.push()}` — use LinkButton.
- Change the label to a result (`Saved!`); confirm with a Toast instead.
**Copy and states**
- Verb + object in sentence case: `New product`, `Create product`, `Save changes`, `Delete product`, `Discard changes` (full table in ux-guidelines/ux-writing#button-labels).
- `Cancel` leaves a form without saving; `Close` closes something with no pending changes.
## Setup
```tsx
import { Button } from "@techsio/ui-kit/atoms/button"
```
Supported visual props from `src/atoms/button.tsx`:
```text
variant: primary | secondary | tertiary | danger | warning
theme: solid | light | borderless | outlined | unstyled
size: sm | md | lg | current
block: boolean
uppercase: boolean
isLoading: boolean
loadingText: string
icon: IconType
iconPosition: left | right
iconSize: xs | sm | md | lg | xl | 2xl | current
```
## Core Patterns
### Choose variant from action semantics
```text
primary -> main positive action in the current scope
secondary -> secondary action with normal emphasis
tertiary -> quiet tertiary action
danger -> destructive action such as delete/remove/cancel order
warning -> risky but not destructive action
```
### Choose theme from emphasis
```text
solid -> strongest emphasis
light -> filled but softer emphasis
outlined -> boundary/emphasis without solid fill
borderless -> quiet action, similar to "ghost"
unstyled -> only when composing inside another component surface
```
There is no `variant="ghost"`. Use `theme="borderless"` for that intent.
### Let Button own its visual styling
```tsx
```
Do not add background, foreground, padding, border, radius, or font classes
that duplicate Button tokens. If the app needs different colors or sizing,
change app token overrides first.
### Use loading props instead of custom disabling
```tsx
```
Use the component API for loading and disabled state instead of wrapping the
button in a conditional spinner.
## Common Mistakes
### HIGH Native button
Wrong:
```tsx
```
Correct:
```tsx
```
Source: libs/ui/src/atoms/button.tsx
### HIGH Hallucinated ghost variant
Wrong:
```tsx
```
Correct:
```tsx
```
Source: libs/ui/src/atoms/button.tsx
### HIGH Duplicated component tokens in className
Wrong:
```tsx
```
Correct:
```tsx
```
If Button danger should look different in the app, override
`--color-button-*` or related semantic tokens in CSS.
Source: libs/ui/src/tokens/components/atoms/_button.css
### MEDIUM Navigation rendered as Button
Wrong:
```tsx
```
Correct:
```tsx
Products
```
Use Button for actions and LinkButton for navigation.
## Validation Commands
```sh
rg -n "