1. /**
    
  2.  * Copyright (c) Meta Platforms, Inc. and affiliates.
    
  3.  *
    
  4.  * This source code is licensed under the MIT license found in the
    
  5.  * LICENSE file in the root directory of this source tree.
    
  6.  *
    
  7.  * @flow
    
  8.  */
    
  9. 
    
  10. import * as React from 'react';
    
  11. import {Fragment, useCallback} from 'react';
    
  12. import Icon from './Icon';
    
  13. 
    
  14. import styles from './TabBar.css';
    
  15. import Tooltip from './Components/reach-ui/tooltip';
    
  16. 
    
  17. import type {IconType} from './Icon';
    
  18. 
    
  19. type TabInfo = {
    
  20.   icon: IconType,
    
  21.   id: string,
    
  22.   label: string,
    
  23.   title?: string,
    
  24. };
    
  25. 
    
  26. export type Props = {
    
  27.   currentTab: any,
    
  28.   disabled?: boolean,
    
  29.   id: string,
    
  30.   selectTab: (tabID: any) => void,
    
  31.   tabs: Array<TabInfo | null>,
    
  32.   type: 'navigation' | 'profiler' | 'settings',
    
  33. };
    
  34. 
    
  35. export default function TabBar({
    
  36.   currentTab,
    
  37.   disabled = false,
    
  38.   id: groupName,
    
  39.   selectTab,
    
  40.   tabs,
    
  41.   type,
    
  42. }: Props): React.Node {
    
  43.   if (!tabs.some(tab => tab !== null && tab.id === currentTab)) {
    
  44.     const firstTab = ((tabs.find(tab => tab !== null): any): TabInfo);
    
  45.     selectTab(firstTab.id);
    
  46.   }
    
  47. 
    
  48.   const onChange = useCallback(
    
  49.     ({currentTarget}: $FlowFixMe) => selectTab(currentTarget.value),
    
  50.     [selectTab],
    
  51.   );
    
  52. 
    
  53.   const handleKeyDown = useCallback((event: $FlowFixMe) => {
    
  54.     switch (event.key) {
    
  55.       case 'ArrowDown':
    
  56.       case 'ArrowLeft':
    
  57.       case 'ArrowRight':
    
  58.       case 'ArrowUp':
    
  59.         event.stopPropagation();
    
  60.         break;
    
  61.       default:
    
  62.         break;
    
  63.     }
    
  64.   }, []);
    
  65. 
    
  66.   let iconSizeClassName;
    
  67.   let tabLabelClassName;
    
  68.   let tabSizeClassName;
    
  69.   switch (type) {
    
  70.     case 'navigation':
    
  71.       iconSizeClassName = styles.IconSizeNavigation;
    
  72.       tabLabelClassName = styles.TabLabelNavigation;
    
  73.       tabSizeClassName = styles.TabSizeNavigation;
    
  74.       break;
    
  75.     case 'profiler':
    
  76.       iconSizeClassName = styles.IconSizeProfiler;
    
  77.       tabLabelClassName = styles.TabLabelProfiler;
    
  78.       tabSizeClassName = styles.TabSizeProfiler;
    
  79.       break;
    
  80.     case 'settings':
    
  81.       iconSizeClassName = styles.IconSizeSettings;
    
  82.       tabLabelClassName = styles.TabLabelSettings;
    
  83.       tabSizeClassName = styles.TabSizeSettings;
    
  84.       break;
    
  85.     default:
    
  86.       throw Error(`Unsupported type "${type}"`);
    
  87.   }
    
  88. 
    
  89.   return (
    
  90.     <Fragment>
    
  91.       {tabs.map(tab => {
    
  92.         if (tab === null) {
    
  93.           return <div key="VRule" className={styles.VRule} />;
    
  94.         }
    
  95. 
    
  96.         const {icon, id, label, title} = tab;
    
  97. 
    
  98.         let button = (
    
  99.           <label
    
  100.             className={[
    
  101.               tabSizeClassName,
    
  102.               disabled ? styles.TabDisabled : styles.Tab,
    
  103.               !disabled && currentTab === id ? styles.TabCurrent : '',
    
  104.             ].join(' ')}
    
  105.             data-testname={`TabBarButton-${id}`}
    
  106.             key={id}
    
  107.             onKeyDown={handleKeyDown}
    
  108.             onMouseDown={() => selectTab(id)}>
    
  109.             <input
    
  110.               type="radio"
    
  111.               className={styles.Input}
    
  112.               checked={currentTab === id}
    
  113.               disabled={disabled}
    
  114.               name={groupName}
    
  115.               value={id}
    
  116.               onChange={onChange}
    
  117.             />
    
  118.             <Icon
    
  119.               className={`${
    
  120.                 disabled ? styles.IconDisabled : ''
    
  121.               } ${iconSizeClassName}`}
    
  122.               type={icon}
    
  123.             />
    
  124.             <span className={tabLabelClassName}>{label}</span>
    
  125.           </label>
    
  126.         );
    
  127. 
    
  128.         if (title) {
    
  129.           button = (
    
  130.             <Tooltip key={id} label={title}>
    
  131.               {button}
    
  132.             </Tooltip>
    
  133.           );
    
  134.         }
    
  135. 
    
  136.         return button;
    
  137.       })}
    
  138.     </Fragment>
    
  139.   );
    
  140. }