RouteTabList.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import { Box, makeStyles, Tab, Tabs, Theme } from '@material-ui/core';
  2. import { FC, useState } from 'react';
  3. import { useNavigate, useLocation } from 'react-router-dom';
  4. import { ITabListProps, ITabPanel } from './Types';
  5. const useStyles = makeStyles((theme: Theme) => ({
  6. wrapper: {
  7. display: 'flex',
  8. flexDirection: 'column',
  9. flexBasis: 0,
  10. flexGrow: 1,
  11. '& .MuiTab-wrapper': {
  12. textTransform: 'capitalize',
  13. fontWeight: 'normal',
  14. color: '#323232',
  15. },
  16. background: '#fff',
  17. border: '1px solid #e9e9ed',
  18. padding: theme.spacing(0, 1),
  19. },
  20. tab: {
  21. backgroundColor: theme.palette.primary.main,
  22. },
  23. tabContainer: {
  24. borderBottom: '1px solid #e0e0e0',
  25. },
  26. tabContent: {
  27. minWidth: 0,
  28. marginRight: theme.spacing(3),
  29. },
  30. tabPanel: {
  31. flexBasis: 0,
  32. flexGrow: 1,
  33. marginTop: theme.spacing(1),
  34. overflow: 'hidden',
  35. },
  36. }));
  37. const TabPanel = (props: ITabPanel) => {
  38. const { children, value, index, className = '', ...other } = props;
  39. return (
  40. <div
  41. role="tabpanel"
  42. hidden={value !== index}
  43. className={className}
  44. id={`tabpanel-${index}`}
  45. aria-labelledby={`tabpanel-${index}`}
  46. {...other}
  47. >
  48. {value === index && <Box height="100%">{children}</Box>}
  49. </div>
  50. );
  51. };
  52. const a11yProps = (index: number) => {
  53. return {
  54. id: `tab-${index}`,
  55. 'aria-controls': `tabpanel-${index}`,
  56. };
  57. };
  58. const RouteTabList: FC<ITabListProps> = props => {
  59. const { tabs, activeIndex = 0, wrapperClass = '' } = props;
  60. const classes = useStyles();
  61. const [value, setValue] = useState<number>(activeIndex);
  62. const navigate = useNavigate();
  63. const location = useLocation();
  64. const handleChange = (event: any, newValue: any) => {
  65. setValue(newValue);
  66. const newPath =
  67. location.pathname.split('/').slice(0, -1).join('/') +
  68. '/' +
  69. tabs[newValue].path;
  70. navigate(`${newPath}`);
  71. };
  72. return (
  73. <div className={`${classes.wrapper} ${wrapperClass}`}>
  74. <Tabs
  75. classes={{
  76. indicator: classes.tab,
  77. flexContainer: classes.tabContainer,
  78. }}
  79. // if not provide this property, Material will add single span element by default
  80. TabIndicatorProps={{ children: <div className="tab-indicator" /> }}
  81. value={value}
  82. onChange={handleChange}
  83. aria-label="tabs"
  84. >
  85. {tabs.map((tab, index) => (
  86. <Tab
  87. classes={{ root: classes.tabContent }}
  88. textColor="primary"
  89. key={tab.label}
  90. label={tab.label}
  91. {...a11yProps(index)}
  92. ></Tab>
  93. ))}
  94. </Tabs>
  95. {tabs.map((tab, index) => (
  96. <TabPanel
  97. key={tab.label}
  98. value={value}
  99. index={index}
  100. className={classes.tabPanel}
  101. >
  102. {tab.component}
  103. </TabPanel>
  104. ))}
  105. </div>
  106. );
  107. };
  108. export default RouteTabList;