Conversation
✅ Deploy Preview for hyprnote-storybook canceled.
|
✅ Deploy Preview for hyprnote canceled.
|
|
|
||
| useHotkeys( | ||
| "mod+alt+left", | ||
| "meta+alt+left", |
There was a problem hiding this comment.
🔴 Changing mod to meta breaks top-level tab navigation on Windows/Linux
The hotkey for switching between top-level tabs was changed from mod+alt+left/right to meta+alt+left/right. In react-hotkeys-hook, mod is a cross-platform alias that maps to Meta (Cmd) on macOS and Control on Windows/Linux, whereas meta always maps to the Meta key specifically (Cmd on macOS, Windows key on Windows/Linux).
Root Cause and Impact
On macOS this change has no effect (both mod and meta resolve to Cmd). However, on Windows/Linux the shortcut changes from Ctrl+Alt+Left/Right to Win+Alt+Left/Right. The Win+Alt+Arrow combination is typically intercepted by the OS for window management, making the shortcut effectively unusable.
Every other hotkey in this file (index.tsx:851, index.tsx:868, index.tsx:879, index.tsx:915, etc.) consistently uses mod for cross-platform compatibility. The new sub-tab navigation shortcuts in ai.tsx:110 and settings.tsx:103 use ctrl+alt+left/right, which would have conflicted with the old mod+alt+left/right on Windows/Linux (since mod = Ctrl there). It appears the intent was to separate the two shortcuts on all platforms, but meta is the wrong choice for Windows/Linux — the top-level shortcut should likely remain mod+alt+left/right and the sub-tab shortcut should use a different key combination entirely.
Impact: Top-level tab navigation via keyboard is completely broken on Windows/Linux.
Prompt for agents
The root problem is that on Windows/Linux, `mod` resolves to `Ctrl`, so both the top-level tab navigation (`mod+alt+left/right`) and the new sub-tab navigation (`ctrl+alt+left/right`) would use the same physical keys. Simply reverting `meta` back to `mod` at lines 934 and 945 in index.tsx would restore Windows/Linux support but re-introduce the conflict with the sub-tab shortcuts in ai.tsx and settings.tsx. You need to pick a different key combination for one of the two levels. For example, keep `mod+alt+left/right` for top-level tabs (lines 934 and 945 in index.tsx) and change the sub-tab navigation in ai.tsx (lines 110, 125) and settings.tsx (lines 103, 118) to a non-conflicting shortcut such as `ctrl+shift+left/right` or `alt+left/right`.
Was this helpful? React with 👍 or 👎 to provide feedback.
Replace focus and aria-selected classes with data-selected attribute for better visual feedback when options are selected. This provides more consistent styling behavior across different interaction states.
Add Ctrl+Alt+Left/Right hotkeys to navigate between tabs in AI and Settings components. Import react-hotkeys-hook and implement tab switching logic that cycles through available sections. Change existing navigation hotkeys from 'mod' to 'meta' modifier in main body component to avoid conflicts with new tab navigation shortcuts.
Add visual highlight styling for active settings items during keyboard navigation. Implements background color, border radius, box shadow, and padding adjustments to improve accessibility and user experience when navigating settings with keyboard.
Implement keyboard navigation for settings panels with arrow key movement and space/enter activation. Add visual highlighting with smooth scrolling and click-to-select functionality. Include smart detection to disable navigation when editing fields or when popovers are open to prevent conflicts with existing interactions.
Add data-settings-item and data-settings-activate attributes to settings components and integrate useSettingsNavigation hook. The data attributes enable keyboard navigation and accessibility features for settings panels. The hook provides programmatic navigation between different settings items and their interactive elements like buttons and switches.
Remove URL validation and HTTPS API key requirement from aiProviderSchema. Change base_url from z.url() to z.string() and remove the refine validation that enforced API keys for HTTPS URLs to make the schema more flexible.
f8cc6e2 to
da07a02
Compare
| useHotkeys( | ||
| "ctrl+alt+left", | ||
| () => { | ||
| if (currentIndex > 0) { | ||
| setActiveTab(enabledMenuKeys[currentIndex - 1]); | ||
| } | ||
| }, | ||
| { | ||
| preventDefault: true, | ||
| enableOnFormTags: true, | ||
| enableOnContentEditable: true, | ||
| }, | ||
| [currentIndex, setActiveTab], | ||
| ); | ||
|
|
||
| useHotkeys( | ||
| "ctrl+alt+right", | ||
| () => { | ||
| if (currentIndex >= 0 && currentIndex < enabledMenuKeys.length - 1) { | ||
| setActiveTab(enabledMenuKeys[currentIndex + 1]); | ||
| } | ||
| }, | ||
| { | ||
| preventDefault: true, | ||
| enableOnFormTags: true, | ||
| enableOnContentEditable: true, | ||
| }, | ||
| [currentIndex, setActiveTab], | ||
| ); |
There was a problem hiding this comment.
🚩 ctrl+alt+left/right hotkey collision between AI/Settings sub-tabs and note-input tabs
The new ctrl+alt+left/right hotkeys added here and in settings.tsx:104-131 use the same key combination as the pre-existing hotkeys in apps/desktop/src/components/main/body/sessions/note-input/index.tsx:352-394. In react-hotkeys-hook, all mounted handlers for the same key fire. If both the AI/Settings view and the note-input view are mounted simultaneously (e.g., multiple tabs rendered in the DOM), pressing ctrl+alt+left would trigger both handlers. However, based on the tab rendering pattern (conditional rendering with {activeTab === ...}), only the active tab's content component should be mounted, which likely prevents the conflict. This warrants investigation to confirm that inactive tab content is truly unmounted rather than hidden.
Was this helpful? React with 👍 or 👎 to provide feedback.
| function hasOpenPopover(): boolean { | ||
| return ( | ||
| document.querySelector( | ||
| '[aria-expanded="true"], [data-state="open"][role="dialog"]', | ||
| ) !== null | ||
| ); | ||
| } |
There was a problem hiding this comment.
🚩 hasOpenPopover uses global document query — may match unrelated elements
The hasOpenPopover() function at line 23-29 queries the entire document for [aria-expanded="true"] or [data-state="open"][role="dialog"]. This is a global check — it will match any element in the document with these attributes, not just those within the settings panel. For example, a combobox in the header, a tooltip, or a dropdown in a different part of the app could cause hasOpenPopover() to return true, blocking keyboard navigation in settings even though the popover is unrelated. Scoping the query to the scrollRef container would be more precise, though it depends on whether Radix popovers portal outside the container (they typically do, rendering to document.body). This is a tradeoff: scoping would miss portaled popovers, but global matching creates false positives.
Was this helpful? React with 👍 or 👎 to provide feedback.
| useHotkeys( | ||
| "down", | ||
| (e) => { | ||
| e.preventDefault(); | ||
| navigate("down"); | ||
| }, | ||
| { enableOnFormTags: false }, | ||
| [navigate], | ||
| ); | ||
|
|
||
| useHotkeys( | ||
| "up", | ||
| (e) => { | ||
| e.preventDefault(); | ||
| navigate("up"); | ||
| }, | ||
| { enableOnFormTags: false }, | ||
| [navigate], | ||
| ); |
There was a problem hiding this comment.
🚩 Arrow key hotkeys may interfere with SearchableSelect and other interactive widgets
The useSettingsNavigation hook registers global up/down arrow key handlers with enableOnFormTags: false. While this prevents interference when focused on <input>, <textarea>, or <select> elements, it does NOT prevent interference with custom interactive components like the SearchableSelect (which uses Radix Command internally and relies on arrow keys for option navigation). When the SearchableSelect popover is open, the hasOpenPopover check ([aria-expanded="true"]) should catch it and bail out of the navigate function. However, the useHotkeys handler still calls e.preventDefault() at useSettingsNavigation.ts:117 before calling navigate(), which internally checks hasOpenPopover. This means the arrow key default behavior may be prevented even when a popover is open, potentially breaking keyboard navigation within popovers.
Was this helpful? React with 👍 or 👎 to provide feedback.
Uh oh!
There was an error while loading. Please reload this page.