import React from "react" ; import { AppBar , Tabs , makeStyles , Theme } from "@material-ui/core" ; import { useHistory } from "react-router-dom" ; import { ChromeTab } from "./ChromeTab" ; import { BrowserTabContent } from "./BrowserTabContent" ; import { useBrowserTabsCallbacks , useBrowserTabsStore } from "./BrowserTabsStore" ; const useStyles = makeStyles ( ( theme ) => ( { tabs : { paddingTop : "2px" , textTransform : "none" , minHeight : "1.2em" , flexShrink : 1 , flexGrow : 1 } , tabsIndicator : { backgroundColor : "transparent" } } ) ) ; export const BrowserTabs = ( ) => { const classes = useStyles ( ) ; const history = useHistory ( ) ; const tabPositionRef = React . useRef ( [ - 1 ] ) ; const { activeTab , tabs , tabContents } = useBrowserTabsStore ( [ "activeTab" , "tabs" , "tabContents" ] ) ; const { setActiveTab , addTab , removeTab , swapTabs } = useBrowserTabsCallbacks ( ) ; React . useEffect ( ( ) => { while ( tabs . length > tabPositionRef . current . length ) { tabPositionRef . current . push ( - 1 ) ; tabPositionRef . current . fill ( - 1 ) ; } } , [ tabs . length ] ) ; React . useEffect ( ( ) => { if ( activeTab ) { history . push ( tabs [ activeTab ] . url ) ; } } , [ activeTab , history , tabs ] ) ; const handleChange = ( event , newValue ) => { setActiveTab ( newValue ) ; } ; const closeTab = ( positionIndex ) => { if ( activeTab === positionIndex ) { const newActiveTab = Math . max ( activeTab - 1 , 0 ) ; setActiveTab ( newActiveTab ) ; } const finishClose = ( ) => { removeTab ( positionIndex ) ; tabPositionRef . current = tabPositionRef . current . splice ( positionIndex , 1 ) ; tabPositionRef . current . fill ( - 1 ) ; } ; return finishClose ; } ; const handleUpdateX = ( x , positionIndex ) => { tabPositionRef . current [ positionIndex ] = x ; } ; const getUpdateX = ( ) : boolean => { return tabPositionRef . current . includes ( - 1 ) ; } ; const handleDrag = ( x , positionIndex ) : boolean => { const calculateMidpoint = ( leftIndex ) => { const val1 = tabPositionRef . current [ leftIndex ] / 2 ; const val2 = tabPositionRef . current [ leftIndex + 1 ] / 2 ; return val1 + val2 ; } ; if ( positionIndex > 0 ) { const leftBoundary = calculateMidpoint ( positionIndex - 1 ) ; if ( x < leftBoundary ) { swapTabs ( positionIndex , positionIndex - 1 ) ; setActiveTab ( positionIndex - 1 ) ; return true ; } } if ( positionIndex < tabPositionRef . current . length - 1 ) { const rightBoundary = calculateMidpoint ( positionIndex ) ; if ( x > rightBoundary ) { swapTabs ( positionIndex , positionIndex + 1 ) ; setActiveTab ( positionIndex + 1 ) ; return true ; } } return false ; } ; return ( < div style = { { } } > < AppBar position = "static" color = "default" style = { { flexDirection : "row" } } > < Tabs className = { classes . tabs } classes = { { indicator : classes . tabsIndicator } } value = { activeTab } onChange = { handleChange } scrollButtons = "off" aria - label = "scrollable auto tabs example" > { tabs . map ( ( tabDescriptor , positionIndex ) => ( < ChromeTab label = { tabDescriptor . title } url = { tabDescriptor . url } positionIndex = { positionIndex } onChange = { handleChange } tabIndex = { tabDescriptor . tabContentIndex } currentValue = { activeTab ! } key = { tabDescriptor . tabContentIndex } onClose = { ( ) => closeTab ( positionIndex ) } onUpdateX = { handleUpdateX } shouldUpdateX = { getUpdateX ( ) } onDrag = { handleDrag } / > ) ) } < /Tabs> < /AppBar> { } < /div>); } ;