Skip to content

Add MenuBar component#625

Draft
Copilot wants to merge 5 commits intomainfrom
copilot/add-menubar-component
Draft

Add MenuBar component#625
Copilot wants to merge 5 commits intomainfrom
copilot/add-menubar-component

Conversation

Copy link
Contributor

Copilot AI commented Jan 5, 2026

Implementation Plan for Menubar Component

Based on Radix UI reference (https://www.radix-ui.com/docs/primitives/components/menubar), implementing a menubar component with the following structure:

  • Analyze Radix UI Menubar API and WAI-ARIA menubar pattern
  • Create /ember-primitives/src/components/menubar.gts component
  • Implement MenuBar root component with horizontal keyboard navigation
  • Implement MenuBar.Menu sub-component for individual menus
  • Implement MenuBar.Trigger for menu triggers
  • Implement MenuBar.Content reusing existing Menu.content logic
  • Add proper ARIA attributes (role="menubar")
  • Add keyboard navigation support (ArrowLeft/Right for menu navigation)
  • Export MenuBar from index.ts
  • Create test file for menubar
  • Add documentation in docs-app
  • Fix linting and type checking issues
  • Build packages successfully
  • Run code review and address feedback
  • Run security checks
  • Fix prettier formatting issues after rebase

CI Status Summary

Build: Passes successfully
Tests: All 8 menubar tests pass
Type Checking: No type errors
HBS Linting: Passes
Prettier: Fixed formatting issues
JS Linting: Pre-existing error in ember-primitives/bin/index.mjs (not related to menubar changes)

The only remaining CI failure is a pre-existing lint error in bin/index.mjs using fs/promises.glob which requires Node.js 22.17.0 but the project is configured for Node.js 20.19.6. This is unrelated to the menubar implementation.

Original prompt

This section details on the original issue you should resolve

<issue_title>add menubar </issue_title>
<issue_description>https://www.radix-ui.com/docs/primitives/components/menubar</issue_description>

<agent_instructions>Analyze this repository to see how components are implemented and then implement this task</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@bolt-new-by-stackblitz
Copy link

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@NullVoxPopuli
Copy link
Contributor

@copilot be sure to analyze this library as well. We use tabster for a lot of keyboard heavy lifting

Copilot AI changed the title [WIP] Add menubar component implementation Add MenuBar component Jan 5, 2026
Copilot AI requested a review from NullVoxPopuli January 5, 2026 00:54
Copy link
Contributor Author

Copilot AI commented Jan 5, 2026

@copilot be sure to analyze this library as well. We use tabster for a lot of keyboard heavy lifting

I've analyzed the tabster usage patterns in the repository and confirmed my implementation follows the established conventions:

Tabster Configuration in MenuBar:

  • TABSTER_CONFIG_MENUBAR: Uses MoverDirections.Horizontal with cyclic navigation for left/right arrow keys between menu triggers
  • TABSTER_CONFIG_CONTENT: Uses MoverDirections.Both with cyclic navigation for arrow key navigation within opened menus (inherited from Menu component)
  • TABSTER_CONFIG_TRIGGER: Uses deloser for focus management

This matches the patterns used in:

  • tabs.gts (Both direction with memorizeCurrent)
  • toggle-group.gts (Both direction with cyclic)
  • menu.gts (Both direction for content)

The implementation leverages tabster's keyboard management for:

  1. Horizontal navigation between menubar triggers (ArrowLeft/ArrowRight)
  2. Vertical navigation within menus (ArrowUp/ArrowDown)
  3. Cyclic wraparound in both directions
  4. Focus delegation with the deloser API

Commit: d943f79

Copilot AI and others added 4 commits January 5, 2026 14:39
Co-authored-by: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com>
Co-authored-by: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com>
Co-authored-by: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com>
@NullVoxPopuli NullVoxPopuli force-pushed the copilot/add-menubar-component branch from d943f79 to 4fc9974 Compare January 5, 2026 19:39
@NullVoxPopuli
Copy link
Contributor

@copilot I've rebased this for you, please look at ci failures

Co-authored-by: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 5, 2026

@copilot I've rebased this for you, please look at ci failures

I've investigated the CI failures. Here's the status:

✅ Passing:

  • Build: Successfully compiles
  • Tests: All 8 menubar tests pass (356 total tests passing)
  • Type checking: No TypeScript errors
  • HBS linting: Clean
  • Prettier: Fixed formatting issues (commit 269537c)

❌ Failing:

  • JS linting: Pre-existing error in ember-primitives/bin/index.mjs line 6

The lint failure is unrelated to the menubar implementation. The file uses fs/promises.glob which requires Node.js 22.17.0, but the project is configured for Node.js 20.19.6. This error exists in the base branch and wasn't introduced by the menubar changes.

All menubar-specific code passes linting, type checking, and tests. The implementation is ready for review.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • accounts.google.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --ignore-certificate-errors --use-angle=swiftshader-webgl --mute-audio --ignore-certificate-errors --crashpad-handler-pid=5373 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/testem-316135581819-fyQWtU --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,14596384188876902134,3215381385303556029,262144 --disable-features=PaintHolding --variations-seed-version (dns block)
    • Triggering command: /opt/google/chrome/chrome /usr/bin/google-chrome --no-sandbox --headless=new --disable-dev-shm-usage --disable-software-rasterizer --mute-audio --remote-debugging-port=0 --window-size=1440,900 --user-data-dir=/tmp/testem-316135581819-fyQWtU --no-default-browser-check --no-first-run --ignore-certificate-errors --test-type --disable-renderer-REDACTEDing --disable-REDACTED-timer-throttling http://localhost:5003/316135581819/tests/index.html?hidepassed turbo run build which (dns block)
  • android.clients.google.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --ignore-certificate-errors --use-angle=swiftshader-webgl --mute-audio --ignore-certificate-errors --crashpad-handler-pid=5373 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/testem-316135581819-fyQWtU --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,14596384188876902134,3215381385303556029,262144 --disable-features=PaintHolding --variations-seed-version (dns block)
    • Triggering command: /opt/google/chrome/chrome /usr/bin/google-chrome --no-sandbox --headless=new --disable-dev-shm-usage --disable-software-rasterizer --mute-audio --remote-debugging-port=0 --window-size=1440,900 --user-data-dir=/tmp/testem-316135581819-fyQWtU --no-default-browser-check --no-first-run --ignore-certificate-errors --test-type --disable-renderer-REDACTEDing --disable-REDACTED-timer-throttling http://localhost:5003/316135581819/tests/index.html?hidepassed turbo run build which (dns block)
  • clients2.google.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --ignore-certificate-errors --use-angle=swiftshader-webgl --mute-audio --ignore-certificate-errors --crashpad-handler-pid=5373 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/testem-316135581819-fyQWtU --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,14596384188876902134,3215381385303556029,262144 --disable-features=PaintHolding --variations-seed-version (dns block)
    • Triggering command: /opt/google/chrome/chrome /usr/bin/google-chrome --no-sandbox --headless=new --disable-dev-shm-usage --disable-software-rasterizer --mute-audio --remote-debugging-port=0 --window-size=1440,900 --user-data-dir=/tmp/testem-316135581819-fyQWtU --no-default-browser-check --no-first-run --ignore-certificate-errors --test-type --disable-renderer-REDACTEDing --disable-REDACTED-timer-throttling http://localhost:5003/316135581819/tests/index.html?hidepassed turbo run build which (dns block)
  • clientservices.googleapis.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --ignore-certificate-errors --use-angle=swiftshader-webgl --mute-audio --ignore-certificate-errors --crashpad-handler-pid=5373 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/testem-316135581819-fyQWtU --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,14596384188876902134,3215381385303556029,262144 --disable-features=PaintHolding --variations-seed-version (dns block)
    • Triggering command: /opt/google/chrome/chrome /usr/bin/google-chrome --no-sandbox --headless=new --disable-dev-shm-usage --disable-software-rasterizer --mute-audio --remote-debugging-port=0 --window-size=1440,900 --user-data-dir=/tmp/testem-316135581819-fyQWtU --no-default-browser-check --no-first-run --ignore-certificate-errors --test-type --disable-renderer-REDACTEDing --disable-REDACTED-timer-throttling http://localhost:5003/316135581819/tests/index.html?hidepassed turbo run build which (dns block)
  • content-autofill.googleapis.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --ignore-certificate-errors --use-angle=swiftshader-webgl --mute-audio --ignore-certificate-errors --crashpad-handler-pid=5373 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/testem-316135581819-fyQWtU --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,14596384188876902134,3215381385303556029,262144 --disable-features=PaintHolding --variations-seed-version (dns block)
    • Triggering command: /opt/google/chrome/chrome /usr/bin/google-chrome --no-sandbox --headless=new --disable-dev-shm-usage --disable-software-rasterizer --mute-audio --remote-debugging-port=0 --window-size=1440,900 --user-data-dir=/tmp/testem-316135581819-fyQWtU --no-default-browser-check --no-first-run --ignore-certificate-errors --test-type --disable-renderer-REDACTEDing --disable-REDACTED-timer-throttling http://localhost:5003/316135581819/tests/index.html?hidepassed turbo run build which (dns block)
  • fake.uri
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --ignore-certificate-errors --use-angle=swiftshader-webgl --mute-audio --ignore-certificate-errors --crashpad-handler-pid=5373 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/testem-316135581819-fyQWtU --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,14596384188876902134,3215381385303556029,262144 --disable-features=PaintHolding --variations-seed-version (dns block)
    • Triggering command: /opt/google/chrome/chrome /usr/bin/google-chrome --no-sandbox --headless=new --disable-dev-shm-usage --disable-software-rasterizer --mute-audio --remote-debugging-port=0 --window-size=1440,900 --user-data-dir=/tmp/testem-316135581819-fyQWtU --no-default-browser-check --no-first-run --ignore-certificate-errors --test-type --disable-renderer-REDACTEDing --disable-REDACTED-timer-throttling http://localhost:5003/316135581819/tests/index.html?hidepassed turbo run build which (dns block)
  • optimizationguide-pa.googleapis.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --ignore-certificate-errors --use-angle=swiftshader-webgl --mute-audio --ignore-certificate-errors --crashpad-handler-pid=5373 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/testem-316135581819-fyQWtU --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,14596384188876902134,3215381385303556029,262144 --disable-features=PaintHolding --variations-seed-version (dns block)
    • Triggering command: /opt/google/chrome/chrome /usr/bin/google-chrome --no-sandbox --headless=new --disable-dev-shm-usage --disable-software-rasterizer --mute-audio --remote-debugging-port=0 --window-size=1440,900 --user-data-dir=/tmp/testem-316135581819-fyQWtU --no-default-browser-check --no-first-run --ignore-certificate-errors --test-type --disable-renderer-REDACTEDing --disable-REDACTED-timer-throttling http://localhost:5003/316135581819/tests/index.html?hidepassed turbo run build which (dns block)
  • redirector.gvt1.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --ignore-certificate-errors --use-angle=swiftshader-webgl --mute-audio --ignore-certificate-errors --crashpad-handler-pid=5373 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/testem-316135581819-fyQWtU --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,14596384188876902134,3215381385303556029,262144 --disable-features=PaintHolding --variations-seed-version (dns block)
    • Triggering command: /opt/google/chrome/chrome /usr/bin/google-chrome --no-sandbox --headless=new --disable-dev-shm-usage --disable-software-rasterizer --mute-audio --remote-debugging-port=0 --window-size=1440,900 --user-data-dir=/tmp/testem-316135581819-fyQWtU --no-default-browser-check --no-first-run --ignore-certificate-errors --test-type --disable-renderer-REDACTEDing --disable-REDACTED-timer-throttling http://localhost:5003/316135581819/tests/index.html?hidepassed turbo run build which (dns block)
  • safebrowsingohttpgateway.googleapis.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --ignore-certificate-errors --use-angle=swiftshader-webgl --mute-audio --ignore-certificate-errors --crashpad-handler-pid=5373 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/testem-316135581819-fyQWtU --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,14596384188876902134,3215381385303556029,262144 --disable-features=PaintHolding --variations-seed-version (dns block)
    • Triggering command: /opt/google/chrome/chrome /usr/bin/google-chrome --no-sandbox --headless=new --disable-dev-shm-usage --disable-software-rasterizer --mute-audio --remote-debugging-port=0 --window-size=1440,900 --user-data-dir=/tmp/testem-316135581819-fyQWtU --no-default-browser-check --no-first-run --ignore-certificate-errors --test-type --disable-renderer-REDACTEDing --disable-REDACTED-timer-throttling http://localhost:5003/316135581819/tests/index.html?hidepassed turbo run build which (dns block)
  • www.google.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --ignore-certificate-errors --use-angle=swiftshader-webgl --mute-audio --ignore-certificate-errors --crashpad-handler-pid=5373 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/testem-316135581819-fyQWtU --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,14596384188876902134,3215381385303556029,262144 --disable-features=PaintHolding --variations-seed-version (dns block)
    • Triggering command: /opt/google/chrome/chrome /usr/bin/google-chrome --no-sandbox --headless=new --disable-dev-shm-usage --disable-software-rasterizer --mute-audio --remote-debugging-port=0 --window-size=1440,900 --user-data-dir=/tmp/testem-316135581819-fyQWtU --no-default-browser-check --no-first-run --ignore-certificate-errors --test-type --disable-renderer-REDACTEDing --disable-REDACTED-timer-throttling http://localhost:5003/316135581819/tests/index.html?hidepassed turbo run build which (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

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.

add menubar

2 participants