Skip to content

Commit

Permalink
Add Show Tips toggle (#7163)
Browse files Browse the repository at this point in the history
* Add Show Tips toggle

Let the user re-enable tips via a Show Tips toggle in the More menu.

* Typo: sholud → should
  • Loading branch information
noisysocks authored and gziolo committed Jun 19, 2018
1 parent f0b0aac commit 879929f
Show file tree
Hide file tree
Showing 13 changed files with 181 additions and 51 deletions.
24 changes: 9 additions & 15 deletions edit-post/components/header/fixed-toolbar-toggle/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,18 @@ import { withSelect, withDispatch } from '@wordpress/data';
*/
import { __ } from '@wordpress/i18n';
import { compose } from '@wordpress/element';
import { MenuGroup, MenuItem, withInstanceId } from '@wordpress/components';
import { MenuItem } from '@wordpress/components';
import { ifViewportMatches } from '@wordpress/viewport';

function FeatureToggle( { onToggle, isActive } ) {
function FixedToolbarToggle( { onToggle, isActive } ) {
return (
<MenuGroup
label={ __( 'Settings' ) }
filterName="editPost.MoreMenu.settings"
<MenuItem
icon={ isActive && 'yes' }
isSelected={ isActive }
onClick={ onToggle }
>
<MenuItem
icon={ isActive && 'yes' }
isSelected={ isActive }
onClick={ onToggle }
>
{ __( 'Fix Toolbar to Top' ) }
</MenuItem>
</MenuGroup>
{ __( 'Fix Toolbar to Top' ) }
</MenuItem>
);
}

Expand All @@ -39,5 +34,4 @@ export default compose( [
},
} ) ),
ifViewportMatches( 'medium' ),
withInstanceId,
] )( FeatureToggle );
] )( FixedToolbarToggle );
9 changes: 8 additions & 1 deletion edit-post/components/header/more-menu/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import './style.scss';
import ModeSwitcher from '../mode-switcher';
import FixedToolbarToggle from '../fixed-toolbar-toggle';
import PluginMoreMenuGroup from '../plugins-more-menu-group';
import TipsToggle from '../tips-toggle';

