feat(app-bar): implement Material 3 app bar specification (#62) - #131
Conversation
bc78a85 to
3aad6a8
Compare
There was a problem hiding this comment.
📋 Review Summary
This pull request completes and expands the Material Design 3 Top App Bar component (md-app-bar), upgrading it from a work-in-progress search placeholder into a full specification-compliant implementation. It introduces support for Small, Centre-Aligned, Medium Flexible, Large Flexible, and Search variants with automatic scroll-driven elevation and collapse behaviours. Comprehensive documentation and a dedicated interactive demo page have also been added, alongside exporting the component from the root bundle.
🔍 General Feedback
- Excellent implementation of the Material Design 3 Top App Bar specification. The inclusion of flexible variants with scroll-responsive collapse and elevation adds significant expressive value to the library.
- The backwards-compatible fallback slots ('leading-icon', 'trailing-icon', 'title') alongside standard Material Design 3 slots ('navigation-icon', 'action-items', 'headline') ensure existing usages will not break.
- The new standalone demo page (
demo/app-bar-demo.html) is comprehensive and clearly demonstrates all five variants and interactive scroll collapse simulation.
📊 Token Usage & Cost Efficiency
| Metric | Value |
|---|---|
| Input Tokens (uncached) | 40,167 |
| Input Tokens (cached) | 346,224 (⚡ 89.6% cached) |
| Thinking / Reasoning Tokens | 15,667 |
| Output Tokens | 1,037 |
| Total Session Tokens | 403,095 |
| Cost (uncached input) | $0.0301 |
| Cost (cached input) | $0.0260 |
| Cost (thinking / reasoning) | $0.0588 |
| Cost (response output) | $0.0039 |
| Estimated Total Cost | $0.1187 |
Gemini 3.8 Flash: introductory rate $0.75/$3.75 per 1M applied; reverts to $1.5/$7.5 after 2026-12-31.
Gemini 3.8 Flash: standard tier; batch and flex are half again, priority is higher.
Cache reads are priced here, but context-cache STORAGE, where the model charges for it separately per token-hour, is not included, so the figure can run slightly low.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
material | ed7de09 | Commit Preview URL Branch Preview URL |
Sep 16 2026, 09:34 PM |
…bbling, and shadow DOM scroll targets
There was a problem hiding this comment.
📋 Review Summary
This pull request expands <md-app-bar> into a full Material Design 3 top app bar implementation supporting small, center-aligned, medium flexible, large flexible, and search variants with scroll-responsive elevation and collapsing behaviour. It also exports the component in the main bundle, updates documentation, and adds dedicated demo pages with interactive controls.
✅ Resolved Items from Prior Reviews
- Updated
_getScrollTargetElementto querythis.getRootNode()first so scroll containers inside Shadow DOM boundaries are properly resolved. (app/bar.js:153) - Removed the redundant
new CustomEvent('input')dispatch in_handleSearchInputso consumers do not receive duplicate input events from the composed text field. (app/bar.js:197) - Addressed duplicate
<slot name="headline">definitions by conditionally rendering the slot in the flexible row when expanded and in the top row when collapsed. (app/bar.js:292)
🔍 General Feedback
- The new app bar implementation cleanly covers the Material Design 3 specification across small, center-aligned, flexible, and search variants with smooth CSS transitions.
- Comprehensive documentation and interactive demonstrations in
demo/app-bar-demo.htmlmake the new features and scroll-driven behaviour easy to test and adopt.
📊 Token Usage & Cost Efficiency
| Metric | Value |
|---|---|
| Input Tokens (uncached) | 40,321 |
| Input Tokens (cached) | 346,224 (⚡ 89.3% cached) |
| PR Comments History Tokens | 1,054 |
| Thinking / Reasoning Tokens | 6,525 |
| Output Tokens | 772 |
| Total Session Tokens | 394,896 |
| Cost (uncached input) | $0.0310 |
| Cost (cached input) | $0.0260 |
| Cost (thinking / reasoning) | $0.0245 |
| Cost (response output) | $0.0029 |
| Estimated Total Cost | $0.0844 |
Gemini 3.8 Flash: introductory rate $0.75/$3.75 per 1M applied; reverts to $1.5/$7.5 after 2026-12-31.
Gemini 3.8 Flash: standard tier; batch and flex are half again, priority is higher.
Cache reads are priced here, but context-cache STORAGE, where the model charges for it separately per token-hour, is not included, so the figure can run slightly low.
There was a problem hiding this comment.
📋 Review Summary
This pull request completes the Material Design 3 Top App Bar implementation in <md-app-bar>, upgrading it from a prototype search bar into a full-featured component supporting small, center-aligned, medium-flexible, large-flexible, and search variants. It adds scroll-driven elevation and collapse behaviour, comprehensive slot aliasing, and backwards compatibility for existing consumers. All previous review findings have been resolved, and a dedicated demo page and documentation have been included.
✅ Resolved Items from Prior Reviews
- Resolved: Target element resolution in _getScrollTargetElement now queries this.getRootNode() first to support Shadow DOM encapsulation. (
app/bar.js:153) - Resolved: Removed redundant CustomEvent('input') redispatch in _handleSearchInput since native input events already bubble and compose across shadow boundaries. (
app/bar.js:197) - Resolved: Corrected duplicate slot name='headline' assignment between the top and flexible rows by conditionally rendering the slot in the active row and fallback text in the inactive row. (
app/bar.js:292) - Resolved: Click listener for clearing search input was moved from the parent slot to the default clear icon element to prevent clearing when custom actions are slotted. (
app/bar.js:346) - Resolved: Replaced physical directional margin and padding in .md3-app-bar__trailing with CSS logical properties (margin-inline-start, padding-inline-end) for RTL compatibility. (
app/bar.js:439)
🔍 General Feedback
- Excellent work transforming the prototype into a compliant Material Design 3 Top App Bar implementation with full variant support and scroll-driven behaviour.
- The backwards-compatible fallback slots (e.g. slot='navigation-icon' falling back to slot='leading-icon') ensure that existing integrations continue to function smoothly without regressions.
- The new standalone demo page (demo/app-bar-demo.html) provides clear, practical examples of all variants and interactive behaviours.
📊 Token Usage & Cost Efficiency
| Metric | Value |
|---|---|
| Input Tokens (uncached) | 40,296 |
| Input Tokens (cached) | 346,224 (⚡ 89.3% cached) |
| PR Comments History Tokens | 1,387 |
| Thinking / Reasoning Tokens | 15,922 |
| Output Tokens | 984 |
| Total Session Tokens | 404,813 |
| Cost (uncached input) | $0.0313 |
| Cost (cached input) | $0.0260 |
| Cost (thinking / reasoning) | $0.0597 |
| Cost (response output) | $0.0037 |
| Estimated Total Cost | $0.1206 |
Gemini 3.8 Flash: introductory rate $0.75/$3.75 per 1M applied; reverts to $1.5/$7.5 after 2026-12-31.
Gemini 3.8 Flash: standard tier; batch and flex are half again, priority is higher.
Cache reads are priced here, but context-cache STORAGE, where the model charges for it separately per token-hour, is not included, so the figure can run slightly low.
There was a problem hiding this comment.
📋 Review Summary
This pull request completes the full Material Design 3 Top App Bar specification within <md-app-bar>. It introduces support for Small, Center-Aligned, Medium Flexible, Large Flexible, and Search app bars with elevation, responsive scroll collapse, and comprehensive documentation and demo coverage. All previously raised feedback items regarding slot assignment, event propagation, DOM encapsulation, and CSS logical properties have been cleanly addressed.
✅ Resolved Items from Prior Reviews
- Resolved Shadow DOM scoping when resolving
scrollTargetby checkingthis.getRootNode()?.querySelectorbefore falling back todocument.querySelector. (app/bar.js:163) - Avoided duplicate
inputevent dispatch in_handleSearchInputby relying on the native composed event frommd-text-field. (app/bar.js:207) - Resolved Shadow DOM duplicate slot assignment by conditionally rendering
<slot name="headline">in the active row (top row when collapsed, flexible row when expanded). (app/bar.js:302) - Moved
@click=${this._clearSearch}from<slot name="trailing-icon-text-field">to the fallback clear icon so custom slotted actions are not inadvertently hijacked. (app/bar.js:346) - Replaced physical CSS directional properties with logical properties (
margin-inline-startandpadding-inline-end) for correct RTL support. (app/bar.js:439) - Added
@slotchangehandling (_handleSubtitleSlotChange) to support custom slotted subtitle markup when thesubtitleattribute is omitted. (app/bar.js:270) - Used
padding-inline: 0;on.md3-app-bar--center-alignedheadline container for CSS logical property consistency. (app/bar.js:485)
🔍 General Feedback
- Excellent implementation of the Material 3 Top App Bar specification. Supporting all variants (Small, Center-Aligned, Medium Flexible, Large Flexible, and Search) along with configurable scroll collapse behaviors makes this component versatile and production-ready.
- The backwards compatibility for slot aliases (
leading-icon->navigation-icon,trailing-icon->action-items,title->headline) ensures existing consumers are not broken by the spec alignment. - The dedicated
demo/app-bar-demo.htmldemo page provides a clear, interactive showcase of all variants and scroll-driven behaviors.
📊 Token Usage & Cost Efficiency
| Metric | Value |
|---|---|
| Input Tokens (uncached) | 40,675 |
| Input Tokens (cached) | 346,224 (⚡ 89.1% cached) |
| PR Comments History Tokens | 1,739 |
| Thinking / Reasoning Tokens | 8,377 |
| Output Tokens | 699 |
| Total Session Tokens | 397,714 |
| Cost (uncached input) | $0.0318 |
| Cost (cached input) | $0.0260 |
| Cost (thinking / reasoning) | $0.0314 |
| Cost (response output) | $0.0026 |
| Estimated Total Cost | $0.0918 |
Gemini 3.8 Flash: introductory rate $0.75/$3.75 per 1M applied; reverts to $1.5/$7.5 after 2026-12-31.
Gemini 3.8 Flash: standard tier; batch and flex are half again, priority is higher.
Cache reads are priced here, but context-cache STORAGE, where the model charges for it separately per token-hour, is not included, so the figure can run slightly low.
There was a problem hiding this comment.
📋 Review Summary
This pull request completes the implementation of the Material Design 3 Top App Bar component across small, center-aligned, medium-flexible, large-flexible, and search variants with scroll-driven elevation and collapse behaviour. It also exports the component in all.js, improves the navigation rail with reflected attributes and change events to support responsive mobile drawers, and adds comprehensive documentation alongside dedicated demos. All previous review findings have been cleanly resolved.
✅ Resolved Items from Prior Reviews
- Resolved Shadow DOM duplicate
<slot name="headline">collision by rendering the headline slot conditionally in either the flexible row or the top row depending on the collapsed state. (app/bar.js:302) - Removed duplicate
inputevent dispatch in_handleSearchInput, avoiding redundant event notifications since<md-text-field>already emits composed bubbling input events. (app/bar.js:207) - Added Shadow DOM boundary traversal in
_getScrollTargetElement()usingthis.getRootNode()?.querySelector()before falling back todocument.querySelector(). (app/bar.js:163) - Moved
@clickclear handler from<slot name="trailing-icon-text-field">directly to the fallback clear icon so custom slotted trailing icons do not inadvertently clear the field. (app/bar.js:346) - Replaced physical CSS directional properties (
margin-left,padding-right) in.md3-app-bar__trailingwith CSS logical properties (margin-inline-start,padding-inline-end) for proper RTL support. (app/bar.js:439) - Added assigned node observation via
_handleSubtitleSlotChangeon<slot name="subtitle">so custom slotted markup renders cleanly without requiring thesubtitleattribute string. (app/bar.js:270) - Updated
.center-alignedheadline container styling to usepadding-inline: 0;consistently with surrounding logical properties. (app/bar.js:485)
🔍 General Feedback
- All previously identified review items regarding slot distribution, event redispatching, and CSS logical properties have been resolved cleanly.
- The responsive off-canvas modal drawer implementation in demo/index.html and demo/css/styles.css provides an intuitive mobile navigation pattern alongside the bottom navigation bar.
- The new demo/app-bar-demo.html and updated app/README.md offer clear, thorough documentation covering all M3 top app bar specifications and scroll behaviours.
📊 Token Usage & Cost Efficiency
| Metric | Value |
|---|---|
| Input Tokens (uncached) | 49,320 |
| Input Tokens (cached) | 354,702 (⚡ 87.4% cached) |
| PR Comments History Tokens | 1,737 |
| Thinking / Reasoning Tokens | 17,742 |
| Output Tokens | 703 |
| Total Session Tokens | 424,204 |
| Cost (uncached input) | $0.0383 |
| Cost (cached input) | $0.0266 |
| Cost (thinking / reasoning) | $0.0665 |
| Cost (response output) | $0.0026 |
| Estimated Total Cost | $0.1341 |
Gemini 3.8 Flash: introductory rate $0.75/$3.75 per 1M applied; reverts to $1.5/$7.5 after 2026-12-31.
Gemini 3.8 Flash: standard tier; batch and flex are half again, priority is higher.
Cache reads are priced here, but context-cache STORAGE, where the model charges for it separately per token-hour, is not included, so the figure can run slightly low.
There was a problem hiding this comment.
📋 Review Summary
This pull request completes the full implementation of the Material Design 3 Top App Bar component (md-app-bar), supporting all five specification variants: Small, Center-Aligned, Medium Flexible, Large Flexible, and Search. It integrates scroll-driven elevation and collapse transitions, robust slot delegation with backwards-compatible aliases, a dedicated demonstration page (app-bar-demo.html), and cohesive mobile modal drawer navigation coordinated with md-nav-rail. All previously flagged review items have been resolved.
✅ Resolved Items from Prior Reviews
- Addressed Shadow DOM encapsulation for
scrollTargetby queryingthis.getRootNode()?.querySelectorbefore falling back todocument.querySelector. (app/bar.js:163) - Removed duplicate
inputevent dispatch in_handleSearchInputto avoid redundant event bubbling. (app/bar.js:207) - Resolved Shadow DOM duplicate
<slot name="headline">assignment conflict by conditionally rendering the slot in the flexible row when expanded and in the top row when collapsed. (app/bar.js:302) - Relocated the
@clickclear handler from the slot element to the clear<md-icon>so custom slotted trailing icons are not inadvertently triggered. (app/bar.js:346) - Replaced physical CSS directional properties (
margin-left,padding-right) with CSS logical properties (margin-inline-start,padding-inline-end) for proper RTL support. (app/bar.js:439) - Added slotchange listener (
_handleSubtitleSlotChange) and_hasSlottedSubtitlestate to support slotted subtitle markup without requiring thesubtitleattribute. (app/bar.js:270) - Replaced
padding-left: 0; padding-right: 0;withpadding-inline: 0;for consistency with CSS logical property conventions. (app/bar.js:485)
🔍 General Feedback
- The implementation of
md-app-barcomprehensively satisfies the Material Design 3 Top App Bar specification across small, center-aligned, medium-flexible, large-flexible, and search variants. - The scroll-driven elevation and collapsing behaviour (
scroll-behavior="collapse"andscroll-target) works smoothly for both window and custom scrollable container selectors. - The responsive drawer pattern in
demo/index.htmlanddemo/css/styles.cssis well integrated, providing smooth mobile modal transitions, backdrop scrim click dismissal, and escape key handling. - Exporting
./app/bar.jsfromall.jsand updatingapp/README.mdprovides complete discoverability and documentation for library consumers.
📊 Token Usage & Cost Efficiency
| Metric | Value |
|---|---|
| Input Tokens (uncached) | 50,596 |
| Input Tokens (cached) | 354,702 (⚡ 87.1% cached) |
| PR Comments History Tokens | 1,737 |
| Thinking / Reasoning Tokens | 15,731 |
| Output Tokens | 753 |
| Total Session Tokens | 423,519 |
| Cost (uncached input) | $0.0392 |
| Cost (cached input) | $0.0266 |
| Cost (thinking / reasoning) | $0.0590 |
| Cost (response output) | $0.0028 |
| Estimated Total Cost | $0.1277 |
Gemini 3.8 Flash: introductory rate $0.75/$3.75 per 1M applied; reverts to $1.5/$7.5 after 2026-12-31.
Gemini 3.8 Flash: standard tier; batch and flex are half again, priority is higher.
Cache reads are priced here, but context-cache STORAGE, where the model charges for it separately per token-hour, is not included, so the figure can run slightly low.
Resolves #62
Resolves #63
Resolves #64
Resolves #65
Resolves #66
Overview
Implements the full Material Design 3 App Bar specification in
<md-app-bar>.Changes Included:
type="small", default): Standard 64px height with left-aligned headline and optional subtitle.type="center-aligned"orcenter-aligned): 64px height with headline and subtitle centered between leading and trailing action items.type="medium-flexible"): Two-row flexible layout (112px–136px) with prominent headline, smoothly collapsing down to 64px on scroll.type="large-flexible"): Two-row flexible layout (120px–152px) with prominent headline, smoothly collapsing down to 64px on scroll.type="search"): Integrated search bar with clear button, input/change/search events, and full backwards compatibility.scroll-behavior="scroll"orscroll-behavior="collapse") with configurablescroll-target(windowor custom container).<md-elevation>to elevate to level 2 and transition container color tovar(--md-sys-color-surface-container)when scrolled.all.js.app/README.mdwith complete API tables, slots, variants, and examples.demo/app-bar-demo.htmlwith interactive examples and live scroll container.demo/index.htmlwithmd-app-barand link to the app bar demo.