-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Expand file tree
/
Copy pathviewport-visibility-info.js
More file actions
138 lines (127 loc) · 3.89 KB
/
viewport-visibility-info.js
File metadata and controls
138 lines (127 loc) · 3.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/**
* WordPress dependencies
*/
import {
Icon,
__experimentalHStack as HStack,
privateApis as componentsPrivateApis,
} from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { __, sprintf } from '@wordpress/i18n';
import { unseen } from '@wordpress/icons';
import { Text } from '@wordpress/ui';
/**
* Internal dependencies
*/
import { unlock } from '../../lock-unlock';
import { store as blockEditorStore } from '../../store';
import useBlockVisibility from './use-block-visibility';
import { useBlockElement } from '../block-list/use-block-props/use-block-refs';
import { deviceTypeKey } from '../../store/private-keys';
import { BLOCK_VISIBILITY_VIEWPORTS } from './constants';
const { Badge: WCBadge } = unlock( componentsPrivateApis );
const DEFAULT_VISIBILITY_STATE = {
currentBlockVisibility: undefined,
hasParentHiddenEverywhere: false,
selectedDeviceType: BLOCK_VISIBILITY_VIEWPORTS.desktop.key,
};
export default function ViewportVisibilityInfo( { clientId } ) {
const {
currentBlockVisibility,
selectedDeviceType,
hasParentHiddenEverywhere,
} = useSelect(
( select ) => {
if ( ! clientId ) {
return DEFAULT_VISIBILITY_STATE;
}
const {
getBlockAttributes,
isBlockParentHiddenEverywhere,
getSettings,
} = unlock( select( blockEditorStore ) );
return {
currentBlockVisibility:
getBlockAttributes( clientId )?.metadata?.blockVisibility,
selectedDeviceType:
getSettings()?.[ deviceTypeKey ]?.toLowerCase() ||
BLOCK_VISIBILITY_VIEWPORTS.desktop.key,
hasParentHiddenEverywhere:
isBlockParentHiddenEverywhere( clientId ),
};
},
[ 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, currentViewport } = useBlockVisibility( {
blockVisibility: currentBlockVisibility,
deviceType: selectedDeviceType,
view: canvasView,
} );
/*
* Selector to check if any parent (immediate or further up the chain) is hidden at current viewport.
* Separated because it depends on currentViewport from the hook above.
*/
const isBlockParentHiddenAtViewport = useSelect(
( select ) => {
if ( ! clientId || ! currentViewport ) {
return false;
}
return unlock(
select( blockEditorStore )
).isBlockParentHiddenAtViewport( clientId, currentViewport );
},
[ clientId, currentViewport ]
);
if (
! (
isBlockCurrentlyHidden ||
hasParentHiddenEverywhere ||
isBlockParentHiddenAtViewport
)
) {
return null;
}
// Determine label based on whether block or parent is hidden
let label;
if ( isBlockCurrentlyHidden ) {
// Block is currently hidden - check if hidden everywhere or at specific viewport
if ( currentBlockVisibility === false ) {
label = __( 'Block is hidden' );
} else {
const viewportLabel =
BLOCK_VISIBILITY_VIEWPORTS[ currentViewport ]?.label ||
currentViewport;
label = sprintf(
/* translators: %s: viewport name (Desktop, Tablet, Mobile) */
__( 'Block is hidden on %s' ),
viewportLabel
);
}
}
// Parent is hidden - check if hidden everywhere or at specific viewport
if ( hasParentHiddenEverywhere ) {
label = __( 'Parent block is hidden' );
} else if ( isBlockParentHiddenAtViewport ) {
const viewportLabel =
BLOCK_VISIBILITY_VIEWPORTS[ currentViewport ]?.label ||
currentViewport;
label = sprintf(
/* translators: %s: viewport name (Desktop, Tablet, Mobile) */
__( 'Parent block is hidden on %s' ),
viewportLabel
);
}
return (
<WCBadge className="block-editor-block-visibility-info">
<HStack spacing={ 2 } justify="start">
<Icon icon={ unseen } />
<Text>{ label }</Text>
</HStack>
</WCBadge>
);
}