Skip to content

Conversation

@illia1f
Copy link
Contributor

@illia1f illia1f commented Dec 25, 2025

Summary

  • Added search functionality to the PathInput component with keyboard shortcut support (/ to open, ESC to close)
  • Created reusable Kbd and KbdGroup UI components for displaying keyboard shortcuts
  • Enhanced FileBrowserDialog to support search across directories

Changes

New Components

  • Kbd & KbdGroup components (kbd.tsx): Reusable components for displaying keyboard shortcuts with consistent styling

PathInput Component

  • Added search popover with Command component for fuzzy searching files and directories
  • Implemented keyboard shortcuts:
    • / key to activate search
    • ESC key to close search
  • Added new props:
    • entries: List of file system entries to search through
    • onSelectEntry: Callback when user selects an entry from search
    • searchPlaceholder: Custom placeholder for search input
  • Added Search button to breadcrumb view (disabled when no entries available)
  • Improved focus management for search input
  • Added click-outside detection to close search

FileBrowserDialog Component

  • Integrated PathInput search functionality with directory listings
  • Replaced inline <kbd> element with new Kbd/KbdGroup components for better consistency
  • Added focus:outline-none to DialogContent for cleaner focus states
  • Passed directory entries to PathInput for search functionality

UX Improvements

  • Users can now quickly search through directories without scrolling
  • Keyboard-first workflow with / and ESC shortcuts
  • Visual distinction between files and folders in search results
  • Consistent keyboard shortcut display across the application

Screenshots

image_2025-12-25_00-41-39 image_2025-12-25_01-04-28

Summary by CodeRabbit

  • New Features

    • Keyboard-driven search overlay in the file browser ("/" to open; Esc, X button, or outside click to close) with searchable file/folder selection, icons, and breadcrumb actions.
    • OS-aware keyboard hints (modifier shows ⌘ on Mac, Ctrl otherwise).
  • UI Improvements

    • Grouped keyboard key visuals and improved dialog focus styling; added inline search and edit controls in the path input.
  • Bug Fixes

    • Directory entries now open folders while other entries trigger selection.

✏️ Tip: You can customize this high-level summary in your review settings.

- Added Kbd and KbdGroup components for keyboard shortcuts in FileBrowserDialog.
- Implemented search functionality in PathInput, allowing users to search files and directories.
- Updated PathInput to handle file system entries and selection from search results.
- Improved UI/UX with better focus management and search input handling.
@coderabbitai
Copy link

coderabbitai bot commented Dec 25, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds OS-detection hook and keyboard UI (Kbd, KbdGroup); extends PathInput with FileSystemEntry, entries, and onSelectEntry plus a Command-style searchable overlay (trigger /); updates FileBrowserDialog to supply directory entries, use keyboard hint UI, and only navigate on directory selection.

Changes

Cohort / File(s) Summary
Keyboard UI components
apps/ui/src/components/ui/kbd.tsx
New Kbd and KbdGroup components exported for styled keyboard key hints.
OS detection hook
apps/ui/src/hooks/use-os-detection.ts, apps/ui/src/hooks/index.ts
New useOSDetection hook (and types) added; re-exported from hooks index.
PathInput search & API
apps/ui/src/components/ui/path-input.tsx
Added FileSystemEntry type; extended PathInputProps with searchPlaceholder, entries, and onSelectEntry; implemented Command-style search overlay (trigger /), entry rendering, keyboard/escape and outside-click handling, and selection callback.
File browser integration
apps/ui/src/components/dialogs/file-browser-dialog.tsx
Passes directory entries and onSelectEntry into PathInput; uses useOSDetection to render OS-aware keyboard hint (KbdGroup); restricts directory navigation handler to directory entries; minor focus-style adjustments.

Sequence Diagram(s)

sequenceDiagram
    rect rgba(240,248,255,0.7)
    participant User
    participant FileBrowserDialog
    participant PathInput
    participant SearchOverlay
    end

    User->>FileBrowserDialog: Open dialog
    User->>PathInput: Press "/"
    PathInput->>SearchOverlay: Open search overlay (focus)
    User->>SearchOverlay: Type query
    SearchOverlay->>SearchOverlay: Filter `entries` (files & dirs)
    User->>SearchOverlay: Select entry
    alt entry.isDirectory
        SearchOverlay->>PathInput: onSelectEntry(directory)
        PathInput->>FileBrowserDialog: handleSelectDirectory(directory.path)
        FileBrowserDialog->>FileBrowserDialog: Navigate into directory
    else file selected
        SearchOverlay->>PathInput: onSelectEntry(file)
        PathInput->>FileBrowserDialog: (file selection callback)
    end
    FileBrowserDialog->>PathInput: Close overlay / update path
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • Shironex

