diff --git a/packages/block-editor/src/components/block-inspector/index.js b/packages/block-editor/src/components/block-inspector/index.js index 3e2aebb5d500a5..b536a0c7539509 100644 --- a/packages/block-editor/src/components/block-inspector/index.js +++ b/packages/block-editor/src/components/block-inspector/index.js @@ -14,7 +14,6 @@ import { __experimentalHStack as HStack, __experimentalVStack as VStack, Button, - __unstableMotion as motion, } from '@wordpress/components'; import { useSelect, useDispatch } from '@wordpress/data'; import { useMemo, useCallback } from '@wordpress/element'; @@ -35,6 +34,7 @@ import { default as InspectorControls } from '../inspector-controls'; import { default as InspectorControlsTabs } from '../inspector-controls-tabs'; import useInspectorControlsTabs from '../inspector-controls-tabs/use-inspector-controls-tabs'; import AdvancedControls from '../inspector-controls-tabs/advanced-controls-panel'; +import NavigationInspector from './navigation-inspector'; function useContentBlocks( blockTypes, block ) { const contentBlocksObjectAux = useMemo( () => { @@ -169,26 +169,11 @@ const BlockInspector = ( { showNoBlockSelectedMessage = true } ) => { }; }, [] ); - const availableTabs = useInspectorControlsTabs( blockType?.name ); - const showTabs = availableTabs?.length > 1; - const isOffCanvasNavigationEditorEnabled = window?.__experimentalEnableOffCanvasNavigationEditor === true; - const blockInspectorAnimationSettings = useSelect( - ( select ) => { - if ( isOffCanvasNavigationEditorEnabled ) { - const globalBlockInspectorAnimationSettings = - select( blockEditorStore ).getSettings() - .__experimentalBlockInspectorAnimation; - return globalBlockInspectorAnimationSettings?.[ - blockType.name - ]; - } - return null; - }, - [ selectedBlockClientId, isOffCanvasNavigationEditorEnabled, blockType ] - ); + const availableTabs = useInspectorControlsTabs( blockType?.name ); + const showTabs = availableTabs?.length > 1; if ( count > 1 ) { return ( @@ -251,64 +236,26 @@ const BlockInspector = ( { showNoBlockSelectedMessage = true } ) => { ); } - return ( - ( - - { children } - - ) } - > - - - ); -}; - -const BlockInspectorSingleBlockWrapper = ( { animate, wrapper, children } ) => { - return animate ? wrapper( children ) : children; -}; - -const AnimatedContainer = ( { - blockInspectorAnimationSettings, - selectedBlockClientId, - children, -} ) => { - const animationOrigin = - blockInspectorAnimationSettings && - blockInspectorAnimationSettings.enterDirection === 'leftToRight' - ? -50 - : 50; + ); + } return ( - - { children } - + ); }; @@ -324,6 +271,7 @@ const BlockInspectorSingleBlock = ( { clientId, blockName } ) => { }, [ blockName ] ); + const blockInformation = useBlockDisplayInformation( clientId ); return ( diff --git a/packages/block-editor/src/components/block-inspector/navigation-inspector.js b/packages/block-editor/src/components/block-inspector/navigation-inspector.js new file mode 100644 index 00000000000000..f03ecce7a78ae3 --- /dev/null +++ b/packages/block-editor/src/components/block-inspector/navigation-inspector.js @@ -0,0 +1,153 @@ +/** + * WordPress dependencies + */ +import { + __experimentalNavigatorProvider as NavigatorProvider, + __experimentalNavigatorScreen as NavigatorScreen, + __experimentalUseNavigator as useNavigator, +} from '@wordpress/components'; +import { useSelect } from '@wordpress/data'; +import { useEffect, useRef } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { store as blockEditorStore } from '../../store'; + +const NavigationInspector = ( { + selectedBlockClientId, + blockName, + blockInspectorSingleBlock, +} ) => { + const { parentNavBlock, childNavBlocks } = useSelect( + ( select ) => { + const { + getBlockParentsByBlockName, + getClientIdsOfDescendants, + getBlock, + } = select( blockEditorStore ); + + let navBlockClientId; + + if ( blockName === 'core/navigation' ) { + navBlockClientId = selectedBlockClientId; + } else if ( + blockName === 'core/navigation-link' || + blockName === 'core/navigation-submenu' + ) { + navBlockClientId = getBlockParentsByBlockName( + selectedBlockClientId, + 'core/navigation', + true + )[ 0 ]; + } + + const _childClientIds = getClientIdsOfDescendants( [ + navBlockClientId, + ] ); + + return { + parentNavBlock: getBlock( navBlockClientId ), + childNavBlocks: _childClientIds.map( ( id ) => { + return getBlock( id ); + } ), + }; + }, + [ selectedBlockClientId, blockName ] + ); + + return ( + + + + ); +}; + +const NavigationInspectorScreens = ( { + selectedBlockClientId, + parentNavBlock, + childNavBlocks, + blockInspectorSingleBlock: BlockInspectorSingleBlock, +} ) => { + const { goTo } = useNavigator(); + const previousDepth = useRef( -1 ); + const { navBlockTree } = useSelect( + ( select ) => { + const { __unstableGetClientIdWithClientIdsTree } = + select( blockEditorStore ); + + return { + navBlockTree: __unstableGetClientIdWithClientIdsTree( + parentNavBlock.clientId + ), + }; + }, + [ selectedBlockClientId ] + ); + + const getBlockDepth = ( targetClientId, currentDepth, rootBlock ) => { + if ( targetClientId === rootBlock.clientId ) { + return currentDepth; + } + for ( let i = 0; i < rootBlock.innerBlocks.length; i++ ) { + const newDepth = getBlockDepth( + targetClientId, + currentDepth + 1, + rootBlock.innerBlocks[ i ] + ); + if ( newDepth > currentDepth ) { + return newDepth; + } + } + }; + + useEffect( () => { + const currentDepth = getBlockDepth( + selectedBlockClientId, + 0, + navBlockTree + ); + let animationOverride = 'disableAnimation'; + if ( currentDepth === 0 && previousDepth.current > 0 ) { + animationOverride = 'forceForward'; + } else if ( currentDepth > 0 && previousDepth.current === 0 ) { + animationOverride = 'forceBackward'; + } + previousDepth.current = currentDepth; + goTo( selectedBlockClientId, {}, animationOverride ); + }, [ selectedBlockClientId ] ); + + return ( + <> + + + + { childNavBlocks.map( ( childNavBlock ) => { + return ( + + + + ); + } ) } + + ); +}; + +export default NavigationInspector; diff --git a/packages/components/src/navigator/navigator-provider/component.tsx b/packages/components/src/navigator/navigator-provider/component.tsx index e80beaec9d14c4..6a48d2d46d5199 100644 --- a/packages/components/src/navigator/navigator-provider/component.tsx +++ b/packages/components/src/navigator/navigator-provider/component.tsx @@ -30,8 +30,13 @@ function UnconnectedNavigatorProvider( props: WordPressComponentProps< NavigatorProviderProps, 'div' >, forwardedRef: ForwardedRef< any > ) { - const { initialPath, children, className, ...otherProps } = - useContextSystem( props, 'NavigatorProvider' ); + const { + initialPath, + initialAnimationOverride = null, + children, + className, + ...otherProps + } = useContextSystem( props, 'NavigatorProvider' ); const [ locationHistory, setLocationHistory ] = useState< NavigatorLocation[] @@ -41,8 +46,13 @@ function UnconnectedNavigatorProvider( }, ] ); + const [ animationOverride, setAnimationOverride ] = useState( + initialAnimationOverride + ); + const goTo: NavigatorContextType[ 'goTo' ] = useCallback( - ( path, options = {} ) => { + ( path, options = {}, newAnimationOverride = null ) => { + setAnimationOverride( newAnimationOverride ); setLocationHistory( ( prevLocationHistory ) => [ ...prevLocationHistory, { @@ -80,8 +90,9 @@ function UnconnectedNavigatorProvider( }, goTo, goBack, + animationOverride, } ), - [ locationHistory, goTo, goBack ] + [ locationHistory, goTo, goBack, animationOverride ] ); const cx = useCx(); diff --git a/packages/components/src/navigator/navigator-screen/component.tsx b/packages/components/src/navigator/navigator-screen/component.tsx index 266bd553e0a8d2..4b048511eb8cf4 100644 --- a/packages/components/src/navigator/navigator-screen/component.tsx +++ b/packages/components/src/navigator/navigator-screen/component.tsx @@ -44,6 +44,8 @@ type Props = Omit< keyof MotionProps >; +type AnimationInitial = boolean | { opacity: number; x: number }; + function UnconnectedNavigatorScreen( props: Props, forwardedRef: ForwardedRef< any > @@ -54,7 +56,7 @@ function UnconnectedNavigatorScreen( ); const prefersReducedMotion = useReducedMotion(); - const { location } = useContext( NavigatorContext ); + const { location, animationOverride } = useContext( NavigatorContext ); const isMatch = location.path === escapeAttribute( path ); const wrapperRef = useRef< HTMLDivElement >( null ); @@ -161,13 +163,28 @@ function UnconnectedNavigatorScreen( }, x: 0, }; - const initial = { + let initial: AnimationInitial = { opacity: 0, x: ( isRTL() && location.isBack ) || ( ! isRTL() && ! location.isBack ) ? 50 : -50, }; + if ( animationOverride ) { + switch ( animationOverride ) { + case 'forceForward': + initial.x = isRTL() ? 50 : -50; + break; + + case 'forceBackward': + initial.x = isRTL() ? -50 : 50; + break; + + case 'disableAnimation': + initial = false; + break; + } + } const exit = { delay: animationExitDelay, opacity: 0, diff --git a/packages/components/src/navigator/types.ts b/packages/components/src/navigator/types.ts index 0b1a6a077ea7a0..f2d852444dedf7 100644 --- a/packages/components/src/navigator/types.ts +++ b/packages/components/src/navigator/types.ts @@ -7,6 +7,12 @@ type NavigateOptions = { focusTargetSelector?: string; }; +export type AnimationOverride = + | 'forceForward' + | 'forceBackward' + | 'disableAnimation' + | null; + export type NavigatorLocation = NavigateOptions & { isInitial?: boolean; isBack?: boolean; @@ -16,8 +22,13 @@ export type NavigatorLocation = NavigateOptions & { export type NavigatorContext = { location: NavigatorLocation; - goTo: ( path: string, options?: NavigateOptions ) => void; + goTo: ( + path: string, + options?: NavigateOptions, + animationOverride?: AnimationOverride + ) => void; goBack: () => void; + animationOverride?: AnimationOverride; }; // Returned by the `useNavigator` hook. @@ -28,6 +39,7 @@ export type NavigatorProviderProps = { * The initial active path. */ initialPath: string; + initialAnimationOverride?: AnimationOverride; /** * The children elements. */ diff --git a/packages/components/src/navigator/use-navigator.ts b/packages/components/src/navigator/use-navigator.ts index 052be3d0be498a..5c018dbb46ae87 100644 --- a/packages/components/src/navigator/use-navigator.ts +++ b/packages/components/src/navigator/use-navigator.ts @@ -13,12 +13,14 @@ import type { Navigator } from './types'; * Retrieves a `navigator` instance. */ function useNavigator(): Navigator { - const { location, goTo, goBack } = useContext( NavigatorContext ); + const { location, goTo, goBack, animationOverride } = + useContext( NavigatorContext ); return { location, goTo, goBack, + animationOverride, }; }