Skip to content

feat: add MoreMenu component for toolbar actions#71

Merged
matt1398 merged 1 commit intomainfrom
feat/tabbar-more-menu
Feb 23, 2026
Merged

feat: add MoreMenu component for toolbar actions#71
matt1398 merged 1 commit intomainfrom
feat/tabbar-more-menu

Conversation

@matt1398
Copy link
Owner

@matt1398 matt1398 commented Feb 23, 2026

  • Introduced MoreMenu component to consolidate less-frequent actions (Search, Export, Analyze, Settings) behind a dropdown menu.
  • Removed individual action buttons from TabBar for a cleaner interface.
  • Implemented functionality to close the menu on outside clicks and Escape key press.

Summary by CodeRabbit

  • New Features

    • Added a “More” menu (⋯) that consolidates actions: Search, Export (Markdown/JSON/Plain Text), Analyze Session, and Settings.
    • Supports keyboard shortcuts, Escape-to-close, and outside-click dismissal for improved accessibility.
  • Refactor

    • Replaced individual action buttons in the tab bar with the new consolidated menu for a cleaner, more organized interface.
    • Streamlined hover and state handling by centralizing interactions within the menu.

- Introduced MoreMenu component to consolidate less-frequent actions (Search, Export, Analyze, Settings) behind a dropdown menu.
- Removed individual action buttons from TabBar for a cleaner interface.
- Implemented functionality to close the menu on outside clicks and Escape key press.
@gemini-code-assist
Copy link

Summary of Changes

Hello @matt1398, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors the application's toolbar by introducing a centralized 'MoreMenu' component. This change aims to declutter the user interface by grouping several less-frequently used actions into a single, accessible dropdown. The consolidation of these actions enhances the overall visual simplicity and navigability of the toolbar, providing a cleaner and more intuitive experience for users without removing any core functionality.

Highlights

  • New MoreMenu Component: Introduced a new MoreMenu React component that consolidates less-frequent toolbar actions (Search, Export, Analyze, Settings) into a single dropdown menu, improving UI cleanliness.
  • TabBar Refactoring: Removed individual action buttons for Search, Export, Analyze, and Settings from the TabBar component, replacing them with the new MoreMenu component.
  • Menu Interaction Logic: Implemented functionality within the MoreMenu to close the dropdown when clicking outside of it or pressing the Escape key, enhancing user experience.
  • Conditional Session Actions: Ensured that session-specific actions like Export and Analyze Session are only displayed in the MoreMenu when an active session tab with loaded data is present.
Changelog
  • src/renderer/components/layout/MoreMenu.tsx
    • Added a new React component MoreMenu to encapsulate dropdown functionality for various actions.
    • Implemented state management for menu visibility, button hover, and item hover.
    • Added useEffect hooks to handle closing the menu on outside clicks and Escape key presses.
    • Defined MenuItem interface for consistent menu item rendering.
    • Integrated actions for opening command palette, settings tab, and session reports.
    • Included conditional rendering for session-specific export and analyze options.
    • Styled the menu and its items using inline styles and Tailwind CSS classes for consistent theming.
  • src/renderer/components/layout/TabBar.tsx
    • Removed imports for Activity, Search, Settings icons and ExportDropdown component.
    • Added import for the new MoreMenu component.
    • Removed openCommandPalette, openSettingsTab, and openSessionReport from useStore selectors.
    • Removed state variables related to hover effects for the previously individual Search, Settings, and Analyze buttons.
    • Deleted the individual Search button, ExportDropdown component, and Analyze Session button from the JSX.
    • Replaced the removed individual action buttons with the MoreMenu component, passing necessary props like activeTab, activeTabSessionDetail, and activeTabId.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request successfully refactors the toolbar by introducing a MoreMenu component to house less-frequently used actions, which significantly cleans up the TabBar interface. The new component is well-implemented. I have one suggestion to combine the useEffect hooks for closing the menu to improve code clarity and maintainability. Overall, this is a great improvement to the UI.

Comment on lines +48 to +73
useEffect(() => {
if (!isOpen) return;

const handleClickOutside = (event: MouseEvent): void => {
if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
setIsOpen(false);
}
};

document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, [isOpen]);

// Close on Escape
useEffect(() => {
if (!isOpen) return;

const handleEscape = (event: KeyboardEvent): void => {
if (event.key === 'Escape') {
setIsOpen(false);
}
};

document.addEventListener('keydown', handleEscape);
return () => document.removeEventListener('keydown', handleEscape);
}, [isOpen]);

Choose a reason for hiding this comment

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

medium

To improve code clarity and reduce duplication, you can combine the two useEffect hooks for closing the menu into a single hook. This groups the related logic for handling 'mousedown' and 'keydown' events together.

  // Close on outside click or Escape
  useEffect(() => {
    if (!isOpen) return;

    const handleClickOutside = (event: MouseEvent): void => {
      if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
        setIsOpen(false);
      }
    };

    const handleEscape = (event: KeyboardEvent): void => {
      if (event.key === 'Escape') {
        setIsOpen(false);
      }
    };

    document.addEventListener('mousedown', handleClickOutside);
    document.addEventListener('keydown', handleEscape);

    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
      document.removeEventListener('keydown', handleEscape);
    };
  }, [isOpen]);

@coderabbitai coderabbitai bot added the feature request New feature or request label Feb 23, 2026
@coderabbitai
Copy link

coderabbitai bot commented Feb 23, 2026

📝 Walkthrough

Walkthrough

The changes introduce a new MoreMenu dropdown component that consolidates search, session analysis, export, and settings actions. TabBar is refactored to use MoreMenu instead of individual action buttons.

Changes

Cohort / File(s) Summary
New MoreMenu Component
src/renderer/components/layout/MoreMenu.tsx
Introduces new dropdown menu component grouping search, session analysis, export, and settings actions with keyboard navigation and outside-click dismissal.
TabBar Refactoring
src/renderer/components/layout/TabBar.tsx
Replaces discrete action buttons (Search, Analyze, Settings) and ExportDropdown with single MoreMenu component; removes related state and imports.

Suggested labels

feature request

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
src/renderer/components/layout/MoreMenu.tsx (2)

8-18: Reorder imports to match project conventions.

Move lucide-react into the external group before path aliases.

♻️ Suggested import ordering
-import React, { useCallback, useEffect, useRef, useState } from 'react';
-
-import { useStore } from '@renderer/store';
-import { triggerDownload } from '@renderer/utils/sessionExporter';
-import { formatShortcut } from '@renderer/utils/stringUtils';
-import { Activity, Braces, FileText, MoreHorizontal, Search, Settings, Type } from 'lucide-react';
+import React, { useCallback, useEffect, useRef, useState } from 'react';
+import { Activity, Braces, FileText, MoreHorizontal, Search, Settings, Type } from 'lucide-react';
+
+import { useStore } from '@renderer/store';
+import { triggerDownload } from '@renderer/utils/sessionExporter';
+import { formatShortcut } from '@renderer/utils/stringUtils';

As per coding guidelines, organize imports in order: external packages, path aliases (@main, @renderer, @shared, @preload), then relative imports.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/renderer/components/layout/MoreMenu.tsx` around lines 8 - 18, The import
ordering in MoreMenu.tsx is out of convention: move the lucide-react import
(icons: Activity, Braces, FileText, MoreHorizontal, Search, Settings, Type) into
the external packages group above the path-alias imports (useStore,
triggerDownload, formatShortcut, types, utils), so imports are ordered as
external packages first, then path aliases (`@renderer/`... symbols like useStore,
triggerDownload, formatShortcut, SessionDetail, Tab, ExportFormat), then any
relative imports; adjust spacing between groups accordingly to match project
import conventions.

149-190: Add type="button" to prevent accidental form submits.

If this component is ever rendered inside a <form>, the default submit type could trigger unintended submits.

✅ Safe button types
-    <button
+    <button
+      type="button"
       key={item.id}
       onClick={item.onClick}
@@
-      <button
+      <button
+        type="button"
         onClick={() => setIsOpen(!isOpen)}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/renderer/components/layout/MoreMenu.tsx` around lines 149 - 190, The
