Skip to content
This repository was archived by the owner on Jul 29, 2025. It is now read-only.

Commit 54224c8

Browse files
authored
fix(tab-bar): Arrow keys should focus adjacent tab (#280)
1 parent 194085d commit 54224c8

File tree

4 files changed

+29
-9
lines changed

4 files changed

+29
-9
lines changed

packages/tab-bar/index.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,14 @@ export default class TabBar extends Component {
6363
getPreviousActiveTabIndex: () => this.state.previousActiveIndex,
6464
getFocusedTabIndex: () => {
6565
const activeElement = document.activeElement;
66-
this.tabList_.forEach((tabList, index) => {
67-
if (tabList.tabElement_.current === activeElement) {
68-
return index;
66+
// cannot use findIndex, not supported in IE11
67+
// cannot use forEach, return statement inside the forEach loop will not return
68+
for (let i = 0; i < this.tabList_.length; i++) {
69+
if (this.tabList_[i].tabElement_.current === activeElement) {
70+
return i;
6971
}
70-
});
72+
}
73+
return -1;
7174
},
7275
getIndexOfTab: (tabToFind) => this.tabList_.indexOf(tabToFind),
7376
getTabListLength: () => this.tabList_.length,

packages/tab/TabRipple.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ import withRipple from '@material/react-ripple';
2727

2828
export class TabRipple extends React.Component {
2929

30-
init = (el) => {
31-
this.props.initRipple(el);
32-
}
33-
3430
get classes() {
3531
return classnames('mdc-tab__ripple', this.props.className);
3632
}

packages/tab/index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export default class Tab extends Component {
3434
tabElement_ = React.createRef();
3535
tabContentElement_ = React.createRef();
3636
tabIndicator_ = React.createRef();
37+
tabRipple_ = React.createRef();
3738

3839
state = {
3940
'classList': new Set(),
@@ -153,6 +154,8 @@ export default class Tab extends Component {
153154
role='tab'
154155
aria-selected={ariaSelected}
155156
tabIndex={tabIndex}
157+
onFocus={(e) => this.tabRipple_.current.handleFocus(e)}
158+
onBlur={(e) => this.tabRipple_.current.handleBlur(e)}
156159
ref={this.tabElement_}
157160
{...otherProps}
158161
>
@@ -164,7 +167,7 @@ export default class Tab extends Component {
164167
{isMinWidthIndicator ? this.renderIndicator() : null}
165168
</span>
166169
{isMinWidthIndicator ? null : this.renderIndicator()}
167-
<TabRipple />
170+
<TabRipple ref={this.tabRipple_} />
168171
</button>
169172
);
170173
}

test/unit/tab/index.test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,3 +305,21 @@ test('#componentWillUnmount destroys foundation', () => {
305305
wrapper.unmount();
306306
td.verify(foundation.destroy(), {times: 1});
307307
});
308+
309+
test('on focus event calls handleFocus on TabRipple', () => {
310+
const wrapper = mount(<Tab />);
311+
const ripple = wrapper.instance().tabRipple_.current;
312+
ripple.handleFocus = td.func();
313+
314+
wrapper.simulate('focus');
315+
td.verify(ripple.handleFocus(td.matchers.isA(Object)), {times: 1});
316+
});
317+
318+
test('on blur event calls handleBlur on TabRipple', () => {
319+
const wrapper = mount(<Tab />);
320+
const ripple = wrapper.instance().tabRipple_.current;
321+
ripple.handleBlur = td.func();
322+
323+
wrapper.simulate('blur');
324+
td.verify(ripple.handleBlur(td.matchers.isA(Object)), {times: 1});
325+
});

0 commit comments

Comments
 (0)