sidebar

The Sidebar component provides a vertical navigation menu with support for nested links, expandable groups, optional footer content, and consumer-controlled active state matching.

Usage

Default


const links = [
  { label: "Dashboard", href: "/dashboard", icon: <FaBook /> },
  {
    label: "Reports",
    href: "/reports",
    children: [
      { label: "Monthly", href: "/reports/monthly", icon: <FaCalendar /> },
      { label: "Annual", href: "/reports/annual", icon: <FaCalendar /> },
    ],
    icon: <FaPaperclip />,
  },
  { label: "Settings", href: "/settings", icon: <FaCogs /> },
];

const currentPath = "/settings";

const normalizePath = (p: string) =>
  p.endsWith("/") && p.length > 1 ? p.slice(0, -1) : p;

const isDescendantPath = (parentPath: string, currentPath: string) => {
  const parent = normalizePath(parentPath);
  const current = normalizePath(currentPath);

  if (parent === "/") return current === "/";
  return current === parent || current.startsWith(`${parent}/`);
};

const isActiveRecursive = (link, matcher) => {
  if (matcher(link)) return true;
  return !!link.children?.some((child) => isActiveRecursive(child, matcher));
};

const isLinkActive = (link) => {
  if (!link.href) return false;

  if (link.children?.length) {
    return isDescendantPath(link.href, currentPath);
  }

  return normalizePath(link.href) === normalizePath(currentPath);
};

const hasActiveChild = (link) =>
  !!link.children?.some((child) => isActiveRecursive(child, isLinkActive));

<Sidebar
  links={links}
  isLinkActive={isLinkActive}
  hasActiveChild={hasActiveChild}
/>
      

Props

Sortable data table
PropTypeDefaultDescription
linksArray<{ label: string; href?: string; icon?: ReactNode; children?: SidebarLink[] }>-Array of navigation links. Each link can include a label, optional href, optional icon, and optional nested children.
isLinkActive(link: SidebarLink) => boolean-Optional callback used to determine whether a link should be styled as active. This allows the consumer app to fully control active route matching.
hasActiveChild(link: SidebarLink) => boolean-Optional callback used to determine whether a link contains an active child. Useful for opening and highlighting parent sections based on app-specific routing rules.
theme"primary" | "secondary" | "tertiary" | "quaternary" | "clear"Configured DefaultTheme color for the sidebar.
state"success" | "error" | "warning"-Visual state for feedback, such as success, warning, or error.
outlinebooleanfalseWhether the sidebar should use an outlined style.
rounding"none" | "small" | "medium" | "large"Configured DefaultCorner rounding style for the sidebar container.
shadow"none" | "light" | "medium" | "strong" | "intense"Configured DefaultBox shadow style for the sidebar container.
showFooterbooleanfalseWhether to display the footer section at the bottom.
footerLinksArray<{ label: string; href: string; icon?: ReactNode }>-Array of footer links displayed when `showFooter` is true.
footerVersionstring-Version label displayed in the footer, such as `v1.0.0`.
classNamestring-Custom class names for the sidebar wrapper.
ariaLabelstring"Sidebar navigation"ARIA label for the sidebar navigation landmark.
data-testidstring"sidebar"Test id for querying the component in tests.