buttons in MoreMenu can accidentally submit a surrounding form because they lack
explicit types; update the button in renderItem (the MenuItem button returned by
the renderItem function) and the trigger button that toggles isOpen (the button
rendering MoreHorizontal and calling setIsOpen/setButtonHover) to include
type="button" to prevent default submit behavior while preserving existing
onClick and hover handlers.
src/renderer/components/layout/TabBar.tsx (1)

10-20: Reorder imports so externals come before path aliases.

lucide-react and zustand/react/shallow should be grouped with other externals ahead of @renderer/* imports.

♻️ Suggested import ordering
-import { useDroppable } from '@dnd-kit/core';
-import { horizontalListSortingStrategy, SortableContext } from '@dnd-kit/sortable';
-import { isElectronMode } from '@renderer/api';
-import { HEADER_ROW1_HEIGHT } from '@renderer/constants/layout';
-import { useStore } from '@renderer/store';
-import { formatShortcut } from '@renderer/utils/stringUtils';
-import { Bell, PanelLeft, Plus, RefreshCw } from 'lucide-react';
-import { useShallow } from 'zustand/react/shallow';
+import { useDroppable } from '@dnd-kit/core';
+import { horizontalListSortingStrategy, SortableContext } from '@dnd-kit/sortable';
+import { Bell, PanelLeft, Plus, RefreshCw } from 'lucide-react';
+import { useShallow } from 'zustand/react/shallow';
+
+import { isElectronMode } from '@renderer/api';
+import { HEADER_ROW1_HEIGHT } from '@renderer/constants/layout';
+import { useStore } from '@renderer/store';
+import { formatShortcut } from '@renderer/utils/stringUtils';

As per coding guidelines, organize imports in order: external packages, path aliases (@main, @renderer, @shared, @preload), then relative imports.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/renderer/components/layout/TabBar.tsx` around lines 10 - 20, The import
block in TabBar.tsx violates the project's ordering rules: external packages
must come before path-alias imports; move lucide-react (Bell, PanelLeft, Plus,
RefreshCw) and zustand/react/shallow (useShallow) up into the external imports
group so they appear before any `@renderer/`* imports (isElectronMode,
HEADER_ROW1_HEIGHT, useStore, formatShortcut), keeping the existing internal
import grouping and relative order otherwise; ensure the import groups are
separated consistently to match the project convention.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/renderer/components/layout/MoreMenu.tsx`:
- Around line 8-18: The import ordering in MoreMenu.tsx is out of convention:
move the lucide-react import (icons: Activity, Braces, FileText, MoreHorizontal,
Search, Settings, Type) into the external packages group above the path-alias
imports (useStore, triggerDownload, formatShortcut, types, utils), so imports
are ordered as external packages first, then path aliases (`@renderer/`... symbols
like useStore, triggerDownload, formatShortcut, SessionDetail, Tab,
ExportFormat), then any relative imports; adjust spacing between groups
accordingly to match project import conventions.
- Around line 149-190: The buttons in MoreMenu can accidentally submit a
surrounding form because they lack explicit types; update the button in
renderItem (the MenuItem button returned by the renderItem function) and the
trigger button that toggles isOpen (the button rendering MoreHorizontal and
calling setIsOpen/setButtonHover) to include type="button" to prevent default
submit behavior while preserving existing onClick and hover handlers.

In `@src/renderer/components/layout/TabBar.tsx`:
- Around line 10-20: The import block in TabBar.tsx violates the project's
ordering rules: external packages must come before path-alias imports; move
lucide-react (Bell, PanelLeft, Plus, RefreshCw) and zustand/react/shallow
(useShallow) up into the external imports group so they appear before any
`@renderer/`* imports (isElectronMode, HEADER_ROW1_HEIGHT, useStore,
formatShortcut), keeping the existing internal import grouping and relative
order otherwise; ensure the import groups are separated consistently to match
the project convention.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6264ec5 and 1535a69.

📒 Files selected for processing (2)
  • src/renderer/components/layout/MoreMenu.tsx
  • src/renderer/components/layout/TabBar.tsx

@matt1398 matt1398 merged commit 3749d7e into main Feb 23, 2026
7 checks passed
matt1398 added a commit that referenced this pull request Feb 26, 2026
The MoreMenu component (from PR #71) referenced openSessionReport
which was introduced by PR #60. Remove the dangling reference.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature request New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant