@spaced-out/ui-design-system
Version:
Sense UI components library
141 lines (128 loc) • 3.88 kB
Flow
// @flow strict
import * as React from 'react';
import {TEXT_COLORS} from '../../../types/typography';
import {classify} from '../../../utils/classify';
import {UnstyledButton} from '../../Button';
import type {IconType} from '../../Icon';
import {Icon} from '../../Icon';
import {ButtonTextMedium, ButtonTextSmall} from '../../Text';
import css from './Tab.module.css';
type ClassNames = $ReadOnly<{wrapper?: string, iconTextWrap?: string}>;
export const TAB_SIZE = Object.freeze({
small: 'small',
medium: 'medium',
});
export const tabSizeOptions: Array<mixed> = [...Object.keys(TAB_SIZE)];
export type TabSize = $Keys<typeof TAB_SIZE>;
export type TabProps = {
classNames?: ClassNames,
onSelect?: ({tabId?: string, label?: string}) => mixed,
size?: TabSize,
selectedTab?: {tabId?: string, label?: string},
disabled?: boolean,
tabId?: string,
label?: string,
iconName?: string,
iconType?: IconType,
width?: string,
onClick?: ?(SyntheticEvent<HTMLElement>) => mixed,
};
export const Tab: React$AbstractComponent<TabProps, HTMLButtonElement> =
React.forwardRef<TabProps, HTMLButtonElement>(
(
{
classNames,
onSelect,
size = 'medium',
selectedTab,
disabled = false,
tabId,
label,
iconName,
iconType,
onClick,
width,
...props
}: TabProps,
forwardRef,
) => {
const tabRef = React.useRef(null);
React.useImperativeHandle(forwardRef, () => tabRef.current);
const selected = tabId && tabId === selectedTab?.tabId;
const onClickHandler = (e) => {
if (!disabled) {
e.preventDefault();
onSelect && onSelect({tabId, label});
onClick && onClick(e);
tabRef.current?.blur();
}
};
return (
<UnstyledButton
{...props}
disabled={disabled}
className={classify(
css.button,
{
[css.selected]: selected === true,
[css.disabled]: disabled === true,
[css.mediumSize]: size === 'medium',
[css.smallSize]: size === 'small',
},
classNames?.wrapper,
)}
onClick={onClickHandler}
style={{width}}
tabIndex={disabled ? -1 : 0}
ref={tabRef}
>
<span
className={classify(
css.iconTextWrap,
{
[css.selected]: selected === true,
[css.disabled]: disabled === true,
},
classNames?.iconTextWrap,
)}
>
{iconName ? (
<Icon
name={iconName}
type={iconType}
size={size}
className={classify(css.icon, {
[css.disabled]: disabled === true,
})}
/>
) : null}
{label && (
<>
{size === TAB_SIZE.medium ? (
<ButtonTextMedium
color={TEXT_COLORS.secondary}
className={classify(css.tabContainer, {
[css.disabled]: disabled === true,
})}
>
{label}
</ButtonTextMedium>
) : (
<ButtonTextSmall
color={TEXT_COLORS.secondary}
className={classify(css.tabContainer, {
[css.selected]: selected === true,
[css.disabled]: disabled === true,
})}
>
{label}
</ButtonTextSmall>
)}
</>
)}
</span>
</UnstyledButton>
);
},
);
Tab.displayName = 'Tab';