src/components/ui/ControlBar/ControlBarButton.tsx (95 lines of code) (raw):

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import React, { FC, ReactNode, useMemo } from 'react'; import { BaseProps } from '../Base'; import IconButton from '../Button/IconButton'; import Caret from '../icons/Caret'; import PopOver, { Placement } from '../PopOver'; import PopOverItem, { PopOverItemProps } from '../PopOver/PopOverItem'; import { Tooltipable, WithTooltip } from '../WithTooltip'; import { useControlBarContext } from './ControlBarContext'; import { isVertical, StyledControlBarItem } from './Styled'; export interface ControlBarButtonProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'css'>, BaseProps, Tooltipable { /** The icon of the control bar item. */ icon: JSX.Element; /** The callback fired when the item is clicked. */ onClick: () => void; /** The label of an control bar item. */ label: string; /** The items to render in a popover menu. When passed, the button will render an arrow to open or close a popover menu. Refer to [PopOverItem](/docs/ui-components-popover--page) */ popOver?: PopOverItemProps[] | null; /** Defines the placement of PopOver menu. */ popOverPlacement?: Placement; /** The label for the optional popOver button. */ popOverLabel?: string; /** Apply this prop to receive visual feedback that the button is 'active' */ isSelected?: boolean; /** Use children to define an alternative to popOver prop with a custom set of elements to be rendered into the popover */ children?: ReactNode | ReactNode[]; } export const ControlBarButton: FC< React.PropsWithChildren<ControlBarButtonProps> > = ({ icon, onClick, label, isSelected = false, popOver = null, popOverPlacement, popOverLabel, tooltipContainerId, tooltipContent, children, ...rest }) => { const context = useControlBarContext(); const IconButtonWithToolTip = useMemo( () => WithTooltip(IconButton, tooltipContainerId), [tooltipContainerId] ); const ButtonComponent = rest['data-tooltip'] ? IconButtonWithToolTip : IconButton; const buttonComponentProps = rest['data-tooltip-position'] ? { tooltipPosition: rest['data-tooltip-position'], tooltipContent } : {}; const renderPopOver = () => ( <PopOver renderButtonWrapper={(isActive, props) => ( <IconButton {...props} icon={ <Caret direction={isVertical(context.layout) ? 'right' : 'up'} data-testid="control-bar-item-caret" /> } label={popOverLabel || label} selected={isActive} className={`ch-control-bar-item-caret ${isActive ? 'isOpen' : ''}`} /> )} a11yLabel={label} className="ch-control-bar-popover" placement={popOverPlacement} > {popOver?.map((option: PopOverItemProps, index: number) => ( <PopOverItem {...option} key={index} /> ))} {children} </PopOver> ); return ( <StyledControlBarItem isSelected={isSelected} data-testid="control-bar-item" {...rest} {...context} popOver={popOver} > <ButtonComponent {...buttonComponentProps} onClick={onClick} label={label} icon={icon} className="ch-control-bar-item-iconButton" selected={isSelected} /> {(popOver || children) && renderPopOver()} {context.showLabels && ( <div className="ch-control-bar-item-label">{label}</div> )} </StyledControlBarItem> ); }; export default ControlBarButton;