PillTabs

Overview

PillTabs are horizontal navigation buttons within panels. They switch between frequently used filters or sub-views of the same content.

When to use:

  • To switch between different views or filters of data within a table.
  • To switch between different variants of content.

Implementation

Edit the code below to see your changes live!

function Example() {
  const [activePills, setActivePills] = useState<string[]>([]);
  const Card: React.FC<{ name: string; description: string }> = ({
    name,
    description,
  }) => (
    <Flex
      border="box"
      borderRadius="normal"
      flexDirection="column"
      margin="xxSmall"
      padding="medium"
    >
      <FlexItem marginBottom="xxSmall">
        <Text bold>{name}</Text>
      </FlexItem>
      <FlexItem flexGrow={1}>
        <Text>{description}</Text>
      </FlexItem>
      <FlexItem>
        <Link href="#">Install</Link>
      </FlexItem>
    </Flex>
  );
  const items = [
    { title: 'Shipping', id: 'shipping' },
    { title: 'Orders', id: 'orders' },
  ];
  const onPillClick = (pillId: string) => {
    const isPillActive = !activePills.includes(pillId);
    const updatedPills = isPillActive
      ? [...activePills, pillId]
      : activePills.filter((activePillId) => activePillId !== pillId);

    setActivePills(updatedPills);
  };
  const cards = [
    {
      name: 'Shipping App Pro',
      description: 'All your shipping needs in a one stop shop.',
      type: 'shipping',
    },
    {
      name: 'Order Tracker Deluxe',
      description: 'Track your orders across all your devices.',
      type: 'orders',
    },
    {
      name: 'Expedited Shipper',
      description: 'The best rush rates in the country.',
      type: 'shipping',
    },
    {
      name: 'Inventory Wizard',
      description: 'Inventory tracking app to cover all your needs.',
      type: 'other',
    },
  ];
  const isFiltered = Boolean(activePills.length);
  const filteredCards = cards.filter((card) => activePills.includes(card.type));
  const appCards = isFiltered ? filteredCards : cards;

  return (
    <>
      <PillTabs activePills={activePills} items={items} onPillClick={onPillClick} />
      <Flex>
        {appCards.map(({ name, description }) => (
          <Card description={description} key={name} name={name} />
        ))}
      </Flex>
    </>
  );
}

Props

Prop name
Type
Default
Description
activePillsstring[]

The currently active pill ids as an array of strings.

items *PillTabItem[]

See PillTabItem for usage.

onPillClick *(itemId: string) => void

Function that will get called when a pill tab is clicked.

Props ending with * are required

Do's and Don'ts

Do
Use on pages that have a large amount of content.
Be concise on the navigation labels, ideally one or two words rather than a phrase.
Default page view should have no PillTabs selected.
Don't
Don’t use to navigate between unrelated items.
Don’t link to content that’s hidden in default view.
Never use PillTabs to navigate a user away from the current page.