/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import * as React from 'react';
import {Fragment, useCallback} from 'react';
import Icon from './Icon';
import styles from './TabBar.css';
import Tooltip from './Components/reach-ui/tooltip';
import type {IconType} from './Icon';
type TabInfo = {
icon: IconType,
id: string,
label: string,
title?: string,
};
export type Props = {
currentTab: any,
disabled?: boolean,
id: string,
selectTab: (tabID: any) => void,
tabs: Array<TabInfo | null>,
type: 'navigation' | 'profiler' | 'settings',
};
export default function TabBar({
currentTab,
disabled = false,
id: groupName,
selectTab,
tabs,
type,
}: Props): React.Node {
if (!tabs.some(tab => tab !== null && tab.id === currentTab)) {
const firstTab = ((tabs.find(tab => tab !== null): any): TabInfo);
selectTab(firstTab.id);
}
const onChange = useCallback(
({currentTarget}: $FlowFixMe) => selectTab(currentTarget.value),
[selectTab],
);
const handleKeyDown = useCallback((event: $FlowFixMe) => {
switch (event.key) {
case 'ArrowDown':
case 'ArrowLeft':
case 'ArrowRight':
case 'ArrowUp':
event.stopPropagation();
break;
default:
break;
}
}, []);
let iconSizeClassName;
let tabLabelClassName;
let tabSizeClassName;
switch (type) {
case 'navigation':
iconSizeClassName = styles.IconSizeNavigation;
tabLabelClassName = styles.TabLabelNavigation;
tabSizeClassName = styles.TabSizeNavigation;
break;
case 'profiler':
iconSizeClassName = styles.IconSizeProfiler;
tabLabelClassName = styles.TabLabelProfiler;
tabSizeClassName = styles.TabSizeProfiler;
break;
case 'settings':
iconSizeClassName = styles.IconSizeSettings;
tabLabelClassName = styles.TabLabelSettings;
tabSizeClassName = styles.TabSizeSettings;
break;
default:
throw Error(`Unsupported type "${type}"`);
}
return (
<Fragment>
{tabs.map(tab => {
if (tab === null) {
return <div key="VRule" className={styles.VRule} />;
}
const {icon, id, label, title} = tab;
let button = (
<label
className={[
tabSizeClassName,
disabled ? styles.TabDisabled : styles.Tab,
!disabled && currentTab === id ? styles.TabCurrent : '',
].join(' ')}
data-testname={`TabBarButton-${id}`}
key={id}
onKeyDown={handleKeyDown}
onMouseDown={() => selectTab(id)}>
<input
type="radio"
className={styles.Input}
checked={currentTab === id}
disabled={disabled}
name={groupName}
value={id}
onChange={onChange}
/>
<Icon
className={`${
disabled ? styles.IconDisabled : ''
} ${iconSizeClassName}`}
type={icon}
/>
<span className={tabLabelClassName}>{label}</span>
</label>
);
if (title) {
button = (
<Tooltip key={id} label={title}>
{button}
</Tooltip>
);
}
return button;
})}
</Fragment>
);
}