Poem

🐇
I hopped on slash and opened a lane,
Keys in a row, a tidy refrain,
Folders and files answer my call,
Return takes me where the directories fall,
A little rabbit cheers this change! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the primary change: adding search functionality to PathInput with keyboard shortcut support, which aligns with the main objectives and code changes.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @illia1f, 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 enhances the PathInput component by adding a robust search functionality, making it easier and faster for users to navigate and select files or directories. The implementation focuses on a keyboard-first experience, introducing intuitive shortcuts and new reusable UI components for displaying keyboard commands. This change streamlines the file browsing process, particularly within the FileBrowserDialog, by providing quick search access and improved visual consistency.

Highlights

  • Search Functionality in PathInput: Introduced a new search feature within the PathInput component, enabling fuzzy searching of files and directories.
  • Keyboard Shortcut Support: Implemented keyboard shortcuts ('/' to open search, 'ESC' to close) for a more efficient user workflow.
  • Reusable Kbd Components: Created Kbd and KbdGroup UI components for consistent and styled display of keyboard shortcuts across the application.
  • FileBrowserDialog Integration: Integrated the new search capabilities into the FileBrowserDialog, allowing users to search through directory listings.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

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
Contributor

@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 introduces a valuable search functionality to the PathInput component, complete with keyboard shortcuts, which significantly improves user experience. The implementation is generally well-executed, including the creation of reusable Kbd components. My review highlights a few areas for improvement to enhance correctness, maintainability, and robustness. Specifically, I've pointed out a component type definition that needs correction, an opportunity to simplify a useEffect hook for better readability, and a syntax error in a Tailwind CSS class name that needs fixing.

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.

Actionable comments posted: 1

🧹 Nitpick comments (3)
apps/ui/src/components/dialogs/file-browser-dialog.tsx (1)

376-383: navigator.platform is deprecated.

navigator.platform is deprecated and may be removed in future browser versions. Consider using navigator.userAgentData?.platform with a fallback, or a simple heuristic based on navigator.userAgent.

🔎 Proposed fix
 <KbdGroup className="ml-1">
   <Kbd>
