@wordpress/editor 13.28.5 → 13.30.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.
Files changed (144) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/build/components/block-removal-warnings/index.js +70 -0
  3. package/build/components/block-removal-warnings/index.js.map +1 -0
  4. package/build/components/commands/index.js +209 -0
  5. package/build/components/commands/index.js.map +1 -0
  6. package/build/components/commands/index.native.js +9 -0
  7. package/build/components/commands/index.native.js.map +1 -0
  8. package/build/components/document-bar/index.js +78 -67
  9. package/build/components/document-bar/index.js.map +1 -1
  10. package/build/components/document-outline/check.js +8 -7
  11. package/build/components/document-outline/check.js.map +1 -1
  12. package/build/components/document-outline/index.js +26 -27
  13. package/build/components/document-outline/index.js.map +1 -1
  14. package/build/components/document-tools/index.js +5 -3
  15. package/build/components/document-tools/index.js.map +1 -1
  16. package/build/components/editor-help/intro-to-blocks.native.js.map +1 -1
  17. package/build/components/entities-saved-states/entity-type-list.js.map +1 -1
  18. package/build/components/global-keyboard-shortcuts/index.js +20 -2
  19. package/build/components/global-keyboard-shortcuts/index.js.map +1 -1
  20. package/build/components/global-keyboard-shortcuts/register-shortcuts.js +18 -0
  21. package/build/components/global-keyboard-shortcuts/register-shortcuts.js.map +1 -1
  22. package/build/components/list-view-sidebar/index.js +1 -1
  23. package/build/components/list-view-sidebar/index.js.map +1 -1
  24. package/build/components/mode-switcher/index.js +86 -0
  25. package/build/components/mode-switcher/index.js.map +1 -0
  26. package/build/components/post-locked-modal/index.js.map +1 -1
  27. package/build/components/post-preview-button/index.js +2 -1
  28. package/build/components/post-preview-button/index.js.map +1 -1
  29. package/build/components/post-publish-button/index.js +2 -1
  30. package/build/components/post-publish-button/index.js.map +1 -1
  31. package/build/components/post-publish-panel/index.js.map +1 -1
  32. package/build/components/post-publish-panel/maybe-upload-media.js.map +1 -1
  33. package/build/components/post-taxonomies/hierarchical-term-selector.js +3 -0
  34. package/build/components/post-taxonomies/hierarchical-term-selector.js.map +1 -1
  35. package/build/components/post-title/index.js +0 -5
  36. package/build/components/post-title/index.js.map +1 -1
  37. package/build/components/post-title/index.native.js.map +1 -1
  38. package/build/components/post-title/post-title-raw.js.map +1 -1
  39. package/build/components/post-view-link/index.js +2 -1
  40. package/build/components/post-view-link/index.js.map +1 -1
  41. package/build/components/provider/index.js +8 -1
  42. package/build/components/provider/index.js.map +1 -1
  43. package/build/components/provider/index.native.js +4 -9
  44. package/build/components/provider/index.native.js.map +1 -1
  45. package/build/components/provider/use-block-editor-settings.js +1 -1
  46. package/build/components/provider/use-block-editor-settings.js.map +1 -1
  47. package/build/components/provider/use-hide-blocks-from-inserter.js +53 -0
  48. package/build/components/provider/use-hide-blocks-from-inserter.js.map +1 -0
  49. package/build/private-apis.js +2 -0
  50. package/build/private-apis.js.map +1 -1
  51. package/build/store/actions.js +69 -2
  52. package/build/store/actions.js.map +1 -1
  53. package/build/store/selectors.js +13 -1
  54. package/build/store/selectors.js.map +1 -1
  55. package/build-module/components/block-removal-warnings/index.js +64 -0
  56. package/build-module/components/block-removal-warnings/index.js.map +1 -0
  57. package/build-module/components/commands/index.js +202 -0
  58. package/build-module/components/commands/index.js.map +1 -0
  59. package/build-module/components/commands/index.native.js +3 -0
  60. package/build-module/components/commands/index.native.js.map +1 -0
  61. package/build-module/components/document-bar/index.js +81 -70
  62. package/build-module/components/document-bar/index.js.map +1 -1
  63. package/build-module/components/document-outline/check.js +9 -8
  64. package/build-module/components/document-outline/check.js.map +1 -1
  65. package/build-module/components/document-outline/index.js +26 -26
  66. package/build-module/components/document-outline/index.js.map +1 -1
  67. package/build-module/components/document-tools/index.js +5 -3
  68. package/build-module/components/document-tools/index.js.map +1 -1
  69. package/build-module/components/editor-help/intro-to-blocks.native.js.map +1 -1
  70. package/build-module/components/entities-saved-states/entity-type-list.js.map +1 -1
  71. package/build-module/components/global-keyboard-shortcuts/index.js +20 -2
  72. package/build-module/components/global-keyboard-shortcuts/index.js.map +1 -1
  73. package/build-module/components/global-keyboard-shortcuts/register-shortcuts.js +18 -0
  74. package/build-module/components/global-keyboard-shortcuts/register-shortcuts.js.map +1 -1
  75. package/build-module/components/list-view-sidebar/index.js +1 -1
  76. package/build-module/components/list-view-sidebar/index.js.map +1 -1
  77. package/build-module/components/mode-switcher/index.js +80 -0
  78. package/build-module/components/mode-switcher/index.js.map +1 -0
  79. package/build-module/components/post-locked-modal/index.js.map +1 -1
  80. package/build-module/components/post-preview-button/index.js +2 -1
  81. package/build-module/components/post-preview-button/index.js.map +1 -1
  82. package/build-module/components/post-publish-button/index.js +2 -1
  83. package/build-module/components/post-publish-button/index.js.map +1 -1
  84. package/build-module/components/post-publish-panel/index.js.map +1 -1
  85. package/build-module/components/post-publish-panel/maybe-upload-media.js.map +1 -1
  86. package/build-module/components/post-taxonomies/hierarchical-term-selector.js +3 -0
  87. package/build-module/components/post-taxonomies/hierarchical-term-selector.js.map +1 -1
  88. package/build-module/components/post-title/index.js +0 -5
  89. package/build-module/components/post-title/index.js.map +1 -1
  90. package/build-module/components/post-title/index.native.js.map +1 -1
  91. package/build-module/components/post-title/post-title-raw.js.map +1 -1
  92. package/build-module/components/post-view-link/index.js +2 -1
  93. package/build-module/components/post-view-link/index.js.map +1 -1
  94. package/build-module/components/provider/index.js +8 -1
  95. package/build-module/components/provider/index.js.map +1 -1
  96. package/build-module/components/provider/index.native.js +4 -10
  97. package/build-module/components/provider/index.native.js.map +1 -1
  98. package/build-module/components/provider/use-block-editor-settings.js +1 -1
  99. package/build-module/components/provider/use-block-editor-settings.js.map +1 -1
  100. package/build-module/components/provider/use-hide-blocks-from-inserter.js +47 -0
  101. package/build-module/components/provider/use-hide-blocks-from-inserter.js.map +1 -0
  102. package/build-module/private-apis.js +2 -0
  103. package/build-module/private-apis.js.map +1 -1
  104. package/build-module/store/actions.js +66 -0
  105. package/build-module/store/actions.js.map +1 -1
  106. package/build-module/store/selectors.js +12 -0
  107. package/build-module/store/selectors.js.map +1 -1
  108. package/build-style/style-rtl.css +4 -47
  109. package/build-style/style.css +4 -47
  110. package/package.json +32 -32
  111. package/src/components/block-removal-warnings/index.js +92 -0
  112. package/src/components/commands/index.js +210 -0
  113. package/src/components/commands/index.native.js +2 -0
  114. package/src/components/document-bar/index.js +115 -94
  115. package/src/components/document-bar/style.scss +4 -37
  116. package/src/components/document-outline/check.js +8 -10
  117. package/src/components/document-outline/index.js +18 -23
  118. package/src/components/document-outline/test/index.js +26 -7
  119. package/src/components/document-tools/index.js +3 -3
  120. package/src/components/editor-help/intro-to-blocks.native.js +1 -1
  121. package/src/components/entities-saved-states/entity-type-list.js +1 -1
  122. package/src/components/global-keyboard-shortcuts/index.js +35 -4
  123. package/src/components/global-keyboard-shortcuts/register-shortcuts.js +20 -0
  124. package/src/components/list-view-sidebar/index.js +1 -1
  125. package/src/components/mode-switcher/index.js +90 -0
  126. package/src/components/post-locked-modal/index.js +1 -1
  127. package/src/components/post-preview-button/index.js +1 -0
  128. package/src/components/post-publish-button/index.js +1 -0
  129. package/src/components/post-publish-panel/index.js +1 -1
  130. package/src/components/post-publish-panel/maybe-upload-media.js +1 -1
  131. package/src/components/post-publish-panel/test/__snapshots__/index.js.snap +3 -3
  132. package/src/components/post-taxonomies/hierarchical-term-selector.js +3 -0
  133. package/src/components/post-title/index.js +0 -3
  134. package/src/components/post-title/index.native.js +2 -2
  135. package/src/components/post-title/post-title-raw.js +1 -1
  136. package/src/components/post-view-link/index.js +1 -0
  137. package/src/components/provider/index.js +9 -0
  138. package/src/components/provider/index.native.js +7 -6
  139. package/src/components/provider/use-block-editor-settings.js +0 -3
  140. package/src/components/provider/use-hide-blocks-from-inserter.js +81 -0
  141. package/src/private-apis.js +2 -0
  142. package/src/store/actions.js +95 -0
  143. package/src/store/selectors.js +12 -0
  144. package/src/store/test/actions.js +82 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/editor",
