Skip to content
OpenPerf
Esc
↑↓navigate↵open⌘Jpreview
On this page

Icons

Tabler Icons, outline, stroke 1.75, coloured from currentColor.

Sizes

import { IconAlertTriangle, IconBug, IconRoute, IconSearch } from "@tabler/icons-react";

const SIZES = [
  { name: "10px", className: "size-2.5", usage: "Checkmarks in checkboxes and checkable items" },
  { name: "12px", className: "size-3", usage: "Chips, tags, sort arrows, filter bar" },
  { name: "14px", className: "size-3.5", usage: "xs buttons, inputs, menu items" },
  { name: "16px", className: "size-4", usage: "Buttons, rows, list and sidebar items, toasts" },
];

export default function IconSizes() {
  return (
    <div className="flex w-full flex-col gap-4 bg-default font-sans text-body-md text-default">
      {SIZES.map((size) => (
        <div className="flex items-center gap-3" key={size.name}>
          <code className="w-16 shrink-0 font-medium">{size.name}</code>
          <div className="flex w-48 shrink-0 items-center gap-3 text-icon">
            {[IconSearch, IconBug, IconRoute, IconAlertTriangle].map((Icon) => (
              <Icon aria-hidden={true} className={size.className} key={Icon.displayName} />
            ))}
          </div>
          <span className="text-muted">{size.usage}</span>
        </div>
      ))}
    </div>
  );
}

Match the icon size to its control: 10px for checkmarks, 12px for chips, tags and sort arrows, 14px for inputs, menu items and xs buttons, and 16px for buttons, rows and navigation. Avatars and breadcrumb separators scale their icon with their own size. The catalog keeps every size in neutral text-icon.

Colour and state

import { IconBug, IconCircleArrowUp, IconCircleCheck, IconCircleDot } from "@tabler/icons-react";

const STATES = [
  { label: "Resting", className: "size-4 text-icon", token: "text-icon", icon: IconBug },
  {
    label: "Hover / current",
    className: "size-4 text-default",
    token: "text-default",
    icon: IconBug,
  },
  {
    label: "Unresolved",
    className: "size-4 text-warning",
    token: "text-warning",
    icon: IconCircleDot,
  },
  {
    label: "Regressed",
    className: "size-4 text-danger",
    token: "text-danger",
    icon: IconCircleArrowUp,
  },
  {
    label: "Resolved",
    className: "size-4 text-success",
    token: "text-success",
    icon: IconCircleCheck,
  },
];

export default function IconStates() {
  return (
    <div className="flex w-full flex-wrap gap-x-6 gap-y-4 bg-default font-sans text-body-md text-default">
      {STATES.map((state) => (
        <div className="flex items-center gap-2.5" key={state.label}>
          <state.icon aria-hidden={true} className={state.className} />
          <div className="flex flex-col">
            <span>{state.label}</span>
            <code className="text-body-md text-muted">{state.token}</code>
          </div>
        </div>
      ))}
    </div>
  );
}

Use text-icon at rest and text-default on hover or when current. Reserve colour for state: text-warning for Unresolved, text-danger for Regressed and text-success for Resolved.

Rules

  • Import from @tabler/icons-react. The stroke is set to 1.75 by the theme; don’t pass stroke. Checkmarks are the one exception: they are drawn at 2.5 so they hold at 10px.
  • An icon-only button needs an aria-label.

Was this page helpful?