Skip to content

Commit 77463ee

Browse files
committed
Deselect block on viewport preview switch when hidden and list view not open
1 parent ce0376a commit 77463ee

4 files changed

Lines changed: 93 additions & 20 deletions

File tree

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* Internal dependencies
3+
*/
4+
import { BLOCK_VISIBILITY_VIEWPORTS } from './constants';
5+
6+
/**
7+
* Resolves the effective viewport used for visibility checks.
8+
*
9+
* @param {string} deviceType Current preview device type.
10+
* @param {boolean} isLargerThanMobile Whether viewport is >= mobile breakpoint.
11+
* @param {boolean} isLargerThanTablet Whether viewport is >= tablet breakpoint.
12+
*
13+
* @return {string} Effective viewport key ('desktop'|'tablet'|'mobile').
14+
*/
15+
export function resolveCurrentViewport(
16+
deviceType,
17+
isLargerThanMobile,
18+
isLargerThanTablet
19+
) {
20+
const normalizedDeviceType = deviceType?.toLowerCase();
21+
22+
if ( normalizedDeviceType === BLOCK_VISIBILITY_VIEWPORTS.mobile.key ) {
23+
return BLOCK_VISIBILITY_VIEWPORTS.mobile.key;
24+
}
25+
26+
if ( normalizedDeviceType === BLOCK_VISIBILITY_VIEWPORTS.tablet.key ) {
27+
return BLOCK_VISIBILITY_VIEWPORTS.tablet.key;
28+
}
29+
30+
// Desktop preview falls back to current window width breakpoints.
31+
if ( ! isLargerThanMobile ) {
32+
return BLOCK_VISIBILITY_VIEWPORTS.mobile.key;
33+
}
34+
35+
if ( ! isLargerThanTablet ) {
36+
return BLOCK_VISIBILITY_VIEWPORTS.tablet.key;
37+
}
38+
39+
return BLOCK_VISIBILITY_VIEWPORTS.desktop.key;
40+
}

packages/block-editor/src/components/block-visibility/use-block-visibility.js

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { useViewportMatch } from '@wordpress/compose';
77
* Internal dependencies
88
*/
99
import { BLOCK_VISIBILITY_VIEWPORTS } from './constants';
10+
import { resolveCurrentViewport } from './resolve-current-viewport';
1011

1112
/**
1213
* Returns information about the current block visibility state.
@@ -25,23 +26,11 @@ export default function useBlockVisibility( options = {} ) {
2526
const isLargerThanMobile = useViewportMatch( 'mobile', '>=' ); // >= 480px
2627
const isLargerThanTablet = useViewportMatch( 'medium', '>=' ); // >= 782px
2728

28-
/*
29-
* Priority:
30-
* 1. Device type override (Mobile/Tablet) - uses device type to determine viewport
31-
* 2. Actual window size (Desktop mode) - uses viewport detection
32-
*/
33-
let currentViewport;
34-
if ( deviceType === BLOCK_VISIBILITY_VIEWPORTS.mobile.key ) {
35-
currentViewport = BLOCK_VISIBILITY_VIEWPORTS.mobile.key;
36-
} else if ( deviceType === BLOCK_VISIBILITY_VIEWPORTS.tablet.key ) {
37-
currentViewport = BLOCK_VISIBILITY_VIEWPORTS.tablet.key;
38-
} else if ( ! isLargerThanMobile ) {
39-
currentViewport = BLOCK_VISIBILITY_VIEWPORTS.mobile.key;
40-
} else if ( isLargerThanMobile && ! isLargerThanTablet ) {
41-
currentViewport = BLOCK_VISIBILITY_VIEWPORTS.tablet.key;
42-
} else {
43-
currentViewport = BLOCK_VISIBILITY_VIEWPORTS.desktop.key;
44-
}
29+
const currentViewport = resolveCurrentViewport(
30+
deviceType,
31+
isLargerThanMobile,
32+
isLargerThanTablet
33+
);
4534

