@wordpress/compose 8.0.0 → 8.1.1

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 (63) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +5 -5
  3. package/build/higher-order/pure/index.cjs +15 -0
  4. package/build/higher-order/pure/index.cjs.map +3 -3
  5. package/build/hooks/use-disabled/index.cjs +2 -2
  6. package/build/hooks/use-disabled/index.cjs.map +2 -2
  7. package/build/hooks/use-focus-return/index.cjs.map +1 -1
  8. package/build/hooks/use-media-query/index.cjs +2 -2
  9. package/build/hooks/use-media-query/index.cjs.map +2 -2
  10. package/build/hooks/use-merge-refs/index.cjs +28 -8
  11. package/build/hooks/use-merge-refs/index.cjs.map +2 -2
  12. package/build/hooks/use-resize-observer/use-resize-observer.cjs.map +2 -2
  13. package/build/hooks/use-viewport-match/index.cjs +1 -1
  14. package/build/hooks/use-viewport-match/index.cjs.map +2 -2
  15. package/build-module/higher-order/pure/index.mjs +5 -0
  16. package/build-module/higher-order/pure/index.mjs.map +2 -2
  17. package/build-module/hooks/use-disabled/index.mjs +2 -2
  18. package/build-module/hooks/use-disabled/index.mjs.map +2 -2
  19. package/build-module/hooks/use-focus-return/index.mjs.map +1 -1
  20. package/build-module/hooks/use-media-query/index.mjs +2 -2
  21. package/build-module/hooks/use-media-query/index.mjs.map +2 -2
  22. package/build-module/hooks/use-merge-refs/index.mjs +28 -8
  23. package/build-module/hooks/use-merge-refs/index.mjs.map +2 -2
  24. package/build-module/hooks/use-resize-observer/use-resize-observer.mjs.map +2 -2
  25. package/build-module/hooks/use-viewport-match/index.mjs +1 -1
  26. package/build-module/hooks/use-viewport-match/index.mjs.map +2 -2
  27. package/build-types/higher-order/pure/index.d.ts.map +1 -1
  28. package/build-types/higher-order/with-safe-timeout/index.d.ts +3 -1
  29. package/build-types/higher-order/with-safe-timeout/index.d.ts.map +1 -1
  30. package/build-types/hooks/use-media-query/index.d.ts +1 -1
  31. package/build-types/hooks/use-media-query/index.d.ts.map +1 -1
  32. package/build-types/hooks/use-merge-refs/index.d.ts +7 -5
  33. package/build-types/hooks/use-merge-refs/index.d.ts.map +1 -1
  34. package/build-types/hooks/use-viewport-match/index.d.ts +1 -1
  35. package/build-types/hooks/use-viewport-match/index.d.ts.map +1 -1
  36. package/package.json +17 -13
  37. package/src/higher-order/pure/index.tsx +6 -0
  38. package/src/higher-order/pure/test/index.js +14 -81
  39. package/src/hooks/use-disabled/index.ts +3 -3
  40. package/src/hooks/use-disabled/test/index.js +4 -4
  41. package/src/hooks/use-drop-zone/README.md +1 -1
  42. package/src/hooks/use-focus-return/index.js +2 -2
  43. package/src/hooks/use-media-query/index.ts +10 -3
  44. package/src/hooks/use-media-query/test/ssr.js +47 -0
  45. package/src/hooks/use-merge-refs/index.ts +51 -20
  46. package/src/hooks/use-merge-refs/test/index.js +288 -0
  47. package/src/hooks/use-resize-observer/use-resize-observer.ts +1 -1
  48. package/src/hooks/use-viewport-match/index.js +8 -2
  49. package/src/higher-order/with-network-connectivity/README.md +0 -20
  50. package/src/higher-order/with-network-connectivity/index.native.js +0 -19
  51. package/src/higher-order/with-preferred-color-scheme/index.native.js +0 -40
  52. package/src/hooks/use-constrained-tabbing/index.native.js +0 -14
  53. package/src/hooks/use-focus-outside/index.native.js +0 -170
  54. package/src/hooks/use-keyboard-shortcut/index.native.js +0 -2
  55. package/src/hooks/use-network-connectivity/index.native.js +0 -59
  56. package/src/hooks/use-network-connectivity/test/index.native.js +0 -87
  57. package/src/hooks/use-preferred-color-scheme/index.android.js +0 -30
  58. package/src/hooks/use-preferred-color-scheme/index.ios.js +0 -13
  59. package/src/hooks/use-preferred-color-scheme-style/index.native.js +0 -33
  60. package/src/hooks/use-resize-observer/index.native.js +0 -1
  61. package/src/hooks/use-resize-observer/legacy/index.native.js +0 -59
  62. package/src/hooks/use-resize-observer/legacy/test/index.native.js +0 -46
  63. package/src/index.native.js +0 -44
