@wordpress/compose 8.1.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 (49) hide show
  1. package/CHANGELOG.md +20 -1
  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-media-query/index.cjs +2 -2
  6. package/build/hooks/use-media-query/index.cjs.map +2 -2
  7. package/build/hooks/use-merge-refs/index.cjs +28 -8
  8. package/build/hooks/use-merge-refs/index.cjs.map +2 -2
  9. package/build/hooks/use-viewport-match/index.cjs +1 -1
  10. package/build/hooks/use-viewport-match/index.cjs.map +2 -2
  11. package/build-module/higher-order/pure/index.mjs +5 -0
  12. package/build-module/higher-order/pure/index.mjs.map +2 -2
  13. package/build-module/hooks/use-media-query/index.mjs +2 -2
  14. package/build-module/hooks/use-media-query/index.mjs.map +2 -2
  15. package/build-module/hooks/use-merge-refs/index.mjs +28 -8
  16. package/build-module/hooks/use-merge-refs/index.mjs.map +2 -2
  17. package/build-module/hooks/use-viewport-match/index.mjs +1 -1
  18. package/build-module/hooks/use-viewport-match/index.mjs.map +2 -2
  19. package/build-types/higher-order/pure/index.d.ts.map +1 -1
  20. package/build-types/hooks/use-media-query/index.d.ts +1 -1
  21. package/build-types/hooks/use-media-query/index.d.ts.map +1 -1
  22. package/build-types/hooks/use-merge-refs/index.d.ts +7 -5
  23. package/build-types/hooks/use-merge-refs/index.d.ts.map +1 -1
  24. package/build-types/hooks/use-viewport-match/index.d.ts +1 -1
  25. package/build-types/hooks/use-viewport-match/index.d.ts.map +1 -1
  26. package/package.json +16 -12
  27. package/src/higher-order/pure/index.tsx +6 -0
  28. package/src/higher-order/pure/test/index.js +14 -81
  29. package/src/hooks/use-drop-zone/README.md +1 -1
  30. package/src/hooks/use-media-query/index.ts +10 -3
  31. package/src/hooks/use-media-query/test/ssr.js +47 -0
  32. package/src/hooks/use-merge-refs/index.ts +49 -18
  33. package/src/hooks/use-merge-refs/test/index.js +288 -0
  34. package/src/hooks/use-viewport-match/index.js +8 -2
  35. package/src/higher-order/with-network-connectivity/README.md +0 -20
  36. package/src/higher-order/with-network-connectivity/index.native.js +0 -19
  37. package/src/higher-order/with-preferred-color-scheme/index.native.js +0 -40
  38. package/src/hooks/use-constrained-tabbing/index.native.js +0 -14
  39. package/src/hooks/use-focus-outside/index.native.js +0 -170
  40. package/src/hooks/use-keyboard-shortcut/index.native.js +0 -2
  41. package/src/hooks/use-network-connectivity/index.native.js +0 -59
  42. package/src/hooks/use-network-connectivity/test/index.native.js +0 -87
  43. package/src/hooks/use-preferred-color-scheme/index.android.js +0 -30
  44. package/src/hooks/use-preferred-color-scheme/index.ios.js +0 -13
  45. package/src/hooks/use-preferred-color-scheme-style/index.native.js +0 -33
  46. package/src/hooks/use-resize-observer/index.native.js +0 -1
  47. package/src/hooks/use-resize-observer/legacy/index.native.js +0 -59
  48. package/src/hooks/use-resize-observer/legacy/test/index.native.js +0 -46
  49. package/src/index.native.js +0 -44
