@wordpress/edit-site 4.8.0 → 4.11.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 (204) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/build/components/add-new-template/add-custom-generic-template-modal.js +84 -0
  3. package/build/components/add-new-template/add-custom-generic-template-modal.js.map +1 -0
  4. package/build/components/add-new-template/add-custom-template-modal.js +204 -0
  5. package/build/components/add-new-template/add-custom-template-modal.js.map +1 -0
  6. package/build/components/add-new-template/new-template.js +91 -33
  7. package/build/components/add-new-template/new-template.js.map +1 -1
  8. package/build/components/add-new-template/utils.js +532 -0
  9. package/build/components/add-new-template/utils.js.map +1 -0
  10. package/build/components/block-editor/index.js +1 -3
  11. package/build/components/block-editor/index.js.map +1 -1
  12. package/build/components/code-editor/index.js +17 -4
  13. package/build/components/code-editor/index.js.map +1 -1
  14. package/build/components/editor/index.js +16 -0
  15. package/build/components/editor/index.js.map +1 -1
  16. package/build/components/error-boundary/index.js +6 -0
  17. package/build/components/error-boundary/index.js.map +1 -1
  18. package/build/components/global-styles/context-menu.js +6 -3
  19. package/build/components/global-styles/context-menu.js.map +1 -1
  20. package/build/components/global-styles/dimensions-panel.js +185 -19
  21. package/build/components/global-styles/dimensions-panel.js.map +1 -1
  22. package/build/components/global-styles/global-styles-provider.js +4 -2
  23. package/build/components/global-styles/global-styles-provider.js.map +1 -1
  24. package/build/components/global-styles/hooks.js +11 -2
  25. package/build/components/global-styles/hooks.js.map +1 -1
  26. package/build/components/global-styles/palette.js +2 -1
  27. package/build/components/global-styles/palette.js.map +1 -1
  28. package/build/components/global-styles/screen-block-list.js +4 -1
  29. package/build/components/global-styles/screen-block-list.js.map +1 -1
  30. package/build/components/global-styles/screen-button-color.js +80 -0
  31. package/build/components/global-styles/screen-button-color.js.map +1 -0
  32. package/build/components/global-styles/screen-color-palette.js +13 -17
  33. package/build/components/global-styles/screen-color-palette.js.map +1 -1
  34. package/build/components/global-styles/screen-colors.js +56 -8
  35. package/build/components/global-styles/screen-colors.js.map +1 -1
  36. package/build/components/global-styles/screen-link-color.js +48 -14
  37. package/build/components/global-styles/screen-link-color.js.map +1 -1
  38. package/build/components/global-styles/screen-root.js +4 -2
  39. package/build/components/global-styles/screen-root.js.map +1 -1
  40. package/build/components/global-styles/screen-typography-element.js +4 -0
  41. package/build/components/global-styles/screen-typography-element.js.map +1 -1
  42. package/build/components/global-styles/screen-typography.js +9 -1
  43. package/build/components/global-styles/screen-typography.js.map +1 -1
  44. package/build/components/global-styles/ui.js +11 -0
  45. package/build/components/global-styles/ui.js.map +1 -1
  46. package/build/components/global-styles/use-global-styles-output.js +282 -35
  47. package/build/components/global-styles/use-global-styles-output.js.map +1 -1
  48. package/build/components/global-styles/utils.js +35 -2
  49. package/build/components/global-styles/utils.js.map +1 -1
  50. package/build/components/header/index.js +29 -10
  51. package/build/components/header/index.js.map +1 -1
  52. package/build/components/header/more-menu/site-export.js +4 -1
  53. package/build/components/header/more-menu/site-export.js.map +1 -1
  54. package/build/components/header/undo-redo/redo.js +13 -4
  55. package/build/components/header/undo-redo/redo.js.map +1 -1
  56. package/build/components/header/undo-redo/undo.js +13 -4
  57. package/build/components/header/undo-redo/undo.js.map +1 -1
  58. package/build/components/keyboard-shortcut-help-modal/config.js +17 -0
  59. package/build/components/keyboard-shortcut-help-modal/config.js.map +1 -1
  60. package/build/components/keyboard-shortcut-help-modal/index.js +1 -3
  61. package/build/components/keyboard-shortcut-help-modal/index.js.map +1 -1
  62. package/build/components/sidebar/template-card/index.js +19 -7
  63. package/build/components/sidebar/template-card/index.js.map +1 -1
  64. package/build/components/sidebar/template-card/template-actions.js +64 -0
  65. package/build/components/sidebar/template-card/template-actions.js.map +1 -0
  66. package/build/components/template-details/edit-template-title.js +11 -3
  67. package/build/components/template-details/edit-template-title.js.map +1 -1
  68. package/build/components/template-details/index.js +1 -20
  69. package/build/components/template-details/index.js.map +1 -1
  70. package/build/hooks/index.js +2 -0
  71. package/build/hooks/index.js.map +1 -1
  72. package/build/hooks/template-part-edit.js +86 -0
  73. package/build/hooks/template-part-edit.js.map +1 -0
  74. package/build/store/selectors.js +4 -1
  75. package/build/store/selectors.js.map +1 -1
  76. package/build-module/components/add-new-template/add-custom-generic-template-modal.js +77 -0
  77. package/build-module/components/add-new-template/add-custom-generic-template-modal.js.map +1 -0
  78. package/build-module/components/add-new-template/add-custom-template-modal.js +189 -0
  79. package/build-module/components/add-new-template/add-custom-template-modal.js.map +1 -0
  80. package/build-module/components/add-new-template/new-template.js +90 -34
  81. package/build-module/components/add-new-template/new-template.js.map +1 -1
  82. package/build-module/components/add-new-template/utils.js +503 -0
  83. package/build-module/components/add-new-template/utils.js.map +1 -0
  84. package/build-module/components/block-editor/index.js +1 -2
  85. package/build-module/components/block-editor/index.js.map +1 -1
  86. package/build-module/components/code-editor/index.js +18 -5
  87. package/build-module/components/code-editor/index.js.map +1 -1
  88. package/build-module/components/editor/index.js +16 -0
  89. package/build-module/components/editor/index.js.map +1 -1
  90. package/build-module/components/error-boundary/index.js +5 -0
  91. package/build-module/components/error-boundary/index.js.map +1 -1
  92. package/build-module/components/global-styles/context-menu.js +6 -3
  93. package/build-module/components/global-styles/context-menu.js.map +1 -1
  94. package/build-module/components/global-styles/dimensions-panel.js +185 -20
  95. package/build-module/components/global-styles/dimensions-panel.js.map +1 -1
  96. package/build-module/components/global-styles/global-styles-provider.js +4 -2
  97. package/build-module/components/global-styles/global-styles-provider.js.map +1 -1
  98. package/build-module/components/global-styles/hooks.js +11 -2
  99. package/build-module/components/global-styles/hooks.js.map +1 -1
  100. package/build-module/components/global-styles/palette.js +2 -1
  101. package/build-module/components/global-styles/palette.js.map +1 -1
  102. package/build-module/components/global-styles/screen-block-list.js +4 -1
  103. package/build-module/components/global-styles/screen-block-list.js.map +1 -1
  104. package/build-module/components/global-styles/screen-button-color.js +67 -0
  105. package/build-module/components/global-styles/screen-button-color.js.map +1 -0
  106. package/build-module/components/global-styles/screen-color-palette.js +14 -19
  107. package/build-module/components/global-styles/screen-color-palette.js.map +1 -1
  108. package/build-module/components/global-styles/screen-colors.js +57 -9
  109. package/build-module/components/global-styles/screen-colors.js.map +1 -1
  110. package/build-module/components/global-styles/screen-link-color.js +47 -14
  111. package/build-module/components/global-styles/screen-link-color.js.map +1 -1
  112. package/build-module/components/global-styles/screen-root.js +4 -2
  113. package/build-module/components/global-styles/screen-root.js.map +1 -1
  114. package/build-module/components/global-styles/screen-typography-element.js +4 -0
  115. package/build-module/components/global-styles/screen-typography-element.js.map +1 -1
  116. package/build-module/components/global-styles/screen-typography.js +10 -2
  117. package/build-module/components/global-styles/screen-typography.js.map +1 -1
  118. package/build-module/components/global-styles/ui.js +10 -0
  119. package/build-module/components/global-styles/ui.js.map +1 -1
  120. package/build-module/components/global-styles/use-global-styles-output.js +280 -42
  121. package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
  122. package/build-module/components/global-styles/utils.js +34 -3
  123. package/build-module/components/global-styles/utils.js.map +1 -1
  124. package/build-module/components/header/index.js +31 -11
  125. package/build-module/components/header/index.js.map +1 -1
  126. package/build-module/components/header/more-menu/site-export.js +4 -1
  127. package/build-module/components/header/more-menu/site-export.js.map +1 -1
  128. package/build-module/components/header/undo-redo/redo.js +9 -3
  129. package/build-module/components/header/undo-redo/redo.js.map +1 -1
  130. package/build-module/components/header/undo-redo/undo.js +9 -3
  131. package/build-module/components/header/undo-redo/undo.js.map +1 -1
  132. package/build-module/components/keyboard-shortcut-help-modal/config.js +17 -0
  133. package/build-module/components/keyboard-shortcut-help-modal/config.js.map +1 -1
  134. package/build-module/components/keyboard-shortcut-help-modal/index.js +1 -2
  135. package/build-module/components/keyboard-shortcut-help-modal/index.js.map +1 -1
  136. package/build-module/components/sidebar/template-card/index.js +18 -7
  137. package/build-module/components/sidebar/template-card/index.js.map +1 -1
  138. package/build-module/components/sidebar/template-card/template-actions.js +49 -0
  139. package/build-module/components/sidebar/template-card/template-actions.js.map +1 -0
  140. package/build-module/components/template-details/edit-template-title.js +12 -3
  141. package/build-module/components/template-details/edit-template-title.js.map +1 -1
  142. package/build-module/components/template-details/index.js +2 -21
  143. package/build-module/components/template-details/index.js.map +1 -1
  144. package/build-module/hooks/index.js +1 -0
  145. package/build-module/hooks/index.js.map +1 -1
  146. package/build-module/hooks/template-part-edit.js +67 -0
  147. package/build-module/hooks/template-part-edit.js.map +1 -0
  148. package/build-module/store/selectors.js +5 -2
  149. package/build-module/store/selectors.js.map +1 -1
  150. package/build-style/style-rtl.css +198 -49
  151. package/build-style/style.css +198 -49
  152. package/package.json +29 -29
  153. package/src/components/add-new-template/add-custom-generic-template-modal.js +97 -0
  154. package/src/components/add-new-template/add-custom-template-modal.js +247 -0
  155. package/src/components/add-new-template/new-template.js +158 -70
  156. package/src/components/add-new-template/style.scss +149 -0
  157. package/src/components/add-new-template/utils.js +538 -0
  158. package/src/components/block-editor/index.js +0 -2
  159. package/src/components/code-editor/index.js +15 -5
  160. package/src/components/editor/index.js +11 -0
  161. package/src/components/error-boundary/index.js +5 -0
  162. package/src/components/global-styles/context-menu.js +3 -0
  163. package/src/components/global-styles/dimensions-panel.js +209 -21
  164. package/src/components/global-styles/global-styles-provider.js +8 -9
  165. package/src/components/global-styles/hooks.js +18 -0
  166. package/src/components/global-styles/palette.js +4 -1
  167. package/src/components/global-styles/screen-block-list.js +10 -1
  168. package/src/components/global-styles/screen-button-color.js +102 -0
  169. package/src/components/global-styles/screen-color-palette.js +25 -27
  170. package/src/components/global-styles/screen-colors.js +58 -7
  171. package/src/components/global-styles/screen-link-color.js +65 -23
  172. package/src/components/global-styles/screen-root.js +8 -2
  173. package/src/components/global-styles/screen-typography-element.js +4 -0
  174. package/src/components/global-styles/screen-typography.js +17 -2
  175. package/src/components/global-styles/style.scss +14 -8
  176. package/src/components/global-styles/test/use-global-styles-output.js +313 -16
  177. package/src/components/global-styles/ui.js +13 -0
  178. package/src/components/global-styles/use-global-styles-output.js +344 -38
  179. package/src/components/global-styles/utils.js +36 -2
  180. package/src/components/header/index.js +42 -17
  181. package/src/components/header/more-menu/site-export.js +3 -0
  182. package/src/components/header/style.scss +58 -8
  183. package/src/components/header/undo-redo/redo.js +6 -1
  184. package/src/components/header/undo-redo/undo.js +6 -1
  185. package/src/components/keyboard-shortcut-help-modal/config.js +12 -0
  186. package/src/components/keyboard-shortcut-help-modal/index.js +1 -2
  187. package/src/components/keyboard-shortcut-help-modal/style.scss +0 -5
  188. package/src/components/list/style.scss +0 -8
  189. package/src/components/sidebar/style.scss +4 -0
  190. package/src/components/sidebar/template-card/index.js +15 -6
  191. package/src/components/sidebar/template-card/style.scss +49 -35
  192. package/src/components/sidebar/template-card/template-actions.js +43 -0
  193. package/src/components/template-details/edit-template-title.js +10 -2
  194. package/src/components/template-details/index.js +4 -21
  195. package/src/components/test/error-boundary.js +38 -0
  196. package/src/hooks/index.js +1 -0
  197. package/src/hooks/template-part-edit.js +82 -0
  198. package/src/store/selectors.js +11 -5
  199. package/src/style.scss +0 -1
  200. package/build/components/edit-template-part-menu-button/index.js +0 -90
  201. package/build/components/edit-template-part-menu-button/index.js.map +0 -1
  202. package/build-module/components/edit-template-part-menu-button/index.js +0 -72
  203. package/build-module/components/edit-template-part-menu-button/index.js.map +0 -1
  204. package/src/components/edit-template-part-menu-button/index.js +0 -82
