Skip to content

Commit

Permalink
Add useViewportMatch react hook alternative to withViewportMatch (#18816
Browse files Browse the repository at this point in the history
)
  • Loading branch information
youknowriad authored Dec 5, 2019
1 parent 6ec0934 commit f4300ff
Show file tree
Hide file tree
Showing 14 changed files with 128 additions and 51 deletions.
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
/**
* WordPress dependencies
*/
import { ifViewportMatches } from '@wordpress/viewport';
import { useViewportMatch } from '@wordpress/compose';

/**
* Internal dependencies
*/
import BlockMover from '../block-mover';

function BlockMobileToolbar( { clientId, moverDirection } ) {
const isMobile = useViewportMatch( 'small', '<' );
if ( ! isMobile ) {
return null;
}

return (
<div className="block-editor-block-mobile-toolbar">
<BlockMover clientIds={ [ clientId ] } __experimentalOrientation={ moverDirection } />
</div>
);
}

export default ifViewportMatches( '< small' )( BlockMobileToolbar );
export default BlockMobileToolbar;
9 changes: 7 additions & 2 deletions packages/block-editor/src/components/tool-selector/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,19 @@ import {
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { useSelect, useDispatch } from '@wordpress/data';
import { ifViewportMatches } from '@wordpress/viewport';
import { useViewportMatch } from '@wordpress/compose';

const editIcon = <SVG xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24"><Path fill="none" d="M0 0h24v24H0V0z" /><Path d="M14.06 9.02l.92.92L5.92 19H5v-.92l9.06-9.06M17.66 3c-.25 0-.51.1-.7.29l-1.83 1.83 3.75 3.75 1.83-1.83c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.2-.2-.45-.29-.71-.29zm-3.6 3.19L3 17.25V21h3.75L17.81 9.94l-3.75-3.75z" /></SVG>;
const selectIcon = <SVG xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24"><Path d="M6.5 1v21.5l6-6.5H21L6.5 1zm5.1 13l-3.1 3.4V5.9l7.8 8.1h-4.7z" /></SVG>;

function ToolSelector() {
const isNavigationTool = useSelect( ( select ) => select( 'core/block-editor' ).isNavigationMode() );
const { setNavigationMode } = useDispatch( 'core/block-editor' );
const isMediumViewport = useViewportMatch( 'medium' );
if ( ! isMediumViewport ) {
return null;
}

const onSwitchMode = ( mode ) => {
setNavigationMode( mode === 'edit' ? false : true );
};
Expand Down Expand Up @@ -73,4 +78,4 @@ function ToolSelector() {
);
}

export default ifViewportMatches( 'medium' )( ToolSelector );
export default ToolSelector;
9 changes: 2 additions & 7 deletions packages/components/src/popover/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useRef, useState, useEffect } from '@wordpress/element';
import { focus, getRectangleFromRange } from '@wordpress/dom';
import { ESCAPE } from '@wordpress/keycodes';
import deprecated from '@wordpress/deprecated';
import { useViewportMatch } from '@wordpress/compose';

/**
* Internal dependencies
Expand Down Expand Up @@ -195,15 +196,9 @@ const Popover = ( {
const anchorRefFallback = useRef( null );
const contentRef = useRef( null );
const containerRef = useRef();
const [ isMobileViewport, setIsMobileViewport ] = useState( false );
const isMobileViewport = useViewportMatch( 'medium', '<' );
const [ animateOrigin, setAnimateOrigin ] = useState();

useEffect( () => {
const resize = () => setIsMobileViewport( window.innerWidth < 782 );
window.addEventListener( 'resize', resize );
return () => window.removeEventListener( 'resize', resize );
} );

useEffect( () => {
if ( isMobileViewport && expandOnMobile ) {
return;
Expand Down
20 changes: 20 additions & 0 deletions packages/compose/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,26 @@ _Returns_

- `boolean`: Reduced motion preference value.

<a name="useViewportMatch" href="#useViewportMatch">#</a> **useViewportMatch**

Returns true if the viewport matches the given query, or false otherwise.

_Usage_

```js
useViewportMatch( 'huge', <' );
useViewportMatch( 'medium' );
```
_Parameters_
- _breakpoint_ `WPBreakpoint`: Breakpoint size name.
- _operator_ `[WPViewportOperator]`: Viewport operator.
_Returns_
- `boolean`: Whether viewport matches query.
<a name="withGlobalEvents" href="#withGlobalEvents">#</a> **withGlobalEvents**
Higher-order component creator which, given an object of DOM event types and
Expand Down
60 changes: 60 additions & 0 deletions packages/compose/src/hooks/use-viewport-match/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* Internal dependencies
*/
import useMediaQuery from '../use-media-query';

/**
* @typedef {"huge"|"wide"|"large"|"medium"|"small"|"mobile"} WPBreakpoint
*/