@@ -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
+ } );
@@ -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;
@@ -1,170 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import { useCallback, useEffect, useRef } from '@wordpress/element';
5
-
6
- /**
7
- * Input types which are classified as button types, for use in considering
8
- * whether element is a (focus-normalized) button.
9
- *
10
- * @type {string[]}
11
- */
12
- const INPUT_BUTTON_TYPES = [ 'button', 'submit' ];
13
-
14
- /**
15
- * @typedef {HTMLButtonElement | HTMLLinkElement | HTMLInputElement} FocusNormalizedButton
16
- */
17
-
18
- /**
19
- * Returns true if the given element is a button element subject to focus
20
- * normalization, or false otherwise.
21
- *
22
- * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus
23
- *
24
- * @param {EventTarget} eventTarget The target from a mouse or touch event.
25
- *
26
- * @return {eventTarget is FocusNormalizedButton} Whether element is a button.
27
- */
28
- function isFocusNormalizedButton( eventTarget ) {
29
- switch ( eventTarget.nodeName ) {
30
- case 'A':
31
- case 'BUTTON':
32
- return true;
33
-
34
- case 'INPUT':
35
- return INPUT_BUTTON_TYPES.includes(
36
- /** @type {HTMLInputElement} */ ( eventTarget ).type
37
- );
38
- }
39
-
40
- return false;
41
- }
42
-
43
- /**
44
- * @typedef {React.SyntheticEvent} SyntheticEvent
45
- */
46
-
47
- /**
48
- * @callback EventCallback
49
- * @param {SyntheticEvent} event input related event.
50
- */
51
-
52
- /**
53
- * @typedef FocusOutsideReactElement
54
- * @property {EventCallback} handleFocusOutside callback for a focus outside event.
55
- */
56
-
57
- /**
58
- * @typedef {React.MutableRefObject<FocusOutsideReactElement | undefined>} FocusOutsideRef
59
- */
60
-
61
- /**
62
- * @typedef {Object} FocusOutsideReturnValue
63
- * @property {EventCallback} onFocus An event handler for focus events.
64
- * @property {EventCallback} onBlur An event handler for blur events.
65
- * @property {EventCallback} onMouseDown An event handler for mouse down events.
66
- * @property {EventCallback} onMouseUp An event handler for mouse up events.
67
- * @property {EventCallback} onTouchStart An event handler for touch start events.
68
- * @property {EventCallback} onTouchEnd An event handler for touch end events.
69
- */
70
-
71
- /**
72
- * A react hook that can be used to check whether focus has moved outside the
73
- * element the event handlers are bound to.
74
- *
75
- * @param {EventCallback} onFocusOutside A callback triggered when focus moves outside
76
- * the element the event handlers are bound to.
77
- *
78
- * @return {FocusOutsideReturnValue} An object containing event handlers. Bind the event handlers
79
- * to a wrapping element element to capture when focus moves
80
- * outside that element.
81
- */
82
- export default function useFocusOutside( onFocusOutside ) {
83
- const currentOnFocusOutside = useRef( onFocusOutside );
84
- useEffect( () => {
85
- currentOnFocusOutside.current = onFocusOutside;
86
- }, [ onFocusOutside ] );
87
-
88
- const preventBlurCheck = useRef( false );
89
-
90
- /**
91
- * @type {React.MutableRefObject<number | undefined>}
92
- */
93
- const blurCheckTimeoutId = useRef();
94
-
95
- /**
96
- * Cancel a blur check timeout.
97
- */
98
- const cancelBlurCheck = useCallback( () => {
99
- clearTimeout( blurCheckTimeoutId.current );
100
- }, [] );
101
-
102
- // Cancel blur checks on unmount.
103
- useEffect( () => {
104
- return () => cancelBlurCheck();
105
- }, [] );
106
-
107
- // Cancel a blur check if the callback or ref is no longer provided.
108
- useEffect( () => {
109
- if ( ! onFocusOutside ) {
110
- cancelBlurCheck();
111
- }
112
- }, [ onFocusOutside, cancelBlurCheck ] );
113
-
114
- /**
115
- * Handles a mousedown or mouseup event to respectively assign and
116
- * unassign a flag for preventing blur check on button elements. Some
117
- * browsers, namely Firefox and Safari, do not emit a focus event on
118
- * button elements when clicked, while others do. The logic here
119
- * intends to normalize this as treating click on buttons as focus.
120
- *
121
- * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus
122
- *
123
- * @param {SyntheticEvent} event Event for mousedown or mouseup.
124
- */
125
- const normalizeButtonFocus = useCallback( ( event ) => {
126
- const { type, target } = event;
127
- const isInteractionEnd = [ 'mouseup', 'touchend' ].includes( type );
128
-
129
- if ( isInteractionEnd ) {
130
- preventBlurCheck.current = false;
131
- } else if ( isFocusNormalizedButton( target ) ) {
132
- preventBlurCheck.current = true;
133
- }
134
- }, [] );
135
-
136
- /**
137
- * A callback triggered when a blur event occurs on the element the handler
138
- * is bound to.
139
- *
140
- * Calls the `onFocusOutside` callback in an immediate timeout if focus has
141
- * move outside the bound element and is still within the document.
142
- *
143
- * @param {SyntheticEvent} event Blur event.
144
- */
145
- const queueBlurCheck = useCallback( ( event ) => {
146
- // React does not allow using an event reference asynchronously
147
- // due to recycling behavior, except when explicitly persisted.
148
- event.persist();
149
-
150
- // Skip blur check if clicking button. See `normalizeButtonFocus`.
151
- if ( preventBlurCheck.current ) {
152
- return;
153
- }
154
-
155
- blurCheckTimeoutId.current = setTimeout( () => {
156
- if ( 'function' === typeof currentOnFocusOutside.current ) {
157
- currentOnFocusOutside.current( event );
158
- }
159
- }, 0 );
160
- }, [] );
161
-
162
- return {
163
- onFocus: cancelBlurCheck,
164
- onMouseDown: normalizeButtonFocus,
165
- onMouseUp: normalizeButtonFocus,
166
- onTouchStart: normalizeButtonFocus,
167
- onTouchEnd: normalizeButtonFocus,
168
- onBlur: queueBlurCheck,
169
- };
170
- }
@@ -1,2 +0,0 @@
1
- const useKeyboardShortcut = () => null;
2
- export default useKeyboardShortcut;
@@ -1,59 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import { useEffect, useState } from '@wordpress/element';
5
- import {
6
- requestConnectionStatus,
7
- subscribeConnectionStatus,
8
- } from '@wordpress/react-native-bridge';
9
-
10
- /**
11
- * @typedef {Object} NetworkInformation
12
- *
13
- * @property {boolean} [isConnected] Whether the device is connected to a network.
14
- */
15
-
16
- /**
17
- * Returns the current network connectivity status provided by the native bridge.
18
- *
19
- * @example
20
- *
21
- * ```jsx
22
- * const { isConnected } = useNetworkConnectivity();
23
- * ```
24
- *
25
- * @return {NetworkInformation} Network information.
26
- */
27
- export default function useNetworkConnectivity() {
28
- const [ isConnected, setIsConnected ] = useState( true );
29
-
30
- useEffect( () => {
31
- let isCurrent = true;
32
-
33
- requestConnectionStatus( ( isBridgeConnected ) => {
34
- if ( ! isCurrent ) {
35
- return;
36
- }
37
-
38
- setIsConnected( isBridgeConnected );
39
- } );
40
-
41
- return () => {
42
- isCurrent = false;
43
- };
44
- }, [] );
45
-
46
- useEffect( () => {
47
- const subscription = subscribeConnectionStatus(
48
- ( { isConnected: isBridgeConnected } ) => {
49
- setIsConnected( isBridgeConnected );
50
- }
51
- );
52
-
53
- return () => {
54
- subscription.remove();
55
- };
56
- }, [] );
57
-
58
- return { isConnected };
59
- }