UNPKG

@spaced-out/ui-design-system

Version:
141 lines (128 loc) 3.88 kB
// @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';