Repository navigation
feat(snackbar): update snackbar to Material Design 3 specification - #148
Conversation
🚀 Deploying Preview to Cloudflare 🚀Preview Deployments by commit
|
There was a problem hiding this comment.
📋 Review Summary
This pull request exports and integrates md-snackbar into the main entry bundle (all.js), updates the button inverse text colour token to inverse-primary, and significantly revamps the snackbar implementation to align with Material Design 3 specifications. The snackbar component now features Level 3 elevation, stacked layout support, auto-dismissal rules for non-actionable notifications, and improved accessibility attributes (role="status", aria-live="polite").
🔍 General Feedback
- Exporting
md-snackbarinall.jsand providing comprehensive documentation insnackbar/README.mdis a great addition for developers consuming the bundle. - The alignment with Material 3 snackbar guidelines (such as persistent actionable notifications and Level 3 elevation) is well-executed.
- Consider adding unit tests for the snackbar component (e.g. testing
snack()helper creation, event dispatch sequence, and auto-dismissal behaviour).
📊 Token Usage & Cost Efficiency
| Metric | Value |
|---|---|
| Input Tokens (uncached) | 41,149 |
| Input Tokens (cached) | 408,454 (⚡ 90.7% cached) |
| PR Comments History Tokens | 487 |
| Thinking / Reasoning Tokens | 26,822 |
| Output Tokens | 798 |
| Total Session Tokens | 477,710 |
| Cost (uncached input) | $0.0312 |
| Cost (cached input) | $0.0306 |
| Cost (thinking / reasoning) | $0.1006 |
| Cost (response output) | $0.0030 |
| Estimated Total Cost | $0.1654 |
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.
… and fallback color
There was a problem hiding this comment.
📋 Review Summary
This pull request completes the Material 3 Snackbar implementation by integrating Level 3 elevation, inverse colour tokens, stacked layouts, dismiss icon buttons, and transition lifecycle events. It also exports the snackbar module from all.js and provides comprehensive documentation and token mappings in snackbar/README.md.
✅ Resolved Items from Prior Reviews
- Updated the fallback colour for
--_label-text-coloron inverse text buttons to#d0bcffinbuttons/button.jsto match the M3 baseline inverse-primary token value. (buttons/button.js:739) - Updated the
snack()helper function insnackbar/snackbar.jsto automatically callsnackbar.close()when an action button is clicked. (snackbar/snackbar.js:46) - Updated
close()insnackbar/snackbar.jsto setthis._open = false, remove theopenattribute, and clear timers immediately to prevent state de-synchronisation during exit transitions. (snackbar/snackbar.js:388)
🔍 General Feedback
- The component now adheres closely to the Material Design 3 Snackbar specification, particularly around persistent actionable notifications versus auto-dismissing non-actionable alerts.
- Exporting both
snackandSnackBarfromall.jswhile preserving alphabetical sort order keeps the root bundle tidy and developer-friendly. - The helper function
snack()ensures that only one snackbar instance remains active at a time, avoiding notification collisions on screen.
📊 Token Usage & Cost Efficiency
| Metric | Value |
|---|---|
| Input Tokens (uncached) | 41,554 |
| Input Tokens (cached) | 408,454 (⚡ 90.6% cached) |
| PR Comments History Tokens | 1,031 |
| Thinking / Reasoning Tokens | 20,224 |
| Output Tokens | 830 |
| Total Session Tokens | 472,093 |
| Cost (uncached input) | $0.0319 |
| Cost (cached input) | $0.0306 |
| Cost (thinking / reasoning) | $0.0758 |
| Cost (response output) | $0.0031 |
| Estimated Total Cost | $0.1415 |
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.
…d close idempotency
There was a problem hiding this comment.
📋 Review Summary
This pull request refactors the Snackbar component to align with the Material Design 3 specification, introducing proper tokens for inverse surface styling, Level 3 elevation, stacked action layouts, and accessible ARIA attributes. It also enhances the programmatic snack() helper by ensuring action dismissals, single-instance coordination, and DOM cleanup on close, whilst updating all.js bundle exports.
✅ Resolved Items from Prior Reviews
- Updated the fallback token for
:host([color='text'].inverse)inbuttons/button.jsto#d0bcffto match the Material 3 inverse-primary baseline palette. (buttons/button.js:739) - Ensured clicking the action button in the
snack()helper invokessnackbar.close()to dismiss actionable snackbars. (snackbar/snackbar.js:46) - Fixed state desynchronisation by immediately setting
this._open = falseinclose()and clearing pending transition timers. (snackbar/snackbar.js:388) - Kept the
#snackbarcontainer in the DOM and drove entry/exit transitions declaratively via component state classes rather than direct DOM mutations. (snackbar/snackbar.js:358) - Added an
if (!this._open) returnguard inclose()to guarantee closing calls are idempotent. (snackbar/snackbar.js:413)
🔍 General Feedback
- The refactored
SnackBarimplementation cleanly adheres to the Material Design 3 specification, particularly regarding auto-dismiss rules (allowing non-actionable snackbars to auto-dismiss after 5s whilst keeping actionable snackbars persistent until interaction). - Cleaning up programmatic DOM nodes on the
closedevent insnack()is an excellent pattern that prevents memory and DOM leaks in single-page applications. - The component includes comprehensive accessibility features via
role="status",aria-live="polite", andaria-atomic="true".
📊 Token Usage & Cost Efficiency
| Metric | Value |
|---|---|
| Input Tokens (uncached) | 41,677 |
| Input Tokens (cached) | 408,454 (⚡ 90.4% cached) |
| PR Comments History Tokens | 1,792 |
| Thinking / Reasoning Tokens | 17,993 |
| Output Tokens | 1,325 |
| Total Session Tokens | 471,241 |
| Cost (uncached input) | $0.0326 |
| Cost (cached input) | $0.0306 |
| Cost (thinking / reasoning) | $0.0675 |
| Cost (response output) | $0.0050 |
| Estimated Total Cost | $0.1357 |
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 refactors the Material 3 Snackbar component and its documentation to align with official Material Design 3 specifications. It introduces Level 3 elevation, inverse-surface and inverse-primary tokens, single-instance coordination, persistent actionable snackbars, and declarative transition management. All previous review suggestions have been resolved and the component is now properly exported from all.js.
✅ Resolved Items from Prior Reviews
- Updated the fallback color for inverse text buttons to
#d0bcff(--md-sys-color-inverse-primary) and applied it across default, hover, focus, and pressed states. (buttons/button.js:739) - Added automatic dismissal of the snackbar when the action button is clicked. (
snackbar/snackbar.js:46) - Immediately set
this._open = falseupon callingclose()and managed animation timer handles to prevent state desynchronisation. (snackbar/snackbar.js:388) - Kept
#snackbarin the DOM and drove entrance and exit transitions declaratively via component state classes. (snackbar/snackbar.js:358) - Added an
if (!this._open) returnguard to makeclose()idempotent during ongoing close transitions. (snackbar/snackbar.js:413) - Updated README examples to explicitly specify
color="text"for action buttons in standard and stacked snackbar layouts. (snackbar/README.md:30) - Replaced
innerTextwithtextContentwhen creating action buttons programmatically. (snackbar/snackbar.js:45)
🔍 General Feedback
- The snackbar implementation now complies with Material Design 3 guidelines regarding persistent actionable snackbars, accessible ARIA status roles (
role="status",aria-live="polite"), and single-instance coordination. - Transitions are managed smoothly through declarative CSS classes without layout flashes or abrupt element mounting.
- Exporting
snackbar.jsinall.jsensures full bundle parity with the rest of the component suite.
📊 Token Usage & Cost Efficiency
| Metric | Value |
|---|---|
| Input Tokens (uncached) | 42,153 |
| Input Tokens (cached) | 408,454 (⚡ 90.0% cached) |
| PR Comments History Tokens | 3,046 |
| Thinking / Reasoning Tokens | 9,916 |
| Output Tokens | 599 |
| Total Session Tokens | 464,168 |
| Cost (uncached input) | $0.0339 |
| Cost (cached input) | $0.0306 |
| Cost (thinking / reasoning) | $0.0372 |
| Cost (response output) | $0.0022 |
| Estimated Total Cost | $0.1040 |
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.
Summary
Updates
<md-snackbar>and thesnack()helper function to comply with the Material Design 3 Snackbar Specification.Key Changes
text-align: centerwith start alignment (text-align: start) and 16px start margin.<md-elevation>with Level 3 elevation (3dp shadow).--md-snackbar-container-color,--md-snackbar-supporting-text-color,--md-snackbar-action-label-text-color,--md-snackbar-icon-color,--md-snackbar-container-elevation, and--md-snackbar-container-shape.min-height: 48pxwith balanced padding: single-line renders at 48px, two-line expands to 68px.stackedproperty/attribute).--md-sys-color-inverse-primary.snack()now uses an accessible<md-icon-button>witharia-label="Dismiss".role="status",aria-live="polite", andaria-atomic="true".open,opened,close,closed).snackbar.jsinall.jsand updatedsnackbar/README.md.Verification
npx vite build(clean build with 0 errors).prettier.all.js,snackbar/snackbar.js, andbuttons/button.jsin Node.js.