Skip to content

Commit

Permalink
Viewport: Split withViewportMatch from ifViewportMatches
Browse files Browse the repository at this point in the history
  • Loading branch information
aduth committed Feb 26, 2018
1 parent b796ad3 commit cc2fb9f
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 29 deletions.
4 changes: 2 additions & 2 deletions edit-post/components/header/header-toolbar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
import { compose } from '@wordpress/element';
import { withSelect } from '@wordpress/data';
import { ifViewportMatches } from '@wordpress/viewport';
import { withViewportMatch } from '@wordpress/viewport';

/**
* WordPress dependencies
Expand Down Expand Up @@ -48,5 +48,5 @@ export default compose( [
withSelect( ( select ) => ( {
hasFixedToolbar: select( 'core/edit-post' ).isFeatureActive( 'fixedToolbar' ),
} ) ),
ifViewportMatches( 'medium', 'isLargeViewport' ),
withViewportMatch( { isLargeViewport: 'medium' } ),
] )( HeaderToolbar );
4 changes: 2 additions & 2 deletions edit-post/components/visual-editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
} from '@wordpress/editor';
import { Fragment, compose } from '@wordpress/element';
import { withSelect } from '@wordpress/data';
import { ifViewportMatches } from '@wordpress/viewport';
import { withViewportMatch } from '@wordpress/viewport';

/**
* Internal dependencies
Expand Down Expand Up @@ -46,5 +46,5 @@ export default compose( [
withSelect( ( select ) => ( {
hasFixedToolbar: select( 'core/edit-post' ).isFeatureActive( 'fixedToolbar' ),
} ) ),
ifViewportMatches( 'medium', 'isLargeViewport' ),
withViewportMatch( { isLargeViewport: 'medium' } ),
] )( VisualEditor );
10 changes: 7 additions & 3 deletions viewport/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const isWideOrHuge = isViewportMatch( '>= wide' );

## `ifViewportMatches` Higher-Order Component

If you are authoring a component which should only be shown under a specific viewport condition, or should vary its rendering behavior depending upon the matching viewport, you can leverage the `ifViewportMatches` higher-order component to achieve this requirement.
If you are authoring a component which should only be shown under a specific viewport condition, you can leverage the `ifViewportMatches` higher-order component to achieve this requirement.

Pass a viewport query to render the component only when the query is matched:

Expand All @@ -48,7 +48,11 @@ function MyMobileComponent() {
MyMobileComponent = ifViewportMatches( '< small' )( MyMobileComponent );
```
Pass a viewport query and a prop name to render the component with the result of the query match:
## `withViewportMatch` Higher-Order Component
If you are authoring a component which should vary its rendering behavior depending upon the matching viewport, you can leverage the `withViewportMatch` higher-order component to achieve this requirement.
Pass an object, where each key is a prop name and its value a viewport query. The component will be rendered with your prop(s) assigned with the result(s) of the query match:
```jsx
function MyComponent( { isMobile } ) {
Expand All @@ -57,5 +61,5 @@ function MyComponent( { isMobile } ) {
);
}
MyComponent = ifViewportMatches( '< small', 'isMobile' )( MyComponent );
MyComponent = withViewportMatch( { isMobile: '< small' } )( MyComponent );
```
25 changes: 13 additions & 12 deletions viewport/if-viewport-matches.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,32 @@
* WordPress dependencies
*/
import { compose, getWrapperDisplayName } from '@wordpress/element';
import { withSelect } from '@wordpress/data';
import { ifCondition } from '@wordpress/components';

/**
* Internal dependencies
*/
import withViewportMatch from './with-viewport-match';

/**
* Higher-order component creator, creating a new component which renders if
* the viewport query is satisfied or with the given optional prop name.
*
* @param {string} query Viewport query.
* @param {?string} propName Optional prop name passed to component with result
* of query match. If provided, component will always
* render even if viewport does not match.
* @param {string} query Viewport query.
*
* @see isViewportMatch
* @see withViewportMatches
*
* @return {Function} Higher-order component.
*/
const ifViewportMatches = ( query, propName ) => ( WrappedComponent ) => {
const ifViewportMatches = ( query ) => ( WrappedComponent ) => {
const EnhancedComponent = compose( [
withSelect( ( select ) => ( {
isViewportSize: select( 'core/viewport' ).isViewportMatch( query ),
} ) ),
ifCondition( ( props ) => props.isViewportSize, propName ),
withViewportMatch( {
isViewportMatch: query,
} ),
ifCondition( ( props ) => props.isViewportMatch ),
] )( WrappedComponent );

EnhancedComponent.displayName = getWrapperDisplayName( WrappedComponent, 'viewportSize' );
EnhancedComponent.displayName = getWrapperDisplayName( WrappedComponent, 'ifViewportMatches' );

return EnhancedComponent;
};
Expand Down
1 change: 1 addition & 0 deletions viewport/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { dispatch } from '@wordpress/data';
import './store';

export { default as ifViewportMatches } from './if-viewport-matches';
export { default as withViewportMatch } from './with-viewport-match';

/**
* Hash of breakpoint names with pixel width at which it becomes effective.
Expand Down
10 changes: 0 additions & 10 deletions viewport/test/if-viewport-matches.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,4 @@ describe( 'ifViewportMatches()', () => {

wrapper.unmount();
} );

it( 'should render with result of query match as prop', () => {
dispatch( 'core/viewport' ).setIsMatching( { '> wide': true } );
const EnhancedComponent = ifViewportMatches( '> wide', 'isMatch' )( Component );
const wrapper = mount( <EnhancedComponent /> );

expect( wrapper.find( Component ).prop( 'isMatch' ) ).toBe( true );

wrapper.unmount();
} );
} );
29 changes: 29 additions & 0 deletions viewport/test/with-viewport-match.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* External dependencies
*/
import { mount } from 'enzyme';

/**
* WordPress dependencies
*/
import { dispatch } from '@wordpress/data';

/**
* Internal dependencies
*/
import '../store';
import withViewportMatch from '../with-viewport-match';

describe( 'withViewportMatch()', () => {
const Component = () => <div>Hello</div>;

it( 'should render with result of query as custom prop name', () => {
dispatch( 'core/viewport' ).setIsMatching( { '> wide': true } );
const EnhancedComponent = withViewportMatch( { isWide: '> wide' } )( Component );
const wrapper = mount( <EnhancedComponent /> );

expect( wrapper.find( Component ).props() ).toEqual( { isWide: true } );

wrapper.unmount();
} );
} );
35 changes: 35 additions & 0 deletions viewport/with-viewport-match.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* External dependencies
*/
import { mapValues } from 'lodash';

/**
* WordPress dependencies
*/
import { compose, getWrapperDisplayName } from '@wordpress/element';
import { withSelect } from '@wordpress/data';

/**
* Higher-order component creator, creating a new component which renders if
* the viewport query is satisfied or with the given optional prop name.
*
* @param {Object} queries Object of prop name to viewport query.
* @param {string} propName Optional prop name to which result is assigned.
*
* @see isViewportMatch
*
* @return {Function} Higher-order component.
*/
const withViewportMatch = ( queries ) => ( WrappedComponent ) => {
const EnhancedComponent = compose( [
withSelect( ( select ) => mapValues( queries, ( query ) => {
return select( 'core/viewport' ).isViewportMatch( query );
} ) ),
] )( WrappedComponent );

EnhancedComponent.displayName = getWrapperDisplayName( WrappedComponent, 'withViewportMatch' );

return EnhancedComponent;
};

export default withViewportMatch;

0 comments on commit cc2fb9f

Please sign in to comment.