@wordpress/edit-site 6.25.0 → 6.26.1-next.719a03cbe.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 (43) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/add-new-template/add-custom-generic-template-modal-content.js +13 -6
  3. package/build/components/add-new-template/add-custom-generic-template-modal-content.js.map +1 -1
  4. package/build/components/add-new-template/add-custom-template-modal-content.js +37 -1
  5. package/build/components/add-new-template/add-custom-template-modal-content.js.map +1 -1
  6. package/build/components/add-new-template/index.js +16 -3
  7. package/build/components/add-new-template/index.js.map +1 -1
  8. package/build/components/add-new-template/utils.js +1 -1
  9. package/build/components/add-new-template/utils.js.map +1 -1
  10. package/build/components/global-styles/font-sizes/font-sizes.js +1 -2
  11. package/build/components/global-styles/font-sizes/font-sizes.js.map +1 -1
  12. package/build/components/global-styles/shadows-edit-panel.js +3 -7
  13. package/build/components/global-styles/shadows-edit-panel.js.map +1 -1
  14. package/build/components/style-book/index.js +61 -13
  15. package/build/components/style-book/index.js.map +1 -1
  16. package/build-module/components/add-new-template/add-custom-generic-template-modal-content.js +14 -7
  17. package/build-module/components/add-new-template/add-custom-generic-template-modal-content.js.map +1 -1
  18. package/build-module/components/add-new-template/add-custom-template-modal-content.js +37 -1
  19. package/build-module/components/add-new-template/add-custom-template-modal-content.js.map +1 -1
  20. package/build-module/components/add-new-template/index.js +17 -4
  21. package/build-module/components/add-new-template/index.js.map +1 -1
  22. package/build-module/components/add-new-template/utils.js +1 -1
  23. package/build-module/components/add-new-template/utils.js.map +1 -1
  24. package/build-module/components/global-styles/font-sizes/font-sizes.js +1 -2
  25. package/build-module/components/global-styles/font-sizes/font-sizes.js.map +1 -1
  26. package/build-module/components/global-styles/shadows-edit-panel.js +3 -7
  27. package/build-module/components/global-styles/shadows-edit-panel.js.map +1 -1
  28. package/build-module/components/style-book/index.js +61 -13
  29. package/build-module/components/style-book/index.js.map +1 -1
  30. package/build-style/posts-rtl.css +313 -19
  31. package/build-style/posts.css +313 -19
  32. package/build-style/style-rtl.css +315 -20
  33. package/build-style/style.css +315 -20
  34. package/package.json +42 -42
  35. package/src/components/add-new-template/add-custom-generic-template-modal-content.js +14 -6
  36. package/src/components/add-new-template/add-custom-template-modal-content.js +45 -1
  37. package/src/components/add-new-template/index.js +25 -3
  38. package/src/components/add-new-template/utils.js +1 -1
  39. package/src/components/global-styles/font-sizes/font-sizes.js +2 -2
  40. package/src/components/global-styles/shadows-edit-panel.js +1 -6
  41. package/src/components/global-styles/style.scss +2 -1
  42. package/src/components/style-book/index.js +76 -13
  43. package/tsconfig.tsbuildinfo +1 -1