3
- "version": "13.28.5",
3
+ "version": "13.30.0",
4
4
  "description": "Enhanced block editor for WordPress posts.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -31,36 +31,36 @@
31
31
  ],
32
32
  "dependencies": {
33
33
  "@babel/runtime": "^7.16.0",
34
- "@wordpress/a11y": "^3.51.1",
35
- "@wordpress/api-fetch": "^6.48.1",
36
- "@wordpress/blob": "^3.51.1",
37
- "@wordpress/block-editor": "^12.19.5",
38
- "@wordpress/blocks": "^12.28.5",
39
- "@wordpress/commands": "^0.22.4",
40
- "@wordpress/components": "^26.0.4",
41
- "@wordpress/compose": "^6.28.1",
42
- "@wordpress/core-data": "^6.28.5",
43
- "@wordpress/data": "^9.21.1",
44
- "@wordpress/date": "^4.51.1",
45
- "@wordpress/deprecated": "^3.51.1",
46
- "@wordpress/dom": "^3.51.1",
47
- "@wordpress/element": "^5.28.1",
48
- "@wordpress/hooks": "^3.51.1",
49
- "@wordpress/html-entities": "^3.51.1",
50
- "@wordpress/i18n": "^4.51.1",
51
- "@wordpress/icons": "^9.42.3",
52
- "@wordpress/keyboard-shortcuts": "^4.28.1",
53
- "@wordpress/keycodes": "^3.51.1",
54
- "@wordpress/media-utils": "^4.42.1",
55
- "@wordpress/notices": "^4.19.1",
56
- "@wordpress/patterns": "^1.12.5",
57
- "@wordpress/preferences": "^3.28.4",
58
- "@wordpress/private-apis": "^0.33.1",
59
- "@wordpress/reusable-blocks": "^4.28.5",
60
- "@wordpress/rich-text": "^6.28.3",
61
- "@wordpress/server-side-render": "^4.28.5",
62
- "@wordpress/url": "^3.52.1",
63
- "@wordpress/wordcount": "^3.51.1",
34
+ "@wordpress/a11y": "^3.53.0",
35
+ "@wordpress/api-fetch": "^6.50.0",
36
+ "@wordpress/blob": "^3.53.0",
37
+ "@wordpress/block-editor": "^12.21.0",
38
+ "@wordpress/blocks": "^12.30.0",
39
+ "@wordpress/commands": "^0.24.0",
40
+ "@wordpress/components": "^27.1.0",
41
+ "@wordpress/compose": "^6.30.0",
42
+ "@wordpress/core-data": "^6.30.0",
43
+ "@wordpress/data": "^9.23.0",
44
+ "@wordpress/date": "^4.53.0",
45
+ "@wordpress/deprecated": "^3.53.0",
46
+ "@wordpress/dom": "^3.53.0",
47
+ "@wordpress/element": "^5.30.0",
48
+ "@wordpress/hooks": "^3.53.0",
49
+ "@wordpress/html-entities": "^3.53.0",
50
+ "@wordpress/i18n": "^4.53.0",
51
+ "@wordpress/icons": "^9.44.0",
52
+ "@wordpress/keyboard-shortcuts": "^4.30.0",
53
+ "@wordpress/keycodes": "^3.53.0",
54
+ "@wordpress/media-utils": "^4.44.0",
55
+ "@wordpress/notices": "^4.21.0",
56
+ "@wordpress/patterns": "^1.14.0",
57
+ "@wordpress/preferences": "^3.30.0",
58
+ "@wordpress/private-apis": "^0.35.0",
59
+ "@wordpress/reusable-blocks": "^4.30.0",
60
+ "@wordpress/rich-text": "^6.30.0",
61
+ "@wordpress/server-side-render": "^4.30.0",
62
+ "@wordpress/url": "^3.54.0",
63
+ "@wordpress/wordcount": "^3.53.0",
64
64
  "classnames": "^2.3.1",
65
65
  "date-fns": "^2.28.0",
66
66
  "memize": "^2.1.0",
@@ -75,5 +75,5 @@
75
75
  "publishConfig": {
76
76
  "access": "public"
77
77
  },
78
- "gitHead": "4927ea437069f9aed12f696df294a79bd8e12fd5"
78
+ "gitHead": "ac3c3e465a083081a86a4da6ee6fb817b41e5130"
79
79
  }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+
