Skip to content

feat(ui-banner): add Banner component - #2779

Open
git-nandor wants to merge 6 commits into
masterfrom
INSTUI-5210_new_banner_component
Open

git-nandor wants to merge 6 commits into
masterfrom
INSTUI-5210_new_banner_component

Conversation

@git-nandor

@git-nandor git-nandor commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • New @instructure/ui-banner package with a Banner v1 component
  • Registered in @instructure/ui/v11_7 and the docs app

Test Plan

  • Docs → Banner: compare the examples with the Figma designs.
  • RTL: the icon box and the close button mirror
  • Dismissing: close button, Escape with focus inside, open={false} from outside and timeout
  • Screen reader: the "Add Banner" example announces the title and the content through the live region

Fixes INSTUI-5210

🤖 Generated with Claude Code

@git-nandor git-nandor self-assigned this Nov 3, 2026
@github-actions

github-actions Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.2

QR code for preview link

🚀 View preview at
https://instructure.design/pr-preview/pr-2779/

Built to branch gh-pages at 2026-11-11 23:07 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

github-actions Bot pushed a commit that referenced this pull request Nov 3, 2026
@github-actions

github-actions Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Visual regression report

Cypress suite: ✅ Passing

Visual diff: ✅ No changes.

Status Count
Unchanged 111
Changed 0
New 3
Removed 0

Accessibility (axe): ✅ No violations.

📊 View full report — click a screenshot's ⚠ badge to see each violation boxed on the image, with the offending element named and contrast failures shown as color swatches.

Baselines come from the visual-baselines branch. They refresh on every merge to master. The Cypress suite line covers the a11y and console-error assertions — a ❌ there means the suite found real issues even if the visual diff is clean.

@git-nandor
git-nandor force-pushed the INSTUI-5210_new_banner_component branch from cad3ddc to d965f74 Compare November 4, 2026 07:55
github-actions Bot pushed a commit that referenced this pull request Nov 4, 2026
@git-nandor
git-nandor marked this pull request as ready for review November 4, 2026 08:42
...rest
} = props

const [open, setOpen] = useState(true)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

its a bit of an edge case, but <Banner open={false} shows the Banner. I think its OK, since there is no code to open a closed banner, so it does not make sense to render a Banner, that is always closed.

@matyasf matyasf left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

overall it looks good, but there are a couple of smaller changes needed

Comment on lines +105 to +106
// JAWS ignores `aria-relevant` and reads the removed node unless the
// attributes are removed and reapplied

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is very likely not true! The comment is copied from Alert, which copied it from Canvas from a 2016 (!!) commit https://github.com/instructure/canvas-lms/blob/master/ui/shared/rails-flash-notifications/jquery/helper.ts#L156
Please test this in JAWS and remove it (from Alert too!) if its not needed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks you're right. The node removal was missing, and the attributes were immediately added back. React only removes the node afterwards, so the code wasn't actually doing anything.


if (transition === 'none') {
return open ? (
<Fragment>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Do not use <Fragment>, use just <>, this is our convention

/**
* The first row of the Banner, displayed above the content.
*/
title?: ReactNode

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Cant we make this just a string? We can widen the type later if needed

/**
* Close button label, setting it renders the close button.
*/
renderCloseButtonLabel?: Renderable

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Cant we make this just a string? We can widen the type later if needed

Comment on lines +5 to +7
The Banner component highlights a non-urgent message, like a new feature or a
tip. For status messages (info, success, warning, error) use [Alert](Alert)
instead.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I would also add where it should be used. in the page flow? at the top?

renderCloseButtonLabel="Close"
margin="0 0 general.spaceMd"
>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can you ask design for some of the examples for a more realistic text, so its easier to understand what this should be used for?

Comment thread regression-test/src/app/banner/page.tsx Outdated
Comment on lines +38 to +40
title="Banner header"
renderIcon={DiamondInstUIIcon}
renderCloseButtonLabel="Close"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

please add here variants that do not render the close button and have no title

Comment thread regression-test/src/app/banner/page.tsx Outdated
const variants = ['relaxed', 'compact'] as const
return (
<main className="flex gap-8 p-8 flex-col items-start axe-test">
{variants.map((variant) => (

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

its a bit overkill to do a loop for 2 variants..

git-nandor and others added 6 commits November 11, 2026 17:06
Add new Banner component

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Both props hold plain text, so renderCloseButtonLabel becomes closeButtonLabel and no longer
accepts a render function.

Co-Authored-By: Claude <noreply@anthropic.com>
The attributes were set again before React removed the announcement node, so the region looked
the same at removal as without the reset. The Canvas code it came from removes the node in
between and was written for JAWS with Internet Explorer.

Co-Authored-By: Claude <noreply@anthropic.com>
… text

Co-Authored-By: Claude <noreply@anthropic.com>
@git-nandor
git-nandor force-pushed the INSTUI-5210_new_banner_component branch from d965f74 to 065c323 Compare November 11, 2026 23:04
github-actions Bot pushed a commit that referenced this pull request Nov 11, 2026
@git-nandor
git-nandor requested a review from matyasf November 12, 2026 07:44

This branch has not been deployed

No deployments
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