Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 59 additions & 45 deletions packages/block-editor/src/hooks/grid-visualizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { useSelect } from '@wordpress/data';
import { GridVisualizer, useGridLayoutSync } from '../components/grid';
import { store as blockEditorStore } from '../store';
import { unlock } from '../lock-unlock';
import { useBlockElement } from '../components/block-list/use-block-props/use-block-refs';
import useBlockVisibility from '../components/block-visibility/use-block-visibility';
import { deviceTypeKey } from '../store/private-keys';
import { BLOCK_VISIBILITY_VIEWPORTS } from '../components/block-visibility/constants';
Expand All @@ -20,60 +21,73 @@ function GridLayoutSync( props ) {
}

function GridTools( { clientId, layout } ) {
const { isVisible, blockVisibility, deviceType, isAnyAncestorHidden } =
useSelect(
( select ) => {
const {
isBlockSelected,
hasSelectedInnerBlock,
isDraggingBlocks,
getTemplateLock,
getBlockEditingMode,
getBlockAttributes,
getSettings,
} = select( blockEditorStore );
const { isVisible, blockVisibility, deviceType } = useSelect(
( select ) => {
const {
isBlockSelected,
hasSelectedInnerBlock,
isDraggingBlocks,
getTemplateLock,
getBlockEditingMode,
getBlockAttributes,
getSettings,
} = select( blockEditorStore );

// These calls are purposely ordered from least expensive to most expensive.
// Hides the visualizer in cases where the user is not or cannot interact with it.
// Also hide if a child block is selected, because layout-child.js will render
// the visualizer in that case (with proper childGridClientId handling).
if (
( ! isDraggingBlocks() && ! isBlockSelected( clientId ) ) ||
getTemplateLock( clientId ) ||
getBlockEditingMode( clientId ) !== 'default' ||
hasSelectedInnerBlock( clientId )
) {
return { isVisible: false };
}
// These calls are purposely ordered from least expensive to most expensive.
// Hides the visualizer in cases where the user is not or cannot interact with it.
// Also hide if a child block is selected, because layout-child.js will render
// the visualizer in that case (with proper childGridClientId handling).
if (
( ! isDraggingBlocks() && ! isBlockSelected( clientId ) ) ||
getTemplateLock( clientId ) ||
getBlockEditingMode( clientId ) !== 'default' ||
hasSelectedInnerBlock( clientId )
) {
return { isVisible: false };
}

const { isBlockParentHiddenAtViewport } = unlock(
select( blockEditorStore )
);
const attributes = getBlockAttributes( clientId );
const settings = getSettings();
const currentDeviceType =
settings?.[ deviceTypeKey ]?.toLowerCase() ||
BLOCK_VISIBILITY_VIEWPORTS.desktop.key;

const attributes = getBlockAttributes( clientId );
const settings = getSettings();
const currentDeviceType =
settings?.[ deviceTypeKey ]?.toLowerCase() ||
BLOCK_VISIBILITY_VIEWPORTS.desktop.key;
return {
isVisible: true,
blockVisibility: attributes?.metadata?.blockVisibility,
deviceType: currentDeviceType,
};
},
[ clientId ]
);

return {
isVisible: true,
blockVisibility: attributes?.metadata?.blockVisibility,
deviceType: currentDeviceType,
isAnyAncestorHidden: isBlockParentHiddenAtViewport(
clientId,
currentDeviceType
),
};
},
[ clientId ]
);
// Get the block's DOM element to derive the canvas iframe window,
// so viewport detection matches the actual block rendering context
const blockElement = useBlockElement( clientId );
const rawCanvasView = blockElement?.ownerDocument?.defaultView;
const canvasView = rawCanvasView === null ? undefined : rawCanvasView;

const { isBlockCurrentlyHidden } = useBlockVisibility( {
const { isBlockCurrentlyHidden, currentViewport } = useBlockVisibility( {
blockVisibility,
deviceType,
view: canvasView,
} );

// Check whether any ancestor is hidden at the viewport actually detected
// from the canvas, so it stays consistent with how blocks are hidden.
const isAnyAncestorHidden = useSelect(
( select ) => {
if ( ! isVisible ) {
return false;
}
const { isBlockParentHiddenAtViewport } = unlock(
select( blockEditorStore )
);
return isBlockParentHiddenAtViewport( clientId, currentViewport );
},
[ clientId, currentViewport, isVisible ]
);

return (
<>
<GridLayoutSync clientId={ clientId } />
Expand Down
50 changes: 41 additions & 9 deletions packages/block-editor/src/hooks/layout-child.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import { useState } from '@wordpress/element';
* Internal dependencies
*/
import { store as blockEditorStore } from '../store';
import { unlock } from '../lock-unlock';
import { useStyleOverride } from './utils';
import { useLayout } from '../components/block-list/layout';
import {
GridVisualizer,
GridItemResizer,
GridItemMovers,
} from '../components/grid';
import { useBlockElement } from '../components/block-list/use-block-props/use-block-refs';
import useBlockVisibility from '../components/block-visibility/use-block-visibility';
import { deviceTypeKey } from '../store/private-keys';
import { BLOCK_VISIBILITY_VIEWPORTS } from '../components/block-visibility/constants';
Expand Down Expand Up @@ -390,6 +392,9 @@ function GridTools( {
const parentAttributes = getBlockAttributes( _rootClientId );
const blockAttributes = getBlockAttributes( clientId );
const settings = getSettings();
const currentDeviceType =
settings?.[ deviceTypeKey ]?.toLowerCase() ||
BLOCK_VISIBILITY_VIEWPORTS.desktop.key;

return {
rootClientId: _rootClientId,
Expand All @@ -398,34 +403,61 @@ function GridTools( {
parentAttributes?.metadata?.blockVisibility,
blockBlockVisibility:
blockAttributes?.metadata?.blockVisibility,
deviceType:
settings?.[ deviceTypeKey ]?.toLowerCase() ||
BLOCK_VISIBILITY_VIEWPORTS.desktop.key,
deviceType: currentDeviceType,
// Check if the selected child block is itself a grid.
isChildBlockAGrid: blockAttributes?.layout?.type === 'grid',
};
},
[ clientId ]
);

const { isBlockCurrentlyHidden: isParentBlockCurrentlyHidden } =
useBlockVisibility( {
blockVisibility: parentBlockVisibility,
deviceType,
} );
// Get the block's DOM element to derive the canvas iframe window,
// so viewport detection matches the actual block rendering context
const blockElement = useBlockElement( clientId );
const rawCanvasView = blockElement?.ownerDocument?.defaultView;
const canvasView = rawCanvasView === null ? undefined : rawCanvasView;

const {
isBlockCurrentlyHidden: isParentBlockCurrentlyHidden,
currentViewport,
} = useBlockVisibility( {
blockVisibility: parentBlockVisibility,
deviceType,
view: canvasView,
} );

// Check whether any ancestor of the parent grid is hidden at the viewport
// actually detected from the canvas, so it stays consistent with how
// blocks are hidden.
const isAnyAncestorHidden = useSelect(
( select ) => {
if ( ! rootClientId ) {
return false;
}
const { isBlockParentHiddenAtViewport } = unlock(
select( blockEditorStore )
);
return isBlockParentHiddenAtViewport(
rootClientId,
currentViewport
);
},
[ rootClientId, currentViewport ]
);

const { isBlockCurrentlyHidden: isBlockItselfCurrentlyHidden } =
useBlockVisibility( {
blockVisibility: blockBlockVisibility,
deviceType,
view: canvasView,
} );

// Use useState() instead of useRef() so that GridItemResizer updates when ref is set.
const [ resizerBounds, setResizerBounds ] = useState();

const childGridClientId = isChildBlockAGrid ? clientId : undefined;

if ( ! isVisible || isParentBlockCurrentlyHidden ) {
if ( ! isVisible || isParentBlockCurrentlyHidden || isAnyAncestorHidden ) {
return null;
}

Expand Down
Loading