diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 09216372ae68b..aecd4e223d693 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -1,5 +1,10 @@ ## Master +### Deprecations + +- The `Guide` component no longer supports passing pages as children. Use the `pages` prop instead. +- The `GuidePage` component is deprecated. Use the `pages` prop in `Guide` instead. + ## 9.2.0 (2020-02-10) ### Enhancements diff --git a/packages/components/src/guide/README.md b/packages/components/src/guide/README.md index 84c354f1674df..cae55dabd4fb4 100644 --- a/packages/components/src/guide/README.md +++ b/packages/components/src/guide/README.md @@ -1,7 +1,7 @@ Guide ======== -`Guide` is a React component that renders a _user guide_ in a modal. The guide consists of several `GuidePage` components which the user can step through one by one. The guide is finished when the modal is closed or when the user clicks _Finish_ on the last page of the guide. +`Guide` is a React component that renders a _user guide_ in a modal. The guide consists of several pages which the user can step through one by one. The guide is finished when the modal is closed or when the user clicks _Finish_ on the last page of the guide. ## Usage @@ -13,14 +13,20 @@ function MyTutorial() { return null; } - setIsOpen( false ) }> - -

Welcome to the ACME Store! Select a category to begin browsing our wares.

-
- -

When you find something you love, click Add to Cart to add the product to your shopping cart.

