Skip to content

chore: Adds internal style api v2 to flashbar - #5206

Draft
vvaliyev wants to merge 1 commit into
mainfrom
style-v2-flashbar
Draft

vvaliyev wants to merge 1 commit into
mainfrom
style-v2-flashbar

Conversation

@vvaliyev

@vvaliyev vvaliyev commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

Description

Adds an internal styleClassNames prop (Style API v2) to Flashbar. The prop is not on the public FlashbarProps interface; it is typed on InternalFlashbarProps for core-system consumers.

Four slots:

  • item: div.flash, one per message, in the flat list and in the expanded stack. In the collapsed stack the class is also applied to the placeholder li.flash elements, so the peeking edges take the item's colours. Accepts a class name or a function of the item, string | ({ item }) => string, so each type can take its own class. Properties: color, background, border, border-radius, box-shadow (also replaces the shadow of the collapsed stack), padding. Tokens: --awsui-style-focus-ring-color, --awsui-style-focus-ring-width, --awsui-style-focus-ring-radius, carried to the ring on div.flash-focus-container::before.
  • icon: div.flash-icon, the status icon or the spinner for loading. Property: color. Icon and Spinner use currentColor, so the consumer colour reaches both.
  • dismissButton: forwards to Button.root through styleClassNames={{ root }} on the dismiss InternalButton. Rendered for dismissible items. Documented with docs-forward, no mixin of its own.
  • notificationBar: div.notification-bar, the bar under the stacked messages that expands and collapses the stack. Rendered for stackItems with more than one message; :hover and :active cover the interaction states. Properties: color, background, border, border-radius, box-shadow, padding. Tokens: the three focus-ring tokens, carried to the ring on button.button::before.

The docs() calls carry the slot descriptions and the box-shadow description, so the generated Style API docs match the tracker section. The focus-ring tokens are registered once, in styles.scss, for both slots.

Two changes to the component's own CSS:

  • The bar's .header, .item-count and .button use color: inherit instead of $color-text-notification-stack-bar. The bar already sets that colour on itself, so default rendering is unchanged. The v1 key style.notificationBar.root.color (default, hover, active) now takes effect; it was a no-op before. The Flashbar style-custom dev page sets this key, so its VR baseline changes (bar text moves from white to the page's neutral10).
  • The focus rings of the item and of the bar's toggle button are composed through the shared style-api.focus-highlight mixin from the width and colour custom properties, each with its design-token fallback. The --awsui-style-focus-ring-box-shadow custom property is no longer declared or read in this component. In the console build this changes the CSS text of the two box-shadow declarations and removes the two custom property declarations; the computed ring is identical because the same v1 custom properties and fallbacks are read.

The existing v1 Style API (style prop, style.tsx, inline custom properties) is otherwise unchanged.

Dev page: pages/flashbar/style-api-v2.page.tsx with three permutations through the generated mixins (flashbar.item, flashbar.icon, flashbar.notificationBar, button.root): a dismissible item with every row, the three focus-ring tokens, the icon and the dismiss button; the item callback with one class per type plus a loading item; a stacked flashbar with the callback on the placeholders and the notification bar with every row, :hover and :active.

The style-docs snapshot is not regenerated here; one follow-up PR regenerates it for all components. The dev page is not registered in the VR suite yet; one follow-up PR registers all style-api-v2 pages.

Tracker section: P3d34KdbCd6o.

How has this been tested?

  • npm run build passes. lib/components-definitions/style-api-doc/flashbar.json carries the four slots with the slot descriptions and the box-shadow description. The compiled CSS registers each focus-ring @property once and contains no --awsui-style-focus-ring-box-shadow.
  • npx jest -c jest.unit.config.js src/flashbar: 14 suites, 226 tests pass. src/flashbar/__tests__/style-api.test.tsx covers: each slot class lands on its element through the test-utils finders and unknown keys are ignored; the item callback resolves for the full item and for the collapsed placeholders of a stacked flashbar, and the notification bar class lands; the prop does not leak to the DOM.
  • npx prettier --check, npx stylelint, npx eslint pass on the changed files.
  • Console build: compiled the component's stylesheet with the console system for main and for this branch and diffed them. Apart from the hashed class names, the differences are color: inherit on the bar's text elements, the two removed --awsui-style-focus-ring-box-shadow declarations, and the two box-shadow declarations of the focus rings now composed from the width and colour custom properties with the same fallbacks.
  • Dev page checked in headless Chrome: every row is applied on div.flash, on the placeholder li.flash elements and on div.notification-bar; the bar's header and button take the consumer colour; the focus rings of the item, the dismiss button and the bar's toggle button take the consumer tokens; axe reports no violations.
  • Visual regression runs in CI. Expected: the Flashbar style-custom page changes (bar text colour, see above); no other page should change.
@codecov

codecov Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.76%. Comparing base (00e5e24) to head (281ba31).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5206      +/-   ##
==========================================
+ Coverage   97.74%   97.76%   +0.01%     
==========================================
  Files        1000     1003       +3     
  Lines       32346    32552     +206     
  Branches    11965    12095     +130     
==========================================
+ Hits        31616    31823     +207     
+ Misses        685      684       -1     
  Partials       45       45              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The focus-ring example cannot be exercised by keyboard because its focus container has tabIndex={-1} and the static, non-dismissible item has no other focus trigger.

1 open issue
What changed in this PR

Adds internal Style API v2 support to Flashbar, allowing core-system consumers to customize message items and stacked notifications without adding props to the public interface.

Changes:

  • Adds four styling slots: item, icon, dismissButton, and notificationBar, including per-item callbacks.
  • Integrates focus-ring tokens and notification-bar color inheritance.
  • Adds slot-forwarding tests and a styled demo page.
File Description
src/​flashbar/​styles.scss Declares item and icon slots, dismiss-button forwarding, and item focus-ring tokens.
src/​flashbar/​non-collapsible-flashbar.tsx Resolves and forwards styling classes to individual messages.
src/​flashbar/​internal-interfaces.ts Defines the internal styling-slot interface.
src/​flashbar/​flash.tsx Applies classes to message elements and dismiss buttons.
src/​flashbar/​collapsible.scss Adds notification-bar styling tokens and color inheritance.
src/​flashbar/​collapsible-flashbar.tsx Applies classes to stacked messages, placeholders, and the notification bar.
src/​flashbar/​__tests__/​style-api.test.tsx Tests class forwarding, callbacks, unknown keys, and DOM prop filtering.
pages/​flashbar/​style-api-v2.page.tsx Demonstrates styling slots and focus-ring customization.
pages/​flashbar/​style-api-v2.page.scss Defines demo styles using generated styling mixins.

Review effort: Balanced

Comment thread pages/flashbar/style-api-v2.page.tsx Resolved

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Outstanding review findings call for prefixing the internal prop with __ and removing decorative containers and subtitles from the dev-page examples.

2 open issues
1 resolved since last review

Review effort: Balanced

Comment on lines +29 to +32
<div>
<Box variant="awsui-key-label" margin={{ bottom: 'xs' }}>
{label}
</Box>
}

export type InternalFlashbarProps = FlashbarProps &
InternalBaseComponentProps & { styleClassNames?: FlashbarStyleClassNames };

This branch was successfully deployed

3 active deployments
dev-pages-react18 — 281ba310 Deployed Oct 30, 2026 by vvaliyev via deploy (React 18) / deploy #3059
dev-pages-react16 — 281ba310 Deployed Oct 30, 2026 by vvaliyev via deploy (React 16) / deploy #3059
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants