@wordpress/compose 5.8.0 → 5.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +2 -2
  3. package/build/higher-order/if-condition/index.js +14 -10
  4. package/build/higher-order/if-condition/index.js.map +1 -1
  5. package/build/higher-order/pure/index.js +9 -5
  6. package/build/higher-order/pure/index.js.map +1 -1
  7. package/build/higher-order/with-global-events/index.js +2 -2
  8. package/build/higher-order/with-global-events/index.js.map +1 -1
  9. package/build/higher-order/with-instance-id/index.js +3 -3
  10. package/build/higher-order/with-instance-id/index.js.map +1 -1
  11. package/build/higher-order/with-preferred-color-scheme/index.native.js +2 -2
  12. package/build/higher-order/with-preferred-color-scheme/index.native.js.map +1 -1
  13. package/build/higher-order/with-safe-timeout/index.js +10 -7
  14. package/build/higher-order/with-safe-timeout/index.js.map +1 -1
  15. package/build/higher-order/with-state/index.js +2 -2
  16. package/build/higher-order/with-state/index.js.map +1 -1
  17. package/build/hooks/use-debounce/index.js.map +1 -1
  18. package/build/hooks/use-dialog/index.js +3 -3
  19. package/build/hooks/use-dialog/index.js.map +1 -1
  20. package/build/hooks/use-disabled/index.js.map +1 -1
  21. package/build/hooks/use-focus-return/index.js.map +1 -1
  22. package/build/hooks/use-keyboard-shortcut/index.js.map +1 -1
  23. package/build/hooks/use-merge-refs/index.js.map +1 -1
  24. package/build/hooks/use-throttle/index.js.map +1 -1
  25. package/build/index.js +48 -7
  26. package/build/index.js.map +1 -1
  27. package/build/index.native.js +40 -7
  28. package/build/index.native.js.map +1 -1
  29. package/build/utils/create-higher-order-component/index.js +19 -5
  30. package/build/utils/create-higher-order-component/index.js.map +1 -1
  31. package/build-module/higher-order/if-condition/index.js +13 -7
  32. package/build-module/higher-order/if-condition/index.js.map +1 -1
  33. package/build-module/higher-order/pure/index.js +10 -9
  34. package/build-module/higher-order/pure/index.js.map +1 -1
  35. package/build-module/higher-order/with-global-events/index.js +1 -1
  36. package/build-module/higher-order/with-global-events/index.js.map +1 -1
  37. package/build-module/higher-order/with-instance-id/index.js +3 -3
  38. package/build-module/higher-order/with-instance-id/index.js.map +1 -1
  39. package/build-module/higher-order/with-preferred-color-scheme/index.native.js +1 -1
  40. package/build-module/higher-order/with-preferred-color-scheme/index.native.js.map +1 -1
  41. package/build-module/higher-order/with-safe-timeout/index.js +9 -7
  42. package/build-module/higher-order/with-safe-timeout/index.js.map +1 -1
  43. package/build-module/higher-order/with-state/index.js +1 -1
  44. package/build-module/higher-order/with-state/index.js.map +1 -1
  45. package/build-module/hooks/use-debounce/index.js.map +1 -1
  46. package/build-module/hooks/use-dialog/index.js +3 -3
  47. package/build-module/hooks/use-dialog/index.js.map +1 -1
  48. package/build-module/hooks/use-disabled/index.js.map +1 -1
  49. package/build-module/hooks/use-focus-return/index.js.map +1 -1
  50. package/build-module/hooks/use-keyboard-shortcut/index.js.map +1 -1
  51. package/build-module/hooks/use-merge-refs/index.js.map +1 -1
  52. package/build-module/hooks/use-throttle/index.js.map +1 -1
  53. package/build-module/index.js +2 -2
  54. package/build-module/index.js.map +1 -1
  55. package/build-module/index.native.js +2 -2
  56. package/build-module/index.native.js.map +1 -1
  57. package/build-module/utils/create-higher-order-component/index.js +18 -4
  58. package/build-module/utils/create-higher-order-component/index.js.map +1 -1
  59. package/build-types/higher-order/if-condition/index.d.ts +5 -1
  60. package/build-types/higher-order/if-condition/index.d.ts.map +1 -1
  61. package/build-types/higher-order/pure/index.d.ts +1 -1
  62. package/build-types/higher-order/pure/index.d.ts.map +1 -1
  63. package/build-types/higher-order/with-global-events/index.d.ts.map +1 -1
  64. package/build-types/higher-order/with-instance-id/index.d.ts +8 -3
  65. package/build-types/higher-order/with-instance-id/index.d.ts.map +1 -1
  66. package/build-types/higher-order/with-safe-timeout/index.d.ts +37 -4
  67. package/build-types/higher-order/with-safe-timeout/index.d.ts.map +1 -1
  68. package/build-types/hooks/use-debounce/index.d.ts.map +1 -1
  69. package/build-types/hooks/use-dialog/index.d.ts +5 -1
  70. package/build-types/hooks/use-dialog/index.d.ts.map +1 -1
  71. package/build-types/hooks/use-disabled/index.d.ts.map +1 -1
  72. package/build-types/hooks/use-focus-return/index.d.ts.map +1 -1
  73. package/build-types/hooks/use-merge-refs/index.d.ts.map +1 -1
  74. package/build-types/hooks/use-throttle/index.d.ts.map +1 -1
  75. package/build-types/index.d.ts +1 -1
  76. package/build-types/utils/create-higher-order-component/index.d.ts +5 -12
  77. package/build-types/utils/create-higher-order-component/index.d.ts.map +1 -1
  78. package/package.json +8 -8
  79. package/src/higher-order/if-condition/index.tsx +11 -7
  80. package/src/higher-order/pure/index.tsx +29 -31
  81. package/src/higher-order/with-global-events/index.js +4 -2
  82. package/src/higher-order/with-global-events/test/index.js +2 -2
  83. package/src/higher-order/with-instance-id/index.tsx +19 -10
  84. package/src/higher-order/with-preferred-color-scheme/index.native.js +1 -1
  85. package/src/higher-order/with-safe-timeout/index.tsx +22 -19
  86. package/src/higher-order/with-state/index.js +1 -1
  87. package/src/hooks/use-debounce/index.js +4 -5
  88. package/src/hooks/use-dialog/index.js +16 -14
  89. package/src/hooks/use-disabled/index.js +8 -9
  90. package/src/hooks/use-focus-return/index.js +3 -1
  91. package/src/hooks/use-keyboard-shortcut/index.js +1 -1
  92. package/src/hooks/use-merge-refs/index.js +2 -1
  93. package/src/hooks/use-throttle/index.js +4 -5
  94. package/src/index.js +2 -2
  95. package/src/index.native.js +2 -2
  96. package/src/utils/create-higher-order-component/index.ts +30 -27
  97. package/src/utils/create-higher-order-component/test/index.js +1 -1
  98. package/tsconfig.tsbuildinfo +1 -1
