@itwin/itwinui-react
Version:
A react component library for iTwinUI
108 lines (107 loc) • 2.62 kB
JavaScript
import cx from 'classnames';
import * as React from 'react';
import { Button } from './Button.js';
import { IconButton } from './IconButton.js';
import {
Box,
mergeEventHandlers,
SvgCaretDownSmall,
SvgCaretUpSmall,
useId,
} from '../../utils/index.js';
import { Menu } from '../Menu/Menu.js';
export const SplitButton = React.forwardRef((props, forwardedRef) => {
let {
onClick,
menuItems,
className,
menuPlacement = 'bottom-end',
styleType = 'default',
size,
children,
wrapperProps,
menuButtonProps,
dropdownMenuProps,
portal = true,
...rest
} = props;
let { middleware, ...dropdownMenuPropsRest } = dropdownMenuProps || {};
let [visible, setVisible] = React.useState(false);
let menuContent = React.useMemo(() => {
if ('function' == typeof menuItems)
return menuItems(() => setVisible(false));
return menuItems;
}, [menuItems]);
let popoverProps = {
visible,
onVisibleChange: setVisible,
placement: menuPlacement,
matchWidth: true,
middleware,
};
let labelId = useId();
let trigger = React.createElement(
IconButton,
{
styleType: styleType,
size: size,
disabled: props.disabled,
'aria-labelledby': props.labelProps?.id || labelId,
...menuButtonProps,
},
visible
? React.createElement(SvgCaretUpSmall, null)
: React.createElement(SvgCaretDownSmall, null),
);
let [positionReference, setPositionReference] = React.useState(null);
return React.createElement(
Box,
{
as: 'div',
...wrapperProps,
ref: setPositionReference,
className: cx(
'iui-button-split',
{
'iui-disabled': props.disabled,
},
wrapperProps?.className,
),
},
React.createElement(
Button,
{
className: className,
styleType: styleType,
size: size,
onClick: onClick,
ref: forwardedRef,
...rest,
labelProps: {
id: labelId,
...props.labelProps,
},
},
children,
),
React.createElement(
Menu,
{
popoverProps: popoverProps,
trigger: trigger,
portal: portal,
positionReference: positionReference,
...dropdownMenuPropsRest,
onKeyDown: mergeEventHandlers(
dropdownMenuPropsRest?.onKeyDown,
({ key }) => {
if ('Tab' === key) setVisible(false);
},
),
},
menuContent,
),
);
});
if ('development' === process.env.NODE_ENV)
SplitButton.displayName = 'SplitButton';