@wordpress/editor 13.26.0 → 13.27.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/bindings/index.js +20 -0
- package/build/bindings/index.js.map +1 -0
- package/build/bindings/post-meta.js +52 -0
- package/build/bindings/post-meta.js.map +1 -0
- package/build/components/block-manager/category.js +106 -0
- package/build/components/block-manager/category.js.map +1 -0
- package/build/components/block-manager/checklist.js +35 -0
- package/build/components/block-manager/checklist.js.map +1 -0
- package/build/components/block-manager/index.js +130 -0
- package/build/components/block-manager/index.js.map +1 -0
- package/build/components/document-tools/index.js +58 -52
- package/build/components/document-tools/index.js.map +1 -1
- package/build/components/editor-canvas/index.js +4 -4
- package/build/components/editor-canvas/index.js.map +1 -1
- package/build/components/editor-notices/index.js +11 -11
- package/build/components/editor-notices/index.js.map +1 -1
- package/build/components/entities-saved-states/entity-type-list.js +38 -7
- package/build/components/entities-saved-states/entity-type-list.js.map +1 -1
- package/build/components/entities-saved-states/index.js +1 -1
- package/build/components/entities-saved-states/index.js.map +1 -1
- package/build/components/offline-status/index.native.js +1 -3
- package/build/components/offline-status/index.native.js.map +1 -1
- package/build/components/post-locked-modal/index.js +1 -1
- package/build/components/post-locked-modal/index.js.map +1 -1
- package/build/components/post-saved-state/index.js +10 -24
- package/build/components/post-saved-state/index.js.map +1 -1
- package/build/components/post-schedule/check.js +5 -16
- package/build/components/post-schedule/check.js.map +1 -1
- package/build/components/preferences-modal/enable-panel.js +42 -0
- package/build/components/preferences-modal/enable-panel.js.map +1 -0
- package/build/components/preferences-modal/enable-plugin-document-setting-panel.js +33 -0
- package/build/components/preferences-modal/enable-plugin-document-setting-panel.js.map +1 -0
- package/build/components/preferences-modal/index.js +186 -0
- package/build/components/preferences-modal/index.js.map +1 -0
- package/build/components/provider/disable-non-page-content-blocks.js +1 -4
- package/build/components/provider/disable-non-page-content-blocks.js.map +1 -1
- package/build/components/provider/use-block-editor-settings.js +34 -8
- package/build/components/provider/use-block-editor-settings.js.map +1 -1
- package/build/hooks/pattern-partial-syncing.js +12 -8
- package/build/hooks/pattern-partial-syncing.js.map +1 -1
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/build/private-apis.js +6 -2
- package/build/private-apis.js.map +1 -1
- package/build/store/defaults.js +2 -0
- package/build/store/defaults.js.map +1 -1
- package/build/store/private-actions.js +33 -1
- package/build/store/private-actions.js.map +1 -1
- package/build/store/private-selectors.js +1 -1
- package/build/store/private-selectors.js.map +1 -1
- package/build-module/bindings/index.js +15 -0
- package/build-module/bindings/index.js.map +1 -0
- package/build-module/bindings/post-meta.js +45 -0
- package/build-module/bindings/post-meta.js.map +1 -0
- package/build-module/components/block-manager/category.js +97 -0
- package/build-module/components/block-manager/category.js.map +1 -0
- package/build-module/components/block-manager/checklist.js +27 -0
- package/build-module/components/block-manager/checklist.js.map +1 -0
- package/build-module/components/block-manager/index.js +121 -0
- package/build-module/components/block-manager/index.js.map +1 -0
- package/build-module/components/document-tools/index.js +58 -52
- package/build-module/components/document-tools/index.js.map +1 -1
- package/build-module/components/editor-canvas/index.js +4 -4
- package/build-module/components/editor-canvas/index.js.map +1 -1
- package/build-module/components/editor-notices/index.js +12 -12
- package/build-module/components/editor-notices/index.js.map +1 -1
- package/build-module/components/entities-saved-states/entity-type-list.js +39 -8
- package/build-module/components/entities-saved-states/entity-type-list.js.map +1 -1
- package/build-module/components/entities-saved-states/index.js +1 -1
- package/build-module/components/entities-saved-states/index.js.map +1 -1
- package/build-module/components/offline-status/index.native.js +1 -3
- package/build-module/components/offline-status/index.native.js.map +1 -1
- package/build-module/components/post-locked-modal/index.js +1 -1
- package/build-module/components/post-locked-modal/index.js.map +1 -1
- package/build-module/components/post-saved-state/index.js +11 -25
- package/build-module/components/post-saved-state/index.js.map +1 -1
- package/build-module/components/post-schedule/check.js +6 -15
- package/build-module/components/post-schedule/check.js.map +1 -1
- package/build-module/components/preferences-modal/enable-panel.js +34 -0
- package/build-module/components/preferences-modal/enable-panel.js.map +1 -0
- package/build-module/components/preferences-modal/enable-plugin-document-setting-panel.js +24 -0
- package/build-module/components/preferences-modal/enable-plugin-document-setting-panel.js.map +1 -0
- package/build-module/components/preferences-modal/index.js +179 -0
- package/build-module/components/preferences-modal/index.js.map +1 -0
- package/build-module/components/provider/disable-non-page-content-blocks.js +1 -4
- package/build-module/components/provider/disable-non-page-content-blocks.js.map +1 -1
- package/build-module/components/provider/use-block-editor-settings.js +35 -9
- package/build-module/components/provider/use-block-editor-settings.js.map +1 -1
- package/build-module/hooks/pattern-partial-syncing.js +12 -8
- package/build-module/hooks/pattern-partial-syncing.js.map +1 -1
- package/build-module/index.js +1 -0
- package/build-module/index.js.map +1 -1
- package/build-module/private-apis.js +6 -2
- package/build-module/private-apis.js.map +1 -1
- package/build-module/store/defaults.js +2 -0
- package/build-module/store/defaults.js.map +1 -1
- package/build-module/store/private-actions.js +29 -0
- package/build-module/store/private-actions.js.map +1 -1
- package/build-module/store/private-selectors.js +1 -1
- package/build-module/store/private-selectors.js.map +1 -1
- package/build-style/style-rtl.css +80 -12
- package/build-style/style.css +80 -12
- package/package.json +33 -33
- package/src/bindings/index.js +13 -0
- package/src/bindings/post-meta.js +42 -0
- package/src/components/block-manager/category.js +96 -0
- package/src/components/block-manager/checklist.js +30 -0
- package/src/components/block-manager/index.js +160 -0
- package/src/components/block-manager/style.scss +82 -0
- package/src/components/document-tools/index.js +9 -1
- package/src/components/editor-canvas/index.js +3 -2
- package/src/components/editor-notices/index.js +11 -12
- package/src/components/editor-notices/style.scss +0 -1
- package/src/components/entities-saved-states/entity-type-list.js +47 -5
- package/src/components/entities-saved-states/index.js +7 -7
- package/src/components/entities-saved-states/style.scss +4 -0
- package/src/components/offline-status/index.native.js +2 -4
- package/src/components/post-locked-modal/index.js +1 -1
- package/src/components/post-locked-modal/style.scss +0 -6
- package/src/components/post-saved-state/index.js +30 -47
- package/src/components/post-schedule/check.js +10 -14
- package/src/components/post-schedule/test/check.js +24 -9
- package/src/components/preferences-modal/enable-panel.js +30 -0
- package/src/components/preferences-modal/enable-plugin-document-setting-panel.js +23 -0
- package/src/components/preferences-modal/index.js +269 -0
- package/src/components/preferences-modal/test/index.js +28 -0
- package/src/components/provider/disable-non-page-content-blocks.js +3 -3
- package/src/components/provider/use-block-editor-settings.js +45 -17
- package/src/hooks/pattern-partial-syncing.js +26 -29
- package/src/index.js +1 -0
- package/src/private-apis.js +6 -2
- package/src/store/defaults.js +2 -0
- package/src/store/private-actions.js +49 -0
- package/src/store/private-selectors.js +1 -1
- package/src/style.scss +1 -1
- package/src/components/editor-canvas/style.scss +0 -5
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { store as blocksStore } from '@wordpress/blocks';
|
|
5
|
+
import { withSelect, withDispatch } from '@wordpress/data';
|
|
6
|
+
import { SearchControl, Button } from '@wordpress/components';
|
|
7
|
+
import { __, _n, sprintf } from '@wordpress/i18n';
|
|
8
|
+
import { useEffect, useState } from '@wordpress/element';
|
|
9
|
+
import { useDebounce, compose } from '@wordpress/compose';
|
|
10
|
+
import { speak } from '@wordpress/a11y';
|
|
11
|
+
import { store as preferencesStore } from '@wordpress/preferences';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Internal dependencies
|
|
15
|
+
*/
|
|
16
|
+
import { unlock } from '../../lock-unlock';
|
|
17
|
+
import { store as editorStore } from '../../store';
|
|
18
|
+
import BlockManagerCategory from './category';
|
|
19
|
+
|
|
20
|
+
function BlockManager( {
|
|
21
|
+
blockTypes,
|
|
22
|
+
categories,
|
|
23
|
+
hasBlockSupport,
|
|
24
|
+
isMatchingSearchTerm,
|
|
25
|
+
numberOfHiddenBlocks,
|
|
26
|
+
enableAllBlockTypes,
|
|
27
|
+
} ) {
|
|
28
|
+
const debouncedSpeak = useDebounce( speak, 500 );
|
|
29
|
+
const [ search, setSearch ] = useState( '' );
|
|
30
|
+
|
|
31
|
+
// Filtering occurs here (as opposed to `withSelect`) to avoid
|
|
32
|
+
// wasted renders by consequence of `Array#filter` producing
|
|
33
|
+
// a new value reference on each call.
|
|
34
|
+
blockTypes = blockTypes.filter(
|
|
35
|
+
( blockType ) =>
|
|
36
|
+
hasBlockSupport( blockType, 'inserter', true ) &&
|
|
37
|
+
( ! search || isMatchingSearchTerm( blockType, search ) ) &&
|
|
38
|
+
( ! blockType.parent ||
|
|
39
|
+
blockType.parent.includes( 'core/post-content' ) )
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
// Announce search results on change
|
|
43
|
+
useEffect( () => {
|
|
44
|
+
if ( ! search ) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const count = blockTypes.length;
|
|
48
|
+
const resultsFoundMessage = sprintf(
|
|
49
|
+
/* translators: %d: number of results. */
|
|
50
|
+
_n( '%d result found.', '%d results found.', count ),
|
|
51
|
+
count
|
|
52
|
+
);
|
|
53
|
+
debouncedSpeak( resultsFoundMessage );
|
|
54
|
+
}, [ blockTypes.length, search, debouncedSpeak ] );
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<div className="editor-block-manager__content">
|
|
58
|
+
{ !! numberOfHiddenBlocks && (
|
|
59
|
+
<div className="editor-block-manager__disabled-blocks-count">
|
|
60
|
+
{ sprintf(
|
|
61
|
+
/* translators: %d: number of blocks. */
|
|
62
|
+
_n(
|
|
63
|
+
'%d block is hidden.',
|
|
64
|
+
'%d blocks are hidden.',
|
|
65
|
+
numberOfHiddenBlocks
|
|
66
|
+
),
|
|
67
|
+
numberOfHiddenBlocks
|
|
68
|
+
) }
|
|
69
|
+
<Button
|
|
70
|
+
variant="link"
|
|
71
|
+
onClick={ () => enableAllBlockTypes( blockTypes ) }
|
|
72
|
+
>
|
|
73
|
+
{ __( 'Reset' ) }
|
|
74
|
+
</Button>
|
|
75
|
+
</div>
|
|
76
|
+
) }
|
|
77
|
+
<SearchControl
|
|
78
|
+
__nextHasNoMarginBottom
|
|
79
|
+
label={ __( 'Search for a block' ) }
|
|
80
|
+
placeholder={ __( 'Search for a block' ) }
|
|
81
|
+
value={ search }
|
|
82
|
+
onChange={ ( nextSearch ) => setSearch( nextSearch ) }
|
|
83
|
+
className="editor-block-manager__search"
|
|
84
|
+
/>
|
|
85
|
+
<div
|
|
86
|
+
tabIndex="0"
|
|
87
|
+
role="region"
|
|
88
|
+
aria-label={ __( 'Available block types' ) }
|
|
89
|
+
className="editor-block-manager__results"
|
|
90
|
+
>
|
|
91
|
+
{ blockTypes.length === 0 && (
|
|
92
|
+
<p className="editor-block-manager__no-results">
|
|
93
|
+
{ __( 'No blocks found.' ) }
|
|
94
|
+
</p>
|
|
95
|
+
) }
|
|
96
|
+
{ categories.map( ( category ) => (
|
|
97
|
+
<BlockManagerCategory
|
|
98
|
+
key={ category.slug }
|
|
99
|
+
title={ category.title }
|
|
100
|
+
blockTypes={ blockTypes.filter(
|
|
101
|
+
( blockType ) =>
|
|
102
|
+
blockType.category === category.slug
|
|
103
|
+
) }
|
|
104
|
+
/>
|
|
105
|
+
) ) }
|
|
106
|
+
<BlockManagerCategory
|
|
107
|
+
title={ __( 'Uncategorized' ) }
|
|
108
|
+
blockTypes={ blockTypes.filter(
|
|
109
|
+
( { category } ) => ! category
|
|
110
|
+
) }
|
|
111
|
+
/>
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export default compose( [
|
|
118
|
+
withSelect( ( select ) => {
|
|
119
|
+
const {
|
|
120
|
+
getBlockTypes,
|
|
121
|
+
getCategories,
|
|
122
|
+
hasBlockSupport,
|
|
123
|
+
isMatchingSearchTerm,
|
|
124
|
+
} = select( blocksStore );
|
|
125
|
+
const { get } = select( preferencesStore );
|
|
126
|
+
|
|
127
|
+
// Some hidden blocks become unregistered
|
|
128
|
+
// by removing for instance the plugin that registered them, yet
|
|
129
|
+
// they're still remain as hidden by the user's action.
|
|
130
|
+
// We consider "hidden", blocks which were hidden and
|
|
131
|
+
// are still registered.
|
|
132
|
+
const blockTypes = getBlockTypes();
|
|
133
|
+
const hiddenBlockTypes = (
|
|
134
|
+
get( 'core', 'hiddenBlockTypes' ) ?? []
|
|
135
|
+
).filter( ( hiddenBlock ) => {
|
|
136
|
+
return blockTypes.some(
|
|
137
|
+
( registeredBlock ) => registeredBlock.name === hiddenBlock
|
|
138
|
+
);
|
|
139
|
+
} );
|
|
140
|
+
const numberOfHiddenBlocks =
|
|
141
|
+
Array.isArray( hiddenBlockTypes ) && hiddenBlockTypes.length;
|
|
142
|
+
|
|
143
|
+
return {
|
|
144
|
+
blockTypes,
|
|
145
|
+
categories: getCategories(),
|
|
146
|
+
hasBlockSupport,
|
|
147
|
+
isMatchingSearchTerm,
|
|
148
|
+
numberOfHiddenBlocks,
|
|
149
|
+
};
|
|
150
|
+
} ),
|
|
151
|
+
withDispatch( ( dispatch ) => {
|
|
152
|
+
const { showBlockTypes } = unlock( dispatch( editorStore ) );
|
|
153
|
+
return {
|
|
154
|
+
enableAllBlockTypes: ( blockTypes ) => {
|
|
155
|
+
const blockNames = blockTypes.map( ( { name } ) => name );
|
|
156
|
+
showBlockTypes( blockNames );
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
} ),
|
|
160
|
+
] )( BlockManager );
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
.editor-block-manager__no-results {
|
|
2
|
+
font-style: italic;
|
|
3
|
+
padding: $grid-unit-30 0;
|
|
4
|
+
text-align: center;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.editor-block-manager__search {
|
|
8
|
+
margin: $grid-unit-20 0;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.editor-block-manager__disabled-blocks-count {
|
|
12
|
+
border: 1px solid $gray-300;
|
|
13
|
+
border-width: 1px 0;
|
|
14
|
+
// Cover up horizontal areas off the sides of the box rectangle
|
|
15
|
+
box-shadow: -$grid-unit-40 0 0 0 $white, $grid-unit-40 0 0 0 $white;
|
|
16
|
+
padding: $grid-unit-10;
|
|
17
|
+
background-color: $white;
|
|
18
|
+
text-align: center;
|
|
19
|
+
position: sticky;
|
|
20
|
+
// When sticking, tuck the top border beneath the modal header border
|
|
21
|
+
top: ($grid-unit-05 + 1) * -1;
|
|
22
|
+
z-index: z-index(".editor-block-manager__disabled-blocks-count");
|
|
23
|
+
|
|
24
|
+
// Stick the category titles to the bottom
|
|
25
|
+
~ .editor-block-manager__results .editor-block-manager__category-title {
|
|
26
|
+
top: $grid-unit-40 - 1;
|
|
27
|
+
}
|
|
28
|
+
.is-link {
|
|
29
|
+
margin-left: 12px;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.editor-block-manager__category {
|
|
34
|
+
margin: 0 0 $grid-unit-30 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.editor-block-manager__category-title {
|
|
38
|
+
position: sticky;
|
|
39
|
+
top: - $grid-unit-05; // Offsets the top padding on the modal content container
|
|
40
|
+
padding: $grid-unit-20 0;
|
|
41
|
+
background-color: $white;
|
|
42
|
+
z-index: z-index(".editor-block-manager__category-title");
|
|
43
|
+
|
|
44
|
+
.components-checkbox-control__label {
|
|
45
|
+
font-weight: 600;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.editor-block-manager__checklist {
|
|
50
|
+
margin-top: 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.editor-block-manager__category-title,
|
|
54
|
+
.editor-block-manager__checklist-item {
|
|
55
|
+
border-bottom: 1px solid $gray-300;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.editor-block-manager__checklist-item {
|
|
59
|
+
display: flex;
|
|
60
|
+
justify-content: space-between;
|
|
61
|
+
align-items: center;
|
|
62
|
+
margin-bottom: 0;
|
|
63
|
+
padding: $grid-unit-10 0 $grid-unit-10 $grid-unit-20;
|
|
64
|
+
|
|
65
|
+
.components-modal__content &.components-checkbox-control__input-container {
|
|
66
|
+
margin: 0 $grid-unit-10;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.block-editor-block-icon {
|
|
70
|
+
margin-right: 10px;
|
|
71
|
+
fill: $gray-900;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.editor-block-manager__results {
|
|
76
|
+
border-top: $border-width solid $gray-300;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Remove the top border from results when adjacent to the disabled block count
|
|
80
|
+
.editor-block-manager__disabled-blocks-count + .editor-block-manager__results {
|
|
81
|
+
border-top-width: 0;
|
|
82
|
+
}
|
|
@@ -104,8 +104,16 @@ function DocumentTools( {
|
|
|
104
104
|
const shortLabel = ! isInserterOpened ? __( 'Add' ) : __( 'Close' );
|
|
105
105
|
|
|
106
106
|
return (
|
|
107
|
+
// Some plugins expect and use the `edit-post-header-toolbar` CSS class to
|
|
108
|
+
// find the toolbar and inject UI elements into it. This is not officially
|
|
109
|
+
// supported, but we're keeping it in the list of class names for backwards
|
|
110
|
+
// compatibility.
|
|
107
111
|
<NavigableToolbar
|
|
108
|
-
className={ classnames(
|
|
112
|
+
className={ classnames(
|
|
113
|
+
'editor-document-tools',
|
|
114
|
+
'edit-post-header-toolbar',
|
|
115
|
+
className
|
|
116
|
+
) }
|
|
109
117
|
aria-label={ toolbarAriaLabel }
|
|
110
118
|
shouldUseKeyboardFocusShortcut={ ! blockToolbarCanBeFocused }
|
|
111
119
|
variant="unstyled"
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
__unstableUseTypewriter as useTypewriter,
|
|
13
13
|
__unstableUseTypingObserver as useTypingObserver,
|
|
14
14
|
useSettings,
|
|
15
|
-
|
|
15
|
+
RecursionProvider,
|
|
16
16
|
privateApis as blockEditorPrivateApis,
|
|
17
17
|
__experimentalUseResizeCanvas as useResizeCanvas,
|
|
18
18
|
} from '@wordpress/block-editor';
|
|
@@ -364,7 +364,8 @@ function EditorCanvas( {
|
|
|
364
364
|
'is-' + deviceType.toLowerCase() + '-preview',
|
|
365
365
|
renderingMode !== 'post-only'
|
|
366
366
|
? 'wp-site-blocks'
|
|
367
|
-
: `${ blockListLayoutClass } wp-block-post-content
|
|
367
|
+
: `${ blockListLayoutClass } wp-block-post-content`, // Ensure root level blocks receive default/flow blockGap styling rules.
|
|
368
|
+
renderingMode !== 'all' && 'is-' + renderingMode
|
|
368
369
|
) }
|
|
369
370
|
layout={ blockListLayout }
|
|
370
371
|
dropZoneElement={
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
4
|
import { NoticeList } from '@wordpress/components';
|
|
5
|
-
import {
|
|
6
|
-
import { compose } from '@wordpress/compose';
|
|
5
|
+
import { useDispatch, useSelect } from '@wordpress/data';
|
|
7
6
|
import { store as noticesStore } from '@wordpress/notices';
|
|
8
7
|
|
|
9
8
|
/**
|
|
@@ -11,7 +10,14 @@ import { store as noticesStore } from '@wordpress/notices';
|
|
|
11
10
|
*/
|
|
12
11
|
import TemplateValidationNotice from '../template-validation-notice';
|
|
13
12
|
|
|
14
|
-
export function EditorNotices(
|
|
13
|
+
export function EditorNotices() {
|
|
14
|
+
const { notices } = useSelect(
|
|
15
|
+
( select ) => ( {
|
|
16
|
+
notices: select( noticesStore ).getNotices(),
|
|
17
|
+
} ),
|
|
18
|
+
[]
|
|
19
|
+
);
|
|
20
|
+
const { removeNotice } = useDispatch( noticesStore );
|
|
15
21
|
const dismissibleNotices = notices.filter(
|
|
16
22
|
( { isDismissible, type } ) => isDismissible && type === 'default'
|
|
17
23
|
);
|
|
@@ -28,7 +34,7 @@ export function EditorNotices( { notices, onRemove } ) {
|
|
|
28
34
|
<NoticeList
|
|
29
35
|
notices={ dismissibleNotices }
|
|
30
36
|
className="components-editor-notices__dismissible"
|
|
31
|
-
onRemove={
|
|
37
|
+
onRemove={ removeNotice }
|
|
32
38
|
>
|
|
33
39
|
<TemplateValidationNotice />
|
|
34
40
|
</NoticeList>
|
|
@@ -36,11 +42,4 @@ export function EditorNotices( { notices, onRemove } ) {
|
|
|
36
42
|
);
|
|
37
43
|
}
|
|
38
44
|
|
|
39
|
-
export default
|
|
40
|
-
withSelect( ( select ) => ( {
|
|
41
|
-
notices: select( noticesStore ).getNotices(),
|
|
42
|
-
} ) ),
|
|
43
|
-
withDispatch( ( dispatch ) => ( {
|
|
44
|
-
onRemove: dispatch( noticesStore ).removeNotice,
|
|
45
|
-
} ) ),
|
|
46
|
-
] )( EditorNotices );
|
|
45
|
+
export default EditorNotices;
|
|
@@ -5,11 +5,18 @@ import { __ } from '@wordpress/i18n';
|
|
|
5
5
|
import { useSelect } from '@wordpress/data';
|
|
6
6
|
import { PanelBody, PanelRow } from '@wordpress/components';
|
|
7
7
|
import { store as coreStore } from '@wordpress/core-data';
|
|
8
|
+
import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';
|
|
9
|
+
import { useContext } from '@wordpress/element';
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* Internal dependencies
|
|
11
13
|
*/
|
|
12
14
|
import EntityRecordItem from './entity-record-item';
|
|
15
|
+
import { unlock } from '../../lock-unlock';
|
|
16
|
+
|
|
17
|
+
const { getGlobalStylesChanges, GlobalStylesContext } = unlock(
|
|
18
|
+
blockEditorPrivateApis
|
|
19
|
+
);
|
|
13
20
|
|
|
14
21
|
function getEntityDescription( entity, count ) {
|
|
15
22
|
switch ( entity ) {
|
|
@@ -27,6 +34,44 @@ function getEntityDescription( entity, count ) {
|
|
|
27
34
|
}
|
|
28
35
|
}
|
|
29
36
|
|
|
37
|
+
function GlobalStylesDescription( { record } ) {
|
|
38
|
+
const { user: currentEditorGlobalStyles } =
|
|
39
|
+
useContext( GlobalStylesContext );
|
|
40
|
+
const savedRecord = useSelect(
|
|
41
|
+
( select ) =>
|
|
42
|
+
select( coreStore ).getEntityRecord(
|
|
43
|
+
record.kind,
|
|
44
|
+
record.name,
|
|
45
|
+
record.key
|
|
46
|
+
),
|
|
47
|
+
[ record.kind, record.name, record.key ]
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const globalStylesChanges = getGlobalStylesChanges(
|
|
51
|
+
currentEditorGlobalStyles,
|
|
52
|
+
savedRecord,
|
|
53
|
+
{
|
|
54
|
+
maxResults: 10,
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
return globalStylesChanges.length ? (
|
|
58
|
+
<>
|
|
59
|
+
<h3 className="entities-saved-states__description-heading">
|
|
60
|
+
{ __( 'Changes made to:' ) }
|
|
61
|
+
</h3>
|
|
62
|
+
<PanelRow>{ globalStylesChanges.join( ', ' ) }</PanelRow>
|
|
63
|
+
</>
|
|
64
|
+
) : null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function EntityDescription( { record, count } ) {
|
|
68
|
+
if ( 'globalStyles' === record?.name ) {
|
|
69
|
+
return <GlobalStylesDescription record={ record } />;
|
|
70
|
+
}
|
|
71
|
+
const description = getEntityDescription( record?.name, count );
|
|
72
|
+
return description ? <PanelRow>{ description }</PanelRow> : null;
|
|
73
|
+
}
|
|
74
|
+
|
|
30
75
|
export default function EntityTypeList( {
|
|
31
76
|
list,
|
|
32
77
|
unselectedEntities,
|
|
@@ -42,19 +87,16 @@ export default function EntityTypeList( {
|
|
|
42
87
|
),
|
|
43
88
|
[ firstRecord.kind, firstRecord.name ]
|
|
44
89
|
);
|
|
45
|
-
const { name } = firstRecord;
|
|
46
90
|
|
|
47
91
|
let entityLabel = entityConfig.label;
|
|
48
|
-
if ( name === 'wp_template_part' ) {
|
|
92
|
+
if ( firstRecord?.name === 'wp_template_part' ) {
|
|
49
93
|
entityLabel =
|
|
50
94
|
1 === count ? __( 'Template Part' ) : __( 'Template Parts' );
|
|
51
95
|
}
|
|
52
|
-
// Set description based on type of entity.
|
|
53
|
-
const description = getEntityDescription( name, count );
|
|
54
96
|
|
|
55
97
|
return (
|
|
56
98
|
<PanelBody title={ entityLabel } initialOpen={ true }>
|
|
57
|
-
{
|
|
99
|
+
<EntityDescription record={ firstRecord } count={ count } />
|
|
58
100
|
{ list.map( ( record ) => {
|
|
59
101
|
return (
|
|
60
102
|
<EntityRecordItem
|
|
@@ -213,13 +213,13 @@ export function EntitiesSavedStatesExtensible( {
|
|
|
213
213
|
{ __( 'Are you ready to save?' ) }
|
|
214
214
|
</strong>
|
|
215
215
|
{ additionalPrompt }
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
216
|
+
<p>
|
|
217
|
+
{ isDirty
|
|
218
|
+
? __(
|
|
219
|
+
'The following changes have been made to your site, templates, and content.'
|
|
220
|
+
)
|
|
221
|
+
: __( 'Select the items you want to save.' ) }
|
|
222
|
+
</p>
|
|
223
223
|
</div>
|
|
224
224
|
|
|
225
225
|
{ sortedPartitionedSavables.map( ( list ) => {
|
|
@@ -90,10 +90,8 @@ const OfflineStatus = () => {
|
|
|
90
90
|
) }
|
|
91
91
|
style={ containerStyle }
|
|
92
92
|
>
|
|
93
|
-
<
|
|
94
|
-
|
|
95
|
-
<Text style={ textStyle }>{ __( 'Working Offline' ) }</Text>
|
|
96
|
-
</View>
|
|
93
|
+
<Icon fill={ iconStyle.fill } icon={ offlineIcon } />
|
|
94
|
+
<Text style={ textStyle }>{ __( 'Working Offline' ) } </Text>
|
|
97
95
|
</View>
|
|
98
96
|
) : null;
|
|
99
97
|
};
|
|
@@ -172,7 +172,7 @@ export default function PostLockedModal() {
|
|
|
172
172
|
shouldCloseOnClickOutside={ false }
|
|
173
173
|
shouldCloseOnEsc={ false }
|
|
174
174
|
isDismissible={ false }
|
|
175
|
-
|
|
175
|
+
size="medium"
|
|
176
176
|
>
|
|
177
177
|
<HStack alignment="top" spacing={ 6 }>
|
|
178
178
|
{ !! userAvatar && (
|
|
@@ -9,7 +9,6 @@ import classnames from 'classnames';
|
|
|
9
9
|
import {
|
|
10
10
|
__unstableGetAnimateClassName as getAnimateClassName,
|
|
11
11
|
Button,
|
|
12
|
-
Tooltip,
|
|
13
12
|
} from '@wordpress/components';
|
|
14
13
|
import { usePrevious, useViewportMatch } from '@wordpress/compose';
|
|
15
14
|
import { useDispatch, useSelect } from '@wordpress/data';
|
|
@@ -129,54 +128,38 @@ export default function PostSavedState( { forceIsDirty } ) {
|
|
|
129
128
|
text = shortLabel;
|
|
130
129
|
}
|
|
131
130
|
|
|
132
|
-
const buttonAccessibleLabel = text || label;
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* The tooltip needs to be enabled only if the button is not disabled. When
|
|
136
|
-
* relying on the internal Button tooltip functionality, this causes the
|
|
137
|
-
* resulting `button` element to be always removed and re-added to the DOM,
|
|
138
|
-
* causing focus loss. An alternative approach to circumvent the issue
|
|
139
|
-
* is not to use the `label` and `shortcut` props on `Button` (which would
|
|
140
|
-
* trigger the tooltip), and instead manually wrap the `Button` in a separate
|
|
141
|
-
* `Tooltip` component.
|
|
142
|
-
*/
|
|
143
|
-
const tooltipProps = isDisabled
|
|
144
|
-
? undefined
|
|
145
|
-
: {
|
|
146
|
-
text: buttonAccessibleLabel,
|
|
147
|
-
shortcut: displayShortcut.primary( 's' ),
|
|
148
|
-
};
|
|
149
|
-
|
|
150
131
|
// Use common Button instance for all saved states so that focus is not
|
|
151
132
|
// lost.
|
|
152
133
|
return (
|
|
153
|
-
<
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
134
|
+
<Button
|
|
135
|
+
className={
|
|
136
|
+
isSaveable || isSaving
|
|
137
|
+
? classnames( {
|
|
138
|
+
'editor-post-save-draft': ! isSavedState,
|
|
139
|
+
'editor-post-saved-state': isSavedState,
|
|
140
|
+
'is-saving': isSaving,
|
|
141
|
+
'is-autosaving': isAutosaving,
|
|
142
|
+
'is-saved': isSaved,
|
|
143
|
+
[ getAnimateClassName( {
|
|
144
|
+
type: 'loading',
|
|
145
|
+
} ) ]: isSaving,
|
|
146
|
+
} )
|
|
147
|
+
: undefined
|
|
148
|
+
}
|
|
149
|
+
onClick={ isDisabled ? undefined : () => savePost() }
|
|
150
|
+
/*
|
|
151
|
+
* We want the tooltip to show the keyboard shortcut only when the
|
|
152
|
+
* button does something, i.e. when it's not disabled.
|
|
153
|
+
*/
|
|
154
|
+
shortcut={ isDisabled ? undefined : displayShortcut.primary( 's' ) }
|
|
155
|
+
variant="tertiary"
|
|
156
|
+
size="compact"
|
|
157
|
+
icon={ isLargeViewport ? undefined : cloudUpload }
|
|
158
|
+
label={ text || label }
|
|
159
|
+
aria-disabled={ isDisabled }
|
|
160
|
+
>
|
|
161
|
+
{ isSavedState && <Icon icon={ isSaved ? check : cloud } /> }
|
|
162
|
+
{ text }
|
|
163
|
+
</Button>
|
|
181
164
|
);
|
|
182
165
|
}
|
|
@@ -1,29 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
import { withSelect } from '@wordpress/data';
|
|
4
|
+
import { useSelect } from '@wordpress/data';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* Internal dependencies
|
|
9
8
|
*/
|
|
10
9
|
import { store as editorStore } from '../../store';
|
|
11
10
|
|
|
12
|
-
export function PostScheduleCheck( {
|
|
11
|
+
export default function PostScheduleCheck( { children } ) {
|
|
12
|
+
const hasPublishAction = useSelect( ( select ) => {
|
|
13
|
+
return (
|
|
14
|
+
select( editorStore ).getCurrentPost()._links?.[
|
|
15
|
+
'wp:action-publish'
|
|
16
|
+
] ?? false
|
|
17
|
+
);
|
|
18
|
+
}, [] );
|
|
19
|
+
|
|
13
20
|
if ( ! hasPublishAction ) {
|
|
14
21
|
return null;
|
|
15
22
|
}
|
|
16
23
|
|
|
17
24
|
return children;
|
|
18
25
|
}
|
|
19
|
-
|
|
20
|
-
export default compose( [
|
|
21
|
-
withSelect( ( select ) => {
|
|
22
|
-
const { getCurrentPost, getCurrentPostType } = select( editorStore );
|
|
23
|
-
return {
|
|
24
|
-
hasPublishAction:
|
|
25
|
-
getCurrentPost()._links?.[ 'wp:action-publish' ] ?? false,
|
|
26
|
-
postType: getCurrentPostType(),
|
|
27
|
-
};
|
|
28
|
-
} ),
|
|
29
|
-
] )( PostScheduleCheck );
|
|
@@ -3,25 +3,40 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { render, screen } from '@testing-library/react';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { useSelect } from '@wordpress/data';
|
|
10
|
+
|
|
6
11
|
/**
|
|
7
12
|
* Internal dependencies
|
|
8
13
|
*/
|
|
9
|
-
import
|
|
14
|
+
import PostScheduleCheck from '../check';
|
|
15
|
+
|
|
16
|
+
jest.mock( '@wordpress/data/src/components/use-select', () => jest.fn() );
|
|
17
|
+
|
|
18
|
+
function setupMockSelect( hasPublishAction ) {
|
|
19
|
+
useSelect.mockImplementation( ( mapSelect ) => {
|
|
20
|
+
return mapSelect( () => ( {
|
|
21
|
+
getCurrentPost: () => ( {
|
|
22
|
+
_links: {
|
|
23
|
+
'wp:action-publish': hasPublishAction,
|
|
24
|
+
},
|
|
25
|
+
} ),
|
|
26
|
+
} ) );
|
|
27
|
+
} );
|
|
28
|
+
}
|
|
10
29
|
|
|
11
30
|
describe( 'PostScheduleCheck', () => {
|
|
12
31
|
it( "should not render anything if the user doesn't have the right capabilities", () => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
yes
|
|
16
|
-
</PostScheduleCheck>
|
|
17
|
-
);
|
|
32
|
+
setupMockSelect( false );
|
|
33
|
+
render( <PostScheduleCheck>yes</PostScheduleCheck> );
|
|
18
34
|
expect( screen.queryByText( 'yes' ) ).not.toBeInTheDocument();
|
|
19
35
|
} );
|
|
20
36
|
|
|
21
37
|
it( 'should render if the user has the correct capability', () => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
);
|
|
38
|
+
setupMockSelect( true );
|
|
39
|
+
render( <PostScheduleCheck>yes</PostScheduleCheck> );
|
|
25
40
|
expect( screen.getByText( 'yes' ) ).toBeVisible();
|
|
26
41
|
} );
|
|
27
42
|
} );
|