Skip to content

Commit

Permalink
Tabs bug (#336)
Browse files Browse the repository at this point in the history
* add story

* only set focus on active tab if tabs component has focus

* add search and tabs story

* don’t overwrite onBlur and onFocus event listeners

* clean up
  • Loading branch information
vnys authored Jun 2, 2020
1 parent 58e0a65 commit b0485d4
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 10 deletions.
51 changes: 50 additions & 1 deletion apps/storybook-react/stories/Tabs.stories.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React, { useState, useEffect, createRef, useRef } from 'react'
import styled from 'styled-components'
import { withKnobs, select, text } from '@storybook/addon-knobs'
import { Tabs, Typography } from '@equinor/eds-core-react'
import { Tabs, Typography, Search } from '@equinor/eds-core-react'
import { action } from '@storybook/addon-actions'

const { TabList, Tab, TabPanels, TabPanel } = Tabs

Expand Down Expand Up @@ -99,3 +100,51 @@ export const tabPanels = () => {
</Wrapper>
)
}

export const tabsAndSearch = () => {
const [searchText, setSearchText] = useState('')
const [activeTab, setActiveTab] = useState(0)

const handleOnTextChange = (event) => {
const value = event.target.value
setSearchText(value)
}
const handleChange = (index) => {
setActiveTab(index)
}

const handleFocus = (e) => {
action('handleFocus')(e.target.textContent)
}

const handleBlur = (e) => {
action('handleBlur')(e.target.textContent)
}

return (
<div style={{ margin: '4rem' }}>
<Search
value={searchText}
placeholder={'Search '}
onChange={handleOnTextChange}
/>
<Tabs
style={{ marginTop: '2rem' }}
activeTab={activeTab}
onChange={handleChange}
variant="fullWidth"
onFocus={handleFocus}
onBlur={handleBlur}
>
<TabList>
<Tab>Tags (5+)</Tab>
<Tab> Docs (5+)</Tab>
</TabList>
<TabPanels>
<TabPanel>Panel one</TabPanel>
<TabPanel>Panel two</TabPanel>
</TabPanels>
</Tabs>
</div>
)
}
17 changes: 11 additions & 6 deletions libraries/core-react/src/Tabs/TabList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,20 @@ const StyledTabList = styled.div.attrs(() => ({
`

const TabList = forwardRef(function TabsList({ children, ...props }, ref) {
const { activeTab, handleChange, tabsId, variant } = useContext(TabsContext)
const { activeTab, handleChange, tabsId, variant, tabsFocused } = useContext(
TabsContext,
)

const currentTab = useRef(activeTab)

const selectedTabRef = useCallback((node) => {
if (node !== null) {
node.focus()
}
}, [])
const selectedTabRef = useCallback(
(node) => {
if (node !== null && tabsFocused) {
node.focus()
}
},
[tabsFocused],
)

useEffect(() => {
currentTab.current = activeTab
Expand Down
1 change: 1 addition & 0 deletions libraries/core-react/src/Tabs/Tabs.context.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const TabsContext = createContext({
handleChange: () => {},
activeTab: 0,
tabsId: '',
tabsFocused: false,
})

const TabsProvider = TabsContext.Provider
Expand Down
34 changes: 31 additions & 3 deletions libraries/core-react/src/Tabs/Tabs.jsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,46 @@
import React, { forwardRef, useMemo } from 'react'
import React, { forwardRef, useMemo, useState, useEffect } from 'react'
import PropTypes from 'prop-types'
import createId from 'lodash.uniqueid'
import { TabsProvider } from './Tabs.context'

const Tabs = forwardRef(function Tabs(
{ activeTab, onChange, variant, ...props },
{ activeTab, onChange, onBlur, onFocus, variant, ...props },
ref,
) {
const tabsId = useMemo(() => createId('tabs-'), [])

const [tabsFocused, setTabsFocused] = useState(false)

let blurTimer

const handleBlur = (e) => {
blurTimer = setTimeout(() => {
if (tabsFocused) {
setTabsFocused(false)
}
}, 0)
onBlur(e)
}

const handleFocus = (e) => {
clearTimeout(blurTimer)
if (!tabsFocused) {
setTabsFocused(true)
}
onFocus(e)
}

return (
<TabsProvider
value={{
activeTab,
handleChange: onChange,
tabsId,
variant,
tabsFocused,
}}
>
<div ref={ref} {...props} />
<div ref={ref} {...props} onBlur={handleBlur} onFocus={handleFocus} />
</TabsProvider>
)
})
Expand All @@ -28,6 +50,10 @@ Tabs.propTypes = {
activeTab: PropTypes.number,
/** The callback function for selecting a tab */
onChange: PropTypes.func,
/** The callback function for removing focus from a tab */
onBlur: PropTypes.func,
/** The callback function for focusing on a tab */
onFocus: PropTypes.func,
/** Sets the width of the tabs */
variant: PropTypes.oneOf(['fullWidth', 'minWidth']),
/** @ignore */
Expand All @@ -37,6 +63,8 @@ Tabs.propTypes = {
Tabs.defaultProps = {
activeTab: 0,
onChange: () => {},
onBlur: () => {},
onFocus: () => {},
variant: 'minWidth',
}

Expand Down

0 comments on commit b0485d4

Please sign in to comment.