Skip to content

bugfix(toast): raise the toast to the notification z-index tier - #1188

Merged
bert-e merged 2 commits into
development/1.0from
bugfix/CUI-toast-anchoring
Aug 27, 2026
Merged

bugfix(toast): raise the toast to the notification z-index tier#1188
bert-e merged 2 commits into
development/1.0from
bugfix/CUI-toast-anchoring

Conversation

@JeanMarcMilletScality

@JeanMarcMilletScality JeanMarcMilletScality commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

TL;DR

Toast rendered position: fixed with no z-index at all, so a toast raised from inside a modal was painted underneath it and never seen. It now uses the theme's notification tier, as its sibling Notifications component already does.

Context

Reported as a toast going missing when a host embeds an application in a box narrower than the viewport. Two separate defects were in play there, and only one belongs to this library.

Approach

Symptom Cause Fixed here
Toast painted under a modal no z-index at all — it painted in DOM order against a modal at 8500 yes
Toast sits outside the application's box position: fixed resolves against the viewport, which is not the box the application was given no — see below

The second one cannot be fixed from inside Toast. A fixed element resolves its offsets against its nearest containing-block ancestor, and contain: layout on that ancestor is what redirects them — but a component cannot style its own ancestor, and no element in this library reliably sits at the application's boundary. Measured: in a 1440px viewport where the application's box ends at 870, a toast at top: 3rem; right: 1rem lands at 1076→1426 with nothing declared and at 506→856 once the box declares contain: layout, inset preserved. That one declaration also covers Notifications, which has the same position: fixed and the same tier — another reason it belongs on the box rather than inside one component.

So the requirement is documented instead: stories/toast.stories.tsx gains a component-level note in the autodocs, stating that offsets resolve against the viewport and that whoever owns the box has to declare contain: layout.

Review focus

  • 🟡 src/lib/components/toast/Toast.component.tsxToast — the toast now paints above modals (notification 9000 > modal 8500). Intended, but it is a visible ordering change for any flow that currently shows a modal over a toast. zIndex sits before the style spread, so a caller-supplied style can still override it.
  • CLAUDE.md — records the existing one-test-file-per-module convention. No code impact.

How to test

  1. Open a Toast while a Modal is open. Before this change the toast was hidden behind the modal; now it paints above it.
  2. Pass an explicit style={{ zIndex: … }} and confirm it still wins.
  3. npm run storybookComponents / Feedback / Toast → the docs tab carries the anchoring note at the top.

Follow-up

Anchoring is fixed where the box is owned, outside this library. This PR only stops the toast being painted under a modal, and records the contract.

What changed

Two lines in Toast.component.tsx: the zIndex import and zIndex: zIndex.notification in the inline style. Eight lines in stories/toast.stories.tsx for the autodocs note — attached at component level rather than to a story, because ToastWithProgressBar spreads SimpleToast and a story-level note would have leaked onto it.

Deliberately not here: no opt-out prop, since the tier already exists in the theme and the sibling component already uses it; no test, because asserting a z-index value would assert CSS rather than behaviour; and no story for the anchoring requirement — a demo would have to invent an application and a panel to show a consumer-side CSS declaration, which reads as though the component offered a containment mode.

@bert-e

bert-e commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Hello jeanmarcmilletscality,

My role is to assist you with the merge of this
pull request. Please type @bert-e help to get information
on this process, or consult the user documentation.

Available options
name description privileged authored
/after_pull_request Wait for the given pull request id to be merged before continuing with the current one.
/bypass_author_approval Bypass the pull request author's approval
/bypass_build_status Bypass the build and test status
/bypass_commit_size Bypass the check on the size of the changeset TBA
/bypass_incompatible_branch Bypass the check on the source branch prefix
/bypass_jira_check Bypass the Jira issue check
/bypass_peer_approval Bypass the pull request peers' approval
/bypass_leader_approval Bypass the pull request leaders' approval
/approve Instruct Bert-E that the author has approved the pull request. ✍️
/create_pull_requests Allow the creation of integration pull requests.
/create_integration_branches Allow the creation of integration branches.
/no_octopus Prevent Wall-E from doing any octopus merge and use multiple consecutive merge instead
/unanimity Change review acceptance criteria from one reviewer at least to all reviewers
/wait Instruct Bert-E not to run until further notice.
Available commands
name description privileged
/help Print Bert-E's manual in the pull request.
/status Print Bert-E's current status in the pull request.
/clear Remove all comments from Bert-E from the history TBA
/retry Re-start a fresh build TBA
/build Re-start a fresh build TBA
/force_reset Delete integration branches & pull requests, and restart merge process from the beginning.
/reset Try to remove integration branches unless there are commits on them which do not appear on the source branch.