4635
// Determine if block is currently hidden.
4736
const isBlockCurrentlyHidden =

packages/block-editor/src/private-apis.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ import {
7373
isHashLink,
7474
isRelativePath,
7575
} from './components/link-control/is-url-like';
76+
import { resolveCurrentViewport } from './components/block-visibility/resolve-current-viewport';
7677

7778
/**
7879
* Private @wordpress/block-editor APIs.
@@ -139,4 +140,5 @@ lock( privateApis, {
139140
useListViewPanelState,
140141
isHashLink,
141142
isRelativePath,
143+
resolveCurrentViewport,
142144
} );

packages/editor/src/components/preview-dropdown/index.js

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@ import {
1717
} from '@wordpress/components';
1818
import { __ } from '@wordpress/i18n';
1919
import { desktop, mobile, tablet, external, check } from '@wordpress/icons';
20-
import { useSelect, useDispatch } from '@wordpress/data';
20+
import { useSelect, useDispatch, useRegistry } from '@wordpress/data';
2121
import { store as coreStore } from '@wordpress/core-data';
2222
import { store as preferencesStore } from '@wordpress/preferences';
2323
import { ActionItem } from '@wordpress/interface';
24-
import { store as blockEditorStore } from '@wordpress/block-editor';
24+
import {
25+
store as blockEditorStore,
26+
privateApis as blockEditorPrivateApis,
27+
} from '@wordpress/block-editor';
2528

2629
/**
2730
* Internal dependencies
@@ -30,6 +33,8 @@ import { store as editorStore } from '../../store';
3033
import PostPreviewButton from '../post-preview-button';
3134
import { unlock } from '../../lock-unlock';
3235

36+
const { resolveCurrentViewport } = unlock( blockEditorPrivateApis );
37+
3338
export default function PreviewDropdown( { forceIsAutosaveable, disabled } ) {
3439
const {
3540
deviceType,
@@ -62,9 +67,46 @@ export default function PreviewDropdown( { forceIsAutosaveable, disabled } ) {
6267
const { setDeviceType, setRenderingMode, setDefaultRenderingMode } = unlock(
6368
useDispatch( editorStore )
6469
);
65-
const { resetZoomLevel } = unlock( useDispatch( blockEditorStore ) );
70+
const blockEditorDispatch = useDispatch( blockEditorStore );
71+
const { clearSelectedBlock } = blockEditorDispatch;
72+
const { resetZoomLevel } = unlock( blockEditorDispatch );
73+
const registry = useRegistry();
74+
75+
const isLargerThanMobile = useViewportMatch( 'mobile', '>=' ); // >= 480px
76+
const isLargerThanTablet = useViewportMatch( 'medium', '>=' ); // >= 782px
6677

6778
const handleDevicePreviewChange = ( newDeviceType ) => {
79+
const isListViewOpened = registry
80+
.select( editorStore )
81+
.isListViewOpened();
82+
const selectedBlockClientId = registry
83+
.select( blockEditorStore )
84+
.getSelectedBlockClientId();
85+
86+
if ( ! isListViewOpened && selectedBlockClientId ) {
87+
const targetViewport = resolveCurrentViewport(
88+
newDeviceType,
89+
isLargerThanMobile,
90+
isLargerThanTablet
91+
);
92+
const blockEditorSelectors = unlock(
93+
registry.select( blockEditorStore )
94+
);
95+
const isSelectedBlockHiddenInTargetViewport =
96+
blockEditorSelectors.isBlockHiddenAtViewport(
97+
selectedBlockClientId,
98+
targetViewport
99+
) ||
100+
blockEditorSelectors.isBlockParentHiddenAtViewport(
101+
selectedBlockClientId,
102+
targetViewport
103+
);
104+
105+
if ( isSelectedBlockHiddenInTargetViewport ) {
106+
clearSelectedBlock();
107+
}
108+
}
109+
68110
setDeviceType( newDeviceType );
69111
resetZoomLevel();
70112
};

0 commit comments

Comments
 (0)