Skip to content

Commit

Permalink
Try: useMergeRefs (#27768)
Browse files Browse the repository at this point in the history
* Try: useMergeRefs

* update lock file

* Rebase fixes

* Add docs

* Clearer documentation

* wip

* wip

* Add docs for unit tests

* Convert new additions
  • Loading branch information
ellatrix authored and oandregal committed Feb 11, 2021
1 parent ac9e3cb commit 95551d9
Show file tree
Hide file tree
Showing 21 changed files with 344 additions and 100 deletions.
13 changes: 2 additions & 11 deletions package-lock.json

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

1 change: 0 additions & 1 deletion packages/block-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@
"lodash": "^4.17.19",
"memize": "^1.1.0",
"react-autosize-textarea": "^7.1.0",
"react-merge-refs": "^1.0.0",
"react-spring": "^8.0.19",
"redux-multi": "^0.1.12",
"rememo": "^3.0.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/block-editor/src/components/iframe/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/**
* External dependencies
*/
import mergeRefs from 'react-merge-refs';
import { compact, map } from 'lodash';
import tinycolor from 'tinycolor2';

Expand All @@ -16,6 +15,7 @@ import {
forwardRef,
} from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { useMergeRefs } from '@wordpress/compose';

/**
* Internal dependencies
Expand Down Expand Up @@ -211,7 +211,7 @@ function Iframe( { contentRef, editorStyles, children, head, ...props }, ref ) {
return (
<iframe
{ ...props }
ref={ useCallback( mergeRefs( [ ref, setRef ] ), [] ) }
ref={ useMergeRefs( [ ref, setRef ] ) }
tabIndex="0"
title={ __( 'Editor canvas' ) }
name="editor-canvas"
Expand Down
1 change: 0 additions & 1 deletion packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
"moment": "^2.22.1",
"re-resizable": "^6.4.0",
"react-dates": "^17.1.1",
"react-merge-refs": "^1.0.0",
"react-resize-aware": "^3.1.0",
"react-spring": "^8.0.20",
"react-use-gesture": "^9.0.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/components/src/modal/frame.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* External dependencies
*/
import classnames from 'classnames';
import mergeRefs from 'react-merge-refs';

/**
* WordPress dependencies
Expand All @@ -14,6 +13,7 @@ import {
useFocusReturn,
useFocusOnMount,
useConstrainedTabbing,
useMergeRefs,
} from '@wordpress/compose';

/**
Expand Down Expand Up @@ -57,7 +57,7 @@ function ModalFrameContent( {
<div
className={ classnames( 'components-modal__frame', className ) }
style={ style }
ref={ mergeRefs( [
ref={ useMergeRefs( [
constrainedTabbingRef,
focusReturnRef,
focusOnMountRef,
Expand Down
5 changes: 2 additions & 3 deletions packages/components/src/panel/body.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
*/
import classnames from 'classnames';
import { noop } from 'lodash';
import mergeRefs from 'react-merge-refs';

/**
* WordPress dependencies
*/
import { useReducedMotion } from '@wordpress/compose';
import { useReducedMotion, useMergeRefs } from '@wordpress/compose';
import { forwardRef, useRef } from '@wordpress/element';
import { chevronUp, chevronDown } from '@wordpress/icons';

Expand Down Expand Up @@ -77,7 +76,7 @@ export function PanelBody(
} );

