Skip to content

Lite: native menus#13317

Open
OliverJAsh wants to merge 1 commit intomasterfrom
push-pzxluozktuwo
Open

Lite: native menus#13317
OliverJAsh wants to merge 1 commit intomasterfrom
push-pzxluozktuwo

Conversation

@OliverJAsh
Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI review requested due to automatic review settings April 14, 2026 21:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR switches “workspace” action/context menus in the Lite UI from Base UI’s in-DOM menus to Electron-native popup menus, wired through a new IPC endpoint.

Changes:

  • Replaced @base-ui/react Menu/ContextMenu usage in the workspace route with native-menu triggers and item definitions.
  • Added a renderer-side native menu helper (native-menu.ts) that serializes menu items and dispatches selection handlers.
  • Added an Electron IPC handler (lite:show-native-menu) plus preload/api typing to display a native Menu.popup() and return the selected item id.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
apps/lite/ui/src/routes/project/$id/workspace/route.tsx Replaces Base UI menus with calls to showNativeContextMenu / showNativeMenuFromTrigger and inline NativeMenuItem[] definitions.
apps/lite/ui/src/routes/project/$id/workspace/route.module.css Removes :has(...aria-expanded="true") styling hook that no longer applies with native menus.
apps/lite/ui/src/native-menu.ts Adds renderer-side menu item serialization + IPC call to show a native menu and run the selected handler.
apps/lite/electron/src/preload.cts Exposes showNativeMenu on window.lite via ipcRenderer.invoke.
apps/lite/electron/src/main.ts Implements lite:show-native-menu handler using Electron Menu.popup() and a template builder.
apps/lite/electron/src/ipc.ts Adds IPC types (NativeMenuPopupItem, ShowNativeMenuParams, etc.) and channel constant.

Comment thread apps/lite/ui/src/native-menu.ts Outdated
Comment thread apps/lite/electron/src/main.ts
Base automatically changed from push-nlvolzpnmtyk to master April 15, 2026 10:22
Copilot AI review requested due to automatic review settings April 15, 2026 19:03
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated 7 comments.

<button
type="button"
className={styles.itemRowAction}
aria-label={`${change.path} menu`}
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

This menu trigger is now a plain <button>; Menu.Trigger previously handled menu-related ARIA. Add aria-haspopup="menu" (and any other necessary ARIA attributes) so screen readers can identify this as opening a menu.

Suggested change
aria-label={`${change.path} menu`}
aria-label={`${change.path} menu`}
aria-haspopup="menu"

Copilot uses AI. Check for mistakes.
<button
type="button"
className={styles.itemRowAction}
aria-label="Changes menu"
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

This button triggers a menu but lacks aria-haspopup="menu" now that it’s not using Menu.Trigger. Adding the appropriate ARIA attributes will prevent an accessibility regression for assistive technology users.

Suggested change
aria-label="Changes menu"
aria-label="Changes menu"
aria-haspopup="menu"

Copilot uses AI. Check for mistakes.
<button
type="button"
className={styles.itemRowAction}
aria-label="Branch menu"
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

Since this button opens the branch menu via the native menu API, it should expose menu semantics (e.g., aria-haspopup="menu") that were previously supplied by Menu.Trigger to avoid an accessibility regression.

Suggested change
aria-label="Branch menu"
aria-label="Branch menu"
aria-haspopup="menu"

Copilot uses AI. Check for mistakes.
<button
type="button"
className={styles.itemRowAction}
aria-label="Stack menu"
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

This stack menu trigger is now a plain button; Menu.Trigger previously provided menu-related ARIA attributes. Add aria-haspopup="menu" (and any other required ARIA attributes) so assistive technologies can recognize it as a menu trigger.

Suggested change
aria-label="Stack menu"
aria-label="Stack menu"
aria-haspopup="menu"

Copilot uses AI. Check for mistakes.
Comment on lines +48 to +50
const handlers = new Map<string, NativeMenuAction | undefined>();
const serializedItems = serializeNativeMenuItems(items, handlers, { value: 0 });

Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

serializeNativeMenuItems expects a Map<string, NativeMenuAction | undefined>, but showNativeMenu constructs handlers as new Map<string, NativeMenuAction>() and passes it in. Because Map is invariant in its value type, this is a TypeScript type error (and it’s also inconsistent with handlers.set(itemId, item.onSelect) where onSelect can be undefined). Make handlers a Map<string, NativeMenuAction | undefined> (or only allocate itemId/store handlers for items that actually have an onSelect).

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,84 @@
import type { NativeMenuPopupItem, NativeMenuPosition } from "#electron/ipc.ts";
import { MouseEvent } from "react";
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

MouseEvent is only used as a type here. Prefer import type { MouseEvent } from "react"; to avoid introducing/keeping a runtime React import unnecessarily in this utility module (especially under isolatedModules/Vite transforms).

Suggested change
import { MouseEvent } from "react";
import type { MouseEvent } from "react";

Copilot uses AI. Check for mistakes.
<button
type="button"
className={styles.itemRowAction}
aria-label="Commit menu"
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

This button opens a menu, but it no longer gets the ARIA semantics that Menu.Trigger previously provided. Consider adding aria-haspopup="menu" (and any other required ARIA attributes your a11y baseline expects) so assistive tech can announce it as a menu trigger.

Suggested change
aria-label="Commit menu"
aria-label="Commit menu"
aria-haspopup="menu"

Copilot uses AI. Check for mistakes.
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.

2 participants