UNPKG

koval-ui

Version:

React components collection with minimalistic design. Supports theming, layout, and input validation.

1 lines 6.66 kB
{"version":3,"file":"Tabs.cjs","sources":["../../../../src/lib/Tabs/Tabs.tsx"],"sourcesContent":["import type {ReactElement} from 'react';\nimport {useEffect, useMemo, forwardRef, Children, useState, useCallback, useRef} from 'react';\nimport classNames from 'classnames';\nimport {useLocalTheme} from 'css-vars-hook';\n\nimport type {DataAttributes, LibraryProps} from '@/internal/LibraryAPI';\nimport {useLinkRefs} from '@/internal/hooks/useLinkRefs.ts';\nimport {useIsOverflow} from '@/internal/hooks/useIsOverflow.ts';\nimport {IconScroll} from '@/internal/Icons';\n\nimport type {Props as TabProps} from './Tab.tsx';\nimport {TabButton} from './TabButton.tsx';\nimport classes from './Tabs.module.css';\n\nexport type Props = DataAttributes &\n LibraryProps & {\n /** Set a pre-selected Tab name */\n selected?: string;\n /** Define common width for all portions */\n width?: number;\n /** Define common height for all portions */\n height?: number;\n children: ReactElement<TabProps> | ReactElement<TabProps>[];\n /** Callback when user selects different Tab */\n onToggle?: (tabName: string) => void;\n };\n\nexport const Tabs = forwardRef<HTMLDivElement, Props>(\n (\n {\n children,\n className,\n selected: selectedProp,\n width,\n height,\n onToggle = () => {},\n ...nativeProps\n },\n ref\n ) => {\n const {LocalRoot, ref: innerRef} = useLocalTheme<HTMLDivElement>();\n\n useLinkRefs(ref, innerRef);\n\n const theme = useMemo(() => {\n let theme = {};\n if (height) {\n theme = {...theme, height};\n }\n if (width) {\n theme = {...theme, width};\n }\n return theme;\n }, [height, width]);\n\n const initiallySelected = useMemo(\n () =>\n selectedProp\n ? selectedProp\n : (Children.toArray(children)[0] as ReactElement<TabProps>).props.name,\n [children, selectedProp]\n );\n\n const [selected, setSelected] = useState(initiallySelected);\n\n useEffect(() => {\n if (selectedProp) {\n setSelected(selectedProp);\n } else {\n setSelected(initiallySelected);\n }\n }, [selectedProp, initiallySelected]);\n\n const handleClick = useCallback(\n (tabName: string) => {\n setSelected(tabName);\n onToggle(tabName);\n },\n [onToggle]\n );\n\n const tabs = useMemo(\n () =>\n Children.map(children, element => {\n return {tabName: element.props.name, icon: element.props.icon};\n }),\n [children]\n );\n\n const visibleTab = useMemo(\n () =>\n (Children.toArray(children) as ReactElement<TabProps>[]).find(\n element => element.props.name === selected\n ),\n [children, selected]\n );\n\n const headerRef = useRef<HTMLElement>(null);\n\n const {overflowX} = useIsOverflow(headerRef);\n\n return (\n <LocalRoot\n {...nativeProps}\n theme={theme}\n className={classNames(classes.tabs, className)}>\n <div className={classes.viewport}>\n <header ref={headerRef} className={classes.header}>\n {tabs.map(({tabName, icon}) => {\n return (\n <TabButton\n key={tabName}\n icon={icon}\n onClick={handleClick}\n tabName={tabName}\n activeName={selected}\n />\n );\n })}\n </header>\n {overflowX && (\n <div className={classes['overflow-indicator']}>\n <IconScroll />\n </div>\n )}\n </div>\n <div className={classes.content}>{visibleTab}</div>\n </LocalRoot>\n );\n }\n);\n\nTabs.displayName = 'Tabs';\n"],"names":["Tabs","forwardRef","children","className","selectedProp","width","height","onToggle","nativeProps","ref","LocalRoot","innerRef","useLocalTheme","useLinkRefs","theme","useMemo","initiallySelected","Children","selected","setSelected","useState","useEffect","handleClick","useCallback","tabName","tabs","element","visibleTab","headerRef","useRef","overflowX","useIsOverflow","jsxs","classNames","classes","jsx","icon","TabButton","IconScroll"],"mappings":"+ZA2BaA,EAAOC,EAAAA,WAChB,CACI,CACI,SAAAC,EACA,UAAAC,EACA,SAAUC,EACV,MAAAC,EACA,OAAAC,EACA,SAAAC,EAAW,IAAM,CAAC,EAClB,GAAGC,CAAA,EAEPC,IACC,CACD,KAAM,CAAC,UAAAC,EAAW,IAAKC,CAAA,EAAYC,EAAAA,cAAA,EAEnCC,EAAAA,YAAYJ,EAAKE,CAAQ,EAEzB,MAAMG,EAAQC,EAAAA,QAAQ,IAAM,CACxB,IAAID,EAAQ,CAAA,EACZ,OAAIR,IACAQ,EAAQ,CAAC,GAAGA,EAAO,OAAAR,CAAA,GAEnBD,IACAS,EAAQ,CAAC,GAAGA,EAAO,MAAAT,CAAA,GAEhBS,CACX,EAAG,CAACR,EAAQD,CAAK,CAAC,EAEZW,EAAoBD,EAAAA,QACtB,IACIX,GAEOa,WAAS,QAAQf,CAAQ,EAAE,CAAC,EAA6B,MAAM,KAC1E,CAACA,EAAUE,CAAY,CAAA,EAGrB,CAACc,EAAUC,CAAW,EAAIC,EAAAA,SAASJ,CAAiB,EAE1DK,EAAAA,UAAU,IAAM,CAERF,EADAf,GAGYY,CAFY,CAIhC,EAAG,CAACZ,EAAcY,CAAiB,CAAC,EAEpC,MAAMM,EAAcC,EAAAA,YACfC,GAAoB,CACjBL,EAAYK,CAAO,EACnBjB,EAASiB,CAAO,CACpB,EACA,CAACjB,CAAQ,CAAA,EAGPkB,EAAOV,EAAAA,QACT,IACIE,WAAS,IAAIf,EAAUwB,IACZ,CAAC,QAASA,EAAQ,MAAM,KAAM,KAAMA,EAAQ,MAAM,IAAA,EAC5D,EACL,CAACxB,CAAQ,CAAA,EAGPyB,EAAaZ,EAAAA,QACf,IACKE,WAAS,QAAQf,CAAQ,EAA+B,KACrDwB,GAAWA,EAAQ,MAAM,OAASR,CAAA,EAE1C,CAAChB,EAAUgB,CAAQ,CAAA,EAGjBU,EAAYC,EAAAA,OAAoB,IAAI,EAEpC,CAAC,UAAAC,CAAA,EAAaC,EAAAA,cAAcH,CAAS,EAE3C,OACII,EAAAA,KAACtB,EAAA,CACI,GAAGF,EACJ,MAAAM,EACA,UAAWmB,EAAWC,UAAQ,KAAM/B,CAAS,EAC7C,SAAA,CAAA6B,EAAAA,KAAC,MAAA,CAAI,UAAWE,EAAAA,QAAQ,SACpB,SAAA,CAAAC,EAAAA,IAAC,SAAA,CAAO,IAAKP,EAAW,UAAWM,EAAAA,QAAQ,OACtC,SAAAT,EAAK,IAAI,CAAC,CAAC,QAAAD,EAAS,KAAAY,CAAA,IAEbD,EAAAA,IAACE,EAAAA,UAAA,CAEG,KAAAD,EACA,QAASd,EACT,QAAAE,EACA,WAAYN,CAAA,EAJPM,CAAA,CAOhB,CAAA,CACL,EACCM,SACI,MAAA,CAAI,UAAWI,EAAAA,QAAQ,oBAAoB,EACxC,SAAAC,EAAAA,IAACG,EAAAA,WAAA,CAAA,CAAW,CAAA,CAChB,CAAA,EAER,EACAH,EAAAA,IAAC,MAAA,CAAI,UAAWD,EAAAA,QAAQ,QAAU,SAAAP,CAAA,CAAW,CAAA,CAAA,CAAA,CAGzD,CACJ,EAEA3B,EAAK,YAAc"}