@wordpress/edit-site 4.9.0 → 4.10.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 (105) hide show
  1. package/CHANGELOG.md +2 -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 +92 -53
  5. package/build/components/add-new-template/add-custom-template-modal.js.map +1 -1
  6. package/build/components/add-new-template/new-template.js +77 -81
  7. package/build/components/add-new-template/new-template.js.map +1 -1
  8. package/build/components/add-new-template/utils.js +310 -44
  9. package/build/components/add-new-template/utils.js.map +1 -1
  10. package/build/components/code-editor/index.js +17 -4
  11. package/build/components/code-editor/index.js.map +1 -1
  12. package/build/components/editor/index.js +16 -0
  13. package/build/components/editor/index.js.map +1 -1
  14. package/build/components/error-boundary/index.js +6 -0
  15. package/build/components/error-boundary/index.js.map +1 -1
  16. package/build/components/global-styles/dimensions-panel.js +2 -6
  17. package/build/components/global-styles/dimensions-panel.js.map +1 -1
  18. package/build/components/global-styles/global-styles-provider.js +4 -2
  19. package/build/components/global-styles/global-styles-provider.js.map +1 -1
  20. package/build/components/global-styles/hooks.js +10 -1
  21. package/build/components/global-styles/hooks.js.map +1 -1
  22. package/build/components/global-styles/screen-color-palette.js +13 -17
  23. package/build/components/global-styles/screen-color-palette.js.map +1 -1
  24. package/build/components/global-styles/screen-colors.js +9 -1
  25. package/build/components/global-styles/screen-colors.js.map +1 -1
  26. package/build/components/global-styles/screen-link-color.js +48 -14
  27. package/build/components/global-styles/screen-link-color.js.map +1 -1
  28. package/build/components/global-styles/use-global-styles-output.js +171 -33
  29. package/build/components/global-styles/use-global-styles-output.js.map +1 -1
  30. package/build/components/global-styles/utils.js +1 -1
  31. package/build/components/global-styles/utils.js.map +1 -1
  32. package/build/components/keyboard-shortcut-help-modal/index.js +1 -3
  33. package/build/components/keyboard-shortcut-help-modal/index.js.map +1 -1
  34. package/build/components/template-details/edit-template-title.js +11 -3
  35. package/build/components/template-details/edit-template-title.js.map +1 -1
  36. package/build/components/template-details/index.js +1 -20
  37. package/build/components/template-details/index.js.map +1 -1
  38. package/build/store/selectors.js +4 -1
  39. package/build/store/selectors.js.map +1 -1
  40. package/build-module/components/add-new-template/add-custom-generic-template-modal.js +77 -0
  41. package/build-module/components/add-new-template/add-custom-generic-template-modal.js.map +1 -0
  42. package/build-module/components/add-new-template/add-custom-template-modal.js +92 -53
  43. package/build-module/components/add-new-template/add-custom-template-modal.js.map +1 -1
  44. package/build-module/components/add-new-template/new-template.js +80 -83
  45. package/build-module/components/add-new-template/new-template.js.map +1 -1
  46. package/build-module/components/add-new-template/utils.js +286 -40
  47. package/build-module/components/add-new-template/utils.js.map +1 -1
  48. package/build-module/components/code-editor/index.js +18 -5
  49. package/build-module/components/code-editor/index.js.map +1 -1
  50. package/build-module/components/editor/index.js +16 -0
  51. package/build-module/components/editor/index.js.map +1 -1
  52. package/build-module/components/error-boundary/index.js +5 -0
  53. package/build-module/components/error-boundary/index.js.map +1 -1
  54. package/build-module/components/global-styles/dimensions-panel.js +2 -6
  55. package/build-module/components/global-styles/dimensions-panel.js.map +1 -1
  56. package/build-module/components/global-styles/global-styles-provider.js +4 -2
  57. package/build-module/components/global-styles/global-styles-provider.js.map +1 -1
  58. package/build-module/components/global-styles/hooks.js +10 -1
  59. package/build-module/components/global-styles/hooks.js.map +1 -1
  60. package/build-module/components/global-styles/screen-color-palette.js +14 -19
  61. package/build-module/components/global-styles/screen-color-palette.js.map +1 -1
  62. package/build-module/components/global-styles/screen-colors.js +9 -1
  63. package/build-module/components/global-styles/screen-colors.js.map +1 -1
  64. package/build-module/components/global-styles/screen-link-color.js +47 -14
  65. package/build-module/components/global-styles/screen-link-color.js.map +1 -1
  66. package/build-module/components/global-styles/use-global-styles-output.js +171 -35
  67. package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
  68. package/build-module/components/global-styles/utils.js +2 -2
  69. package/build-module/components/global-styles/utils.js.map +1 -1
  70. package/build-module/components/keyboard-shortcut-help-modal/index.js +1 -2
  71. package/build-module/components/keyboard-shortcut-help-modal/index.js.map +1 -1
  72. package/build-module/components/template-details/edit-template-title.js +12 -3
  73. package/build-module/components/template-details/edit-template-title.js.map +1 -1
  74. package/build-module/components/template-details/index.js +2 -21
  75. package/build-module/components/template-details/index.js.map +1 -1
  76. package/build-module/store/selectors.js +5 -2
  77. package/build-module/store/selectors.js.map +1 -1
  78. package/build-style/style-rtl.css +21 -23
  79. package/build-style/style.css +21 -23
  80. package/package.json +29 -29
  81. package/src/components/add-new-template/add-custom-generic-template-modal.js +97 -0
  82. package/src/components/add-new-template/add-custom-template-modal.js +92 -58
  83. package/src/components/add-new-template/new-template.js +142 -94
  84. package/src/components/add-new-template/style.scss +21 -0
  85. package/src/components/add-new-template/utils.js +290 -46
  86. package/src/components/code-editor/index.js +15 -5
  87. package/src/components/editor/index.js +11 -0
  88. package/src/components/error-boundary/index.js +5 -0
  89. package/src/components/global-styles/dimensions-panel.js +2 -7
  90. package/src/components/global-styles/global-styles-provider.js +8 -9
  91. package/src/components/global-styles/hooks.js +15 -0
  92. package/src/components/global-styles/screen-color-palette.js +25 -27
  93. package/src/components/global-styles/screen-colors.js +9 -3
  94. package/src/components/global-styles/screen-link-color.js +65 -23
  95. package/src/components/global-styles/style.scss +7 -11
  96. package/src/components/global-styles/test/use-global-styles-output.js +168 -0
  97. package/src/components/global-styles/use-global-styles-output.js +234 -59
  98. package/src/components/global-styles/utils.js +2 -2
  99. package/src/components/keyboard-shortcut-help-modal/index.js +1 -2
  100. package/src/components/keyboard-shortcut-help-modal/style.scss +0 -5
  101. package/src/components/list/style.scss +0 -8
  102. package/src/components/template-details/edit-template-title.js +10 -2
  103. package/src/components/template-details/index.js +4 -21
  104. package/src/components/test/error-boundary.js +38 -0
  105. package/src/store/selectors.js +11 -5
