Skip to content

Commit 0c26db1

Browse files
Scrollable tabs (#3)
1 parent 8c9af4a commit 0c26db1

File tree

3 files changed

+47
-6
lines changed

3 files changed

+47
-6
lines changed

lib/components/tab.tsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import React, {forwardRef} from 'react';
1+
import React, {useEffect, useRef} from 'react';
22

33
import type {TabProps} from '../../typings/hyper';
44

5-
const Tab = forwardRef<HTMLLIElement, TabProps>((props, ref) => {
5+
const Tab = (props: TabProps) => {
66
const handleClick = (event: React.MouseEvent) => {
77
const isLeftClick = event.nativeEvent.which === 1;
88

@@ -19,6 +19,16 @@ const Tab = forwardRef<HTMLLIElement, TabProps>((props, ref) => {
1919
}
2020
};
2121

22+
const ref = useRef<HTMLLIElement>(null);
23+
24+
useEffect(() => {
25+
if (props.lastFocused) {
26+
ref?.current?.scrollIntoView({
27+
behavior: 'smooth'
28+
});
29+
}
30+
}, [props.lastFocused]);
31+
2232
const {isActive, isFirst, isLast, borderColor, hasActivity} = props;
2333

2434
return (
@@ -60,6 +70,7 @@ const Tab = forwardRef<HTMLLIElement, TabProps>((props, ref) => {
6070
list-style-type: none;
6171
flex-grow: 1;
6272
position: relative;
73+
min-width: 10em;
6374
}
6475
6576
.tab_tab:hover {
@@ -161,7 +172,7 @@ const Tab = forwardRef<HTMLLIElement, TabProps>((props, ref) => {
161172
`}</style>
162173
</>
163174
);
164-
});
175+
};
165176

166177
Tab.displayName = 'Tab';
167178

lib/components/tabs.tsx

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
import React, {forwardRef} from 'react';
1+
import React, {forwardRef, useEffect, useState} from 'react';
22

3-
import type {TabsProps} from '../../typings/hyper';
3+
import debounce from 'lodash/debounce';
4+
5+
import type {ITab, TabsProps} from '../../typings/hyper';
46
import {decorate, getTabProps} from '../utils/plugins';
57

68
import DropdownButton from './new-tab';
@@ -12,6 +14,23 @@ const isMac = /Mac/.test(navigator.userAgent);
1214
const Tabs = forwardRef<HTMLElement, TabsProps>((props, ref) => {
1315
const {tabs = [], borderColor, onChange, onClose, fullScreen} = props;
1416

17+
const [shouldFocusCounter, setShouldFocusCounter] = useState({
18+
index: 0,
19+
when: undefined as Date | undefined
20+
});
21+
22+
const scrollToActiveTab = debounce((currTabs: ITab[]) => {
23+
const activeTab = currTabs.findIndex((t) => t.isActive);
24+
setShouldFocusCounter({
25+
index: activeTab,
26+
when: new Date()
27+
});
28+
}, 100);
29+
30+
useEffect(() => {
31+
scrollToActiveTab(tabs);
32+
}, [tabs, tabs.length]);
33+
1534
const hide = !isMac && tabs.length === 1;
1635

1736
return (
@@ -31,8 +50,12 @@ const Tabs = forwardRef<HTMLElement, TabsProps>((props, ref) => {
3150
isActive,
3251
hasActivity,
3352
onSelect: onChange.bind(null, uid),
34-
onClose: onClose.bind(null, uid)
53+
onClose: onClose.bind(null, uid),
54+
lastFocused: undefined as Date | undefined
3555
});
56+
if (shouldFocusCounter.index === i) {
57+
tabProps.lastFocused = shouldFocusCounter.when;
58+
}
3659
return <Tab key={`tab-${uid}`} {...tabProps} />;
3760
})}
3861
</ul>
@@ -85,6 +108,12 @@ const Tabs = forwardRef<HTMLElement, TabsProps>((props, ref) => {
85108
flex-flow: row;
86109
margin-left: ${isMac ? '76px' : '0'};
87110
flex-grow: 1;
111+
overflow-x: auto;
112+
}
113+
114+
.tabs_list::-webkit-scrollbar,
115+
.tabs_list::-webkit-scrollbar-button {
116+
display: none;
88117
}
89118
90119
.tabs_fullScreen {

typings/hyper.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ export type TabProps = {
230230
onClose: () => void;
231231
onSelect: () => void;
232232
text: string;
233+
lastFocused: Date | undefined;
233234
} & extensionProps;
234235

235236
export type ITab = {

0 commit comments

Comments
 (0)