Button
Overviewimport { Button, ButtonGroup, CompactButton, FancyButton, LinkButton } from '@nili/ui';This is the library’s own overview page, rendered live. Switch the language or the theme in the header and it follows.
Appearances
Four visual styles. Filled is the default; use stroke, lighter or ghost when you need less visual weight.
import { Button } from "@nili/ui"
export function Example() {
return (
<>
<Button appearance="filled">Filled</Button>
<Button appearance="stroke">Stroke</Button>
<Button appearance="lighter">Lighter</Button>
<Button appearance="ghost">Ghost</Button>
</>
)
}Colors
Primary, Neutral, Error and Success. Combine freely with any appearance.
import { Button } from "@nili/ui"
export function Example() {
return (
<>
<Button color="primary">Primary</Button>
<Button color="neutral">Neutral</Button>
<Button color="error">Error</Button>
<Button color="success">Success</Button>
</>
)
}Sizes
Medium (40px) is the default. Smaller sizes keep the same icon size and typography scale.
import { Button } from "@nili/ui"
export function Example() {
return (
<>
<Button size="md">Medium</Button>
<Button size="sm">Small</Button>
<Button size="xs">X-Small</Button>
<Button size="2xs">2X-Small</Button>
</>
)
}With icons
Pass any React node to startIcon or endIcon. Icons are sized and spaced for you.
import { Button, Icon } from "@nili/ui"
import { RiArrowLeftSLine, RiArrowRightSLine } from "@remixicon/react"
export function Example() {
return (
<Button
startIcon={<Icon icon={RiArrowLeftSLine} mirrored />}
endIcon={<Icon icon={RiArrowRightSLine} mirrored />}
>
Continue
</Button>
)
}Icon only
Square buttons. Always give one an accessible name with aria-label — a glyph on its own has none.
import { Button, Icon } from "@nili/ui"
import { RiAddLine } from "@remixicon/react"
export function Example() {
return (
<Button iconOnly aria-label="Add" startIcon={<Icon icon={RiAddLine} />} />
)
}Loading & disabled
Loading keeps the original width so the layout does not jump. Disabled is a real disabled attribute.
import { Button } from "@nili/ui"
export function Example() {
return (
<>
<Button loading loadingLabel="Sending">Send</Button>
<Button disabled>Disabled</Button>
</>
)
}Full width
Useful inside forms or mobile sheets.
import { Button } from "@nili/ui"
export function Example() {
return <Button fullWidth>Continue</Button>
}Link Buttons
Text-weight actions that sit inline with copy. Use underline for an always-underlined link, or let it appear on hover.
import { LinkButton, Icon } from "@nili/ui"
import { RiArrowRightSLine } from "@remixicon/react"
export function Example() {
return (
<>
<LinkButton href="#" color="primary">Primary link</LinkButton>
<LinkButton href="#" color="gray">Gray link</LinkButton>
<LinkButton href="#" color="error" underline>
Underlined
</LinkButton>
<LinkButton
href="#"
color="primary"
endIcon={<Icon icon={RiArrowRightSLine} mirrored />}
>
With icon
</LinkButton>
</>
)
}Fancy Buttons
The raised variant, for the single most important action on a screen. Reserve it — if there are three of them, none is fancy.
import { FancyButton, Icon } from "@nili/ui"
import { RiArrowRightSLine } from "@remixicon/react"
export function Example() {
return (
<>
<FancyButton color="primary">Primary</FancyButton>
<FancyButton color="neutral">Neutral</FancyButton>
<FancyButton color="basic">Basic</FancyButton>
<FancyButton
color="primary"
endIcon={<Icon icon={RiArrowRightSLine} mirrored />}
>
Continue
</FancyButton>
</>
)
}Compact Buttons
Square icon-only controls for tight spaces — table row actions, input adornments, toolbars. Always provide aria-label.
import { CompactButton, Icon } from "@nili/ui"
import { RiCloseLine, RiSettings3Line, RiMore2Fill } from "@remixicon/react"
export function Example() {
return (
<>
<CompactButton appearance="stroke" aria-label="Close">
<Icon icon={RiCloseLine} />
</CompactButton>
<CompactButton appearance="ghost" aria-label="Settings">
<Icon icon={RiSettings3Line} />
</CompactButton>
<CompactButton appearance="error" aria-label="Delete">
<Icon icon={RiCloseLine} />
</CompactButton>
</>
)
}Button
extends Omit< ComponentPropsWithoutRef<'button'>, 'color' >
Variant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| color | primary | neutral | error | success | basic | primary | Figma `🧩 Type` — Primary · Neutral · Error · Success. |
| appearance | filled | stroke | lighter | ghost | filled | |
| size | md | sm | xs | 2xs | md | |
| fullWidth | boolean | false | |
| iconOnly | boolean | false | Square icon-only button. Requires `aria-label` — a button whose only content is an SVG has no accessible name otherwise. |
Other props
| Prop | Type | Default | Notes |
|---|---|---|---|
| children | ReactNode | — | |
| disabled | boolean | — | |
| required | boolean | — | |
| readOnly | boolean | — | |
| value | string | — | |
| defaultValue | string | — | |
| name | string | — | |
| aria-label | string | — | |
| startIcon | ReactNode | — | |
| endIcon | ReactNode | — | |
| loading | boolean | false | Shows a spinner and blocks interaction without collapsing the layout. |
| loadingLabel | string | — | Announced while `loading`, e.g. `'Sending'`. |
| asChild | boolean | false | Render the child element instead of a `<button>`, keeping every style and handler. Use for links: `<Button asChild><a href="…">…</a></Button>`. |
ButtonGroup
extends ComponentPropsWithoutRef<'div'>
Variant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| orientation | horizontal | vertical | horizontal |
Other props
| Prop | Type | Default | Notes |
|---|---|---|---|
| children* | ReactNode | — | |
| aria-label | string | — | |
| size | sm | xs | 2xs | sm | |
| role | toolbar | radiogroup | group | toolbar | `'toolbar'` (default) for a row of independent actions. Use `'radiogroup'` when the segments are mutually exclusive choices — the roles are read out differently, and only one of them promises "pick exactly one". |
| label | string | — |
ButtonGroupItem
extends Omit< ComponentPropsWithoutRef<'button'>, 'color' >
Variant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| selected | boolean | false | |
| iconOnly | boolean | false | |
| size | sm | xs | 2xs | sm | Overrides the size inherited from the group. Rarely needed. |
| orientation | horizontal | vertical | horizontal |
Other props
| Prop | Type | Default | Notes |
|---|---|---|---|
| children | ReactNode | — | |
| disabled | boolean | — | |
| required | boolean | — | |
| readOnly | boolean | — | |
| value | string | — | |
| defaultValue | string | — | |
| name | string | — | |
| aria-label | string | — | |
| startIcon | ReactNode | — | |
| endIcon | ReactNode | — |
CompactButton
extends Omit< ComponentPropsWithoutRef<'button'>, 'color' | 'children' >
Variant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| appearance | stroke | ghost | white | error | inherit | stroke | |
| size | lg | md | lg | |
| fullRadius | boolean | false | Pill instead of a rounded square. |
Other props
| Prop | Type | Default | Notes |
|---|---|---|---|
| children* | ReactNode | — | The glyph. Required — this control is always icon-only. |
| disabled | boolean | — | |
| required | boolean | — | |
| readOnly | boolean | — | |
| value | string | — | |
| defaultValue | string | — | |
| name | string | — | |
| aria-label* | string | — | Accessible name. Required, not optional: a button whose only content is an SVG has no accessible name at all, so the type system asks for one. |
FancyButton
extends Omit< ComponentPropsWithoutRef<'button'>, 'color' >
Variant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| color | neutral | primary | error | success | basic | primary | Figma `🧩 Type` — Neutral · Primary · Error · Success · Basic. |
| size | md | sm | xs | md | Figma `📏 Size` — Medium (40) · Small (36) · X-Small (32). |
| fullWidth | boolean | false |
Other props
| Prop | Type | Default | Notes |
|---|---|---|---|
| children | ReactNode | — | |
| disabled | boolean | — | |
| required | boolean | — | |
| readOnly | boolean | — | |
| value | string | — | |
| defaultValue | string | — | |
| name | string | — | |
| aria-label | string | — | |
| startIcon | ReactNode | — | |
| endIcon | ReactNode | — | |
| asChild | boolean | false |
LinkButton
extends Omit< ComponentPropsWithoutRef<'a'>, 'color' >
Variant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| color | gray | black | primary | error | success | inherit | gray | |
| size | md | sm | md | |
| underline | boolean | false |
Other props
| Prop | Type | Default | Notes |
|---|---|---|---|
| children | ReactNode | — | |
| aria-label | string | — | |
| startIcon | ReactNode | — | |
| endIcon | ReactNode | — | |
| disabled | boolean | — | |
| asChild | boolean | false | Render the child element instead of an `<a>` — for router links. |