/**
* Hash of breakpoint names with pixel width at which it becomes effective.
*
* @see _breakpoints.scss
*
* @type {Object<WPBreakpoint,number>}
*/
const BREAKPOINTS = {
huge: 1440,
wide: 1280,
large: 960,
medium: 782,
small: 600,
mobile: 480,
};

/**
* @typedef {">="|"<"} WPViewportOperator
*/

/**
* Object mapping media query operators to the condition to be used.
*
* @type {Object<WPViewportOperator,string>}
*/
const CONDITIONS = {
'>=': 'min-width',
'<': 'max-width',
};

/**
* Returns true if the viewport matches the given query, or false otherwise.
*
* @param {WPBreakpoint} breakpoint Breakpoint size name.
* @param {WPViewportOperator} [operator=">="] Viewport operator.
*
* @example
*
* ```js
* useViewportMatch( 'huge', <' );
* useViewportMatch( 'medium' );
* ```
*
* @return {boolean} Whether viewport matches query.
*/
const useViewportMatch = ( breakpoint, operator = '>=' ) => {
const mediaQuery = `(${ CONDITIONS[ operator ] }: ${ BREAKPOINTS[ breakpoint ] }px)`;
return useMediaQuery( mediaQuery );
};

export default useViewportMatch;
1 change: 1 addition & 0 deletions packages/compose/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ export { default as withState } from './higher-order/with-state';
// Hooks
export { default as useMediaQuery } from './hooks/use-media-query';
export { default as useReducedMotion } from './hooks/use-reduced-motion';
export { default as useViewportMatch } from './hooks/use-viewport-match';
25 changes: 12 additions & 13 deletions packages/edit-post/src/components/header/header-toolbar/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
/**
* WordPress dependencies
*/
import { compose } from '@wordpress/compose';
import { withSelect } from '@wordpress/data';
import { withViewportMatch } from '@wordpress/viewport';
import { useViewportMatch } from '@wordpress/compose';
import { useSelect } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import {
Inserter,
Expand All @@ -18,7 +17,15 @@ import {
EditorHistoryUndo,
} from '@wordpress/editor';

function HeaderToolbar( { hasFixedToolbar, isLargeViewport, showInserter, isTextModeEnabled } ) {
function HeaderToolbar() {
const { hasFixedToolbar, showInserter, isTextModeEnabled } = useSelect( ( select ) => ( {
hasFixedToolbar: select( 'core/edit-post' ).isFeatureActive( 'fixedToolbar' ),
// This setting (richEditingEnabled) should not live in the block editor's setting.
showInserter: select( 'core/edit-post' ).getEditorMode() === 'visual' && select( 'core/editor' ).getEditorSettings().richEditingEnabled,
isTextModeEnabled: select( 'core/edit-post' ).getEditorMode() === 'text',
} ) );
const isLargeViewport = useViewportMatch( 'medium' );

const toolbarAriaLabel = hasFixedToolbar ?
/* translators: accessibility text for the editor toolbar when Top Toolbar is on */
__( 'Document and block tools' ) :
Expand All @@ -45,12 +52,4 @@ function HeaderToolbar( { hasFixedToolbar, isLargeViewport, showInserter, isText
);
}

export default compose( [
withSelect( ( select ) => ( {
hasFixedToolbar: select( 'core/edit-post' ).isFeatureActive( 'fixedToolbar' ),
// This setting (richEditingEnabled) should not live in the block editor's setting.
showInserter: select( 'core/edit-post' ).getEditorMode() === 'visual' && select( 'core/editor' ).getEditorSettings().richEditingEnabled,
isTextModeEnabled: select( 'core/edit-post' ).getEditorMode() === 'text',
} ) ),
withViewportMatch( { isLargeViewport: 'medium' } ),
] )( HeaderToolbar );
export default HeaderToolbar;
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,15 @@ import { get } from 'lodash';
/**
* WordPress dependencies
*/
import { compose } from '@wordpress/compose';
import { useViewportMatch, compose } from '@wordpress/compose';
import { withDispatch, withSelect } from '@wordpress/data';
import { PostPublishButton } from '@wordpress/editor';
import { withViewportMatch } from '@wordpress/viewport';

export function PostPublishButtonOrToggle( {
forceIsDirty,
forceIsSaving,
hasPublishAction,
isBeingScheduled,
isLessThanMediumViewport,
isPending,
isPublished,
isPublishSidebarEnabled,
Expand All @@ -26,6 +24,7 @@ export function PostPublishButtonOrToggle( {
} ) {
const IS_TOGGLE = 'toggle';
const IS_BUTTON = 'button';
const isSmallerThanMediumViewport = useViewportMatch( 'medium', '<' );
let component;

/**
Expand Down Expand Up @@ -53,10 +52,10 @@ export function PostPublishButtonOrToggle( {
if (
isPublished ||
( isScheduled && isBeingScheduled ) ||
( isPending && ! hasPublishAction && ! isLessThanMediumViewport )
( isPending && ! hasPublishAction && ! isSmallerThanMediumViewport )
) {
component = IS_BUTTON;
} else if ( isLessThanMediumViewport ) {
} else if ( isSmallerThanMediumViewport ) {
component = IS_TOGGLE;
} else if ( isPublishSidebarEnabled ) {
component = IS_TOGGLE;
Expand Down Expand Up @@ -95,5 +94,4 @@ export default compose(
togglePublishSidebar,
};
} ),
withViewportMatch( { isLessThanMediumViewport: '< medium' } ),
)( PostPublishButtonOrToggle );
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,3 @@ exports[`PostPublishButtonOrToggle should render a toggle when post is not (1),
isToggle={true}
/>
`;

exports[`PostPublishButtonOrToggle should render a toggle when post is not published or scheduled and the viewport is < medium 1`] = `
<WithSelect(WithDispatch(PostPublishButton))
isToggle={true}
/>
`;
5 changes: 0 additions & 5 deletions packages/edit-post/src/components/header/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,8 @@ describe( 'PostPublishButtonOrToggle should render a', () => {
const wrapper = shallow( <PostPublishButtonOrToggle
isPending={ true }
hasPublishAction={ false }
isLessThanMediumViewport={ false }
/> );
expect( wrapper ).toMatchSnapshot();
} );

it( 'toggle when post is not published or scheduled and the viewport is < medium', () => {
const wrapper = shallow( <PostPublishButtonOrToggle isLessThanMediumViewport={ true } /> );
expect( wrapper ).toMatchSnapshot();
} );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@
*/
import { MenuGroup } from '@wordpress/components';
import { __, _x } from '@wordpress/i18n';
import { ifViewportMatches } from '@wordpress/viewport';
import { useViewportMatch } from '@wordpress/compose';

/**
* Internal dependencies
*/
import FeatureToggle from '../feature-toggle';

function WritingMenu() {
const isLargeViewport = useViewportMatch( 'medium' );
if ( ! isLargeViewport ) {
return null;
}

return (
<MenuGroup
label={ _x( 'View', 'noun' ) }
Expand Down Expand Up @@ -40,4 +45,4 @@ function WritingMenu() {
);
}

export default ifViewportMatches( 'medium' )( WritingMenu );
export default WritingMenu;
7 changes: 4 additions & 3 deletions packages/edit-post/src/components/layout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
Popover,
FocusReturnProvider,
} from '@wordpress/components';
import { withViewportMatch } from '@wordpress/viewport';
import { useViewportMatch } from '@wordpress/compose';
import { PluginArea } from '@wordpress/plugins';
import { __ } from '@wordpress/i18n';

Expand All @@ -49,7 +49,8 @@ import PluginPostPublishPanel from '../sidebar/plugin-post-publish-panel';
import PluginPrePublishPanel from '../sidebar/plugin-pre-publish-panel';
import WelcomeGuide from '../welcome-guide';

function Layout( { isMobileViewport } ) {
function Layout() {
const isMobileViewport = useViewportMatch( 'small', '<' );
const { closePublishSidebar, togglePublishSidebar } = useDispatch( 'core/edit-post' );
const {
mode,
Expand Down Expand Up @@ -149,4 +150,4 @@ function Layout( { isMobileViewport } ) {
);
}

export default withViewportMatch( { isMobileViewport: '< small' } )( Layout );
export default Layout;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`PostSavedState returns a switch to draft link if the post is published 1`] = `<WithSelect(WithDispatch(WithViewportMatch(PostSwitchToDraftButton))) />`;
exports[`PostSavedState returns a switch to draft link if the post is published 1`] = `<WithSelect(WithDispatch(PostSwitchToDraftButton)) />`;

exports[`PostSavedState should return Save button if edits to be saved 1`] = `
<ForwardRef(Button)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
import { Button } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { withSelect, withDispatch } from '@wordpress/data';
import { compose } from '@wordpress/compose';
import { withViewportMatch } from '@wordpress/viewport';
import { compose, useViewportMatch } from '@wordpress/compose';

function PostSwitchToDraftButton( {
isSaving,
isPublished,
isScheduled,
onClick,
isMobileViewport,
} ) {
const isMobileViewport = useViewportMatch( 'small', '<' );

if ( ! isPublished && ! isScheduled ) {
return null;
}
Expand Down Expand Up @@ -61,6 +61,5 @@ export default compose( [
},
};
} ),
withViewportMatch( { isMobileViewport: '< small' } ),
] )( PostSwitchToDraftButton );

0 comments on commit f4300ff

Please sign in to comment.