Propel

Pill

A pill-shaped button that holds a label with optional inline-start and inline-end icons.

Basic

Show code
import { Icon } from "@makeplane/propel/components/icon";
import { PillButton } from "@makeplane/propel/components/pill";
import { Tag } from "lucide-react";

export default function BasicDemo() {
  return <PillButton magnitude="md" startIcon={<Icon icon={Tag} />} label="Design" />;
}

Magnitudes

Show code
import { Icon } from "@makeplane/propel/components/icon";
import { PillButton } from "@makeplane/propel/components/pill";
import { Tag } from "lucide-react";

export default function MagnitudesDemo() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <PillButton magnitude="sm" startIcon={<Icon icon={Tag} />} label="Small" />
      <PillButton magnitude="md" startIcon={<Icon icon={Tag} />} label="Medium" />
      <PillButton magnitude="lg" startIcon={<Icon icon={Tag} />} label="Large" />
    </div>
  );
}

States

disabled and loading both drop the pill to a transparent fill with a dimmed label; loading also swaps the inline-start node for a spinner and blocks clicks while staying focusable.

Show code
import { Icon } from "@makeplane/propel/components/icon";
import { PillButton } from "@makeplane/propel/components/pill";
import { Tag } from "lucide-react";

export default function StatesDemo() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <PillButton magnitude="md" startIcon={<Icon icon={Tag} />} label="Default" />
      <PillButton magnitude="md" startIcon={<Icon icon={Tag} />} disabled label="Disabled" />
      <PillButton magnitude="md" loading label="Loading" />
    </div>
  );
}

Switch

PillSwitch is a toggle whose selected look is its pressed state — use it for segmented on/off choices.

Show code
import { Icon } from "@makeplane/propel/components/icon";
import { PillSwitch } from "@makeplane/propel/components/pill";
import { Check, Tag } from "lucide-react";

export default function SwitchDemo() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <PillSwitch magnitude="md" startIcon={<Icon icon={Tag} />} label="Off" />
      <PillSwitch magnitude="md" startIcon={<Icon icon={Check} />} defaultPressed label="On" />
    </div>
  );
}

Icon only

IconPill is a square, icon-only pill and requires an aria-label for its accessible name.

Show code
import { Icon } from "@makeplane/propel/components/icon";
import { IconPill } from "@makeplane/propel/components/pill";
import { Plus, X } from "lucide-react";

export default function IconOnlyDemo() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <IconPill magnitude="sm" aria-label="Remove label" icon={<Icon icon={X} />} />
      <IconPill magnitude="md" aria-label="Remove label" icon={<Icon icon={X} />} />
      <IconPill magnitude="lg" aria-label="Remove label" icon={<Icon icon={X} />} />
      <IconPill magnitude="md" aria-label="Add label" disabled icon={<Icon icon={Plus} />} />
      <IconPill magnitude="md" aria-label="Add label" loading icon={<Icon icon={Plus} />} />
    </div>
  );
}

Installation

import { Icon } from "@makeplane/propel/components/icon";
import { PillButton } from "@makeplane/propel/components/pill";

Props

PillButton

PropTypeRequiredDescription
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, {}>NoAllows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render.
magnitude"sm" | "md" | "lg"Yes
emphasis"outline" | "soft"NoFill treatment. Defaults to `outline` (≈ Button secondary). `soft` ≈ Button tertiary.
startIconReactNodeNoElement rendered before the label (inline-start), e.g. `<Icon icon={Tag} />`.
endIconReactNodeNoElement rendered after the label (inline-end), e.g. `<Icon icon={X} />`.
labelstringYesVisible pill label.
loadingbooleanNoBusy state: hides start/end icons, shows a spinner after the label, and blocks clicks.