@@ -21,6 +21,9 @@ export default function SiteExport() {
21
21
  const response = await apiFetch( {
22
22
  path: '/wp-block-editor/v1/export',
23
23
  parse: false,
24
+ headers: {
25
+ Accept: 'application/zip',
26
+ },
24
27
  } );
25
28
  const blob = await response.blob();
26
29
  const contentDisposition = response.headers.get(
@@ -16,9 +16,14 @@ $header-toolbar-min-width: 335px;
16
16
  @include reduce-motion("transition");
17
17
  }
18
18
 
19
- .edit-site-header_start,
19
+ .edit-site-header_start {
20
+ display: flex;
21
+ border: none;
22
+ }
23
+
20
24
  .edit-site-header_end {
21
25
  display: flex;
26
+ justify-content: flex-end;
22
27
  }
23
28
 
24
29
  .edit-site-header_center {
@@ -33,10 +38,6 @@ $header-toolbar-min-width: 335px;
33
38
  // See https://dev.w3.org/csswg/css-flexbox/#min-size-auto
34
39
  min-width: 0;
35
40
  }
36
-
37
- .edit-site-header_end {
38
- justify-content: flex-end;
39
- }
40
41
  }
41
42
 
42
43
  // Keeps the document title centered when the sidebar is open
@@ -152,6 +153,49 @@ body.is-navigation-sidebar-open {
152
153
  }
