Skip to content

feat: implement Toolbar component - #5043

Open
k0ndee wants to merge 4 commits into
callstack:mainfrom
k0ndee:@k0ndee/toolbar
Open

feat: implement Toolbar component#5043
k0ndee wants to merge 4 commits into
callstack:mainfrom
k0ndee:@k0ndee/toolbar

Conversation

@k0ndee

@k0ndee k0ndee commented Aug 11, 2026

Copy link
Copy Markdown

Motivation

Introduce a new Toolbar component implementing the Material Design 3 toolbars spec. Reuse theme tokens (shape, color roles, elevation) and follow the same component-tokens pattern as FAB / Checkbox.

Spec re-check (M3 toolbars)

Re-checked the M3 toolbars specs:

  • Two variants: floating (self-positioned pill, corner.full, elevation level 3) and docked (full-width bar pinned to the bottom edge, corner.none, no elevation, extends into safe-area insets).
  • floating supports horizontal/vertical orientation; docked is always horizontal per spec.
  • Default (standard) colors: container/unselected-button surfaceContainer, icon/label onSurfaceVariant, selected button secondaryContainer with onSecondaryFixedVariant (light) / onSecondaryContainer (dark) icon.
  • vibrant colorScheme: container/unselected-button primaryContainer, icon/label onPrimaryFixedVariant (light) / onPrimaryContainer (dark), selected button falls back to surfaceContainer with onSurface icon.
  • Direct IconButton/Button children are auto-recolored to match colorScheme unless they already set their own color (a mode on either opts them out in favor of their own mode-based coloring).

Changes

Toolbar / tokens / utils

  • New src/components/Toolbar/{Toolbar.tsx,tokens.ts,utils.ts}: variant (floating/docked), orientation (horizontal/vertical, floating-only), colorScheme (standard/vibrant), containerColor override, style/contentContainerStyle, testID, aria-label, theme, ref
  • Container shape/elevation/spacing resolved from ToolbarTokens; docked extends into safe-area insets via margin outside Surface's box, keeping the 64dp icon band untouched
  • withToolbarChildColors auto-recolors mode-less IconButton/Button children per colorScheme, without touching children that already set their own color/mode
  • Exported from src/index.tsx

Example / docs / tests

  • Example screen (ToolbarExample.tsx) covering both variants, both orientations, both color schemes, over a scrollable list
  • Docs page + prop table + theme colors table; screenshots for floating (horizontal/vertical) and docked, each in standard/vibrant
  • Unit tests (Toolbar.test.tsx) covering shape/elevation per variant, color resolution across light/dark themes for both color schemes, and child auto-recoloring behavior

Scope note

Per Satyajit Sahoo's recommendation, this implementation is split into a series of PRs for easier review, rather than landing as one large change. This PR is PR 1 of the series:

  • PR 1 (this PR) — Floating + docked variant, static (without animation, no FAB pairing), colorScheme standard/vibrant. Component, tokens, tests, docs, example.
  • PR 2 — Show/hide animation (offscreen slide + spring), generic scroll shared-value primitive.
  • PR 3 — FAB pairing, FAB/key-action collapse on scroll.
  • PR 4 — Trailing-edge overflow menu.

Related issue

Related to #4988

Test plan

  • yarn typecheck / yarn lint / Toolbar unit tests
  • Full unit test suite green
  • Manually verified in the example app: floating (horizontal/vertical) and docked, standard/vibrant, over scrolling content, light and dark themes

Visual verification

standard vibrant
floating, horizontal floating-h-standard floating-h-vibrant
floating, vertical floating-v-standard floating-v-vibrant
docked docked-standard docked-vibrant

Docs screenshots: docs/public/screenshots/toolbar_*.png.

@k0ndee k0ndee changed the title @k0ndee/toolbar feat: implement Toolbar component Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant