import type { DropdownTriggerProps } from '@planview/pv-uikit' import { Tooltip } from '@planview/pv-uikit' import * as React from 'react' import { ToolbarDropdownMenu } from '../dropdown' import { useUserMenu } from '../utils/context' import { ToolbarItem, ToolbarItemView } from '../wrapper' import { StrippedButton } from './styles' import { useIsFocusVisible } from '@planview/pv-utilities' import { useMergeRefs } from '../utils/refs' type Props = { trigger: React.ReactNode children: React.ReactNode label: string } const UserMenuImpl = ({ children, trigger, label }: Props) => { const { innerRef: _innerRef, focusVisible, ...focusProps } = useIsFocusVisible() const buttonRef = React.useRef(null) const mergedRef = useMergeRefs([buttonRef, focusProps.ref]) return ( ( refOverride={buttonRef}> {( _ref, { toolbarItemProps: { focused: _focused, ...toolbarItemProps }, } ) => ( { mergedRef?.(el) if (props.ref) { ;( props.ref as React.MutableRefObject ).current = el } }} onKeyDown={(ev) => { toolbarItemProps.onKeyDown(ev) props.onKeyDown(ev) }} > {trigger} )} )} > {children} ) } export const UserMenuInternal = React.memo(UserMenuImpl) export type UserMenuProps = { /** element to be wrapped inside a `DropdownMenu` trigger **/ triggerElement: React.JSX.Element /** * any `DropdownMenu`-compatible content */ children: React.ReactNode } export const UserMenuConfig = ({ triggerElement, children }: UserMenuProps) => { const { add, remove } = useUserMenu() React.useEffect(() => { add({ trigger: triggerElement, children }) return () => { remove() } }, [triggerElement, children, add, remove]) return null } /** * * `import { UserMenu } from '@planview/pv-toolbar'` * * The `UserMenu` uses a _component-as-configuration_ strategy. This means the content of the component will not be rendered where it is placed inside the `NavigationBar`. * Rendering of the content, and it's placement is handled internally inside the `NavigationBar`. * * ### Accessibility * * `aria-label` is automatically added with localized label for the drop-down which internally uses the `DropdownMenu` implementing the [Menu WAI aria pattern](https://www.w3.org/WAI/ARIA/apg/patterns/menu/) * */ export const UserMenu = React.memo(UserMenuConfig)