153
154
  }
154
155
 
156
+ .edit-site-header_start {
157
+ display: flex;
158
+ border: none;
159
+
160
+ // The Toolbar component adds different styles to buttons, so we reset them
161
+ // here to the original button styles
162
+ .edit-site-header__toolbar > .components-button.has-icon,
163
+ .edit-site-header__toolbar > .components-dropdown > .components-button.has-icon {
164
+ height: $button-size;
165
+ min-width: $button-size;
166
+ padding: 6px;
167
+
168
+ &.is-pressed {
169
+ background: $gray-900;
170
+ }
171
+
172
+ &:focus:not(:disabled) {
173
+ box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color), inset 0 0 0 $border-width $white;
174
+ outline: 1px solid transparent;
175
+ }
176
+
177
+ &::before {
178
+ display: none;
179
+ }
180
+ }
181
+
182
+ .edit-site-header__toolbar > .edit-site-header-toolbar__inserter-toggle.has-icon {
183
+ margin-right: $grid-unit-10;
184
+ // Special dimensions for this button.
185
+ min-width: 32px;
186
+ width: 32px;
187
+ height: 32px;
188
+ padding: 0;
189
+ }
190
+
191
+ .edit-site-header__toolbar > .edit-site-header-toolbar__inserter-toggle.has-text.has-icon {
192
+ width: auto;
193
+ padding: 0 $grid-unit-10;
194
+ }
195
+
196
+
197
+ }
198
+
155
199
  // Button text label styles
