UNPKG

@equinor/eds-core-react

Version:

The React implementation of the Equinor Design System

95 lines (91 loc) 2.56 kB
import { forwardRef, useRef, useMemo, useState, useEffect } from 'react'; import { TabsProvider } from './Tabs.context.js'; import { token } from './Tabs.tokens.js'; import { useId, mergeRefs, useToken } from '@equinor/eds-utils'; import { ThemeProvider } from 'styled-components'; import { jsx } from 'react/jsx-runtime'; import { useEds } from '../EdsProvider/eds.context.js'; const Tabs = /*#__PURE__*/forwardRef(function Tabs({ activeTab = 0, onChange = () => null, onBlur, onFocus, variant = 'minWidth', scrollable = false, id, ...props }, ref) { const tabsId = useId(id, 'tabs'); const tabsRef = useRef(null); const combinedTabsRef = useMemo(() => mergeRefs(tabsRef, ref), [tabsRef, ref]); const [tabsFocused, setTabsFocused] = useState(false); const [listenerAttached, setListenerAttached] = useState(false); let blurTimer; const handleBlur = e => { setListenerAttached(false); if (tabsRef.current) { tabsRef.current.removeEventListener('keyup', checkIfTabWasPressed); } blurTimer = setTimeout(() => { if (tabsFocused) { setTabsFocused(false); } }, 0); onBlur && onBlur(e); }; const handleFocus = e => { if (e.target.getAttribute('role') !== 'tab') { return; } clearTimeout(blurTimer); if (tabsFocused) return; if (!listenerAttached) { if (tabsRef.current) { setListenerAttached(true); tabsRef.current.addEventListener('keyup', checkIfTabWasPressed, { once: true, capture: true }); } } onFocus && onFocus(e); }; //Only force focus on active Tab if Tabs was navigated to with keyboard const checkIfTabWasPressed = event => { setListenerAttached(false); if (event.key === 'Tab') setTabsFocused(true); }; useEffect(() => { const tabs = tabsRef.current; return () => { if (tabs) tabs.removeEventListener('keyup', checkIfTabWasPressed); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const { density } = useEds(); const token$1 = useToken({ density }, token); return /*#__PURE__*/jsx(ThemeProvider, { theme: token$1, children: /*#__PURE__*/jsx(TabsProvider, { value: { activeTab, handleChange: onChange, tabsId, variant, scrollable, tabsFocused }, children: /*#__PURE__*/jsx("div", { ref: combinedTabsRef, ...props, onBlur: handleBlur, onFocus: handleFocus }) }) }); }); export { Tabs };