@@ -2,13 +2,34 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import { useRef, useCallback, useLayoutEffect } from '@wordpress/element';
5
- import type { Ref, RefCallback } from 'react';
5
+ import type { MutableRefObject, Ref, RefCallback } from 'react';
6
6
 
7
- function assignRef< T >( ref: Ref< T >, value: T ) {
7
+ // Returns a cleanup function if the ref callback returned one (React 19 ref
8
+ // callback cleanup pattern), otherwise `undefined`. Object refs never have a
9
+ // cleanup and only set `.current`.
10
+ function assignRef< T >( ref: Ref< T >, value: T ): ( () => void ) | undefined {
8
11
  if ( typeof ref === 'function' ) {
9
- ref( value );
12
+ const returned = ref( value );
13
+ return typeof returned === 'function' ? returned : undefined;
10
14
  } else if ( ref && ref.hasOwnProperty( 'current' ) ) {
11
- ref.current = value;
15
+ ( ref as MutableRefObject< T > ).current = value;
16
+ }
17
+ return undefined;
18
+ }
19
+
20
+ // Tear down a ref at the given index: prefer the stored cleanup; otherwise
21
+ // fall back to calling the ref with `null`.
22
+ function detachRef< T >(
23
+ ref: Ref< T >,
24
+ index: number,
25
+ cleanups: Array< ( () => void ) | undefined >
26
+ ): void {
27
+ const cleanup = cleanups[ index ];
28
+ if ( cleanup ) {
29
+ cleanups[ index ] = undefined;
30
+ cleanup();
31
+ } else {
32
+ assignRef( ref, null );
12
33
  }
13
34
  }
14
35
 
@@ -28,22 +49,24 @@ function assignRef< T >( ref: Ref< T >, value: T ) {
28
49
  * old ref callback will be called with `null` and the new ref callback will be
29
50
  * called with the same value.
30
51
  *
31
- * To make ref callbacks easier to use, you can also pass the result of
32
- * `useRefEffect`, which makes cleanup easier by allowing you to return a
33
- * cleanup function instead of handling `null`.
52
+ * Inner ref callbacks may return a cleanup function (React 19's ref callback
53
+ * cleanup pattern). When a ref callback returns a function, that function is
54
+ * invoked at teardown (node change, dependency change, or unmount) **instead
55
+ * of** the callback being called with `null`. Callbacks that do not return a
56
+ * cleanup continue to receive `null` on teardown as before.
34
57
  *
35
58
  * It's also possible to _disable_ a ref (and its behaviour) by simply not
36
59
  * passing the ref.
37
60
  *
38
61
  * ```jsx
39
- * const ref = useRefEffect( ( node ) => {
62
+ * const ref = useCallback( ( node ) => {
40
63
  * node.addEventListener( ... );
41
64
  * return () => {
42
65
  * node.removeEventListener( ... );
43
66
  * };
44
67
  * }, [ ...dependencies ] );
45
68
  * const otherRef = useRef();
46
- * const mergedRefs useMergeRefs( [
69
+ * const mergedRefs = useMergeRefs( [
47
70
  * enabled && ref,
48
71
  * otherRef,
49
72
  * ] );
@@ -56,11 +79,15 @@ function assignRef< T >( ref: Ref< T >, value: T ) {
56
79
  export default function useMergeRefs< T >(
57
80
  refs: Ref< T >[]
58
81
  ): RefCallback< T > {
59
- const element = useRef( null );
82
+ const elementRef = useRef< T | null >( null );
60
83
  const isAttachedRef = useRef( false );
61
84
  const didElementChangeRef = useRef( false );
62
85
  const previousRefsRef = useRef< Ref< T >[] >( [] );
63
86
  const currentRefsRef = useRef( refs );
87
+ // Position-indexed cleanups returned by inner ref callbacks. A slot is
88
+ // `undefined` when the ref at that position did not return a cleanup (or
89
+ // is an object ref / disabled).
90
+ const cleanupsRef = useRef< Array< ( () => void ) | undefined > >( [] );
64
91
 
65
92
  // Update on render before the ref callback is called, so the ref callback
66
93
  // always has access to the current refs.
@@ -77,8 +104,11 @@ export default function useMergeRefs< T >(
77
104
  refs.forEach( ( ref, index ) => {
78
105
  const previousRef = previousRefsRef.current[ index ];
79
106
  if ( ref !== previousRef ) {
80
- assignRef( previousRef, null );
81
- assignRef( ref, element.current );
107
+ detachRef( previousRef, index, cleanupsRef.current );
108
+ cleanupsRef.current[ index ] = assignRef(
109
+ ref,
110
+ elementRef.current as T
111
+ );
82
112
  }
83
113
  } );
84
114
  }
@@ -97,20 +127,21 @@ export default function useMergeRefs< T >(
97
127
  return useCallback( ( value: T | null ) => {
98
128
  // Update the element so it can be used when calling ref callbacks on a
99
129
  // dependency change.
100
- assignRef( element, value );
130
+ elementRef.current = value;
101
131
 
102
132
  didElementChangeRef.current = true;
103
133
  isAttachedRef.current = value !== null;
104
134
 
105
135
  // When an element changes, the current ref callback should be called
106
136
  // with the new element and the previous one with `null`.
107
- const refsToAssign = value
108
- ? currentRefsRef.current
109
- : previousRefsRef.current;
110
-
111
- // Update the latest refs.
112
- for ( const ref of refsToAssign ) {
113
- assignRef( ref, value );
137
+ if ( value === null ) {
138
+ previousRefsRef.current.forEach( ( ref, index ) => {
139
+ detachRef( ref, index, cleanupsRef.current );
140
+ } );
141
+ } else {
142
+ currentRefsRef.current.forEach( ( ref, index ) => {
143
+ cleanupsRef.current[ index ] = assignRef( ref, value );
144
+ } );
114
145
  }
115
146
  }, [] );
116
147
  }
@@ -345,3 +345,291 @@ describe( 'useMergeRefs', () => {
345
345
  ] );
346
346
  } );
347
347
  } );
348
+
349
+ describe( 'useMergeRefs with cleanup-returning ref callbacks', () => {
350
+ // Setup
351
+ // =====
352
+ //
353
+ // Same structure as the suite above, but the ref callbacks return a
354
+ // cleanup function. React 19 (and `useMergeRefs`) invokes the cleanup at
355
+ // teardown instead of calling the callback with `null`. The cleanup pushes
356
+ // the string `'cleanup'` into the same history array, so each call site's
357
+ // full lifecycle is captured as `[ node, 'cleanup', newNode, 'cleanup' ]`.
358
+ // The strict invariant is that `null` never appears in the history of a
359
+ // cleanup-returning ref.
360
+
361
+ function renderCallback( args ) {
362
+ renderCallback.history.push( args );
363
+ }
364
+
365
+ renderCallback.history = [];
366
+
367
+ function MergedRefs( {
368
+ count,
369
+ tagName: TagName = 'ul',
370
+ disable1,
371
+ disable2,
372
+ } ) {
373
+ function refCallback1( value ) {
374
+ refCallback1.history.push( value );
375
+ return () => {
376
+ refCallback1.history.push( 'cleanup' );
377
+ };
378
+ }
379
+
380
+ refCallback1.history = [];
381
+
382
+ function refCallback2( value ) {
383
+ refCallback2.history.push( value );
384
+ return () => {
385
+ refCallback2.history.push( 'cleanup' );
386
+ };
387
+ }
388
+
389
+ refCallback2.history = [];
390
+
391
+ renderCallback( [ refCallback1.history, refCallback2.history ] );
392
+
393
+ const ref1 = useCallback( refCallback1, [] );
394
+ const ref2 = useCallback( refCallback2, [ count ] );
395
+ const mergedRefs = useMergeRefs( [
396
+ ! disable1 && ref1,
397
+ ! disable2 && ref2,
398
+ ] );
399
+
400
+ return <TagName ref={ mergedRefs } />;
401
+ }
402
+
403
+ afterEach( () => {
404
+ renderCallback.history = [];
405
+ } );
406
+
407
+ it( 'should invoke cleanup on unmount instead of calling ref with null', () => {
408
+ const { unmount } = render( <MergedRefs /> );
409
+
410
+ const originalElement = screen.getByRole( 'list' );
411
+
412
+ expect( renderCallback.history ).toEqual( [
413
+ [ [ originalElement ], [ originalElement ] ],
414
+ ] );
415
+
416
+ unmount();
417
+
418
+ // Cleanups run; refs are NOT called with `null`.
419
+ expect( renderCallback.history ).toEqual( [
420
+ [
421
+ [ originalElement, 'cleanup' ],
422
+ [ originalElement, 'cleanup' ],
423
+ ],
424
+ ] );
425
+ } );
426
+
427
+ it( 'should invoke cleanup on node change instead of calling ref with null', () => {
428
+ const { rerender, unmount } = render( <MergedRefs /> );
429
+
430
+ const originalElement = screen.getByRole( 'list' );
431
+
432
+ rerender( <MergedRefs tagName="button" /> );
433
+
434
+ const newElement = screen.getByRole( 'button' );
435
+
436
+ // Node change triggers the outer callback first with `null` (which
437
+ // runs the cleanups) and then with the new node (which sets up new
438
+ // cleanups).
439
+ expect( renderCallback.history ).toEqual( [
440
+ [
441
+ [ originalElement, 'cleanup', newElement ],
442
+ [ originalElement, 'cleanup', newElement ],
443
+ ],
444
+ [ [], [] ],
445
+ ] );
446
+
447
+ unmount();
448
+
449
+ expect( renderCallback.history ).toEqual( [
450
+ [
451
+ [ originalElement, 'cleanup', newElement, 'cleanup' ],
452
+ [ originalElement, 'cleanup', newElement, 'cleanup' ],
453
+ ],
454
+ [ [], [] ],
455
+ ] );
456
+ } );
457
+
458
+ it( 'should invoke cleanup on dependency change instead of calling ref with null', () => {
459
+ const { rerender, unmount } = render( <MergedRefs count={ 1 } /> );
460
+
461
+ const originalElement = screen.getByRole( 'list' );
462
+
463
+ expect( renderCallback.history ).toEqual( [
464
+ [ [ originalElement ], [ originalElement ] ],
465
+ ] );
466
+
467
+ rerender( <MergedRefs count={ 2 } /> );
468
+
469
+ // Only ref2's deps changed. Its previous cleanup runs and the new ref
470
+ // callback is called with the still-attached node. ref1 is untouched.
471
+ expect( renderCallback.history ).toEqual( [
472
+ [ [ originalElement ], [ originalElement, 'cleanup' ] ],
473
+ [ [], [ originalElement ] ],
474
+ ] );
475
+
476
+ unmount();
477
+
478
+ expect( renderCallback.history ).toEqual( [
479
+ [
480
+ [ originalElement, 'cleanup' ],
481
+ [ originalElement, 'cleanup' ],
482
+ ],
483
+ [ [], [ originalElement, 'cleanup' ] ],
484
+ ] );
485
+ } );
486
+
487
+ it( 'should invoke cleanup on simultaneous node and dependency change', () => {
488
+ const { rerender, unmount } = render( <MergedRefs count={ 1 } /> );
489
+
490
+ const originalElement = screen.getByRole( 'list' );
491
+
492
+ rerender( <MergedRefs count={ 2 } tagName="button" /> );
493
+
494
+ const newElement = screen.getByRole( 'button' );
495
+
496
+ // Outer callback's null/new-node pair runs both cleanups and sets
497
+ // up the new ones (ref1 reused, ref2 has a new identity).
498
+ expect( renderCallback.history ).toEqual( [
499
+ [
500
+ [ originalElement, 'cleanup', newElement ],
501
+ [ originalElement, 'cleanup' ],
502
+ ],
503
+ [ [], [ newElement ] ],
504
+ ] );
505
+
506
+ unmount();
507
+
508
+ expect( renderCallback.history ).toEqual( [
509
+ [
510
+ [ originalElement, 'cleanup', newElement, 'cleanup' ],
511
+ [ originalElement, 'cleanup' ],
512
+ ],
513
+ [ [], [ newElement, 'cleanup' ] ],
514
+ ] );
515
+ } );
516
+
517
+ it( 'should invoke cleanup when a ref becomes disabled', () => {
518
+ const { rerender, unmount } = render( <MergedRefs /> );
519
+
520
+ const originalElement = screen.getByRole( 'list' );
521
+
522
+ rerender( <MergedRefs disable1 /> );
523
+
524
+ // ref1 is disabled: its stored cleanup must fire. ref2 is unchanged.
525
+ expect( renderCallback.history ).toEqual( [
526
+ [ [ originalElement, 'cleanup' ], [ originalElement ] ],
527
+ [ [], [] ],
528
+ ] );
529
+
530
+ unmount();
531
+
532
+ expect( renderCallback.history ).toEqual( [
533
+ [
534
+ [ originalElement, 'cleanup' ],
535
+ [ originalElement, 'cleanup' ],
536
+ ],
537
+ [ [], [] ],
538
+ ] );
539
+ } );
540
+
541
+ it( 'should support mixing a cleanup-returning ref with a void-returning ref', () => {
542
+ function MergedRefsMixed() {
543
+ function refCleanup( value ) {
544
+ refCleanup.history.push( value );
545
+ return () => {
546
+ refCleanup.history.push( 'cleanup' );
547
+ };
548
+ }
549
+
550
+ refCleanup.history = [];
551
+
552
+ function refVoid( value ) {
553
+ refVoid.history.push( value );
554
+ }
555
+
556
+ refVoid.history = [];
557
+
558
+ renderCallback( [ refCleanup.history, refVoid.history ] );
559
+
560
+ const r1 = useCallback( refCleanup, [] );
561
+ const r2 = useCallback( refVoid, [] );
562
+ const merged = useMergeRefs( [ r1, r2 ] );
563
+
564
+ return <ul ref={ merged } />;
565
+ }
566
+
567
+ const { unmount } = render( <MergedRefsMixed /> );
568
+
569
+ const el = screen.getByRole( 'list' );
570
+
571
+ expect( renderCallback.history ).toEqual( [ [ [ el ], [ el ] ] ] );
572
+
573
+ unmount();
574
+
575
+ // Cleanup ref sees the cleanup; void ref still sees null. Independent.
576
+ expect( renderCallback.history ).toEqual( [
577
+ [
578
+ [ el, 'cleanup' ],
579
+ [ el, null ],
580
+ ],
581
+ ] );
582
+ } );
583
+
584
+ it( 'should support mixing an object ref with a cleanup-returning ref', () => {
585
+ const objectRef = { current: null };
586
+
587
+ function MergedRefsMixed( { tagName: TagName = 'ul' } ) {
588
+ function refCleanup( value ) {
589
+ refCleanup.history.push( value );
590
+ return () => {
591
+ refCleanup.history.push( 'cleanup' );
592
+ };
593
+ }
594
+
595
+ refCleanup.history = [];
596
+
597
+ renderCallback( [ refCleanup.history ] );
598
+
599
+ const r = useCallback( refCleanup, [] );
600
+ const merged = useMergeRefs( [ objectRef, r ] );
601
+
602
+ return <TagName ref={ merged } />;
603
+ }
604
+
605
+ const { rerender, unmount } = render( <MergedRefsMixed /> );
606
+
607
+ const originalElement = screen.getByRole( 'list' );
608
+
609
+ // Object ref's .current is set; cleanup ref is called with the node.
610
+ expect( objectRef.current ).toBe( originalElement );
611
+ expect( renderCallback.history ).toEqual( [ [ [ originalElement ] ] ] );
612
+
613
+ rerender( <MergedRefsMixed tagName="button" /> );
614
+
615
+ const newElement = screen.getByRole( 'button' );
616
+
617
+ // Node change: object ref retargets, callback ref's cleanup fires
618
+ // and the callback is re-invoked with the new node.
619
+ expect( objectRef.current ).toBe( newElement );
620
+ expect( renderCallback.history ).toEqual( [
621
+ [ [ originalElement, 'cleanup', newElement ] ],
622
+ [ [] ],
623
+ ] );
624
+
625
+ unmount();
626
+
627
+ // Object ref nulled via the fallback assignRef path; callback ref
628
+ // sees its cleanup, never null.
629
+ expect( objectRef.current ).toBe( null );
630
+ expect( renderCallback.history ).toEqual( [
631
+ [ [ originalElement, 'cleanup', newElement, 'cleanup' ] ],
632
+ [ [] ],
633
+ ] );
634
+ } );
635
+ } );
@@ -18,7 +18,7 @@ export function useResizeObserver< T extends HTMLElement >(
18
18
  ): ( element?: T | null ) => void {
19
19
  const callbackEvent = useEvent( callback );
20
20
 
21
- const observedElementRef = useRef< T >( null );
21
+ const observedElementRef = useRef< T | null >( null );
22
22
  const resizeObserverRef = useRef< ResizeObserver >( undefined );
23
23
  return useEvent( ( element?: T | null ) => {
24
24
  if ( element === observedElementRef.current ) {
@@ -64,7 +64,7 @@ ViewportMatchWidthContext.displayName = 'ViewportMatchWidthContext';
64
64
  *
65
65
  * @param {WPBreakpoint} breakpoint Breakpoint size name.
66
66
  * @param {WPViewportOperator} [operator=">="] Viewport operator.
67
- * @param {Window} [view=window] Window instance in which to perform viewport matching.
67
+ * @param {Window|undefined} [view=window] Window instance in which to perform viewport matching.
68
68
  *
69
69
  * @example
70
70
  *
@@ -75,7 +75,13 @@ ViewportMatchWidthContext.displayName = 'ViewportMatchWidthContext';
75
75
  *
76
76
  * @return {boolean} Whether viewport matches query.
77
77
  */
78
- const useViewportMatch = ( breakpoint, operator = '>=', view = window ) => {
78
+ const useViewportMatch = (
79
+ breakpoint,
80
+ operator = '>=',
81
+ // Resolve the default lazily so SSR (where `window` is undeclared) does not
82
+ // throw a ReferenceError when this default expression is evaluated.
83
+ view = typeof window !== 'undefined' ? window : undefined
84
+ ) => {
79
85
  const simulatedWidth = useContext( ViewportMatchWidthContext );
80
86
  const mediaQuery =
81
87
  ! simulatedWidth &&
@@ -1,20 +0,0 @@
1
- # withNetworkConnectivity
2
-
3
- `withNetworkConnectivity` provides a true/false mobile connectivity status based on the `useNetworkConnectivity` hook.
4
-
5
- ## Usage
6
-
7
- ```jsx
8
- /**
9
- * WordPress dependencies
10
- */
11
- import { withNetworkConnectivity } from '@wordpress/compose';
12
-
13
- export class MyComponent extends Component {
14
- if ( this.props.isConnected !== true ) {
15
- console.log( 'You are currently offline.' )
16
- }
17
- }
18
-
19
- export default withNetworkConnectivity( MyComponent )
20
- ```
@@ -1,19 +0,0 @@
1
- /**
2
- * Internal dependencies
3
- */
4
- import { createHigherOrderComponent } from '../../utils/create-higher-order-component';
5
- import useNetworkConnectivity from '../../hooks/use-network-connectivity';
6
-
7
- const withNetworkConnectivity = createHigherOrderComponent(
8
- ( WrappedComponent ) => {
9
- return ( props ) => {
10
- const { isConnected } = useNetworkConnectivity();
11
- return (
12
- <WrappedComponent { ...props } isConnected={ isConnected } />
13
- );
14
- };
15
- },
16
- 'withNetworkConnectivity'
17
- );
18
-
19
- export default withNetworkConnectivity;
@@ -1,40 +0,0 @@
1
- /**
2
- * Internal dependencies
3
- */
4
- import { createHigherOrderComponent } from '../../utils/create-higher-order-component';
5
- import usePreferredColorScheme from '../../hooks/use-preferred-color-scheme';
6
-
7
- /**
8
- * WordPress dependencies
9
- */
10
- import { useCallback } from '@wordpress/element';
11
-
12
- const withPreferredColorScheme = createHigherOrderComponent(
13
- ( WrappedComponent ) => ( props ) => {
14
- const colorScheme = usePreferredColorScheme();
15
- const isDarkMode = colorScheme === 'dark';
16
-
17
- const getStyles = useCallback(
18
- ( lightStyles, darkStyles ) => {
19
- const finalDarkStyles = {
20
- ...lightStyles,
21
- ...darkStyles,
22
- };
23
-
24
- return isDarkMode ? finalDarkStyles : lightStyles;
25
- },
26
- [ isDarkMode ]
27
- );
28
-
29
- return (
30
- <WrappedComponent
31
- preferredColorScheme={ colorScheme }
32
- getStylesFromColorScheme={ getStyles }
33
- { ...props }
34
- />
35
- );
36
- },
37
- 'withPreferredColorScheme'
38
- );
39
-
40
- export default withPreferredColorScheme;
@@ -1,14 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import { useRef } from '@wordpress/element';
5
-
6
- function useConstrainedTabbing() {
7
- const ref = useRef();
8
-
9
- // Do nothing on mobile as tabbing is not a mobile behavior.
10
-
11
- return ref;
12
- }
13
-
14
- export default useConstrainedTabbing;