@@ -1,7 +1,12 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import type { ComponentType } from 'react';
5
+
1
6
  /**
2
7
  * Internal dependencies
3
8
  */
4
- import createHigherOrderComponent from '../../utils/create-higher-order-component';
9
+ import { createHigherOrderComponent } from '../../utils/create-higher-order-component';
5
10
 
6
11
  /**
7
12
  * Higher-order component creator, creating a new component which renders if
@@ -20,12 +25,10 @@ import createHigherOrderComponent from '../../utils/create-higher-order-componen
20
25
  *
21
26
  * @return Higher-order component.
22
27
  */
23
- const ifCondition = < TProps extends Record< string, any > >(
24
- predicate: ( props: TProps ) => boolean
25
- ) =>
26
- createHigherOrderComponent< {} >(
27
- ( WrappedComponent ) => ( props ) => {
28
- if ( ! predicate( props as TProps ) ) {
28
+ function ifCondition< Props >( predicate: ( props: Props ) => boolean ) {
29
+ return createHigherOrderComponent(
30
+ ( WrappedComponent: ComponentType< Props > ) => ( props: Props ) => {
31
+ if ( ! predicate( props ) ) {
29
32
  return null;
30
33
  }
31
34
 
@@ -33,5 +36,6 @@ const ifCondition = < TProps extends Record< string, any > >(
33
36
  },
34
37
  'ifCondition'
35
38
  );
39
+ }
36
40
 
37
41
  export default ifCondition;
@@ -1,3 +1,8 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import type { ComponentType, ComponentClass } from 'react';
5
+
1
6
  /**
2
7
  * WordPress dependencies
3
8
  */
@@ -7,43 +12,36 @@ import { Component } from '@wordpress/element';
7
12
  /**
8
13
  * Internal dependencies
9
14
  */
10
- import createHigherOrderComponent from '../../utils/create-higher-order-component';
11
-
12
- /**
13
- * External dependencies
14
- */
15
- import type { ComponentType, ComponentClass } from 'react';
15
+ import { createHigherOrderComponent } from '../../utils/create-higher-order-component';
16
16
 
17
17
  /**
18
18
  * Given a component returns the enhanced component augmented with a component
19
19
  * only re-rendering when its props/state change
20
20
  */
21
- const pure = createHigherOrderComponent(
22
- < TProps extends Record< string, any > >(
23
- Wrapped: ComponentType< TProps >
24
- ) => {
25
- if ( Wrapped.prototype instanceof Component ) {
26
- return class extends ( Wrapped as ComponentClass< TProps > ) {
27
- shouldComponentUpdate( nextProps: TProps, nextState: any ) {
28
- return (
29
- ! isShallowEqual( nextProps, this.props ) ||
30
- ! isShallowEqual( nextState, this.state )
31
- );
32
- }
33
- };
34
- }
35
-
36
- return class extends Component< TProps > {
37
- shouldComponentUpdate( nextProps: TProps ) {
38
- return ! isShallowEqual( nextProps, this.props );
39
- }
40
-
41
- render() {
42
- return <Wrapped { ...this.props } />;
21
+ const pure = createHigherOrderComponent( function < Props >(
22
+ WrappedComponent: ComponentType< Props >
23
+ ): ComponentType< Props > {
24
+ if ( WrappedComponent.prototype instanceof Component ) {
25
+ return class extends ( WrappedComponent as ComponentClass< Props > ) {
26
+ shouldComponentUpdate( nextProps: Props, nextState: any ) {
27
+ return (
28
+ ! isShallowEqual( nextProps, this.props ) ||
29
+ ! isShallowEqual( nextState, this.state )
30
+ );
43
31
  }
44
32
  };
45
- },
46
- 'pure'
47
- );
33
+ }
34
+
35
+ return class extends Component< Props > {
36
+ shouldComponentUpdate( nextProps: Props ) {
37
+ return ! isShallowEqual( nextProps, this.props );
38
+ }
39
+
40
+ render() {
41
+ return <WrappedComponent { ...this.props } />;
42
+ }
43
+ };
44
+ },
45
+ 'pure' );
48
46
 
49
47
  export default pure;
@@ -12,7 +12,7 @@ import deprecated from '@wordpress/deprecated';
12
12
  /**
13
13
  * Internal dependencies
14
14
  */
15
- import createHigherOrderComponent from '../../utils/create-higher-order-component';
15
+ import { createHigherOrderComponent } from '../../utils/create-higher-order-component';
16
16
  import Listener from './listener';
17
17
 
18
18
  /**
@@ -71,7 +71,9 @@ export default function withGlobalEvents( eventTypesToHandlers ) {
71
71
  handleEvent( /** @type {any} */ event ) {
72
72
  const handler =
73
73
  eventTypesToHandlers[
74
- /** @type {keyof GlobalEventHandlersEventMap} */ ( event.type )
74
+ /** @type {keyof GlobalEventHandlersEventMap} */ (
75
+ event.type
76
+ )
75
77
  /* eslint-enable jsdoc/no-undefined-types */
76
78
  ];
77
79
  if ( typeof this.wrappedRef[ handler ] === 'function' ) {
@@ -82,8 +82,8 @@ describe( 'withGlobalEvents', () => {
82
82
  mountEnhancedComponent();
83
83
 
84
84
  // Get the HOC wrapper instance.
85
- const hocInstance = wrapper.root.findByType( OriginalComponent ).parent
86
- .instance;
85
+ const hocInstance =
86
+ wrapper.root.findByType( OriginalComponent ).parent.instance;
87
87
 
88
88
  expect( Listener._instance.add ).toHaveBeenCalledWith(
89
89
  'resize',
@@ -1,21 +1,30 @@
1
1
  /**
2
2
  * Internal dependencies
3
3
  */
4
- import createHigherOrderComponent from '../../utils/create-higher-order-component';
4
+ import {
5
+ createHigherOrderComponent,
6
+ WithInjectedProps,
7
+ WithoutInjectedProps,
8
+ } from '../../utils/create-higher-order-component';
5
9
  import useInstanceId from '../../hooks/use-instance-id';
6
10
 
11
+ type InstanceIdProps = { instanceId: string | number };
12
+
7
13
  /**
8
14
  * A Higher Order Component used to be provide a unique instance ID by
9
15
  * component.
10
16
  */
11
- const withInstanceId = createHigherOrderComponent< {
12
- instanceId: string | number;
13
- } >( ( WrappedComponent ) => {
14
- return ( props ) => {
15
- const instanceId = useInstanceId( WrappedComponent );
16
- // @ts-ignore
17
- return <WrappedComponent { ...props } instanceId={ instanceId } />;
18
- };
19
- }, 'withInstanceId' );
17
+ const withInstanceId = createHigherOrderComponent(
18
+ < C extends WithInjectedProps< C, InstanceIdProps > >(
19
+ WrappedComponent: C
20
+ ) => {
21
+ return ( props: WithoutInjectedProps< C, InstanceIdProps > ) => {
22
+ const instanceId = useInstanceId( WrappedComponent );
23
+ // @ts-ignore
24
+ return <WrappedComponent { ...props } instanceId={ instanceId } />;
25
+ };
26
+ },
27
+ 'instanceId'
28
+ );
20
29
 
21
30
  export default withInstanceId;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Internal dependencies
3
3
  */
4
- import createHigherOrderComponent from '../../utils/create-higher-order-component';
4
+ import { createHigherOrderComponent } from '../../utils/create-higher-order-component';
5
5
  import usePreferredColorScheme from '../../hooks/use-preferred-color-scheme';
6
6
 
7
7
  /**
@@ -2,7 +2,6 @@
2
2
  * External dependencies
3
3
  */
4
4
  import { without } from 'lodash';
5
- import type { ComponentType } from 'react';
6
5
 
7
6
  /**
8
7
  * WordPress dependencies
@@ -12,7 +11,11 @@ import { Component } from '@wordpress/element';
12
11
  /**
13
12
  * Internal dependencies
14
13
  */
15
- import createHigherOrderComponent from '../../utils/create-higher-order-component';
14
+ import {
15
+ createHigherOrderComponent,
16
+ WithInjectedProps,
17
+ WithoutInjectedProps,
18
+ } from '../../utils/create-higher-order-component';
16
19
 
17
20
  /**
18
21
  * We cannot use the `Window['setTimeout']` and `Window['clearTimeout']`
@@ -22,25 +25,24 @@ import createHigherOrderComponent from '../../utils/create-higher-order-componen
22
25
  * In the case of this component, we only handle the simplest case where
23
26
  * `setTimeout` only accepts a function (not a string) and an optional delay.
24
27
  */
25
- type TimeoutProps = {
28
+ interface TimeoutProps {
26
29
  setTimeout: ( fn: () => void, delay: number ) => number;
27
30
  clearTimeout: ( id: number ) => void;
28
- };
31
+ }
29
32
 
30
33
  /**
31
34
  * A higher-order component used to provide and manage delayed function calls
32
35
  * that ought to be bound to a component's lifecycle.
33
36
  */
34
- const withSafeTimeout = createHigherOrderComponent< TimeoutProps >(
35
- < TProps extends TimeoutProps >(
36
- OriginalComponent: ComponentType< TProps >
37
+ const withSafeTimeout = createHigherOrderComponent(
38
+ < C extends WithInjectedProps< C, TimeoutProps > >(
39
+ OriginalComponent: C
37
40
  ) => {
38
- return class WrappedComponent extends Component<
39
- Omit< TProps, keyof TimeoutProps >
40
- > {
41
+ type WrappedProps = WithoutInjectedProps< C, TimeoutProps >;
42
+ return class WrappedComponent extends Component< WrappedProps > {
41
43
  timeouts: number[];
42
44
 
43
- constructor( props: Omit< TProps, keyof TimeoutProps > ) {
45
+ constructor( props: WrappedProps ) {
44
46
  super( props );
45
47
  this.timeouts = [];
46
48
  this.setTimeout = this.setTimeout.bind( this );
@@ -51,7 +53,7 @@ const withSafeTimeout = createHigherOrderComponent< TimeoutProps >(
51
53
  this.timeouts.forEach( clearTimeout );
52
54
  }
53
55
 
54
- setTimeout( fn: ( ...args: any[] ) => void, delay: number ) {
56
+ setTimeout( fn: () => void, delay: number ) {
55
57
  const id = setTimeout( () => {
56
58
  fn();
57
59
  this.clearTimeout( id );
@@ -66,13 +68,14 @@ const withSafeTimeout = createHigherOrderComponent< TimeoutProps >(
66
68
  }
67
69
 
68
70
  render() {
69
- const props = {
70
- ...this.props,
71
- setTimeout: this.setTimeout,
72
- clearTimeout: this.clearTimeout,
73
- } as TProps;
74
-
75
- return <OriginalComponent { ...props } />;
71
+ return (
72
+ // @ts-ignore
73
+ <OriginalComponent
74
+ { ...this.props }
75
+ setTimeout={ this.setTimeout }
76
+ clearTimeout={ this.clearTimeout }
77
+ />
78
+ );
76
79
  }
77
80
  };
78
81
  },
@@ -7,7 +7,7 @@ import deprecated from '@wordpress/deprecated';
7
7
  /**
8
8
  * Internal dependencies
9
9
  */
10
- import createHigherOrderComponent from '../../utils/create-higher-order-component';
10
+ import { createHigherOrderComponent } from '../../utils/create-higher-order-component';
11
11
 
12
12
  /**
13
13
  * A Higher Order Component used to provide and manage internal component state
@@ -27,11 +27,10 @@ import { useEffect } from '@wordpress/element';
27
27
  */
28
28
  export default function useDebounce( fn, wait, options ) {
29
29
  /* eslint-enable jsdoc/valid-types */
30
- const debounced = useMemoOne( () => debounce( fn, wait, options ), [
31
- fn,
32
- wait,
33
- options,
34
- ] );
30
+ const debounced = useMemoOne(
31
+ () => debounce( fn, wait, options ),
32
+ [ fn, wait, options ]
33
+ );
35
34
  useEffect( () => () => debounced.cancel(), [ debounced ] );
36
35
  return debounced;
37
36
  }
@@ -13,13 +13,14 @@ import useFocusReturn from '../use-focus-return';
13
13
  import useFocusOutside from '../use-focus-outside';
14
14
  import useMergeRefs from '../use-merge-refs';
15
15
 
16
- /* eslint-disable jsdoc/valid-types */
16
+ /**
17
+ * @typedef {import('../use-focus-on-mount').default} useFocusOnMount
18
+ */
17
19
  /**
18
20
  * @typedef DialogOptions
19
21
  * @property {Parameters<useFocusOnMount>[0]} focusOnMount Focus on mount arguments.
20
22
  * @property {() => void} onClose Function to call when the dialog is closed.
21
23
  */
22
- /* eslint-enable jsdoc/valid-types */
23
24
 
24
25
  /**
25
26
  * Returns a ref and props to apply to a dialog wrapper to enable the following behaviors:
@@ -57,19 +58,20 @@ function useDialog( options ) {
57
58
  return;
58
59
  }
59
60
 
60
- node.addEventListener( 'keydown', (
61
- /** @type {KeyboardEvent} */ event
62
- ) => {
63
- // Close on escape.
64
- if (
65
- event.keyCode === ESCAPE &&
66
- ! event.defaultPrevented &&
67
- currentOptions.current?.onClose
68
- ) {
69
- event.preventDefault();
70
- currentOptions.current.onClose();
61
+ node.addEventListener(
62
+ 'keydown',
63
+ ( /** @type {KeyboardEvent} */ event ) => {
64
+ // Close on escape.
65
+ if (
66
+ event.keyCode === ESCAPE &&
67
+ ! event.defaultPrevented &&
68
+ currentOptions.current?.onClose
69
+ ) {
70
+ event.preventDefault();
71
+ currentOptions.current.onClose();
72
+ }
71
73
  }
72
- } );
74
+ );
73
75
  }, [] );
74
76
 
75
77
  return [
@@ -70,9 +70,8 @@ export default function useDisabled( {
70
70
 
71
71
  const disable = () => {
72
72
  if ( node.style.getPropertyValue( 'user-select' ) !== 'none' ) {
73
- const previousValue = node.style.getPropertyValue(
74
- 'user-select'
75
- );
73
+ const previousValue =
74
+ node.style.getPropertyValue( 'user-select' );
76
75
  node.style.setProperty( 'user-select', 'none' );
77
76
  node.style.setProperty( '-webkit-user-select', 'none' );
78
77
  updates.push( () => {
@@ -110,9 +109,8 @@ export default function useDisabled( {
110
109
  focusable.nodeName === 'A' &&
111
110
  focusable.getAttribute( 'tabindex' ) !== '-1'
112
111
  ) {
113
- const previousValue = focusable.getAttribute(
114
- 'tabindex'
115
- );
112
+ const previousValue =
113
+ focusable.getAttribute( 'tabindex' );
116
114
  focusable.setAttribute( 'tabindex', '-1' );
117
115
  updates.push( () => {
118
116
  if ( ! focusable.isConnected ) {
@@ -158,9 +156,10 @@ export default function useDisabled( {
158
156
  focusable instanceof
159
157
  node.ownerDocument.defaultView.HTMLElement
160
158
  ) {
161
- const previousValue = focusable.style.getPropertyValue(
162
- 'pointer-events'
163
- );
159
+ const previousValue =
160
+ focusable.style.getPropertyValue(
161
+ 'pointer-events'
162
+ );
164
163
  focusable.style.setProperty( 'pointer-events', 'none' );
165
164
  updates.push( () => {
166
165
  if ( ! focusable.isConnected ) {
@@ -64,7 +64,9 @@ function useFocusReturn( onFocusReturn ) {
64
64
  if ( onFocusReturnRef.current ) {
65
65
  onFocusReturnRef.current();
66
66
  } else {
67
- /** @type {null | HTMLElement} */ ( focusedBeforeMount.current )?.focus();
67
+ /** @type {null | HTMLElement} */ (
68
+ focusedBeforeMount.current
69
+ )?.focus();
68
70
  }
69
71
  }
70
72
  }, [] );
@@ -73,7 +73,7 @@ function useKeyboardShortcut(
73
73
  : // We were passing `document` here previously, so to successfully cast it to Element we must cast it first to `unknown`.
74
74
  // Not sure if this is a mistake but it was the behavior previous to the addition of types so we're just doing what's
75
75
  // necessary to maintain the existing behavior.
76
- /** @type {Element} */ (/** @type {unknown} */ ( document ))
76
+ /** @type {Element} */ ( /** @type {unknown} */ ( document ) )
77
77
  );
78
78
  castArray( shortcuts ).forEach( ( shortcut ) => {
79
79
  const keys = shortcut.split( '+' );
@@ -20,7 +20,8 @@ function assignRef( ref, value ) {
20
20
  ref( value );
21
21
  } else if ( ref && ref.hasOwnProperty( 'current' ) ) {
22
22
  /* eslint-disable jsdoc/no-undefined-types */
23
- /** @type {import('react').MutableRefObject<T>} */ ( ref ).current = value;
23
+ /** @type {import('react').MutableRefObject<T>} */ ( ref ).current =
24
+ value;
24
25
  /* eslint-enable jsdoc/no-undefined-types */
25
26
  }
26
27
  }
@@ -25,11 +25,10 @@ import { useEffect } from '@wordpress/element';
25
25
  * @return {import('lodash').DebouncedFunc<TFunc>} Throttled function.
26
26
  */
27
27
  export default function useThrottle( fn, wait, options ) {
28
- const throttled = useMemoOne( () => throttle( fn, wait, options ), [
29
- fn,
30
- wait,
31
- options,
32
- ] );
28
+ const throttled = useMemoOne(
29
+ () => throttle( fn, wait, options ),
30
+ [ fn, wait, options ]
31
+ );
33
32
  useEffect( () => () => throttled.cancel(), [ throttled ] );
34
33
  return throttled;
35
34
  }
package/src/index.js CHANGED
@@ -1,5 +1,5 @@
1
- // Utils.
2
- export { default as createHigherOrderComponent } from './utils/create-higher-order-component';
1
+ // The `createHigherOrderComponent` helper and helper types.
2
+ export * from './utils/create-higher-order-component';
3
3
 
4
4
  // Compose helper (aliased flowRight from Lodash)
5
5
  export { default as compose } from './higher-order/compose';
@@ -1,5 +1,5 @@
1
- // Utils.
2
- export { default as createHigherOrderComponent } from './utils/create-higher-order-component';
1
+ // The `createHigherOrderComponent` helper and helper types.
2
+ export * from './utils/create-higher-order-component';
3
3
 
4
4
  // Compose helper (aliased flowRight from Lodash)
5
5
  export { default as compose } from './higher-order/compose';
@@ -4,22 +4,13 @@
4
4
  import { camelCase, upperFirst } from 'lodash';
5
5
  import type { ComponentType } from 'react';
6
6
 
7
- /**
8
- * Higher order components can cause props to be obviated. For example a HOC that
9
- * injects i18n props will obviate the need for the i18n props to be passed to the component.
10
- *
11
- * If a HOC does not obviate the need for any specific props then we default to `{}` which
12
- * essentially subtracts 0 from the original props of the passed in component. An example
13
- * of this is the `pure` HOC which does not change the API surface of the component but
14
- * simply modifies the internals.
15
- */
16
- export type HigherOrderComponent< HOCProps extends Record< string, any > > = <
17
- InnerProps extends HOCProps
18
- >(
19
- Inner: ComponentType< InnerProps >
20
- ) => {} extends HOCProps
21
- ? ComponentType< InnerProps >
22
- : ComponentType< Omit< InnerProps, keyof HOCProps > >;
7
+ type GetProps< C > = C extends ComponentType< infer P > ? P : never;
8
+
9
+ export type WithoutInjectedProps< C, I > = Omit< GetProps< C >, keyof I >;
10
+
11
+ export type WithInjectedProps< C, I > = ComponentType<
12
+ WithoutInjectedProps< C, I > & I
13
+ >;
23
14
 
24
15
  /**
25
16
  * Given a function mapping a component to an enhanced component and modifier
@@ -30,19 +21,31 @@ export type HigherOrderComponent< HOCProps extends Record< string, any > > = <
30
21
  *
31
22
  * @return Component class with generated display name assigned.
32
23
  */
33
- function createHigherOrderComponent<
34
- HOCProps extends Record< string, any > = {}
35
- >( mapComponent: HigherOrderComponent< HOCProps >, modifierName: string ) {
36
- return < InnerProps extends HOCProps >(
37
- Inner: ComponentType< InnerProps >
38
- ) => {
24
+ export function createHigherOrderComponent<
25
+ TInner extends ComponentType< any >,
26
+ TOuter extends ComponentType< any >
27
+ >( mapComponent: ( Inner: TInner ) => TOuter, modifierName: string ) {
28
+ return ( Inner: TInner ) => {
39
29
  const Outer = mapComponent( Inner );
40
- const displayName = Inner.displayName || Inner.name || 'Component';
41
- Outer.displayName = `${ upperFirst(
42
- camelCase( modifierName )
43
- ) }(${ displayName })`;
30
+ Outer.displayName = hocName( modifierName, Inner );
44
31
  return Outer;
45
32
  };
46
33
  }
47
34
 
48
- export default createHigherOrderComponent;
35
+ /**
36
+ * Returns a displayName for a higher-order component, given a wrapper name.
37
+ *
38
+ * @example
39
+ * hocName( 'MyMemo', Widget ) === 'MyMemo(Widget)';
40
+ * hocName( 'MyMemo', <div /> ) === 'MyMemo(Component)';
41
+ *
42
+ * @param name Name assigned to higher-order component's wrapper component.
43
+ * @param Inner Wrapped component inside higher-order component.
44
+ * @return Wrapped name of higher-order component.
45
+ */
46
+ const hocName = ( name: string, Inner: ComponentType< any > ) => {
47
+ const inner = Inner.displayName || Inner.name || 'Component';
48
+ const outer = upperFirst( camelCase( name ) );
49
+
50
+ return `${ outer }(${ inner })`;
51
+ };
@@ -6,7 +6,7 @@ import { Component } from '@wordpress/element';
6
6
  /**
7
7
  * Internal dependencies
8
8
  */
9
- import createHigherOrderComponent from '../';
9
+ import { createHigherOrderComponent } from '../';
10
10
 
11
11
  describe( 'createHigherOrderComponent', () => {
12
12
  it( 'should use default name for anonymous function', () => {