From 4512dadaeaed3ac0e14fe0f5a2df1baf0ebe5e48 Mon Sep 17 00:00:00 2001 From: bozdoz Date: Wed, 25 Nov 2020 14:08:51 -0400 Subject: [PATCH] feat: Always set focus on tabs BREAKING CHANGE: The tabs are now instantly focused on click. The default styling has been adapted for that, so that there is no outline shown anymore on focus. closes #272 --- src/components/Tabs.js | 37 ++++++++++++++++++------------------- style/react-tabs.css | 4 +--- style/react-tabs.less | 2 -- style/react-tabs.scss | 2 -- 4 files changed, 19 insertions(+), 26 deletions(-) diff --git a/src/components/Tabs.js b/src/components/Tabs.js index f374c66cf..5416b1448 100644 --- a/src/components/Tabs.js +++ b/src/components/Tabs.js @@ -64,42 +64,41 @@ For more information about controlled and uncontrolled mode of react-tabs see ht * It is initialized from the prop defaultFocus, and after the first render it is reset back to false. Later it can become true again when using keys to navigate the tabs. */ const Tabs = (props) => { - const [focus, setFocus] = useState(props.defaultFocus); + const { children, defaultFocus, defaultIndex, onSelect } = props; + + const [focus, setFocus] = useState(defaultFocus); const [mode] = useState(getModeFromProps(props)); const [selectedIndex, setSelectedIndex] = useState( - mode === MODE_UNCONTROLLED ? props.defaultIndex || 0 : null, + mode === MODE_UNCONTROLLED ? defaultIndex || 0 : null, ); - // Reset focus after initial render, see comment above useEffect(() => { + // Reset focus after initial render, see comment above setFocus(false); }, []); if (mode === MODE_UNCONTROLLED) { // Ensure that we handle removed tabs and don't let selectedIndex get out of bounds + const tabsCount = getTabsCount(children); useEffect(() => { if (selectedIndex != null) { - const maxTabIndex = Math.max(0, getTabsCount(props.children) - 1); + const maxTabIndex = Math.max(0, tabsCount - 1); setSelectedIndex(Math.min(selectedIndex, maxTabIndex)); } - }, [getTabsCount(props.children)]); + }, [tabsCount]); } checkForIllegalModeChange(props, mode); const handleSelected = (index, last, event) => { - const { onSelect } = props; - // Call change event handler if (typeof onSelect === 'function') { // Check if the change event handler cancels the tab change if (onSelect(index, last, event) === false) return; } - if (event.type === 'keydown') { - // Set focus if the change was triggered from the keyboard - setFocus(true); - } + // Always set focus on tabs + setFocus(true); if (mode === MODE_UNCONTROLLED) { // Update selected index @@ -107,19 +106,19 @@ const Tabs = (props) => { } }; - let newProps = { ...props }; - const { children } = props; + let subProps = { ...props }; - newProps.focus = focus; - newProps.onSelect = handleSelected; + subProps.focus = focus; + subProps.onSelect = handleSelected; if (selectedIndex != null) { - newProps.selectedIndex = selectedIndex; + subProps.selectedIndex = selectedIndex; } - delete newProps.defaultFocus; - delete newProps.defaultIndex; - return {children}; + delete subProps.defaultFocus; + delete subProps.defaultIndex; + return {children}; }; + Tabs.propTypes = propTypes; Tabs.defaultProps = defaultProps; Tabs.tabsRole = 'Tabs'; diff --git a/style/react-tabs.css b/style/react-tabs.css index 8bb668b70..eeddde5ba 100644 --- a/style/react-tabs.css +++ b/style/react-tabs.css @@ -32,13 +32,11 @@ } .react-tabs__tab:focus { - box-shadow: 0 0 5px hsl(208, 99%, 50%); - border-color: hsl(208, 99%, 50%); outline: none; } .react-tabs__tab:focus:after { - content: ""; + content: ''; position: absolute; height: 5px; left: -4px; diff --git a/style/react-tabs.less b/style/react-tabs.less index 87c792e1c..73264d418 100644 --- a/style/react-tabs.less +++ b/style/react-tabs.less @@ -30,8 +30,6 @@ } &:focus { - box-shadow: 0 0 5px hsl(208, 99%, 50%); - border-color: hsl(208, 99%, 50%); outline: none; &:after { diff --git a/style/react-tabs.scss b/style/react-tabs.scss index 87c792e1c..73264d418 100644 --- a/style/react-tabs.scss +++ b/style/react-tabs.scss @@ -30,8 +30,6 @@ } &:focus { - box-shadow: 0 0 5px hsl(208, 99%, 50%); - border-color: hsl(208, 99%, 50%); outline: none; &:after {