156
200
 
157
201
  .show-icon-labels .edit-site-header {
@@ -182,14 +226,20 @@ body.is-navigation-sidebar-open {
182
226
  padding-right: 6px;
183
227
  }
184
228
 
185
- // The inserter and the template details toggle have custom labels, different from their aria-label, so we don't want to display both.
186
- .edit-site-header-toolbar__inserter-toggle.edit-site-header-toolbar__inserter-toggle,
229
+ // The template details toggle has a custom label, different from its aria-label, so we don't want to display both.
187
230
  .edit-site-document-actions__get-info.edit-site-document-actions__get-info.edit-site-document-actions__get-info {
188
231
  &::after {
189
232
  content: none;
190
233
  }
234
+ }
191
235
 
236
+ .edit-site-header-toolbar__inserter-toggle.edit-site-header-toolbar__inserter-toggle,
237
+ .edit-site-document-actions__get-info.edit-site-document-actions__get-info.edit-site-document-actions__get-info {
192
238
  height: 36px;
193
- padding: 0 6px;
239
+ padding: 0 $grid-unit-10;
240
+ }
241
+
242
+ .edit-site-header_start .edit-site-header__toolbar > * + * {
243
+ margin-left: $grid-unit-10;
194
244
  }
195
245
  }
@@ -7,8 +7,9 @@ import { useSelect, useDispatch } from '@wordpress/data';
7
7
  import { redo as redoIcon, undo as undoIcon } from '@wordpress/icons';
8
8
  import { displayShortcut } from '@wordpress/keycodes';
9
9
  import { store as coreStore } from '@wordpress/core-data';
10
+ import { forwardRef } from '@wordpress/element';
10
11
 