-    {typeof navigator !== 'undefined' && navigator.platform?.includes('Mac')
+    {typeof navigator !== 'undefined' &&
+    (navigator.userAgentData?.platform === 'macOS' ||
+      navigator.platform?.includes('Mac'))
       ? '⌘'
       : 'Ctrl'}
   </Kbd>
   <Kbd>↵</Kbd>
 </KbdGroup>
apps/ui/src/components/ui/path-input.tsx (2)

322-324: Inconsistent keyboard hint styling.

This inline <kbd> element should use the new Kbd component for visual consistency across the codebase.

🔎 Proposed fix

First, add the import at the top of the file:

+import { Kbd } from '@/components/ui/kbd';

Then update the inline kbd:

-                      <kbd className="hidden sm:inline-block px-1.5 py-0.5 text-[10px] bg-muted rounded border border-border text-muted-foreground">
-                        ESC
-                      </kbd>
+                      <Kbd className="hidden sm:inline-block">ESC</Kbd>

130-143: Consider using a ref callback instead of setTimeout for focus management.

Using setTimeout(..., 0) to wait for the DOM is fragile and may fail if the Command component defers its own rendering. A ref callback or requestAnimationFrame can be more reliable, though for a simple case like this the current approach is acceptable.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8a02265 and bed8038.

📒 Files selected for processing (3)
  • apps/ui/src/components/dialogs/file-browser-dialog.tsx
  • apps/ui/src/components/ui/kbd.tsx
  • apps/ui/src/components/ui/path-input.tsx
🧰 Additional context used
🧬 Code graph analysis (2)
apps/ui/src/components/ui/path-input.tsx (3)
apps/ui/src/components/ui/button.tsx (1)
  • Button (108-108)
apps/ui/src/lib/utils.ts (1)
  • cn (5-7)
apps/ui/src/components/ui/breadcrumb.tsx (6)
  • Breadcrumb (95-95)
  • BreadcrumbList (96-96)
  • BreadcrumbItem (97-97)
  • BreadcrumbPage (99-99)
  • BreadcrumbLink (98-98)
  • BreadcrumbSeparator (100-100)
apps/ui/src/components/ui/kbd.tsx (1)
apps/ui/src/lib/utils.ts (1)
  • cn (5-7)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: e2e
🔇 Additional comments (5)
apps/ui/src/components/dialogs/file-browser-dialog.tsx (1)

256-261: LGTM!

The PathInput integration correctly maps directories to the expected FileSystemEntry format and properly handles entry selection by navigating only into directories.

apps/ui/src/components/ui/path-input.tsx (4)

226-249: LGTM on global keyboard shortcuts.

The implementation correctly:

  • Uses capture phase to intercept events before other handlers
  • Prevents "/" from being typed into input/textarea elements
  • Uses stopPropagation() on Escape to prevent parent modal from closing
  • Cleans up event listeners properly

251-264: LGTM on click-outside handling.

The mousedown event is appropriate here as it fires before focus changes, ensuring the search closes before any other element receives focus.


63-67: LGTM!

Clean interface definition with appropriate properties for file system entries.


303-350: Search popover implementation looks solid.

The Command-based search UI is well-structured with proper accessibility labels, keyboard navigation, and visual distinction between files and directories.

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.

Actionable comments posted: 1

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bed8038 and cd30306.

📒 Files selected for processing (2)
  • apps/ui/src/components/ui/kbd.tsx
  • apps/ui/src/components/ui/path-input.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
apps/ui/src/components/ui/kbd.tsx (1)
apps/ui/src/lib/utils.ts (1)
  • cn (5-7)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: e2e
🔇 Additional comments (15)
apps/ui/src/components/ui/kbd.tsx (2)

3-16: LGTM! Clean implementation of the Kbd component.

The component is properly typed, uses data-slot for styling hooks, and includes comprehensive styling for various use cases including tooltip content.


18-26: LGTM! Type mismatch resolved.

The component now correctly uses React.ComponentProps<'span'> and renders a <span> element, addressing the previous review concerns. The use of <span> is semantically appropriate for grouping Kbd components.

apps/ui/src/components/ui/path-input.tsx (13)

3-3: LGTM! Appropriate icon additions.

The new icons (Search, Folder, File, X) support the search functionality and visual distinction between file types.


14-21: LGTM! Command component imports.

These imports are necessary for the new search overlay functionality using the Command component.


63-67: LGTM! Clean FileSystemEntry interface.

The interface is well-defined with clear properties for representing file system entries. The isDirectory boolean provides necessary distinction between files and folders.


80-91: LGTM! Well-documented prop additions.

The new props for search functionality are properly typed and documented with clear JSDoc comments. The optional nature of these props maintains backward compatibility.


100-108: LGTM! Proper state and prop defaults.

The component properly destructures the new props with sensible defaults (searchPlaceholder, entries, onSelectEntry) and adds the isSearchOpen state for managing search visibility.


201-209: LGTM! Clean entry selection handler.

The callback correctly invokes the parent's onSelectEntry handler when provided and properly closes the search overlay. Dependencies are correct.


211-234: LGTM! Comprehensive keyboard shortcut handling.

The global keyboard shortcuts are well-implemented:

  • / opens search (excluded when in input fields)
  • Escape closes search with intentional stopPropagation to prevent parent modal closure
  • Uses capture phase for reliable event interception
  • Proper dependency array

236-249: LGTM! Standard click-outside pattern.

The effect properly closes the search overlay when clicking outside, using mousedown event for reliable detection and including proper cleanup.


290-310: LGTM! Clean search overlay implementation.

The search popover is properly positioned with good z-index management. The use of autoFocus on the CommandInput (line 297) addresses previous review feedback and provides a better user experience.


316-334: LGTM! Clean search results rendering.

The search results properly distinguish between directories and files using appropriate icons and styling. The use of CommandList, CommandEmpty, and CommandItem follows the Command component patterns correctly.


341-349: LGTM! Proper click handling.

The container click handler correctly excludes the search open state (line 190) and prevents triggering when clicking buttons or links.


351-404: LGTM! Well-structured breadcrumb view with integrated controls.

The breadcrumb display is clean and includes properly positioned search and edit buttons. The search button is appropriately disabled when there are no entries to search (line 390), providing good UX feedback.


405-432: LGTM! Clean input mode implementation.

The input view provides a straightforward text input with a go button, proper keyboard handling (Enter/Escape), and appropriate disabled states. All accessibility attributes are in place.

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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/ui/src/components/ui/path-input.tsx (1)

318-331: Consider memoizing the entry list rendering.

The entries mapping is not memoized and will re-render on every component render. For directories with many files (hundreds or thousands), this could impact performance.

🔎 Proposed optimization

Memoize the entry items:

+  const entryItems = useMemo(
+    () =>
+      entries.map((entry) => (
+        <CommandItem
+          key={entry.path}
+          value={entry.name}
+          onSelect={() => handleSelectEntry(entry)}
+        >
+          {entry.isDirectory ? (
+            <Folder className="w-3.5 h-3.5 text-brand-500 mr-2" />
+          ) : (
+            <File className="w-3.5 h-3.5 text-muted-foreground mr-2" />
+          )}
+          <span className="flex-1 truncate font-mono text-xs">{entry.name}</span>
+        </CommandItem>
+      )),
+    [entries, handleSelectEntry]
+  );

   <CommandList className="scrollbar-styled">
     <CommandEmpty>No files or directories found</CommandEmpty>
     <CommandGroup>
-      {entries.map((entry) => (
-        <CommandItem
-          key={entry.path}
-          value={entry.name}
-          onSelect={() => handleSelectEntry(entry)}
-        >
-          {entry.isDirectory ? (
-            <Folder className="w-3.5 h-3.5 text-brand-500 mr-2" />
-          ) : (
-            <File className="w-3.5 h-3.5 text-muted-foreground mr-2" />
-          )}
-          <span className="flex-1 truncate font-mono text-xs">{entry.name}</span>
-        </CommandItem>
-      ))}
+      {entryItems}
     </CommandGroup>
   </CommandList>
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd30306 and fd51abb.

📒 Files selected for processing (1)
  • apps/ui/src/components/ui/path-input.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: e2e
🔇 Additional comments (7)
apps/ui/src/components/ui/path-input.tsx (7)

64-68: LGTM!

The FileSystemEntry interface is well-defined with appropriate fields for representing filesystem items in the search functionality.


81-82: LGTM!

The new props are well-designed with appropriate types, sensible defaults, and maintain backward compatibility through optional parameters.

Also applies to: 89-92


202-210: LGTM!

The handleSelectEntry callback correctly invokes the parent handler and manages the search state. The useCallback dependencies are appropriate.


237-250: LGTM!

The click-outside handler correctly detects clicks outside the container and closes the search. The use of mousedown and the conditional setup based on isSearchOpen follow best practices.


289-338: LGTM!

The search popover implementation is well-structured with proper positioning, focus management (autoFocus on line 298), and the reusable Kbd component (line 312) for keyboard shortcut display.


382-392: LGTM!

The search button correctly handles the disabled state when no entries are available and includes proper accessibility attributes.


439-439: LGTM!

The exports correctly include the new FileSystemEntry type alongside the existing exports.

- Updated keydown event logic to prevent search activation when input fields or contenteditable elements are focused.
- Enhanced ESC key handling to ensure parent modal does not close when search is open.
- Adjusted dependencies in useEffect to include entries length for better state management.
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.

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/ui/src/components/ui/path-input.tsx (1)

233-234: Clarify the comment about ESC handling mechanism.

The comment states "prevent parent modal from closing when search is open," but it's actually preventDefault() on line 228 (not stopPropagation()) that achieves this. Using capture phase ensures this handler runs before the parent modal's ESC handler, and preventDefault() then prevents the default action.

Consider updating the comment to accurately reflect the mechanism and whether capture phase is necessary for the "/" shortcut (which doesn't need to prevent other handlers).

🔎 Suggested clarification
-    window.addEventListener('keydown', handleGlobalKeyDown, true); // Use capture phase for ESC handling and prevent parent modal from closing when search is open
-    return () => window.removeEventListener('keydown', handleGlobalKeyDown, true);
+    // Use capture phase to handle ESC before parent modal handlers.
+    // preventDefault() on line 228 prevents the parent modal from seeing the ESC key.
+    window.addEventListener('keydown', handleGlobalKeyDown, true);
+    return () => window.removeEventListener('keydown', handleGlobalKeyDown, true);

Alternatively, if you want both shortcuts to use standard bubble phase (and only preventDefault for ESC):

-    window.addEventListener('keydown', handleGlobalKeyDown, true); // Use capture phase for ESC handling and prevent parent modal from closing when search is open
-    return () => window.removeEventListener('keydown', handleGlobalKeyDown, true);
+    window.addEventListener('keydown', handleGlobalKeyDown);
+    return () => window.removeEventListener('keydown', handleGlobalKeyDown);

Note: The second approach would allow the parent modal to also close when ESC is pressed (both search and modal close together). Choose based on your desired UX.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fd51abb and a7de640.

📒 Files selected for processing (1)
  • apps/ui/src/components/ui/path-input.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
apps/ui/src/components/ui/path-input.tsx (3)
apps/ui/src/components/ui/button.tsx (1)
  • Button (108-108)
apps/ui/src/lib/utils.ts (1)
  • cn (5-7)
apps/ui/src/components/ui/breadcrumb.tsx (6)
  • Breadcrumb (95-95)
  • BreadcrumbList (96-96)
  • BreadcrumbItem (97-97)
  • BreadcrumbPage (99-99)
  • BreadcrumbLink (98-98)
  • BreadcrumbSeparator (100-100)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: e2e
🔇 Additional comments (7)
apps/ui/src/components/ui/path-input.tsx (7)

64-68: LGTM! Well-defined interface for filesystem entries.

The FileSystemEntry interface is clean and appropriately typed for representing files and directories in the search functionality.


81-92: LGTM! New props are well-designed and documented.

The new props for search functionality (searchPlaceholder, entries, onSelectEntry) have appropriate defaults and are properly documented, maintaining backward compatibility.


202-210: LGTM! Entry selection handler is well-implemented.

The handleSelectEntry callback correctly invokes the parent callback and closes the search overlay, with proper memoization.


237-250: LGTM! Click-outside handler follows best practices.

The implementation correctly uses mousedown instead of click and properly checks containment before closing the search overlay.


289-338: LGTM! Search overlay is well-implemented with good accessibility.

The search UI properly uses the Command component pattern with:

  • Auto-focus for immediate typing
  • Clear visual distinction between files and folders
  • Accessible close button
  • Keyboard hint (ESC) displayed with the Kbd component

All previously flagged issues have been addressed.


381-402: LGTM! Search and edit buttons are well-integrated.

The new action buttons properly:

  • Disable the search button when no entries are available (consistent with the "/" keyboard shortcut)
  • Provide clear aria-labels and titles
  • Use appropriate sizing and styling
  • Maintain layout stability with the shrink-0 class

439-439: LGTM! All necessary types are exported.

The export includes the new FileSystemEntry type, enabling consumers to properly type their entries arrays and onSelectEntry callbacks.

@Shironex Shironex added Enhancement Improvements to existing functionality or UI. Ready-To-Merge A feature or bug has been improved/fixed and a final review is requested before merging. labels Dec 25, 2025
…ndling in comments

- Replaced inline entry mapping with a memoized entryItems component for improved performance.
- Clarified keydown event handling comments to enhance understanding of ESC key behavior in relation to modal interactions.
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.

Actionable comments posted: 1

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a7de640 and 1c59eab.

📒 Files selected for processing (1)
  • apps/ui/src/components/ui/path-input.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: e2e
🔇 Additional comments (3)
apps/ui/src/components/ui/path-input.tsx (3)

64-68: LGTM on FileSystemEntry type and memoized rendering.

The FileSystemEntry type is clean and well-suited for the search functionality. The entryItems memoization is a good optimization for potentially large directory listings, ensuring CommandItem elements aren't recreated on every render.

Also applies to: 256-269


306-340: LGTM on search popover implementation.

The Command-based search UI is well-structured with proper focus management (autoFocus), consistent keyboard hint display using the Kbd component, and appropriate accessibility attributes. The overlay positioning and max-height constraint provide good UX for the search results.


384-394: Good consistency between button state and keyboard shortcut.

The search button's disabled state (entries.length === 0) correctly matches the "/" keyboard shortcut condition on line 220, preventing inconsistent behavior between mouse and keyboard users.

… does not close when the search is active and the ESC key is pressed
…improved keyboard shortcut handling

- Introduced useOSDetection hook to determine the user's operating system.
- Updated FileBrowserDialog to utilize the OS detection for displaying the correct keyboard shortcut (⌘ or Ctrl) based on the detected OS.
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.

Actionable comments posted: 0

🧹 Nitpick comments (2)
apps/ui/src/hooks/use-os-detection.ts (1)

38-47: Consider removing useMemo for simpler implementation.

The useMemo with an empty dependency array doesn't provide meaningful performance benefits here since detectOS() is a synchronous pure function. The hook could be simplified:

🔎 Optional refactor to remove useMemo
 export function useOSDetection(): OSDetectionResult {
-  return useMemo(() => {
-    const os = detectOS();
-    return {
-      os,
-      isMac: os === 'mac',
-      isWindows: os === 'windows',
-      isLinux: os === 'linux',
-    };
-  }, []);
+  const os = detectOS();
+  return {
+    os,
+    isMac: os === 'mac',
+    isWindows: os === 'windows',
+    isLinux: os === 'linux',
+  };
 }

This also removes the now-unused useMemo import. However, if you expect to add stateful logic or effects in the future, keeping the memoization is fine.

apps/ui/src/components/dialogs/file-browser-dialog.tsx (1)

258-263: Optional: Remove redundant isDirectory check.

Since entries only contains directories (all mapped with isDirectory: true), the conditional check on line 260 is redundant. You could simplify:

🔎 Optional refactor
           entries={directories.map((dir) => ({ ...dir, isDirectory: true }))}
-          onSelectEntry={(entry) => {
-            if (entry.isDirectory) {
-              handleSelectDirectory(entry);
-            }
-          }}
+          onSelectEntry={handleSelectDirectory}

However, the explicit check provides safety if the code evolves to include file entries in the future.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f4b60b and 3d36102.

📒 Files selected for processing (3)
  • apps/ui/src/components/dialogs/file-browser-dialog.tsx
  • apps/ui/src/hooks/index.ts
  • apps/ui/src/hooks/use-os-detection.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: e2e
🔇 Additional comments (7)
apps/ui/src/hooks/use-os-detection.ts (2)

1-10: LGTM! Clean type definitions.

The type definitions are well-structured with appropriate use of readonly properties and literal union types.


12-32: Current code already safely handles bundler polyfill scenarios.

The check on line 14 is correct as written. The typeof process !== 'undefined' guard combined with the truthiness check on process.platform ensures safe access:

  • In Electron: process is the real Node.js global with a platform property
  • In browser without polyfill: typeof process === 'undefined', so the block is skipped
  • In browser with incomplete polyfill: process.platform is undefined (falsy), so the block is skipped and the fallback to navigator.platform is used

The suggested additional type check (typeof process.platform === 'string') is defensive but unnecessary since process.platform is always a non-empty string in Node.js or properly caught as undefined by the existing truthiness check.

apps/ui/src/hooks/index.ts (1)

6-6: LGTM! Proper export pattern.

The export follows the established pattern in this file and correctly includes both the hook and its associated types.

apps/ui/src/components/dialogs/file-browser-dialog.tsx (4)

72-72: LGTM! Clean hook usage.

The hook usage correctly extracts only the needed isMac property for conditional keyboard hint rendering.


238-238: Verify focus removal doesn't impact keyboard navigation accessibility.

Adding focus:outline-none and focus-visible:outline-none removes the default focus indicator. Ensure that:

  1. The Dialog component provides its own focus management
  2. Keyboard users can still identify which element has focus
  3. This aligns with WCAG 2.4.7 (Focus Visible) guidelines

If custom focus indicators aren't implemented elsewhere, consider removing these classes or implementing alternative focus styling.


378-381: LGTM! Clean keyboard hint implementation.

The keyboard hint correctly displays platform-specific modifier keys (⌘ for Mac, Ctrl for others) and uses the universal return symbol (↵). The implementation is clean and follows good UX patterns.


13-13: Imports are valid. The Kbd and KbdGroup components exist in apps/ui/src/components/ui/kbd.tsx and are properly exported.

@webdevcody webdevcody merged commit 2caa63a into AutoMaker-Org:main Dec 26, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement Improvements to existing functionality or UI. Ready-To-Merge A feature or bug has been improved/fixed and a final review is requested before merging.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants