import * as React from 'react'; import styles from '@patternfly/react-styles/css/components/MenuToggle/menu-toggle'; import { css } from '@patternfly/react-styles'; import CaretDownIcon from '@patternfly/react-icons/dist/esm/icons/caret-down-icon'; import { BadgeProps } from '../Badge'; export type MenuToggleElement = HTMLDivElement | HTMLButtonElement; export interface SplitButtonOptions { /** Elements to display before the toggle button. When included, renders the menu toggle as a split button. */ items: React.ReactNode[]; /** Variant of split button toggle */ variant?: 'action' | 'checkbox'; } export interface MenuToggleProps extends Omit, 'ref' | 'icon' > { /** Content rendered inside the toggle */ children?: React.ReactNode; /** Additional classes added to the toggle */ className?: string; /** Flag indicating the toggle has expanded styling */ isExpanded?: boolean; /** Flag indicating the toggle is disabled */ isDisabled?: boolean; /** Flag indicating the toggle is full height */ isFullHeight?: boolean; /** Flag indicating the toggle takes up the full width of its parent */ isFullWidth?: boolean; /** Object used to configure a split button menu toggle */ splitButtonOptions?: SplitButtonOptions; /** Variant styles of the menu toggle */ variant?: 'default' | 'plain' | 'primary' | 'plainText' | 'secondary' | 'typeahead'; /** Optional icon or image rendered inside the toggle, before the children content. It is * recommended to wrap most basic icons in our icon component. */ icon?: React.ReactNode; /** Optional badge rendered inside the toggle, after the children content */ badge?: BadgeProps | React.ReactNode; /** @hide Forwarded ref */ innerRef?: React.ForwardedRef; } class MenuToggleBase extends React.Component { displayName = 'MenuToggleBase'; static defaultProps: MenuToggleProps = { className: '', isExpanded: false, isDisabled: false, isFullWidth: false, isFullHeight: false }; render() { const { children, className, icon, badge, isExpanded, isDisabled, isFullHeight, isFullWidth, splitButtonOptions, variant, innerRef, onClick, 'aria-label': ariaLabel, ...otherProps } = this.props; const isPlain = variant === 'plain'; const isPlainText = variant === 'plainText'; const isTypeahead = variant === 'typeahead'; const toggleControls = ( ); const content = ( <> {icon && {icon}} {isTypeahead ? children : {children}} {React.isValidElement(badge) && {badge}} {isTypeahead ? ( ) : ( toggleControls )} ); const commonStyles = css( styles.menuToggle, isExpanded && styles.modifiers.expanded, variant === 'primary' && styles.modifiers.primary, variant === 'secondary' && styles.modifiers.secondary, (isPlain || isPlainText) && styles.modifiers.plain, isPlainText && styles.modifiers.text, isFullHeight && styles.modifiers.fullHeight, isFullWidth && styles.modifiers.fullWidth, isDisabled && styles.modifiers.disabled, className ); const componentProps = { children: isPlain ? children : content, ...(isDisabled && { disabled: true }), ...otherProps }; if (isTypeahead) { return (
} className={css(commonStyles, styles.modifiers.typeahead)} {...componentProps} /> ); } if (splitButtonOptions) { return (
} className={css( commonStyles, styles.modifiers.splitButton, splitButtonOptions?.variant === 'action' && styles.modifiers.action )} > {splitButtonOptions?.items}
); } return (