Design system

App bar & Button App bar

Top bar for title, actions, and navigation.

App bar Examples

Copy-ready examples for App_bar + Button_appbar.

Mobile (controlled selection)

App_bar does not manage selection; keep the selected destination in your own state and pass isSelected to the item.

Button_appbar uses a roving tab index pattern: set exactly one item as isSelected so it is focusable via Tab.

Live preview

Mobile app bar (controlled)

import { useState } from "react";
import App_bar from "@/_components/app_bar/App_bar";
import Button_appbar from "@/_components/app_bar/button_appbar/Button_appbar";

export default function Example() {
  const [selected, setSelected] = useState<"home" | "search" | "profile">("home");

  return (
    <App_bar typeOfAppBar="mobile" ariaLabel="Primary navigation">
      <Button_appbar
        mode="mobile"
        iconName="Home"
        label="Home"
        isSelected={selected === "home"}
        onClick={() => setSelected("home")}
      />

      <Button_appbar
        mode="mobile"
        iconName="Search"
        label="Search"
        isSelected={selected === "search"}
        onClick={() => setSelected("search")}
      />

      <Button_appbar
        mode="mobile"
        iconName="Person"
        label="Profile"
        isSelected={selected === "profile"}
        onClick={() => setSelected("profile")}
      />
    </App_bar>
  );
}

Mobile (counter + dot badge)

Use showInfo + baseNumber/baseLimit for a counter, or showInfo + notQuantity for a dot.

Live preview

Badges (counter + dot)

import { useState } from "react";
import App_bar from "@/_components/app_bar/App_bar";
import Button_appbar from "@/_components/app_bar/button_appbar/Button_appbar";

export default function Example() {
  const [selected, setSelected] = useState<"home" | "inbox" | "alerts">("home");

  return (
    <App_bar typeOfAppBar="mobile" ariaLabel="Primary navigation">
      <Button_appbar
        mode="mobile"
        iconName="Home"
        label="Home"
        isSelected={selected === "home"}
        onClick={() => setSelected("home")}
      />

      <Button_appbar
        mode="mobile"
        iconName="Inbox"
        label="Inbox"
        showInfo
        baseNumber={12}
        baseLimit={99}
        isSelected={selected === "inbox"}
        onClick={() => setSelected("inbox")}
      />

      <Button_appbar
        mode="mobile"
        iconName="Notifications"
        label="Alerts"
        showInfo
        notQuantity
        variant="info"
        isSelected={selected === "alerts"}
        onClick={() => setSelected("alerts")}
      />
    </App_bar>
  );
}

Fullscreen (horizontal layout)

In full mode, Button_appbar renders a horizontal layout and wraps the entire item with the pill.

Live preview

Full app bar + capped counter

import { useState } from "react";
import App_bar from "@/_components/app_bar/App_bar";
import Button_appbar from "@/_components/app_bar/button_appbar/Button_appbar";

export default function Example() {
  const [selected, setSelected] = useState<"home" | "notifications" | "settings">("home");

  return (
    <App_bar typeOfAppBar="full" ariaLabel="Primary navigation">
      <Button_appbar
        mode="full"
        iconName="Home"
        label="Home"
        isSelected={selected === "home"}
        onClick={() => setSelected("home")}
      />

      <Button_appbar
        mode="full"
        iconName="Notifications"
        label="Notifications"
        showInfo
        baseNumber={128}
        baseLimit={99}
        variant="secondary"
        isSelected={selected === "notifications"}
        onClick={() => setSelected("notifications")}
      />

      <Button_appbar
        mode="full"
        iconName="Settings"
        label="Settings"
        isSelected={selected === "settings"}
        onClick={() => setSelected("settings")}
      />
    </App_bar>
  );
}

Disabled item

Use isDisabled to prevent interaction and apply disabled + aria-disabled.

Live preview

Disabled destination

