packageDocumentation module import "./PopupItem.scss" ; import classnames from "classnames" ; import * as React from "react" ; import { ActionButton , RelativePosition } from "@itwin/appui-abstract" ; import { Popup , useRefState } from "@itwin/core-react" ; import { ToolbarButtonItemProps } from "./Item" ; import { useToolbarWithOverflowDirectionContext , useToolItemEntryContext } from "./ToolbarWithOverflow" ; import { toToolbarPopupRelativePosition } from "./PopupItemWithDrag" ; public export interface ToolbarPopupContextProps { readonly closePanel : ( ) => void ; readonly setSelectedItem ? : ( buttonItem : ActionButton ) => void ; } public export const ToolbarPopupContext = React . createContext < ToolbarPopupContextProps > ( { /** function used to close popup panel */ closePanel : ( ) => { } , /** if popup panel is a GroupButton then this is call to set the selected action item within the panel */ setSelectedItem : ( _buttonItem ) => { } } ) ; public export function useToolbarPopupContext ( ) { return React . useContext ( ToolbarPopupContext ) ; } public export interface PopupItemProps extends ToolbarButtonItemProps { /** Describes if expandable item triangle indicator should be hidden. */ hideIndicator ? : boolean ; /** Panel of the toolbar. */ panel ? : React . ReactNode ; /** If true the popup panel is mounted once and unmounted when button is unmounted. If false the
     * content node is unmounted each time the popup is closed. */ keepContentsMounted ? : boolean ; } public export function PopupItem ( props ) { const [ isPanelShown , setPanelShown ] = React . useState ( false ) ; const { expandsTo , overflowExpandsTo , panelAlignment , onPopupPanelOpenClose } = useToolbarWithOverflowDirectionContext ( ) ; const processPanelOpenClose = React . useCallback ( ( isOpening ) => { setPanelShown ( ( prev ) => { if ( prev !== isOpening ) onPopupPanelOpenClose ( isOpening ) ; return isOpening ; } ) ; } , [ setPanelShown , onPopupPanelOpenClose ] ) ; const onButtonClick = React . useCallback ( ( ) => { processPanelOpenClose ( ! isPanelShown ) ; if ( props . onClick ) props . onClick ( ) ; } , [ props , isPanelShown , processPanelOpenClose ] ) ; const className = classnames ( "components-toolbar-button-item" , "components-toolbar-expandable-button" , props . isDisabled && "components-disabled" , props . className ) ; const [ targetRef , target ] = useRefState < HTMLButtonElement > ( ) ; const handleClose = React . useCallback ( ( ) => { processPanelOpenClose ( false ) ; } , [ processPanelOpenClose ] ) ; const { hasOverflow } = useToolItemEntryContext ( ) ; const expandsToDirection = hasOverflow ? overflowExpandsTo : expandsTo ; const { hideIndicator , panel } = props ; return ( < ToolbarPopupContext . Provider value = { { closePanel : ( ) => processPanelOpenClose ( false ) } } > < button data - item - id = { props . itemId } data - item - type = "tool-button" ref = { targetRef } disabled = { props . isDisabled } onClick = { onButtonClick } onKeyDown = { props . onKeyDown } className = { className } style = { props . style } title = { props . title } > < div className = "components-icon" > { props . icon } < /div> { props . badge && < div className = "components-badge" > { props . badge } < /div>} { hideIndicator ? undefined : < div className = "components-triangle" / > } < /button> < PopupItemPopup isOpen = { isPanelShown } onClose = { handleClose } position = { toToolbarPopupRelativePosition ( expandsToDirection , panelAlignment ) } target = { target } keepContentsMounted = { props . keepContentsMounted } > { panel } < /PopupItemPopup> < /ToolbarPopupContext.Provider>); } internal interface PopupItemPopupProps { children ? : React . ReactNode ; isOpen ? : boolean ; onClose ( ) : void ; position : RelativePosition ; target ? : HTMLElement ; keepContentsMounted ? : boolean ; } internal export function PopupItemPopup ( props ) { return < Popup className = "components-toolbar-popupItem_popupItemPopup" offset = { 0 } showShadow = { false } { ... props } />; }