-
-
+ return ( + setIsOpen( false ) } + pages={ [ + { + content:

Welcome to the ACME Store!

, + }, + { + image: , + content:

Click Add to Cart to buy a product.

, + }, + ] } + /> + ); } ``` @@ -35,10 +41,11 @@ A function which is called when the guide is finished. The guide is finished whe - Type: `function` - Required: Yes -### children +### pages -A list of `GuidePage` components. One page is shown at a time. +A list of objects describing each page in the guide. Each object **must** contain a `'content'` property and may optionally contain a `'image'` property. +- Type: `array` - Required: Yes ### className diff --git a/packages/components/src/guide/icons.js b/packages/components/src/guide/icons.js index 7c589cc2af926..1f9713d6fdd8c 100644 --- a/packages/components/src/guide/icons.js +++ b/packages/components/src/guide/icons.js @@ -1,28 +1,14 @@ /** * WordPress dependencies */ -import { SVG, Path, Circle } from '@wordpress/primitives'; - -export const BackButtonIcon = () => ( - - - - -); - -export const ForwardButtonIcon = () => ( - - - - -); +import { SVG, Circle } from '@wordpress/primitives'; export const PageControlIcon = ( { isSelected } ) => ( - + diff --git a/packages/components/src/guide/index.js b/packages/components/src/guide/index.js index 857df38df0ffd..4bbc7198b668a 100644 --- a/packages/components/src/guide/index.js +++ b/packages/components/src/guide/index.js @@ -6,7 +6,8 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { useState, Children } from '@wordpress/element'; +import { useState, useEffect, Children } from '@wordpress/element'; +import deprecated from '@wordpress/deprecated'; import { __ } from '@wordpress/i18n'; /** @@ -16,7 +17,6 @@ import Modal from '../modal'; import KeyboardShortcuts from '../keyboard-shortcuts'; import Button from '../button'; import PageControl from './page-control'; -import { BackButtonIcon, ForwardButtonIcon } from './icons'; import FinishButton from './finish-button'; export default function Guide( { @@ -25,12 +25,24 @@ export default function Guide( { contentLabel, finishButtonText, onFinish, + pages = [], } ) { const [ currentPage, setCurrentPage ] = useState( 0 ); - const numberOfPages = Children.count( children ); + useEffect( () => { + if ( Children.count( children ) ) { + deprecated( 'Passing children to ', { + alternative: 'the `pages` prop', + } ); + } + }, [ children ] ); + + if ( Children.count( children ) ) { + pages = Children.map( children, ( child ) => ( { content: child } ) ); + } + const canGoBack = currentPage > 0; - const canGoForward = currentPage < numberOfPages - 1; + const canGoForward = currentPage < pages.length - 1; const goBack = () => { if ( canGoBack ) { @@ -44,7 +56,7 @@ export default function Guide( { } }; - if ( numberOfPages === 0 ) { + if ( pages.length === 0 ) { return null; } @@ -63,36 +75,39 @@ export default function Guide( { />
- { children[ currentPage ] } +
+ { pages[ currentPage ].image } - { ! canGoForward && ( - - { finishButtonText || __( 'Finish' ) } - - ) } + + + { pages[ currentPage ].content } + + { ! canGoForward && ( + + { finishButtonText || __( 'Finish' ) } + + ) } +
{ canGoBack && ( ) } - { canGoForward && ( { isOpen && ( - - { times( numberOfPages, ( page ) => ( - -

- Page { page + 1 } of { numberOfPages } -

-

{ loremIpsum }

-
- ) ) } -
+ ( { + content: ( + <> +

+ Page { page + 1 } of { numberOfPages } +

+

{ loremIpsum }

+ + ), + } ) ) } + /> ) } ); diff --git a/packages/components/src/guide/style.scss b/packages/components/src/guide/style.scss index 0afc819f9f718..b2ca62dcb2ac7 100644 --- a/packages/components/src/guide/style.scss +++ b/packages/components/src/guide/style.scss @@ -1,56 +1,97 @@ .components-guide { + $image-height: 300px; + $image-width: 320px; + + @include break-small() { + width: 600px; + } + .components-modal__header { background: none; border-bottom: none; + width: 100%; + padding: 0; + margin: 0; .components-button { align-self: flex-start; - margin-top: $grid-unit-30; + margin: $grid-unit-10 $grid-unit-10 0 0; position: static; + + &:hover { + svg { + fill: #fff; + } + } } } &__container { display: flex; flex-direction: column; + justify-content: space-between; margin-top: -$header-height; min-height: 100%; } + &__page { + display: flex; + flex-direction: column; + justify-content: center; + position: relative; + + @include break-small() { + min-height: $image-height; + } + } + &__footer { align-content: center; display: flex; height: 30px; justify-content: center; - margin: auto 0 $grid-unit-30 0; + margin: 0 0 $grid-unit-30 0; + padding: 0 $grid-unit-40; position: relative; width: 100%; - @include break-small() { - margin: $grid-unit-30 0 0; + @media (max-width: $break-small) { + position: absolute; + bottom: 0; } } &__page-control { - margin: 0; + margin: $grid-unit-10 0 $grid-unit-10 0; + text-align: center; li { display: inline-block; - margin: 0 2px; } .components-button { height: 30px; + min-width: 20px; } } + + .components-modal__content { + padding: 0; + } } .components-modal__frame.components-guide { + border: none; + min-width: 312px; + height: 80vh; + max-height: 575px; + @media (max-width: $break-small) { - bottom: 15%; - left: $grid-unit-30; - right: $grid-unit-30; - top: 15%; + bottom: 5%; + left: $grid-unit-20; + right: $grid-unit-20; + top: 5%; + margin: 0 auto; } } @@ -64,55 +105,33 @@ &.components-guide__back-button, &.components-guide__forward-button { - font-size: 0; + font-size: $default-font-size; padding: 4px 2px; &.has-text svg { margin: 0; } - @include break-small() { - font-size: $default-font-size; + &:hover { + text-decoration: underline; } } &.components-guide__back-button { - left: 0; - - @include break-small() { - padding: 4px 8px 4px 2px; - - &.has-text svg { - margin-right: 4px; - } - } + left: $grid-unit-40; } &.components-guide__forward-button { - right: 0; - - @include break-small() { - padding: 4px 2px 4px 8px; - - &.has-text svg { - margin-left: 4px; - order: 1; - } - } + right: $grid-unit-40; + color: #1386bf; + font-weight: bold; } &.components-guide__finish-button { - display: none; - right: 0; - - @include break-small() { - display: block; - } + right: $grid-unit-40; } &.components-guide__inline-finish-button { - @include break-small() { - display: none; - } + display: none; } } diff --git a/packages/components/src/guide/test/index.js b/packages/components/src/guide/test/index.js index 7739987e502be..f2e1a584c7ca3 100644 --- a/packages/components/src/guide/test/index.js +++ b/packages/components/src/guide/test/index.js @@ -7,7 +7,6 @@ import { shallow } from 'enzyme'; * Internal dependencies */ import Guide from '../'; -import GuidePage from '../page'; import PageControl from '../page-control'; import Modal from '../../modal'; @@ -19,20 +18,24 @@ describe( 'Guide', () => { it( 'renders one page at a time', () => { const wrapper = shallow( - - Page 1 - Page 2 - + Page 1

}, + { content:

Page 2

}, + ] } + /> ); - expect( wrapper.find( GuidePage ) ).toHaveLength( 1 ); + expect( wrapper.find( 'p' ) ).toHaveLength( 1 ); } ); it( 'hides back button and shows forward button on the first page', () => { const wrapper = shallow( - - Page 1 - Page 2 - + Page 1

}, + { content:

Page 2

}, + ] } + /> ); expect( wrapper.find( PageControl ).prop( 'currentPage' ) ).toBe( 0 ); expect( wrapper.find( '.components-guide__back-button' ) ).toHaveLength( @@ -48,10 +51,12 @@ describe( 'Guide', () => { it( 'shows back button and shows finish button on the last page', () => { const wrapper = shallow( - - Page 1 - Page 2 - + Page 1

}, + { content:

Page 2

}, + ] } + /> ); wrapper.find( '.components-guide__forward-button' ).simulate( 'click' ); expect( wrapper.find( PageControl ).prop( 'currentPage' ) ).toBe( 1 ); @@ -69,9 +74,10 @@ describe( 'Guide', () => { it( 'calls onFinish when the finish button is clicked', () => { const onFinish = jest.fn(); const wrapper = shallow( - - Page 1 - + Page 1

} ] } + /> ); wrapper.find( '.components-guide__finish-button' ).simulate( 'click' ); expect( onFinish ).toHaveBeenCalled(); @@ -80,9 +86,10 @@ describe( 'Guide', () => { it( 'calls onFinish when the modal is closed', () => { const onFinish = jest.fn(); const wrapper = shallow( - - Page 1 - + Page 1

} ] } + /> ); wrapper.find( Modal ).prop( 'onRequestClose' )(); expect( onFinish ).toHaveBeenCalled(); diff --git a/packages/edit-post/src/components/welcome-guide/images.js b/packages/edit-post/src/components/welcome-guide/images.js index f809e54ce40d7..bdaf23deb1b72 100644 --- a/packages/edit-post/src/components/welcome-guide/images.js +++ b/packages/edit-post/src/components/welcome-guide/images.js @@ -4,35 +4,71 @@ import { __ } from '@wordpress/i18n'; export const CanvasImage = ( props ) => ( - + <> + + + ); export const EditorImage = ( props ) => ( - + <> + + + ); export const BlockLibraryImage = ( props ) => ( - + <> + + + ); export const DocumentationImage = ( props ) => ( - + <> + + + ); export const InserterIconImage = ( props ) => ( diff --git a/packages/edit-post/src/components/welcome-guide/index.js b/packages/edit-post/src/components/welcome-guide/index.js index ad58758315cb3..56c30202af172 100644 --- a/packages/edit-post/src/components/welcome-guide/index.js +++ b/packages/edit-post/src/components/welcome-guide/index.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import { useSelect, useDispatch } from '@wordpress/data'; -import { ExternalLink, Guide, GuidePage } from '@wordpress/components'; +import { ExternalLink, Guide } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { createInterpolateElement } from '@wordpress/element'; @@ -36,68 +36,82 @@ export default function WelcomeGuide() { contentLabel={ __( 'Welcome to the block editor' ) } finishButtonText={ __( 'Get started' ) } onFinish={ () => toggleFeature( 'welcomeGuide' ) } - > - -

- { __( 'Welcome to the block editor' ) } -

- -

- { __( - 'In the WordPress editor, each paragraph, image, or video is presented as a distinct “block” of content.' - ) } -

-
- - -

- { __( 'Make each block your own' ) } -

- -

- { __( - 'Each block comes with its own set of controls for changing things like color, width, and alignment. These will show and hide automatically when you have a block selected.' - ) } -

-
- - -

- { __( 'Get to know the block library' ) } -

- -

- { createInterpolateElement( - __( - 'All of the blocks available to you live in the block library. You’ll find it wherever you see the icon.' - ), - { - InserterIconImage: ( - - ), - } - ) } -

-
- - -

- { __( 'Learn how to use the block editor' ) } -

- -

- { __( - 'New to the block editor? Want to learn more about using it? ' - ) } - - { __( "Here's a detailed guide." ) } - -

-
-
+ pages={ [ + { + image: , + content: ( + <> +

+ { __( 'Welcome to the block editor' ) } +

+

+ { __( + 'In the WordPress editor, each paragraph, image, or video is presented as a distinct “block” of content.' + ) } +

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

+ { __( 'Make each block your own' ) } +

+

+ { __( + 'Each block comes with its own set of controls for changing things like color, width, and alignment. These will show and hide automatically when you have a block selected.' + ) } +

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

+ { __( 'Get to know the block library' ) } +

+

+ { createInterpolateElement( + __( + 'All of the blocks available to you live in the block library. You’ll find it wherever you see the icon.' + ), + { + InserterIconImage: ( + + ), + } + ) } +

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

+ { __( 'Learn how to use the block editor' ) } +

+

+ { __( + 'New to the block editor? Want to learn more about using it? ' + ) } + + { __( "Here's a detailed guide." ) } + +

+ + ), + }, + ] } + /> ); } diff --git a/packages/edit-post/src/components/welcome-guide/style.scss b/packages/edit-post/src/components/welcome-guide/style.scss index b5ac8faba14a8..63ef009bcf752 100644 --- a/packages/edit-post/src/components/welcome-guide/style.scss +++ b/packages/edit-post/src/components/welcome-guide/style.scss @@ -1,55 +1,44 @@ .edit-post-welcome-guide { - $image-height: 300px; - $image-width: 320px; + $image-height: 240px; + $image-width: 312px; + width: 312px; - &__page { - display: flex; - flex-direction: column; - justify-content: center; - position: relative; + &__image { + background: #00a0d2; + height: 240px; + + &__prm-r { + display: none; + } - @include break-small() { - min-height: $image-height; - padding-left: $image-width + $grid-unit-30; + @media (prefers-reduced-motion: reduce) { + &__prm-r { + display: block; + } + + &__prm-np { + display: none; + } } } &__heading { font-family: $editor-font; - font-size: 21px; + font-size: 24px; line-height: 1.4; - margin: $grid-unit-10 0; - } - - &__image { - background: #66c6e4; - border-radius: $radius-round-rectangle; - height: 200px; - margin: $grid-unit-10 0; - - @include break-small() { - position: absolute; - left: 0; - top: 50%; - height: $image-height; - width: $image-width; - margin-top: -0.5 * $image-height; - } + margin: 0 0 $grid-unit-20 0; + padding: 0 $grid-unit-40; } &__text { - font-size: $editor-font-size; + font-size: $default-font-size; line-height: 1.4; - margin: $grid-unit-10 0; + margin: 0 0 $grid-unit-30 0; + padding: 0 $grid-unit-40; } &__inserter-icon { margin: 0 4px; - position: relative; - top: 4px; - } - - @include break-small() { - width: 600px; + vertical-align: text-top; } }