import { useState } from "react";
import App_bar from "@/_components/app_bar/App_bar";
import Button_appbar from "@/_components/app_bar/button_appbar/Button_appbar";

export default function Example() {
  const [selected, setSelected] = useState<"home" | "reports">("home");

  return (
    <App_bar typeOfAppBar="full" ariaLabel="Primary navigation">
      <Button_appbar
        mode="full"
        iconName="Home"
        label="Home"
        isSelected={selected === "home"}
        onClick={() => setSelected("home")}
      />

      <Button_appbar
        mode="full"
        iconName="Assessment"
        label="Reports"
        isDisabled
        isSelected={selected === "reports"}
        onClick={() => setSelected("reports")}
      />
    </App_bar>
  );
}

App_bar with custom items (no Button_appbar)

App_bar is intentionally minimal; you can render any destination controls as children.

Custom item markup

import App_bar from "@/_components/app_bar/App_bar";

export default function Example() {
  return (
    <App_bar typeOfAppBar="mobile" ariaLabel="Primary navigation">
      <button className="cssnt-appbar__item" type="button">
        Home
      </button>

      <button className="cssnt-appbar__item" type="button">
        Search
      </button>

      <button className="cssnt-appbar__item" type="button">
        Profile
      </button>
    </App_bar>
  );
}

On this page

App bar Props

Navigation container for app-level destinations (mobile/fullscreen variants). It only renders the semantic wrapper + layout classes; you provide items via children.

The inner list is rendered with role='tablist'. If your items behave like tabs (one active at a time), apply the appropriate ARIA attributes to each child (e.g., aria-selected).

App_bar does not manage selection state; control selection at the item level.

App bar props
PropTypeRequiredDefaultDescription
typeOfAppBar"mobile" | "full"No"mobile"Layout variant of the app bar. (Values: mobile, full)
ariaLabelstringNo"App bar"aria-label applied to the root <nav>.
childrenReact.ReactNodeYesn/aDestination items rendered inside the app bar list (buttons/links, usually Button_appbar).

Button app bar Props

Tab-style destination button intended to be used inside App_bar. Internally it renders a <button role="tab"> and uses Badges to display icon + label + optional counter/dot.

Use this component as a child of App_bar.

Badge behavior: set showInfo=true and either (a) baseNumber + baseLimit for a counter, or (b) notQuantity=true for a dot.

Roving tab index: set isSelected=true on exactly one item so it is focusable via Tab (tabIndex=0).

Mode controls layout: mobile is vertical and wraps only the target; full is horizontal and wraps the entire item.

Button app bar props
PropTypeRequiredDefaultDescription
mode"mobile" | "full"Yesn/aLayout preset for the app bar item. (Values: mobile, full)
iconNamestringYesn/aIcon name forwarded to Badges (and ultimately to your Icon component).
labelstringNo""Text label rendered by Badges. It is truncated for predictability: 10 chars on mobile, 24 chars on full (adds ...).
showInfobooleanNoundefinedIf true, renders the badge node (counter or dot).
baseNumbernumberNo0Counter value (used when showInfo is true and notQuantity is false).
baseLimitnumberNo0Counter cap (renders `${baseLimit}+` when baseNumber > baseLimit).
notQuantitybooleanNoundefinedIf true, shows a dot instead of a numeric counter.
variant"primary" | "secondary" | "tertiary" | "success" | "warning" | "danger" | "info"NoundefinedBadge/pill tone forwarded to Badges. (Values: primary, secondary, tertiary, success, warning, danger, info)
isSelectedbooleanNofalseSelected state: adds "is-selected", sets aria-selected="true" and tabIndex={0} (roving tab index).
isDisabledbooleanNofalseDisabled state: adds "is-disabled", sets disabled, and aria-disabled="true".
onClick(...args: any[]) => anyNoundefinedClick handler passed to the <button>.
onChange(...args: any[]) => anyNoundefinedPassed through to the <button> (native buttons typically use onClick; this is kept for API consistency).