import * as React from "react"; import { Tabs as ReactTabs, TabList, TabPanel } from "react-tabs"; import { injectGlobal, cx } from "@emotion/css"; import { TabItemProps } from "./TabItem"; import { TabTitle } from ".."; import { fontWeightMedium, themeTextColorPrimary, themeBrandPrimary, themeBgHover } from "../../design-tokens/build/js/designTokens"; import { listReset } from "../../shared/styles/styleUtils"; import { BreakpointConfig } from "../../shared/styles/breakpoints"; import { fullHeightTabs, getTabLayout } from "../style"; export const defaultTabDirection = "horiz"; // Copy & paste from node_modules/react-tabs/style/react-tabs.css // Also changed to better fit the ui kit styles. // This is needed to give the tabs a style /* eslint-disable */ injectGlobal` .react-tabs { -webkit-tap-highlight-color: transparent; } .react-tabs__tab-list { ${listReset}; } .react-tabs__tab { position: relative; cursor: pointer; font-weight: ${fontWeightMedium}; color: ${themeTextColorPrimary}; &:after{ content: ""; position: absolute; background: ${themeBrandPrimary}; display: none; } } .react-tabs__tab:focus { outline: none; background: ${themeBgHover} } .react-tabs__tab--selected { &:after{ display: block; } color: ${themeBrandPrimary}; } .react-tabs__tab--disabled { color: GrayText; cursor: default; } .react-tabs__tab-panel { display: none; flex-grow: 1; } .react-tabs__tab-panel--selected { display: block; } `; /* eslint-enable */ export type TabDirections = "horiz" | "vert"; export type TabDirection = BreakpointConfig; export type TabSelected = string; export interface TabsProps { children: | Array> | React.ReactElement; selectedIndex?: number; onSelect?: (tabIndex: number) => void; direction?: TabDirection; } const Tabs = ({ children, selectedIndex, onSelect, direction = defaultTabDirection }: TabsProps) => { const { tabs, tabsContent } = ( React.Children.toArray(children) as Array> ) .filter(item => React.isValidElement(item)) .reduce<{ tabs: React.ReactNode[]; tabsContent: React.ReactNode[]; }>( (acc, item) => { const { tabs = [], tabsContent = [] } = acc; const { children } = item.props; const key = item.key ? item.key : undefined; const childrenWithKeys = React.Children.toArray(children).map( (child, index) => React.isValidElement(child) ? React.cloneElement(child, { key: `${key}-${index}` }) : child ); const title = childrenWithKeys.find( child => React.isValidElement(child) && child.type === TabTitle ); const tabChildren = childrenWithKeys.filter( child => !(React.isValidElement(child) && child.type === TabTitle) ); return { tabs: [...tabs, title], tabsContent: [ ...tabsContent, ...(tabChildren.length ? [{tabChildren}] : []) ] }; }, { tabs: [], tabsContent: [] } ); return ( {}} data-cy="tabs" > {tabs} {tabsContent} ); }; export default React.memo(Tabs);