11
- export default function RedoButton() {
12
+ function RedoButton( props, ref ) {
12
13
  const hasRedo = useSelect(
13
14
  ( select ) => select( coreStore ).hasRedo(),
14
15
  []
@@ -16,6 +17,8 @@ export default function RedoButton() {
16
17
  const { redo } = useDispatch( coreStore );
17
18
  return (
18
19
  <Button
20
+ { ...props }
21
+ ref={ ref }
19
22
  icon={ ! isRTL() ? redoIcon : undoIcon }
20
23
  label={ __( 'Redo' ) }
21
24
  shortcut={ displayShortcut.primaryShift( 'z' ) }
@@ -27,3 +30,5 @@ export default function RedoButton() {
27
30
  />
28
31
  );
29
32
  }
33
+
34
+ export default forwardRef( RedoButton );
@@ -7,8 +7,9 @@ import { useSelect, useDispatch } from '@wordpress/data';
7
7
  import { undo as undoIcon, redo as redoIcon } from '@wordpress/icons';
8
8
  import { displayShortcut } from '@wordpress/keycodes';
9
9
  import { store as coreStore } from '@wordpress/core-data';
10
+ import { forwardRef } from '@wordpress/element';
10
11
 
11
- export default function UndoButton() {
12
+ function UndoButton( props, ref ) {
12
13
  const hasUndo = useSelect(
13
14
  ( select ) => select( coreStore ).hasUndo(),
14
15
  []
@@ -16,6 +17,8 @@ export default function UndoButton() {
16
17
  const { undo } = useDispatch( coreStore );
17
18
  return (
18
19
  <Button
20
+ { ...props }
21
+ ref={ ref }
19
22
  icon={ ! isRTL() ? undoIcon : redoIcon }
20
23
  label={ __( 'Undo' ) }
21
24
  shortcut={ displayShortcut.primary( 'z' ) }
@@ -27,3 +30,5 @@ export default function UndoButton() {
27
30
  />
28
31
  );
29
32
  }
33
+
34
+ export default forwardRef( UndoButton );
@@ -20,8 +20,20 @@ export const textFormattingShortcuts = [
20
20
  keyCombination: { modifier: 'primaryShift', character: 'k' },
21
21
  description: __( 'Remove a link.' ),
22
22
  },
23
+ {
24
+ keyCombination: { character: '[[' },
25
+ description: __( 'Insert a link to a post or page' ),
26
+ },
23
27
  {
24
28
  keyCombination: { modifier: 'primary', character: 'u' },
25
29
  description: __( 'Underline the selected text.' ),
26
30
  },
31
+ {
32
+ keyCombination: { modifier: 'access', character: 'd' },
33
+ description: __( 'Strikethrough the selected text.' ),
34
+ },
35
+ {
36
+ keyCombination: { modifier: 'access', character: 'x' },
37
+ description: __( 'Make the selected text inline code.' ),
38
+ },
27
39
  ];
@@ -2,7 +2,6 @@
2
2
  * External dependencies
3
3
  */
4
4
  import classnames from 'classnames';
5
- import { isString } from 'lodash';
6
5
 
7
6
  /**
8
7
  * WordPress dependencies
@@ -34,7 +33,7 @@ const ShortcutList = ( { shortcuts } ) => (
34
33
  className="edit-site-keyboard-shortcut-help-modal__shortcut"
35
34
  key={ index }
36
35
  >
37
- { isString( shortcut ) ? (
36
+ { typeof shortcut === 'string' ? (
38
37
  <DynamicShortcut name={ shortcut } />
39
38
  ) : (
40
39
  <Shortcut { ...shortcut } />
@@ -3,11 +3,6 @@
3
3
  margin: 0 0 2rem 0;
4
4
  }
5
5
 
6
- &__main-shortcuts .edit-site-keyboard-shortcut-help-modal__shortcut-list {
7
- // Push the shortcut to be flush with top modal header.
8
- margin-top: -$grid-unit-30 -$border-width;
9
- }
10
-
11
6
  &__section-title {
12
7
  font-size: 0.9rem;
13
8
  font-weight: 600;
@@ -131,14 +131,6 @@
131
131
  width: $grid-unit * 40;
132
132
  }
133
133
  }
134
-
135
- .components-modal__header {
136
- border-bottom: none;
137
- }
138
-
139
- .components-modal__content::before {
140
- margin-bottom: $grid-unit-05;
141
- }
142
134
  }
143
135
 
144
136
  .edit-site-list__rename-modal-actions {
@@ -60,6 +60,10 @@
60
60
  grid-column: span 1;
61
61
  }
62
62
 
63
+ .edit-site-global-styles-sidebar .components-tools-panel .span-columns {
64
+ grid-column: 1 / -1;
65
+ }
66
+
63
67
  .edit-site-global-styles-sidebar__blocks-group {
64
68
  padding-top: $grid-unit-30;
65
69
  border-top: $border-width solid $gray-200;
@@ -10,21 +10,26 @@ import { store as coreStore } from '@wordpress/core-data';
10
10
  * Internal dependencies
11
11
  */
12
12
  import { store as editSiteStore } from '../../../store';
13
+ import TemplateActions from './template-actions';
13
14
  import TemplateAreas from './template-areas';
14
15
 
15
16
  export default function TemplateCard() {
16
- const { title, description, icon } = useSelect( ( select ) => {
17
+ const {
18
+ info: { title, description, icon },
19
+ template,
20
+ } = useSelect( ( select ) => {
17
21
  const { getEditedPostType, getEditedPostId } = select( editSiteStore );
18
- const { getEntityRecord } = select( coreStore );
22
+ const { getEditedEntityRecord } = select( coreStore );
19
23
  const { __experimentalGetTemplateInfo: getTemplateInfo } =
20
24
  select( editorStore );
21
25
 
22
26
  const postType = getEditedPostType();
23
27
  const postId = getEditedPostId();
24
- const record = getEntityRecord( 'postType', postType, postId );
28
+ const record = getEditedEntityRecord( 'postType', postType, postId );
29
+
25
30
  const info = record ? getTemplateInfo( record ) : {};
26
31
 
27
- return info;
32
+ return { info, template: record };
28
33
  }, [] );
29
34
 
30
35
  if ( ! title && ! description ) {
@@ -35,11 +40,15 @@ export default function TemplateCard() {
35
40
  <div className="edit-site-template-card">
36
41
  <Icon className="edit-site-template-card__icon" icon={ icon } />
37
42
  <div className="edit-site-template-card__content">
38
- <h2 className="edit-site-template-card__title">{ title }</h2>
43
+ <div className="edit-site-template-card__header">
44
+ <h2 className="edit-site-template-card__title">
45
+ { title }
46
+ </h2>
47
+ <TemplateActions template={ template } />
48
+ </div>
39
49
  <div className="edit-site-template-card__description">
40
50
  { description }
41
51
  </div>
42
-
43
52
  <TemplateAreas />
44
53
  </div>
45
54
  </div>
@@ -1,51 +1,65 @@
1
1
  .edit-site-template-card {
2
2
  display: flex;
3
3
  align-items: flex-start;
4
- }
5
4
 
6
- .edit-site-template-card__content {
7
- flex-grow: 1;
8
- margin-bottom: $grid-unit-05;
9
- }
5
+ &__content {
6
+ flex-grow: 1;
7
+ margin-bottom: $grid-unit-05;
8
+ }
10
9
 
11
- .edit-site-template-card__title {
12
- font-weight: 500;
13
- line-height: $icon-size;
14
- &.edit-site-template-card__title {
15
- margin: 0 0 $grid-unit-05;
10
+ &__title {
11
+ font-weight: 500;
12
+ line-height: $icon-size;
13
+ &.edit-site-template-card__title {
14
+ margin: 0;
15
+ }
16
16
  }
17
- }
18
17
 
19
- .edit-site-template-card__description {
20
- font-size: $default-font-size;
21
- margin: 0 0 $grid-unit-20;
22
- }
18
+ &__description {
19
+ font-size: $default-font-size;
20
+ margin: 0 0 $grid-unit-20;
21
+ }
23
22
 
24
- .edit-site-template-card__icon {
25
- flex: 0 0 $icon-size;
26
- margin-right: $grid-unit-15;
27
- width: $icon-size;
28
- height: $icon-size;
29
- }
23
+ &__icon {
24
+ flex: 0 0 $icon-size;
25
+ margin-right: $grid-unit-15;
26
+ width: $icon-size;
27
+ height: $icon-size;
28
+ }
30
29
 
31
- h3.edit-site-template-card__template-areas-title {
32
- font-weight: 500;
33
- margin: 0 0 $grid-unit-10;
34
- }
30
+ &__template-areas-list {
31
+ margin: 0;
35
32
 
36
- .edit-site-template-card__template-areas-list {
37
- margin: 0;
33
+ > li {
34
+ margin: 0;
35
+ }
36
+ }
38
37
 
39
- > li {
40
- margin: 0;
38
+ &__template-areas-item {
39
+ width: 100%;
40
+
41
+ // Override the default padding.
42
+ &.components-button.has-icon {
43
+ padding: 0;
44
+ }
41
45
  }
42
- }
43
46
 
44
- .edit-site-template-card__template-areas-item {
45
- width: 100%;
47
+ &__header {
48
+ display: flex;
49
+ justify-content: space-between;
50
+ margin: 0 0 $grid-unit-05;
51
+ }
46
52
 
47
- // Override the default padding.
48
- &.components-button.has-icon {
49
- padding: 0;
53
+ &__actions {
54
+ line-height: 0;
55
+ > .components-button.is-small.has-icon {
56
+ padding: 0;
57
+ min-width: auto;
58
+ }
50
59
  }
51
60
  }
61
+
62
+ h3.edit-site-template-card__template-areas-title {
63
+ font-weight: 500;
64
+ margin: 0 0 $grid-unit-10;
65
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useDispatch } from '@wordpress/data';
5
+ import { __ } from '@wordpress/i18n';
6
+ import { DropdownMenu, MenuGroup, MenuItem } from '@wordpress/components';
7
+ import { moreVertical } from '@wordpress/icons';
8
+
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import { store as editSiteStore } from '../../../store';
13
+ import isTemplateRevertable from '../../../utils/is-template-revertable';
14
+
15
+ export default function Actions( { template } ) {
16
+ const { revertTemplate } = useDispatch( editSiteStore );
17
+ const isRevertable = isTemplateRevertable( template );
18
+ if ( ! isRevertable ) {
19
+ return null;
20
+ }
21
+ return (
22
+ <DropdownMenu
23
+ icon={ moreVertical }
24
+ label={ __( 'Actions' ) }
25
+ className="edit-site-template-card__actions"
26
+ toggleProps={ { isSmall: true } }
27
+ >
28
+ { ( { onClose } ) => (
29
+ <MenuGroup>
30
+ <MenuItem
31
+ info={ __( 'Restore to default state' ) }
32
+ onClick={ () => {
33
+ revertTemplate( template );
34
+ onClose();
35
+ } }
36
+ >
37
+ { __( 'Clear customizations' ) }
38
+ </MenuItem>
39
+ </MenuGroup>
40
+ ) }
41
+ </DropdownMenu>
42
+ );
43
+ }
@@ -4,8 +4,10 @@
4
4
  import { __ } from '@wordpress/i18n';
5
5
  import { TextControl } from '@wordpress/components';
6
6
  import { useEntityProp } from '@wordpress/core-data';
7
+ import { useState } from '@wordpress/element';
7
8
 
8
9
  export default function EditTemplateTitle( { template } ) {
10
+ const [ forceEmpty, setForceEmpty ] = useState( false );
9
11
  const [ title, setTitle ] = useEntityProp(
10
12
  'postType',
11
13
  template.type,
@@ -16,13 +18,19 @@ export default function EditTemplateTitle( { template } ) {
16
18
  return (
17
19
  <TextControl
18
20
  label={ __( 'Title' ) }
19
- value={ title }
21
+ value={ forceEmpty ? '' : title }
20
22
  help={ __(
21
23
  'Give the template a title that indicates its purpose, e.g. "Full Width".'
22
24
  ) }
23
25
  onChange={ ( newTitle ) => {
24
- setTitle( newTitle || template.slug );
26
+ if ( ! newTitle && ! forceEmpty ) {
27
+ setForceEmpty( true );
28
+ return;
29
+ }
30
+ setForceEmpty( false );
31
+ setTitle( newTitle );
25
32
  } }
33
+ onBlur={ () => setForceEmpty( false ) }
26
34
  />
27
35
  );
28
36
  }
@@ -1,8 +1,7 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { useMemo } from '@wordpress/element';
5
- import { sprintf, __ } from '@wordpress/i18n';
4
+ import { __ } from '@wordpress/i18n';
6
5
  import {
7
6
  Button,
8
7
  MenuGroup,
@@ -17,10 +16,6 @@ import { store as editorStore } from '@wordpress/editor';
17
16
  * Internal dependencies
18
17
  */
19
18
  import isTemplateRevertable from '../../utils/is-template-revertable';
20
- import {
21
- MENU_TEMPLATES,
22
- TEMPLATE_PARTS_SUB_MENUS,
23
- } from '../navigation-sidebar/navigation-panel/constants';
24
19
  import { store as editSiteStore } from '../../store';
25
20
  import TemplateAreas from './template-areas';
26
21
  import EditTemplateTitle from './edit-template-title';
@@ -34,16 +29,6 @@ export default function TemplateDetails( { template, onClose } ) {
34
29
  );
35
30
  const { revertTemplate } = useDispatch( editSiteStore );
36
31
 
37
- const templateSubMenu = useMemo( () => {
38
- if ( template?.type === 'wp_template' ) {
39
- return { title: __( 'templates' ), menu: MENU_TEMPLATES };
40
- }
41
-
42
- return TEMPLATE_PARTS_SUB_MENUS.find(
43
- ( { area } ) => area === template?.area
44
- );
45
- }, [ template ] );
46
-
47
32
  const browseAllLinkProps = useLink( {
48
33
  // TODO: We should update this to filter by template part's areas as well.
49
34
  postType: template.type,
@@ -106,11 +91,9 @@ export default function TemplateDetails( { template, onClose } ) {
106
91
  className="edit-site-template-details__show-all-button"
107
92
  { ...browseAllLinkProps }
108
93
  >
109
- { sprintf(
110
- /* translators: the template part's area name ("Headers", "Sidebars") or "templates". */
111
- __( 'Browse all %s' ),
112
- templateSubMenu.title
113
- ) }
94
+ { template?.type === 'wp_template'
95
+ ? __( 'Browse all templates' )
96
+ : __( 'Browse all template parts' ) }
114
97
  </Button>
115
98
  </div>
116
99
  );
@@ -0,0 +1,38 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import * as wpHooks from '@wordpress/hooks';
5
+ /**
6
+ * Internal dependencies
7
+ */
8
+ import ErrorBoundary from '../error-boundary';
9
+ /**
10
+ * External dependencies
11
+ */
12
+ import { render } from '@testing-library/react';
13
+
14
+ const theError = new Error( 'Kaboom' );
15
+
16
+ const ChildComponent = () => {
17
+ throw theError;
18
+ };
19
+
20
+ describe( 'Error Boundary', () => {
21
+ describe( 'when error is thrown from a Child component', () => {
22
+ it( 'calls the `editor.ErrorBoundary.errorLogged` hook action with the error object', () => {
23
+ const doAction = jest.spyOn( wpHooks, 'doAction' );
24
+
25
+ render(
26
+ <ErrorBoundary>
27
+ <ChildComponent />
28
+ </ErrorBoundary>
29
+ );
30
+
31
+ expect( doAction ).toHaveBeenCalledWith(
32
+ 'editor.ErrorBoundary.errorLogged',
33
+ theError
34
+ );
35
+ expect( console ).toHaveErrored();
36
+ } );
37
+ } );
38
+ } );
@@ -2,3 +2,4 @@
2
2
  * Internal dependencies
3
3
  */
4
4
  import './components';
5
+ import './template-part-edit';
@@ -0,0 +1,82 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+ import { useSelect } from '@wordpress/data';
6
+ import { BlockControls } from '@wordpress/block-editor';
7
+ import { store as coreStore } from '@wordpress/core-data';
8
+ import { ToolbarButton } from '@wordpress/components';
9
+ import { addFilter } from '@wordpress/hooks';
10
+ import { createHigherOrderComponent } from '@wordpress/compose';
11
+
12
+ /**
13
+ * Internal dependencies
14
+ */
15
+ import { useLocation } from '../components/routes';
16
+ import { useLink } from '../components/routes/link';
17
+
18
+ function EditTemplatePartMenuItem( { attributes } ) {
19
+ const { theme, slug } = attributes;
20
+ const { params } = useLocation();
21
+ const templatePart = useSelect(
22
+ ( select ) => {
23
+ return select( coreStore ).getEntityRecord(
24
+ 'postType',
25
+ 'wp_template_part',
26
+ // Ideally this should be an official public API.
27
+ `${ theme }//${ slug }`
28
+ );
29
+ },
30
+ [ theme, slug ]
31
+ );
32
+
33
+ const linkProps = useLink(
34
+ {
35
+ postId: templatePart?.id,
36
+ postType: templatePart?.type,
37
+ },
38
+ {
39
+ fromTemplateId: params.postId,
40
+ }
41
+ );
42
+
43
+ if ( ! templatePart ) {
44
+ return null;
45
+ }
46
+
47
+ return (
48
+ <BlockControls group="other">
49
+ <ToolbarButton
50
+ { ...linkProps }
51
+ onClick={ ( event ) => {
52
+ linkProps.onClick( event );
53
+ } }
54
+ >
55
+ { __( 'Edit' ) }
56
+ </ToolbarButton>
57
+ </BlockControls>
58
+ );
59
+ }
60
+
61
+ export const withEditBlockControls = createHigherOrderComponent(
62
+ ( BlockEdit ) => ( props ) => {
63
+ const { attributes, name } = props;
64
+ const isDisplayed = name === 'core/template-part' && attributes.slug;
65
+
66
+ return (
67
+ <>
68
+ <BlockEdit { ...props } />
69
+ { isDisplayed && (
70
+ <EditTemplatePartMenuItem attributes={ attributes } />
71
+ ) }
72
+ </>
73
+ );
74
+ },
75
+ 'withEditBlockControls'
76
+ );
77
+
78
+ addFilter(
79
+ 'editor.BlockEdit',
80
+ 'core/edit-site/template-part-edit-button',
81
+ withEditBlockControls
82
+ );
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { map, keyBy } from 'lodash';
4
+ import { map } from 'lodash';
5
5
  import createSelector from 'rememo';
6
6
 
7
7
  /**
@@ -341,10 +341,16 @@ export const getCurrentTemplateTemplateParts = createRegistrySelector(
341
341
  'wp_template_part',
342
342
  { per_page: -1 }
343
343
  );
344
- const templatePartsById = keyBy(
345
- templateParts,
346
- ( templatePart ) => templatePart.id
347
- );
344
+ const templatePartsById = templateParts
345
+ ? // Key template parts by their ID.
346
+ templateParts.reduce(
347
+ ( newTemplateParts, part ) => ( {
348
+ ...newTemplateParts,
349
+ [ part.id ]: part,
350
+ } ),
351
+ {}
352
+ )
353
+ : {};
348
354
 
349
355
  return ( template.blocks ?? [] )
350
356
  .filter( ( block ) => isTemplatePart( block ) )