Status report is not available.

@bert-e

bert-e commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Waiting for approval

The following approvals are needed before I can proceed with the merge:

  • the author

  • one peer

Peer approvals must include at least 1 approval from the following list:

aria-labelledby={`${status}_toast`}
style={{
position: 'fixed',
zIndex: zIndex.notification,

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.

The PR description says toastAnchoring.ts is new and Toast.component.tsx gains a useContainWithinParent hook call plus a typed ref — but neither the file nor the hook call appear in this diff. The only component change here is adding zIndex.

Without useContainWithinParent, the toast does not automatically stay inside the parent's box. The ToastBesideAPanel story shows the fix requires the consumer to add contain: layout on the ancestor, which is a different contract from what the description promises. Either the file was not committed, or the description needs to be updated to match what the PR actually delivers.

@JeanMarcMilletScality JeanMarcMilletScality changed the title Toast: keep the toast inside the application's box, not the browser's bugfix(toast): raise the toast to the notification z-index tier Aug 27, 2026
The toast rendered `position: fixed` with no `z-index` at all, so it painted in
DOM order against whatever surrounded it. A toast raised from inside a modal was
the visible consequence: modals render through a body portal at 8500, so the
toast was painted underneath and never seen. The theme already reserves
`notification` (9000) above that tier, and the sibling Notifications component
already applies it — the toast was the only member of the family that did not.

Anchoring is a separate matter and stays with the host. A fixed-position toast
resolves its offsets against the viewport, which is not always the box the
application was given, and only the element that owns that box can turn it into
a containing block for fixed descendants (`contain: layout`). A component cannot
reach its own ancestor, so this is recorded as a contract note in the component
documentation rather than implemented here.
Two names for one component's tests (`Modal.test.tsx` and
`Modal.component.test.tsx`) both pass CI, so nothing flags the split and the
next contributor ends up testing the same component in two places. 32 of the 42
existing test files already mirror their source filename; write that down.
@JeanMarcMilletScality
JeanMarcMilletScality marked this pull request as ready for review August 27, 2026 10:33
@bert-e

bert-e commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Waiting for approval

The following approvals are needed before I can proceed with the merge:

  • the author

  • one peer

Peer approvals must include at least 1 approval from the following list:

@JeanMarcMilletScality

Copy link
Copy Markdown
Contributor Author

/approve

@bert-e

bert-e commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

In the queue

The changeset has received all authorizations and has been added to the
relevant queue(s). The queue(s) will be merged in the target development
branch(es) as soon as builds have passed.

The changeset will be merged in:

  • ✔️ development/1.0

There is no action required on your side. You will be notified here once
the changeset has been merged. In the unlikely event that the changeset
fails permanently on the queue, a member of the admin team will
contact you to help resolve the matter.

IMPORTANT

Please do not attempt to modify this pull request.

  • Any commit you add on the source branch will trigger a new cycle after the
    current queue is merged.
  • Any commit you add on one of the integration branches will be lost.

If you need this pull request to be removed from the queue, please contact a
member of the admin team now.

The following options are set: approve

@bert-e

bert-e commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

I have successfully merged the changeset of this pull request
into targetted development branches:

  • ✔️ development/1.0

Please check the status of the associated issue None.

Goodbye jeanmarcmilletscality.

@bert-e
bert-e merged commit 3177d9a into development/1.0 Aug 27, 2026
8 checks passed
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.

3 participants