UNPKG

@wordpress/compose

Version:
511 lines (321 loc) 14.8 kB
# Compose The `compose` package is a collection of handy [Hooks](https://reactjs.org/docs/hooks-intro.html) and [Higher Order Components](https://facebook.github.io/react/docs/higher-order-components.html) (HOCs) you can use to wrap your WordPress components and provide some basic features like: state, instance id, pure... The `compose` function is an alias to [flowRight](https://lodash.com/docs/#flowRight) from Lodash. It comes from functional programming, and allows you to compose any number of functions. You might also think of this as layering functions; `compose` will execute the last function first, then sequentially move back through the previous functions passing the result of each function upward. An example that illustrates it for two functions: ```js const compose = ( f, g ) => x => f( g( x ) ); ``` Here's a simplified example of **compose** in use from Gutenberg's [`PluginSidebar` component](https://github.com/WordPress/gutenberg/blob/HEAD/packages/edit-post/src/components/sidebar/plugin-sidebar/index.js): Using compose: ```js const applyWithSelect = withSelect( ( select, ownProps ) => { return doSomething( select, ownProps ); } ); const applyWithDispatch = withDispatch( ( dispatch, ownProps ) => { return doSomethingElse( dispatch, ownProps ); } ); export default compose( withPluginContext, applyWithSelect, applyWithDispatch )( PluginSidebarMoreMenuItem ); ``` Without `compose`, the code would look like this: ```js const applyWithSelect = withSelect( ( select, ownProps ) => { return doSomething( select, ownProps ); } ); const applyWithDispatch = withDispatch( ( dispatch, ownProps ) => { return doSomethingElse( dispatch, ownProps ); } ); export default withPluginContext( applyWithSelect( applyWithDispatch( PluginSidebarMoreMenuItem ) ) ); ``` ## Installation Install the module ```bash npm install @wordpress/compose --save ``` _This package assumes that your code will run in an **ES2015+** environment. If you're using an environment that has limited or no support for ES2015+ such as IE browsers then using [core-js](https://github.com/zloirock/core-js) will add polyfills for these methods._ ## API For more details, you can refer to each Higher Order Component's README file. [Available components are located here.](https://github.com/WordPress/gutenberg/tree/HEAD/packages/compose/src) <!-- START TOKEN(Autogenerated API docs) --> <a name="compose" href="#compose">#</a> **compose** Composes multiple higher-order components into a single higher-order component. Performs right-to-left function composition, where each successive invocation is supplied the return value of the previous. _Parameters_ - _hocs_ `...Function`: The HOC functions to invoke. _Returns_ - `Function`: Returns the new composite function. <a name="createHigherOrderComponent" href="#createHigherOrderComponent">#</a> **createHigherOrderComponent** Given a function mapping a component to an enhanced component and modifier name, returns the enhanced component augmented with a generated displayName. _Parameters_ - _mapComponentToEnhancedComponent_ `HigherOrderComponent< TInnerProps, TOuterProps >`: Function mapping component to enhanced component. - _modifierName_ `string`: Seed name from which to generated display name. _Returns_ - `HigherOrderComponent< TInnerProps, TOuterProps >`: Component class with generated display name assigned. <a name="ifCondition" href="#ifCondition">#</a> **ifCondition** Higher-order component creator, creating a new component which renders if the given condition is satisfied or with the given optional prop name. _Usage_ ```ts type Props = { foo: string }; const Component = ( props: Props ) => <div>{ props.foo }</div>; const ConditionalComponent = ifCondition( ( props: Props ) => props.foo.length !== 0 )( Component ); <ConditionalComponent foo="" />; // => null <ConditionalComponent foo="bar" />; // => <div>bar</div>; ``` _Parameters_ - _predicate_ `( props: TProps ) => boolean`: Function to test condition. _Returns_ - `HigherOrderComponent< TProps, TProps >`: Higher-order component. <a name="pure" href="#pure">#</a> **pure** Given a component returns the enhanced component augmented with a component only rerendering when its props/state change _Type_ - `SimpleHigherOrderComponent` <a name="useAsyncList" href="#useAsyncList">#</a> **useAsyncList** React hook returns an array which items get asynchronously appended from a source array. This behavior is useful if we want to render a list of items asynchronously for performance reasons. _Parameters_ - _list_ `Array`: Source array. _Returns_ - `Array`: Async array. <a name="useConstrainedTabbing" href="#useConstrainedTabbing">#</a> **useConstrainedTabbing** In Dialogs/modals, the tabbing must be constrained to the content of the wrapper element. This hook adds the behavior to the returned ref. _Usage_ ```js import { useConstrainedTabbing } from '@wordpress/compose'; const ConstrainedTabbingExample = () => { const constrainedTabbingRef = useConstrainedTabbing() return ( <div ref={ constrainedTabbingRef }> <Button /> <Button /> </div> ); } ``` _Returns_ - `Object|Function`: Element Ref. <a name="useCopyOnClick" href="#useCopyOnClick">#</a> **useCopyOnClick** > **Deprecated** Copies the text to the clipboard when the element is clicked. _Parameters_ - _ref_ `Object`: Reference with the element. - _text_ `string|Function`: The text to copy. - _timeout_ `number`: Optional timeout to reset the returned state. 4 seconds by default. _Returns_ - `boolean`: Whether or not the text has been copied. Resets after the timeout. <a name="useCopyToClipboard" href="#useCopyToClipboard">#</a> **useCopyToClipboard** Copies the given text to the clipboard when the element is clicked. _Parameters_ - _text_ `text|Function`: The text to copy. Use a function if not already available and expensive to compute. - _onSuccess_ `Function`: Called when to text is copied. _Returns_ - `RefObject`: A ref to assign to the target element. <a name="useDebounce" href="#useDebounce">#</a> **useDebounce** Debounces a function with Lodash's `debounce`. A new debounced function will be returned and any scheduled calls cancelled if any of the arguments change, including the function to debounce, so please wrap functions created on render in components in `useCallback`. _Parameters_ - _args_ `...any`: Arguments passed to Lodash's `debounce`. _Returns_ - `Function`: Debounced function. <a name="useFocusOnMount" href="#useFocusOnMount">#</a> **useFocusOnMount** Hook used to focus the first tabbable element on mount. _Usage_ ```js import { useFocusOnMount } from '@wordpress/compose'; const WithFocusOnMount = () => { const ref = useFocusOnMount() return ( <div ref={ ref }> <Button /> <Button /> </div> ); } ``` _Parameters_ - _focusOnMount_ `boolean|string`: Focus on mount mode. _Returns_ - `Function`: Ref callback. <a name="useFocusReturn" href="#useFocusReturn">#</a> **useFocusReturn** When opening modals/sidebars/dialogs, the focus must move to the opened area and return to the previously focused element when closed. The current hook implements the returning behavior. _Usage_ ```js import { useFocusReturn } from '@wordpress/compose'; const WithFocusReturn = () => { const ref = useFocusReturn() return ( <div ref={ ref }> <Button /> <Button /> </div> ); } ``` _Parameters_ - _onFocusReturn_ `Function?`: Overrides the default return behavior. _Returns_ - `Function`: Element Ref. <a name="useInstanceId" href="#useInstanceId">#</a> **useInstanceId** Provides a unique instance ID. _Parameters_ - _object_ `Object`: Object reference to create an id for. - _prefix_ `string`: Prefix for the unique id. - _preferredId_ `string`: Default ID to use. _Returns_ - `string | number`: The unique instance id. <a name="useIsomorphicLayoutEffect" href="#useIsomorphicLayoutEffect">#</a> **useIsomorphicLayoutEffect** Preferred over direct usage of `useLayoutEffect` when supporting server rendered components (SSR) because currently React throws a warning when using useLayoutEffect in that environment. <a name="useKeyboardShortcut" href="#useKeyboardShortcut">#</a> **useKeyboardShortcut** Attach a keyboard shortcut handler. _Parameters_ - _shortcuts_ `string[]|string`: Keyboard Shortcuts. - _callback_ `Function`: Shortcut callback. - _options_ `WPKeyboardShortcutConfig`: Shortcut options. <a name="useMediaQuery" href="#useMediaQuery">#</a> **useMediaQuery** Runs a media query and returns its value when it changes. _Parameters_ - _query_ `[string]`: Media Query. _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. Based on <https://usehooks.com/usePrevious/>. _Parameters_ - _value_ `T`: The value to track. _Returns_ - `T|undefined`: The value from the previous render. <a name="useReducedMotion" href="#useReducedMotion">#</a> **useReducedMotion** Hook returning whether the user has a preference for reduced motion. _Returns_ - `boolean`: Reduced motion preference value. <a name="useRefEffect" href="#useRefEffect">#</a> **useRefEffect** Effect-like ref callback. Just like with `useEffect`, this allows you to return a cleanup function to be run if the ref changes or one of the dependencies changes. The ref is provided as an argument to the callback functions. The main difference between this and `useEffect` is that the `useEffect` callback is not called when the ref changes, but this is. Pass the returned ref callback as the component's ref and merge multiple refs with `useMergeRefs`. It's worth noting that if the dependencies array is empty, there's not strictly a need to clean up event handlers for example, because the node is to be removed. It _is_ necessary if you add dependencies because the ref callback will be called multiple times for the same node. _Parameters_ - _callback_ `Function`: Callback with ref as argument. - _dependencies_ `Array`: Dependencies of the callback. _Returns_ - `Function`: Ref callback. <a name="useResizeObserver" href="#useResizeObserver">#</a> **useResizeObserver** Hook which allows to listen the resize event of any target element when it changes sizes. _Note: `useResizeObserver` will report `null` until after first render_ _Usage_ ```js const App = () => { const [ resizeListener, sizes ] = useResizeObserver(); return ( <div> { resizeListener } Your content here </div> ); }; ``` _Returns_ - `Array`: An array of {Element} `resizeListener` and {?Object} `sizes` with properties `width` and `height` <a name="useThrottle" href="#useThrottle">#</a> **useThrottle** Throttles a function with Lodash's `throttle`. A new throttled function will be returned and any scheduled calls cancelled if any of the arguments change, including the function to throttle, so please wrap functions created on render in components in `useCallback`. _Parameters_ - _args_ `...any`: Arguments passed to Lodash's `throttle`. _Returns_ - `Function`: Throttled function. <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="useWarnOnChange" href="#useWarnOnChange">#</a> **useWarnOnChange** Hook that performs a shallow comparison between the preview value of an object and the new one, if there's a difference, it prints it to the console. this is useful in performance related work, to check why a component re-renders. _Usage_ ```jsx function MyComponent(props) { useWarnOnChange(props); return "Something"; } ``` _Parameters_ - _object_ `Object`: Object which changes to compare. - _prefix_ `string`: Just a prefix to show when console logging. <a name="withGlobalEvents" href="#withGlobalEvents">#</a> **withGlobalEvents** > **Deprecated** Higher-order component creator which, given an object of DOM event types and values corresponding to a callback function name on the component, will create or update a window event handler to invoke the callback when an event occurs. On behalf of the consuming developer, the higher-order component manages unbinding when the component unmounts, and binding at most a single event handler for the entire application. _Parameters_ - _eventTypesToHandlers_ `Object<string,string>`: Object with keys of DOM event type, the value a name of the function on the original component's instance which handles the event. _Returns_ - `Function`: Higher-order component. <a name="withInstanceId" href="#withInstanceId">#</a> **withInstanceId** A Higher Order Component used to be provide a unique instance ID by component. _Parameters_ - _WrappedComponent_ `WPComponent`: The wrapped component. _Returns_ - `WPComponent`: Component with an instanceId prop. <a name="withSafeTimeout" href="#withSafeTimeout">#</a> **withSafeTimeout** A higher-order component used to provide and manage delayed function calls that ought to be bound to a component's lifecycle. _Parameters_ - _OriginalComponent_ `WPComponent`: Component requiring setTimeout _Returns_ - `WPComponent`: Wrapped component. <a name="withState" href="#withState">#</a> **withState** A Higher Order Component used to provide and manage internal component state via props. _Parameters_ - _initialState_ `?Object`: Optional initial state of the component. _Returns_ - `WPComponent`: Wrapped component. <!-- END TOKEN(Autogenerated API docs) --> <br/><br/><p align="center"><img src="https://s.w.org/style/images/codeispoetry.png?1" alt="Code is Poetry." /></p>