All files / src/components/Tabs index.tsx

0% Statements 0/18
0% Branches 0/16
0% Functions 0/6
0% Lines 0/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124                                                                                                                                                                                                                                                       
import { TabContext, TabList, TabPanel } from '@mui/lab';
import { Box, Tab as MuiTab, SxProps, Theme, useTheme } from '@mui/material';
import React, { useEffect, useState } from 'react';
 
import { useDeviceInfo } from '../../utils';
import Icon from '../Icon/Icon';
import { IconName } from '../Icon/icons';
 
export type Tab = {
  children: React.ReactNode;
  disabled?: boolean;
  icon?: IconName;
  id: string;
  label: string;
};
 
export type TabsProps = {
  activeTab?: string;
  onChangeTab?: (tab: string) => void;
  tabs: Tab[];
  tabStyle?: SxProps<Theme>;
  headerBorder?: boolean;
};
 
const Tabs = ({ activeTab, onChangeTab, tabs, tabStyle, headerBorder = false }: TabsProps): JSX.Element => {
  const [selectedTab, setSelectedTab] = useState<string>(activeTab ?? tabs[0]?.id ?? '');
  const theme = useTheme();
  const { isMobile } = useDeviceInfo();
 
  const tabStyles = [
    {
      color: theme.palette.TwClrTxtSecondary as string,
      fontSize: '16px',
      fontWeight: 600,
      lineHeight: '24px',
      minHeight: theme.spacing(4.5),
      padding: theme.spacing(1, 2),
      textTransform: 'capitalize',
      '&:hover': {
        backgroundColor: theme.palette.TwClrBgHover as string,
      },
      '&.Mui-selected': {
        color: theme.palette.TwClrTxtBrand as string,
      },
      '&.MuiTab-labelIcon': {
        alignItems: 'center',
        display: 'flex',
        flexDirection: 'row',
      },
      '& .MuiTab-iconWrapper': {
        fill: theme.palette.TwClrIcnSecondary as string,
        marginBottom: 0,
        marginRight: theme.spacing(1),
      },
      '&.Mui-selected .MuiTab-iconWrapper': {
        fill: theme.palette.TwClrIcnBrand as string,
      },
    },
    ...(Array.isArray(tabStyle) ? tabStyle : [tabStyle]),
  ];
 
  const tabHeaderProps = {
    borderBottom: headerBorder ? 1 : 0,
    borderColor: 'divider',
    margin: isMobile ? 0 : theme.spacing(0, 4),
  };
 
  const tabPanelStyles = {
    padding: 0,
  };
 
  const setTab = (tab: string) => {
    if (onChangeTab) {
      onChangeTab(tab);
    } else {
      setSelectedTab(tab);
    }
  };
 
  useEffect(() => {
    if (activeTab !== undefined) {
      setSelectedTab(activeTab);
    }
  }, [activeTab]);
 
  return (
    <Box sx={{ width: '100%' }}>
      <TabContext value={selectedTab}>
        <Box sx={tabHeaderProps}>
          <TabList
            onChange={(unused, value: string) => setTab(value)}
            sx={{ minHeight: theme.spacing(4.5) }}
            TabIndicatorProps={{
              style: {
                background: theme.palette.TwClrBgBrand,
                height: '4px',
              },
            }}
            variant={'scrollable'}
          >
            {tabs.map((tab, index) => (
              <MuiTab
                disabled={tab.disabled}
                icon={tab.icon ? <Icon name={tab.icon} /> : undefined}
                key={index}
                label={tab.label}
                sx={tabStyles}
                value={tab.id}
              />
            ))}
          </TabList>
        </Box>
        {tabs.map((tab, index) => (
          <TabPanel key={index} sx={tabPanelStyles} value={tab.id}>
            {tab.children}
          </TabPanel>
        ))}
      </TabContext>
    </Box>
  );
};
 
export default Tabs;