koval-ui
Version:
React components collection with minimalistic design. Supports theming, layout, and input validation.
1 lines • 6.42 kB
Source Map (JSON)
{"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 selected?: string;\n width?: number;\n height?: number;\n children: ReactElement<TabProps> | ReactElement<TabProps>[];\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":"+ZAuBaA,EAAOC,EAAA,WAChB,CACI,CACI,SAAAC,EACA,UAAAC,EACA,SAAUC,EACV,MAAAC,EACA,OAAAC,EACA,SAAAC,EAAW,IAAM,CAAC,EAClB,GAAGC,GAEPC,IACC,CACD,KAAM,CAAC,UAAAC,EAAW,IAAKC,CAAA,EAAYC,EAAAA,cAA8B,EAEjEC,EAAA,YAAYJ,EAAKE,CAAQ,EAEnB,MAAAG,EAAQC,EAAAA,QAAQ,IAAM,CACxB,IAAID,EAAQ,CAAC,EACb,OAAIR,IACAQ,EAAQ,CAAC,GAAGA,EAAO,OAAAR,CAAM,GAEzBD,IACAS,EAAQ,CAAC,GAAGA,EAAO,MAAAT,CAAK,GAErBS,CAAA,EACR,CAACR,EAAQD,CAAK,CAAC,EAEZW,EAAoBD,EAAA,QACtB,IACIX,GAEOa,WAAS,QAAQf,CAAQ,EAAE,CAAC,EAA6B,MAAM,KAC1E,CAACA,EAAUE,CAAY,CAC3B,EAEM,CAACc,EAAUC,CAAW,EAAIC,EAAAA,SAASJ,CAAiB,EAE1DK,EAAAA,UAAU,IAAM,CAERF,EADAf,GAGYY,CAFY,CAG5B,EACD,CAACZ,EAAcY,CAAiB,CAAC,EAEpC,MAAMM,EAAcC,EAAA,YACfC,GAAoB,CACjBL,EAAYK,CAAO,EACnBjB,EAASiB,CAAO,CACpB,EACA,CAACjB,CAAQ,CACb,EAEMkB,EAAOV,EAAA,QACT,IACIE,WAAS,IAAIf,EAAqBwB,IACvB,CAAC,QAASA,EAAQ,MAAM,KAAM,KAAMA,EAAQ,MAAM,IAAI,EAChE,EACL,CAACxB,CAAQ,CACb,EAEMyB,EAAaZ,EAAA,QACf,IACKE,WAAS,QAAQf,CAAQ,EAA+B,KACrDwB,GAAWA,EAAQ,MAAM,OAASR,CACtC,EACJ,CAAChB,EAAUgB,CAAQ,CACvB,EAEMU,EAAYC,SAAoB,IAAI,EAEpC,CAAC,UAAAC,CAAA,EAAaC,EAAA,cAAcH,CAAS,EAGvC,OAAAI,EAAA,KAACtB,EAAA,CACI,GAAGF,EACJ,MAAAM,EACA,UAAWmB,EAAWC,UAAQ,KAAM/B,CAAS,EAC7C,SAAA,CAAC6B,EAAA,KAAA,MAAA,CAAI,UAAWE,EAAAA,QAAQ,SACpB,SAAA,CAAAC,EAAAA,IAAC,SAAO,CAAA,IAAKP,EAAW,UAAWM,EAAQ,QAAA,OACtC,SAAKT,EAAA,IAAI,CAAC,CAAC,QAAAD,EAAS,KAAAY,CAAA,IAEbD,EAAA,IAACE,EAAA,UAAA,CAEG,KAAAD,EACA,QAASd,EACT,QAAAE,EACA,WAAYN,CAAA,EAJPM,CAKT,CAEP,EACL,EACCM,SACI,MAAI,CAAA,UAAWI,UAAQ,oBAAoB,EACxC,SAACC,EAAAA,IAAAG,EAAA,WAAA,CAAW,CAAA,CAChB,CAAA,CAAA,EAER,EACCH,EAAA,IAAA,MAAA,CAAI,UAAWD,EAAA,QAAQ,QAAU,SAAWP,CAAA,CAAA,CAAA,CAAA,CACjD,CAAA,CAGZ,EAEA3B,EAAK,YAAc"}