// @flow strict import * as React from 'react'; import {classify} from '../../utils/classify'; import {UnstyledButton} from '../Button'; import {Checkbox} from '../Checkbox'; import {Icon} from '../Icon'; import {RadioButton} from '../RadioButton'; import {Truncate} from '../Truncate'; import {TruncatedTextWithTooltip} from '../TruncatedTextWithTooltip'; import type {BaseMenuProps, MenuOption} from './Menu'; import css from './Menu.module.css'; export type MenuOptionProps = { ...BaseMenuProps, option: MenuOption, isLastItem?: boolean, style?: mixed, }; export const MenuOptionButton = (props: MenuOptionProps): React.Node => { const lastMenuItemRef: {current: HTMLButtonElement | null} = React.useRef(null); const { option, size = 'medium', onSelect, selectedOption, menuDisabled, classNames, optionsVariant = 'normal', selectedKeys, isLastItem, onTabOut, resolveLabel, resolveSecondaryLabel, style, showLabelTooltip, allowWrap = false, } = props; const { key, label, secondaryLabel, customComponent, iconLeft, iconLeftType, classNames: optionClassNames, iconRight, iconRightType, disabled, optionSize, optionVariant = optionsVariant, indeterminate = false, } = option; const [buttonSize, setButtonSize] = React.useState(optionSize || size); const resolvedLabel = resolveLabel ? resolveLabel(option) : label; const resolvedSecondaryLabel = resolveSecondaryLabel ? resolveSecondaryLabel(option) : secondaryLabel; const isSelected = () => { if (!selectedKeys || !Array.isArray(selectedKeys) || !selectedKeys.length) { return false; } return selectedKeys.includes(option.key); }; React.useEffect(() => { setButtonSize(optionSize || size); }, [optionSize, size]); React.useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { if (event.key === 'Tab' && !event.shiftKey) { // Tab pressed without shift key, calling tab out callback onTabOut?.(); } }; lastMenuItemRef.current?.addEventListener('keydown', handleKeyDown); return () => { lastMenuItemRef.current?.removeEventListener('keydown', handleKeyDown); }; }, [isLastItem]); return ( onSelect && onSelect(option, e)} autoFocus={selectedOption?.key === key} {...(isLastItem ? {ref: lastMenuItemRef} : {})} > {optionVariant === 'checkbox' && ( )} {optionVariant === 'radio' && ( )} {!!iconLeft && ( )} {React.isValidElement(customComponent) ? ( customComponent ) : ( {renderLabel(resolvedLabel, allowWrap, showLabelTooltip)} )} {!!secondaryLabel && ( {resolvedSecondaryLabel} )} {!!iconRight && ( )} ); }; const renderLabel = (label, allowWrap, showLabelTooltip) => { if (showLabelTooltip) { return ( {label} ); } if (allowWrap) { return ( {label} ); } return {label}; };