diff --git a/packages/edit-site/src/components/add-new-template/add-custom-generic-template-modal-content.js b/packages/edit-site/src/components/add-new-template/add-custom-generic-template-modal-content.js
new file mode 100644
index 0000000000000..6da96e791679b
--- /dev/null
+++ b/packages/edit-site/src/components/add-new-template/add-custom-generic-template-modal-content.js
@@ -0,0 +1,82 @@
+/**
+ * External dependencies
+ */
+import { kebabCase } from 'lodash';
+
+/**
+ * WordPress dependencies
+ */
+import { useState } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import {
+ Button,
+ TextControl,
+ __experimentalHStack as HStack,
+ __experimentalVStack as VStack,
+} from '@wordpress/components';
+
+function AddCustomGenericTemplateModalContent( { onClose, createTemplate } ) {
+ const [ title, setTitle ] = useState( '' );
+ const defaultTitle = __( 'Custom Template' );
+ const [ isBusy, setIsBusy ] = useState( false );
+ async function onCreateTemplate( event ) {
+ event.preventDefault();
+ if ( isBusy ) {
+ return;
+ }
+ setIsBusy( true );
+ try {
+ await createTemplate(
+ {
+ slug:
+ 'wp-custom-template-' +
+ kebabCase( title || defaultTitle ),
+ title: title || defaultTitle,
+ },
+ false
+ );
+ } finally {
+ setIsBusy( false );
+ }
+ }
+ return (
+
+ );
+}
+
+export default AddCustomGenericTemplateModalContent;
diff --git a/packages/edit-site/src/components/add-new-template/add-custom-generic-template-modal.js b/packages/edit-site/src/components/add-new-template/add-custom-generic-template-modal.js
deleted file mode 100644
index 05688d032a591..0000000000000
--- a/packages/edit-site/src/components/add-new-template/add-custom-generic-template-modal.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * External dependencies
- */
-import { kebabCase } from 'lodash';
-
-/**
- * WordPress dependencies
- */
-import { useState } from '@wordpress/element';
-import { __ } from '@wordpress/i18n';
-import {
- Button,
- Modal,
- TextControl,
- __experimentalHStack as HStack,
- __experimentalVStack as VStack,
-} from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import TemplateActionsLoadingScreen from './template-actions-loading-screen';
-
-function AddCustomGenericTemplateModal( {
- onClose,
- createTemplate,
- isCreatingTemplate,
-} ) {
- const [ title, setTitle ] = useState( '' );
- const defaultTitle = __( 'Custom Template' );
- const [ isBusy, setIsBusy ] = useState( false );
- async function onCreateTemplate( event ) {
- event.preventDefault();
- if ( isBusy ) {
- return;
- }
- setIsBusy( true );
- try {
- await createTemplate(
- {
- slug:
- 'wp-custom-template-' +
- kebabCase( title || defaultTitle ),
- title: title || defaultTitle,
- },
- false
- );
- } finally {
- setIsBusy( false );
- }
- }
- return (
- {
- onClose();
- } }
- overlayClassName="edit-site-custom-generic-template__modal"
- >
- { isCreatingTemplate && }
-
-
- );
-}
-
-export default AddCustomGenericTemplateModal;
diff --git a/packages/edit-site/src/components/add-new-template/add-custom-template-modal.js b/packages/edit-site/src/components/add-new-template/add-custom-template-modal-content.js
similarity index 89%
rename from packages/edit-site/src/components/add-new-template/add-custom-template-modal.js
rename to packages/edit-site/src/components/add-new-template/add-custom-template-modal-content.js
index ccab5d82bd058..5636ec16e1ac1 100644
--- a/packages/edit-site/src/components/add-new-template/add-custom-template-modal.js
+++ b/packages/edit-site/src/components/add-new-template/add-custom-template-modal-content.js
@@ -2,12 +2,11 @@
* WordPress dependencies
*/
import { useState, useMemo, useEffect } from '@wordpress/element';
-import { __, sprintf } from '@wordpress/i18n';
+import { __ } from '@wordpress/i18n';
import {
Button,
Flex,
FlexItem,
- Modal,
SearchControl,
TextHighlight,
__experimentalText as Text,
@@ -23,7 +22,6 @@ import { decodeEntities } from '@wordpress/html-entities';
/**
* Internal dependencies
*/
-import TemplateActionsLoadingScreen from './template-actions-loading-screen';
import { mapToIHasNameAndId } from './utils';
const EMPTY_ARRAY = [];
@@ -179,36 +177,25 @@ function SuggestionList( { entityForSuggestions, onSelect } ) {
);
}
-function AddCustomTemplateModal( {
- onClose,
- onSelect,
- entityForSuggestions,
- isCreatingTemplate,
-} ) {
+function AddCustomTemplateModalContent( { onSelect, entityForSuggestions } ) {
const [ showSearchEntities, setShowSearchEntities ] = useState(
entityForSuggestions.hasGeneralTemplate
);
- const baseCssClass = 'edit-site-custom-template-modal';
return (
-
- { isCreatingTemplate && }
{ ! showSearchEntities && (
-
+ <>
{ __(
'Select whether to create a single template for all items or a specific one.'
) }
@@ -272,10 +259,10 @@ function AddCustomTemplateModal( {
-
+ >
) }
{ showSearchEntities && (
-
+ <>
{ __(
'This template will be used only for the specific item chosen.'
@@ -285,10 +272,10 @@ function AddCustomTemplateModal( {
entityForSuggestions={ entityForSuggestions }
onSelect={ onSelect }
/>
-
+ >
) }
-
+
);
}
-export default AddCustomTemplateModal;
+export default AddCustomTemplateModalContent;
diff --git a/packages/edit-site/src/components/add-new-template/new-template.js b/packages/edit-site/src/components/add-new-template/new-template.js
index 3db38fffdee81..841d45749e628 100644
--- a/packages/edit-site/src/components/add-new-template/new-template.js
+++ b/packages/edit-site/src/components/add-new-template/new-template.js
@@ -1,34 +1,22 @@
+/**
+ * External dependencies
+ */
+import classnames from 'classnames';
+
/**
* WordPress dependencies
*/
import {
- DropdownMenu,
- MenuGroup,
- MenuItem,
- Tooltip,
- VisuallyHidden,
+ Button,
+ Modal,
+ __experimentalGrid as Grid,
+ __experimentalText as Text,
+ __experimentalVStack as VStack,
} from '@wordpress/components';
import { useState } from '@wordpress/element';
import { useDispatch } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
-import {
- archive,
- blockMeta,
- category,
- home,
- list,
- media,
- notFound,
- page,
- plus,
- post,
- postAuthor,
- postDate,
- postList,
- search,
- tag,
- layout as customGenericTemplateIcon,
-} from '@wordpress/icons';
+import { plus } from '@wordpress/icons';
import { __, sprintf } from '@wordpress/i18n';
import { store as noticesStore } from '@wordpress/notices';
import { privateApis as routerPrivateApis } from '@wordpress/router';
@@ -36,7 +24,7 @@ import { privateApis as routerPrivateApis } from '@wordpress/router';
/**
* Internal dependencies
*/
-import AddCustomTemplateModal from './add-custom-template-modal';
+import AddCustomTemplateModalContent from './add-custom-template-modal-content';
import {
useExistingTemplates,
useDefaultTemplateTypes,
@@ -45,7 +33,7 @@ import {
useAuthorMenuItem,
usePostTypeArchiveMenuItems,
} from './utils';
-import AddCustomGenericTemplateModal from './add-custom-generic-template-modal';
+import AddCustomGenericTemplateModalContent from './add-custom-generic-template-modal-content';
import TemplateActionsLoadingScreen from './template-actions-loading-screen';
import { store as editSiteStore } from '../../store';
import { unlock } from '../../private-apis';
@@ -68,21 +56,35 @@ const DEFAULT_TEMPLATE_SLUGS = [
'404',
];
-const TEMPLATE_ICONS = {
- 'front-page': home,
- home: postList,
- single: post,
- page,
- archive,
- search,
- 404: notFound,
- index: list,
- category,
- author: postAuthor,
- taxonomy: blockMeta,
- date: postDate,
- tag,
- attachment: media,
+function TemplateListItem( { title, description, onClick } ) {
+ return (
+
+ );
+}
+
+const modalContentMap = {
+ templatesList: 1,
+ customTemplate: 2,
+ customGenericTemplate: 3,
};
export default function NewTemplate( {
@@ -90,8 +92,10 @@ export default function NewTemplate( {
toggleProps,
showIcon = true,
} ) {
- const [ showCustomTemplateModal, setShowCustomTemplateModal ] =
- useState( false );
+ const [ showModal, setShowModal ] = useState( false );
+ const [ modalContent, setModalContent ] = useState(
+ modalContentMap.templatesList
+ );
const [
showCustomGenericTemplateModal,
setShowCustomGenericTemplateModal,
@@ -159,130 +163,114 @@ export default function NewTemplate( {
setIsCreatingTemplate( false );
}
}
+ const onModalClose = () => {
+ setShowModal( false );
+ setModalContent( modalContentMap.templatesList );
+ };
- const missingTemplates = useMissingTemplates(
- setEntityForSuggestions,
- setShowCustomTemplateModal
+ const missingTemplates = useMissingTemplates( setEntityForSuggestions, () =>
+ setModalContent( modalContentMap.customTemplate )
);
if ( ! missingTemplates.length ) {
return null;
}
+ const { as: Toggle = Button, ...restToggleProps } = toggleProps ?? {};
- const customTemplateDescription = __(
- 'A custom template can be manually applied to any post or page.'
- );
-
+ let modalTitle = __( 'Add template' );
+ if ( modalContent === modalContentMap.customTemplate ) {
+ modalTitle = sprintf(
+ // translators: %s: Name of the post type e.g: "Post".
+ __( 'Add template: %s' ),
+ entityForSuggestions.labels.singular_name
+ );
+ } else if ( showCustomGenericTemplateModal ) {
+ modalTitle = __( 'Create custom template' );
+ }
return (
<>
- }
+ setShowModal( true ) }
icon={ showIcon ? plus : null }
- text={ showIcon ? null : postType.labels.add_new }
label={ postType.labels.add_new_item }
- popoverProps={ {
- noArrow: false,
- } }
- toggleProps={ toggleProps }
>
- { () => (
- <>
- { isCreatingTemplate && (
-
- ) }
-
-
- { missingTemplates.map( ( template ) => {
- const {
- title,
- description,
- slug,
- onClick,
- icon,
- } = template;
- return (
-
-
-
- );
- } ) }
-
-
-
-
-
-
-
- >
- ) }
-
- { showCustomTemplateModal && (
- setShowCustomTemplateModal( false ) }
- onSelect={ createTemplate }
- entityForSuggestions={ entityForSuggestions }
- isCreatingTemplate={ isCreatingTemplate }
- />
- ) }
- { showCustomGenericTemplateModal && (
- setShowCustomGenericTemplateModal( false ) }
- createTemplate={ createTemplate }
- isCreatingTemplate={ isCreatingTemplate }
- />
+ />
+ );
+ } ) }
+
+ setShowCustomGenericTemplateModal( true )
+ }
+ />
+
+ ) }
+ { modalContent === modalContentMap.customTemplate && (
+
+ ) }
+ { modalContent ===
+ modalContentMap.customGenericTemplate && (
+
+ ) }
+
) }
>
);
}
-function useMissingTemplates(
- setEntityForSuggestions,
- setShowCustomTemplateModal
-) {
+function useMissingTemplates( setEntityForSuggestions, onClick ) {
const existingTemplates = useExistingTemplates();
const defaultTemplateTypes = useDefaultTemplateTypes();
const existingTemplateSlugs = ( existingTemplates || [] ).map(
@@ -294,7 +282,7 @@ function useMissingTemplates(
! existingTemplateSlugs.includes( template.slug )
);
const onClickMenuItem = ( _entityForSuggestions ) => {
- setShowCustomTemplateModal( true );
+ onClick?.();
setEntityForSuggestions( _entityForSuggestions );
};
// We need to replace existing default template types with
diff --git a/packages/edit-site/src/components/add-new-template/style.scss b/packages/edit-site/src/components/add-new-template/style.scss
index fc33da1f35a13..f0617ad62fc5b 100644
--- a/packages/edit-site/src/components/add-new-template/style.scss
+++ b/packages/edit-site/src/components/add-new-template/style.scss
@@ -1,70 +1,23 @@
-.edit-site-new-template-dropdown {
- .edit-site-new-template-dropdown__menu-groups {
- @include break-small() {
- min-width: 300px;
- }
- }
+.edit-site-custom-template-modal {
+ &__contents-wrapper {
+ height: 100%;
+ justify-content: flex-start !important; // Required as topLeft alignment isn't working on VStack
- // The specificity is needed to override the default tooltip styles.
- &__menu-item-tooltip.components-tooltip .components-popover__content {
- max-width: 320px;
- padding: $grid-unit-10 $grid-unit-15;
- border-radius: 2px;
- white-space: pre-wrap;
- min-width: 0;
- width: auto;
- text-align: left;
- }
-}
+ > * {
+ width: 100%;
+ }
-.edit-site-custom-template-modal {
- &__suggestions_list {
- margin-left: - $grid-unit-15;
- margin-right: - $grid-unit-15;
+ &__suggestions_list {
+ margin-left: - $grid-unit-15;
+ margin-right: - $grid-unit-15;
+ width: calc(100% + #{$grid-unit-15 * 2});
+ }
}
&__contents {
> .components-button {
- padding: $grid-unit-30;
- border-radius: $radius-block-ui;
height: auto;
- display: flex;
- flex-direction: column;
justify-content: center;
- border: $border-width solid $gray-300;
-
- // Show the boundary of the button, in High Contrast Mode.
- outline: 1px solid transparent;
-
- span:first-child {
- color: $gray-900;
- }
-
- span {
- color: $gray-700;
- }
-
- &:hover {
- color: var(--wp-admin-theme-color-darker-10);
- background: rgba(var(--wp-admin-theme-color--rgb), 0.04);
- border-color: transparent;
-
- span {
- color: var(--wp-admin-theme-color);
- }
- }
-
- &:focus {
- box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
- border-color: transparent;
-
- // Windows High Contrast mode will show this outline, but not the box-shadow.
- outline: 3px solid transparent;
-
- span:first-child {
- color: var(--wp-admin-theme-color);
- }
- }
}
}
@@ -86,7 +39,6 @@
.edit-site-custom-template-modal__suggestions_list {
@include break-small() {
- height: 232px;
overflow: scroll;
}
@@ -177,5 +129,72 @@
align-items: center;
justify-content: center;
height: 100%;
+ position: absolute;
+ left: 50%;
+ transform: translateX(-50%);
+ }
+}
+
+.edit-site-add-new-template__modal {
+ max-width: $grid-unit-80 * 13;
+ width: calc(100% - #{$grid-unit-80});
+ margin-top: $grid-unit-80;
+ max-height: calc(100% - #{$grid-unit-80 * 2});
+
+ @include break-large() {
+ width: calc(100% - #{$grid-unit-80 * 2});
+ }
+}
+
+.edit-site-custom-template-modal__contents,
+.edit-site-add-new-template__template-list__contents {
+ > .components-button {
+ padding: $grid-unit-30;
+ border-radius: $radius-block-ui;
+ display: flex;
+ flex-direction: column;
+ border: $border-width solid $gray-300;
+ min-height: $grid-unit-80 * 3;
+
+ // Show the boundary of the button, in High Contrast Mode.
+ outline: 1px solid transparent;
+
+ span:first-child {
+ color: $gray-900;
+ }
+
+ span {
+ color: $gray-700;
+ }
+
+ &:hover {
+ color: var(--wp-admin-theme-color-darker-10);
+ background: rgba(var(--wp-admin-theme-color--rgb), 0.04);
+ border-color: transparent;
+
+ span {
+ color: var(--wp-admin-theme-color);
+ }
+ }
+
+ &:focus {
+ box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
+ border-color: transparent;
+
+ // Windows High Contrast mode will show this outline, but not the box-shadow.
+ outline: 3px solid transparent;
+
+ span:first-child {
+ color: var(--wp-admin-theme-color);
+ }
+ }
+ }
+}
+
+.edit-site-add-new-template__template-list__contents {
+ > .components-button {
+ height: 100%;
+ text-align: start;
+ align-items: flex-start;
}
}
diff --git a/test/e2e/specs/site-editor/site-editor-url-navigation.spec.js b/test/e2e/specs/site-editor/site-editor-url-navigation.spec.js
index edc4909a98c97..5668832e4162c 100644
--- a/test/e2e/specs/site-editor/site-editor-url-navigation.spec.js
+++ b/test/e2e/specs/site-editor/site-editor-url-navigation.spec.js
@@ -45,7 +45,7 @@ test.describe( 'Site editor url navigation', () => {
] );
await page.click( 'role=button[name="Add New Template"i]' );
await page
- .getByRole( 'menuitem', {
+ .getByRole( 'button', {
name: 'Single item: Post',
} )
.click();