Skip to content

Commit 3518152

Browse files
committed
feat: make tab hotkeys work
1 parent d130ceb commit 3518152

File tree

1 file changed

+62
-9
lines changed

1 file changed

+62
-9
lines changed

src/renderer/components/TabBar.tsx

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,102 @@
1-
import React from 'react';
2-
import { Flex, Box, Text, IconButton } from '@radix-ui/themes';
1+
import React, { useCallback } from 'react';
2+
import { Flex, Box, Text, IconButton, Kbd } from '@radix-ui/themes';
33
import { Cross2Icon } from '@radix-ui/react-icons';
44
import { useTabStore } from '../stores/tabStore';
55
import { useHotkeys } from 'react-hotkeys-hook';
66

77
export function TabBar() {
88
const { tabs, activeTabId, setActiveTab, closeTab } = useTabStore();
99

10-
// Keyboard shortcuts for tab navigation
11-
useHotkeys('cmd+shift+[, ctrl+shift+[', () => {
10+
// Keyboard navigation handlers
11+
const handlePrevTab = useCallback(() => {
1212
const currentIndex = tabs.findIndex(tab => tab.id === activeTabId);
1313
if (currentIndex > 0) {
1414
setActiveTab(tabs[currentIndex - 1].id);
1515
}
1616
}, [tabs, activeTabId, setActiveTab]);
1717

18-
useHotkeys('cmd+shift+], ctrl+shift+]', () => {
18+
const handleNextTab = useCallback(() => {
1919
const currentIndex = tabs.findIndex(tab => tab.id === activeTabId);
2020
if (currentIndex < tabs.length - 1) {
2121
setActiveTab(tabs[currentIndex + 1].id);
2222
}
2323
}, [tabs, activeTabId, setActiveTab]);
2424

25-
useHotkeys('cmd+w, ctrl+w', () => {
25+
const handleCloseTab = useCallback(() => {
26+
console.log('Closing tab');
2627
if (tabs.length > 1) {
2728
closeTab(activeTabId);
2829
}
2930
}, [tabs, activeTabId, closeTab]);
3031

32+
// Tab switching by number handlers
33+
const handleSwitchToTab = useCallback((index: number) => {
34+
if (tabs[index]) {
35+
setActiveTab(tabs[index].id);
36+
}
37+
}, [tabs, setActiveTab]);
38+
39+
const HOTKEYS = {
40+
CTRL_PREV_TAB: 'ctrl+shift+[',
41+
MOD_PREV_TAB: 'mod+shift+[',
42+
CTRL_NEXT_TAB: 'ctrl+shift+]',
43+
MOD_NEXT_TAB: 'mod+shift+]',
44+
CTRL_CLOSE_TAB: 'ctrl+w',
45+
MOD_CLOSE_TAB: 'mod+w',
46+
// Cmd/Ctrl+1 through Cmd/Ctrl+9
47+
...Object.fromEntries(
48+
Array.from({ length: 9 }, (_, i) => [`TAB_${i + 1}`, `mod+${i + 1}, ctrl+${i + 1}`])
49+
),
50+
};
51+
52+
useHotkeys(Object.values(HOTKEYS), (event, { hotkey }) => {
53+
switch (hotkey) {
54+
case HOTKEYS.CTRL_PREV_TAB:
55+
case HOTKEYS.MOD_PREV_TAB:
56+
handlePrevTab();
57+
break;
58+
case HOTKEYS.CTRL_NEXT_TAB:
59+
case HOTKEYS.MOD_NEXT_TAB:
60+
handleNextTab();
61+
break;
62+
case HOTKEYS.MOD_CLOSE_TAB:
63+
case HOTKEYS.CTRL_CLOSE_TAB:
64+
handleCloseTab();
65+
break;
66+
default: {
67+
// Check if it's a tab switching shortcut
68+
const tabMatch = hotkey.match(/[1-9]/);
69+
if (tabMatch) {
70+
const tabIndex = parseInt(tabMatch[0], 10) - 1;
71+
handleSwitchToTab(tabIndex);
72+
}
73+
break;
74+
}
75+
}
76+
}, [handlePrevTab, handleNextTab, handleCloseTab, handleSwitchToTab]);
77+
3178
return (
3279
<Flex className="drag border-b border-gray-6" height="40px">
3380
{/* Spacer for macOS window controls */}
3481
<Box width="80px" flexShrink="0" />
3582

36-
{tabs.map((tab) => (
83+
{tabs.map((tab, index) => (
3784
<Flex
3885
key={tab.id}
3986
className={`no-drag cursor-pointer border-r border-gray-6 transition-colors group ${tab.id === activeTabId
40-
? 'bg-accent-3 text-accent-12 border-b-2 border-b-accent-8 font-medium'
41-
: 'text-gray-11 hover:bg-gray-3 hover:text-gray-12'
87+
? 'bg-accent-3 text-accent-12 border-b-2 border-b-accent-8 font-medium'
88+
: 'text-gray-11 hover:bg-gray-3 hover:text-gray-12'
4289
}`}
4390
align="center"
4491
px="4"
4592
onClick={() => setActiveTab(tab.id)}
4693
>
94+
{index < 9 && (
95+
<Kbd size="1" className="mr-2 opacity-70">
96+
{navigator.platform.includes('Mac') ? '⌘' : 'Ctrl+'}{index + 1}
97+
</Kbd>
98+
)}
99+
47100
<Text
48101
size="2"
49102
className={`max-w-[200px] overflow-hidden select-none text-ellipsis whitespace-nowrap ${tab.id === activeTabId ? 'font-medium' : ''

0 commit comments

Comments
 (0)