const MoreMenu = () => (
<Dropdown
Expand All @@ -27,7 +28,13 @@ const MoreMenu = () => (
renderContent={ ( { onClose } ) => (
<div className="edit-post-more-menu__content">
<ModeSwitcher onSelect={ onClose } />
<FixedToolbarToggle onToggle={ onClose } />
<MenuGroup
label={ __( 'Settings' ) }
filterName="editPost.MoreMenu.settings"
>
<FixedToolbarToggle onToggle={ onClose } />
<TipsToggle onToggle={ onClose } />
</MenuGroup>
<PluginMoreMenuGroup.Slot fillProps={ { onClose } } />
<MenuGroup
label={ __( 'Tools' ) }
Expand Down
40 changes: 40 additions & 0 deletions edit-post/components/header/tips-toggle/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* WordPress Dependencies
*/
import { withSelect, withDispatch } from '@wordpress/data';

/**
* WordPress Dependencies
*/
import { __ } from '@wordpress/i18n';
import { compose } from '@wordpress/element';
import { MenuItem } from '@wordpress/components';

function TipsToggle( { onToggle, isActive } ) {
return (
<MenuItem
icon={ isActive && 'yes' }
isSelected={ isActive }
onClick={ onToggle }
>
{ __( 'Show Tips' ) }
</MenuItem>
);
}

export default compose( [
withSelect( ( select ) => ( {
isActive: select( 'core/nux' ).areTipsEnabled(),
} ) ),
withDispatch( ( dispatch, ownProps ) => ( {
onToggle() {
const { disableTips, enableTips } = dispatch( 'core/nux' );
if ( ownProps.isActive ) {
disableTips();
} else {
enableTips();
}
ownProps.onToggle();
},
} ) ),
] )( TipsToggle );
29 changes: 19 additions & 10 deletions nux/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,33 @@ console.log( isVisible ); // true or false
<button
onClick={ () => {
dispatch( 'core/nux' ).dismissTip( 'acme/add-to-cart' );
}
} }
>
Dismiss tip
</button>
```

## Manually disabling tips
## Disabling and enabling tips

`disableTips` is a dispatch method that allows you to programmatically disable all tips.
Tips can be programatically disabled or enabled using the `disableTips` and `enableTips` dispatch methods. You can query the current setting by using the `areTipsEnabled` select method.

Calling `enableTips` will also un-dismiss all previously dismissed tips.

```jsx
<button
onClick={ () => {
dispatch( 'core/nux' ).disableTips();
}
>
Disable tips
</button>
const areTipsEnabled = select( 'core/nux' ).areTipsEnabled();
return (
<button
onClick={ () => {
if ( areTipsEnabled ) {
dispatch( 'core/nux' ).disableTips();
} else {
dispatch( 'core/nux' ).enableTips();
}
} }
>
{ areTipsEnabled ? 'Disable tips' : 'Enable tips' }
</button>
);
```

## Triggering a guide
Expand Down
11 changes: 7 additions & 4 deletions nux/components/dot-tip/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class DotTip extends Component {
}

render() {
const { children, isVisible, hasNextTip, onDismiss } = this.props;
const { children, isVisible, hasNextTip, onDismiss, onDisable } = this.props;

if ( ! isVisible ) {
return null;
Expand All @@ -65,8 +65,8 @@ export class DotTip extends Component {
<IconButton
className="nux-dot-tip__disable"
icon="no-alt"
label={ __( 'Dismiss tip' ) }
onClick={ onDismiss }
label={ __( 'Disable tips' ) }
onClick={ onDisable }
/>
</Popover>
);
Expand All @@ -83,11 +83,14 @@ export default compose(
};
} ),
withDispatch( ( dispatch, { id } ) => {
const { dismissTip } = dispatch( 'core/nux' );
const { dismissTip, disableTips } = dispatch( 'core/nux' );
return {
onDismiss() {
dismissTip( id );
},
onDisable() {
disableTips();
},
};
} ),
)( DotTip );
2 changes: 1 addition & 1 deletion nux/components/dot-tip/test/__snapshots__/index.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ exports[`DotTip should render correctly 1`] = `
<IconButton
className="nux-dot-tip__disable"
icon="no-alt"
label="Dismiss tip"
label="Disable tips"
/>
</Popover>
`;
10 changes: 5 additions & 5 deletions nux/components/dot-tip/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ describe( 'DotTip', () => {
expect( onDismiss ).toHaveBeenCalled();
} );

it( 'should call onDismiss when the X button is clicked', () => {
const onDismiss = jest.fn();
it( 'should call onDisable when the X button is clicked', () => {
const onDisable = jest.fn();
const wrapper = shallow(
<DotTip isVisible onDismiss={ onDismiss }>
<DotTip isVisible onDisable={ onDisable }>
It looks like you’re writing a letter. Would you like help?
</DotTip>
);
wrapper.find( 'IconButton[label="Dismiss tip"]' ).first().simulate( 'click' );
expect( onDismiss ).toHaveBeenCalled();
wrapper.find( 'IconButton[label="Disable tips"]' ).first().simulate( 'click' );
expect( onDisable ).toHaveBeenCalled();
} );
} );
11 changes: 11 additions & 0 deletions nux/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,14 @@ export function disableTips() {
type: 'DISABLE_TIPS',
};
}

/**
* Returns an action object that, when dispatched, makes all tips show again.
*
* @return {Object} Action object.
*/
export function enableTips() {
return {
type: 'ENABLE_TIPS',
};
}
12 changes: 9 additions & 3 deletions nux/store/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,19 @@ export function guides( state = [], action ) {
}

/**
* Reducer that tracks whether or not tips are globally disabled.
* Reducer that tracks whether or not tips are globally enabled.
*
* @param {boolean} state Current state.
* @param {Object} action Dispatched action.
*
* @return {boolean} Updated state.
*/
export function areTipsDisabled( state = false, action ) {
export function areTipsEnabled( state = true, action ) {
switch ( action.type ) {
case 'DISABLE_TIPS':
return false;

case 'ENABLE_TIPS':
return true;
}

Expand All @@ -57,11 +60,14 @@ export function dismissedTips( state = {}, action ) {
...state,
[ action.id ]: true,
};

case 'ENABLE_TIPS':
return {};
}

return state;
}

const preferences = combineReducers( { areTipsDisabled, dismissedTips } );
const preferences = combineReducers( { areTipsEnabled, dismissedTips } );

export default combineReducers( { guides, preferences } );
13 changes: 12 additions & 1 deletion nux/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const getAssociatedGuide = createSelector(
* @return {boolean} Whether or not the given tip is showing.
*/
export function isTipVisible( state, id ) {
if ( state.preferences.areTipsDisabled ) {
if ( ! state.preferences.areTipsEnabled ) {
return false;
}

Expand All @@ -66,3 +66,14 @@ export function isTipVisible( state, id ) {

return true;
}

/**
* Returns whether or not tips are globally enabled.
*
* @param {Object} state Global application state.
*
* @return {boolean} Whether tips are globally enabled.
*/
export function areTipsEnabled( state ) {
return state.preferences.areTipsEnabled;
}
10 changes: 9 additions & 1 deletion nux/store/test/actions.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Internal dependencies
*/
import { triggerGuide, dismissTip, disableTips } from '../actions';
import { triggerGuide, dismissTip, disableTips, enableTips } from '../actions';

describe( 'actions', () => {
describe( 'triggerGuide', () => {
Expand Down Expand Up @@ -29,4 +29,12 @@ describe( 'actions', () => {
} );
} );
} );

describe( 'enableTips', () => {
it( 'should return an ENABLE_TIPS action', () => {
expect( enableTips() ).toEqual( {
type: 'ENABLE_TIPS',
} );
} );
} );
} );
27 changes: 22 additions & 5 deletions nux/store/test/reducer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Internal dependencies
*/
import { guides, areTipsDisabled, dismissedTips } from '../reducer';
import { guides, areTipsEnabled, dismissedTips } from '../reducer';

describe( 'reducer', () => {
describe( 'guides', () => {
Expand All @@ -20,15 +20,22 @@ describe( 'reducer', () => {
} );
} );

describe( 'areTipsDisabled', () => {
it( 'should default to false', () => {
expect( areTipsDisabled( undefined, {} ) ).toBe( false );
describe( 'areTipsEnabled', () => {
it( 'should default to true', () => {
expect( areTipsEnabled( undefined, {} ) ).toBe( true );
} );

it( 'should flip when tips are disabled', () => {
const state = areTipsDisabled( false, {
const state = areTipsEnabled( true, {
type: 'DISABLE_TIPS',
} );
expect( state ).toBe( false );
} );

it( 'should flip when tips are enabled', () => {
const state = areTipsEnabled( false, {
type: 'ENABLE_TIPS',
} );
expect( state ).toBe( true );
} );
} );
Expand All @@ -47,5 +54,15 @@ describe( 'reducer', () => {
'test/tip': true,
} );
} );

it( 'should reset if tips are enabled', () => {
const initialState = {
'test/tip': true,
};
const state = dismissedTips( initialState, {
type: 'ENABLE_TIPS',
} );
expect( state ).toEqual( {} );
} );
} );
} );
Loading

0 comments on commit 879929f

Please sign in to comment.