nili/ui
All components

Button

Overview
42 exports19 variant axes72 props12 files
import { 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.

primary
neutral
error
success
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.

Colors
Sizes
With icons
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.

Appearances
Sizes
Full radius (pill)
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>
    </>
  )
}