@@ -16,6 +16,7 @@ import {
16
16
  import { useEntityRecords } from '@wordpress/core-data';
17
17
  import { decodeEntities } from '@wordpress/html-entities';
18
18
  import { useDebouncedInput } from '@wordpress/compose';
19
+ import { focus } from '@wordpress/dom';
19
20
 
20
21
  /**
21
22
  * Internal dependencies
@@ -165,10 +166,27 @@ function SuggestionList( { entityForSuggestions, onSelect } ) {
165
166
  );
166
167
  }
167
168
 
168
- function AddCustomTemplateModalContent( { onSelect, entityForSuggestions } ) {
169
+ function AddCustomTemplateModalContent( {
170
+ onSelect,
171
+ entityForSuggestions,
172
+ onBack,
173
+ containerRef,
174
+ } ) {
169
175
  const [ showSearchEntities, setShowSearchEntities ] = useState(
170
176
  entityForSuggestions.hasGeneralTemplate
171
177
  );
178
+
179
+ // Focus on the first focusable element when the modal opens.
180
+ // We handle focus management in the parent modal, just need to focus on the first focusable element.
181
+ useEffect( () => {
182
+ if ( containerRef.current ) {
183
+ const [ firstFocusable ] = focus.focusable.find(
184
+ containerRef.current
185
+ );
186
+ firstFocusable?.focus();
187
+ }
188
+ }, [ showSearchEntities ] );
189
+
172
190
  return (
173
191
  <VStack
174
192
  spacing={ 4 }
@@ -247,6 +265,15 @@ function AddCustomTemplateModalContent( { onSelect, entityForSuggestions } ) {
247
265
  </Text>
248
266
  </FlexItem>
249
267
  </Flex>
268
+ <Flex justify="right">
269
+ <Button
270
+ __next40pxDefaultSize
271
+ variant="tertiary"
272
+ onClick={ onBack }
273
+ >
274
+ { __( 'Back' ) }
275
+ </Button>
276
+ </Flex>
250
277
  </>
251
278
  ) }
252
279
  { showSearchEntities && (
@@ -260,6 +287,23 @@ function AddCustomTemplateModalContent( { onSelect, entityForSuggestions } ) {
260
287
  entityForSuggestions={ entityForSuggestions }
261
288
  onSelect={ onSelect }
262
289
  />
290
+ <Flex justify="right">
291
+ <Button
292
+ __next40pxDefaultSize
293
+ variant="tertiary"
294
+ onClick={ () => {
295
+ // If general template exists, go directly back to main screen
296
+ // instead of showing the choice screen
297
+ if ( entityForSuggestions.hasGeneralTemplate ) {
298
+ onBack();
299
+ } else {
300
+ setShowSearchEntities( false );
301
+ }
302
+ } }
303
+ >
304
+ { __( 'Back' ) }
305
+ </Button>
306
+ </Flex>
263
307
  </>
264
308
  ) }
265
309
  </VStack>
@@ -16,7 +16,7 @@ import {
16
16
  Icon,
17
17
  } from '@wordpress/components';
18
18
  import { decodeEntities } from '@wordpress/html-entities';
19
- import { useState, memo } from '@wordpress/element';
19
+ import { useState, memo, useRef, useEffect } from '@wordpress/element';
20
20
  import { useSelect, useDispatch } from '@wordpress/data';
21
21
  import { store as coreStore } from '@wordpress/core-data';
22
22
  import { useViewportMatch } from '@wordpress/compose';
@@ -41,6 +41,7 @@ import {
41
41
  import { __, sprintf } from '@wordpress/i18n';
42
42
  import { store as noticesStore } from '@wordpress/notices';
43
43
  import { privateApis as routerPrivateApis } from '@wordpress/router';
44
+ import { focus } from '@wordpress/dom';
44
45
 
45
46
  /**
46
47
  * Internal dependencies
@@ -162,7 +163,7 @@ function NewTemplateModal( { onClose } ) {
162
163
  const { saveEntityRecord } = useDispatch( coreStore );
163
164
  const { createErrorNotice, createSuccessNotice } =
164
165
  useDispatch( noticesStore );
165
-
166
+ const containerRef = useRef( null );
166
167
  const isMobile = useViewportMatch( 'medium', '<' );
167
168
 
168
169
  const homeUrl = useSelect( ( select ) => {
@@ -180,6 +181,20 @@ function NewTemplateModal( { onClose } ) {
180
181
  ),
181
182
  };
182
183
 
184
+ useEffect( () => {
185
+ // Focus the first focusable element when component mounts or UI changes
186
+ // We don't want to focus on the other modals because they have their own focus management.
187
+ if (
188
+ containerRef.current &&
189
+ modalContent === modalContentMap.templatesList
190
+ ) {
191
+ const [ firstFocusable ] = focus.focusable.find(
192
+ containerRef.current
193
+ );
194
+ firstFocusable?.focus();
195
+ }
196
+ }, [ modalContent ] );
197
+
183
198
  async function createTemplate( template, isWPSuggestion = true ) {
184
199
  if ( isSubmitting ) {
185
200
  return;
@@ -261,6 +276,7 @@ function NewTemplateModal( { onClose } ) {
261
276
  ? 'edit-site-custom-generic-template__modal'
262
277
  : undefined
263
278
  }
279
+ ref={ containerRef }
264
280
  >
265
281
  { modalContent === modalContentMap.templatesList && (
266
282
  <Grid
@@ -320,12 +336,18 @@ function NewTemplateModal( { onClose } ) {
320
336
  <AddCustomTemplateModalContent
321
337
  onSelect={ createTemplate }
322
338
  entityForSuggestions={ entityForSuggestions }
339
+ onBack={ () =>
340
+ setModalContent( modalContentMap.templatesList )
341
+ }
342
+ containerRef={ containerRef }
323
343
  />
324
344
  ) }
325
345
  { modalContent === modalContentMap.customGenericTemplate && (
326
346
  <AddCustomGenericTemplateModalContent
327
- onClose={ onModalClose }
328
347
  createTemplate={ createTemplate }
348
+ onBack={ () =>
349
+ setModalContent( modalContentMap.templatesList )
350
+ }
329
351
  />
330
352
  ) }
331
353
  </Modal>
@@ -412,7 +412,7 @@ export const useTaxonomiesMenuItems = ( onClickMenuItem ) => {
412
412
  if ( _needsUniqueIdentifier ) {
413
413
  menuItemTitle = labels.template_name
414
414
  ? sprintf(
415
- // translators: 1: Name of the template e.g: "Products by Category". 2s: Slug of the taxonomy e.g: "product_cat".
415
+ // translators: 1: Name of the template e.g: "Products by Category". 2: Slug of the taxonomy e.g: "product_cat".
416
416
  _x( '%1$s (%2$s)', 'taxonomy template menu label' ),
417
417
  labels.template_name,
418
418
  slug
@@ -69,9 +69,9 @@ function FontSizeGroup( {
69
69
  />
70
70
  ) }
71
71
  <VStack spacing={ 4 }>
72
- <HStack justify="space-between" align="center">
72
+ <HStack>
73
73
  <Subtitle level={ 3 }>{ label }</Subtitle>
74
- <FlexItem>
74
+ <FlexItem className="edit-site-global-styles__typography-panel__options-container">
75
75
  { origin === 'custom' && (
76
76
  <Button
77
77
  label={ __( 'Add font size' ) }
@@ -327,12 +327,7 @@ function ShadowEditor( { shadow, onChange } ) {
327
327
  <>
328
328
  <VStack spacing={ 2 }>
329
329
  <HStack justify="space-between">
330
- <Flex
331
- align="center"
332
- className="edit-site-global-styles__shadows-panel__title"
333
- >
334
- <Subtitle level={ 3 }>{ __( 'Shadows' ) }</Subtitle>
335
- </Flex>
330
+ <Subtitle level={ 3 }>{ __( 'Shadows' ) }</Subtitle>
336
331
  <FlexItem className="edit-site-global-styles__shadows-panel__options-container">
337
332
  <Button
338
333
  size="small"
@@ -104,7 +104,8 @@
104
104
  flex-shrink: 0;
105
105
  }
106
106
 
107
- .edit-site-global-styles__shadows-panel__options-container {
107
+ .edit-site-global-styles__shadows-panel__options-container,
108
+ .edit-site-global-styles__typography-panel__options-container {
108
109
  height: $grid-unit * 3;
109
110
  }
110
111
 
@@ -51,6 +51,7 @@ import { getExamples } from './examples';
51
51
  import { store as siteEditorStore } from '../../store';
52
52
  import { useSection } from '../sidebar-global-styles-wrapper';
53
53
  import { GlobalStylesRenderer } from '../global-styles-renderer';
54
+ import { getVariationClassName } from '../global-styles/utils';
54
55
  import {
55
56
  STYLE_BOOK_COLOR_GROUPS,
56
57
  STYLE_BOOK_PREVIEW_CATEGORIES,
@@ -215,6 +216,32 @@ export function getExamplesForSinglePageUse( examples ) {
215
216
  return examplesForSinglePageUse;
216
217
  }
217
218
 
219
+ /**
220
+ * Applies a block variation to each example by updating its attributes.
221
+ *
222
+ * @param {Array} examples Array of examples
223
+ * @param {string} variation Block variation name.
224
+ * @return {Array} Updated examples with variation applied.
225
+ */
226
+ function applyBlockVariationsToExamples( examples, variation ) {
227
+ if ( ! variation ) {
228
+ return examples;
229
+ }
230
+
231
+ return examples.map( ( example ) => ( {
232
+ ...example,
233
+ variation,
234
+ blocks: {
235
+ ...example.blocks,
236
+ attributes: {
237
+ ...example.blocks.attributes,
238
+ style: undefined,
239
+ className: getVariationClassName( variation ),
240
+ },
241
+ },
242
+ } ) );
243
+ }
244
+
218
245
  function StyleBook( {
219
246
  enableResizing = true,
220
247
  isSelected,
@@ -394,7 +421,7 @@ export const StyleBookPreview = ( { userConfig = {}, isStatic = false } ) => {
394
421
  );
395
422
  };
396
423
 
397
- const onSelect = ( blockName ) => {
424
+ const onSelect = ( blockName, isBlockVariation = false ) => {
398
425
  if (
399
426
  STYLE_BOOK_COLOR_GROUPS.find(
400
427
  ( group ) => group.slug === blockName
@@ -410,6 +437,10 @@ export const StyleBookPreview = ( { userConfig = {}, isStatic = false } ) => {
410
437
  return;
411
438
  }
412
439
 
440
+ if ( isBlockVariation ) {
441
+ return;
442
+ }
443
+
413
444
  // Now go to the selected block.
414
445
  onChangeSection( `/blocks/${ encodeURIComponent( blockName ) }` );
415
446
  };
@@ -419,14 +450,20 @@ export const StyleBookPreview = ( { userConfig = {}, isStatic = false } ) => {
419
450
  const examplesForSinglePageUse = getExamplesForSinglePageUse( examples );
420
451
 
421
452
  let previewCategory = null;
453
+ let blockVariation = null;
422
454
  if ( section.includes( '/colors' ) ) {
423
455
  previewCategory = 'colors';
424
456
  } else if ( section.includes( '/typography' ) ) {
425
457
  previewCategory = 'text';
426
458
  } else if ( section.includes( '/blocks' ) ) {
427
459
  previewCategory = 'blocks';
428
- const blockName =
429
- decodeURIComponent( section ).split( '/blocks/' )[ 1 ];
460
+ let blockName = decodeURIComponent( section ).split( '/blocks/' )[ 1 ];
461
+
462
+ // The blockName can contain variations, if so, extract the variation.
463
+ if ( blockName?.includes( '/variations' ) ) {
464
+ [ blockName, blockVariation ] = blockName.split( '/variations/' );
465
+ }
466
+
430
467
  if (
431
468
  blockName &&
432
469
  examples.find( ( example ) => example.name === blockName )
@@ -440,21 +477,43 @@ export const StyleBookPreview = ( { userConfig = {}, isStatic = false } ) => {
440
477
  ( category ) => category.slug === previewCategory
441
478
  );
442
479
 
443
- // If there's no category definition there may be a single block.
444
- const filteredExamples = categoryDefinition
445
- ? getExamplesByCategory( categoryDefinition, examples )
446
- : {
480
+ const filteredExamples = useMemo( () => {
481
+ // If there's no category definition there may be a single block.
482
+ if ( ! categoryDefinition ) {
483
+ return {
447
484
  examples: [
448
485
  examples.find(
449
486
  ( example ) => example.name === previewCategory
450
487
  ),
451
488
  ],
452
- };
489
+ };
490
+ }
491
+
492
+ return getExamplesByCategory( categoryDefinition, examples );
493
+ }, [ categoryDefinition, examples, previewCategory ] );
453
494
 
454
- // If there's no preview category, show all examples.
455
- const displayedExamples = previewCategory
456
- ? filteredExamples
457
- : { examples: examplesForSinglePageUse };
495
+ const displayedExamples = useMemo( () => {
496
+ // If there's no preview category, show all examples.
497
+ if ( ! previewCategory ) {
498
+ return { examples: examplesForSinglePageUse };
499
+ }
500
+
501
+ if ( blockVariation ) {
502
+ return {
503
+ examples: applyBlockVariationsToExamples(
504
+ filteredExamples.examples,
505
+ blockVariation
506
+ ),
507
+ };
508
+ }
509
+
510
+ return filteredExamples;
511
+ }, [
512
+ previewCategory,
513
+ examplesForSinglePageUse,
514
+ blockVariation,
515
+ filteredExamples,
516
+ ] );
458
517
 
459
518
  const { base: baseConfig } = useContext( GlobalStylesContext );
460
519
  const goTo = getStyleBookNavigationFromPath( section );
@@ -603,7 +662,11 @@ const Examples = memo(
603
662
  isSelected={ isSelected?.( example.name ) }
604
663
  onClick={
605
664
  !! onSelect
606
- ? () => onSelect( example.name )
665
+ ? () =>
666
+ onSelect(
667
+ example.name,
668
+ !! example.variation
669
+ )
607
670
  : null
608
671
  }
609
672
  />