@jobber/hooks 2.17.1 → 2.17.2
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/dist/index.js +18 -34
- package/dist/useBool/index.js +1 -5
- package/dist/useBool/useBool.js +6 -9
- package/dist/useBool/useBool.test.js +9 -11
- package/dist/useBreakpoints/index.js +2 -20
- package/dist/useBreakpoints/mockViewportWidth/index.js +1 -17
- package/dist/useBreakpoints/mockViewportWidth/mockViewportWidth.js +2 -6
- package/dist/useBreakpoints/mockViewportWidth/mockViewportWidth.test.js +4 -6
- package/dist/useBreakpoints/useBreakpoints.js +9 -13
- package/dist/useBreakpoints/useBreakpoints.test.js +30 -35
- package/dist/useBreakpoints/useMediaQuery.js +5 -9
- package/dist/useCallbackRef/index.js +1 -5
- package/dist/useCallbackRef/useCallbackRef.js +5 -8
- package/dist/useCallbackRef/useCallbackRef.test.js +4 -6
- package/dist/useCollectionQuery/index.js +1 -5
- package/dist/useCollectionQuery/mdxUtils.js +8 -12
- package/dist/useCollectionQuery/test-utilities/index.js +3 -19
- package/dist/useCollectionQuery/test-utilities/mocks.js +19 -30
- package/dist/useCollectionQuery/test-utilities/queries.js +4 -7
- package/dist/useCollectionQuery/test-utilities/utils.js +1 -4
- package/dist/useCollectionQuery/uniqueEdges.js +2 -6
- package/dist/useCollectionQuery/uniqueNodes.js +1 -4
- package/dist/useCollectionQuery/useCollectionQuery.js +27 -34
- package/dist/useCollectionQuery/useCollectionQuery.test.js +126 -128
- package/dist/useDebounce/index.js +1 -5
- package/dist/useDebounce/useDebounce.js +8 -11
- package/dist/useDebounce/useDebounce.test.js +42 -70
- package/dist/useFocusTrap/index.js +1 -5
- package/dist/useFocusTrap/useFocusTrap.js +4 -7
- package/dist/useFocusTrap/useFocusTrap.test.js +26 -31
- package/dist/useFormState/index.js +1 -5
- package/dist/useFormState/useFormState.js +3 -6
- package/dist/useInView/index.js +1 -17
- package/dist/useInView/useInView.js +6 -9
- package/dist/useInView/useInView.test.js +12 -17
- package/dist/useIsMounted/index.js +1 -5
- package/dist/useIsMounted/useIsMounted.js +5 -8
- package/dist/useIsMounted/useIsMounted.test.js +4 -6
- package/dist/useLiveAnnounce/index.js +1 -5
- package/dist/useLiveAnnounce/useLiveAnnounce.js +4 -7
- package/dist/useLiveAnnounce/useLiveAnnounce.test.js +19 -24
- package/dist/useOnKeyDown/index.js +1 -5
- package/dist/useOnKeyDown/useOnKeyDown.js +3 -6
- package/dist/useOnKeyDown/useOnKeyDown.test.js +7 -12
- package/dist/useOnMount/index.js +1 -5
- package/dist/useOnMount/useOnMount.js +6 -10
- package/dist/useOnMount/useOnMount.test.js +4 -6
- package/dist/useRefocusOnActivator/index.js +1 -5
- package/dist/useRefocusOnActivator/useRefocusOnActivator.js +3 -6
- package/dist/useResizeObserver/index.js +1 -17
- package/dist/useResizeObserver/useResizeObserver.js +9 -16
- package/dist/useSafeLayoutEffect/index.js +1 -5
- package/dist/useSafeLayoutEffect/useSafeLayoutEffect.js +4 -7
- package/dist/useShowClear/index.js +1 -5
- package/dist/useShowClear/useShowClear.js +1 -4
- package/dist/useShowClear/useShowClear.test.js +6 -8
- package/dist/useStepper/index.js +1 -5
- package/dist/useStepper/useStepper.js +9 -15
- package/dist/useStepper/useStepper.test.js +15 -17
- package/dist/useWindowDimensions/index.js +1 -5
- package/dist/useWindowDimensions/useWIndowDimensions.test.js +6 -8
- package/dist/useWindowDimensions/useWindowDimensions.js +4 -7
- package/package.json +102 -5
|
@@ -1,27 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
1
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
2
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
3
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -31,14 +7,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
31
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
8
|
});
|
|
33
9
|
};
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const react_1 = __importStar(require("react"));
|
|
39
|
-
const react_2 = require("@testing-library/react");
|
|
40
|
-
const user_event_1 = __importDefault(require("@testing-library/user-event"));
|
|
41
|
-
const useDebounce_1 = require("./useDebounce");
|
|
10
|
+
import React, { useEffect, useState } from "react";
|
|
11
|
+
import { act, render, renderHook, screen } from "@testing-library/react";
|
|
12
|
+
import userEvent from "@testing-library/user-event";
|
|
13
|
+
import { useDebounce } from "./useDebounce";
|
|
42
14
|
const DEBOUNCE_WAIT = 300;
|
|
43
15
|
describe("useDebounce", () => {
|
|
44
16
|
beforeEach(() => {
|
|
@@ -49,10 +21,10 @@ describe("useDebounce", () => {
|
|
|
49
21
|
});
|
|
50
22
|
it("should debounce the function call", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
51
23
|
const mockFn = jest.fn();
|
|
52
|
-
const { result } =
|
|
24
|
+
const { result } = renderHook(() => useDebounce(mockFn, DEBOUNCE_WAIT));
|
|
53
25
|
result.current("test");
|
|
54
26
|
expect(mockFn).not.toHaveBeenCalled();
|
|
55
|
-
|
|
27
|
+
act(() => {
|
|
56
28
|
jest.advanceTimersByTime(DEBOUNCE_WAIT);
|
|
57
29
|
});
|
|
58
30
|
expect(mockFn).toHaveBeenCalledWith("test");
|
|
@@ -60,23 +32,23 @@ describe("useDebounce", () => {
|
|
|
60
32
|
}));
|
|
61
33
|
it("should cancel pending debounced calls on unmount", () => {
|
|
62
34
|
const mockFn = jest.fn();
|
|
63
|
-
const { result, unmount } =
|
|
35
|
+
const { result, unmount } = renderHook(() => useDebounce(mockFn, DEBOUNCE_WAIT));
|
|
64
36
|
result.current("test");
|
|
65
37
|
unmount();
|
|
66
|
-
|
|
38
|
+
act(() => {
|
|
67
39
|
jest.advanceTimersByTime(DEBOUNCE_WAIT);
|
|
68
40
|
});
|
|
69
41
|
expect(mockFn).not.toHaveBeenCalled();
|
|
70
42
|
});
|
|
71
43
|
it("should handle multiple calls within the debounce period", () => {
|
|
72
44
|
const mockFn = jest.fn();
|
|
73
|
-
const { result } =
|
|
45
|
+
const { result } = renderHook(() => useDebounce(mockFn, DEBOUNCE_WAIT));
|
|
74
46
|
result.current("first");
|
|
75
|
-
|
|
47
|
+
act(() => {
|
|
76
48
|
jest.advanceTimersByTime(DEBOUNCE_WAIT / 2);
|
|
77
49
|
});
|
|
78
50
|
result.current("second");
|
|
79
|
-
|
|
51
|
+
act(() => {
|
|
80
52
|
jest.advanceTimersByTime(DEBOUNCE_WAIT);
|
|
81
53
|
});
|
|
82
54
|
expect(mockFn).toHaveBeenCalledTimes(1);
|
|
@@ -86,7 +58,7 @@ describe("useDebounce", () => {
|
|
|
86
58
|
const mockFn = jest.fn();
|
|
87
59
|
const debounceEgdesOption = ["trailing"];
|
|
88
60
|
// Use a function that returns a new options object each time
|
|
89
|
-
const { result, rerender } =
|
|
61
|
+
const { result, rerender } = renderHook(({ options }) => useDebounce(mockFn, DEBOUNCE_WAIT, options), { initialProps: { options: { edges: debounceEgdesOption } } });
|
|
90
62
|
const debounceRef = result.current;
|
|
91
63
|
rerender({ options: { edges: debounceEgdesOption } });
|
|
92
64
|
expect(debounceRef).toBe(result.current);
|
|
@@ -98,16 +70,16 @@ describe("useDebounce", () => {
|
|
|
98
70
|
// Start with trailing edge
|
|
99
71
|
const debounceEgdesOption = ["trailing"];
|
|
100
72
|
// Use a function that returns a new options object each time
|
|
101
|
-
const { result, rerender } =
|
|
73
|
+
const { result, rerender } = renderHook(({ options }) => useDebounce(mockFn, DEBOUNCE_WAIT, options), { initialProps: { options: { edges: debounceEgdesOption } } });
|
|
102
74
|
result.current("first");
|
|
103
|
-
|
|
75
|
+
act(() => {
|
|
104
76
|
jest.advanceTimersByTime(TIME_INCREMENT_LESSER_THAN_DEBOUNCE_WAIT);
|
|
105
77
|
});
|
|
106
78
|
expect(mockFn).not.toHaveBeenCalled();
|
|
107
79
|
// This means it calls immediately at the leading edge of the timeout.
|
|
108
80
|
rerender({ options: { edges: ["leading"] } });
|
|
109
81
|
result.current("second");
|
|
110
|
-
|
|
82
|
+
act(() => {
|
|
111
83
|
jest.advanceTimersByTime(TIME_INCREMENT_LESSER_THAN_DEBOUNCE_WAIT);
|
|
112
84
|
});
|
|
113
85
|
// The config change should be ignored, options are hardcoded
|
|
@@ -115,52 +87,52 @@ describe("useDebounce", () => {
|
|
|
115
87
|
});
|
|
116
88
|
it("should work with React components", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
117
89
|
function DebouncedComponent() {
|
|
118
|
-
const [value, setValue] =
|
|
119
|
-
const [debouncedValue, setDebouncedValue] =
|
|
120
|
-
const debouncedSetValue =
|
|
90
|
+
const [value, setValue] = useState("");
|
|
91
|
+
const [debouncedValue, setDebouncedValue] = useState("");
|
|
92
|
+
const debouncedSetValue = useDebounce((newValue) => {
|
|
121
93
|
setDebouncedValue(newValue);
|
|
122
94
|
}, DEBOUNCE_WAIT);
|
|
123
|
-
|
|
95
|
+
useEffect(() => {
|
|
124
96
|
debouncedSetValue(value);
|
|
125
97
|
}, [value, debouncedSetValue]);
|
|
126
|
-
return (
|
|
127
|
-
|
|
128
|
-
|
|
98
|
+
return (React.createElement("div", null,
|
|
99
|
+
React.createElement("input", { "data-testid": "input", value: value, onChange: e => setValue(e.target.value) }),
|
|
100
|
+
React.createElement("div", { "data-testid": "debounced-value" }, debouncedValue)));
|
|
129
101
|
}
|
|
130
|
-
|
|
131
|
-
const input =
|
|
132
|
-
const debouncedValue =
|
|
133
|
-
const user =
|
|
102
|
+
render(React.createElement(DebouncedComponent, null));
|
|
103
|
+
const input = screen.getByTestId("input");
|
|
104
|
+
const debouncedValue = screen.getByTestId("debounced-value");
|
|
105
|
+
const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
|
|
134
106
|
yield user.type(input, "test");
|
|
135
107
|
expect(debouncedValue.textContent).toBe("");
|
|
136
|
-
|
|
108
|
+
act(() => {
|
|
137
109
|
jest.advanceTimersByTime(DEBOUNCE_WAIT + 100);
|
|
138
110
|
});
|
|
139
111
|
expect(debouncedValue.textContent).toBe("test");
|
|
140
112
|
}), 10000);
|
|
141
113
|
it("should properly handle options object", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
142
114
|
function DebouncedComponent() {
|
|
143
|
-
const [count, setCount] =
|
|
144
|
-
const [debouncedCount, setDebouncedCount] =
|
|
115
|
+
const [count, setCount] = useState(0);
|
|
116
|
+
const [debouncedCount, setDebouncedCount] = useState(0);
|
|
145
117
|
const options = {
|
|
146
118
|
edges: ["leading", "trailing"],
|
|
147
119
|
};
|
|
148
|
-
const debouncedSetCount =
|
|
120
|
+
const debouncedSetCount = useDebounce((value) => {
|
|
149
121
|
setDebouncedCount(value);
|
|
150
122
|
}, DEBOUNCE_WAIT, options);
|
|
151
|
-
return (
|
|
152
|
-
|
|
123
|
+
return (React.createElement("div", null,
|
|
124
|
+
React.createElement("button", { "data-testid": "increment", onClick: () => {
|
|
153
125
|
const newCount = count + 1;
|
|
154
126
|
setCount(newCount);
|
|
155
127
|
debouncedSetCount(newCount);
|
|
156
128
|
}, type: "button" }, "Increment"),
|
|
157
|
-
|
|
158
|
-
|
|
129
|
+
React.createElement("div", { "data-testid": "count" }, count),
|
|
130
|
+
React.createElement("div", { "data-testid": "debounced-count" }, debouncedCount)));
|
|
159
131
|
}
|
|
160
|
-
|
|
161
|
-
const incrementButton =
|
|
162
|
-
const debouncedCount =
|
|
163
|
-
const user =
|
|
132
|
+
render(React.createElement(DebouncedComponent, null));
|
|
133
|
+
const incrementButton = screen.getByTestId("increment");
|
|
134
|
+
const debouncedCount = screen.getByTestId("debounced-count");
|
|
135
|
+
const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
|
|
164
136
|
yield user.click(incrementButton);
|
|
165
137
|
// With leading edge, the value should be updated immediately
|
|
166
138
|
expect(debouncedCount.textContent).toBe("1");
|
|
@@ -169,7 +141,7 @@ describe("useDebounce", () => {
|
|
|
169
141
|
// Additional clicks shouldn't update immediately (debounced)
|
|
170
142
|
expect(debouncedCount.textContent).toBe("1");
|
|
171
143
|
// After the debounce period, the trailing edge should update with the latest value
|
|
172
|
-
|
|
144
|
+
act(() => {
|
|
173
145
|
jest.advanceTimersByTime(DEBOUNCE_WAIT);
|
|
174
146
|
});
|
|
175
147
|
expect(debouncedCount.textContent).toBe("3");
|
|
@@ -177,12 +149,12 @@ describe("useDebounce", () => {
|
|
|
177
149
|
it("should abort debounced function when signal is aborted", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
178
150
|
const mockFn = jest.fn();
|
|
179
151
|
const controller = new AbortController();
|
|
180
|
-
const { result } =
|
|
152
|
+
const { result } = renderHook(() => useDebounce(mockFn, DEBOUNCE_WAIT, { signal: controller.signal }));
|
|
181
153
|
result.current("test");
|
|
182
|
-
|
|
154
|
+
act(() => {
|
|
183
155
|
controller.abort();
|
|
184
156
|
});
|
|
185
|
-
|
|
157
|
+
act(() => {
|
|
186
158
|
jest.advanceTimersByTime(DEBOUNCE_WAIT + 100);
|
|
187
159
|
});
|
|
188
160
|
expect(mockFn).not.toHaveBeenCalled();
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useFocusTrap = void 0;
|
|
4
|
-
var useFocusTrap_1 = require("./useFocusTrap");
|
|
5
|
-
Object.defineProperty(exports, "useFocusTrap", { enumerable: true, get: function () { return useFocusTrap_1.useFocusTrap; } });
|
|
1
|
+
export { useFocusTrap } from "./useFocusTrap";
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useFocusTrap = useFocusTrap;
|
|
4
|
-
const react_1 = require("react");
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
5
2
|
/**
|
|
6
3
|
* Traps the focus within the children of the ref element.
|
|
7
4
|
*
|
|
@@ -10,11 +7,11 @@ const react_1 = require("react");
|
|
|
10
7
|
*
|
|
11
8
|
* @returns ref
|
|
12
9
|
*/
|
|
13
|
-
function useFocusTrap(active) {
|
|
10
|
+
export function useFocusTrap(active) {
|
|
14
11
|
// There's an ongoing issue with useRef return type clashing with an element's
|
|
15
12
|
// ref prop type. TLDR: Use null because useRef doesn't expect undefined.
|
|
16
13
|
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/35572
|
|
17
|
-
const ref =
|
|
14
|
+
const ref = useRef(null);
|
|
18
15
|
function handleKeyDown(event) {
|
|
19
16
|
if (!(active && ref.current) || event.key !== "Tab") {
|
|
20
17
|
return;
|
|
@@ -33,7 +30,7 @@ function useFocusTrap(active) {
|
|
|
33
30
|
}
|
|
34
31
|
}
|
|
35
32
|
}
|
|
36
|
-
|
|
33
|
+
useEffect(() => {
|
|
37
34
|
if (active && ref.current) {
|
|
38
35
|
const { firstElement } = getElements(ref.current);
|
|
39
36
|
firstElement.focus();
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
2
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
3
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -8,54 +7,50 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
8
|
});
|
|
10
9
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const react_1 = __importDefault(require("react"));
|
|
16
|
-
const react_2 = require("@testing-library/react");
|
|
17
|
-
const user_event_1 = __importDefault(require("@testing-library/user-event"));
|
|
18
|
-
const useFocusTrap_1 = require("./useFocusTrap");
|
|
10
|
+
import React from "react";
|
|
11
|
+
import { render } from "@testing-library/react";
|
|
12
|
+
import userEvent from "@testing-library/user-event";
|
|
13
|
+
import { useFocusTrap } from "./useFocusTrap";
|
|
19
14
|
const targetId = "target";
|
|
20
15
|
const firstFocusableChild = "first-element";
|
|
21
16
|
const lastFocusableChild = "last-element";
|
|
22
17
|
it("should focus on the ref target on mount", () => {
|
|
23
|
-
const { getByTestId } =
|
|
18
|
+
const { getByTestId } = render(React.createElement(TestComponent, null));
|
|
24
19
|
expect(getByTestId(targetId)).toHaveFocus();
|
|
25
20
|
});
|
|
26
21
|
it("should focus on the ref target when tabbing out of the last focusable element and ignore the tabindex'=-1'", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
27
|
-
const { getByTestId } =
|
|
22
|
+
const { getByTestId } = render(React.createElement(TestComponent, null));
|
|
28
23
|
getByTestId(lastFocusableChild).focus();
|
|
29
|
-
yield
|
|
24
|
+
yield userEvent.tab();
|
|
30
25
|
expect(getByTestId(targetId)).toHaveFocus();
|
|
31
26
|
}));
|
|
32
27
|
it("should focus on the first focusable element", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
33
|
-
const { getByTestId } =
|
|
34
|
-
yield
|
|
28
|
+
const { getByTestId } = render(React.createElement(TestComponent, null));
|
|
29
|
+
yield userEvent.tab();
|
|
35
30
|
expect(getByTestId(firstFocusableChild)).toHaveFocus();
|
|
36
31
|
}));
|
|
37
32
|
it("should focus on the last focusable element", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
38
|
-
const { getByTestId } =
|
|
39
|
-
yield
|
|
33
|
+
const { getByTestId } = render(React.createElement(TestComponent, null));
|
|
34
|
+
yield userEvent.tab({ shift: true });
|
|
40
35
|
expect(getByTestId(lastFocusableChild)).toHaveFocus();
|
|
41
36
|
}));
|
|
42
37
|
it("should not trap the tabbing and focus on the first child node", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
|
-
const { getByTestId } =
|
|
44
|
-
yield
|
|
38
|
+
const { getByTestId } = render(React.createElement(TestComponent, { trap: false }));
|
|
39
|
+
yield userEvent.tab();
|
|
45
40
|
expect(getByTestId(targetId).previousElementSibling).toHaveFocus();
|
|
46
41
|
}));
|
|
47
42
|
function TestComponent({ trap = true }) {
|
|
48
|
-
const testRef =
|
|
49
|
-
return (
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
43
|
+
const testRef = useFocusTrap(trap);
|
|
44
|
+
return (React.createElement(React.Fragment, null,
|
|
45
|
+
React.createElement("input", { type: "number" }),
|
|
46
|
+
React.createElement("div", { ref: testRef, "data-testid": targetId, tabIndex: 0 },
|
|
47
|
+
React.createElement("button", { "data-testid": firstFocusableChild }, "Click me"),
|
|
48
|
+
React.createElement("a", { href: "#" }),
|
|
49
|
+
React.createElement("input", { type: "text" }),
|
|
50
|
+
React.createElement("select", null,
|
|
51
|
+
React.createElement("option", { value: "A" })),
|
|
52
|
+
React.createElement("textarea", null),
|
|
53
|
+
React.createElement("span", { tabIndex: 0, "data-testId": lastFocusableChild }),
|
|
54
|
+
React.createElement("span", { tabIndex: -1 })),
|
|
55
|
+
React.createElement("input", { type: "calendar" })));
|
|
61
56
|
}
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useFormState = void 0;
|
|
4
|
-
var useFormState_1 = require("./useFormState");
|
|
5
|
-
Object.defineProperty(exports, "useFormState", { enumerable: true, get: function () { return useFormState_1.useFormState; } });
|
|
1
|
+
export { useFormState } from "./useFormState";
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const react_1 = require("react");
|
|
5
|
-
function useFormState() {
|
|
6
|
-
const [formState, setFormState] = (0, react_1.useState)({
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
export function useFormState() {
|
|
3
|
+
const [formState, setFormState] = useState({
|
|
7
4
|
isDirty: false,
|
|
8
5
|
isValid: false,
|
|
9
6
|
});
|
package/dist/useInView/index.js
CHANGED
|
@@ -1,17 +1 @@
|
|
|
1
|
-
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./useInView"), exports);
|
|
1
|
+
export * from "./useInView";
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const [isInView, setIsInView] = (0, react_1.useState)(false);
|
|
8
|
-
const handleIntersection = (0, react_1.useCallback)(entries => setIsInView(entries[0].isIntersecting), [setIsInView]);
|
|
9
|
-
(0, react_1.useEffect)(() => {
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
+
export function useInView() {
|
|
3
|
+
const ref = useRef(null);
|
|
4
|
+
const [isInView, setIsInView] = useState(false);
|
|
5
|
+
const handleIntersection = useCallback(entries => setIsInView(entries[0].isIntersecting), [setIsInView]);
|
|
6
|
+
useEffect(() => {
|
|
10
7
|
if (!window.IntersectionObserver)
|
|
11
8
|
return;
|
|
12
9
|
const observer = new IntersectionObserver(handleIntersection);
|
|
@@ -1,29 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
const react_2 = require("@testing-library/react");
|
|
8
|
-
const jsdom_testing_mocks_1 = require("jsdom-testing-mocks");
|
|
9
|
-
const useInView_1 = require("./useInView");
|
|
10
|
-
(0, jsdom_testing_mocks_1.configMocks)({ act: react_2.act });
|
|
11
|
-
const observer = (0, jsdom_testing_mocks_1.mockIntersectionObserver)();
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { act, render, renderHook, screen } from "@testing-library/react";
|
|
3
|
+
import { configMocks, mockIntersectionObserver } from "jsdom-testing-mocks";
|
|
4
|
+
import { useInView } from "./useInView";
|
|
5
|
+
configMocks({ act });
|
|
6
|
+
const observer = mockIntersectionObserver();
|
|
12
7
|
describe("useInView", () => {
|
|
13
8
|
it("should return true when the target element is in view", () => {
|
|
14
|
-
const { result, rerender } =
|
|
9
|
+
const { result, rerender } = renderHook(() => useInView());
|
|
15
10
|
const [ref, isInView] = result.current;
|
|
16
|
-
|
|
11
|
+
render(React.createElement("button", { ref: ref }));
|
|
17
12
|
rerender();
|
|
18
13
|
expect(result.current[0].current).toBeInstanceOf(HTMLButtonElement);
|
|
19
|
-
observer.leaveNode(
|
|
14
|
+
observer.leaveNode(screen.getByRole("button"));
|
|
20
15
|
expect(isInView).toBe(false);
|
|
21
16
|
});
|
|
22
17
|
it("should return false when the target element is in view", () => {
|
|
23
|
-
const { result, rerender } =
|
|
24
|
-
|
|
18
|
+
const { result, rerender } = renderHook(() => useInView());
|
|
19
|
+
render(React.createElement("button", { ref: result.current[0] }));
|
|
25
20
|
rerender();
|
|
26
|
-
observer.enterNode(
|
|
21
|
+
observer.enterNode(screen.getByRole("button"));
|
|
27
22
|
expect(result.current[1]).toBe(true);
|
|
28
23
|
});
|
|
29
24
|
});
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useIsMounted = void 0;
|
|
4
|
-
var useIsMounted_1 = require("./useIsMounted");
|
|
5
|
-
Object.defineProperty(exports, "useIsMounted", { enumerable: true, get: function () { return useIsMounted_1.useIsMounted; } });
|
|
1
|
+
export { useIsMounted } from "./useIsMounted";
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.useIsMounted = useIsMounted;
|
|
4
|
-
const react_1 = require("react");
|
|
5
|
-
const useSafeLayoutEffect_1 = require("../useSafeLayoutEffect");
|
|
1
|
+
import { useRef } from "react";
|
|
2
|
+
import { useSafeLayoutEffect } from "../useSafeLayoutEffect";
|
|
6
3
|
/**
|
|
7
4
|
* If you are using this hook in order to only perform an action once after mounting (for example sending
|
|
8
5
|
* analytics events), use `useOnMount` instead
|
|
@@ -22,9 +19,9 @@ const useSafeLayoutEffect_1 = require("../useSafeLayoutEffect");
|
|
|
22
19
|
* When the component unmounts, it calls the cleanup function that sets `isMounted` to false.
|
|
23
20
|
* This `useLayoutEffect` hook will only be run once.
|
|
24
21
|
*/
|
|
25
|
-
function useIsMounted() {
|
|
26
|
-
const isMounted =
|
|
27
|
-
|
|
22
|
+
export function useIsMounted() {
|
|
23
|
+
const isMounted = useRef(false);
|
|
24
|
+
useSafeLayoutEffect(() => {
|
|
28
25
|
isMounted.current = true;
|
|
29
26
|
return () => {
|
|
30
27
|
isMounted.current = false;
|
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const react_hooks_1 = require("@testing-library/react-hooks");
|
|
4
|
-
const useIsMounted_1 = require("./useIsMounted");
|
|
1
|
+
import { renderHook } from "@testing-library/react-hooks";
|
|
2
|
+
import { useIsMounted } from "./useIsMounted";
|
|
5
3
|
it("should return true when the component is currently mounted", () => {
|
|
6
|
-
const { result } =
|
|
4
|
+
const { result } = renderHook(() => useIsMounted());
|
|
7
5
|
const isMounted = result.current;
|
|
8
6
|
expect(isMounted.current).toBe(true);
|
|
9
7
|
});
|
|
10
8
|
it("should return false when the component is unmounted", () => {
|
|
11
|
-
const { result, unmount } =
|
|
9
|
+
const { result, unmount } = renderHook(() => useIsMounted());
|
|
12
10
|
const isMounted = result.current;
|
|
13
11
|
unmount();
|
|
14
12
|
expect(isMounted.current).toBe(false);
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useLiveAnnounce = void 0;
|
|
4
|
-
var useLiveAnnounce_1 = require("./useLiveAnnounce");
|
|
5
|
-
Object.defineProperty(exports, "useLiveAnnounce", { enumerable: true, get: function () { return useLiveAnnounce_1.useLiveAnnounce; } });
|
|
1
|
+
export { useLiveAnnounce } from "./useLiveAnnounce";
|
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useLiveAnnounce = useLiveAnnounce;
|
|
4
|
-
const react_1 = require("react");
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
5
2
|
/**
|
|
6
3
|
* Announce a message on voice over whenever you do an action. This is
|
|
7
4
|
* especially helpful when you have an action that adds or deletes an element
|
|
8
5
|
* from the screen.
|
|
9
6
|
*/
|
|
10
|
-
function useLiveAnnounce() {
|
|
11
|
-
const [announcedMessage, setAnnouncedMessage] =
|
|
12
|
-
|
|
7
|
+
export function useLiveAnnounce() {
|
|
8
|
+
const [announcedMessage, setAnnouncedMessage] = useState("");
|
|
9
|
+
useEffect(() => {
|
|
13
10
|
let target;
|
|
14
11
|
if (announcedMessage) {
|
|
15
12
|
target = createAnnouncedElement();
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
2
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
3
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -8,30 +7,26 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
8
|
});
|
|
10
9
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
const react_1 = __importDefault(require("react"));
|
|
16
|
-
const react_2 = require("@testing-library/react");
|
|
17
|
-
const _1 = require(".");
|
|
10
|
+
import React from "react";
|
|
11
|
+
import { act, render, screen, waitFor } from "@testing-library/react";
|
|
12
|
+
import { useLiveAnnounce } from ".";
|
|
18
13
|
function setupHook() {
|
|
19
14
|
const returnVal = {
|
|
20
15
|
liveAnnounce: jest.fn,
|
|
21
16
|
};
|
|
22
17
|
function TestComponent() {
|
|
23
|
-
Object.assign(returnVal,
|
|
24
|
-
return
|
|
18
|
+
Object.assign(returnVal, useLiveAnnounce());
|
|
19
|
+
return React.createElement(React.Fragment, null);
|
|
25
20
|
}
|
|
26
|
-
const { rerender } =
|
|
27
|
-
return Object.assign(Object.assign({}, returnVal), { rerenderComponent: () => rerender(
|
|
21
|
+
const { rerender } = render(React.createElement(TestComponent, null));
|
|
22
|
+
return Object.assign(Object.assign({}, returnVal), { rerenderComponent: () => rerender(React.createElement(TestComponent, null)) });
|
|
28
23
|
}
|
|
29
24
|
it("should render a div to announce", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
30
25
|
const { liveAnnounce } = setupHook();
|
|
31
26
|
const message = "Huzzah";
|
|
32
|
-
|
|
33
|
-
yield
|
|
34
|
-
const expectedElement =
|
|
27
|
+
act(() => liveAnnounce(message));
|
|
28
|
+
yield waitFor(() => {
|
|
29
|
+
const expectedElement = screen.queryByRole("status");
|
|
35
30
|
expect(expectedElement).toBeInTheDocument();
|
|
36
31
|
expect(expectedElement === null || expectedElement === void 0 ? void 0 : expectedElement.textContent).toBe(message);
|
|
37
32
|
expect(expectedElement).toHaveAttribute("role", "status");
|
|
@@ -41,20 +36,20 @@ it("should render a div to announce", () => __awaiter(void 0, void 0, void 0, fu
|
|
|
41
36
|
}));
|
|
42
37
|
it("should not render the announced div", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
38
|
setupHook();
|
|
44
|
-
expect(
|
|
39
|
+
expect(screen.queryByRole("status")).not.toBeInTheDocument();
|
|
45
40
|
}));
|
|
46
41
|
it("should only have 1 div to announce a message on a single instance of the hook", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
47
42
|
const { liveAnnounce } = setupHook();
|
|
48
43
|
const firstMessage = "I am first";
|
|
49
44
|
const secondMessage = "I am second";
|
|
50
|
-
|
|
51
|
-
yield
|
|
52
|
-
expect(
|
|
53
|
-
expect(
|
|
45
|
+
act(() => liveAnnounce(firstMessage));
|
|
46
|
+
yield waitFor(() => {
|
|
47
|
+
expect(screen.queryAllByRole("status")).toHaveLength(1);
|
|
48
|
+
expect(screen.getByRole("status").textContent).toBe(firstMessage);
|
|
54
49
|
});
|
|
55
|
-
|
|
56
|
-
yield
|
|
57
|
-
expect(
|
|
58
|
-
expect(
|
|
50
|
+
act(() => liveAnnounce(secondMessage));
|
|
51
|
+
yield waitFor(() => {
|
|
52
|
+
expect(screen.queryAllByRole("status")).toHaveLength(1);
|
|
53
|
+
expect(screen.getByRole("status").textContent).toBe(secondMessage);
|
|
59
54
|
});
|
|
60
55
|
}));
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useOnKeyDown = void 0;
|
|
4
|
-
var useOnKeyDown_1 = require("./useOnKeyDown");
|
|
5
|
-
Object.defineProperty(exports, "useOnKeyDown", { enumerable: true, get: function () { return useOnKeyDown_1.useOnKeyDown; } });
|
|
1
|
+
export { useOnKeyDown } from "./useOnKeyDown";
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const react_1 = require("react");
|
|
5
|
-
function useOnKeyDown(callback, keys) {
|
|
6
|
-
(0, react_1.useEffect)(() => {
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
export function useOnKeyDown(callback, keys) {
|
|
3
|
+
useEffect(() => {
|
|
7
4
|
window.addEventListener("keydown", handler);
|
|
8
5
|
return () => {
|
|
9
6
|
window.removeEventListener("keydown", handler);
|