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,
};
}