App Bars
App Bars display information and actions at the top and bottom of a screen.
App Bars display information and actions relating to the current screen. The Material Design 3 Expressive update introduces dynamic scrolling behaviors, shared element search transitions, and fully responsive Flexible App Bars.
Introduction
The MD3 Expressive App Bar system is a comprehensive suite of header and footer components. It ranges from compact headers (Small) to immersive, expanding banners (Medium/Large). Integrated with Framer Motion, it supports advanced features like shared-element transitions for search and scroll-aware behaviors that optimize screen real estate.
Anatomy
- Container: The background surface spanning the width of the screen.
- Navigation Icon: Typically a "Back" arrow or a "Menu" hamburger icon at the start.
- Title: The name of the current view or application.
- Actions: A row of interactive icons (e.g., Search, Settings, Profile) at the end.
- Flexible Space (Medium/Large): An expanded area that collapses as the user scrolls.
Variants
Small App Bar
The standard, most common header variant. Ideal for simple navigation and consistent UI across views.
Flexible App Bars (Medium & Large)
These bars start out expanded, often showing a larger headline or additional context, and smoothly collapse to a standard size as the user scrolls up.
Search App Bar & Shared Element Transitions
A specialized variant featuring a built-in search field. Using SearchViewContainer and SearchAppBar together enables a premium "shared element" transition (searchBarId) where the search pill morphs into the full-screen search view overlay upon focus or click.
Bottom App Bar
Provides primary actions at the bottom of the screen, within easy reach of the user's thumb. Often used on mobile devices.
Fading Edge & Backdrop Blur
All App Bar components support an opt-in hardware-accelerated fading edge and backdrop blur effect (enableFadingBlur). As content scrolls beneath the bar, it smoothly transitions from fully transparent to the surface container background color.
Features
Scroll Behaviors
App bars can respond to page scrolling in several ways:
- Pinned: Stays at the top/bottom regardless of scroll.
- Enter Always: Hides on scroll down, appears immediately on scroll up.
- Exit Until Collapsed: (Flexible only) Collapses as the user scrolls but stays visible in its collapsed state.
Fading Edge & Backdrop Blur Overlay
Top and Bottom App Bars support hardware-accelerated linear gradient backdrop blur overlays:
enableFadingBlur: Toggles the linear gradient backdrop blur overlay.blurIntensity: Custom backdrop blur radius in pixels (default:12).blurHeight: Custom gradient mask height or container height.
Search Transitions
Shared element transitions are powered by Framer Motion layoutId. Setting a matching searchBarId on both <SearchAppBar> and <SearchViewContainer> enables seamless morphing from the compact bar into the full-screen search interface.
Usage
Basic Small App Bar
import { SmallAppBar, IconButton } from "@bug-on/m3-expressive";
<SmallAppBar
title="Page Title"
navigationIcon={<IconButton icon="menu" />}
actions={<IconButton icon="more_vert" />}
/>
App Bar with Fading Edge Backdrop Blur
import { SmallAppBar, BottomAppBar } from "@bug-on/m3-expressive";
// Top App Bar with Fading Edge Backdrop Blur
<SmallAppBar
title="Inbox"
enableFadingBlur={true}
blurIntensity={16}
/>
// Bottom App Bar with Fading Edge Blur
<BottomAppBar
enableFadingBlur={true}
blurIntensity={20}
actions={/* ... */}
/>
Flexible App Bar with Scroll tracking
import { MediumFlexibleAppBar, useAppBarScroll } from "@bug-on/m3-expressive";
export function Page() {
const scrollRef = useRef<HTMLDivElement>(null);
const scrollBehavior = useAppBarScroll({
behavior: "exitUntilCollapsed",
scrollElement: scrollRef
});
return (
<div ref={scrollRef} className="overflow-auto h-screen">
<MediumFlexibleAppBar
title="Expanded Title"
scrollBehavior={scrollBehavior}
/>
<div className="h-[200vh]">Content...</div>
</div>
);
}
Best Practices
Do
- Use a Small App Bar for standard views with 1-3 primary actions.
- Use a Flexible App Bar for landing pages or media-heavy headers to create a sense of depth.
- Use the Bottom App Bar for mobile-first apps where thumb-reachability is a priority.
- Enable
enableFadingBlurwhen content scrolls under translucent headers or footers. - Keep the title clear and concise to avoid truncation on small screens.
Don't
- Don't put more than 3-4 icons in the actions area; use an overflow menu for secondary actions.
- Avoid using a Flexible App Bar if there isn't enough scrollable content to justify the collapse.
- Don't hide the App Bar if it contains critical navigation or search functionality that users need constantly.
Accessibility
- Roles: Automatically applies
role="banner"(top) orrole="contentinfo"(bottom). - Heading Level: Titles are rendered within appropriate heading levels (typically
h1orh2). - Focus: Interactive elements are reachable via
Tab. - Motion: Scroll transitions, search expansions, and backdrop blur intensities respect
prefers-reduced-motion.
API Reference
SmallAppBar
| Prop | Type | Default | Description |
|---|---|---|---|
title | ReactNode | — | View title. |
subtitle | ReactNode | — | Optional secondary text. |
titleAlignment | "start" | "center" | "start" | Alignment of title text. Center mode includes automatic 48px width symmetry spacer. |
navigationIcon | ReactNode | — | Leading navigation icon button. |
actions | ReactNode | — | Trailing action icons or AppBarRow. |
scrollBehavior | "pinned" | "enterAlways" | "pinned" | Scroll behavior mode. |
scrollElement | RefObject<HTMLElement> | — | Ref to scrollable container. |
enableFadingBlur | boolean | false | Enables linear gradient backdrop blur overlay. |
blurIntensity | number | 12 | Backdrop blur radius in pixels. |
blurHeight | number | string | "100%" | Gradient fade height or container height. |
colors | AppBarColors | — | Custom color overrides. |
SearchAppBar
| Prop | Type | Default | Description |
|---|---|---|---|
searchBarId | string | "search-bar" | Framer Motion layoutId for shared element transition with <SearchView>. |
searchPlaceholder | string | "Search" | Search input placeholder text. |
searchValue | string | — | Controlled search value. |
searchBarVariant | "filled" | "outlined" | "filled" | Visual style of search pill container. |
searchBarHeight | number | 56 | Search bar pill height in pixels (MD3 spec: 56dp). |
navigationIcon | ReactNode | — | Leading icon outside search bar. |
leadingSearchIcon | ReactNode | — | Icon inside search bar (defaults to search icon). |
trailingSearchActions | ReactNode | — | Action icons inside search bar (e.g. mic, camera). |
externalActions | ReactNode | — | Trailing elements outside search bar (e.g. avatar). |
scrollBehavior | "pinned" | "enterAlways" | "pinned" | Scroll behavior mode. |
scrollElement | RefObject<HTMLElement> | — | Ref to scrollable container. |
enableFadingBlur | boolean | false | Enables top linear gradient backdrop blur. |
blurIntensity | number | 12 | Backdrop blur radius in pixels. |
blurHeight | number | string | "100%" | Gradient fade height. |
colors | AppBarColors | — | Custom color overrides. |
FlexibleAppBar (Medium & Large)
| Prop | Type | Default | Description |
|---|---|---|---|
title | ReactNode | — | Main title (animates size on collapse). |
subtitle | ReactNode | — | Optional subtitle. |
titleAlignment | "start" | "center" | "start" | Headline alignment. |
headerContent | ReactNode | — | Additional content in expanded space (banner, chips, profile). |
navigationIcon | ReactNode | — | Leading navigation icon. |
actions | ReactNode | — | Trailing action icons. |
collapsedHeight | number | 64 | Collapsed height in pixels. |
expandedHeight | number | 112/136 (Med), 120/152 (Large) | Expanded initial height in pixels. |
scrollElement | RefObject<HTMLElement> | — | Ref to scrollable container. |
enableFadingBlur | boolean | false | Enables linear gradient backdrop blur overlay. |
blurIntensity | number | 12 | Backdrop blur radius in pixels. |
BottomAppBar
| Prop | Type | Default | Description |
|---|---|---|---|
actions | ReactNode | — | Leading action icon buttons. |
floatingActionButton | ReactNode | — | Optional FAB integrated into trailing end. |
scrollBehavior | "visible" | "hidden" | "visible" | Auto-hides on scroll down, reveals on scroll up when set to "hidden". |
scrollElement | RefObject<HTMLElement> | — | Ref to scrollable container. |
enableFadingBlur | boolean | false | Enables upward linear gradient backdrop blur. |
blurIntensity | number | 12 | Backdrop blur radius in pixels. |
FadingBlurMask
Standalone primitive component for custom fading edge backdrop blur overlays.
| Prop | Type | Default | Description |
|---|---|---|---|
direction | "top" | "bottom" | "both" | "top" | Gradient fade direction. |
blurIntensity | number | 12 | Backdrop blur radius in pixels. |
blurHeight | number | string | "100%" | Gradient fade height. |
color | string | var(--md-sys-color-surface) | Background color overlay tint. |