nishant-design-system
Version:
Sense UI components library
136 lines (124 loc) • 3.29 kB
Flow
// @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 type {BaseMenuProps, MenuOption} from './Menu';
import css from './Menu.module.css';
export type MenuOptionProps = {
...BaseMenuProps,
option: MenuOption,
};
export const MenuOptionButton = (props: MenuOptionProps): React.Node => {
const {
option,
size,
onSelect,
selectedOption,
menuDisabled,
classNames,
optionsVariant = 'normal',
selectedKeys,
} = props;
const {
key,
label,
secondaryLabel,
customComponent,
iconLeft,
iconLeftType,
iconRight,
iconRightType,
disabled,
optionSize,
optionVariant = optionsVariant,
} = option;
const [buttonSize, setButtonSize] = React.useState(optionSize || size);
const isSelected = () => {
if (!selectedKeys || !Array.isArray(selectedKeys) || !selectedKeys.length) {
return false;
}
return selectedKeys.includes(option.key);
};
React.useEffect(() => {
setButtonSize(optionSize || size);
}, [optionSize, size]);
return (
<UnstyledButton
className={classify(
css.option,
{
[css.selected]: isSelected() || key === selectedOption?.key,
[css.optionSmall]: buttonSize === 'small',
[css.optionMedium]: buttonSize === 'medium',
[css.disabled]: menuDisabled || disabled,
[css.withIconLeft]: !!iconLeft,
[css.withIconRight]: !!iconRight,
},
classNames?.option,
)}
disabled={menuDisabled || disabled}
onClick={() => onSelect && onSelect(option)}
autoFocus={selectedOption?.key === key}
>
{optionVariant === 'checkbox' && (
<Checkbox
tabIndex={-1}
disabled={menuDisabled || disabled}
checked={isSelected()}
/>
)}
{optionVariant === 'radio' && (
<RadioButton
disabled={menuDisabled || disabled}
value={option.key}
selectedValue={selectedKeys?.[0]}
tabIndex={-1}
/>
)}
{!!iconLeft && (
<Icon
name={iconLeft}
type={iconLeftType}
size="small"
className={css.icon}
/>
)}
<div
className={classify(
css.optionTextContainer,
classNames?.optionTextContainer,
)}
>
{React.isValidElement(customComponent) ? (
customComponent
) : (
<div
className={classify(
css.optionTextLabel,
classNames?.optionTextLabel,
)}
>
<Truncate>{label}</Truncate>
</div>
)}
{!!secondaryLabel && (
<div className={css.optionTextSecondaryLabel}>
<Truncate>{secondaryLabel}</Truncate>
</div>
)}
</div>
{!!iconRight && (
<Icon
name={iconRight}
type={iconRightType}
size="small"
className={classify(css.icon, css.rightIcon)}
/>
)}
</UnstyledButton>
);
};