Skip to content

Pill ​

The small label in a header, a sidebar row or a settings line: a count, a branch, a status. With an onClick it is a button, and with pressed a toggle.

tsx
import { Pill } from '@adecore/ui';
tsx
import { useState } from 'react';
import { CircleAlert, GitBranch } from 'lucide-react';
import { Icon, Pill } from '@adecore/ui';

export default function PillDemo() {
    const [staged, setStaged] = useState(false);

    return (
        <div className="flex flex-col items-center gap-3">
            <div className="flex flex-wrap items-center gap-2">
                <Pill>12 files</Pill>
                <Pill tone="raised">Draft</Pill>
                <Pill tone="idle">Idle</Pill>
                <Pill tone="needsYou" icon={<Icon icon={CircleAlert} size={12} />}>
                    Needs you
                </Pill>
                <Pill tone="error">Failed</Pill>
                <Pill tone="accent">New</Pill>
            </div>
            <div className="flex flex-wrap items-center gap-2">
                <Pill mono icon={<Icon icon={GitBranch} size={12} />}>
                    feature/export
                </Pill>
                <Pill shape="tag" tone="accent">
                    Beta
                </Pill>
                <Pill pressed={staged} onClick={() => setStaged(!staged)}>
                    Staged only
                </Pill>
            </div>
        </div>
    );
}

The tone says what the label means about the thing it names. muted is the default, and raised lifts a label off a sunken header so it reads as a control. idle, needsYou and error use the status colors. A tag is tighter and heavier than a pill, for the end of a line of prose. mono suits a branch name or a count that is read character by character.

Every ground is an alpha of the text color, or of the status or accent color, over whatever the pill stands on. In the dark theme a pill lifts a shade off its row, in the light theme it sinks one, so it reads on a sidebar row, a header and a card alike. The text is 12px on a 19px line, and a pill never breaks inside itself: in a row that wraps it moves to the next line whole.

Props ​

PropTypeDefault
childrenReactNodeRequired.
iconReactNodeDrawn before the text; use a 12 pixel Icon.
tone'muted' | 'raised' | 'idle' | 'needsYou' | 'error' | 'accent''muted'
shape'pill' | 'tag''pill'
monobooleanfalse
onClick() => voidMakes the pill a button.
pressedbooleanMakes the button a toggle (aria-pressed).
disabledboolean
classNamestring
refRef<HTMLElement>A <span>, or a <button> with onClick.

PillProps is an exported type.