5
+ import { _n } from '@wordpress/i18n';
6
+ import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';
7
+ import { useSelect } from '@wordpress/data';
8
+ import { useMemo } from '@wordpress/element';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import { unlock } from '../../lock-unlock';
14
+ import { store as editorStore } from '../../store';
15
+
16
+ const { BlockRemovalWarningModal } = unlock( blockEditorPrivateApis );
17
+
18
+ // Prevent accidental removal of certain blocks, asking the user for confirmation first.
19
+ const TEMPLATE_BLOCKS = [
20
+ 'core/post-content',
21
+ 'core/post-template',
22
+ 'core/query',
23
+ ];
24
+ const BLOCK_REMOVAL_RULES = [
25
+ {
26
+ // Template blocks.
27
+ // The warning is only shown when a user manipulates templates or template parts.
28
+ postTypes: [ 'wp_template', 'wp_template_part' ],
29
+ callback( removedBlocks ) {
30
+ const removedTemplateBlocks = removedBlocks.filter( ( { name } ) =>
31
+ TEMPLATE_BLOCKS.includes( name )
32
+ );
33
+ if ( removedTemplateBlocks.length ) {
34
+ return _n(
35
+ 'Deleting this block will stop your post or page content from displaying on this template. It is not recommended.',
36
+ 'Some of the deleted blocks will stop your post or page content from displaying on this template. It is not recommended.',
37
+ removedBlocks.length
38
+ );
39
+ }
40
+ },
41
+ },
42
+ {
43
+ // Pattern overrides.
44
+ // The warning is only shown when the user edits a pattern.
45
+ postTypes: [ 'wp_block' ],
46
+ callback( removedBlocks ) {
47
+ const removedBlocksWithOverrides = removedBlocks.filter(
48
+ ( { attributes } ) =>
49
+ attributes?.metadata?.bindings &&
50
+ Object.values( attributes.metadata.bindings ).some(
51
+ ( binding ) =>
52
+ binding.source === 'core/pattern-overrides'
53
+ )
54
+ );
55
+ if ( removedBlocksWithOverrides.length ) {
56
+ return _n(
57
+ 'The deleted block allows instance overrides. Removing it may result in content not displaying where this pattern is used. Are you sure you want to proceed?',
58
+ 'Some of the deleted blocks allow instance overrides. Removing them may result in content not displaying where this pattern is used. Are you sure you want to proceed?',
59
+ removedBlocks.length
60
+ );
61
+ }
62
+ },
63
+ },
64
+ ];
65
+
66
+ export default function BlockRemovalWarnings() {
67
+ const currentPostType = useSelect(
68
+ ( select ) => select( editorStore ).getCurrentPostType(),
69
+ []
70
+ );
71
+
72
+ const removalRulesForPostType = useMemo(
73
+ () =>
74
+ BLOCK_REMOVAL_RULES.filter( ( rule ) =>
75
+ rule.postTypes.includes( currentPostType )
76
+ ),
77
+ [ currentPostType ]
78
+ );
79
+
80
+ // `BlockRemovalWarnings` is rendered in the editor provider, a shared component
81
+ // across react native and web. However, `BlockRemovalWarningModal` is web only.
82
+ // Check it exists before trying to render it.
83
+ if ( ! BlockRemovalWarningModal ) {
84
+ return null;
85
+ }
86
+
87
+ if ( ! removalRulesForPostType ) {
88
+ return null;
89
+ }
90
+
91
+ return <BlockRemovalWarningModal rules={ removalRulesForPostType } />;
92
+ }
@@ -0,0 +1,210 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect, useDispatch } from '@wordpress/data';
5
+ import { __ } from '@wordpress/i18n';
6
+ import { code, listView, external } from '@wordpress/icons';
7
+ import { useCommandLoader } from '@wordpress/commands';
8
+ import { store as preferencesStore } from '@wordpress/preferences';
9
+ import { store as noticesStore } from '@wordpress/notices';
10
+ import { store as blockEditorStore } from '@wordpress/block-editor';
11
+ import { store as coreStore } from '@wordpress/core-data';
12
+
13
+ /**
14
+ * Internal dependencies
15
+ */
16
+ import { store as editorStore } from '../../store';
17
+
18
+ function useEditorCommandLoader() {
19
+ const {
20
+ editorMode,
21
+ isListViewOpen,
22
+ showBlockBreadcrumbs,
23
+ isDistractionFree,
24
+ isTopToolbar,
25
+ isFocusMode,
26
+ isPreviewMode,
27
+ isViewable,
28
+ isCodeEditingEnabled,
29
+ isRichEditingEnabled,
30
+ } = useSelect( ( select ) => {
31
+ const { get } = select( preferencesStore );
32
+ const { isListViewOpened, getCurrentPostType, getEditorSettings } =
33
+ select( editorStore );
34
+ const { getSettings } = select( blockEditorStore );
35
+ const { getPostType } = select( coreStore );
36
+
37
+ return {
38
+ editorMode: get( 'core', 'editorMode' ) ?? 'visual',
39
+ isListViewOpen: isListViewOpened(),
40
+ showBlockBreadcrumbs: get( 'core', 'showBlockBreadcrumbs' ),
41
+ isDistractionFree: get( 'core', 'distractionFree' ),
42
+ isFocusMode: get( 'core', 'focusMode' ),
43
+ isTopToolbar: get( 'core', 'fixedToolbar' ),
44
+ isPreviewMode: getSettings().__unstableIsPreviewMode,
45
+ isViewable: getPostType( getCurrentPostType() )?.viewable ?? false,
46
+ isCodeEditingEnabled: getEditorSettings().codeEditingEnabled,
47
+ isRichEditingEnabled: getEditorSettings().richEditingEnabled,
48
+ };
49
+ }, [] );
50
+ const { toggle } = useDispatch( preferencesStore );
51
+ const { createInfoNotice } = useDispatch( noticesStore );
52
+ const {
53
+ __unstableSaveForPreview,
54
+ setIsListViewOpened,
55
+ switchEditorMode,
56
+ toggleDistractionFree,
57
+ } = useDispatch( editorStore );
58
+ const { getCurrentPostId } = useSelect( editorStore );
59
+ const allowSwitchEditorMode = isCodeEditingEnabled && isRichEditingEnabled;
60
+
61
+ if ( isPreviewMode ) {
62
+ return { commands: [], isLoading: false };
63
+ }
64
+
65
+ const commands = [];
66
+
67
+ commands.push( {
68
+ name: 'core/toggle-distraction-free',
69
+ label: isDistractionFree
70
+ ? __( 'Exit Distraction Free' )
71
+ : __( 'Enter Distraction Free ' ),
72
+ callback: ( { close } ) => {
73
+ toggleDistractionFree();
74
+ close();
75
+ },
76
+ } );
77
+
78
+ commands.push( {
79
+ name: 'core/toggle-spotlight-mode',
80
+ label: __( 'Toggle spotlight' ),
81
+ callback: ( { close } ) => {
82
+ toggle( 'core', 'focusMode' );
83
+ close();
84
+ createInfoNotice(
85
+ isFocusMode ? __( 'Spotlight off.' ) : __( 'Spotlight on.' ),
86
+ {
87
+ id: 'core/editor/toggle-spotlight-mode/notice',
88
+ type: 'snackbar',
89
+ actions: [
90
+ {
91
+ label: __( 'Undo' ),
92
+ onClick: () => {
93
+ toggle( 'core', 'focusMode' );
94
+ },
95
+ },
96
+ ],
97
+ }
98
+ );
99
+ },
100
+ } );
101
+
102
+ commands.push( {
103
+ name: 'core/toggle-list-view',
104
+ label: isListViewOpen
105
+ ? __( 'Close List View' )
106
+ : __( 'Open List View' ),
107
+ icon: listView,
108
+ callback: ( { close } ) => {
109
+ setIsListViewOpened( ! isListViewOpen );
110
+ close();
111
+ createInfoNotice(
112
+ isListViewOpen ? __( 'List View off.' ) : __( 'List View on.' ),
113
+ {
114
+ id: 'core/editor/toggle-list-view/notice',
115
+ type: 'snackbar',
116
+ }
117
+ );
118
+ },
119
+ } );
120
+
121
+ commands.push( {
122
+ name: 'core/toggle-top-toolbar',
123
+ label: __( 'Toggle top toolbar' ),
124
+ callback: ( { close } ) => {
125
+ toggle( 'core', 'fixedToolbar' );
126
+ if ( isDistractionFree ) {
127
+ toggleDistractionFree();
128
+ }
129
+ close();
130
+ createInfoNotice(
131
+ isTopToolbar
132
+ ? __( 'Top toolbar off.' )
133
+ : __( 'Top toolbar on.' ),
134
+ {
135
+ id: 'core/editor/toggle-top-toolbar/notice',
136
+ type: 'snackbar',
137
+ actions: [
138
+ {
139
+ label: __( 'Undo' ),
140
+ onClick: () => {
141
+ toggle( 'core', 'fixedToolbar' );
142
+ },
143
+ },
144
+ ],
145
+ }
146
+ );
147
+ },
148
+ } );
149
+
150
+ if ( allowSwitchEditorMode ) {
151
+ commands.push( {
152
+ name: 'core/toggle-code-editor',
153
+ label:
154
+ editorMode === 'visual'
155
+ ? __( 'Open code editor' )
156
+ : __( 'Exit code editor' ),
157
+ icon: code,
158
+ callback: ( { close } ) => {
159
+ switchEditorMode( editorMode === 'visual' ? 'text' : 'visual' );
160
+ close();
161
+ },
162
+ } );
163
+ }
164
+
165
+ commands.push( {
166
+ name: 'core/toggle-breadcrumbs',
167
+ label: showBlockBreadcrumbs
168
+ ? __( 'Hide block breadcrumbs' )
169
+ : __( 'Show block breadcrumbs' ),
170
+ callback: ( { close } ) => {
171
+ toggle( 'core', 'showBlockBreadcrumbs' );
172
+ close();
173
+ createInfoNotice(
174
+ showBlockBreadcrumbs
175
+ ? __( 'Breadcrumbs hidden.' )
176
+ : __( 'Breadcrumbs visible.' ),
177
+ {
178
+ id: 'core/editor/toggle-breadcrumbs/notice',
179
+ type: 'snackbar',
180
+ }
181
+ );
182
+ },
183
+ } );
184
+
185
+ if ( isViewable ) {
186
+ commands.push( {
187
+ name: 'core/preview-link',
188
+ label: __( 'Preview in a new tab' ),
189
+ icon: external,
190
+ callback: async ( { close } ) => {
191
+ close();
192
+ const postId = getCurrentPostId();
193
+ const link = await __unstableSaveForPreview();
194
+ window.open( link, `wp-preview-${ postId }` );
195
+ },
196
+ } );
197
+ }
198
+
199
+ return {
200
+ commands,
201
+ isLoading: false,
202
+ };
203
+ }
204
+
205
+ export default function useCommands() {
206
+ useCommandLoader( {
207
+ name: 'core/editor/edit-ui',
208
+ hook: useEditorCommandLoader,
209
+ } );
210
+ }
@@ -0,0 +1,2 @@
1
+ // Commands are disabled in the mobile native version.
2
+ export default function useCommands() {}
@@ -11,7 +11,8 @@ import { useSelect, useDispatch } from '@wordpress/data';
11
11
  import {
12
12
  Button,
13
13
  __experimentalText as Text,
14
- __experimentalHStack as HStack,
14
+ __unstableMotion as motion,
15
+ __unstableAnimatePresence as AnimatePresence,
15
16
  } from '@wordpress/components';