@@ -1,8 +1,3 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { filter, includes } from 'lodash';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
@@ -13,9 +8,8 @@ import {
13
8
  NavigableMenu,
14
9
  } from '@wordpress/components';
15
10
  import { useState } from '@wordpress/element';
16
- import { useSelect, useDispatch } from '@wordpress/data';
11
+ import { useDispatch } from '@wordpress/data';
17
12
  import { store as coreStore } from '@wordpress/core-data';
18
- import { store as editorStore } from '@wordpress/editor';
19
13
  import {
20
14
  archive,
21
15
  blockMeta,
@@ -30,15 +24,27 @@ import {
30
24
  postDate,
31
25
  search,
32
26
  tag,
27
+ layout as customGenericTemplateIcon,
33
28
  } from '@wordpress/icons';
34
- import { __, sprintf } from '@wordpress/i18n';
29
+ import { __ } from '@wordpress/i18n';
35
30
  import { store as noticesStore } from '@wordpress/notices';
36
31
 
37
32
  /**
38
33
  * Internal dependencies
39
34
  */
40
35
  import AddCustomTemplateModal from './add-custom-template-modal';
41
- import { usePostTypes, usePostTypesEntitiesInfo } from './utils';
36
+ import {
37
+ useExistingTemplates,
38
+ useDefaultTemplateTypes,
39
+ entitiesConfig,
40
+ usePostTypes,
41
+ usePostTypePage,
42
+ useTaxonomies,
43
+ useTaxonomyCategory,
44
+ useTaxonomyTag,
45
+ useExtraTemplates,
46
+ } from './utils';
47
+ import AddCustomGenericTemplateModal from './add-custom-generic-template-modal';
42
48
  import { useHistory } from '../routes';
43
49
  import { store as editSiteStore } from '../../store';
44
50
 
@@ -74,29 +80,20 @@ const TEMPLATE_ICONS = {
74
80
  };
75
81
 
76
82
  export default function NewTemplate( { postType } ) {
77
- const history = useHistory();
78
- const postTypes = usePostTypes();
79
83
  const [ showCustomTemplateModal, setShowCustomTemplateModal ] =
80
84
  useState( false );
85
+ const [
86
+ showCustomGenericTemplateModal,
87
+ setShowCustomGenericTemplateModal,
88
+ ] = useState( false );
81
89
  const [ entityForSuggestions, setEntityForSuggestions ] = useState( {} );
82
- const { existingTemplates, defaultTemplateTypes } = useSelect(
83
- ( select ) => ( {
84
- existingTemplates: select( coreStore ).getEntityRecords(
85
- 'postType',
86
- 'wp_template',
87
- { per_page: -1 }
88
- ),
89
- defaultTemplateTypes:
90
- select( editorStore ).__experimentalGetDefaultTemplateTypes(),
91
- } ),
92
- []
93
- );
94
- const postTypesEntitiesInfo = usePostTypesEntitiesInfo( existingTemplates );
90
+
91
+ const history = useHistory();
95
92
  const { saveEntityRecord } = useDispatch( coreStore );
96
93
  const { createErrorNotice } = useDispatch( noticesStore );
97
94
  const { setTemplate } = useDispatch( editSiteStore );
98
95
 
99
- async function createTemplate( template ) {
96
+ async function createTemplate( template, isWPSuggestion = true ) {
100
97
  try {
101
98
  const { title, description, slug } = template;
102
99
  const newTemplate = await saveEntityRecord(
@@ -109,7 +106,7 @@ export default function NewTemplate( { postType } ) {
109
106
  status: 'publish',
110
107
  title,
111
108
  // This adds a post meta field in template that is part of `is_custom` value calculation.
112
- is_wp_suggestion: true,
109
+ is_wp_suggestion: isWPSuggestion,
113
110
  },
114
111
  { throwOnError: true }
115
112
  );
@@ -135,78 +132,14 @@ export default function NewTemplate( { postType } ) {
135
132
  } );
136
133
  }
137
134
  }
138
- const existingTemplateSlugs = ( existingTemplates || [] ).map(
139
- ( { slug } ) => slug
140
- );
141
- const missingTemplates = filter(
142
- defaultTemplateTypes,
143
- ( template ) =>
144
- includes( DEFAULT_TEMPLATE_SLUGS, template.slug ) &&
145
- ! includes( existingTemplateSlugs, template.slug )
146
- );
147
135
 
148
- const extraTemplates = ( postTypes || [] ).reduce(
149
- ( accumulator, _postType ) => {
150
- const { slug, labels, icon } = _postType;
151
- const hasGeneralTemplate = existingTemplateSlugs?.includes(
152
- `single-${ slug }`
153
- );
154
- const hasEntities = postTypesEntitiesInfo?.[ slug ]?.hasEntities;
155
- const menuItem = {
156
- slug: `single-${ slug }`,
157
- title: sprintf(
158
- // translators: %s: Name of the post type e.g: "Post".
159
- __( 'Single item: %s' ),
160
- labels.singular_name
161
- ),
162
- description: sprintf(
163
- // translators: %s: Name of the post type e.g: "Post".
164
- __( 'Displays a single item: %s.' ),
165
- labels.singular_name
166
- ),
167
- // `icon` is the `menu_icon` property of a post type. We
168
- // only handle `dashicons` for now, even if the `menu_icon`
169
- // also supports urls and svg as values.
170
- icon: icon?.startsWith( 'dashicons-' )
171
- ? icon.slice( 10 )
172
- : null,
173
- };
174
- // We have a different template creation flow only if they have entities.
175
- if ( hasEntities ) {
176
- menuItem.onClick = ( template ) => {
177
- setShowCustomTemplateModal( true );
178
- setEntityForSuggestions( {
179
- type: 'postType',
180
- slug,
181
- labels,
182
- hasGeneralTemplate,
183
- template,
184
- postsToExclude:
185
- postTypesEntitiesInfo[ slug ].existingPosts,
186
- } );
187
- };
188
- }
189
- // We don't need to add the menu item if there are no
190
- // entities and the general template exists.
191
- if ( ! hasGeneralTemplate || hasEntities ) {
192
- accumulator.push( menuItem );
193
- }
194
- return accumulator;
195
- },
196
- []
136
+ const missingTemplates = useMissingTemplates(
137
+ setEntityForSuggestions,
138
+ setShowCustomTemplateModal
197
139
  );
198
- if ( ! missingTemplates.length && ! extraTemplates.length ) {
140
+ if ( ! missingTemplates.length ) {
199
141
  return null;
200
142
  }
201
- // Update the sort order to match the DEFAULT_TEMPLATE_SLUGS order.
202
- missingTemplates?.sort( ( template1, template2 ) => {
203
- return (
204
- DEFAULT_TEMPLATE_SLUGS.indexOf( template1.slug ) -
205
- DEFAULT_TEMPLATE_SLUGS.indexOf( template2.slug )
206
- );
207
- } );
208
- // Append all extra templates at the end of the list for now.
209
- missingTemplates.push( ...extraTemplates );
210
143
  return (
211
144
  <>
212
145
  <DropdownMenu
@@ -253,6 +186,21 @@ export default function NewTemplate( { postType } ) {
253
186
  );
254
187
  } ) }
255
188
  </MenuGroup>
189
+ <MenuGroup>
190
+ <MenuItem
191
+ icon={ customGenericTemplateIcon }
192
+ iconPosition="left"
193
+ info={ __(
194
+ 'Custom templates can be applied to any post or page.'
195
+ ) }
196
+ key="custom-template"
197
+ onClick={ () =>
198
+ setShowCustomGenericTemplateModal( true )
199
+ }
200
+ >
201
+ { __( 'Custom template' ) }
202
+ </MenuItem>
203
+ </MenuGroup>
256
204
  </NavigableMenu>
257
205
  ) }
