Skip to content

Commit

Permalink
NUX: Make tips appear inline
Browse files Browse the repository at this point in the history
Improve the usability of NUX tips by making them appear as inline
notices rather than floating popovers.

Adds a new InlineTip component to accomplish this.
  • Loading branch information
noisysocks committed Jul 15, 2019
1 parent cf1da64 commit 2011a87
Show file tree
Hide file tree
Showing 25 changed files with 256 additions and 253 deletions.
3 changes: 1 addition & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/block-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@wordpress/i18n": "file:../i18n",
"@wordpress/is-shallow-equal": "file:../is-shallow-equal",
"@wordpress/keycodes": "file:../keycodes",
"@wordpress/nux": "file:../nux",
"@wordpress/rich-text": "file:../rich-text",
"@wordpress/token-list": "file:../token-list",
"@wordpress/url": "file:../url",
Expand Down
4 changes: 4 additions & 0 deletions packages/block-editor/src/components/block-inspector/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { __ } from '@wordpress/i18n';
import { getBlockType, getUnregisteredTypeHandlerName } from '@wordpress/blocks';
import { PanelBody } from '@wordpress/components';
import { withSelect } from '@wordpress/data';
import { InlineTip } from '@wordpress/nux';

/**
* Internal dependencies
Expand Down Expand Up @@ -51,6 +52,9 @@ const BlockInspector = ( {

return (
<>
<InlineTip tipId="core/editor.blockInspector" className="block-editor-block-inspector__tip">
{ __( 'The block tab contains additional settings for the selected block.' ) }
</InlineTip>
<div className="editor-block-inspector__card block-editor-block-inspector__card">
<BlockIcon icon={ blockType.icon } showColors />
<div className="editor-block-inspector__card-content block-editor-block-inspector__card-content">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
text-align: center;
}

.block-editor-block-inspector__tip {
margin: 0 0 16px 0;
}

.block-editor-block-inspector__card {
display: flex;
Expand Down
11 changes: 10 additions & 1 deletion packages/block-editor/src/components/inserter/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import scrollIntoView from 'dom-scroll-into-view';
*/
import { __, _n, _x, sprintf } from '@wordpress/i18n';
import { Component, createRef } from '@wordpress/element';
import { withSpokenMessages, PanelBody } from '@wordpress/components';
import { withSpokenMessages, PanelBody, ExternalLink } from '@wordpress/components';
import {
getCategories,
isReusableBlock,
Expand All @@ -33,6 +33,7 @@ import { withDispatch, withSelect } from '@wordpress/data';
import { withInstanceId, compose, withSafeTimeout } from '@wordpress/compose';
import { LEFT, RIGHT, UP, DOWN, BACKSPACE, ENTER } from '@wordpress/keycodes';
import { addQueryArgs } from '@wordpress/url';
import { InlineTip } from '@wordpress/nux';

/**
* Internal dependencies
Expand Down Expand Up @@ -290,6 +291,14 @@ export class InserterMenu extends Component {
aria-label={ __( 'Available block types' ) }
>

<InlineTip tipId="core/editor.inserter" className="block-editor-inserter__tip">
{ __( 'There are Blocks for most types of content: text, headings, images, lists, and lots more!' ) }
{ ' ' }
<ExternalLink href="https://wordpress.org/support/article/wordpress-editor/#blocks">
{ __( 'Learn more' ) }
</ExternalLink>
</InlineTip>

<ChildBlocks
rootClientId={ rootClientId }
items={ childItems }
Expand Down
4 changes: 4 additions & 0 deletions packages/block-editor/src/components/inserter/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ $block-inserter-search-height: 38px;
}
}

.block-editor-inserter__tip {
margin: 0 0 $grid-size-large 0;
}

.block-editor-inserter__popover .block-editor-block-types-list {
margin: 0 -8px;
}
Expand Down
4 changes: 0 additions & 4 deletions packages/e2e-test-utils/src/create-new-post.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,4 @@ export async function createNewPost( {
const action = _enableTips ? 'enableTips' : 'disableTips';
wp.data.dispatch( 'core/nux' )[ action ]();
}, enableTips );

if ( enableTips ) {
await page.reload();
}
}
209 changes: 63 additions & 146 deletions packages/e2e-tests/specs/nux.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,179 +2,96 @@
* WordPress dependencies
*/
import {
clickBlockAppender,
clickOnMoreMenuItem,
createNewPost,
saveDraft,
insertBlock,
openGlobalBlockInserter,
toggleScreenOption,
} from '@wordpress/e2e-test-utils';

describe( 'New User Experience (NUX)', () => {
async function clickAllTips( page ) {
// Click through all available tips.
const tips = await getTips( page );
const numberOfTips = tips.tipIds.length;

for ( let i = 1; i < numberOfTips; i++ ) {
await page.click( '.nux-dot-tip .components-button.is-link' );
}

return { numberOfTips, tips };
}

async function getTips( page ) {
return await page.evaluate( () => {
return wp.data.select( 'core/nux' ).getAssociatedGuide( 'core/editor.inserter' );
} );
}

async function getTipsEnabled( page ) {
return await page.evaluate( () => {
return wp.data.select( 'core/nux' ).areTipsEnabled();
} );
}
/**
* Queries the data store and returns whether or not NUX tips are enabled.
*
* @return {boolean} Whether or not NUX tips are enabled.
*/
async function areTipsEnabled() {
return await page.evaluate( () => wp.data.select( 'core/nux' ).areTipsEnabled() );
}

describe( 'New User Experience (NUX)', () => {
beforeEach( async () => {
await createNewPost( { enableTips: true } );
} );

it( 'should show tips to a first-time user', async () => {
const firstTipText = await page.$eval( '.nux-dot-tip', ( element ) => element.innerText );
expect( firstTipText ).toContain( 'Welcome to the wonderful world of blocks!' );

const [ nextTipButton ] = await page.$x( "//button[contains(text(), 'See next tip')]" );
await nextTipButton.click();

const secondTipText = await page.$eval( '.nux-dot-tip', ( element ) => element.innerText );
expect( secondTipText ).toContain( 'You’ll find more settings for your page and blocks in the sidebar.' );
} );

it( 'should show "Got it" once all tips have been displayed', async () => {
await clickAllTips( page );
it( 'should show a tip in the inserter', async () => {
// Open up the inserter.
await openGlobalBlockInserter();

// Make sure "Got it" button appears on the last tip.
const gotItButton = await page.$x( "//button[contains(text(), 'Got it')]" );
expect( gotItButton ).toHaveLength( 1 );

// Click the "Got it button".
await page.click( '.nux-dot-tip .components-button.is-link' );

// Verify no more tips are visible on the page.
const nuxTipElements = await page.$$( '.nux-dot-tip' );
expect( nuxTipElements ).toHaveLength( 0 );

// Tips should not be marked as disabled, but when the user has seen all
// of the available tips, they will not appear.
const areTipsEnabled = await getTipsEnabled( page );
expect( areTipsEnabled ).toEqual( true );
// Check there's a tip in the inserter.
const inserterTip = await page.$( '.block-editor-inserter__tip' );
expect( inserterTip ).not.toBeNull();
} );

it( 'should hide and disable tips if "disable tips" button is clicked', async () => {
await page.click( '.nux-dot-tip__disable' );

// Verify no more tips are visible on the page.
let nuxTipElements = await page.$$( '.nux-dot-tip' );
expect( nuxTipElements ).toHaveLength( 0 );
it( 'should show a tip in the block inspector', async () => {
// Insert any old block.
await insertBlock( 'Paragraph' );

// We should be disabling the tips so they don't appear again.
const areTipsEnabled = await getTipsEnabled( page );
expect( areTipsEnabled ).toEqual( false );

// Refresh the page; tips should not show because they were disabled.
await page.reload();

nuxTipElements = await page.$$( '.nux-dot-tip' );
expect( nuxTipElements ).toHaveLength( 0 );
// Check there's a tip in the block inspector.
const blockInspectorTip = await page.$( '.block-editor-block-inspector__tip' );
expect( blockInspectorTip ).not.toBeNull();
} );

it( 'should enable tips when the "Enable tips" option is toggled on', async () => {
// Start by disabling tips.
await page.click( '.nux-dot-tip__disable' );

// Verify no more tips are visible on the page.
let nuxTipElements = await page.$$( '.nux-dot-tip' );
expect( nuxTipElements ).toHaveLength( 0 );

// Tips should be disabled in localStorage as well.
let areTipsEnabled = await getTipsEnabled( page );
expect( areTipsEnabled ).toEqual( false );
it( 'should dismiss a single tip if X button is clicked and dialog is dismissed', async () => {
// We need to *dismiss* the upcoming confirm() dialog, so let's temporarily
// remove the listener that was added in by enablePageDialogAccept().
const listeners = page.rawListeners( 'dialog' );
page.removeAllListeners( 'dialog' );

// Toggle the 'Enable Tips' option to enable.
await toggleScreenOption( 'Enable Tips' );
// Open up the inserter.
await openGlobalBlockInserter();

// Tips should once again appear.
nuxTipElements = await page.$$( '.nux-dot-tip' );
expect( nuxTipElements ).toHaveLength( 1 );
// Dismiss the upcoming confirm() dialog.
page.once( 'dialog', async ( dialog ) => {
await dialog.dismiss();
} );

// Tips should be enabled in localStorage as well.
areTipsEnabled = await getTipsEnabled( page );
expect( areTipsEnabled ).toEqual( true );
} );
// Click the tip's X button.
await page.click( '.block-editor-inserter__tip button[aria-label="Dismiss this notice"]' );

// TODO: This test should be enabled once
// https://github.com/WordPress/gutenberg/issues/7458 is fixed.
it.skip( 'should show tips as disabled if all tips have been shown', async () => {
await clickAllTips( page );
// The tip should be gone.
const inserterTip = await page.$( '.block-editor-inserter__tip' );
expect( inserterTip ).toBeNull();

// Open the "More" menu to check the "Show Tips" element.
await page.click( '.edit-post-more-menu [aria-label="More tools & options"]' );
const showTipsButton = await page.$x( '//button[contains(text(), "Show Tips")][@aria-pressed="false"]' );
// Tips should still be enabled.
expect( await areTipsEnabled() ).toBe( true );

expect( showTipsButton ).toHaveLength( 1 );
// Restore the listeners that we removed above.
for ( const listener of listeners ) {
page.addListener( 'dialog', listener );
}
} );

// TODO: This test should be enabled once
// https://github.com/WordPress/gutenberg/issues/7458 is fixed.
it.skip( 'should reset tips if all tips have been shown and show tips was unchecked', async () => {
const { numberOfTips } = await clickAllTips( page );

// Click again to re-enable tips; they should appear.
await clickOnMoreMenuItem( 'Show Tips' );
it( 'should disable all tips if X button is clicked and dialog is confirmed', async () => {
// Open up the inserter.
await openGlobalBlockInserter();

// Open the "More" menu to check the "Show Tips" element.
await page.click( '.edit-post-more-menu [aria-label="More tools & options"]' );
const showTipsButton = await page.$x( '//button[contains(text(), "Show Tips")][@aria-pressed="true"]' );
// Dismiss the tip. (The confirm() dialog will automatically be accepted.)
await page.click( '.block-editor-inserter__tip button[aria-label="Dismiss this notice"]' );

expect( showTipsButton ).toHaveLength( 1 );
// The tip should be gone.
const inserterTip = await page.$( '.block-editor-inserter__tip' );
expect( inserterTip ).toBeNull();

// Tips should re-appear on the page.
const nuxTipElements = await page.$$( '.nux-dot-tip' );
expect( nuxTipElements ).toHaveLength( 1 );

// Tips should be enabled again.
const areTipsEnabled = await getTipsEnabled( page );
expect( areTipsEnabled ).toEqual( true );

// Dismissed tips should be reset and ready to be shown again.
const resetTips = await getTips( page );
const newNumberOfTips = resetTips.tipIds.length;
expect( newNumberOfTips ).toHaveLength( numberOfTips );
// Tips should now be disabled.
expect( await areTipsEnabled() ).toBe( false );
} );

// TODO: This test should be enabled once
// https://github.com/WordPress/gutenberg/issues/7753 is fixed.
// See: https://github.com/WordPress/gutenberg/issues/7753#issuecomment-403952816
it.skip( 'should show tips if "Show tips" was disabled on a draft and then enabled', async () => {
// Click the "Show tips" button (enabled by default) to disable tips.
await clickOnMoreMenuItem( 'Show Tips' );

// Let's type something so there's content in this post.
await page.click( '.editor-post-title__input' );
await page.keyboard.type( 'Post title' );
await clickBlockAppender();
await page.keyboard.type( 'Post content goes here.' );
await saveDraft();

// Refresh the page; tips should be disabled.
await page.reload();
let nuxTipElements = await page.$$( '.nux-dot-tip' );
expect( nuxTipElements ).toHaveLength( 0 );

// Clicking should re-enable tips.
await clickOnMoreMenuItem( 'Show Tips' );

// Tips should re-appear on the page.
nuxTipElements = await page.$$( '.nux-dot-tip' );
expect( nuxTipElements ).toHaveLength( 1 );
it( 'should enable and disable tips when option is toggled', async () => {
// Toggling the option off should disable tips.
await toggleScreenOption( 'Enable Tips', false );
expect( await areTipsEnabled() ).toBe( false );

// Toggling the option on should enable tips.
await toggleScreenOption( 'Enable Tips', true );
expect( await areTipsEnabled() ).toBe( true );
} );
} );
1 change: 0 additions & 1 deletion packages/edit-post/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
"@wordpress/hooks": "file:../hooks",
"@wordpress/i18n": "file:../i18n",
"@wordpress/keycodes": "file:../keycodes",
"@wordpress/nux": "file:../nux",
"@wordpress/plugins": "file:../plugins",
"@wordpress/url": "file:../url",
"@wordpress/viewport": "file:../viewport",
Expand Down
15 changes: 0 additions & 15 deletions packages/edit-post/src/components/editor-initialization/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
/**
* WordPress dependencies
*/
import { useEffect } from '@wordpress/element';
import { useDispatch } from '@wordpress/data';

/**
* Internal dependencies
*/
Expand All @@ -24,14 +18,5 @@ export default function( { postId } ) {
useAdjustSidebarListener( postId );
useBlockSelectionListener( postId );
useUpdatePostLinkListener( postId );
const { triggerGuide } = useDispatch( 'core/nux' );
useEffect( () => {
triggerGuide( [
'core/editor.inserter',
'core/editor.settings',
'core/editor.preview',
'core/editor.publish',
] );
}, [ triggerGuide ] );
return null;
}
Loading

0 comments on commit 2011a87

Please sign in to comment.