@spaced-out/ui-design-system
Version:
Sense UI components library
154 lines (144 loc) • 4.17 kB
Flow
// @flow strict
import * as React from 'react';
import classify from '../../utils/classify';
import type {ClickAwayRefType} from '../../utils/click-away';
import type {ButtonProps} from '../Button';
import {Button} from '../Button';
import type {AnchorType} from '../ButtonDropdown';
import {ButtonDropdown} from '../ButtonDropdown';
import {ConditionalWrapper} from '../ConditionalWrapper';
import type {MenuOption, MenuProps} from '../Menu';
import type {BaseTooltipProps} from '../Tooltip';
import {Tooltip} from '../Tooltip';
import css from './OptionButton.module.css';
type ClassNames = $ReadOnly<{
wrapper?: string,
baseButtonWrapper?: string,
baseButtonIcon?: string,
optionsButtonWrapper?: string,
optionsButtonIcon?: string,
dropdownContainer?: string,
}>;
export type OptionButtonTooltipProps = {
baseButton?: BaseTooltipProps,
optionsButton?: BaseTooltipProps,
};
export type OptionButtonProps = {
...ButtonProps,
menu?: MenuProps,
anchorPosition?: AnchorType,
onOptionSelect?: (option: MenuOption, ?SyntheticEvent<HTMLElement>) => mixed,
onButtonClick?: ?(SyntheticEvent<HTMLElement>) => mixed,
onMenuOpen?: () => mixed,
onMenuClose?: () => mixed,
tooltip?: OptionButtonTooltipProps,
classNames?: ClassNames,
clickAwayRef?: ClickAwayRefType,
...
};
export const OptionButton: React$AbstractComponent<
OptionButtonProps,
HTMLDivElement,
> = React.forwardRef<OptionButtonProps, HTMLDivElement>(
(
{
children,
iconLeftName,
iconLeftType,
type,
isFluid,
disabled,
size,
isLoading,
menu,
anchorPosition,
onOptionSelect,
onButtonClick,
onMenuOpen,
onMenuClose,
ariaLabel,
actionType,
tooltip,
classNames,
clickAwayRef,
}: OptionButtonProps,
ref,
): React.Node => {
const [iconName, setIconName] = React.useState('chevron-down');
const [isMenuOpen, setIsMenuOpen] = React.useState(false);
return (
<div
className={classify(
css.container,
{[css.isFluid]: isFluid},
classNames?.wrapper,
)}
ref={ref}
>
<ConditionalWrapper
condition={Boolean(tooltip?.baseButton)}
wrapper={(children) => (
<Tooltip
{...tooltip?.baseButton}
hidden={isMenuOpen ? true : tooltip?.optionsButton?.hidden}
>
{children}
</Tooltip>
)}
>
<Button
iconLeftName={iconLeftName}
iconLeftType={iconLeftType}
onClick={onButtonClick}
size={size}
type={type}
disabled={disabled}
isFluid={isFluid}
ariaLabel={ariaLabel}
actionType={actionType}
isLoading={isLoading}
classNames={{
wrapper: classify(css.leftButton, classNames?.baseButtonWrapper),
icon: classNames?.baseButtonIcon,
}}
>
{children}
</Button>
</ConditionalWrapper>
<ButtonDropdown
anchorPosition={anchorPosition}
ariaLabel={ariaLabel}
iconLeftName={iconName}
tooltip={tooltip?.optionsButton}
classNames={{
buttonWrapper: classify(
css.rightButton,
classNames?.optionsButtonWrapper,
),
dropdownContainer: classify(
css.dropDownContainer,
classNames?.dropdownContainer,
),
buttonIcon: classNames?.optionsButtonIcon,
}}
type={type}
disabled={disabled}
menu={menu}
onMenuClose={() => {
setIconName('chevron-down');
setIsMenuOpen(false);
onMenuOpen && onMenuOpen();
}}
onMenuOpen={() => {
setIconName('chevron-up');
setIsMenuOpen(true);
onMenuClose && onMenuClose();
}}
onOptionSelect={onOptionSelect}
size={size}
clickAwayRef={clickAwayRef}
/>
</div>
);
},
);