UNPKG

@spaced-out/ui-design-system

Version:
162 lines (141 loc) 4.11 kB
// @flow strict import * as React from 'react'; import type {MenuClassNames, MenuLabelTooltip} from '../../types/menu'; import type {ClickAwayRefType} from '../../utils/click-away'; import {getSelectedKeysFromSelectedOption} from '../../utils/menu'; import type {ButtonProps} from '../Button'; import type {AnchorType} from '../ButtonDropdown'; import type {MenuOption, MenuOptionsVariant, Virtualization} from '../Menu'; import type {OptionButtonTooltipProps} from './OptionButton'; import {OptionButton} from './OptionButton'; type ClassNames = $ReadOnly<{ wrapper?: string, baseButtonWrapper?: string, baseButtonIcon?: string, optionsButtonWrapper?: string, optionsButtonIcon?: string, dropdownContainer?: string, }>; export type SimpleOptionButtonRef = { selectedKeys?: Array<string>, }; export type SimpleOptionButtonProps = { // Input props ...ButtonProps, classNames?: ClassNames, tooltip?: OptionButtonTooltipProps, anchorPosition?: AnchorType, tooltip?: OptionButtonTooltipProps, menuSize?: 'small' | 'medium', // Menu props options?: Array<MenuOption>, optionsVariant?: MenuOptionsVariant, allowSearch?: boolean, selectedKeys?: Array<string>, menuVirtualization?: Virtualization, header?: React.Node, footer?: React.Node, menuClassNames?: MenuClassNames, showLabelTooltip?: MenuLabelTooltip, allowWrap?: boolean, // events onOptionSelect?: (option: MenuOption, ?SyntheticEvent<HTMLElement>) => mixed, onButtonClick?: ?(SyntheticEvent<HTMLElement>) => mixed, onMenuOpen?: () => mixed, onMenuClose?: () => mixed, // Resolvers resolveLabel?: (option: MenuOption) => string | React.Node, resolveSecondaryLabel?: (option: MenuOption) => string | React.Node, clickAwayRef?: ClickAwayRefType, ... }; const SimpleOptionButtonBase = (props: SimpleOptionButtonProps, ref) => { const { size = 'small', classNames, tooltip, anchorPosition, options, optionsVariant, allowSearch, selectedKeys, onOptionSelect, onButtonClick, onMenuOpen, onMenuClose, resolveLabel, resolveSecondaryLabel, children, menuSize = 'small', menuVirtualization, header, footer, menuClassNames, showLabelTooltip, clickAwayRef, allowWrap = false, ...buttonProps } = props; const [optionButtonSelectedKeys, setOptionButtonSelectedKeys] = React.useState(selectedKeys); React.useEffect(() => { setOptionButtonSelectedKeys(selectedKeys); }, [selectedKeys]); const handleOptionChange = (selectedOption: MenuOption, e) => { e?.stopPropagation(); let newSelectedKeys = [selectedOption.key]; if (optionsVariant === 'checkbox') { newSelectedKeys = getSelectedKeysFromSelectedOption( selectedOption, optionButtonSelectedKeys, ); } else { newSelectedKeys = [selectedOption.key]; } setOptionButtonSelectedKeys(newSelectedKeys); setTimeout(() => { onOptionSelect?.(selectedOption, e); }); }; React.useImperativeHandle(ref, () => ({ selectedKeys: optionButtonSelectedKeys, })); return ( <OptionButton {...buttonProps} tooltip={tooltip} onButtonClick={onButtonClick} anchorPosition={anchorPosition} classNames={classNames} size={size} onOptionSelect={handleOptionChange} onMenuOpen={onMenuOpen} onMenuClose={onMenuClose} clickAwayRef={clickAwayRef} menu={{ isFluid: false, options, selectedKeys: optionButtonSelectedKeys, optionsVariant, allowSearch, resolveLabel, resolveSecondaryLabel, size: menuSize, virtualization: menuVirtualization, header, footer, classNames: menuClassNames, showLabelTooltip, allowWrap, }} > {children} </OptionButton> ); }; export const SimpleOptionButton: React.AbstractComponent< SimpleOptionButtonProps, SimpleOptionButtonRef, > = React.forwardRef<SimpleOptionButtonProps, SimpleOptionButtonRef>( SimpleOptionButtonBase, );