@wordpress/edit-site 5.28.3 → 5.29.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 (195) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/block-editor/use-site-editor-settings.js +2 -1
  3. package/build/components/block-editor/use-site-editor-settings.js.map +1 -1
  4. package/build/components/code-editor/index.js +3 -2
  5. package/build/components/code-editor/index.js.map +1 -1
  6. package/build/components/editor/index.js +4 -4
  7. package/build/components/editor/index.js.map +1 -1
  8. package/build/components/editor-canvas-container/index.js +1 -1
  9. package/build/components/editor-canvas-container/index.js.map +1 -1
  10. package/build/components/header-edit-mode/document-tools/index.js +1 -2
  11. package/build/components/header-edit-mode/document-tools/index.js.map +1 -1
  12. package/build/components/header-edit-mode/index.js +3 -1
  13. package/build/components/header-edit-mode/index.js.map +1 -1
  14. package/build/components/header-edit-mode/more-menu/index.js +7 -4
  15. package/build/components/header-edit-mode/more-menu/index.js.map +1 -1
  16. package/build/components/keyboard-shortcuts/edit-mode.js +0 -13
  17. package/build/components/keyboard-shortcuts/edit-mode.js.map +1 -1
  18. package/build/components/keyboard-shortcuts/register.js +0 -18
  19. package/build/components/keyboard-shortcuts/register.js.map +1 -1
  20. package/build/components/layout/index.js +0 -1
  21. package/build/components/layout/index.js.map +1 -1
  22. package/build/components/page-patterns/dataviews-pattern-actions.js +25 -8
  23. package/build/components/page-patterns/dataviews-pattern-actions.js.map +1 -1
  24. package/build/components/page-patterns/header.js +2 -1
  25. package/build/components/page-patterns/header.js.map +1 -1
  26. package/build/components/page-patterns/index.js +0 -1
  27. package/build/components/page-patterns/index.js.map +1 -1
  28. package/build/components/save-button/index.js +2 -1
  29. package/build/components/save-button/index.js.map +1 -1
  30. package/build/components/sidebar/index.js +3 -2
  31. package/build/components/sidebar/index.js.map +1 -1
  32. package/build/components/sidebar-edit-mode/global-styles-sidebar.js +5 -5
  33. package/build/components/sidebar-edit-mode/global-styles-sidebar.js.map +1 -1
  34. package/build/components/sidebar-edit-mode/template-panel/hooks.js +20 -5
  35. package/build/components/sidebar-edit-mode/template-panel/hooks.js.map +1 -1
  36. package/build/components/sidebar-edit-mode/template-panel/index.js +48 -5
  37. package/build/components/sidebar-edit-mode/template-panel/index.js.map +1 -1
  38. package/build/components/sidebar-edit-mode/template-panel/template-actions.js +2 -9
  39. package/build/components/sidebar-edit-mode/template-panel/template-actions.js.map +1 -1
  40. package/build/components/sidebar-navigation-screen-global-styles/index.js +6 -2
  41. package/build/components/sidebar-navigation-screen-global-styles/index.js.map +1 -1
  42. package/build/components/style-book/index.js +2 -0
  43. package/build/components/style-book/index.js.map +1 -1
  44. package/build/hooks/commands/use-edit-mode-commands.js +3 -171
  45. package/build/hooks/commands/use-edit-mode-commands.js.map +1 -1
  46. package/build/hooks/index.js +0 -1
  47. package/build/hooks/index.js.map +1 -1
  48. package/build/hooks/push-changes-to-global-styles/index.js +4 -5
  49. package/build/hooks/push-changes-to-global-styles/index.js.map +1 -1
  50. package/build/hooks/use-theme-style-variations/use-theme-style-variations-by-property.js +91 -0
  51. package/build/hooks/use-theme-style-variations/use-theme-style-variations-by-property.js.map +1 -0
  52. package/build/store/actions.js +19 -50
  53. package/build/store/actions.js.map +1 -1
  54. package/build/utils/clone-deep.js +15 -0
  55. package/build/utils/clone-deep.js.map +1 -0
  56. package/build-module/components/block-editor/use-site-editor-settings.js +2 -1
  57. package/build-module/components/block-editor/use-site-editor-settings.js.map +1 -1
  58. package/build-module/components/code-editor/index.js +3 -2
  59. package/build-module/components/code-editor/index.js.map +1 -1
  60. package/build-module/components/editor/index.js +4 -4
  61. package/build-module/components/editor/index.js.map +1 -1
  62. package/build-module/components/editor-canvas-container/index.js +2 -2
  63. package/build-module/components/editor-canvas-container/index.js.map +1 -1
  64. package/build-module/components/header-edit-mode/document-tools/index.js +1 -2
  65. package/build-module/components/header-edit-mode/document-tools/index.js.map +1 -1
  66. package/build-module/components/header-edit-mode/index.js +3 -1
  67. package/build-module/components/header-edit-mode/index.js.map +1 -1
  68. package/build-module/components/header-edit-mode/more-menu/index.js +6 -3
  69. package/build-module/components/header-edit-mode/more-menu/index.js.map +1 -1
  70. package/build-module/components/keyboard-shortcuts/edit-mode.js +0 -13
  71. package/build-module/components/keyboard-shortcuts/edit-mode.js.map +1 -1
  72. package/build-module/components/keyboard-shortcuts/register.js +0 -18
  73. package/build-module/components/keyboard-shortcuts/register.js.map +1 -1
  74. package/build-module/components/layout/index.js +1 -2
  75. package/build-module/components/layout/index.js.map +1 -1
  76. package/build-module/components/page-patterns/dataviews-pattern-actions.js +25 -8
  77. package/build-module/components/page-patterns/dataviews-pattern-actions.js.map +1 -1
  78. package/build-module/components/page-patterns/header.js +2 -1
  79. package/build-module/components/page-patterns/header.js.map +1 -1
  80. package/build-module/components/page-patterns/index.js +0 -1
  81. package/build-module/components/page-patterns/index.js.map +1 -1
  82. package/build-module/components/save-button/index.js +2 -1
  83. package/build-module/components/save-button/index.js.map +1 -1
  84. package/build-module/components/sidebar/index.js +3 -2
  85. package/build-module/components/sidebar/index.js.map +1 -1
  86. package/build-module/components/sidebar-edit-mode/global-styles-sidebar.js +5 -5
  87. package/build-module/components/sidebar-edit-mode/global-styles-sidebar.js.map +1 -1
  88. package/build-module/components/sidebar-edit-mode/template-panel/hooks.js +20 -5
  89. package/build-module/components/sidebar-edit-mode/template-panel/hooks.js.map +1 -1
  90. package/build-module/components/sidebar-edit-mode/template-panel/index.js +50 -7
  91. package/build-module/components/sidebar-edit-mode/template-panel/index.js.map +1 -1
  92. package/build-module/components/sidebar-edit-mode/template-panel/template-actions.js +2 -9
  93. package/build-module/components/sidebar-edit-mode/template-panel/template-actions.js.map +1 -1
  94. package/build-module/components/sidebar-navigation-screen-global-styles/index.js +6 -2
  95. package/build-module/components/sidebar-navigation-screen-global-styles/index.js.map +1 -1
  96. package/build-module/components/style-book/index.js +2 -0
  97. package/build-module/components/style-book/index.js.map +1 -1
  98. package/build-module/hooks/commands/use-edit-mode-commands.js +4 -172
  99. package/build-module/hooks/commands/use-edit-mode-commands.js.map +1 -1
  100. package/build-module/hooks/index.js +0 -1
  101. package/build-module/hooks/index.js.map +1 -1
  102. package/build-module/hooks/push-changes-to-global-styles/index.js +1 -3
  103. package/build-module/hooks/push-changes-to-global-styles/index.js.map +1 -1
  104. package/build-module/hooks/use-theme-style-variations/use-theme-style-variations-by-property.js +82 -0
  105. package/build-module/hooks/use-theme-style-variations/use-theme-style-variations-by-property.js.map +1 -0
  106. package/build-module/store/actions.js +19 -50
  107. package/build-module/store/actions.js.map +1 -1
  108. package/build-module/utils/clone-deep.js +9 -0
  109. package/build-module/utils/clone-deep.js.map +1 -0
  110. package/build-style/style-rtl.css +24 -208
  111. package/build-style/style.css +24 -208
  112. package/package.json +43 -42
  113. package/src/components/block-editor/use-site-editor-settings.js +1 -0
  114. package/src/components/code-editor/index.js +3 -2
  115. package/src/components/editor/index.js +10 -7
  116. package/src/components/editor-canvas-container/index.js +2 -5
  117. package/src/components/{test → error-boundary/test}/error-boundary.js +7 -5
  118. package/src/components/global-styles/screen-revisions/style.scss +2 -2
  119. package/src/components/global-styles/style.scss +1 -1
  120. package/src/components/header-edit-mode/document-tools/index.js +1 -2
  121. package/src/components/header-edit-mode/index.js +1 -1
  122. package/src/components/header-edit-mode/more-menu/index.js +8 -3
  123. package/src/components/keyboard-shortcuts/edit-mode.js +0 -11
  124. package/src/components/keyboard-shortcuts/register.js +0 -19
  125. package/src/components/layout/index.js +0 -2
  126. package/src/components/page-patterns/dataviews-pattern-actions.js +41 -10
  127. package/src/components/page-patterns/header.js +1 -0
  128. package/src/components/page-patterns/index.js +0 -1
  129. package/src/components/page-patterns/style.scss +0 -182
  130. package/src/components/save-button/index.js +2 -1
  131. package/src/components/save-hub/style.scss +1 -1
  132. package/src/components/sidebar/index.js +2 -1
  133. package/src/components/sidebar-button/style.scss +1 -1
  134. package/src/components/sidebar-edit-mode/global-styles-sidebar.js +5 -7
  135. package/src/components/sidebar-edit-mode/style.scss +4 -0
  136. package/src/components/sidebar-edit-mode/template-panel/hooks.js +37 -24
  137. package/src/components/sidebar-edit-mode/template-panel/index.js +76 -18
  138. package/src/components/sidebar-edit-mode/template-panel/style.scss +5 -14
  139. package/src/components/sidebar-edit-mode/template-panel/template-actions.js +1 -12
  140. package/src/components/sidebar-navigation-screen-global-styles/index.js +4 -1
  141. package/src/components/style-book/index.js +5 -1
  142. package/src/hooks/commands/use-edit-mode-commands.js +3 -184
  143. package/src/hooks/index.js +0 -1
  144. package/src/hooks/push-changes-to-global-styles/index.js +1 -4
  145. package/src/hooks/use-theme-style-variations/test/use-theme-style-variations-by-property.js +964 -0
  146. package/src/hooks/use-theme-style-variations/use-theme-style-variations-by-property.js +92 -0
  147. package/src/store/actions.js +21 -85
  148. package/src/store/test/actions.js +0 -75
  149. package/src/style.scss +1 -6
  150. package/src/utils/clone-deep.js +8 -0
  151. package/build/components/header-edit-mode/mode-switcher/index.js +0 -62
  152. package/build/components/header-edit-mode/mode-switcher/index.js.map +0 -1
  153. package/build/components/page-patterns/duplicate-menu-item.js +0 -93
  154. package/build/components/page-patterns/duplicate-menu-item.js.map +0 -1
  155. package/build/components/page-patterns/grid-item.js +0 -223
  156. package/build/components/page-patterns/grid-item.js.map +0 -1
  157. package/build/components/page-patterns/grid.js +0 -31
  158. package/build/components/page-patterns/grid.js.map +0 -1
  159. package/build/components/page-patterns/no-patterns.js +0 -18
  160. package/build/components/page-patterns/no-patterns.js.map +0 -1
  161. package/build/components/page-patterns/patterns-list.js +0 -168
  162. package/build/components/page-patterns/patterns-list.js.map +0 -1
  163. package/build/components/page-patterns/rename-menu-item.js +0 -105
  164. package/build/components/page-patterns/rename-menu-item.js.map +0 -1
  165. package/build/components/sidebar-edit-mode/template-panel/replace-template-button.js +0 -83
  166. package/build/components/sidebar-edit-mode/template-panel/replace-template-button.js.map +0 -1
  167. package/build/hooks/navigation-menu-edit.js +0 -82
  168. package/build/hooks/navigation-menu-edit.js.map +0 -1
  169. package/build-module/components/header-edit-mode/mode-switcher/index.js +0 -56
  170. package/build-module/components/header-edit-mode/mode-switcher/index.js.map +0 -1
  171. package/build-module/components/page-patterns/duplicate-menu-item.js +0 -85
  172. package/build-module/components/page-patterns/duplicate-menu-item.js.map +0 -1
  173. package/build-module/components/page-patterns/grid-item.js +0 -215
  174. package/build-module/components/page-patterns/grid-item.js.map +0 -1
  175. package/build-module/components/page-patterns/grid.js +0 -23
  176. package/build-module/components/page-patterns/grid.js.map +0 -1
  177. package/build-module/components/page-patterns/no-patterns.js +0 -11
  178. package/build-module/components/page-patterns/no-patterns.js.map +0 -1
  179. package/build-module/components/page-patterns/patterns-list.js +0 -160
  180. package/build-module/components/page-patterns/patterns-list.js.map +0 -1
  181. package/build-module/components/page-patterns/rename-menu-item.js +0 -98
  182. package/build-module/components/page-patterns/rename-menu-item.js.map +0 -1
  183. package/build-module/components/sidebar-edit-mode/template-panel/replace-template-button.js +0 -76
  184. package/build-module/components/sidebar-edit-mode/template-panel/replace-template-button.js.map +0 -1
  185. package/build-module/hooks/navigation-menu-edit.js +0 -75
  186. package/build-module/hooks/navigation-menu-edit.js.map +0 -1
  187. package/src/components/header-edit-mode/mode-switcher/index.js +0 -60
  188. package/src/components/page-patterns/duplicate-menu-item.js +0 -105
  189. package/src/components/page-patterns/grid-item.js +0 -331
  190. package/src/components/page-patterns/grid.js +0 -22
  191. package/src/components/page-patterns/no-patterns.js +0 -12
  192. package/src/components/page-patterns/patterns-list.js +0 -229
  193. package/src/components/page-patterns/rename-menu-item.js +0 -132
  194. package/src/components/sidebar-edit-mode/template-panel/replace-template-button.js +0 -89
  195. package/src/hooks/navigation-menu-edit.js +0 -92
