// @flow strict import * as React from 'react'; import type {ColorTypes} from '../../types/typography'; import classify from '../../utils/classify'; import {Button} from '../Button'; import type {IconProps} from '../Icon'; import {Icon} from '../Icon'; import type {TextProps} from '../Text'; import { ButtonTextSmall, SubTitleExtraSmall, SubTitleMedium, TEXT_COLORS, } from '../Text'; import css from './SubMenu.module.css'; type ClassNames = $ReadOnly<{wrapper?: string}>; export const SubMenuItemIcon = ({ className, ...props }: IconProps): React.Node => ( ); SubMenuItemIcon.displayName = 'SubMenuItemIcon'; export const SubMenuItemText = ({ children, className, ...props }: TextProps): React.Node => ( {children} ); SubMenuItemText.displayName = 'SubMenuItemText'; export type SubMenuItemActionProps = { children?: React.Node, color?: ColorTypes, className?: string, ... }; export const SubMenuItemAction = ({ children, className, ...props }: SubMenuItemActionProps): React.Node => (
{children}
); SubMenuItemAction.displayName = 'SubMenuItemAction'; export type SubMenuItemProps = { classNames?: ClassNames, children?: React.Node, selectedMenuKey?: string, disabled?: boolean, onChange?: (selectedMenuKey: string) => mixed, menuKey: string, ... }; export const SubMenuItem: React$AbstractComponent< SubMenuItemProps, HTMLElement, > = React.forwardRef( ( { children, selectedMenuKey, disabled, classNames, onChange, menuKey, ...props }: SubMenuItemProps, ref, ): React.Node => { const onChangeHandler = () => { if (!disabled) { onChange && onChange(menuKey); } }; const onKeyDownHandler = (e) => { if (e.key === 'Enter') { onChangeHandler(); } }; const selected = selectedMenuKey === menuKey; const getNamedComp = (comp: string) => { const childrenArray = React.Children.toArray(children); if (childrenArray.length) { const nodes: React.Node[] = []; for (const child of childrenArray) { if (child?.type?.displayName === comp) { nodes.push( React.cloneElement(child, { selected, disabled, }), ); } } return nodes.length > 1 ? nodes : nodes[0]; } return null; }; return (
{getNamedComp('SubMenuItemIcon')} {getNamedComp('SubMenuItemText')}
{getNamedComp('SubMenuItemAction')}
); }, ); type SubMenuGroupClassNames = $ReadOnly<{ wrapper?: string, groupHeader?: string, menuGroup?: string, }>; export type SubMenuGroupProps = { children?: React.Node, groupTitle?: string, collapsible?: boolean, disabled?: boolean, onChange?: (value: string) => mixed, selectedMenuKey?: string, classNames?: SubMenuGroupClassNames, }; export const SubMenuGroup = ({ children, groupTitle, collapsible = false, disabled = false, onChange, selectedMenuKey, classNames, }: SubMenuGroupProps): React.Node => { const [collapsed, setCollapsed] = React.useState(false); const collapseHandler = () => { collapsible && setCollapsed(!collapsed); }; const onChangeHandler = (value) => { if (onChange) { onChange(value); } }; const onKeyDownHandlerHeader = (e) => { if (e.key === 'Enter') { collapseHandler(); } }; const childrenWithProps = React.Children.map(children, (child) => { if (React.isValidElement(child)) { const {disabled: disabledChild} = child.props; return React.cloneElement(child, { selectedMenuKey, onChange: onChangeHandler, disabled: disabledChild || disabled, }); } return child; }); return (
{groupTitle} {collapsible && ( )}
{childrenWithProps}
); }; export type SubMenuProps = { classNames?: ClassNames, title: string, children?: React.Node, onClose?: () => mixed, showClose?: boolean, }; export const SubMenu: React$AbstractComponent = React.forwardRef( ( {classNames, children, title, onClose, showClose = false}: SubMenuProps, ref, ): React.Node => { const childrenWithProps = React.Children.map(children, (child) => { if (React.isValidElement(child)) { return
{child}
; } }); return (
{title} {showClose && (
{childrenWithProps}
); }, ); SubMenu.displayName = 'SubMenu';