16
17
  import { BlockIcon } from '@wordpress/block-editor';
17
18
  import {
@@ -22,16 +23,17 @@ import {
22
23
  symbol,
23
24
  } from '@wordpress/icons';
24
25
  import { displayShortcut } from '@wordpress/keycodes';
25
- import { useEntityRecord } from '@wordpress/core-data';
26
+ import { store as coreStore } from '@wordpress/core-data';
26
27
  import { store as commandsStore } from '@wordpress/commands';
27
- import { useState, useEffect, useRef } from '@wordpress/element';
28
+ import { useRef, useEffect } from '@wordpress/element';
29
+ import { useReducedMotion } from '@wordpress/compose';
28
30
 
29
31
  /**
30
32
  * Internal dependencies
31
33
  */
32
34
  import { store as editorStore } from '../../store';
33
35
 
34
- const typeLabels = {
36
+ const TYPE_LABELS = {
35
37
  // translators: 1: Pattern title.
36
38
  wp_pattern: __( 'Editing pattern: %s' ),
37
39
  // translators: 1: Navigation menu title.
@@ -42,133 +44,152 @@ const typeLabels = {
42
44
  wp_template_part: __( 'Editing template part: %s' ),
43
45
  };
44
46
 
45
- const icons = {
47
+ const ICONS = {
46
48
  wp_block: symbol,
47
49
  wp_navigation: navigationIcon,
48
50
  };
49
51
 
50
- export default function DocumentBar() {
51
- const { postType, postId, onNavigateToPreviousEntityRecord } = useSelect(
52
- ( select ) => {
53
- const {
54
- getCurrentPostId,
55
- getCurrentPostType,
56
- getEditorSettings: getSettings,
57
- } = select( editorStore );
58
- return {
59
- postType: getCurrentPostType(),
60
- postId: getCurrentPostId(),
61
- onNavigateToPreviousEntityRecord:
62
- getSettings().onNavigateToPreviousEntityRecord,
63
- getEditorSettings: getSettings,
64
- };
65
- },
66
- []
67
- );
52
+ const TEMPLATE_POST_TYPES = [ 'wp_template', 'wp_template_part' ];
68
53
 
69
- const handleOnBack = () => {
70
- if ( onNavigateToPreviousEntityRecord ) {
71
- onNavigateToPreviousEntityRecord();
72
- }
73
- };
54
+ const GLOBAL_POST_TYPES = [
55
+ ...TEMPLATE_POST_TYPES,
56
+ 'wp_block',
57
+ 'wp_navigation',
58
+ ];
74
59
 
75
- return (
76
- <BaseDocumentActions
77
- postType={ postType }
78
- postId={ postId }
79
- onBack={
80
- onNavigateToPreviousEntityRecord ? handleOnBack : undefined
81
- }
82
- />
83
- );
84
- }
60
+ const MotionButton = motion( Button );
85
61
 
86
- function BaseDocumentActions( { postType, postId, onBack } ) {
87
- const { open: openCommandCenter } = useDispatch( commandsStore );
88
- const { editedRecord: doc, isResolving } = useEntityRecord(
89
- 'postType',
62
+ export default function DocumentBar() {
63
+ const {
90
64
  postType,
91
- postId
92
- );
93
- const { templateIcon, templateTitle } = useSelect( ( select ) => {
94
- const { __experimentalGetTemplateInfo: getTemplateInfo } =
95
- select( editorStore );
96
- const templateInfo = getTemplateInfo( doc );
65
+ document,
66
+ isResolving,
67
+ templateIcon,
68
+ templateTitle,
69
+ onNavigateToPreviousEntityRecord,
70
+ } = useSelect( ( select ) => {
71
+ const {
72
+ getCurrentPostType,
73
+ getCurrentPostId,
74
+ getEditorSettings,
75
+ __experimentalGetTemplateInfo: getTemplateInfo,
76
+ } = select( editorStore );
77
+ const { getEditedEntityRecord, getIsResolving } = select( coreStore );
78
+ const _postType = getCurrentPostType();
79
+ const _postId = getCurrentPostId();
80
+ const _document = getEditedEntityRecord(
81
+ 'postType',
82
+ _postType,
83
+ _postId
84
+ );
85
+ const _templateInfo = getTemplateInfo( _document );
97
86
  return {
98
- templateIcon: templateInfo.icon,
99
- templateTitle: templateInfo.title,
87
+ postType: _postType,
88
+ document: _document,
89
+ isResolving: getIsResolving(
90
+ 'getEditedEntityRecord',
91
+ 'postType',
92
+ _postType,
93
+ _postId
94
+ ),
95
+ templateIcon: _templateInfo.icon,
96
+ templateTitle: _templateInfo.title,
97
+ onNavigateToPreviousEntityRecord:
98
+ getEditorSettings().onNavigateToPreviousEntityRecord,
100
99
  };
101
- } );
102
- const isNotFound = ! doc && ! isResolving;
103
- const icon = icons[ postType ] ?? pageIcon;
104
- const [ isAnimated, setIsAnimated ] = useState( false );
105
- const isMounting = useRef( true );
106
- const isTemplate = [ 'wp_template', 'wp_template_part' ].includes(
107
- postType
108
- );
109
- const isGlobalEntity = [
110
- 'wp_template',
111
- 'wp_navigation',
112
- 'wp_template_part',
113
- 'wp_block',
114
- ].includes( postType );
100
+ }, [] );
115
101
 
116
- useEffect( () => {
117
- if ( ! isMounting.current ) {
118
- setIsAnimated( true );
119
- }
120
- isMounting.current = false;
121
- }, [ postType, postId ] );
102
+ const { open: openCommandCenter } = useDispatch( commandsStore );
103
+ const isReducedMotion = useReducedMotion();
104
+
105
+ const isNotFound = ! document && ! isResolving;
106
+ const icon = ICONS[ postType ] ?? pageIcon;
107
+ const isTemplate = TEMPLATE_POST_TYPES.includes( postType );
108
+ const isGlobalEntity = GLOBAL_POST_TYPES.includes( postType );
109
+ const hasBackButton = !! onNavigateToPreviousEntityRecord;
110
+ const title = isTemplate ? templateTitle : document.title;
122
111
 
123
- const title = isTemplate ? templateTitle : doc.title;
112
+ const mounted = useRef( false );
113
+ useEffect( () => {
114
+ mounted.current = true;
115
+ }, [] );
124
116
 
125
117
  return (
126
118
  <div
127
119
  className={ classnames( 'editor-document-bar', {
128
- 'has-back-button': !! onBack,
129
- 'is-animated': isAnimated,
120
+ 'has-back-button': hasBackButton,
130
121
  'is-global': isGlobalEntity,
131
122
  } ) }
132
123
  >
133
- { onBack && (
134
- <Button
135
- className="editor-document-bar__back"
136
- icon={ isRTL() ? chevronRightSmall : chevronLeftSmall }
137
- onClick={ ( event ) => {
138
- event.stopPropagation();
139
- onBack();
140
- } }
141
- size="compact"
142
- >
143
- { __( 'Back' ) }
144
- </Button>
145
- ) }
146
- { isNotFound && <Text>{ __( 'Document not found' ) }</Text> }
147
- { ! isNotFound && (
124
+ <AnimatePresence>
125
+ { hasBackButton && (
126
+ <MotionButton
127
+ className="editor-document-bar__back"
128
+ icon={ isRTL() ? chevronRightSmall : chevronLeftSmall }
129
+ onClick={ ( event ) => {
130
+ event.stopPropagation();
131
+ onNavigateToPreviousEntityRecord();
132
+ } }
133
+ size="compact"
134
+ initial={
135
+ mounted.current
136
+ ? { opacity: 0, transform: 'translateX(15%)' }
137
+ : false // Don't show entry animation when DocumentBar mounts.
138
+ }
139
+ animate={ { opacity: 1, transform: 'translateX(0%)' } }
140
+ exit={ { opacity: 0, transform: 'translateX(15%)' } }
141
+ transition={
142
+ isReducedMotion ? { duration: 0 } : undefined
143
+ }
144
+ >
145
+ { __( 'Back' ) }
146
+ </MotionButton>
147
+ ) }
148
+ </AnimatePresence>
149
+ { isNotFound ? (
150
+ <Text>{ __( 'Document not found' ) }</Text>
151
+ ) : (
148
152
  <Button
149
153
  className="editor-document-bar__command"
150
154
  onClick={ () => openCommandCenter() }
151
155
  size="compact"
152
156
  >
153
- <HStack
157
+ <motion.div
154
158
  className="editor-document-bar__title"
155
- spacing={ 1 }
156
- justify="center"
159
+ // Force entry animation when the back button is added or removed.
160
+ key={ hasBackButton }
161
+ initial={
162
+ mounted.current
163
+ ? {
164
+ opacity: 0,
165
+ transform: hasBackButton
166
+ ? 'translateX(15%)'
167
+ : 'translateX(-15%)',
168
+ }
169
+ : false // Don't show entry animation when DocumentBar mounts.
170
+ }
171
+ animate={ {
172
+ opacity: 1,
173
+ transform: 'translateX(0%)',
174
+ } }
175
+ transition={
176
+ isReducedMotion ? { duration: 0 } : undefined
177
+ }
157
178
  >
158
179
  <BlockIcon icon={ isTemplate ? templateIcon : icon } />
159
180
  <Text
160
181
  size="body"
161
182
  as="h1"
162
183
  aria-label={
163
- typeLabels[ postType ]
184
+ TYPE_LABELS[ postType ]
164
185
  ? // eslint-disable-next-line @wordpress/valid-sprintf
165
- sprintf( typeLabels[ postType ], title )
186
+ sprintf( TYPE_LABELS[ postType ], title )
166
187
  : undefined
167
188
  }
168
189
  >
169
190
  { title }
170
191
  </Text>
171
- </HStack>
192
+ </motion.div>
172
193
  <span className="editor-document-bar__shortcut">
173
194
  { displayShortcut.primary( 'k' ) }
174
195
  </span>