@wordpress/edit-site 4.6.0 → 4.9.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.
- package/CHANGELOG.md +6 -0
- package/build/components/add-new-template/add-custom-template-modal.js +185 -0
- package/build/components/add-new-template/add-custom-template-modal.js.map +1 -0
- package/build/components/add-new-template/new-template.js +92 -32
- package/build/components/add-new-template/new-template.js.map +1 -1
- package/build/components/add-new-template/utils.js +139 -0
- package/build/components/add-new-template/utils.js.map +1 -0
- package/build/components/block-editor/block-inspector-button.js.map +1 -1
- package/build/components/block-editor/index.js.map +1 -1
- package/build/components/code-editor/code-editor-text-area.js +11 -9
- package/build/components/code-editor/code-editor-text-area.js.map +1 -1
- package/build/components/edit-template-part-menu-button/index.js.map +1 -1
- package/build/components/editor/index.js.map +1 -1
- package/build/components/global-styles/context-menu.js +6 -3
- package/build/components/global-styles/context-menu.js.map +1 -1
- package/build/components/global-styles/global-styles-provider.js.map +1 -1
- package/build/components/global-styles/gradients-palette-panel.js +3 -7
- package/build/components/global-styles/gradients-palette-panel.js.map +1 -1
- package/build/components/global-styles/hooks.js +1 -1
- package/build/components/global-styles/hooks.js.map +1 -1
- package/build/components/global-styles/palette.js +2 -1
- package/build/components/global-styles/palette.js.map +1 -1
- package/build/components/global-styles/preview.js +13 -2
- package/build/components/global-styles/preview.js.map +1 -1
- package/build/components/global-styles/screen-block-list.js +4 -1
- package/build/components/global-styles/screen-block-list.js.map +1 -1
- package/build/components/global-styles/screen-button-color.js +80 -0
- package/build/components/global-styles/screen-button-color.js.map +1 -0
- package/build/components/global-styles/screen-colors.js +47 -7
- package/build/components/global-styles/screen-colors.js.map +1 -1
- package/build/components/global-styles/screen-root.js +4 -2
- package/build/components/global-styles/screen-root.js.map +1 -1
- package/build/components/global-styles/screen-style-variations.js +9 -1
- package/build/components/global-styles/screen-style-variations.js.map +1 -1
- package/build/components/global-styles/screen-typography-element.js +4 -0
- package/build/components/global-styles/screen-typography-element.js.map +1 -1
- package/build/components/global-styles/screen-typography.js +9 -1
- package/build/components/global-styles/screen-typography.js.map +1 -1
- package/build/components/global-styles/ui.js +11 -0
- package/build/components/global-styles/ui.js.map +1 -1
- package/build/components/global-styles/use-global-styles-output.js +40 -9
- package/build/components/global-styles/use-global-styles-output.js.map +1 -1
- package/build/components/global-styles/utils.js +3 -1
- package/build/components/global-styles/utils.js.map +1 -1
- package/build/components/header/index.js +28 -10
- package/build/components/header/index.js.map +1 -1
- package/build/components/header/mode-switcher/index.js.map +1 -1
- package/build/components/header/more-menu/copy-content-menu-item.js +1 -1
- package/build/components/header/more-menu/copy-content-menu-item.js.map +1 -1
- package/build/components/header/more-menu/site-export.js +4 -1
- package/build/components/header/more-menu/site-export.js.map +1 -1
- package/build/components/header/undo-redo/redo.js +13 -4
- package/build/components/header/undo-redo/redo.js.map +1 -1
- package/build/components/header/undo-redo/undo.js +13 -4
- package/build/components/header/undo-redo/undo.js.map +1 -1
- package/build/components/keyboard-shortcut-help-modal/config.js +17 -0
- package/build/components/keyboard-shortcut-help-modal/config.js.map +1 -1
- package/build/components/keyboard-shortcuts/index.js.map +1 -1
- package/build/components/list/actions/index.js.map +1 -1
- package/build/components/list/actions/rename-menu-item.js.map +1 -1
- package/build/components/list/added-by.js.map +1 -1
- package/build/components/navigation-sidebar/index.js.map +1 -1
- package/build/components/save-button/index.js.map +1 -1
- package/build/components/sidebar/index.js.map +1 -1
- package/build/components/sidebar/navigation-menu-sidebar/navigation-inspector.js.map +1 -1
- package/build/components/sidebar/template-card/index.js +19 -7
- package/build/components/sidebar/template-card/index.js.map +1 -1
- package/build/components/sidebar/template-card/template-actions.js +64 -0
- package/build/components/sidebar/template-card/template-actions.js.map +1 -0
- package/build/components/sidebar/template-card/template-areas.js.map +1 -1
- package/build/components/template-details/template-areas.js.map +1 -1
- package/build/components/template-part-converter/index.js.map +1 -1
- package/build/components/url-query-controller/index.js.map +1 -1
- package/build/store/actions.js.map +1 -1
- package/build/store/selectors.js.map +1 -1
- package/build-module/components/add-new-template/add-custom-template-modal.js +170 -0
- package/build-module/components/add-new-template/add-custom-template-modal.js.map +1 -0
- package/build-module/components/add-new-template/new-template.js +92 -35
- package/build-module/components/add-new-template/new-template.js.map +1 -1
- package/build-module/components/add-new-template/utils.js +119 -0
- package/build-module/components/add-new-template/utils.js.map +1 -0
- package/build-module/components/block-editor/block-inspector-button.js.map +1 -1
- package/build-module/components/block-editor/index.js.map +1 -1
- package/build-module/components/code-editor/code-editor-text-area.js +12 -10
- package/build-module/components/code-editor/code-editor-text-area.js.map +1 -1
- package/build-module/components/edit-template-part-menu-button/index.js.map +1 -1
- package/build-module/components/editor/index.js.map +1 -1
- package/build-module/components/global-styles/context-menu.js +6 -3
- package/build-module/components/global-styles/context-menu.js.map +1 -1
- package/build-module/components/global-styles/global-styles-provider.js.map +1 -1
- package/build-module/components/global-styles/gradients-palette-panel.js +3 -5
- package/build-module/components/global-styles/gradients-palette-panel.js.map +1 -1
- package/build-module/components/global-styles/hooks.js +1 -1
- package/build-module/components/global-styles/hooks.js.map +1 -1
- package/build-module/components/global-styles/palette.js +2 -1
- package/build-module/components/global-styles/palette.js.map +1 -1
- package/build-module/components/global-styles/preview.js +14 -3
- package/build-module/components/global-styles/preview.js.map +1 -1
- package/build-module/components/global-styles/screen-block-list.js +4 -1
- package/build-module/components/global-styles/screen-block-list.js.map +1 -1
- package/build-module/components/global-styles/screen-button-color.js +67 -0
- package/build-module/components/global-styles/screen-button-color.js.map +1 -0
- package/build-module/components/global-styles/screen-colors.js +48 -8
- package/build-module/components/global-styles/screen-colors.js.map +1 -1
- package/build-module/components/global-styles/screen-root.js +4 -2
- package/build-module/components/global-styles/screen-root.js.map +1 -1
- package/build-module/components/global-styles/screen-style-variations.js +9 -1
- package/build-module/components/global-styles/screen-style-variations.js.map +1 -1
- package/build-module/components/global-styles/screen-typography-element.js +4 -0
- package/build-module/components/global-styles/screen-typography-element.js.map +1 -1
- package/build-module/components/global-styles/screen-typography.js +10 -2
- package/build-module/components/global-styles/screen-typography.js.map +1 -1
- package/build-module/components/global-styles/ui.js +10 -0
- package/build-module/components/global-styles/ui.js.map +1 -1
- package/build-module/components/global-styles/use-global-styles-output.js +39 -9
- package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
- package/build-module/components/global-styles/utils.js +3 -1
- package/build-module/components/global-styles/utils.js.map +1 -1
- package/build-module/components/header/index.js +29 -11
- package/build-module/components/header/index.js.map +1 -1
- package/build-module/components/header/mode-switcher/index.js.map +1 -1
- package/build-module/components/header/more-menu/copy-content-menu-item.js +1 -1
- package/build-module/components/header/more-menu/copy-content-menu-item.js.map +1 -1
- package/build-module/components/header/more-menu/site-export.js +4 -1
- package/build-module/components/header/more-menu/site-export.js.map +1 -1
- package/build-module/components/header/undo-redo/redo.js +9 -3
- package/build-module/components/header/undo-redo/redo.js.map +1 -1
- package/build-module/components/header/undo-redo/undo.js +9 -3
- package/build-module/components/header/undo-redo/undo.js.map +1 -1
- package/build-module/components/keyboard-shortcut-help-modal/config.js +17 -0
- package/build-module/components/keyboard-shortcut-help-modal/config.js.map +1 -1
- package/build-module/components/keyboard-shortcuts/index.js.map +1 -1
- package/build-module/components/list/actions/index.js.map +1 -1
- package/build-module/components/list/actions/rename-menu-item.js.map +1 -1
- package/build-module/components/list/added-by.js.map +1 -1
- package/build-module/components/navigation-sidebar/index.js.map +1 -1
- package/build-module/components/save-button/index.js.map +1 -1
- package/build-module/components/sidebar/index.js.map +1 -1
- package/build-module/components/sidebar/navigation-menu-sidebar/navigation-inspector.js.map +1 -1
- package/build-module/components/sidebar/template-card/index.js +18 -7
- package/build-module/components/sidebar/template-card/index.js.map +1 -1
- package/build-module/components/sidebar/template-card/template-actions.js +49 -0
- package/build-module/components/sidebar/template-card/template-actions.js.map +1 -0
- package/build-module/components/sidebar/template-card/template-areas.js.map +1 -1
- package/build-module/components/template-details/template-areas.js.map +1 -1
- package/build-module/components/template-part-converter/index.js.map +1 -1
- package/build-module/components/url-query-controller/index.js.map +1 -1
- package/build-module/store/actions.js.map +1 -1
- package/build-module/store/selectors.js.map +1 -1
- package/build-style/style-rtl.css +170 -23
- package/build-style/style.css +170 -23
- package/package.json +30 -30
- package/src/components/add-new-template/add-custom-template-modal.js +231 -0
- package/src/components/add-new-template/new-template.js +135 -59
- package/src/components/add-new-template/style.scss +116 -0
- package/src/components/add-new-template/utils.js +125 -0
- package/src/components/block-editor/block-inspector-button.js +2 -3
- package/src/components/block-editor/index.js +4 -9
- package/src/components/code-editor/code-editor-text-area.js +12 -7
- package/src/components/edit-template-part-menu-button/index.js +2 -3
- package/src/components/editor/index.js +4 -5
- package/src/components/global-styles/context-menu.js +3 -0
- package/src/components/global-styles/global-styles-provider.js +4 -8
- package/src/components/global-styles/gradients-palette-panel.js +2 -5
- package/src/components/global-styles/hooks.js +5 -3
- package/src/components/global-styles/palette.js +4 -1
- package/src/components/global-styles/preview.js +17 -2
- package/src/components/global-styles/screen-block-list.js +14 -5
- package/src/components/global-styles/screen-button-color.js +102 -0
- package/src/components/global-styles/screen-colors.js +49 -4
- package/src/components/global-styles/screen-root.js +12 -5
- package/src/components/global-styles/screen-style-variations.js +10 -4
- package/src/components/global-styles/screen-typography-element.js +4 -0
- package/src/components/global-styles/screen-typography.js +17 -2
- package/src/components/global-styles/style.scss +10 -0
- package/src/components/global-styles/test/use-global-styles-output.js +82 -16
- package/src/components/global-styles/ui.js +13 -0
- package/src/components/global-styles/use-global-styles-output.js +43 -4
- package/src/components/global-styles/utils.js +3 -0
- package/src/components/header/index.js +38 -13
- package/src/components/header/mode-switcher/index.js +4 -4
- package/src/components/header/more-menu/copy-content-menu-item.js +3 -4
- package/src/components/header/more-menu/site-export.js +5 -3
- package/src/components/header/style.scss +53 -5
- package/src/components/header/undo-redo/redo.js +6 -1
- package/src/components/header/undo-redo/undo.js +6 -1
- package/src/components/keyboard-shortcut-help-modal/config.js +12 -0
- package/src/components/keyboard-shortcuts/index.js +6 -10
- package/src/components/list/actions/index.js +2 -3
- package/src/components/list/actions/rename-menu-item.js +4 -6
- package/src/components/list/added-by.js +4 -3
- package/src/components/navigation-sidebar/index.js +2 -4
- package/src/components/save-button/index.js +2 -4
- package/src/components/sidebar/index.js +6 -6
- package/src/components/sidebar/navigation-menu-sidebar/navigation-inspector.js +6 -9
- package/src/components/sidebar/navigation-menu-sidebar/style.scss +0 -1
- package/src/components/sidebar/template-card/index.js +17 -9
- package/src/components/sidebar/template-card/style.scss +49 -35
- package/src/components/sidebar/template-card/template-actions.js +43 -0
- package/src/components/sidebar/template-card/template-areas.js +6 -6
- package/src/components/template-details/template-areas.js +6 -6
- package/src/components/template-part-converter/index.js +2 -3
- package/src/components/url-query-controller/index.js +2 -3
- package/src/store/actions.js +257 -233
- package/src/store/selectors.js +9 -10
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { filter,
|
|
4
|
+
import { filter, includes } from 'lodash';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* WordPress dependencies
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
MenuItem,
|
|
13
13
|
NavigableMenu,
|
|
14
14
|
} from '@wordpress/components';
|
|
15
|
+
import { useState } from '@wordpress/element';
|
|
15
16
|
import { useSelect, useDispatch } from '@wordpress/data';
|
|
16
17
|
import { store as coreStore } from '@wordpress/core-data';
|
|
17
18
|
import { store as editorStore } from '@wordpress/editor';
|
|
@@ -30,12 +31,14 @@ import {
|
|
|
30
31
|
search,
|
|
31
32
|
tag,
|
|
32
33
|
} from '@wordpress/icons';
|
|
33
|
-
import { __ } from '@wordpress/i18n';
|
|
34
|
+
import { __, sprintf } from '@wordpress/i18n';
|
|
34
35
|
import { store as noticesStore } from '@wordpress/notices';
|
|
35
36
|
|
|
36
37
|
/**
|
|
37
38
|
* Internal dependencies
|
|
38
39
|
*/
|
|
40
|
+
import AddCustomTemplateModal from './add-custom-template-modal';
|
|
41
|
+
import { usePostTypes, usePostTypesEntitiesInfo } from './utils';
|
|
39
42
|
import { useHistory } from '../routes';
|
|
40
43
|
import { store as editSiteStore } from '../../store';
|
|
41
44
|
|
|
@@ -72,49 +75,52 @@ const TEMPLATE_ICONS = {
|
|
|
72
75
|
|
|
73
76
|
export default function NewTemplate( { postType } ) {
|
|
74
77
|
const history = useHistory();
|
|
75
|
-
const
|
|
78
|
+
const postTypes = usePostTypes();
|
|
79
|
+
const [ showCustomTemplateModal, setShowCustomTemplateModal ] =
|
|
80
|
+
useState( false );
|
|
81
|
+
const [ entityForSuggestions, setEntityForSuggestions ] = useState( {} );
|
|
82
|
+
const { existingTemplates, defaultTemplateTypes } = useSelect(
|
|
76
83
|
( select ) => ( {
|
|
77
|
-
|
|
84
|
+
existingTemplates: select( coreStore ).getEntityRecords(
|
|
78
85
|
'postType',
|
|
79
86
|
'wp_template',
|
|
80
87
|
{ per_page: -1 }
|
|
81
88
|
),
|
|
82
|
-
defaultTemplateTypes:
|
|
83
|
-
editorStore
|
|
84
|
-
).__experimentalGetDefaultTemplateTypes(),
|
|
89
|
+
defaultTemplateTypes:
|
|
90
|
+
select( editorStore ).__experimentalGetDefaultTemplateTypes(),
|
|
85
91
|
} ),
|
|
86
92
|
[]
|
|
87
93
|
);
|
|
94
|
+
const postTypesEntitiesInfo = usePostTypesEntitiesInfo( existingTemplates );
|
|
88
95
|
const { saveEntityRecord } = useDispatch( coreStore );
|
|
89
96
|
const { createErrorNotice } = useDispatch( noticesStore );
|
|
90
97
|
const { setTemplate } = useDispatch( editSiteStore );
|
|
91
98
|
|
|
92
|
-
async function createTemplate(
|
|
99
|
+
async function createTemplate( template ) {
|
|
93
100
|
try {
|
|
94
|
-
const { title, description } =
|
|
95
|
-
|
|
96
|
-
} );
|
|
97
|
-
|
|
98
|
-
const template = await saveEntityRecord(
|
|
101
|
+
const { title, description, slug } = template;
|
|
102
|
+
const newTemplate = await saveEntityRecord(
|
|
99
103
|
'postType',
|
|
100
104
|
'wp_template',
|
|
101
105
|
{
|
|
102
|
-
|
|
106
|
+
description,
|
|
103
107
|
// Slugs need to be strings, so this is for template `404`
|
|
104
108
|
slug: slug.toString(),
|
|
105
109
|
status: 'publish',
|
|
106
110
|
title,
|
|
111
|
+
// This adds a post meta field in template that is part of `is_custom` value calculation.
|
|
112
|
+
is_wp_suggestion: true,
|
|
107
113
|
},
|
|
108
114
|
{ throwOnError: true }
|
|
109
115
|
);
|
|
110
116
|
|
|
111
117
|
// Set template before navigating away to avoid initial stale value.
|
|
112
|
-
setTemplate(
|
|
118
|
+
setTemplate( newTemplate.id, newTemplate.slug );
|
|
113
119
|
|
|
114
120
|
// Navigate to the created template editor.
|
|
115
121
|
history.push( {
|
|
116
|
-
postId:
|
|
117
|
-
postType:
|
|
122
|
+
postId: newTemplate.id,
|
|
123
|
+
postType: newTemplate.type,
|
|
118
124
|
} );
|
|
119
125
|
|
|
120
126
|
// TODO: Add a success notice?
|
|
@@ -129,9 +135,9 @@ export default function NewTemplate( { postType } ) {
|
|
|
129
135
|
} );
|
|
130
136
|
}
|
|
131
137
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
138
|
+
const existingTemplateSlugs = ( existingTemplates || [] ).map(
|
|
139
|
+
( { slug } ) => slug
|
|
140
|
+
);
|
|
135
141
|
const missingTemplates = filter(
|
|
136
142
|
defaultTemplateTypes,
|
|
137
143
|
( template ) =>
|
|
@@ -139,54 +145,124 @@ export default function NewTemplate( { postType } ) {
|
|
|
139
145
|
! includes( existingTemplateSlugs, template.slug )
|
|
140
146
|
);
|
|
141
147
|
|
|
142
|
-
|
|
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
|
+
[]
|
|
197
|
+
);
|
|
198
|
+
if ( ! missingTemplates.length && ! extraTemplates.length ) {
|
|
143
199
|
return null;
|
|
144
200
|
}
|
|
145
|
-
|
|
146
201
|
// Update the sort order to match the DEFAULT_TEMPLATE_SLUGS order.
|
|
147
|
-
missingTemplates
|
|
202
|
+
missingTemplates?.sort( ( template1, template2 ) => {
|
|
148
203
|
return (
|
|
149
204
|
DEFAULT_TEMPLATE_SLUGS.indexOf( template1.slug ) -
|
|
150
205
|
DEFAULT_TEMPLATE_SLUGS.indexOf( template2.slug )
|
|
151
206
|
);
|
|
152
207
|
} );
|
|
153
|
-
|
|
208
|
+
// Append all extra templates at the end of the list for now.
|
|
209
|
+
missingTemplates.push( ...extraTemplates );
|
|
154
210
|
return (
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
<
|
|
170
|
-
{
|
|
171
|
-
missingTemplates
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
211
|
+
<>
|
|
212
|
+
<DropdownMenu
|
|
213
|
+
className="edit-site-new-template-dropdown"
|
|
214
|
+
icon={ null }
|
|
215
|
+
text={ postType.labels.add_new }
|
|
216
|
+
label={ postType.labels.add_new_item }
|
|
217
|
+
popoverProps={ {
|
|
218
|
+
noArrow: false,
|
|
219
|
+
} }
|
|
220
|
+
toggleProps={ {
|
|
221
|
+
variant: 'primary',
|
|
222
|
+
} }
|
|
223
|
+
>
|
|
224
|
+
{ () => (
|
|
225
|
+
<NavigableMenu className="edit-site-new-template-dropdown__popover">
|
|
226
|
+
<MenuGroup label={ postType.labels.add_new_item }>
|
|
227
|
+
{ missingTemplates.map( ( template ) => {
|
|
228
|
+
const {
|
|
229
|
+
title,
|
|
230
|
+
description,
|
|
231
|
+
slug,
|
|
232
|
+
onClick,
|
|
233
|
+
icon,
|
|
234
|
+
} = template;
|
|
235
|
+
return (
|
|
236
|
+
<MenuItem
|
|
237
|
+
icon={
|
|
238
|
+
icon ||
|
|
239
|
+
TEMPLATE_ICONS[ slug ] ||
|
|
240
|
+
post
|
|
241
|
+
}
|
|
242
|
+
iconPosition="left"
|
|
243
|
+
info={ description }
|
|
244
|
+
key={ slug }
|
|
245
|
+
onClick={ () =>
|
|
246
|
+
onClick
|
|
247
|
+
? onClick( template )
|
|
248
|
+
: createTemplate( template )
|
|
249
|
+
}
|
|
250
|
+
>
|
|
251
|
+
{ title }
|
|
252
|
+
</MenuItem>
|
|
253
|
+
);
|
|
254
|
+
} ) }
|
|
255
|
+
</MenuGroup>
|
|
256
|
+
</NavigableMenu>
|
|
257
|
+
) }
|
|
258
|
+
</DropdownMenu>
|
|
259
|
+
{ showCustomTemplateModal && (
|
|
260
|
+
<AddCustomTemplateModal
|
|
261
|
+
onClose={ () => setShowCustomTemplateModal( false ) }
|
|
262
|
+
onSelect={ createTemplate }
|
|
263
|
+
entityForSuggestions={ entityForSuggestions }
|
|
264
|
+
/>
|
|
189
265
|
) }
|
|
190
|
-
|
|
266
|
+
</>
|
|
191
267
|
);
|
|
192
268
|
}
|
|
@@ -9,3 +9,119 @@
|
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
+
|
|
13
|
+
.edit-site-custom-template-modal {
|
|
14
|
+
&__contents {
|
|
15
|
+
> div {
|
|
16
|
+
text-align: center;
|
|
17
|
+
cursor: pointer;
|
|
18
|
+
padding: $grid-unit-30;
|
|
19
|
+
border: 1px solid $gray-300;
|
|
20
|
+
border-radius: $radius-block-ui;
|
|
21
|
+
width: 256px;
|
|
22
|
+
display: flex;
|
|
23
|
+
flex-direction: column;
|
|
24
|
+
gap: $grid-unit;
|
|
25
|
+
align-items: center;
|
|
26
|
+
justify-content: center;
|
|
27
|
+
|
|
28
|
+
span {
|
|
29
|
+
color: $gray-700;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&:hover {
|
|
33
|
+
border-color: var(--wp-admin-theme-color);
|
|
34
|
+
|
|
35
|
+
h5 {
|
|
36
|
+
color: var(--wp-admin-theme-color);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
&:focus {
|
|
41
|
+
box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.components-search-control {
|
|
47
|
+
input[type="search"].components-search-control__input {
|
|
48
|
+
background: $white;
|
|
49
|
+
border: 1px solid $gray-300;
|
|
50
|
+
|
|
51
|
+
&:focus {
|
|
52
|
+
border-color: var(--wp-admin-theme-color);
|
|
53
|
+
box-shadow: 0 0 0 1px var(--wp-admin-theme-color);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@include break-medium() {
|
|
59
|
+
width: 456px;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.edit-site-custom-template-modal__suggestions_list {
|
|
64
|
+
margin-top: $grid-unit-20;
|
|
65
|
+
|
|
66
|
+
@include break-small() {
|
|
67
|
+
height: 232px;
|
|
68
|
+
overflow: scroll;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
&__list-item {
|
|
72
|
+
display: block;
|
|
73
|
+
width: 100%;
|
|
74
|
+
text-align: left;
|
|
75
|
+
white-space: pre-wrap;
|
|
76
|
+
overflow-wrap: break-word;
|
|
77
|
+
height: auto;
|
|
78
|
+
|
|
79
|
+
mark {
|
|
80
|
+
font-weight: 700;
|
|
81
|
+
background: none;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
&:hover {
|
|
85
|
+
background-color: $gray-100;
|
|
86
|
+
|
|
87
|
+
mark {
|
|
88
|
+
color: var(--wp-admin-theme-color);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
&:focus {
|
|
93
|
+
background-color: $gray-100;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
&:focus:not(:disabled) {
|
|
97
|
+
box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color) inset;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
&__title,
|
|
101
|
+
&__info {
|
|
102
|
+
overflow: hidden;
|
|
103
|
+
text-overflow: ellipsis;
|
|
104
|
+
display: block;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
&__title {
|
|
108
|
+
font-weight: 500;
|
|
109
|
+
margin-bottom: 0.2em;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
&__info {
|
|
113
|
+
color: $gray-700;
|
|
114
|
+
font-size: 0.9em;
|
|
115
|
+
line-height: 1.3;
|
|
116
|
+
word-break: break-all;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.edit-site-custom-template-modal__no-results {
|
|
122
|
+
border: 1px solid $gray-400;
|
|
123
|
+
border-radius: $radius-block-ui;
|
|
124
|
+
padding: $grid-unit-20;
|
|
125
|
+
margin-bottom: 0;
|
|
126
|
+
margin-top: $grid-unit-20;
|
|
127
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { get } from 'lodash';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { useSelect } from '@wordpress/data';
|
|
10
|
+
import { store as coreStore } from '@wordpress/core-data';
|
|
11
|
+
import { decodeEntities } from '@wordpress/html-entities';
|
|
12
|
+
import { useMemo } from '@wordpress/element';
|
|
13
|
+
|
|
14
|
+
export const usePostTypes = () => {
|
|
15
|
+
const postTypes = useSelect(
|
|
16
|
+
( select ) => select( coreStore ).getPostTypes( { per_page: -1 } ),
|
|
17
|
+
[]
|
|
18
|
+
);
|
|
19
|
+
return useMemo( () => {
|
|
20
|
+
const excludedPostTypes = [ 'attachment', 'page' ];
|
|
21
|
+
return postTypes?.filter(
|
|
22
|
+
( { viewable, slug } ) =>
|
|
23
|
+
viewable && ! excludedPostTypes.includes( slug )
|
|
24
|
+
);
|
|
25
|
+
}, [ postTypes ] );
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @typedef {Object} PostTypeEntitiesInfo
|
|
30
|
+
* @property {boolean} hasEntities If a postType has available entities.
|
|
31
|
+
* @property {number[]} existingPosts An array of the existing entities ids.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Helper hook that returns information about a post type having
|
|
36
|
+
* posts that we can create a specific template for.
|
|
37
|
+
*
|
|
38
|
+
* First we need to find the existing posts with an associated template,
|
|
39
|
+
* to query afterwards for any remaing post, by excluding them.
|
|
40
|
+
*
|
|
41
|
+
* @param {string[]} existingTemplates The existing templates.
|
|
42
|
+
* @return {Record<string,PostTypeEntitiesInfo>} An object with the postTypes as `keys` and PostTypeEntitiesInfo as values.
|
|
43
|
+
*/
|
|
44
|
+
export const usePostTypesEntitiesInfo = ( existingTemplates ) => {
|
|
45
|
+
const postTypes = usePostTypes();
|
|
46
|
+
const slugsToExcludePerEntity = useMemo( () => {
|
|
47
|
+
return postTypes?.reduce( ( accumulator, _postType ) => {
|
|
48
|
+
const slugsWithTemplates = ( existingTemplates || [] ).reduce(
|
|
49
|
+
( _accumulator, existingTemplate ) => {
|
|
50
|
+
const prefix = `single-${ _postType.slug }-`;
|
|
51
|
+
if ( existingTemplate.slug.startsWith( prefix ) ) {
|
|
52
|
+
_accumulator.push(
|
|
53
|
+
existingTemplate.slug.substring( prefix.length )
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
return _accumulator;
|
|
57
|
+
},
|
|
58
|
+
[]
|
|
59
|
+
);
|
|
60
|
+
if ( slugsWithTemplates.length ) {
|
|
61
|
+
accumulator[ _postType.slug ] = slugsWithTemplates;
|
|
62
|
+
}
|
|
63
|
+
return accumulator;
|
|
64
|
+
}, {} );
|
|
65
|
+
}, [ postTypes, existingTemplates ] );
|
|
66
|
+
const postsToExcludePerEntity = useSelect(
|
|
67
|
+
( select ) => {
|
|
68
|
+
if ( ! slugsToExcludePerEntity ) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const postsToExclude = Object.entries(
|
|
72
|
+
slugsToExcludePerEntity
|
|
73
|
+
).reduce( ( accumulator, [ slug, slugsWithTemplates ] ) => {
|
|
74
|
+
const postsWithTemplates = select( coreStore ).getEntityRecords(
|
|
75
|
+
'postType',
|
|
76
|
+
slug,
|
|
77
|
+
{
|
|
78
|
+
_fields: 'id',
|
|
79
|
+
context: 'view',
|
|
80
|
+
slug: slugsWithTemplates,
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
if ( postsWithTemplates?.length ) {
|
|
84
|
+
accumulator[ slug ] = postsWithTemplates;
|
|
85
|
+
}
|
|
86
|
+
return accumulator;
|
|
87
|
+
}, {} );
|
|
88
|
+
return postsToExclude;
|
|
89
|
+
},
|
|
90
|
+
[ slugsToExcludePerEntity ]
|
|
91
|
+
);
|
|
92
|
+
const entitiesInfo = useSelect(
|
|
93
|
+
( select ) => {
|
|
94
|
+
return postTypes?.reduce( ( accumulator, { slug } ) => {
|
|
95
|
+
const existingPosts =
|
|
96
|
+
postsToExcludePerEntity?.[ slug ]?.map(
|
|
97
|
+
( { id } ) => id
|
|
98
|
+
) || [];
|
|
99
|
+
accumulator[ slug ] = {
|
|
100
|
+
hasEntities: !! select( coreStore ).getEntityRecords(
|
|
101
|
+
'postType',
|
|
102
|
+
slug,
|
|
103
|
+
{
|
|
104
|
+
per_page: 1,
|
|
105
|
+
_fields: 'id',
|
|
106
|
+
context: 'view',
|
|
107
|
+
exclude: existingPosts,
|
|
108
|
+
}
|
|
109
|
+
)?.length,
|
|
110
|
+
existingPosts,
|
|
111
|
+
};
|
|
112
|
+
return accumulator;
|
|
113
|
+
}, {} );
|
|
114
|
+
},
|
|
115
|
+
[ postTypes, postsToExcludePerEntity ]
|
|
116
|
+
);
|
|
117
|
+
return entitiesInfo;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export const mapToIHasNameAndId = ( entities, path ) => {
|
|
121
|
+
return ( entities || [] ).map( ( entity ) => ( {
|
|
122
|
+
...entity,
|
|
123
|
+
name: decodeEntities( get( entity, path ) ),
|
|
124
|
+
} ) );
|
|
125
|
+
};
|
|
@@ -30,9 +30,8 @@ export default function BlockInspectorButton( { onClick = () => {} } ) {
|
|
|
30
30
|
} ),
|
|
31
31
|
[]
|
|
32
32
|
);
|
|
33
|
-
const { enableComplementaryArea, disableComplementaryArea } =
|
|
34
|
-
interfaceStore
|
|
35
|
-
);
|
|
33
|
+
const { enableComplementaryArea, disableComplementaryArea } =
|
|
34
|
+
useDispatch( interfaceStore );
|
|
36
35
|
|
|
37
36
|
const label = isBlockInspectorOpen
|
|
38
37
|
? __( 'Hide more settings' )
|
|
@@ -51,12 +51,8 @@ const LAYOUT = {
|
|
|
51
51
|
export default function BlockEditor( { setIsInserterOpen } ) {
|
|
52
52
|
const { storedSettings, templateType, templateId, page } = useSelect(
|
|
53
53
|
( select ) => {
|
|
54
|
-
const {
|
|
55
|
-
|
|
56
|
-
getEditedPostType,
|
|
57
|
-
getEditedPostId,
|
|
58
|
-
getPage,
|
|
59
|
-
} = select( editSiteStore );
|
|
54
|
+
const { getSettings, getEditedPostType, getEditedPostId, getPage } =
|
|
55
|
+
select( editSiteStore );
|
|
60
56
|
|
|
61
57
|
return {
|
|
62
58
|
storedSettings: getSettings( setIsInserterOpen ),
|
|
@@ -78,9 +74,8 @@ export default function BlockEditor( { setIsInserterOpen } ) {
|
|
|
78
74
|
const { restBlockPatterns, restBlockPatternCategories } = useSelect(
|
|
79
75
|
( select ) => ( {
|
|
80
76
|
restBlockPatterns: select( coreStore ).getBlockPatterns(),
|
|
81
|
-
restBlockPatternCategories:
|
|
82
|
-
coreStore
|
|
83
|
-
).getBlockPatternCategories(),
|
|
77
|
+
restBlockPatternCategories:
|
|
78
|
+
select( coreStore ).getBlockPatternCategories(),
|
|
84
79
|
} ),
|
|
85
80
|
[]
|
|
86
81
|
);
|
|
@@ -3,17 +3,11 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import Textarea from 'react-autosize-textarea';
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
* WordPress dependencies
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* WordPress dependencies
|
|
11
|
-
*/
|
|
12
6
|
/**
|
|
13
7
|
* WordPress dependencies
|
|
14
8
|
*/
|
|
15
9
|
import { __ } from '@wordpress/i18n';
|
|
16
|
-
import { useState } from '@wordpress/element';
|
|
10
|
+
import { useEffect, useState, useRef } from '@wordpress/element';
|
|
17
11
|
import { useInstanceId } from '@wordpress/compose';
|
|
18
12
|
import { VisuallyHidden } from '@wordpress/components';
|
|
19
13
|
|
|
@@ -21,6 +15,7 @@ export default function CodeEditorTextArea( { value, onChange, onInput } ) {
|
|
|
21
15
|
const [ stateValue, setStateValue ] = useState( value );
|
|
22
16
|
const [ isDirty, setIsDirty ] = useState( false );
|
|
23
17
|
const instanceId = useInstanceId( CodeEditorTextArea );
|
|
18
|
+
const valueRef = useRef();
|
|
24
19
|
|
|
25
20
|
if ( ! isDirty && stateValue !== value ) {
|
|
26
21
|
setStateValue( value );
|
|
@@ -42,6 +37,7 @@ export default function CodeEditorTextArea( { value, onChange, onInput } ) {
|
|
|
42
37
|
onInput( newValue );
|
|
43
38
|
setStateValue( newValue );
|
|
44
39
|
setIsDirty( true );
|
|
40
|
+
valueRef.current = newValue;
|
|
45
41
|
};
|
|
46
42
|
|
|
47
43
|
/**
|
|
@@ -56,6 +52,15 @@ export default function CodeEditorTextArea( { value, onChange, onInput } ) {
|
|
|
56
52
|
}
|
|
57
53
|
};
|
|
58
54
|
|
|
55
|
+
// Ensure changes aren't lost when component unmounts.
|
|
56
|
+
useEffect( () => {
|
|
57
|
+
return () => {
|
|
58
|
+
if ( valueRef.current ) {
|
|
59
|
+
onChange( valueRef.current );
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}, [] );
|
|
63
|
+
|
|
59
64
|
return (
|
|
60
65
|
<>
|
|
61
66
|
<VisuallyHidden
|
|
@@ -34,9 +34,8 @@ function EditTemplatePartMenuItem( { selectedClientId, onClose } ) {
|
|
|
34
34
|
const { params } = useLocation();
|
|
35
35
|
const selectedTemplatePart = useSelect(
|
|
36
36
|
( select ) => {
|
|
37
|
-
const block =
|
|
38
|
-
selectedClientId
|
|
39
|
-
);
|
|
37
|
+
const block =
|
|
38
|
+
select( blockEditorStore ).getBlock( selectedClientId );
|
|
40
39
|
|
|
41
40
|
if ( block && isTemplatePart( block ) ) {
|
|
42
41
|
const { theme, slug } = block.attributes;
|
|
@@ -119,10 +119,8 @@ function Editor( { onError } ) {
|
|
|
119
119
|
const { setPage, setIsInserterOpened } = useDispatch( editSiteStore );
|
|
120
120
|
const { enableComplementaryArea } = useDispatch( interfaceStore );
|
|
121
121
|
|
|
122
|
-
const [
|
|
123
|
-
|
|
124
|
-
setIsEntitiesSavedStatesOpen,
|
|
125
|
-
] = useState( false );
|
|
122
|
+
const [ isEntitiesSavedStatesOpen, setIsEntitiesSavedStatesOpen ] =
|
|
123
|
+
useState( false );
|
|
126
124
|
const openEntitiesSavedStates = useCallback(
|
|
127
125
|
() => setIsEntitiesSavedStatesOpen( true ),
|
|
128
126
|
[]
|
|
@@ -217,7 +215,8 @@ function Editor( { onError } ) {
|
|
|
217
215
|
<InterfaceSkeleton
|
|
218
216
|
labels={ {
|
|
219
217
|
...interfaceLabels,
|
|
220
|
-
secondarySidebar:
|
|
218
|
+
secondarySidebar:
|
|
219
|
+
secondarySidebarLabel,
|
|
221
220
|
} }
|
|
222
221
|
className={
|
|
223
222
|
showIconLabels &&
|
|
@@ -27,6 +27,7 @@ function ContextMenu( { name, parentMenu = '' } ) {
|
|
|
27
27
|
<NavigationButtonAsItem
|
|
28
28
|
icon={ typography }
|
|
29
29
|
path={ parentMenu + '/typography' }
|
|
30
|
+
aria-label={ __( 'Typography styles' ) }
|
|
30
31
|
>
|
|
31
32
|
{ __( 'Typography' ) }
|
|
32
33
|
</NavigationButtonAsItem>
|
|
@@ -35,6 +36,7 @@ function ContextMenu( { name, parentMenu = '' } ) {
|
|
|
35
36
|
<NavigationButtonAsItem
|
|
36
37
|
icon={ color }
|
|
37
38
|
path={ parentMenu + '/colors' }
|
|
39
|
+
aria-label={ __( 'Colors styles' ) }
|
|
38
40
|
>
|
|
39
41
|
{ __( 'Colors' ) }
|
|
40
42
|
</NavigationButtonAsItem>
|
|
@@ -43,6 +45,7 @@ function ContextMenu( { name, parentMenu = '' } ) {
|
|
|
43
45
|
<NavigationButtonAsItem
|
|
44
46
|
icon={ layout }
|
|
45
47
|
path={ parentMenu + '/layout' }
|
|
48
|
+
aria-label={ __( 'Layout styles' ) }
|
|
46
49
|
>
|
|
47
50
|
{ __( 'Layout' ) }
|
|
48
51
|
</NavigationButtonAsItem>
|
|
@@ -48,9 +48,8 @@ const cleanEmptyObject = ( object ) => {
|
|
|
48
48
|
|
|
49
49
|
function useGlobalStylesUserConfig() {
|
|
50
50
|
const { globalStylesId, settings, styles } = useSelect( ( select ) => {
|
|
51
|
-
const _globalStylesId =
|
|
52
|
-
coreStore
|
|
53
|
-
).__experimentalGetCurrentGlobalStylesId();
|
|
51
|
+
const _globalStylesId =
|
|
52
|
+
select( coreStore ).__experimentalGetCurrentGlobalStylesId();
|
|
54
53
|
const record = _globalStylesId
|
|
55
54
|
? select( coreStore ).getEditedEntityRecord(
|
|
56
55
|
'root',
|
|
@@ -108,11 +107,8 @@ function useGlobalStylesBaseConfig() {
|
|
|
108
107
|
}
|
|
109
108
|
|
|
110
109
|
function useGlobalStylesContext() {
|
|
111
|
-
const [
|
|
112
|
-
|
|
113
|
-
userConfig,
|
|
114
|
-
setUserConfig,
|
|
115
|
-
] = useGlobalStylesUserConfig();
|
|
110
|
+
const [ isUserConfigReady, userConfig, setUserConfig ] =
|
|
111
|
+
useGlobalStylesUserConfig();
|
|
116
112
|
const [ isBaseConfigReady, baseConfig ] = useGlobalStylesBaseConfig();
|
|
117
113
|
const mergedConfig = useMemo( () => {
|
|
118
114
|
if ( ! baseConfig || ! userConfig ) {
|