@wordpress/compose 5.17.0 → 5.18.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.
- package/CHANGELOG.md +2 -0
- package/README.md +3 -0
- package/build/hooks/use-disabled/index.js +10 -98
- package/build/hooks/use-disabled/index.js.map +1 -1
- package/build/hooks/use-resize-observer/index.native.js +1 -0
- package/build/hooks/use-resize-observer/index.native.js.map +1 -1
- package/build-module/hooks/use-disabled/index.js +10 -97
- package/build-module/hooks/use-disabled/index.js.map +1 -1
- package/build-module/hooks/use-resize-observer/index.native.js +1 -0
- package/build-module/hooks/use-resize-observer/index.native.js.map +1 -1
- package/build-types/hooks/use-disabled/index.d.ts +4 -1
- package/build-types/hooks/use-disabled/index.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/higher-order/with-global-events/test/index.js +18 -29
- package/src/higher-order/with-state/test/index.js +13 -26
- package/src/hooks/use-disabled/index.ts +81 -0
- package/src/hooks/use-disabled/test/index.js +4 -36
- package/src/hooks/use-focus-outside/test/index.js +44 -45
- package/src/hooks/use-instance-id/test/index.js +9 -16
- package/src/hooks/use-media-query/test/index.js +33 -53
- package/src/hooks/use-resize-observer/index.native.js +5 -1
- package/src/hooks/use-resize-observer/test/index.native.js +18 -22
- package/src/hooks/use-viewport-match/test/index.js +78 -78
- package/tsconfig.tsbuildinfo +1 -1
- package/src/hooks/use-disabled/index.js +0 -197
|
@@ -1,31 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import { render, screen } from '@testing-library/react';
|
|
5
|
+
import userEvent from '@testing-library/user-event';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Internal dependencies
|
|
8
9
|
*/
|
|
9
10
|
import withState from '../';
|
|
10
11
|
|
|
11
|
-
/**
|
|
12
|
-
* WordPress dependencies
|
|
13
|
-
*/
|
|
14
|
-
import { Component } from '@wordpress/element';
|
|
15
|
-
|
|
16
|
-
// This is needed because TestUtils does not accept a stateless component.
|
|
17
|
-
// anything run through a HOC ends up as a stateless component.
|
|
18
|
-
const getTestComponent = ( WrappedComponent ) => {
|
|
19
|
-
class TestComponent extends Component {
|
|
20
|
-
render() {
|
|
21
|
-
return <WrappedComponent { ...this.props } />;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return <TestComponent />;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
12
|
describe( 'withState', () => {
|
|
28
|
-
it( 'should pass initial state and allow updates', () => {
|
|
13
|
+
it( 'should pass initial state and allow updates', async () => {
|
|
14
|
+
const user = userEvent.setup( {
|
|
15
|
+
advanceTimers: jest.advanceTimersByTime,
|
|
16
|
+
} );
|
|
29
17
|
const EnhancedComponent = withState( {
|
|
30
18
|
count: 0,
|
|
31
19
|
} )( ( { count, setState } ) => (
|
|
@@ -38,16 +26,15 @@ describe( 'withState', () => {
|
|
|
38
26
|
</button>
|
|
39
27
|
) );
|
|
40
28
|
|
|
41
|
-
|
|
42
|
-
getTestComponent( EnhancedComponent )
|
|
43
|
-
);
|
|
29
|
+
render( <EnhancedComponent /> );
|
|
44
30
|
|
|
45
|
-
const
|
|
46
|
-
TestUtils.findRenderedDOMComponentWithTag( wrapper, 'button' );
|
|
31
|
+
const button = screen.getByRole( 'button' );
|
|
47
32
|
|
|
48
33
|
expect( console ).toHaveWarned();
|
|
49
|
-
expect(
|
|
50
|
-
|
|
51
|
-
|
|
34
|
+
expect( button ).toHaveTextContent( '0' );
|
|
35
|
+
|
|
36
|
+
await user.click( button );
|
|
37
|
+
|
|
38
|
+
expect( button ).toHaveTextContent( '1' );
|
|
52
39
|
} );
|
|
53
40
|
} );
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { debounce } from '../../utils/debounce';
|
|
5
|
+
import useRefEffect from '../use-ref-effect';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* In some circumstances, such as block previews, all focusable DOM elements
|
|
9
|
+
* (input fields, links, buttons, etc.) need to be disabled. This hook adds the
|
|
10
|
+
* behavior to disable nested DOM elements to the returned ref.
|
|
11
|
+
*
|
|
12
|
+
* If you can, prefer the use of the inert HTML attribute.
|
|
13
|
+
*
|
|
14
|
+
* @param {Object} config Configuration object.
|
|
15
|
+
* @param {boolean=} config.isDisabled Whether the element should be disabled.
|
|
16
|
+
* @return {import('react').RefCallback<HTMLElement>} Element Ref.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```js
|
|
20
|
+
* import { useDisabled } from '@wordpress/compose';
|
|
21
|
+
*
|
|
22
|
+
* const DisabledExample = () => {
|
|
23
|
+
* const disabledRef = useDisabled();
|
|
24
|
+
* return (
|
|
25
|
+
* <div ref={ disabledRef }>
|
|
26
|
+
* <a href="#">This link will have tabindex set to -1</a>
|
|
27
|
+
* <input placeholder="This input will have the disabled attribute added to it." type="text" />
|
|
28
|
+
* </div>
|
|
29
|
+
* );
|
|
30
|
+
* };
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export default function useDisabled( {
|
|
34
|
+
isDisabled: isDisabledProp = false,
|
|
35
|
+
} = {} ) {
|
|
36
|
+
return useRefEffect(
|
|
37
|
+
( node ) => {
|
|
38
|
+
if ( isDisabledProp ) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** A variable keeping track of the previous updates in order to restore them. */
|
|
43
|
+
const updates: Function[] = [];
|
|
44
|
+
const disable = () => {
|
|
45
|
+
node.childNodes.forEach( ( child ) => {
|
|
46
|
+
if ( ! ( child instanceof HTMLElement ) ) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if ( ! child.getAttribute( 'inert' ) ) {
|
|
50
|
+
child.setAttribute( 'inert', 'true' );
|
|
51
|
+
updates.push( () => {
|
|
52
|
+
child.removeAttribute( 'inert' );
|
|
53
|
+
} );
|
|
54
|
+
}
|
|
55
|
+
} );
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// Debounce re-disable since disabling process itself will incur
|
|
59
|
+
// additional mutations which should be ignored.
|
|
60
|
+
const debouncedDisable = debounce( disable, 0, {
|
|
61
|
+
leading: true,
|
|
62
|
+
} );
|
|
63
|
+
disable();
|
|
64
|
+
|
|
65
|
+
/** @type {MutationObserver | undefined} */
|
|
66
|
+
const observer = new window.MutationObserver( debouncedDisable );
|
|
67
|
+
observer.observe( node, {
|
|
68
|
+
childList: true,
|
|
69
|
+
} );
|
|
70
|
+
|
|
71
|
+
return () => {
|
|
72
|
+
if ( observer ) {
|
|
73
|
+
observer.disconnect();
|
|
74
|
+
}
|
|
75
|
+
debouncedDisable.cancel();
|
|
76
|
+
updates.forEach( ( update ) => update() );
|
|
77
|
+
};
|
|
78
|
+
},
|
|
79
|
+
[ isDisabledProp ]
|
|
80
|
+
);
|
|
81
|
+
}
|
|
@@ -13,36 +13,6 @@ import { forwardRef } from '@wordpress/element';
|
|
|
13
13
|
*/
|
|
14
14
|
import useDisabled from '../';
|
|
15
15
|
|
|
16
|
-
jest.mock( '@wordpress/dom', () => {
|
|
17
|
-
const focus = jest.requireActual( '../../../../../dom/src' ).focus;
|
|
18
|
-
|
|
19
|
-
return {
|
|
20
|
-
focus: {
|
|
21
|
-
...focus,
|
|
22
|
-
focusable: {
|
|
23
|
-
...focus.focusable,
|
|
24
|
-
find( context ) {
|
|
25
|
-
// In JSDOM, all elements have zero'd widths and height.
|
|
26
|
-
// This is a metric for focusable's `isVisible`, so find
|
|
27
|
-
// and apply an arbitrary non-zero width.
|
|
28
|
-
Array.from( context.querySelectorAll( '*' ) ).forEach(
|
|
29
|
-
( element ) => {
|
|
30
|
-
Object.defineProperties( element, {
|
|
31
|
-
offsetWidth: {
|
|
32
|
-
get: () => 1,
|
|
33
|
-
configurable: true,
|
|
34
|
-
},
|
|
35
|
-
} );
|
|
36
|
-
}
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
return focus.focusable.find( ...arguments );
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
};
|
|
44
|
-
} );
|
|
45
|
-
|
|
46
16
|
jest.useRealTimers();
|
|
47
17
|
|
|
48
18
|
describe( 'useDisabled', () => {
|
|
@@ -69,11 +39,9 @@ describe( 'useDisabled', () => {
|
|
|
69
39
|
const link = screen.getByRole( 'link' );
|
|
70
40
|
const p = container.querySelector( 'p' );
|
|
71
41
|
|
|
72
|
-
expect( input.
|
|
73
|
-
expect( link.
|
|
74
|
-
expect( p.
|
|
75
|
-
expect( p.hasAttribute( 'tabindex' ) ).toBe( false );
|
|
76
|
-
expect( p.hasAttribute( 'disabled' ) ).toBe( false );
|
|
42
|
+
expect( input ).toHaveAttribute( 'inert', 'true' );
|
|
43
|
+
expect( link ).toHaveAttribute( 'inert', 'true' );
|
|
44
|
+
expect( p ).toHaveAttribute( 'inert', 'true' );
|
|
77
45
|
} );
|
|
78
46
|
|
|
79
47
|
it( 'will disable an element rendered in an update to the component', async () => {
|
|
@@ -86,7 +54,7 @@ describe( 'useDisabled', () => {
|
|
|
86
54
|
|
|
87
55
|
const button = screen.getByText( 'Button' );
|
|
88
56
|
await waitFor( () => {
|
|
89
|
-
expect( button.
|
|
57
|
+
expect( button ).toHaveAttribute( 'inert', 'true' );
|
|
90
58
|
} );
|
|
91
59
|
} );
|
|
92
60
|
} );
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import { render, screen } from '@testing-library/react';
|
|
5
|
+
import userEvent from '@testing-library/user-event';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* WordPress dependencies
|
|
@@ -12,38 +13,24 @@ import { Component } from '@wordpress/element';
|
|
|
12
13
|
* Internal dependencies
|
|
13
14
|
*/
|
|
14
15
|
import useFocusOutside from '../';
|
|
15
|
-
import ReactDOM from 'react-dom';
|
|
16
16
|
|
|
17
|
-
let
|
|
17
|
+
let onFocusOutside;
|
|
18
18
|
|
|
19
19
|
describe( 'useFocusOutside', () => {
|
|
20
20
|
let origHasFocus;
|
|
21
21
|
|
|
22
22
|
const FocusOutsideComponent = ( { onFocusOutside: callback } ) => (
|
|
23
23
|
<div { ...useFocusOutside( callback ) }>
|
|
24
|
-
<input />
|
|
24
|
+
<input type="text" />
|
|
25
25
|
<input type="button" />
|
|
26
26
|
</div>
|
|
27
27
|
);
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class TestComponent extends Component {
|
|
33
|
-
render() {
|
|
34
|
-
return <WrappedComponent { ...props } />;
|
|
35
|
-
}
|
|
29
|
+
class TestComponent extends Component {
|
|
30
|
+
render() {
|
|
31
|
+
return <FocusOutsideComponent { ...this.props } />;
|
|
36
32
|
}
|
|
37
|
-
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const simulateEvent = ( event, index = 0 ) => {
|
|
41
|
-
const element = TestUtils.scryRenderedDOMComponentsWithTag(
|
|
42
|
-
wrapper,
|
|
43
|
-
'input'
|
|
44
|
-
);
|
|
45
|
-
TestUtils.Simulate[ event ]( element[ index ] );
|
|
46
|
-
};
|
|
33
|
+
}
|
|
47
34
|
|
|
48
35
|
beforeEach( () => {
|
|
49
36
|
// Mock document.hasFocus() to always be true for testing
|
|
@@ -52,9 +39,6 @@ describe( 'useFocusOutside', () => {
|
|
|
52
39
|
document.hasFocus = () => true;
|
|
53
40
|
|
|
54
41
|
onFocusOutside = jest.fn();
|
|
55
|
-
wrapper = TestUtils.renderIntoDocument(
|
|
56
|
-
getTestComponent( FocusOutsideComponent, { onFocusOutside } )
|
|
57
|
-
);
|
|
58
42
|
} );
|
|
59
43
|
|
|
60
44
|
afterEach( () => {
|
|
@@ -62,24 +46,31 @@ describe( 'useFocusOutside', () => {
|
|
|
62
46
|
} );
|
|
63
47
|
|
|
64
48
|
it( 'should not call handler if focus shifts to element within component', () => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
49
|
+
render( <TestComponent onFocusOutside={ onFocusOutside } /> );
|
|
50
|
+
|
|
51
|
+
const input = screen.getByRole( 'textbox' );
|
|
52
|
+
const button = screen.getByRole( 'button' );
|
|
53
|
+
|
|
54
|
+
input.focus();
|
|
55
|
+
input.blur();
|
|
56
|
+
button.focus();
|
|
68
57
|
|
|
69
58
|
jest.runAllTimers();
|
|
70
59
|
|
|
71
60
|
expect( onFocusOutside ).not.toHaveBeenCalled();
|
|
72
61
|
} );
|
|
73
62
|
|
|
74
|
-
it( 'should not call handler if focus transitions via click to button', () => {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
63
|
+
it( 'should not call handler if focus transitions via click to button', async () => {
|
|
64
|
+
const user = userEvent.setup( {
|
|
65
|
+
advanceTimers: jest.advanceTimersByTime,
|
|
66
|
+
} );
|
|
67
|
+
render( <TestComponent onFocusOutside={ onFocusOutside } /> );
|
|
68
|
+
|
|
69
|
+
const input = screen.getByRole( 'textbox' );
|
|
70
|
+
const button = screen.getByRole( 'button' );
|
|
78
71
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
// the normalization behavior tested here.
|
|
82
|
-
simulateEvent( 'mouseUp', 1 );
|
|
72
|
+
input.focus();
|
|
73
|
+
await user.click( button );
|
|
83
74
|
|
|
84
75
|
jest.runAllTimers();
|
|
85
76
|
|
|
@@ -87,8 +78,11 @@ describe( 'useFocusOutside', () => {
|
|
|
87
78
|
} );
|
|
88
79
|
|
|
89
80
|
it( 'should call handler if focus doesn’t shift to element within component', () => {
|
|
90
|
-
|
|
91
|
-
|
|
81
|
+
render( <TestComponent onFocusOutside={ onFocusOutside } /> );
|
|
82
|
+
|
|
83
|
+
const input = screen.getByRole( 'textbox' );
|
|
84
|
+
input.focus();
|
|
85
|
+
input.blur();
|
|
92
86
|
|
|
93
87
|
jest.runAllTimers();
|
|
94
88
|
|
|
@@ -96,12 +90,15 @@ describe( 'useFocusOutside', () => {
|
|
|
96
90
|
} );
|
|
97
91
|
|
|
98
92
|
it( 'should not call handler if focus shifts outside the component when the document does not have focus', () => {
|
|
93
|
+
render( <TestComponent onFocusOutside={ onFocusOutside } /> );
|
|
94
|
+
|
|
99
95
|
// Force document.hasFocus() to return false to simulate the window/document losing focus
|
|
100
96
|
// See https://developer.mozilla.org/en-US/docs/Web/API/Document/hasFocus.
|
|
101
97
|
document.hasFocus = () => false;
|
|
102
98
|
|
|
103
|
-
|
|
104
|
-
|
|
99
|
+
const input = screen.getByRole( 'textbox' );
|
|
100
|
+
input.focus();
|
|
101
|
+
input.blur();
|
|
105
102
|
|
|
106
103
|
jest.runAllTimers();
|
|
107
104
|
|
|
@@ -109,14 +106,16 @@ describe( 'useFocusOutside', () => {
|
|
|
109
106
|
} );
|
|
110
107
|
|
|
111
108
|
it( 'should cancel check when unmounting while queued', () => {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
ReactDOM.unmountComponentAtNode(
|
|
116
|
-
// eslint-disable-next-line react/no-find-dom-node
|
|
117
|
-
ReactDOM.findDOMNode( wrapper ).parentNode
|
|
109
|
+
const { rerender } = render(
|
|
110
|
+
<TestComponent onFocusOutside={ onFocusOutside } />
|
|
118
111
|
);
|
|
119
112
|
|
|
113
|
+
const input = screen.getByRole( 'textbox' );
|
|
114
|
+
input.focus();
|
|
115
|
+
input.blur();
|
|
116
|
+
|
|
117
|
+
rerender( <div /> );
|
|
118
|
+
|
|
120
119
|
jest.runAllTimers();
|
|
121
120
|
|
|
122
121
|
expect( onFocusOutside ).not.toHaveBeenCalled();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { render } from '@testing-library/react';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Internal dependencies
|
|
@@ -14,23 +14,16 @@ describe( 'useInstanceId', () => {
|
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
it( 'should manage ids', async () => {
|
|
17
|
-
|
|
17
|
+
const { container, rerender } = render( <TestComponent /> );
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
test0 = create( <TestComponent /> );
|
|
21
|
-
} );
|
|
19
|
+
expect( container ).toHaveTextContent( '0' );
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
rerender(
|
|
22
|
+
<div>
|
|
23
|
+
<TestComponent />
|
|
24
|
+
</div>
|
|
25
|
+
);
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
await act( async () => {
|
|
28
|
-
test1 = create( <TestComponent /> );
|
|
29
|
-
} );
|
|
30
|
-
|
|
31
|
-
expect( test1.toJSON() ).toBe( '1' );
|
|
32
|
-
|
|
33
|
-
test0.unmount();
|
|
34
|
-
test1.unmount();
|
|
27
|
+
expect( container ).toHaveTextContent( '1' );
|
|
35
28
|
} );
|
|
36
29
|
} );
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { render, act } from '@testing-library/react';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Internal dependencies
|
|
@@ -33,18 +33,6 @@ describe( 'useMediaQuery', () => {
|
|
|
33
33
|
return `useMediaQuery: ${ queryResult }`;
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
-
it( 'should return true when query matches on the first render', async () => {
|
|
37
|
-
global.matchMedia.mockReturnValue( {
|
|
38
|
-
addListener,
|
|
39
|
-
removeListener,
|
|
40
|
-
matches: true,
|
|
41
|
-
} );
|
|
42
|
-
|
|
43
|
-
const root = create( <TestComponent query="(min-width: 782px)" /> );
|
|
44
|
-
|
|
45
|
-
expect( root.toJSON() ).toBe( 'useMediaQuery: true' );
|
|
46
|
-
} );
|
|
47
|
-
|
|
48
36
|
it( 'should return true when query matches', async () => {
|
|
49
37
|
global.matchMedia.mockReturnValue( {
|
|
50
38
|
addListener,
|
|
@@ -52,17 +40,14 @@ describe( 'useMediaQuery', () => {
|
|
|
52
40
|
matches: true,
|
|
53
41
|
} );
|
|
54
42
|
|
|
55
|
-
|
|
43
|
+
const { container, unmount } = render(
|
|
44
|
+
<TestComponent query="(min-width: 782px)" />
|
|
45
|
+
);
|
|
56
46
|
|
|
57
|
-
|
|
58
|
-
root = create( <TestComponent query="(min-width: 782px)" /> );
|
|
59
|
-
} );
|
|
47
|
+
expect( container ).toHaveTextContent( 'useMediaQuery: true' );
|
|
60
48
|
|
|
61
|
-
|
|
49
|
+
unmount();
|
|
62
50
|
|
|
63
|
-
await act( async () => {
|
|
64
|
-
root.unmount();
|
|
65
|
-
} );
|
|
66
51
|
expect( removeListener ).toHaveBeenCalled();
|
|
67
52
|
} );
|
|
68
53
|
|
|
@@ -90,24 +75,23 @@ describe( 'useMediaQuery', () => {
|
|
|
90
75
|
matches: false,
|
|
91
76
|
} );
|
|
92
77
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
expect(
|
|
78
|
+
const { container, unmount } = render(
|
|
79
|
+
<TestComponent query="(min-width: 782px)" />
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
expect( container ).toHaveTextContent( 'useMediaQuery: true' );
|
|
98
83
|
|
|
84
|
+
let updateMatchFunction;
|
|
99
85
|
await act( async () => {
|
|
100
86
|
updateMatchFunction = addListener.mock.calls[ 0 ][ 0 ];
|
|
101
87
|
updateMatchFunction();
|
|
102
88
|
} );
|
|
103
|
-
expect( root.toJSON() ).toBe( 'useMediaQuery: false' );
|
|
104
89
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
] );
|
|
90
|
+
expect( container ).toHaveTextContent( 'useMediaQuery: false' );
|
|
91
|
+
|
|
92
|
+
unmount();
|
|
93
|
+
|
|
94
|
+
expect( removeListener ).toHaveBeenCalledWith( updateMatchFunction );
|
|
111
95
|
} );
|
|
112
96
|
|
|
113
97
|
it( 'should return false when the query does not matches', async () => {
|
|
@@ -116,15 +100,15 @@ describe( 'useMediaQuery', () => {
|
|
|
116
100
|
removeListener,
|
|
117
101
|
matches: false,
|
|
118
102
|
} );
|
|
119
|
-
let root;
|
|
120
|
-
await act( async () => {
|
|
121
|
-
root = create( <TestComponent query="(min-width: 782px)" /> );
|
|
122
|
-
} );
|
|
123
|
-
expect( root.toJSON() ).toBe( 'useMediaQuery: false' );
|
|
124
103
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
104
|
+
const { container, unmount } = render(
|
|
105
|
+
<TestComponent query="(min-width: 782px)" />
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
expect( container ).toHaveTextContent( 'useMediaQuery: false' );
|
|
109
|
+
|
|
110
|
+
unmount();
|
|
111
|
+
|
|
128
112
|
expect( removeListener ).toHaveBeenCalled();
|
|
129
113
|
} );
|
|
130
114
|
|
|
@@ -134,21 +118,17 @@ describe( 'useMediaQuery', () => {
|
|
|
134
118
|
removeListener,
|
|
135
119
|
matches: false,
|
|
136
120
|
} );
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
} );
|
|
121
|
+
|
|
122
|
+
const { container, rerender, unmount } = render( <TestComponent /> );
|
|
123
|
+
|
|
141
124
|
// Query will be case to a boolean to simplify the return type.
|
|
142
|
-
expect(
|
|
125
|
+
expect( container ).toHaveTextContent( 'useMediaQuery: false' );
|
|
143
126
|
|
|
144
|
-
|
|
145
|
-
root.update( <TestComponent query={ false } /> );
|
|
146
|
-
} );
|
|
147
|
-
expect( root.toJSON() ).toBe( 'useMediaQuery: false' );
|
|
127
|
+
rerender( <TestComponent query={ false } /> );
|
|
148
128
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
129
|
+
expect( container ).toHaveTextContent( 'useMediaQuery: false' );
|
|
130
|
+
|
|
131
|
+
unmount();
|
|
152
132
|
expect( global.matchMedia ).not.toHaveBeenCalled();
|
|
153
133
|
expect( addListener ).not.toHaveBeenCalled();
|
|
154
134
|
expect( removeListener ).not.toHaveBeenCalled();
|
|
@@ -47,7 +47,11 @@ const useResizeObserver = () => {
|
|
|
47
47
|
}, [] );
|
|
48
48
|
|
|
49
49
|
const observer = (
|
|
50
|
-
<View
|
|
50
|
+
<View
|
|
51
|
+
testID="resize-observer"
|
|
52
|
+
style={ StyleSheet.absoluteFill }
|
|
53
|
+
onLayout={ onLayout }
|
|
54
|
+
/>
|
|
51
55
|
);
|
|
52
56
|
|
|
53
57
|
return [ observer, measurements ];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { render, fireEvent } from 'test/helpers';
|
|
5
5
|
import { View } from 'react-native';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -13,36 +13,32 @@ const TestComponent = ( { onLayout } ) => {
|
|
|
13
13
|
const [ resizeObserver, sizes ] = useResizeObserver();
|
|
14
14
|
|
|
15
15
|
return (
|
|
16
|
-
<View sizes={ sizes } onLayout={ onLayout }>
|
|
16
|
+
<View testID="test-component" sizes={ sizes } onLayout={ onLayout }>
|
|
17
17
|
{ resizeObserver }
|
|
18
18
|
</View>
|
|
19
19
|
);
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
describe( 'useResizeObserver()', () => {
|
|
23
|
+
it( 'should return "{ width: 300, height: 500 }"', () => {
|
|
24
|
+
const mockNativeEvent = {
|
|
25
|
+
nativeEvent: {
|
|
26
|
+
layout: {
|
|
27
|
+
width: 300,
|
|
28
|
+
height: 500,
|
|
29
|
+
},
|
|
30
30
|
},
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
act( () => {
|
|
35
|
-
testComponent.toJSON().children[ 0 ].props.onLayout( mockNativeEvent );
|
|
36
|
-
} );
|
|
31
|
+
};
|
|
37
32
|
|
|
38
|
-
|
|
39
|
-
}
|
|
33
|
+
const { getByTestId } = render(
|
|
34
|
+
<TestComponent onLayout={ mockNativeEvent } />
|
|
35
|
+
);
|
|
40
36
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const component = renderWithOnLayout( <TestComponent /> );
|
|
37
|
+
const resizeObserver = getByTestId( 'resize-observer' );
|
|
38
|
+
fireEvent( resizeObserver, 'layout', mockNativeEvent );
|
|
44
39
|
|
|
45
|
-
|
|
40
|
+
const testComponent = getByTestId( 'test-component' );
|
|
41
|
+
expect( testComponent.props.sizes ).toMatchObject( {
|
|
46
42
|
width: 300,
|
|
47
43
|
height: 500,
|
|
48
44
|
} );
|