parent
1432e4969e
commit
11aa7f548f
4 changed files with 104 additions and 16 deletions
@ -1,26 +1,98 @@ |
|||||||
import { |
import { |
||||||
|
Breakpoint, |
||||||
|
tabClasses as muiTabClasses, |
||||||
Tabs as MUITabs, |
Tabs as MUITabs, |
||||||
tabsClasses as muiTabsClasses, |
tabsClasses as muiTabsClasses, |
||||||
TabsProps as MUITabsProps, |
useMediaQuery, |
||||||
|
useTheme, |
||||||
} from '@mui/material'; |
} from '@mui/material'; |
||||||
import { FC } from 'react'; |
import { FC, useCallback, useMemo } from 'react'; |
||||||
|
|
||||||
import { BLUE, BORDER_RADIUS } from '../lib/consts/DEFAULT_THEME'; |
import { BLUE, BORDER_RADIUS } from '../lib/consts/DEFAULT_THEME'; |
||||||
|
|
||||||
const Tabs: FC<MUITabsProps> = ({ |
const TABS_MIN_HEIGHT = '1em'; |
||||||
|
const TABS_VERTICAL_MIN_HEIGHT = '1.8em'; |
||||||
|
|
||||||
|
const Tabs: FC<TabsProps> = ({ |
||||||
|
orientation: rawOrientation, |
||||||
variant = 'fullWidth', |
variant = 'fullWidth', |
||||||
...restTabsProps |
...restTabsProps |
||||||
}) => ( |
}) => { |
||||||
<MUITabs |
const theme = useTheme(); |
||||||
{...restTabsProps} |
|
||||||
variant={variant} |
const bp = useCallback( |
||||||
sx={{ |
(breakpoint: Breakpoint) => theme.breakpoints.up(breakpoint), |
||||||
[`& .${muiTabsClasses.indicator}`]: { |
[theme], |
||||||
backgroundColor: BLUE, |
); |
||||||
borderRadius: BORDER_RADIUS, |
|
||||||
}, |
const bpxs = useMediaQuery(bp('xs')); |
||||||
}} |
const bpsm = useMediaQuery(bp('sm')); |
||||||
/> |
const bpmd = useMediaQuery(bp('md')); |
||||||
); |
const bplg = useMediaQuery(bp('lg')); |
||||||
|
const bpxl = useMediaQuery(bp('xl')); |
||||||
|
|
||||||
|
const mapToBreakpointUp: [Breakpoint, boolean][] = useMemo( |
||||||
|
() => [ |
||||||
|
['xs', bpxs], |
||||||
|
['sm', bpsm], |
||||||
|
['md', bpmd], |
||||||
|
['lg', bplg], |
||||||
|
['xl', bpxl], |
||||||
|
], |
||||||
|
[bplg, bpmd, bpsm, bpxl, bpxs], |
||||||
|
); |
||||||
|
|
||||||
|
const orientation = useMemo(() => { |
||||||
|
let result: TabsOrientation | undefined; |
||||||
|
|
||||||
|
if (typeof rawOrientation === 'object') { |
||||||
|
mapToBreakpointUp.some(([breakpoint, isUp]) => { |
||||||
|
if (isUp && rawOrientation[breakpoint]) { |
||||||
|
result = rawOrientation[breakpoint]; |
||||||
|
} |
||||||
|
|
||||||
|
return !isUp; |
||||||
|
}); |
||||||
|
} else { |
||||||
|
result = rawOrientation; |
||||||
|
} |
||||||
|
|
||||||
|
return result; |
||||||
|
}, [mapToBreakpointUp, rawOrientation]); |
||||||
|
|
||||||
|
return ( |
||||||
|
<MUITabs |
||||||
|
{...restTabsProps} |
||||||
|
orientation={orientation} |
||||||
|
variant={variant} |
||||||
|
sx={{ |
||||||
|
minHeight: TABS_MIN_HEIGHT, |
||||||
|
|
||||||
|
[`&.${muiTabsClasses.vertical}`]: { |
||||||
|
minHeight: TABS_VERTICAL_MIN_HEIGHT, |
||||||
|
|
||||||
|
[`& .${muiTabClasses.root}`]: { |
||||||
|
alignItems: 'flex-start', |
||||||
|
minHeight: TABS_VERTICAL_MIN_HEIGHT, |
||||||
|
paddingLeft: '2em', |
||||||
|
}, |
||||||
|
|
||||||
|
[`& .${muiTabsClasses.indicator}`]: { |
||||||
|
right: 'initial', |
||||||
|
}, |
||||||
|
}, |
||||||
|
|
||||||
|
[`& .${muiTabClasses.root}`]: { |
||||||
|
minHeight: TABS_MIN_HEIGHT, |
||||||
|
}, |
||||||
|
|
||||||
|
[`& .${muiTabsClasses.indicator}`]: { |
||||||
|
backgroundColor: BLUE, |
||||||
|
borderRadius: BORDER_RADIUS, |
||||||
|
}, |
||||||
|
}} |
||||||
|
/> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
export default Tabs; |
export default Tabs; |
||||||
|
@ -0,0 +1,10 @@ |
|||||||
|
type TabsOrientation = Exclude< |
||||||
|
import('@mui/material').TabsProps['orientation'], |
||||||
|
undefined |
||||||
|
>; |
||||||
|
|
||||||
|
type TabsProps = Omit<import('@mui/material').TabsProps, 'orientation'> & { |
||||||
|
orientation?: |
||||||
|
| TabsOrientation |
||||||
|
| Partial<Record<import('@mui/material').Breakpoint, TabsOrientation>>; |
||||||
|
}; |
Loading…
Reference in new issue