@wordpress/block-editor 15.4.1-next.f56bd8138.0 → 15.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/build/components/background-image-control/index.js +51 -24
- package/build/components/background-image-control/index.js.map +1 -1
- package/build/components/block-edit/edit.js +13 -5
- package/build/components/block-edit/edit.js.map +1 -1
- package/build/components/block-list/block.js +14 -4
- package/build/components/block-list/block.js.map +1 -1
- package/build/components/block-list/use-block-props/index.js +5 -4
- package/build/components/block-list/use-block-props/index.js.map +1 -1
- package/build/components/block-settings-menu-controls/index.js +10 -2
- package/build/components/block-settings-menu-controls/index.js.map +1 -1
- package/build/components/block-toolbar/index.js +5 -0
- package/build/components/block-toolbar/index.js.map +1 -1
- package/build/components/block-visibility/index.js +21 -0
- package/build/components/block-visibility/index.js.map +1 -0
- package/build/components/block-visibility/menu-item.js +52 -0
- package/build/components/block-visibility/menu-item.js.map +1 -0
- package/build/components/block-visibility/toolbar.js +88 -0
- package/build/components/block-visibility/toolbar.js.map +1 -0
- package/build/components/inspector-controls-tabs/index.js +23 -0
- package/build/components/inspector-controls-tabs/index.js.map +1 -1
- package/build/components/link-control/index.js +1 -1
- package/build/components/link-control/index.js.map +1 -1
- package/build/components/list-view/block-select-button.js +23 -4
- package/build/components/list-view/block-select-button.js.map +1 -1
- package/build/components/list-view/block.js +9 -3
- package/build/components/list-view/block.js.map +1 -1
- package/build/components/rich-text/index.js +4 -2
- package/build/components/rich-text/index.js.map +1 -1
- package/build/components/use-block-drop-zone/index.js +5 -1
- package/build/components/use-block-drop-zone/index.js.map +1 -1
- package/build/hooks/block-bindings.js +9 -4
- package/build/hooks/block-bindings.js.map +1 -1
- package/build/store/private-selectors.js +19 -1
- package/build/store/private-selectors.js.map +1 -1
- package/build/store/reducer.js +1 -5
- package/build/store/reducer.js.map +1 -1
- package/build/utils/block-bindings.js +3 -48
- package/build/utils/block-bindings.js.map +1 -1
- package/build-module/components/background-image-control/index.js +52 -25
- package/build-module/components/background-image-control/index.js.map +1 -1
- package/build-module/components/block-edit/edit.js +14 -6
- package/build-module/components/block-edit/edit.js.map +1 -1
- package/build-module/components/block-list/block.js +14 -4
- package/build-module/components/block-list/block.js.map +1 -1
- package/build-module/components/block-list/use-block-props/index.js +5 -4
- package/build-module/components/block-list/use-block-props/index.js.map +1 -1
- package/build-module/components/block-settings-menu-controls/index.js +10 -2
- package/build-module/components/block-settings-menu-controls/index.js.map +1 -1
- package/build-module/components/block-toolbar/index.js +5 -0
- package/build-module/components/block-toolbar/index.js.map +1 -1
- package/build-module/components/block-visibility/index.js +3 -0
- package/build-module/components/block-visibility/index.js.map +1 -0
- package/build-module/components/block-visibility/menu-item.js +45 -0
- package/build-module/components/block-visibility/menu-item.js.map +1 -0
- package/build-module/components/block-visibility/toolbar.js +81 -0
- package/build-module/components/block-visibility/toolbar.js.map +1 -0
- package/build-module/components/inspector-controls-tabs/index.js +23 -0
- package/build-module/components/inspector-controls-tabs/index.js.map +1 -1
- package/build-module/components/link-control/index.js +1 -1
- package/build-module/components/link-control/index.js.map +1 -1
- package/build-module/components/list-view/block-select-button.js +24 -5
- package/build-module/components/list-view/block-select-button.js.map +1 -1
- package/build-module/components/list-view/block.js +9 -3
- package/build-module/components/list-view/block.js.map +1 -1
- package/build-module/components/rich-text/index.js +4 -2
- package/build-module/components/rich-text/index.js.map +1 -1
- package/build-module/components/use-block-drop-zone/index.js +6 -2
- package/build-module/components/use-block-drop-zone/index.js.map +1 -1
- package/build-module/hooks/block-bindings.js +10 -5
- package/build-module/hooks/block-bindings.js.map +1 -1
- package/build-module/store/private-selectors.js +18 -1
- package/build-module/store/private-selectors.js.map +1 -1
- package/build-module/store/reducer.js +1 -5
- package/build-module/store/reducer.js.map +1 -1
- package/build-module/utils/block-bindings.js +3 -45
- package/build-module/utils/block-bindings.js.map +1 -1
- package/build-style/content-rtl.css +13 -0
- package/build-style/content.css +13 -0
- package/build-style/style-rtl.css +27 -0
- package/build-style/style.css +27 -0
- package/package.json +34 -34
- package/src/components/background-image-control/index.js +54 -27
- package/src/components/background-image-control/style.scss +28 -0
- package/src/components/block-edit/edit.js +23 -5
- package/src/components/block-list/block.js +16 -0
- package/src/components/block-list/content.scss +19 -0
- package/src/components/block-list/use-block-props/index.js +9 -9
- package/src/components/block-settings-menu-controls/index.js +21 -1
- package/src/components/block-toolbar/index.js +9 -0
- package/src/components/block-visibility/index.js +2 -0
- package/src/components/block-visibility/menu-item.js +53 -0
- package/src/components/block-visibility/toolbar.js +88 -0
- package/src/components/inspector-controls-tabs/index.js +33 -1
- package/src/components/link-control/index.js +1 -1
- package/src/components/link-control/test/index.js +4 -4
- package/src/components/list-view/block-select-button.js +32 -9
- package/src/components/list-view/block.js +24 -14
- package/src/components/list-view/style.scss +1 -0
- package/src/components/media-replace-flow/test/index.js +1 -1
- package/src/components/rich-text/index.js +6 -2
- package/src/components/use-block-drop-zone/index.js +14 -1
- package/src/hooks/block-bindings.js +49 -43
- package/src/store/private-selectors.js +21 -1
- package/src/store/reducer.js +1 -6
- package/src/utils/block-bindings.js +6 -48
|
@@ -624,6 +624,7 @@ function BlockListBlockProvider( props ) {
|
|
|
624
624
|
? getBlockDefaultClassName( blockName )
|
|
625
625
|
: undefined,
|
|
626
626
|
blockTitle: blockType?.title,
|
|
627
|
+
isBlockHidden: attributes?.metadata?.blockVisibility === false,
|
|
627
628
|
};
|
|
628
629
|
|
|
629
630
|
// When in preview mode, we can avoid a lot of selection and
|
|
@@ -632,6 +633,9 @@ function BlockListBlockProvider( props ) {
|
|
|
632
633
|
return previewContext;
|
|
633
634
|
}
|
|
634
635
|
|
|
636
|
+
const { isBlockHidden: _isBlockHidden } = unlock(
|
|
637
|
+
select( blockEditorStore )
|
|
638
|
+
);
|
|
635
639
|
const _isSelected = isBlockSelected( clientId );
|
|
636
640
|
const canRemove = canRemoveBlock( clientId );
|
|
637
641
|
const canMove = canMoveBlock( clientId );
|
|
@@ -705,6 +709,7 @@ function BlockListBlockProvider( props ) {
|
|
|
705
709
|
originalBlockClientId: isInvalid
|
|
706
710
|
? blocksWithSameName[ 0 ]
|
|
707
711
|
: false,
|
|
712
|
+
isBlockHidden: _isBlockHidden( clientId ),
|
|
708
713
|
};
|
|
709
714
|
},
|
|
710
715
|
[ clientId, rootClientId ]
|
|
@@ -747,6 +752,7 @@ function BlockListBlockProvider( props ) {
|
|
|
747
752
|
className,
|
|
748
753
|
defaultClassName,
|
|
749
754
|
originalBlockClientId,
|
|
755
|
+
isBlockHidden,
|
|
750
756
|
} = selectedProps;
|
|
751
757
|
|
|
752
758
|
// Users of the editor.BlockListBlock filter used to be able to
|
|
@@ -795,8 +801,18 @@ function BlockListBlockProvider( props ) {
|
|
|
795
801
|
originalBlockClientId,
|
|
796
802
|
themeSupportsLayout,
|
|
797
803
|
canMove,
|
|
804
|
+
isBlockHidden,
|
|
798
805
|
};
|
|
799
806
|
|
|
807
|
+
if (
|
|
808
|
+
isBlockHidden &&
|
|
809
|
+
! isSelected &&
|
|
810
|
+
! isMultiSelected &&
|
|
811
|
+
! hasChildSelected
|
|
812
|
+
) {
|
|
813
|
+
return null;
|
|
814
|
+
}
|
|
815
|
+
|
|
800
816
|
// Here we separate between the props passed to BlockListBlock and any other
|
|
801
817
|
// information we selected for internal use. BlockListBlock is a filtered
|
|
802
818
|
// component and thus ALL the props are PUBLIC API.
|
|
@@ -93,6 +93,25 @@ _::-webkit-full-page-media, _:future, :root [data-has-multi-selection="true"] .b
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
|
|
97
|
+
// Hidden blocks.
|
|
98
|
+
// In order for the block toolbar to render correctly, blocks cannot be hidden.
|
|
99
|
+
// Instead, use styles to visually hide blocks.
|
|
100
|
+
.block-editor-block-list__block.is-block-hidden {
|
|
101
|
+
visibility: hidden;
|
|
102
|
+
overflow: hidden;
|
|
103
|
+
height: 0;
|
|
104
|
+
border: none !important;
|
|
105
|
+
padding: 0 !important;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
&.is-layout-flex:not(.is-vertical) > .is-block-hidden {
|
|
109
|
+
width: 0;
|
|
110
|
+
height: auto;
|
|
111
|
+
align-self: stretch;
|
|
112
|
+
white-space: nowrap !important;
|
|
113
|
+
}
|
|
114
|
+
|
|
96
115
|
// Re-enable it on components inside.
|
|
97
116
|
[class^="components-"] {
|
|
98
117
|
user-select: text;
|
|
@@ -29,7 +29,6 @@ import { useBlockRefProvider } from './use-block-refs';
|
|
|
29
29
|
import { useIntersectionObserver } from './use-intersection-observer';
|
|
30
30
|
import { useScrollIntoView } from './use-scroll-into-view';
|
|
31
31
|
import { useFlashEditableBlocks } from '../../use-flash-editable-blocks';
|
|
32
|
-
import { canBindBlock } from '../../../utils/block-bindings';
|
|
33
32
|
import { useFirefoxDraggableCompatibility } from './use-firefox-draggable-compatibility';
|
|
34
33
|
|
|
35
34
|
/**
|
|
@@ -102,6 +101,7 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) {
|
|
|
102
101
|
defaultClassName,
|
|
103
102
|
isSectionBlock,
|
|
104
103
|
canMove,
|
|
104
|
+
isBlockHidden,
|
|
105
105
|
} = useContext( PrivateBlockContext );
|
|
106
106
|
|
|
107
107
|
// translators: %s: Type of block (i.e. Text, Image etc)
|
|
@@ -128,14 +128,13 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) {
|
|
|
128
128
|
|
|
129
129
|
const blockEditContext = useBlockEditContext();
|
|
130
130
|
const hasBlockBindings = !! blockEditContext[ blockBindingsKey ];
|
|
131
|
-
const bindingsStyle =
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
'--wp-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
: {};
|
|
131
|
+
const bindingsStyle = hasBlockBindings
|
|
132
|
+
? {
|
|
133
|
+
'--wp-admin-theme-color': 'var(--wp-block-synced-color)',
|
|
134
|
+
'--wp-admin-theme-color--rgb':
|
|
135
|
+
'var(--wp-block-synced-color--rgb)',
|
|
136
|
+
}
|
|
137
|
+
: {};
|
|
139
138
|
|
|
140
139
|
// Ensures it warns only inside the `edit` implementation for the block.
|
|
141
140
|
if ( blockApiVersion < 2 && clientId === blockEditContext.clientId ) {
|
|
@@ -185,6 +184,7 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) {
|
|
|
185
184
|
'has-negative-margin': hasNegativeMargin,
|
|
186
185
|
'is-content-locked-temporarily-editing-as-blocks':
|
|
187
186
|
isTemporarilyEditingAsBlocks,
|
|
187
|
+
'is-block-hidden': isBlockHidden,
|
|
188
188
|
},
|
|
189
189
|
className,
|
|
190
190
|
props.className,
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
MenuGroup,
|
|
7
7
|
__experimentalStyleProvider as StyleProvider,
|
|
8
8
|
} from '@wordpress/components';
|
|
9
|
+
import { hasBlockSupport } from '@wordpress/blocks';
|
|
9
10
|
import { useSelect } from '@wordpress/data';
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -20,13 +21,20 @@ import { store as blockEditorStore } from '../../store';
|
|
|
20
21
|
import BlockModeToggle from '../block-settings-menu/block-mode-toggle';
|
|
21
22
|
import { ModifyContentLockMenuItem } from '../content-lock';
|
|
22
23
|
import { BlockRenameControl, useBlockRename } from '../block-rename';
|
|
24
|
+
import { BlockVisibilityMenuItem } from '../block-visibility';
|
|
23
25
|
|
|
24
26
|
const { Fill, Slot } = createSlotFill( 'BlockSettingsMenuControls' );
|
|
25
27
|
|
|
26
28
|
const BlockSettingsMenuControlsSlot = ( { fillProps, clientIds = null } ) => {
|
|
27
|
-
const {
|
|
29
|
+
const {
|
|
30
|
+
selectedBlocks,
|
|
31
|
+
selectedClientIds,
|
|
32
|
+
isContentOnly,
|
|
33
|
+
canToggleSelectedBlocksVisibility,
|
|
34
|
+
} = useSelect(
|
|
28
35
|
( select ) => {
|
|
29
36
|
const {
|
|
37
|
+
getBlocksByClientId,
|
|
30
38
|
getBlockNamesByClientId,
|
|
31
39
|
getSelectedBlockClientIds,
|
|
32
40
|
getBlockEditingMode,
|
|
@@ -38,6 +46,11 @@ const BlockSettingsMenuControlsSlot = ( { fillProps, clientIds = null } ) => {
|
|
|
38
46
|
selectedClientIds: ids,
|
|
39
47
|
isContentOnly:
|
|
40
48
|
getBlockEditingMode( ids[ 0 ] ) === 'contentOnly',
|
|
49
|
+
canToggleSelectedBlocksVisibility: getBlocksByClientId(
|
|
50
|
+
ids
|
|
51
|
+
).every( ( block ) =>
|
|
52
|
+
hasBlockSupport( block.name, 'blockVisibility', true )
|
|
53
|
+
),
|
|
41
54
|
};
|
|
42
55
|
},
|
|
43
56
|
[ clientIds ]
|
|
@@ -49,6 +62,8 @@ const BlockSettingsMenuControlsSlot = ( { fillProps, clientIds = null } ) => {
|
|
|
49
62
|
selectedClientIds.length === 1 && canLock && ! isContentOnly;
|
|
50
63
|
const showRenameButton =
|
|
51
64
|
selectedClientIds.length === 1 && canRename && ! isContentOnly;
|
|
65
|
+
const showVisibilityButton =
|
|
66
|
+
canToggleSelectedBlocksVisibility && ! isContentOnly;
|
|
52
67
|
|
|
53
68
|
// Check if current selection of blocks is Groupable or Ungroupable
|
|
54
69
|
// and pass this props down to ConvertToGroupButton.
|
|
@@ -93,6 +108,11 @@ const BlockSettingsMenuControlsSlot = ( { fillProps, clientIds = null } ) => {
|
|
|
93
108
|
clientId={ selectedClientIds[ 0 ] }
|
|
94
109
|
/>
|
|
95
110
|
) }
|
|
111
|
+
{ showVisibilityButton && (
|
|
112
|
+
<BlockVisibilityMenuItem
|
|
113
|
+
clientIds={ selectedClientIds }
|
|
114
|
+
/>
|
|
115
|
+
) }
|
|
96
116
|
{ fills }
|
|
97
117
|
{ selectedClientIds.length === 1 && (
|
|
98
118
|
<ModifyContentLockMenuItem
|
|
@@ -28,6 +28,7 @@ import BlockControls from '../block-controls';
|
|
|
28
28
|
import __unstableBlockToolbarLastItem from './block-toolbar-last-item';
|
|
29
29
|
import BlockSettingsMenu from '../block-settings-menu';
|
|
30
30
|
import { BlockLockToolbar } from '../block-lock';
|
|
31
|
+
import { BlockVisibilityToolbar } from '../block-visibility';
|
|
31
32
|
import { BlockGroupToolbar } from '../convert-to-group-buttons';
|
|
32
33
|
import BlockEditVisuallyButton from '../block-edit-visually-button';
|
|
33
34
|
import { useShowHoveredOrFocusedGestures } from './utils';
|
|
@@ -73,6 +74,7 @@ export function PrivateBlockToolbar( {
|
|
|
73
74
|
showSlots,
|
|
74
75
|
showGroupButtons,
|
|
75
76
|
showLockButtons,
|
|
77
|
+
showBlockVisibilityButton,
|
|
76
78
|
showSwitchSectionStyleButton,
|
|
77
79
|
hasFixedToolbar,
|
|
78
80
|
isNavigationMode,
|
|
@@ -163,6 +165,7 @@ export function PrivateBlockToolbar( {
|
|
|
163
165
|
showSlots: ! _isZoomOut,
|
|
164
166
|
showGroupButtons: ! _isZoomOut,
|
|
165
167
|
showLockButtons: ! _isZoomOut,
|
|
168
|
+
showBlockVisibilityButton: ! _isZoomOut,
|
|
166
169
|
showSwitchSectionStyleButton: _showSwitchSectionStyleButton,
|
|
167
170
|
hasFixedToolbar: getSettings().hasFixedToolbar,
|
|
168
171
|
isNavigationMode: isNavigationModeEnabled,
|
|
@@ -227,6 +230,12 @@ export function PrivateBlockToolbar( {
|
|
|
227
230
|
>
|
|
228
231
|
<ToolbarGroup className="block-editor-block-toolbar__block-controls">
|
|
229
232
|
<BlockSwitcher clientIds={ blockClientIds } />
|
|
233
|
+
{ isDefaultEditingMode &&
|
|
234
|
+
showBlockVisibilityButton && (
|
|
235
|
+
<BlockVisibilityToolbar
|
|
236
|
+
clientIds={ blockClientIds }
|
|
237
|
+
/>
|
|
238
|
+
) }
|
|
230
239
|
{ ! isMultiToolbar &&
|
|
231
240
|
isDefaultEditingMode &&
|
|
232
241
|
showLockButtons && (
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
import { MenuItem } from '@wordpress/components';
|
|
6
|
+
import { seen, unseen } from '@wordpress/icons';
|
|
7
|
+
import { useSelect, useDispatch } from '@wordpress/data';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Internal dependencies
|
|
11
|
+
*/
|
|
12
|
+
import { cleanEmptyObject } from '../../hooks/utils';
|
|
13
|
+
import { store as blockEditorStore } from '../../store';
|
|
14
|
+
|
|
15
|
+
export default function BlockVisibilityMenuItem( { clientIds } ) {
|
|
16
|
+
const { updateBlockAttributes } = useDispatch( blockEditorStore );
|
|
17
|
+
const blocks = useSelect(
|
|
18
|
+
( select ) => {
|
|
19
|
+
return select( blockEditorStore ).getBlocksByClientId( clientIds );
|
|
20
|
+
},
|
|
21
|
+
[ clientIds ]
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const hasHiddenBlock = blocks.some(
|
|
25
|
+
( block ) => block.attributes.metadata?.blockVisibility === false
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const toggleBlockVisibility = () => {
|
|
29
|
+
const attributesByClientId = Object.fromEntries(
|
|
30
|
+
blocks?.map( ( { clientId, attributes } ) => [
|
|
31
|
+
clientId,
|
|
32
|
+
{
|
|
33
|
+
metadata: cleanEmptyObject( {
|
|
34
|
+
...attributes?.metadata,
|
|
35
|
+
blockVisibility: hasHiddenBlock ? undefined : false,
|
|
36
|
+
} ),
|
|
37
|
+
},
|
|
38
|
+
] )
|
|
39
|
+
);
|
|
40
|
+
updateBlockAttributes( clientIds, attributesByClientId, {
|
|
41
|
+
uniqueByBlock: true,
|
|
42
|
+
} );
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<MenuItem
|
|
47
|
+
icon={ hasHiddenBlock ? seen : unseen }
|
|
48
|
+
onClick={ toggleBlockVisibility }
|
|
49
|
+
>
|
|
50
|
+
{ hasHiddenBlock ? __( 'Show' ) : __( 'Hide' ) }
|
|
51
|
+
</MenuItem>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
import { ToolbarButton, ToolbarGroup } from '@wordpress/components';
|
|
6
|
+
import { useRef, useEffect } from '@wordpress/element';
|
|
7
|
+
import { seen, unseen } from '@wordpress/icons';
|
|
8
|
+
import { useSelect, useDispatch } from '@wordpress/data';
|
|
9
|
+
import { hasBlockSupport } from '@wordpress/blocks';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Internal dependencies
|
|
13
|
+
*/
|
|
14
|
+
import { store as blockEditorStore } from '../../store';
|
|
15
|
+
import { cleanEmptyObject } from '../../hooks/utils';
|
|
16
|
+
|
|
17
|
+
export default function BlockVisibilityToolbar( { clientIds } ) {
|
|
18
|
+
const { blocks, canToggleBlockVisibility } = useSelect(
|
|
19
|
+
( select ) => {
|
|
20
|
+
const { getBlockName, getBlocksByClientId } =
|
|
21
|
+
select( blockEditorStore );
|
|
22
|
+
const _blocks = getBlocksByClientId( clientIds );
|
|
23
|
+
return {
|
|
24
|
+
blocks: _blocks,
|
|
25
|
+
canToggleBlockVisibility: _blocks.every( ( { clientId } ) =>
|
|
26
|
+
hasBlockSupport(
|
|
27
|
+
getBlockName( clientId ),
|
|
28
|
+
'blockVisibility',
|
|
29
|
+
true
|
|
30
|
+
)
|
|
31
|
+
),
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
[ clientIds ]
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
const hasHiddenBlock = blocks.some(
|
|
38
|
+
( block ) => block.attributes.metadata?.blockVisibility === false
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const hasBlockVisibilityButtonShownRef = useRef( false );
|
|
42
|
+
const { updateBlockAttributes } = useDispatch( blockEditorStore );
|
|
43
|
+
|
|
44
|
+
// If the block visibility button has been shown, we don't want to
|
|
45
|
+
// remove it from the toolbar until the toolbar is rendered again
|
|
46
|
+
// without it. Removing it beforehand can cause focus loss issues.
|
|
47
|
+
// It needs to return focus from whence it came, and to do that,
|
|
48
|
+
// we need to leave the button in the toolbar.
|
|
49
|
+
useEffect( () => {
|
|
50
|
+
if ( hasHiddenBlock ) {
|
|
51
|
+
hasBlockVisibilityButtonShownRef.current = true;
|
|
52
|
+
}
|
|
53
|
+
}, [ hasHiddenBlock ] );
|
|
54
|
+
|
|
55
|
+
if ( ! hasHiddenBlock && ! hasBlockVisibilityButtonShownRef.current ) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const toggleBlockVisibility = () => {
|
|
60
|
+
const attributesByClientId = Object.fromEntries(
|
|
61
|
+
blocks?.map( ( { clientId, attributes } ) => [
|
|
62
|
+
clientId,
|
|
63
|
+
{
|
|
64
|
+
metadata: cleanEmptyObject( {
|
|
65
|
+
...attributes?.metadata,
|
|
66
|
+
blockVisibility: hasHiddenBlock ? undefined : false,
|
|
67
|
+
} ),
|
|
68
|
+
},
|
|
69
|
+
] )
|
|
70
|
+
);
|
|
71
|
+
updateBlockAttributes( clientIds, attributesByClientId, {
|
|
72
|
+
uniqueByBlock: true,
|
|
73
|
+
} );
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<>
|
|
78
|
+
<ToolbarGroup className="block-editor-block-lock-toolbar">
|
|
79
|
+
<ToolbarButton
|
|
80
|
+
disabled={ ! canToggleBlockVisibility }
|
|
81
|
+
icon={ hasHiddenBlock ? unseen : seen }
|
|
82
|
+
label={ hasHiddenBlock ? __( 'Hidden' ) : __( 'Visible' ) }
|
|
83
|
+
onClick={ toggleBlockVisibility }
|
|
84
|
+
/>
|
|
85
|
+
</ToolbarGroup>
|
|
86
|
+
</>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
Tooltip,
|
|
7
7
|
privateApis as componentsPrivateApis,
|
|
8
8
|
} from '@wordpress/components';
|
|
9
|
+
import { useEffect, useState } from '@wordpress/element';
|
|
9
10
|
import { store as preferencesStore } from '@wordpress/preferences';
|
|
10
11
|
import { useSelect } from '@wordpress/data';
|
|
11
12
|
|
|
@@ -43,9 +44,40 @@ export default function InspectorControlsTabs( {
|
|
|
43
44
|
? TAB_LIST_VIEW.name
|
|
44
45
|
: undefined;
|
|
45
46
|
|
|
47
|
+
const [ selectedTabId, setSelectedTabId ] = useState(
|
|
48
|
+
initialTabName ?? tabs[ 0 ]?.name
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
// When the active tab is not amongst the available `tabs`, it indicates
|
|
52
|
+
// the list of tabs was changed dynamically with the active one being
|
|
53
|
+
// removed. Set the active tab back to the first tab.
|
|
54
|
+
useEffect( () => {
|
|
55
|
+
// Skip this behavior if `initialTabName` is supplied. In the navigation
|
|
56
|
+
// block, the list view tab isn't present in `tabs` initially. The early
|
|
57
|
+
// return here prevents the dynamic behavior that follows from overriding
|
|
58
|
+
// `initialTabName`.
|
|
59
|
+
if ( initialTabName ) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if ( tabs?.length && selectedTabId ) {
|
|
64
|
+
const activeTab = tabs.find(
|
|
65
|
+
( tab ) => tab.name === selectedTabId
|
|
66
|
+
);
|
|
67
|
+
if ( ! activeTab ) {
|
|
68
|
+
setSelectedTabId( tabs[ 0 ].name );
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}, [ tabs, selectedTabId, initialTabName ] );
|
|
72
|
+
|
|
46
73
|
return (
|
|
47
74
|
<div className="block-editor-block-inspector__tabs">
|
|
48
|
-
<Tabs
|
|
75
|
+
<Tabs
|
|
76
|
+
defaultTabId={ initialTabName }
|
|
77
|
+
selectedTabId={ selectedTabId }
|
|
78
|
+
onSelect={ setSelectedTabId }
|
|
79
|
+
key={ clientId }
|
|
80
|
+
>
|
|
49
81
|
<Tabs.TabList>
|
|
50
82
|
{ tabs.map( ( tab ) =>
|
|
51
83
|
showIconLabels ? (
|
|
@@ -795,7 +795,7 @@ describe( 'Manual link entry', () => {
|
|
|
795
795
|
}
|
|
796
796
|
|
|
797
797
|
const submitButton = screen.queryByRole( 'button', {
|
|
798
|
-
name: '
|
|
798
|
+
name: 'Apply',
|
|
799
799
|
} );
|
|
800
800
|
|
|
801
801
|
// Verify the submission UI is disabled.
|
|
@@ -1035,7 +1035,7 @@ describe( 'Link submission', () => {
|
|
|
1035
1035
|
expect( createSubmitButton ).not.toBeInTheDocument();
|
|
1036
1036
|
|
|
1037
1037
|
const editSubmitButton = screen.getByRole( 'button', {
|
|
1038
|
-
name: '
|
|
1038
|
+
name: 'Apply',
|
|
1039
1039
|
} );
|
|
1040
1040
|
|
|
1041
1041
|
expect( editSubmitButton ).toBeVisible();
|
|
@@ -2033,7 +2033,7 @@ describe( 'Addition Settings UI', () => {
|
|
|
2033
2033
|
|
|
2034
2034
|
// check that the "Apply" button is disabled by default.
|
|
2035
2035
|
const submitButton = screen.queryByRole( 'button', {
|
|
2036
|
-
name: '
|
|
2036
|
+
name: 'Apply',
|
|
2037
2037
|
} );
|
|
2038
2038
|
|
|
2039
2039
|
expect( submitButton ).toHaveAttribute( 'aria-disabled', 'true' );
|
|
@@ -2489,7 +2489,7 @@ describe( 'Controlling link title text', () => {
|
|
|
2489
2489
|
expect( textInput ).toHaveValue( textValue );
|
|
2490
2490
|
|
|
2491
2491
|
const submitButton = screen.queryByRole( 'button', {
|
|
2492
|
-
name: '
|
|
2492
|
+
name: 'Apply',
|
|
2493
2493
|
} );
|
|
2494
2494
|
|
|
2495
2495
|
await user.click( submitButton );
|
|
@@ -12,9 +12,10 @@ import {
|
|
|
12
12
|
privateApis as componentsPrivateApis,
|
|
13
13
|
} from '@wordpress/components';
|
|
14
14
|
import { forwardRef } from '@wordpress/element';
|
|
15
|
-
import { Icon, lockSmall as lock, pinSmall } from '@wordpress/icons';
|
|
15
|
+
import { Icon, lockSmall as lock, pinSmall, unseen } from '@wordpress/icons';
|
|
16
16
|
import { SPACE, ENTER } from '@wordpress/keycodes';
|
|
17
17
|
import { useSelect } from '@wordpress/data';
|
|
18
|
+
import { hasBlockSupport } from '@wordpress/blocks';
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Internal dependencies
|
|
@@ -27,6 +28,7 @@ import { useBlockLock } from '../block-lock';
|
|
|
27
28
|
import useListViewImages from './use-list-view-images';
|
|
28
29
|
import { store as blockEditorStore } from '../../store';
|
|
29
30
|
import { unlock } from '../../lock-unlock';
|
|
31
|
+
|
|
30
32
|
const { Badge } = unlock( componentsPrivateApis );
|
|
31
33
|
|
|
32
34
|
function ListViewBlockSelectButton(
|
|
@@ -53,15 +55,31 @@ function ListViewBlockSelectButton(
|
|
|
53
55
|
context: 'list-view',
|
|
54
56
|
} );
|
|
55
57
|
const { isLocked } = useBlockLock( clientId );
|
|
56
|
-
const { isContentOnly } =
|
|
57
|
-
(
|
|
58
|
-
|
|
59
|
-
select( blockEditorStore )
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
const { canToggleBlockVisibility, isBlockHidden, isContentOnly } =
|
|
59
|
+
useSelect(
|
|
60
|
+
( select ) => {
|
|
61
|
+
const { getBlockName } = select( blockEditorStore );
|
|
62
|
+
const { isBlockHidden: _isBlockHidden } = unlock(
|
|
63
|
+
select( blockEditorStore )
|
|
64
|
+
);
|
|
65
|
+
return {
|
|
66
|
+
canToggleBlockVisibility: hasBlockSupport(
|
|
67
|
+
getBlockName( clientId ),
|
|
68
|
+
'blockVisibility',
|
|
69
|
+
true
|
|
70
|
+
),
|
|
71
|
+
isBlockHidden: _isBlockHidden( clientId ),
|
|
72
|
+
isContentOnly:
|
|
73
|
+
select( blockEditorStore ).getBlockEditingMode(
|
|
74
|
+
clientId
|
|
75
|
+
) === 'contentOnly',
|
|
76
|
+
};
|
|
77
|
+
},
|
|
78
|
+
[ clientId ]
|
|
79
|
+
);
|
|
64
80
|
const shouldShowLockIcon = isLocked && ! isContentOnly;
|
|
81
|
+
const shouldShowBlockVisibilityIcon =
|
|
82
|
+
canToggleBlockVisibility && isBlockHidden;
|
|
65
83
|
const isSticky = blockInformation?.positionType === 'sticky';
|
|
66
84
|
const images = useListViewImages( { clientId, isExpanded } );
|
|
67
85
|
|
|
@@ -147,6 +165,11 @@ function ListViewBlockSelectButton(
|
|
|
147
165
|
) ) }
|
|
148
166
|
</span>
|
|
149
167
|
) : null }
|
|
168
|
+
{ shouldShowBlockVisibilityIcon && (
|
|
169
|
+
<span className="block-editor-list-view-block-select-button__block-visibility">
|
|
170
|
+
<Icon icon={ unseen } />
|
|
171
|
+
</span>
|
|
172
|
+
) }
|
|
150
173
|
{ shouldShowLockIcon && (
|
|
151
174
|
<span className="block-editor-list-view-block-select-button__lock">
|
|
152
175
|
<Icon icon={ lock } />
|
|
@@ -119,20 +119,25 @@ function ListViewBlock( {
|
|
|
119
119
|
|
|
120
120
|
const pasteStyles = usePasteStyles();
|
|
121
121
|
|
|
122
|
-
const { block, blockName, allowRightClickOverrides } =
|
|
123
|
-
(
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
122
|
+
const { block, blockName, allowRightClickOverrides, isBlockHidden } =
|
|
123
|
+
useSelect(
|
|
124
|
+
( select ) => {
|
|
125
|
+
const { getBlock, getBlockName, getSettings } =
|
|
126
|
+
select( blockEditorStore );
|
|
127
|
+
const { isBlockHidden: _isBlockHidden } = unlock(
|
|
128
|
+
select( blockEditorStore )
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
block: getBlock( clientId ),
|
|
133
|
+
blockName: getBlockName( clientId ),
|
|
134
|
+
allowRightClickOverrides:
|
|
135
|
+
getSettings().allowRightClickOverrides,
|
|
136
|
+
isBlockHidden: _isBlockHidden( clientId ),
|
|
137
|
+
};
|
|
138
|
+
},
|
|
139
|
+
[ clientId ]
|
|
140
|
+
);
|
|
136
141
|
|
|
137
142
|
const showBlockActions =
|
|
138
143
|
// When a block hides its toolbar it also hides the block settings menu,
|
|
@@ -484,6 +489,10 @@ function ListViewBlock( {
|
|
|
484
489
|
isLocked
|
|
485
490
|
);
|
|
486
491
|
|
|
492
|
+
const blockVisibilityDescription = isBlockHidden
|
|
493
|
+
? __( 'Block is hidden.' )
|
|
494
|
+
: null;
|
|
495
|
+
|
|
487
496
|
const hasSiblings = siblingBlockCount > 0;
|
|
488
497
|
const hasRenderedMovers = showBlockMovers && hasSiblings;
|
|
489
498
|
const moverCellClassName = clsx(
|
|
@@ -581,6 +590,7 @@ function ListViewBlock( {
|
|
|
581
590
|
{ [
|
|
582
591
|
blockPositionDescription,
|
|
583
592
|
blockPropertiesDescription,
|
|
593
|
+
blockVisibilityDescription,
|
|
584
594
|
]
|
|
585
595
|
.filter( Boolean )
|
|
586
596
|
.join( ' ' ) }
|
|
@@ -39,7 +39,6 @@ import FormatEdit from './format-edit';
|
|
|
39
39
|
import { getAllowedFormats } from './utils';
|
|
40
40
|
import { Content, valueToHTMLString } from './content';
|
|
41
41
|
import { withDeprecations } from './with-deprecations';
|
|
42
|
-
import { canBindBlock } from '../../utils/block-bindings';
|
|
43
42
|
import BlockContext from '../block-context';
|
|
44
43
|
|
|
45
44
|
export const keyboardShortcutContext = createContext();
|
|
@@ -177,9 +176,14 @@ export function RichTextWrapper(
|
|
|
177
176
|
|
|
178
177
|
const { disableBoundBlock, bindingsPlaceholder, bindingsLabel } = useSelect(
|
|
179
178
|
( select ) => {
|
|
179
|
+
const { __experimentalBlockBindingsSupportedAttributes } =
|
|
180
|
+
select( blockEditorStore ).getSettings();
|
|
181
|
+
|
|
180
182
|
if (
|
|
181
183
|
! blockBindings?.[ identifier ] ||
|
|
182
|
-
!
|
|
184
|
+
! (
|
|
185
|
+
blockName in __experimentalBlockBindingsSupportedAttributes
|
|
186
|
+
)
|
|
183
187
|
) {
|
|
184
188
|
return {};
|
|
185
189
|
}
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
} from '@wordpress/compose';
|
|
10
10
|
import { isRTL } from '@wordpress/i18n';
|
|
11
11
|
import {
|
|
12
|
+
hasBlockSupport,
|
|
12
13
|
isUnmodifiedDefaultBlock as getIsUnmodifiedDefaultBlock,
|
|
13
14
|
store as blocksStore,
|
|
14
15
|
} from '@wordpress/blocks';
|
|
@@ -410,7 +411,19 @@ export default function useBlockDropZone( {
|
|
|
410
411
|
return;
|
|
411
412
|
}
|
|
412
413
|
|
|
413
|
-
const blocks = getBlocks( targetRootClientId )
|
|
414
|
+
const blocks = getBlocks( targetRootClientId )
|
|
415
|
+
// Filter out blocks that are hidden
|
|
416
|
+
.filter( ( block ) => {
|
|
417
|
+
return ! (
|
|
418
|
+
hasBlockSupport(
|
|
419
|
+
block.name,
|
|
420
|
+
'blockVisibility',
|
|
421
|
+
true
|
|
422
|
+
) &&
|
|
423
|
+
block.attributes?.metadata?.blockVisibility ===
|
|
424
|
+
false
|
|
425
|
+
);
|
|
426
|
+
} );
|
|
414
427
|
|
|
415
428
|
// The block list is empty, don't show the insertion point but still allow dropping.
|
|
416
429
|
if ( blocks.length === 0 ) {
|