diff --git a/packages/e2e-tests/experimental-features.js b/packages/e2e-tests/experimental-features.js index 0976b2c4086037..51dae0605d975c 100644 --- a/packages/e2e-tests/experimental-features.js +++ b/packages/e2e-tests/experimental-features.js @@ -157,4 +157,31 @@ export const siteEditor = { return ''; } ); }, + + async disableWelcomeGuide() { + const isWelcomeGuideActive = await page.evaluate( () => + wp.data.select( 'core/edit-site' ).isFeatureActive( 'welcomeGuide' ) + ); + const isWelcomeGuideStyesActive = await page.evaluate( () => + wp.data + .select( 'core/edit-site' ) + .isFeatureActive( 'welcomeGuideStyles' ) + ); + + if ( isWelcomeGuideActive ) { + await page.evaluate( () => + wp.data + .dispatch( 'core/edit-site' ) + .toggleFeature( 'welcomeGuide' ) + ); + } + + if ( isWelcomeGuideStyesActive ) { + await page.evaluate( () => + wp.data + .dispatch( 'core/edit-site' ) + .toggleFeature( 'welcomeGuideStyles' ) + ); + } + }, }; diff --git a/packages/e2e-tests/specs/experiments/document-settings.test.js b/packages/e2e-tests/specs/experiments/document-settings.test.js index c3a13c75abb102..0d764a3e3dda34 100644 --- a/packages/e2e-tests/specs/experiments/document-settings.test.js +++ b/packages/e2e-tests/specs/experiments/document-settings.test.js @@ -36,6 +36,7 @@ describe( 'Document Settings', () => { beforeEach( async () => { await siteEditor.visit(); + await siteEditor.disableWelcomeGuide(); } ); describe( 'when a template is selected from the navigation sidebar', () => { diff --git a/packages/e2e-tests/specs/experiments/multi-entity-editing.test.js b/packages/e2e-tests/specs/experiments/multi-entity-editing.test.js index c2090e340f39cf..8d8a6ac7e4fc7d 100644 --- a/packages/e2e-tests/specs/experiments/multi-entity-editing.test.js +++ b/packages/e2e-tests/specs/experiments/multi-entity-editing.test.js @@ -145,6 +145,7 @@ describe( 'Multi-entity editor states', () => { it( 'should not display any dirty entities when loading the site editor', async () => { await siteEditor.visit(); + await siteEditor.disableWelcomeGuide(); expect( await openEntitySavePanel() ).toBe( false ); } ); @@ -204,6 +205,7 @@ describe( 'Multi-entity editor states', () => { ); await saveAllEntities(); await siteEditor.visit(); + await siteEditor.disableWelcomeGuide(); // Wait for site editor to load. await canvas().waitForSelector( diff --git a/packages/e2e-tests/specs/experiments/multi-entity-saving.test.js b/packages/e2e-tests/specs/experiments/multi-entity-saving.test.js index fd73d280166e14..a8429cc24a475f 100644 --- a/packages/e2e-tests/specs/experiments/multi-entity-saving.test.js +++ b/packages/e2e-tests/specs/experiments/multi-entity-saving.test.js @@ -244,6 +244,7 @@ describe( 'Multi-entity save flow', () => { postId: 'tt1-blocks//index', postType: 'wp_template', } ); + await siteEditor.disableWelcomeGuide(); // Select the header template part via list view. await page.click( '.edit-site-header-toolbar__list-view-toggle' ); diff --git a/packages/e2e-tests/specs/experiments/settings-sidebar.test.js b/packages/e2e-tests/specs/experiments/settings-sidebar.test.js index be3e44fce32b47..d36bc9bc092250 100644 --- a/packages/e2e-tests/specs/experiments/settings-sidebar.test.js +++ b/packages/e2e-tests/specs/experiments/settings-sidebar.test.js @@ -53,6 +53,7 @@ describe( 'Settings sidebar', () => { } ); beforeEach( async () => { await siteEditor.visit(); + await siteEditor.disableWelcomeGuide(); } ); describe( 'Template tab', () => { diff --git a/packages/e2e-tests/specs/experiments/site-editor-export.test.js b/packages/e2e-tests/specs/experiments/site-editor-export.test.js index 961a19525c6a23..b534509de4b006 100644 --- a/packages/e2e-tests/specs/experiments/site-editor-export.test.js +++ b/packages/e2e-tests/specs/experiments/site-editor-export.test.js @@ -41,6 +41,7 @@ describe( 'Site Editor Templates Export', () => { beforeEach( async () => { await siteEditor.visit(); + await siteEditor.disableWelcomeGuide(); } ); it( 'clicking export should download edit-site-export.zip file', async () => { diff --git a/packages/e2e-tests/specs/experiments/site-editor-inserter.test.js b/packages/e2e-tests/specs/experiments/site-editor-inserter.test.js index 3aa7d649f86ef1..fab65066206a3f 100644 --- a/packages/e2e-tests/specs/experiments/site-editor-inserter.test.js +++ b/packages/e2e-tests/specs/experiments/site-editor-inserter.test.js @@ -19,6 +19,7 @@ describe( 'Site Editor Inserter', () => { } ); beforeEach( async () => { await siteEditor.visit(); + await siteEditor.disableWelcomeGuide(); } ); it( 'inserter toggle button should toggle global inserter', async () => { diff --git a/packages/e2e-tests/specs/experiments/template-part.test.js b/packages/e2e-tests/specs/experiments/template-part.test.js index ddec6e7d362018..8f18da2b88006e 100644 --- a/packages/e2e-tests/specs/experiments/template-part.test.js +++ b/packages/e2e-tests/specs/experiments/template-part.test.js @@ -36,6 +36,7 @@ describe( 'Template Part', () => { describe( 'Template part block', () => { beforeEach( async () => { await siteEditor.visit(); + await siteEditor.disableWelcomeGuide(); } ); async function navigateToHeader() { diff --git a/packages/e2e-tests/specs/experiments/template-revert.test.js b/packages/e2e-tests/specs/experiments/template-revert.test.js index 67a167728cbdd9..771578215ca701 100644 --- a/packages/e2e-tests/specs/experiments/template-revert.test.js +++ b/packages/e2e-tests/specs/experiments/template-revert.test.js @@ -16,7 +16,11 @@ import { addQueryArgs } from '@wordpress/url'; */ import { siteEditor } from '../../experimental-features'; -const { visit: visitSiteEditor, getEditedPostContent } = siteEditor; +const { + visit: visitSiteEditor, + getEditedPostContent, + disableWelcomeGuide, +} = siteEditor; const assertSaveButtonIsDisabled = () => page.waitForSelector( @@ -97,6 +101,7 @@ describe( 'Template Revert', () => { beforeEach( async () => { await trashAllPosts( 'wp_template' ); await visitSiteEditor(); + await disableWelcomeGuide(); } ); it( 'should delete the template after saving the reverted template', async () => { diff --git a/packages/e2e-tests/specs/performance/site-editor.test.js b/packages/e2e-tests/specs/performance/site-editor.test.js index 6e3f801d5905a8..db2c5987cc24a7 100644 --- a/packages/e2e-tests/specs/performance/site-editor.test.js +++ b/packages/e2e-tests/specs/performance/site-editor.test.js @@ -84,6 +84,7 @@ describe( 'Site Editor Performance', () => { ); await siteEditor.visit( { postId: id, postType: 'page' } ); + await siteEditor.disableWelcomeGuide(); let i = 3; diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js index 796f3ac135a877..467cd854f8f4c6 100644 --- a/packages/edit-site/src/components/editor/index.js +++ b/packages/edit-site/src/components/editor/index.js @@ -39,6 +39,7 @@ import URLQueryController from '../url-query-controller'; import InserterSidebar from '../secondary-sidebar/inserter-sidebar'; import ListViewSidebar from '../secondary-sidebar/list-view-sidebar'; import ErrorBoundary from '../error-boundary'; +import WelcomeGuide from '../welcome-guide'; import { store as editSiteStore } from '../../store'; import { GlobalStylesRenderer } from './global-styles-renderer'; import { GlobalStylesProvider } from '../global-styles/global-styles-provider'; @@ -288,6 +289,7 @@ function Editor( { initialSettings, onError } ) { } footer={ } /> + diff --git a/packages/edit-site/src/components/welcome-guide/editor.js b/packages/edit-site/src/components/welcome-guide/editor.js new file mode 100644 index 00000000000000..680423118eaeb1 --- /dev/null +++ b/packages/edit-site/src/components/welcome-guide/editor.js @@ -0,0 +1,63 @@ +/** + * WordPress dependencies + */ +import { useDispatch } from '@wordpress/data'; +import { Guide } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import { createInterpolateElement } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import WelcomeGuideImage from './image'; +import { store as editSiteStore } from '../../store'; + +export default function WelcomeGuideEditor() { + const { toggleFeature } = useDispatch( editSiteStore ); + + return ( + toggleFeature( 'welcomeGuide' ) } + pages={ [ + { + image: ( + + ), + content: ( + <> +

+ { __( 'Edit your site' ) } +

+

+ { __( + 'Design everything on your site — from the header right down to the footer — using blocks.' + ) } +

+

+ { createInterpolateElement( + __( + 'Click to start designing your blocks, and choose your typography, layout, and colors.' + ), + { + StylesIconImage: ( + { + ), + } + ) } +

+ + ), + }, + ] } + /> + ); +} diff --git a/packages/edit-site/src/components/welcome-guide/image.js b/packages/edit-site/src/components/welcome-guide/image.js new file mode 100644 index 00000000000000..5f2fcc6e10bd4c --- /dev/null +++ b/packages/edit-site/src/components/welcome-guide/image.js @@ -0,0 +1,11 @@ +export default function WelcomeGuideImage( { nonAnimatedSrc, animatedSrc } ) { + return ( + + + + + ); +} diff --git a/packages/edit-site/src/components/welcome-guide/index.js b/packages/edit-site/src/components/welcome-guide/index.js new file mode 100644 index 00000000000000..44736a15374602 --- /dev/null +++ b/packages/edit-site/src/components/welcome-guide/index.js @@ -0,0 +1,33 @@ +/** + * WordPress dependencies + */ +import { useSelect } from '@wordpress/data'; +import { store as interfaceStore } from '@wordpress/interface'; + +/** + * Internal dependencies + */ +import WelcomeGuideEditor from './editor'; +import WelcomeGuideStyles from './styles'; +import { store as editSiteStore } from '../../store'; + +export default function WelcomeGuide() { + const { isActive, isStylesOpen } = useSelect( ( select ) => { + const sidebar = select( interfaceStore ).getActiveComplementaryArea( + editSiteStore.name + ); + const isStylesSidebar = sidebar === 'edit-site/global-styles'; + const feature = isStylesSidebar ? 'welcomeGuideStyles' : 'welcomeGuide'; + + return { + isActive: select( editSiteStore ).isFeatureActive( feature ), + isStylesOpen: isStylesSidebar, + }; + }, [] ); + + if ( ! isActive ) { + return null; + } + + return isStylesOpen ? : ; +} diff --git a/packages/edit-site/src/components/welcome-guide/style.scss b/packages/edit-site/src/components/welcome-guide/style.scss new file mode 100644 index 00000000000000..78cc70d0b426c5 --- /dev/null +++ b/packages/edit-site/src/components/welcome-guide/style.scss @@ -0,0 +1,37 @@ +.edit-site-welcome-guide { + width: 312px; + + &__image { + background: #00a0d2; + margin: 0 0 $grid-unit-20; + > img { + display: block; + max-width: 100%; + object-fit: cover; + } + } + + &__heading { + font-family: $default-font; + font-size: 24px; + line-height: 1.4; + margin: $grid-unit-20 0 $grid-unit-20 0; + padding: 0 $grid-unit-40; + } + + &__text { + font-size: $default-font-size; + line-height: 1.4; + margin: 0 0 $grid-unit-20 0; + padding: 0 $grid-unit-40; + + img { + vertical-align: bottom; + } + } + + &__inserter-icon { + margin: 0 4px; + vertical-align: text-top; + } +} diff --git a/packages/edit-site/src/components/welcome-guide/styles.js b/packages/edit-site/src/components/welcome-guide/styles.js new file mode 100644 index 00000000000000..1dae8045535fbc --- /dev/null +++ b/packages/edit-site/src/components/welcome-guide/styles.js @@ -0,0 +1,116 @@ +/** + * WordPress dependencies + */ +import { useDispatch } from '@wordpress/data'; +import { ExternalLink, Guide } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import WelcomeGuideImage from './image'; +import { store as editSiteStore } from '../../store'; + +export default function WelcomeGuideStyles() { + const { toggleFeature } = useDispatch( editSiteStore ); + + return ( + toggleFeature( 'welcomeGuideStyles' ) } + pages={ [ + { + image: ( + + ), + content: ( + <> +

+ { __( 'Welcome to Styles' ) } +

+

+ { __( + 'Tweak your site, or give it a whole new look! Get creative — how about a new color palette for your buttons, or choosing a new font? Take a look at what you can do here.' + ) } +

+ + ), + }, + { + image: ( + + ), + content: ( + <> +

+ { __( 'Set the design' ) } +

+

+ { __( + 'You can customize your site as much as you like with different colors, typography, and layouts. Or if you prefer, just leave it up to your theme to handle! ' + ) } +

+ + ), + }, + { + image: ( + + ), + content: ( + <> +

+ { __( 'Personalize blocks' ) } +

+

+ { __( + 'You can adjust your blocks to ensure a cohesive experience across your site — add your unique colors to a branded Button block, or adjust the Heading block to your preferred size.' + ) } +

+ + ), + }, + { + image: ( + + ), + content: ( + <> +

+ { __( 'Learn more' ) } +

+

+ { __( + 'New to block themes and styling your site? ' + ) } + + { __( + 'Here’s a detailed guide to learn how to make the most of it.' + ) } + +

+ + ), + }, + ] } + /> + ); +} diff --git a/packages/edit-site/src/plugins/index.js b/packages/edit-site/src/plugins/index.js index 0971eff7be792c..9c74d64010380c 100644 --- a/packages/edit-site/src/plugins/index.js +++ b/packages/edit-site/src/plugins/index.js @@ -16,6 +16,7 @@ import { download } from '@wordpress/icons'; * Internal dependencies */ import ToolsMoreMenuGroup from '../components/header/tools-more-menu-group'; +import WelcomeGuideMenuItem from './welcome-guide-menu-item'; registerPlugin( 'edit-site', { render() { @@ -45,6 +46,7 @@ registerPlugin( 'edit-site', { > { __( 'Export' ) } + ); diff --git a/packages/edit-site/src/plugins/welcome-guide-menu-item.js b/packages/edit-site/src/plugins/welcome-guide-menu-item.js new file mode 100644 index 00000000000000..5a20582b59435f --- /dev/null +++ b/packages/edit-site/src/plugins/welcome-guide-menu-item.js @@ -0,0 +1,35 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { useDispatch, useSelect } from '@wordpress/data'; +import { MenuItem } from '@wordpress/components'; +import { store as interfaceStore } from '@wordpress/interface'; + +/** + * Internal dependencies + */ +import { store as editSiteStore } from '../store'; + +export default function WelcomeGuideMenuItem() { + const { toggleFeature } = useDispatch( editSiteStore ); + const isStylesOpen = useSelect( ( select ) => { + const sidebar = select( interfaceStore ).getActiveComplementaryArea( + editSiteStore.name + ); + + return sidebar === 'edit-site/global-styles'; + }, [] ); + + return ( + + toggleFeature( + isStylesOpen ? 'welcomeGuideStyles' : 'welcomeGuide' + ) + } + > + { __( 'Welcome Guide' ) } + + ); +} diff --git a/packages/edit-site/src/store/defaults.js b/packages/edit-site/src/store/defaults.js index d3a1116465d978..f351ef21533b3b 100644 --- a/packages/edit-site/src/store/defaults.js +++ b/packages/edit-site/src/store/defaults.js @@ -1,3 +1,6 @@ export const PREFERENCES_DEFAULTS = { - features: {}, + features: { + welcomeGuide: true, + welcomeGuideStyles: true, + }, }; diff --git a/packages/edit-site/src/style.scss b/packages/edit-site/src/style.scss index 1aa89763c7a373..7142a750eef460 100644 --- a/packages/edit-site/src/style.scss +++ b/packages/edit-site/src/style.scss @@ -13,6 +13,7 @@ @import "./components/template-details/style.scss"; @import "./components/template-part-converter/style.scss"; @import "./components/secondary-sidebar/style.scss"; +@import "./components/welcome-guide/style.scss"; // In order to use mix-blend-mode, this element needs to have an explicitly set background-color. // We scope it to .wp-toolbar to be wp-admin only, to prevent bleed into other implementations.