Skip to content

Commit

Permalink
Lodash: Remove completely from @wordpress/viewport package (#44572)
Browse files Browse the repository at this point in the history
* Lodash: Remove completely from viewport package

* Optimization and enhancement as per review

* addListener -> addEventListener

* Revert "addListener -> addEventListener"

This reverts commit 02472db.

* Revert "Optimization and enhancement as per review"

This reverts commit 7f17ee9.

* Address feedback, again

* Fix MediaQueryList mockks

* Add the missing Object.fromEntries
  • Loading branch information
tyxla authored Oct 5, 2022
1 parent 4b19439 commit 2c45ac1
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 72 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.

2 changes: 2 additions & 0 deletions packages/jest-preset-default/scripts/setup-globals.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ global.window.cancelIdleCallback = function cancelIdleCallback( handle ) {
global.window.matchMedia = () => ( {
matches: false,
addListener: () => {},
addEventListener: () => {},
removeListener: () => {},
removeEventListener: () => {},
} );

// Setup fake localStorage.
Expand Down
2 changes: 2 additions & 0 deletions packages/react-native-editor/src/globals.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ if ( ! global.window.matchMedia ) {
global.window.matchMedia = () => ( {
matches: false,
addListener: () => {},
addEventListener: () => {},
removeListener: () => {},
removeEventListener: () => {},
} );
}

Expand Down
3 changes: 1 addition & 2 deletions packages/viewport/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
"dependencies": {
"@babel/runtime": "^7.16.0",
"@wordpress/compose": "file:../compose",
"@wordpress/data": "file:../data",
"lodash": "^4.17.21"
"@wordpress/data": "file:../data"
},
"peerDependencies": {
"react": "^17.0.0"
Expand Down
38 changes: 14 additions & 24 deletions packages/viewport/src/listener.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
/**
* External dependencies
*/
import { reduce, mapValues } from 'lodash';

/**
* WordPress dependencies
*/
Expand All @@ -21,7 +16,9 @@ const addDimensionsEventListener = ( breakpoints, operators ) => {
*/
const setIsMatching = debounce(
() => {
const values = mapValues( queries, ( query ) => query.matches );
const values = Object.fromEntries(
queries.map( ( [ key, query ] ) => [ key, query.matches ] )
);
dispatch( store ).setIsMatching( values );
},
0,
Expand All @@ -37,24 +34,17 @@ const addDimensionsEventListener = ( breakpoints, operators ) => {
*
* @type {Object<string,MediaQueryList>}
*/
const queries = reduce(
breakpoints,
( result, width, name ) => {
Object.entries( operators ).forEach(
( [ operator, condition ] ) => {
const list = window.matchMedia(
`(${ condition }: ${ width }px)`
);
list.addListener( setIsMatching );

const key = [ operator, name ].join( ' ' );
result[ key ] = list;
}
);

return result;
},
{}
const operatorEntries = Object.entries( operators );
const queries = Object.entries( breakpoints ).flatMap(
( [ name, width ] ) => {
return operatorEntries.map( ( [ operator, condition ] ) => {
const list = window.matchMedia(
`(${ condition }: ${ width }px)`
);
list.addEventListener( 'change', setIsMatching );
return [ `${ operator } ${ name }`, list ];
} );
}
);

window.addEventListener( 'orientationchange', setIsMatching );
Expand Down
24 changes: 10 additions & 14 deletions packages/viewport/src/listener.native.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/**
* External dependencies
*/
import { reduce } from 'lodash';
import { Dimensions } from 'react-native';

/**
Expand All @@ -25,20 +24,17 @@ const matchWidth = ( operator, breakpoint ) => {
};

const addDimensionsEventListener = ( breakpoints, operators ) => {
const operatorEntries = Object.entries( operators );
const breakpointEntries = Object.entries( breakpoints );

const setIsMatching = () => {
const matches = reduce(
breakpoints,
( result, width, name ) => {
Object.entries( operators ).forEach(
( [ operator, condition ] ) => {
const key = [ operator, name ].join( ' ' );
result[ key ] = matchWidth( condition, width );
}
);

return result;
},
{}
const matches = Object.fromEntries(
breakpointEntries.flatMap( ( [ name, width ] ) => {
return operatorEntries.map( ( [ operator, condition ] ) => [
`${ operator } ${ name }`,
matchWidth( condition, width ),
] );
} )
);

dispatch( store ).setIsMatching( matches );
Expand Down
32 changes: 15 additions & 17 deletions packages/viewport/src/with-viewport-match.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
/**
* External dependencies
*/
import { mapValues } from 'lodash';

/**
* WordPress dependencies
*/
Expand Down Expand Up @@ -36,19 +31,22 @@ import {
* @return {Function} Higher-order component.
*/
const withViewportMatch = ( queries ) => {
const queryEntries = Object.entries( queries );
const useViewPortQueriesResult = () =>
mapValues( queries, ( query ) => {
let [ operator, breakpointName ] = query.split( ' ' );
if ( breakpointName === undefined ) {
breakpointName = operator;
operator = '>=';
}
// Hooks should unconditionally execute in the same order,
// we are respecting that as from the static query of the HOC we generate
// a hook that calls other hooks always in the same order (because the query never changes).
// eslint-disable-next-line react-hooks/rules-of-hooks
return useViewportMatch( breakpointName, operator );
} );
Object.fromEntries(
queryEntries.map( ( [ key, query ] ) => {
let [ operator, breakpointName ] = query.split( ' ' );
if ( breakpointName === undefined ) {
breakpointName = operator;
operator = '>=';
}
// Hooks should unconditionally execute in the same order,
// we are respecting that as from the static query of the HOC we generate
// a hook that calls other hooks always in the same order (because the query never changes).
// eslint-disable-next-line react-hooks/rules-of-hooks
return [ key, useViewportMatch( breakpointName, operator ) ];
} )
);
return createHigherOrderComponent( ( WrappedComponent ) => {
return pure( ( props ) => {
const queriesResult = useViewPortQueriesResult();
Expand Down
25 changes: 12 additions & 13 deletions packages/viewport/src/with-viewport-match.native.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
/**
* External dependencies
*/
import { mapValues } from 'lodash';

/**
* WordPress dependencies
*/
Expand All @@ -27,24 +22,28 @@ import { store } from './store';
*
* ```jsx
* function MyComponent( { isMobile } ) {
* return (
* <div>Currently: { isMobile ? 'Mobile' : 'Not Mobile' }</div>
* );
* return (
* <div>Currently: { isMobile ? 'Mobile' : 'Not Mobile' }</div>
* );
* }
*
* MyComponent = withViewportMatch( { isMobile: '< small' } )( MyComponent );
* ```
*
* @return {Function} Higher-order component.
*/
const withViewportMatch = ( queries ) =>
createHigherOrderComponent(
const withViewportMatch = ( queries ) => {
const queryEntries = Object.entries( queries );
return createHigherOrderComponent(
withSelect( ( select ) => {
return mapValues( queries, ( query ) => {
return select( store ).isViewportMatch( query );
} );
return Object.fromEntries(
queryEntries.map( ( [ key, query ] ) => {
return [ key, select( store ).isViewportMatch( query ) ];
} )
);
} ),
'withViewportMatch'
);
};

export default withViewportMatch;

0 comments on commit 2c45ac1

Please sign in to comment.