Skip to content

Add Menu and Navbar components#647

Draft
mkernohanbc wants to merge 27 commits intomainfrom
518-menu
Draft

Add Menu and Navbar components#647
mkernohanbc wants to merge 27 commits intomainfrom
518-menu

Conversation

@mkernohanbc
Copy link
Copy Markdown
Contributor

Draft PR for initial feedback on design and implementation.

This PR adds two new components:

  • Menu and various subcomponents: a dropdown menu for use in cases where a Select is inappropriate (eg. navigation)
  • Navbar: a generic navigation bar, implemented based on RA Toolbar

Menu

Screenshot 2026-03-19 at 2 28 06 PM

Menu is logically very similar to Select, and follows the same Collections API.

The MenuTrigger, Menu and MenuItem components are the core parts, but MenuSection, MenuSection and SubmenuTrigger components are also exported to support complex composition:

function App() {
  return (
    <MenuTrigger>
      <Button>This button activates the menu</Button>
      <Menu>
        <MenuSection>
          <MenuSectionHeader />
          <MenuItem />
        </MenuSection>
        <Separator />
        <MenuSection>
          <MenuSectionHeader />
          <MenuItem />
        </MenuSection>
      </Menu>
    </MenuTrigger>
  );
}

Menus can be composed dynamically using the items or sections props, or manually composed via the children slot.

See Storybook docs for a more detailed explanation of the structure of this set of components, and each component's individual API.

Navbar

Screenshot 2026-03-19 at 2 33 57 PM

This is a (currently extremely basic) implementation of an idea we've discussed previously: a secondary navigation menu that can be used alongside the Header component.

What I currently have on this branch is:

  • A standalone Navbar component, implemented using RA Toolbar
  • A change to Header to natively integrate Navbar via a new subMenuItems prop

Navbar has relatively little internal logic of its own, beyond sizing/spacing and automatically generating <Separator /> elements between items. It is built around a generic children slot, expecting some number of <Link>, <Button>, <Menu> etc.

@mkernohanbc mkernohanbc added this to the Components v1.0.0 milestone Mar 19, 2026
@mkernohanbc mkernohanbc self-assigned this Mar 19, 2026
@mkernohanbc mkernohanbc added the Components Changes or issues affect the design-system-react-components package label Mar 19, 2026
@mkernohanbc mkernohanbc linked an issue Mar 19, 2026 that may be closed by this pull request
@mkernohanbc
Copy link
Copy Markdown
Contributor Author

@Philip-Cheung these components are feature-complete(ish), but the design is largely judgement calls and mimicking our general design language. Please take a look to familiarize yourself with these components' feature-set and behaviour; when you have a formal design spec, I'll work back on that.

@ty2k would appreciate an initial look over this, particularly the Menu piece. I've taken a slightly different approach to implementation than we did with Select (ie. decomposing into multiple discrete subcomponents), and hit on a bunch of complexity around how to elegantly handle multiple methods of composition (children / items / sections)

@Philip-Cheung
Copy link
Copy Markdown

@mkernohanbc will take a look at this this afternoon

@Philip-Cheung
Copy link
Copy Markdown

Bugs:

Screenshot 2026-03-20 at 3 25 58 PM When I open the menu, the dropdown menu's focus mode is wrapped around all of the menu items.

@Philip-Cheung
Copy link
Copy Markdown

Screenshot 2026-03-20 at 3 28 04 PM Not sure what check icon we're using here but its not the icon from our DS: https://www.figma.com/design/6BAmnRmL9FXxY2bkkSYiQj/B.C.-Design-System?node-id=3351-1754&t=MIKwwQnz00xAJTjf-4

@mkernohanbc
Copy link
Copy Markdown
Contributor Author

Not sure what check icon we're using here but its not the icon from our DS: https://www.figma.com/design/6BAmnRmL9FXxY2bkkSYiQj/B.C.-Design-System?node-id=3351-1754&t=MIKwwQnz00xAJTjf-4

This tracked back to a discrepancy between FA versions, corrected in 882a9a3

Copy link
Copy Markdown
Contributor

@ty2k ty2k left a comment

Choose a reason for hiding this comment

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

Very slick! I like the Menu implementation and it seems to work really nicely with keyboard controls, including for complex cases like the Submenu.

I haven't gone through this with a fine-toothed comb because of the amount of code here, but this is a first pass. In general, I think it would be ideal to break this into several PRs:

  • One for each SVG icon
  • Popover by itself if it's generic
  • Menu and MenuItem
  • Navbar


return (
<div className="bcds-react-aria-Navbar">
<Toolbar
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.

I think Toolbar should just be a regular <nav>.

The issue with Toolbar is it gets the toolbar role, whereas a <nav> gets navigation.


import "./Popover.css";

export default function Popover(props: PopoverProps) {
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.

Is this a general purpose Popover or specific to Navbar and Menu? Can it go in by itself if it's generic? If it's generic, we're already using the Popover from RAC throughout the library, so the names and usage should be reconciled.

If it's specific, can it be renamed for specificity?

@@ -1,5 +1,5 @@
import { cloneElement, PropsWithChildren } from "react";

import Navbar from "../Navbar";
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.

Can we leave it out of Header?

  • Better separation of concerns.
  • Leaves the Header props cleaner.
  • Better customization for breakpoints (contrived example: Header goes from desktop to tablet design at 900px but Navbar needs to change at 750px).

width="10"
height="10"
viewBox="0 0 10 10"
viewBox="0 0 448 512"
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.

I see the move to the v6 version of this icon has a different (not square) aspect ratio. Will this cause visual regressions in other components like Checkbox?

Something to think about in general for icons if we're going to mix and match versions of Font Awesome. I think the majority we have right now are following the old square ratio.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Components Changes or issues affect the design-system-react-components package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Menu/menu item

3 participants