diff --git a/packages/components/src/dropdown-menu-v2/checkbox-item.tsx b/packages/components/src/dropdown-menu-v2/checkbox-item.tsx index bcbc920cbb7205..476c63437902b8 100644 --- a/packages/components/src/dropdown-menu-v2/checkbox-item.tsx +++ b/packages/components/src/dropdown-menu-v2/checkbox-item.tsx @@ -29,6 +29,12 @@ export const DropdownMenuCheckboxItem = forwardRef< const focusVisibleFixProps = useTemporaryFocusVisibleFix( { onBlur } ); const dropdownMenuContext = useContext( DropdownMenuContext ); + if ( ! dropdownMenuContext?.store ) { + throw new Error( + 'DropdownMenu.CheckboxItem can only be rendered inside a DropdownMenu component' + ); + } + return ( >( function DropdownMenuGroup( props, ref ) { const dropdownMenuContext = useContext( DropdownMenuContext ); + + if ( ! dropdownMenuContext?.store ) { + throw new Error( + 'DropdownMenu.GroupLabel can only be rendered inside a DropdownMenu component' + ); + } + return ( >( function DropdownMenuGroup( props, ref ) { const dropdownMenuContext = useContext( DropdownMenuContext ); + + if ( ! dropdownMenuContext?.store ) { + throw new Error( + 'DropdownMenu.Group can only be rendered inside a DropdownMenu component' + ); + } + return ( , - ref: React.ForwardedRef< HTMLDivElement > -) => { +const UnconnectedDropdownMenu = ( props: DropdownMenuProps ) => { const { - // Store props open, defaultOpen = false, onOpenChange, placement, - - // Menu trigger props - trigger, - - // Menu props - gutter, children, - shift, - modal = true, // From internal components context variant, - - // Rest - ...otherProps } = useContextSystem< + // @ts-expect-error TODO: missing 'className' typeof props & Pick< DropdownMenuContextType, 'variant' > >( props, 'DropdownMenu' ); const parentContext = useContext( DropdownMenuContext ); - const computedDirection = isRTL() ? 'rtl' : 'ltr'; + const rtl = isRTLFn(); // If an explicit value for the `placement` prop is not passed, // apply a default placement of `bottom-start` for the root dropdown, // and of `right-start` for nested dropdowns. let computedPlacement = - props.placement ?? - ( parentContext?.store ? 'right-start' : 'bottom-start' ); + placement ?? ( parentContext?.store ? 'right-start' : 'bottom-start' ); + // Swap left/right in case of RTL direction - if ( computedDirection === 'rtl' ) { + if ( rtl ) { if ( /right/.test( computedPlacement ) ) { computedPlacement = computedPlacement.replace( 'right', @@ -100,7 +79,7 @@ const UnconnectedDropdownMenu = ( setOpen( willBeOpen ) { onOpenChange?.( willBeOpen ); }, - rtl: computedDirection === 'rtl', + rtl, } ); const contextValue = useMemo( @@ -108,112 +87,28 @@ const UnconnectedDropdownMenu = ( [ dropdownMenuStore, variant ] ); - // Extract the side from the applied placement — useful for animations. - // Using `currentPlacement` instead of `placement` to make sure that we - // use the final computed placement (including "flips" etc). - const appliedPlacementSide = useStoreState( - dropdownMenuStore, - 'currentPlacement' - ).split( '-' )[ 0 ]; - - if ( - dropdownMenuStore.parent && - ! ( isValidElement( trigger ) && DropdownMenuItem === trigger.type ) - ) { - // eslint-disable-next-line no-console - console.warn( - 'For nested DropdownMenus, the `trigger` should always be a `DropdownMenuItem`.' - ); - } - - const hideOnEscape = useCallback( - ( event: React.KeyboardEvent< Element > ) => { - // Pressing Escape can cause unexpected consequences (ie. exiting - // full screen mode on MacOs, close parent modals...). - event.preventDefault(); - // Returning `true` causes the menu to hide. - return true; - }, - [] - ); - - const wrapperProps = useMemo( - () => ( { - dir: computedDirection, - style: { - direction: - computedDirection as React.CSSProperties[ 'direction' ], - }, - } ), - [ computedDirection ] - ); - return ( - <> - { /* Menu trigger */ } - - { trigger.props.suffix } -