258
206
  </DropdownMenu>
@@ -263,6 +211,106 @@ export default function NewTemplate( { postType } ) {
263
211
  entityForSuggestions={ entityForSuggestions }
264
212
  />
265
213
  ) }
214
+ { showCustomGenericTemplateModal && (
215
+ <AddCustomGenericTemplateModal
216
+ onClose={ () => setShowCustomGenericTemplateModal( false ) }
217
+ createTemplate={ createTemplate }
218
+ />
219
+ ) }
266
220
  </>
267
221
  );
268
222
  }
223
+
224
+ function useMissingTemplates(
225
+ setEntityForSuggestions,
226
+ setShowCustomTemplateModal
227
+ ) {
228
+ const postTypes = usePostTypes();
229
+ const pagePostType = usePostTypePage();
230
+ const taxonomies = useTaxonomies();
231
+ const categoryTaxonomy = useTaxonomyCategory();
232
+ const tagTaxonomy = useTaxonomyTag();
233
+
234
+ const existingTemplates = useExistingTemplates();
235
+ const defaultTemplateTypes = useDefaultTemplateTypes();
236
+
237
+ const existingTemplateSlugs = ( existingTemplates || [] ).map(
238
+ ( { slug } ) => slug
239
+ );
240
+
241
+ const missingDefaultTemplates = ( defaultTemplateTypes || [] ).filter(
242
+ ( template ) =>
243
+ DEFAULT_TEMPLATE_SLUGS.includes( template.slug ) &&
244
+ ! existingTemplateSlugs.includes( template.slug )
245
+ );
246
+ const onClickMenuItem = ( _entityForSuggestions ) => {
247
+ setShowCustomTemplateModal( true );
248
+ setEntityForSuggestions( _entityForSuggestions );
249
+ };
250
+ // TODO: find better names for these variables. `useExtraTemplates` returns an array of items.
251
+ const categoryMenuItem = useExtraTemplates(
252
+ categoryTaxonomy,
253
+ entitiesConfig.category,
254
+ onClickMenuItem
255
+ );
256
+ const tagMenuItem = useExtraTemplates(
257
+ tagTaxonomy,
258
+ entitiesConfig.tag,
259
+ onClickMenuItem
260
+ );
261
+ const pageMenuItem = useExtraTemplates(
262
+ pagePostType,
263
+ entitiesConfig.page,
264
+ onClickMenuItem
265
+ );
266
+ // We need to replace existing default template types with
267
+ // the create specific template functionality. The original
268
+ // info (title, description, etc.) is preserved in the
269
+ // `useExtraTemplates` hook.
270
+ const enhancedMissingDefaultTemplateTypes = [ ...missingDefaultTemplates ];
271
+ [ categoryMenuItem, tagMenuItem, pageMenuItem ].forEach( ( menuItem ) => {
272
+ if ( ! menuItem?.length ) {
273
+ return;
274
+ }
275
+ const matchIndex = enhancedMissingDefaultTemplateTypes.findIndex(
276
+ ( template ) => template.slug === menuItem[ 0 ].slug
277
+ );
278
+ // Some default template types might have been filtered above from
279
+ // `missingDefaultTemplates` because they only check for the general
280
+ // template. So here we either replace or append the item, augmented
281
+ // with the check if it has available specific item to create a
282
+ // template for.
283
+ if ( matchIndex > -1 ) {
284
+ enhancedMissingDefaultTemplateTypes.splice(
285
+ matchIndex,
286
+ 1,
287
+ menuItem[ 0 ]
288
+ );
289
+ } else {
290
+ enhancedMissingDefaultTemplateTypes.push( menuItem[ 0 ] );
291
+ }
292
+ } );
293
+ // Update the sort order to match the DEFAULT_TEMPLATE_SLUGS order.
294
+ enhancedMissingDefaultTemplateTypes?.sort( ( template1, template2 ) => {
295
+ return (
296
+ DEFAULT_TEMPLATE_SLUGS.indexOf( template1.slug ) -
297
+ DEFAULT_TEMPLATE_SLUGS.indexOf( template2.slug )
298
+ );
299
+ } );
300
+ const extraPostTypeTemplates = useExtraTemplates(
301
+ postTypes,
302
+ entitiesConfig.postType,
303
+ onClickMenuItem
304
+ );
305
+ const extraTaxonomyTemplates = useExtraTemplates(
306
+ taxonomies,
307
+ entitiesConfig.taxonomy,
308
+ onClickMenuItem
309
+ );
310
+ const missingTemplates = [
311
+ ...enhancedMissingDefaultTemplateTypes,
312
+ ...extraPostTypeTemplates,
313
+ ...extraTaxonomyTemplates,
314
+ ];
315
+ return missingTemplates;
316
+ }
@@ -125,3 +125,24 @@
125
125
  margin-bottom: 0;
126
126
  margin-top: $grid-unit-20;
127
127
  }
128
+
129
+
130
+ .edit-site-custom-generic-template__modal {
131
+ .components-base-control {
132
+ @include break-medium() {
133
+ width: $grid-unit * 40;
134
+ }
135
+ }
136
+
137
+ .components-modal__header {
138
+ border-bottom: none;
139
+ }
140
+
141
+ .components-modal__content::before {
142
+ margin-bottom: $grid-unit-05;
143
+ }
144
+ }
145
+
146
+ .edit-site-custom-generic-template__modal-actions {
147
+ margin-top: $grid-unit-15;
148
+ }