@@ -1,105 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import { MenuItem } from '@wordpress/components';
5
- import { useDispatch } from '@wordpress/data';
6
- import { useState } from '@wordpress/element';
7
- import { __, sprintf } from '@wordpress/i18n';
8
- import { store as noticesStore } from '@wordpress/notices';
9
- import { privateApis as patternsPrivateApis } from '@wordpress/patterns';
10
- import { privateApis as routerPrivateApis } from '@wordpress/router';
11
-
12
- /**
13
- * Internal dependencies
14
- */
15
- import { TEMPLATE_PART_POST_TYPE, PATTERN_TYPES } from '../../utils/constants';
16
- import { unlock } from '../../lock-unlock';
17
- import CreateTemplatePartModal from '../create-template-part-modal';
18
-
19
- const { DuplicatePatternModal } = unlock( patternsPrivateApis );
20
- const { useHistory } = unlock( routerPrivateApis );
21
-
22
- export default function DuplicateMenuItem( {
23
- categoryId,
24
- item,
25
- label = __( 'Duplicate' ),
26
- onClose,
27
- } ) {
28
- const { createSuccessNotice } = useDispatch( noticesStore );
29
- const [ isModalOpen, setIsModalOpen ] = useState( false );
30
- const history = useHistory();
31
-
32
- const closeModal = () => setIsModalOpen( false );
33
-
34
- const isTemplatePart = item.type === TEMPLATE_PART_POST_TYPE;
35
- const isThemePattern = item.type === PATTERN_TYPES.theme;
36
-
37
- async function onTemplatePartSuccess( templatePart ) {
38
- createSuccessNotice(
39
- sprintf(
40
- // translators: %s: The new template part's title e.g. 'Call to action (copy)'.
41
- __( '"%s" duplicated.' ),
42
- item.title
43
- ),
44
- {
45
- type: 'snackbar',
46
- id: 'edit-site-patterns-success',
47
- }
48
- );
49
-
50
- history.push( {
51
- postType: TEMPLATE_PART_POST_TYPE,
52
- postId: templatePart?.id,
53
- categoryType: TEMPLATE_PART_POST_TYPE,
54
- categoryId,
55
- } );
56
-
57
- onClose();
58
- }
59
-
60
- function onPatternSuccess( { pattern } ) {
61
- history.push( {
62
- categoryType: PATTERN_TYPES.theme,
63
- categoryId,
64
- postType: PATTERN_TYPES.user,
65
- postId: pattern.id,
66
- } );
67
-
68
- onClose();
69
- }
70
-
71
- return (
72
- <>
73
- <MenuItem
74
- onClick={ () => setIsModalOpen( true ) }
75
- aria-expanded={ isModalOpen }
76
- aria-haspopup="dialog"
77
- >
78
- { label }
79
- </MenuItem>
80
- { isModalOpen && ! isTemplatePart && (
81
- <DuplicatePatternModal
82
- onClose={ closeModal }
83
- onSuccess={ onPatternSuccess }
84
- pattern={ isThemePattern ? item : item.patternPost }
85
- />
86
- ) }
87
- { isModalOpen && isTemplatePart && (
88
- <CreateTemplatePartModal
89
- blocks={ item.blocks }
90
- closeModal={ closeModal }
91
- confirmLabel={ __( 'Duplicate' ) }
92
- defaultArea={ item.templatePart.area }
93
- defaultTitle={ sprintf(
94
- /* translators: %s: Existing template part title */
95
- __( '%s (Copy)' ),
96
- item.title
97
- ) }
98
- modalTitle={ __( 'Duplicate template part' ) }
99
- onCreate={ onTemplatePartSuccess }
100
- onError={ closeModal }
101
- />
102
- ) }
103
- </>
104
- );
105
- }
@@ -1,331 +0,0 @@
1
- /**
2
- * External dependencies
3
- */
4
- import classnames from 'classnames';
5
- import { paramCase as kebabCase } from 'change-case';
6
-
7
- /**
8
- * WordPress dependencies
9
- */
10
- import {
11
- BlockPreview,
12
- privateApis as blockEditorPrivateApis,
13
- } from '@wordpress/block-editor';
14
- import {
15
- Button,
16
- __experimentalConfirmDialog as ConfirmDialog,
17
- DropdownMenu,
18
- MenuGroup,
19
- MenuItem,
20
- __experimentalHeading as Heading,
21
- __experimentalHStack as HStack,
22
- Tooltip,
23
- Flex,
24
- } from '@wordpress/components';
25
- import { useDispatch } from '@wordpress/data';
26
- import { useState, useId, memo } from '@wordpress/element';
27
- import { __, sprintf } from '@wordpress/i18n';
28
- import {
29
- Icon,
30
- header,
31
- footer,
32
- symbolFilled as uncategorized,
33
- symbol,
34
- moreVertical,
35
- lockSmall,
36
- } from '@wordpress/icons';
37
- import { store as noticesStore } from '@wordpress/notices';
38
- import { store as reusableBlocksStore } from '@wordpress/reusable-blocks';
39
- import { downloadBlob } from '@wordpress/blob';
40
-
41
- /**
42
- * Internal dependencies
43
- */
44
- import RenameMenuItem from './rename-menu-item';
45
- import DuplicateMenuItem from './duplicate-menu-item';
46
- import {
47
- PATTERN_TYPES,
48
- TEMPLATE_PART_POST_TYPE,
49
- PATTERN_SYNC_TYPES,
50
- } from '../../utils/constants';
51
- import { store as editSiteStore } from '../../store';
52
- import { useLink } from '../routes/link';
53
- import { unlock } from '../../lock-unlock';
54
-
55
- const { useGlobalStyle } = unlock( blockEditorPrivateApis );
56
-
57
- const templatePartIcons = { header, footer, uncategorized };
58
-
59
- function GridItem( { categoryId, item, ...props } ) {
60
- const descriptionId = useId();
61
- const [ isDeleteDialogOpen, setIsDeleteDialogOpen ] = useState( false );
62
- const [ backgroundColor ] = useGlobalStyle( 'color.background' );
63
-
64
- const { removeTemplate } = useDispatch( editSiteStore );
65
- const { __experimentalDeleteReusableBlock } =
66
- useDispatch( reusableBlocksStore );
67
- const { createErrorNotice, createSuccessNotice } =
68
- useDispatch( noticesStore );
69
-
70
- const isUserPattern = item.type === PATTERN_TYPES.user;
71
- const isNonUserPattern = item.type === PATTERN_TYPES.theme;
72
- const isTemplatePart = item.type === TEMPLATE_PART_POST_TYPE;
73
-
74
- const { onClick } = useLink( {
75
- postType: item.type,
76
- postId: isUserPattern ? item.id : item.name,
77
- categoryId,
78
- categoryType: isTemplatePart ? item.type : PATTERN_TYPES.theme,
79
- } );
80
-
81
- const isEmpty = ! item.blocks?.length;
82
- const patternClassNames = classnames( 'edit-site-patterns__pattern', {
83
- 'is-placeholder': isEmpty,
84
- } );
85
- const previewClassNames = classnames( 'edit-site-patterns__preview', {
86
- 'is-inactive': isNonUserPattern,
87
- } );
88
-
89
- const deletePattern = async () => {
90
- try {
91
- await __experimentalDeleteReusableBlock( item.id );
92
- createSuccessNotice(
93
- sprintf(
94
- // translators: %s: The pattern's title e.g. 'Call to action'.
95
- __( '"%s" deleted.' ),
96
- item.title
97
- ),
98
- { type: 'snackbar', id: 'edit-site-patterns-success' }
99
- );
100
- } catch ( error ) {
101
- const errorMessage =
102
- error.message && error.code !== 'unknown_error'
103
- ? error.message
104
- : __( 'An error occurred while deleting the pattern.' );
105
- createErrorNotice( errorMessage, {
106
- type: 'snackbar',
107
- id: 'edit-site-patterns-error',
108
- } );
109
- }
110
- };
111
- const deleteItem = () =>
112
- isTemplatePart ? removeTemplate( item ) : deletePattern();
113
- const exportAsJSON = () => {
114
- const json = {
115
- __file: item.type,
116
- title: item.title || item.name,
117
- content: item.patternPost.content.raw,
118
- syncStatus: item.patternPost.wp_pattern_sync_status,
119
- };
120
-
121
- return downloadBlob(
122
- `${ kebabCase( item.title || item.name ) }.json`,
123
- JSON.stringify( json, null, 2 ),
124
- 'application/json'
125
- );
126
- };
127
-
128
- // Only custom patterns or custom template parts can be renamed or deleted.
129
- const isCustomPattern =
130
- isUserPattern || ( isTemplatePart && item.isCustom );
131
- const hasThemeFile = isTemplatePart && item.templatePart.has_theme_file;
132
- const ariaDescriptions = [];
133
-
134
- if ( isCustomPattern ) {
135
- // User patterns don't have descriptions, but can be edited and deleted, so include some help text.
136
- ariaDescriptions.push(
137
- __( 'Press Enter to edit, or Delete to delete the pattern.' )
138
- );
139
- } else if ( item.description ) {
140
- ariaDescriptions.push( item.description );
141
- }
142
-
143
- if ( isNonUserPattern ) {
144
- ariaDescriptions.push(
145
- __( 'Theme & plugin patterns cannot be edited.' )
146
- );
147
- }
148
-
149
- let itemIcon;
150
- if ( ! isUserPattern && templatePartIcons[ categoryId ] ) {
151
- itemIcon = templatePartIcons[ categoryId ];
152
- } else {
153
- itemIcon =
154
- item.syncStatus === PATTERN_SYNC_TYPES.full ? symbol : undefined;
155
- }
156
-
157
- const confirmButtonText = hasThemeFile ? __( 'Clear' ) : __( 'Delete' );
158
- const confirmPrompt = hasThemeFile
159
- ? __( 'Are you sure you want to clear these customizations?' )
160
- : sprintf(
161
- // translators: %s: The pattern or template part's title e.g. 'Call to action'.
162
- __( 'Are you sure you want to delete "%s"?' ),
163
- item.title || item.name
164
- );
165
-
166
- const additionalStyles = ! backgroundColor
167
- ? [ { css: 'body { background: #fff; }' } ]
168
- : undefined;
169
-
170
- return (
171
- <li className={ patternClassNames }>
172
- <button
173
- className={ previewClassNames }
174
- id={ `edit-site-patterns-${ item.name }` }
175
- type="button"
176
- { ...props }
177
- onClick={
178
- item.type !== PATTERN_TYPES.theme ? onClick : undefined
179
- }
180
- aria-disabled={
181
- item.type !== PATTERN_TYPES.theme ? 'false' : 'true'
182
- }
183
- aria-label={ item.title }
184
- aria-describedby={
185
- ariaDescriptions.length
186
- ? ariaDescriptions
187
- .map(
188
- ( _, index ) =>
189
- `${ descriptionId }-${ index }`
190
- )
191
- .join( ' ' )
192
- : undefined
193
- }
194
- >
195
- { isEmpty && isTemplatePart && __( 'Empty template part' ) }
196
- { isEmpty && ! isTemplatePart && __( 'Empty pattern' ) }
197
- { ! isEmpty && (
198
- <BlockPreview
199
- blocks={ item.blocks }
200
- additionalStyles={ additionalStyles }
201
- viewportWidth={ item.viewportWidth }
202
- />
203
- ) }
204
- </button>
205
- { ariaDescriptions.map( ( ariaDescription, index ) => (
206
- <div
207
- key={ index }
208
- hidden
209
- id={ `${ descriptionId }-${ index }` }
210
- >
211
- { ariaDescription }
212
- </div>
213
- ) ) }
214
- <HStack
215
- className="edit-site-patterns__footer"
216
- justify="space-between"
217
- >
218
- <HStack
219
- alignment="center"
220
- justify="left"
221
- spacing={ 3 }
222
- className="edit-site-patterns__pattern-title"
223
- >
224
- { itemIcon && ! isNonUserPattern && (
225
- <Tooltip
226
- placement="top"
227
- text={ __(
228
- 'Editing this pattern will also update anywhere it is used'
229
- ) }
230
- >
231
- <Icon
232
- className="edit-site-patterns__pattern-icon"
233
- icon={ itemIcon }
234
- />
235
- </Tooltip>
236
- ) }
237
- <Flex as="span" gap={ 0 } justify="left">
238
- { item.type === PATTERN_TYPES.theme ? (
239
- item.title
240
- ) : (
241
- <Heading level={ 5 }>
242
- <Button
243
- variant="link"
244
- onClick={ onClick }
245
- // Required for the grid's roving tab index system.
246
- // See https://github.com/WordPress/gutenberg/pull/51898#discussion_r1243399243.
247
- tabIndex="-1"
248
- >
249
- { item.title || item.name }
250
- </Button>
251
- </Heading>
252
- ) }
253
- { item.type === PATTERN_TYPES.theme && (
254
- <Tooltip
255
- placement="top"
256
- text={ __( 'This pattern cannot be edited.' ) }
257
- >
258
- <Icon
259
- className="edit-site-patterns__pattern-lock-icon"
260
- icon={ lockSmall }
261
- size={ 24 }
262
- />
263
- </Tooltip>
264
- ) }
265
- </Flex>
266
- </HStack>
267
- <DropdownMenu
268
- icon={ moreVertical }
269
- label={ __( 'Actions' ) }
270
- className="edit-site-patterns__dropdown"
271
- popoverProps={ { placement: 'bottom-end' } }
272
- toggleProps={ {
273
- className: 'edit-site-patterns__button',
274
- describedBy: sprintf(
275
- /* translators: %s: pattern name */
276
- __( 'Action menu for %s pattern' ),
277
- item.title
278
- ),
279
- } }
280
- >
281
- { ( { onClose } ) => (
282
- <MenuGroup>
283
- { isCustomPattern && ! hasThemeFile && (
284
- <RenameMenuItem
285
- item={ item }
286
- onClose={ onClose }
287
- />
288
- ) }
289
- <DuplicateMenuItem
290
- categoryId={ categoryId }
291
- item={ item }
292
- onClose={ onClose }
293
- label={ __( 'Duplicate' ) }
294
- />
295
- { item.type === PATTERN_TYPES.user && (
296
- <MenuItem onClick={ () => exportAsJSON() }>
297
- { __( 'Export as JSON' ) }
298
- </MenuItem>
299
- ) }
300
-
301
- { isCustomPattern && (
302
- <MenuItem
303
- isDestructive={ ! hasThemeFile }
304
- onClick={ () =>
305
- setIsDeleteDialogOpen( true )
306
- }
307
- >
308
- { hasThemeFile
309
- ? __( 'Clear customizations' )
310
- : __( 'Delete' ) }
311
- </MenuItem>
312
- ) }
313
- </MenuGroup>
314
- ) }
315
- </DropdownMenu>
316
- </HStack>
317
-
318
- { isDeleteDialogOpen && (
319
- <ConfirmDialog
320
- confirmButtonText={ confirmButtonText }
321
- onConfirm={ deleteItem }
322
- onCancel={ () => setIsDeleteDialogOpen( false ) }
323
- >
324
- { confirmPrompt }
325
- </ConfirmDialog>
326
- ) }
327
- </li>
328
- );
329
- }
330
-
331
- export default memo( GridItem );
@@ -1,22 +0,0 @@
1
- /**
2
- * Internal dependencies
3
- */
4
- import GridItem from './grid-item';
5
-
6
- export default function Grid( { categoryId, items, ...props } ) {
7
- if ( ! items?.length ) {
8
- return null;
9
- }
10
-
11
- return (
12
- <ul className="edit-site-patterns__grid" { ...props }>
13
- { items.map( ( item ) => (
14
- <GridItem
15
- key={ item.name }
16
- item={ item }
17
- categoryId={ categoryId }
18
- />
19
- ) ) }
20
- </ul>
21
- );
22
- }
@@ -1,12 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import { __ } from '@wordpress/i18n';
5
-
6
- export default function NoPatterns() {
7
- return (
8
- <div className="edit-site-patterns__no-results">
9
- { __( 'No patterns found.' ) }
10
- </div>
11
- );
12
- }
@@ -1,229 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import { useState, useDeferredValue, useId, useMemo } from '@wordpress/element';
5
- import {
6
- SearchControl,
7
- __experimentalVStack as VStack,
8
- Flex,
9
- FlexBlock,
10
- __experimentalToggleGroupControl as ToggleGroupControl,
11
- __experimentalToggleGroupControlOption as ToggleGroupControlOption,
12
- __experimentalHeading as Heading,
13
- __experimentalText as Text,
14
- } from '@wordpress/components';
15
- import { __, _x, isRTL } from '@wordpress/i18n';
16
- import { chevronLeft, chevronRight } from '@wordpress/icons';
17
- import { privateApis as routerPrivateApis } from '@wordpress/router';
18
- import {
19
- useAsyncList,
20
- useViewportMatch,
21
- useDebouncedInput,
22
- } from '@wordpress/compose';
23
-
24
- /**
25
- * Internal dependencies
26
- */
27
- import PatternsHeader from './header';
28
- import Grid from './grid';
29
- import NoPatterns from './no-patterns';
30
- import usePatterns from './use-patterns';
31
- import SidebarButton from '../sidebar-button';
32
- import { unlock } from '../../lock-unlock';
33
- import { PATTERN_SYNC_TYPES, PATTERN_TYPES } from '../../utils/constants';
34
- import Pagination from '../pagination';
35
-
36
- const { useLocation, useHistory } = unlock( routerPrivateApis );
37
-
38
- const SYNC_FILTERS = {
39
- all: _x( 'All', 'Option that shows all patterns' ),
40
- [ PATTERN_SYNC_TYPES.full ]: _x(
41
- 'Synced',
42
- 'Option that shows all synchronized patterns'
43
- ),
44
- [ PATTERN_SYNC_TYPES.unsynced ]: _x(
45
- 'Not synced',
46
- 'Option that shows all patterns that are not synchronized'
47
- ),
48
- };
49
-
50
- const SYNC_DESCRIPTIONS = {
51
- all: '',
52
- [ PATTERN_SYNC_TYPES.full ]: __(
53
- 'Patterns that are kept in sync across the site.'
54
- ),
55
- [ PATTERN_SYNC_TYPES.unsynced ]: __(
56
- 'Patterns that can be changed freely without affecting the site.'
57
- ),
58
- };
59
-
60
- const PAGE_SIZE = 20;
61
-
62
- export default function PatternsList( { categoryId, type } ) {
63
- const location = useLocation();
64
- const history = useHistory();
65
- const isMobileViewport = useViewportMatch( 'medium', '<' );
66
- const [ filterValue, setFilterValue, delayedFilterValue ] =
67
- useDebouncedInput( '' );
68
- const deferredFilterValue = useDeferredValue( delayedFilterValue );
69
-
70
- const [ syncFilter, setSyncFilter ] = useState( 'all' );
71
- const [ currentPage, setCurrentPage ] = useState( 1 );
72
-
73
- const deferredSyncedFilter = useDeferredValue( syncFilter );
74
-
75
- const isUncategorizedThemePatterns =
76
- type === PATTERN_TYPES.theme && categoryId === 'uncategorized';
77
-
78
- const { patterns, isResolving } = usePatterns(
79
- type,
80
- isUncategorizedThemePatterns ? '' : categoryId,
81
- {
82
- search: deferredFilterValue,
83
- syncStatus:
84
- deferredSyncedFilter === 'all'
85
- ? undefined
86
- : deferredSyncedFilter,
87
- }
88
- );
89
-
90
- const updateSearchFilter = ( value ) => {
91
- setCurrentPage( 1 );
92
- setFilterValue( value );
93
- };
94
-
95
- const updateSyncFilter = ( value ) => {
96
- setCurrentPage( 1 );
97
- setSyncFilter( value );
98
- };
99
-
100
- const id = useId();
101
- const titleId = `${ id }-title`;
102
- const descriptionId = `${ id }-description`;
103
-
104
- const hasPatterns = patterns.length;
105
- const title = SYNC_FILTERS[ syncFilter ];
106
- const description = SYNC_DESCRIPTIONS[ syncFilter ];
107
-
108
- const totalItems = patterns.length;
109
- const pageIndex = currentPage - 1;
110
- const numPages = Math.ceil( patterns.length / PAGE_SIZE );
111
-
112
- const list = useMemo( () => {
113
- return patterns.slice(
114
- pageIndex * PAGE_SIZE,
115
- pageIndex * PAGE_SIZE + PAGE_SIZE
116
- );
117
- }, [ pageIndex, patterns ] );
118
-
119
- const asyncList = useAsyncList( list, { step: 10 } );
120
-
121
- const changePage = ( page ) => {
122
- const scrollContainer = document.querySelector( '.edit-site-patterns' );
123
- scrollContainer?.scrollTo( 0, 0 );
124
-
125
- setCurrentPage( page );
126
- };
127
-
128
- return (
129
- <>
130
- <VStack className="edit-site-patterns__header" spacing={ 6 }>
131
- <PatternsHeader
132
- categoryId={ categoryId }
133
- type={ type }
134
- titleId={ titleId }
135
- descriptionId={ descriptionId }
136
- />
137
- <Flex alignment="stretch" wrap>
138
- { isMobileViewport && (
139
- <SidebarButton
140
- icon={ isRTL() ? chevronRight : chevronLeft }
141
- label={ __( 'Back' ) }
142
- onClick={ () => {
143
- // Go back in history if we came from the Patterns page.
144
- // Otherwise push a stack onto the history.
145
- if (
146
- location.state?.backPath === '/patterns'
147
- ) {
148
- history.back();
149
- } else {
150
- history.push( { path: '/patterns' } );
151
- }
152
- } }
153
- />
154
- ) }
155
- <FlexBlock className="edit-site-patterns__search-block">
156
- <SearchControl
157
- className="edit-site-patterns__search"
158
- onChange={ ( value ) =>
159
- updateSearchFilter( value )
160
- }
161
- placeholder={ __( 'Search patterns' ) }
162
- label={ __( 'Search patterns' ) }
163
- value={ filterValue }
164
- __nextHasNoMarginBottom
165
- />
166
- </FlexBlock>
167
- { type === PATTERN_TYPES.theme && (
168
- <ToggleGroupControl
169
- className="edit-site-patterns__sync-status-filter"
170
- hideLabelFromVision
171
- label={ __( 'Filter by sync status' ) }
172
- value={ syncFilter }
173
- isBlock
174
- onChange={ ( value ) => updateSyncFilter( value ) }
175
- __nextHasNoMarginBottom
176
- >
177
- { Object.entries( SYNC_FILTERS ).map(
178
- ( [ key, label ] ) => (
179
- <ToggleGroupControlOption
180
- className="edit-site-patterns__sync-status-filter-option"
181
- key={ key }
182
- value={ key }
183
- label={ label }
184
- />
185
- )
186
- ) }
187
- </ToggleGroupControl>
188
- ) }
189
- </Flex>
190
- </VStack>
191
- <VStack
192
- className="edit-site-patterns__section"
193
- justify="flex-start"
194
- spacing={ 6 }
195
- >
196
- { syncFilter !== 'all' && (
197
- <VStack className="edit-site-patterns__section-header">
198
- <Heading as="h3" level={ 5 } id={ titleId }>
199
- { title }
200
- </Heading>
201
- { description ? (
202
- <Text variant="muted" as="p" id={ descriptionId }>
203
- { description }
204
- </Text>
205
- ) : null }
206
- </VStack>
207
- ) }
208
- { hasPatterns && (
209
- <Grid
210
- categoryId={ categoryId }
211
- items={ asyncList }
212
- aria-labelledby={ titleId }
213
- aria-describedby={ descriptionId }
214
- />
215
- ) }
216
- { ! isResolving && ! hasPatterns && <NoPatterns /> }
217
- </VStack>
218
- { numPages > 1 && (
219
- <Pagination
220
- className="edit-site-patterns__pagination"
221
- currentPage={ currentPage }
222
- numPages={ numPages }
223
- changePage={ changePage }
224
- totalItems={ totalItems }
225
- />
226
- ) }
227
- </>
228
- );
229
- }