return (
<div className={ classes } ref={ mergeRefs( [ nodeRef, ref ] ) }>
<div className={ classes } ref={ useMergeRefs( [ nodeRef, ref ] ) }>
<PanelBodyTitle
icon={ icon }
isOpened={ isOpened }
Expand Down
14 changes: 4 additions & 10 deletions packages/components/src/popover/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,11 @@
* External dependencies
*/
import classnames from 'classnames';
import mergeRefs from 'react-merge-refs';

/**
* WordPress dependencies
*/
import {
useRef,
useState,
useLayoutEffect,
useCallback,
} from '@wordpress/element';
import { useRef, useState, useLayoutEffect } from '@wordpress/element';
import { getRectangleFromRange } from '@wordpress/dom';
import { ESCAPE } from '@wordpress/keycodes';
import deprecated from '@wordpress/deprecated';
Expand All @@ -23,6 +17,7 @@ import {
__experimentalUseFocusOutside as useFocusOutside,
useConstrainedTabbing,
useFocusReturn,
useMergeRefs,
} from '@wordpress/compose';
import { close } from '@wordpress/icons';

Expand Down Expand Up @@ -492,13 +487,12 @@ const Popover = ( {
const focusReturnRef = useFocusReturn();
const focusOnMountRef = useFocusOnMount( focusOnMount );
const focusOutsideProps = useFocusOutside( handleOnFocusOutside );
const allRefs = [
const mergedRefs = useMergeRefs( [
containerRef,
focusOnMount ? constrainedTabbingRef : null,
focusOnMount ? focusReturnRef : null,
focusOnMount ? focusOnMountRef : null,
];
const mergedRefs = useCallback( mergeRefs( allRefs ), allRefs );
] );

// Event handlers
const maybeClose = ( event ) => {
Expand Down
18 changes: 18 additions & 0 deletions packages/compose/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,24 @@ _Returns_

- `boolean`: return value of the media query.

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

Merges refs into one ref callback. Ensures the merged ref callbacks are only
called when it changes (as a result of a `useCallback` dependency update) or
when the ref value changes. If you don't wish a ref callback to be called on
every render, wrap it with `useCallback( ref, [] )`.
Dependencies can be added, but when a dependency changes, the old ref
callback will be called with `null` and the new ref callback will be called
with the same node.

_Parameters_

- _refs_ `Array<(RefObject|RefCallback)>`: The refs to be merged.

_Returns_

- `RefCallback`: The merged ref callback.

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

Use something's value from the previous render.
Expand Down
1 change: 0 additions & 1 deletion packages/compose/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
"lodash": "^4.17.19",
"memize": "^1.1.0",
"mousetrap": "^1.6.5",
"react-merge-refs": "^1.0.0",
"react-resize-aware": "^3.1.0",
"use-memo-one": "^1.1.1"
},
Expand Down
20 changes: 0 additions & 20 deletions packages/compose/src/hooks/use-callback-ref/index.js

This file was deleted.

8 changes: 2 additions & 6 deletions packages/compose/src/hooks/use-constrained-tabbing/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@
*/
import { TAB } from '@wordpress/keycodes';
import { focus } from '@wordpress/dom';

/**
* Internal dependencies
*/
import useCallbackRef from '../use-callback-ref';
import { useCallback } from '@wordpress/element';

/**
* In Dialogs/modals, the tabbing must be constrained to the content of
Expand All @@ -31,7 +27,7 @@ import useCallbackRef from '../use-callback-ref';
* ```
*/
function useConstrainedTabbing() {
const ref = useCallbackRef( ( node ) => {
const ref = useCallback( ( node ) => {
if ( ! node ) {
return;
}
Expand Down
13 changes: 4 additions & 9 deletions packages/compose/src/hooks/use-dialog/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
/**
* External dependencies
*/
import mergeRefs from 'react-merge-refs';

/**
* WordPress dependencies
*/
import { useRef, useEffect } from '@wordpress/element';
import { useRef, useEffect, useCallback } from '@wordpress/element';
import { ESCAPE } from '@wordpress/keycodes';

/**
Expand All @@ -16,7 +11,7 @@ import useConstrainedTabbing from '../use-constrained-tabbing';
import useFocusOnMount from '../use-focus-on-mount';
import useFocusReturn from '../use-focus-return';
import useFocusOutside from '../use-focus-outside';
import useCallbackRef from '../use-callback-ref';
import useMergeRefs from '../use-merge-refs';

/**
* Returns a ref and props to apply to a dialog wrapper to enable the following behaviors:
Expand All @@ -36,7 +31,7 @@ function useDialog( options ) {
const focusOnMountRef = useFocusOnMount();
const focusReturnRef = useFocusReturn();
const focusOutsideProps = useFocusOutside( options.onClose );
const closeOnEscapeRef = useCallbackRef( ( node ) => {
const closeOnEscapeRef = useCallback( ( node ) => {
if ( ! node ) {
return;
}
Expand All @@ -51,7 +46,7 @@ function useDialog( options ) {
}, [] );

return [
mergeRefs( [
useMergeRefs( [
constrainedTabbingRef,
focusReturnRef,
focusOnMountRef,
Expand Down
9 changes: 2 additions & 7 deletions packages/compose/src/hooks/use-focus-on-mount/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
/**
* WordPress dependencies
*/
import { useRef, useEffect } from '@wordpress/element';
import { useRef, useEffect, useCallback } from '@wordpress/element';
import { focus } from '@wordpress/dom';

/**
* Internal dependencies
*/
import useCallbackRef from '../use-callback-ref';

/**
* Hook used to focus the first tabbable element on mount.
*
Expand Down Expand Up @@ -36,7 +31,7 @@ export default function useFocusOnMount( focusOnMount = 'firstElement' ) {
focusOnMountRef.current = focusOnMount;
}, [ focusOnMount ] );

return useCallbackRef( ( node ) => {
return useCallback( ( node ) => {
if ( ! node || focusOnMountRef.current === false ) {
return;
}
Expand Down
9 changes: 2 additions & 7 deletions packages/compose/src/hooks/use-focus-return/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
/**
* WordPress dependencies
*/
import { useRef, useEffect } from '@wordpress/element';

/**
* Internal dependencies
*/
import useCallbackRef from '../use-callback-ref';
import { useRef, useEffect, useCallback } from '@wordpress/element';

/**
* When opening modals/sidebars/dialogs, the focus
Expand Down Expand Up @@ -40,7 +35,7 @@ function useFocusReturn( onFocusReturn ) {
onFocusReturnRef.current = onFocusReturn;
}, [ onFocusReturn ] );

return useCallbackRef( ( node ) => {
return useCallback( ( node ) => {
if ( node ) {
// Set ref to be used when unmounting.
ref.current = node;
Expand Down
Loading

0 comments on commit 95551d9

Please sign in to comment.