nili/ui
All components

Radio

Overview
16 exports8 variant axes57 props4 files
import { Radio, RadioCard, RadioGroup } 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.

Group

RadioGroup shares a name across its radios — generated if you do not pass one. Without it the browser will not treat them as one group, and arrow keys stop moving between them.

Plan
import { Radio, RadioGroup } from "@nili/ui"

export function Example() {
  const [plan, setPlan] = useState("pro")

  return (
    <RadioGroup value={plan} onValueChange={setPlan} title={t('plan.label')}>
      <Radio value="free" label={t('plan.free')} />
      <Radio value="pro" label={t('plan.pro')} />
      <Radio value="team" label={t('plan.team')} />
    </RadioGroup>
  )
}

Orientation

Vertical by default. Horizontal works for two or three short options — beyond that the row wraps and the grouping stops reading.

horizontal
disabled & invalid group
Pick one
import { Radio, RadioGroup } from "@nili/ui"

export function Example() {
  return (
    <RadioGroup orientation="horizontal" defaultValue="monthly" label="Billing">
      <Radio value="monthly" label={t('billing.monthly')} />
      <Radio value="yearly" label={t('billing.yearly')} />
    </RadioGroup>
  )
}

The label row

Same four slots as Checkbox: sublabel, badge, description and linkButton. labelPosition flips the control to the other side.

Plan
(most popular)Save 20%Everything in Free, plus unlimited projects.Compare plans
One project, one seat.
import { Radio, RadioGroup, Badge, LinkButton } from "@nili/ui"

export function Example() {
  return (
    <RadioGroup defaultValue="pro" title={t('plan.label')}>
      <Radio
        value="pro"
        label="Pro"
        sublabel="(most popular)"
        badge={<Badge size="small" color="blue" appearance="lighter">Save 20%</Badge>}
        description="Everything in Free, plus unlimited projects."
        linkButton={<LinkButton href="#" size="sm">Compare plans</LinkButton>}
      />
      <Radio value="free" label="Free" description="One project, one seat." />
    </RadioGroup>
  )
}

Radio Card

A radio rendered as a selectable panel — plan pickers, payment methods. Figma's six Types are one startAdornment slot: as an enum they would be mutually exclusive, and a seventh would need a library release.

Payment method
import { RadioGroup, RadioCard, KeyIcon, Icon } from "@nili/ui"
import { RiBankCardLine, RiWallet3Line } from "@remixicon/react"

export function Example() {
  const [method, setMethod] = useState("card")

  return (
    <RadioGroup value={method} onValueChange={setMethod} title="Payment method">
      <RadioCard
        value="card"
        label="Card"
        description="Visa, Mastercard or a local card."
        startAdornment={
          <KeyIcon size="md" color="blue"><Icon icon={RiBankCardLine} /></KeyIcon>
        }
      />
      <RadioCard
        value="wallet"
        label="Wallet"
        sublabel="balance ۱۲۰٬۰۰۰"
        startAdornment={
          <KeyIcon size="md" color="green"><Icon icon={RiWallet3Line} /></KeyIcon>
        }
      />
    </RadioGroup>
  )
}