@uxf/core-react 11.35.0 → 11.38.3
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/README.md +88 -3
- package/hooks/use-debounce.d.ts +1 -0
- package/hooks/use-debounce.js +15 -0
- package/hooks/use-increment.d.ts +2 -0
- package/hooks/use-increment.js +11 -0
- package/hooks/use-increment.test.d.ts +1 -0
- package/hooks/use-increment.test.js +61 -0
- package/hooks/use-toggle.d.ts +2 -0
- package/hooks/use-toggle.js +11 -0
- package/hooks/use-toggle.test.d.ts +1 -0
- package/hooks/use-toggle.test.js +46 -0
- package/package.json +23 -23
package/README.md
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
# UXF Core-React
|
|
2
2
|
|
|
3
3
|
## Hooks
|
|
4
|
+
---
|
|
5
|
+
### useBodyScrollLock
|
|
4
6
|
|
|
7
|
+
Lock scrolling on body element. Useful for modals, popovers, etc.
|
|
5
8
|
```tsx
|
|
6
9
|
import { useBodyScrollLock } from "@uxf/core-react/hooks/use-body-scroll-lock";
|
|
7
10
|
import { useState } from "react";
|
|
@@ -19,17 +22,25 @@ useBodyScrollLock<HTMLDivElement>(innerRef, isOpen, {
|
|
|
19
22
|
|
|
20
23
|
<div ref={innerRef}>Element which activates scroll lock on its parent elements.</div>
|
|
21
24
|
```
|
|
25
|
+
---
|
|
26
|
+
### isMounted
|
|
27
|
+
Check if component is mounted.
|
|
22
28
|
```tsx
|
|
23
29
|
import { useIsMounted } from "@uxf/core-react/hooks/use-is-mounted";
|
|
24
30
|
|
|
25
31
|
const isMounted = useIsMounted();
|
|
26
32
|
```
|
|
33
|
+
---
|
|
34
|
+
### useIsomorphicLayoutEffect
|
|
35
|
+
Returns `useEffect` on client and `useLayoutEffect` on server.
|
|
27
36
|
```tsx
|
|
28
37
|
import { useIsomorphicLayoutEffect } from "@uxf/core-react/hooks/use-isomorphic-layout-effect";
|
|
29
38
|
|
|
30
39
|
useIsomorphicLayoutEffect(() => {/* code */}, [/* deps */]);
|
|
31
40
|
```
|
|
32
|
-
|
|
41
|
+
---
|
|
42
|
+
### useKey
|
|
43
|
+
Trigger callback on given key.
|
|
33
44
|
```tsx
|
|
34
45
|
import { useKey } from "@uxf/core-react/hooks/use-key";
|
|
35
46
|
import { useRef } from "react";
|
|
@@ -45,6 +56,9 @@ useKey<HTMLDivElement>("Enter", () => console.log("callback"), {
|
|
|
45
56
|
|
|
46
57
|
<div ref={targetRef} tabIndex={0}>Element with callback triggerable by enter key.</div>
|
|
47
58
|
```
|
|
59
|
+
---
|
|
60
|
+
### useMinWindowWidth
|
|
61
|
+
Returns boolean if window width is equal or greater than given value.
|
|
48
62
|
```tsx
|
|
49
63
|
import { useMinWindowWidth } from "@uxf/core-react/hooks/use-min-window-width";
|
|
50
64
|
|
|
@@ -54,18 +68,25 @@ const isDesktopWithDebounce = useMinWindowWidth(1200, 200); // will be updated e
|
|
|
54
68
|
const example = isDesktop ? "desktop" : "tablet";
|
|
55
69
|
const debouncedExample = isDesktopWithDebounce ? "debouncedDesktop" : "debouncedTablet";
|
|
56
70
|
```
|
|
57
|
-
|
|
71
|
+
---
|
|
72
|
+
### usePagination
|
|
73
|
+
Returns array of pagination items.
|
|
58
74
|
```ts
|
|
59
75
|
import { usePagination } from "@uxf/core-react/hooks/use-pagination";
|
|
60
76
|
|
|
61
77
|
const paginationItems = usePagination({ page: 1, count: 10 })
|
|
62
78
|
```
|
|
63
|
-
|
|
79
|
+
---
|
|
80
|
+
### useRafState
|
|
81
|
+
Updates state only in the callback of `requestAnimationFrame`.
|
|
64
82
|
```tsx
|
|
65
83
|
import { useRafState } from "@uxf/core-react/hooks/use-raf-state";
|
|
66
84
|
|
|
67
85
|
const [state, setState] = useRafState<boolean>(false);
|
|
68
86
|
```
|
|
87
|
+
---
|
|
88
|
+
### useOnMount
|
|
89
|
+
Calls the callback on component mount.
|
|
69
90
|
```tsx
|
|
70
91
|
import { useOnUnmount } from "@uxf/core-react/hooks/use-on-unmount";
|
|
71
92
|
|
|
@@ -73,11 +94,17 @@ const exampleCallback = () => {};
|
|
|
73
94
|
|
|
74
95
|
useOnUnmount(exampleCallback());
|
|
75
96
|
```
|
|
97
|
+
---
|
|
98
|
+
### useOnUpdate
|
|
99
|
+
Calls the callback only on component update, except initial mount.
|
|
76
100
|
```tsx
|
|
77
101
|
import { useOnUpdate } from "@uxf/core-react/hooks/use-on-update";
|
|
78
102
|
|
|
79
103
|
useOnUpdate(() => {/* code */}, [/* deps */]);
|
|
80
104
|
```
|
|
105
|
+
---
|
|
106
|
+
### useWindowScroll
|
|
107
|
+
Returns x and y scroll coordinates of window on scroll.
|
|
81
108
|
```tsx
|
|
82
109
|
import { useWindowScroll } from "@uxf/core-react/hooks/use-window-scroll";
|
|
83
110
|
|
|
@@ -85,6 +112,9 @@ const windowScroll = useWindowScroll();
|
|
|
85
112
|
|
|
86
113
|
const example = windowScroll && windowScroll.y > 100 ? "scroled" : "on top";
|
|
87
114
|
```
|
|
115
|
+
---
|
|
116
|
+
### useWindowSize
|
|
117
|
+
Returns window width and height.
|
|
88
118
|
```tsx
|
|
89
119
|
import { useWindowSize } from "@uxf/core-react/hooks/use-window-size";
|
|
90
120
|
|
|
@@ -92,6 +122,9 @@ const windowSize = useWindowSize();
|
|
|
92
122
|
|
|
93
123
|
const example = windowSize && windowSize.width > 1200 ? "desktop" : "tablet";
|
|
94
124
|
```
|
|
125
|
+
---
|
|
126
|
+
### useFocusTrap
|
|
127
|
+
Locks focus inside given element.
|
|
95
128
|
```tsx
|
|
96
129
|
import { useFocusTrap } from "@uxf/core-react/hooks/use-focus-trap";
|
|
97
130
|
import { useState } from "react";
|
|
@@ -102,6 +135,9 @@ const focusTrapRef = useFocusTrap(active);
|
|
|
102
135
|
|
|
103
136
|
<div ref={focusTrapRef}>Element which trap focus inside if `active` is truthy.</div>
|
|
104
137
|
```
|
|
138
|
+
---
|
|
139
|
+
### useFocusReturn
|
|
140
|
+
Returns focus to last active element.
|
|
105
141
|
```tsx
|
|
106
142
|
import { useFocusReturn } from "@uxf/core-react/hooks/use-focus-return";
|
|
107
143
|
import { useState } from "react";
|
|
@@ -111,6 +147,9 @@ const [active, setActive] = useState<boolean>();
|
|
|
111
147
|
// Returns focus to last active element, e.g. in Modal or Popover
|
|
112
148
|
useFocusReturn(active);
|
|
113
149
|
```
|
|
150
|
+
---
|
|
151
|
+
### useAnchorProps
|
|
152
|
+
Returns props for anchor element.
|
|
114
153
|
```tsx
|
|
115
154
|
import { useAnchorProps } from "@uxf/core-react/hooks/use-anchor-props";
|
|
116
155
|
import { AnchorHTMLAttributes } from "react";
|
|
@@ -144,6 +183,9 @@ const anchorProps = useAnchorProps<Props>({
|
|
|
144
183
|
<a {...anchorProps}>Click me</a>
|
|
145
184
|
|
|
146
185
|
```
|
|
186
|
+
---
|
|
187
|
+
### useButtonProps
|
|
188
|
+
Returns props for button element.
|
|
147
189
|
```tsx
|
|
148
190
|
import { useButtonProps } from "@uxf/core-react/hooks/use-button-props";
|
|
149
191
|
import { ButtonHTMLAttributes } from "react";
|
|
@@ -175,6 +217,9 @@ const buttonProps = useButtonProps<Props>({
|
|
|
175
217
|
|
|
176
218
|
<button {...buttonProps}>Click me</button>
|
|
177
219
|
```
|
|
220
|
+
---
|
|
221
|
+
### useClickableProps
|
|
222
|
+
Returns props for clickable element.
|
|
178
223
|
```tsx
|
|
179
224
|
import { useClickableProps } from "@uxf/core-react/hooks/use-clickable-props";
|
|
180
225
|
import { HTMLAttributes } from "react";
|
|
@@ -206,6 +251,9 @@ const buttonProps = useClickableProps<Props>({
|
|
|
206
251
|
|
|
207
252
|
<button {...buttonProps}>Click me</button>
|
|
208
253
|
```
|
|
254
|
+
---
|
|
255
|
+
### useMouseDragToScroll
|
|
256
|
+
Allow to scroll element by dragging mouse.
|
|
209
257
|
```tsx
|
|
210
258
|
import { useMouseDragToScroll } from "@uxf/core-react/hooks/use-mouse-drag-to-scroll";
|
|
211
259
|
|
|
@@ -215,6 +263,9 @@ const style = useMouseDragToScroll(scrollRef);
|
|
|
215
263
|
|
|
216
264
|
<div style={style}>Drag to scroll</div>
|
|
217
265
|
```
|
|
266
|
+
---
|
|
267
|
+
### useInputFocus
|
|
268
|
+
Manage focus states of input element.
|
|
218
269
|
```tsx
|
|
219
270
|
import { useInputFocus } from "@uxf/core-react/hooks/use-input-focus";
|
|
220
271
|
|
|
@@ -227,6 +278,9 @@ const input = useInputFocus(focusRef, onBlur, onFocus);
|
|
|
227
278
|
<button onClick={input.focus}>Focus input</button>
|
|
228
279
|
<input onBlur={input.onBlur} onFocus={input.onFocus} ref={focusRef} />
|
|
229
280
|
```
|
|
281
|
+
---
|
|
282
|
+
### useLatest
|
|
283
|
+
Allways returns latest value of given variable.
|
|
230
284
|
```tsx
|
|
231
285
|
import { useLatest } from "@uxf/core-react/hooks/use-latest";
|
|
232
286
|
|
|
@@ -236,6 +290,9 @@ useEffect(() => {
|
|
|
236
290
|
latestState.current(); // use newest state of 'someUnstableWhatever' without affecting this effetct update
|
|
237
291
|
}, [latestState])
|
|
238
292
|
```
|
|
293
|
+
---
|
|
294
|
+
### usePrevious
|
|
295
|
+
Returns previous value of given variable.
|
|
239
296
|
```tsx
|
|
240
297
|
import { usePrevious } from "@uxf/core-react/hooks/use-previous";
|
|
241
298
|
|
|
@@ -245,3 +302,31 @@ useEffect(() => {
|
|
|
245
302
|
previousState.current(); // use state of 'someUnstableWhatever' from previous render without affecting this effetct update
|
|
246
303
|
}, [previousState])
|
|
247
304
|
```
|
|
305
|
+
---
|
|
306
|
+
### useToggle
|
|
307
|
+
Returns boolean state and methods to toggle it.
|
|
308
|
+
```tsx
|
|
309
|
+
import { useToggle } from "@uxf/core-react/hooks/use-toggle";
|
|
310
|
+
|
|
311
|
+
const [isVisible, toggleIsVisible, setVisible, setInvisible] = useToggle(false);
|
|
312
|
+
|
|
313
|
+
<button onClick={toggleIsVisible}>Toggle visibility</button>
|
|
314
|
+
```
|
|
315
|
+
---
|
|
316
|
+
### useIncrement
|
|
317
|
+
Returns number state and methods to increment, decrement and reset.
|
|
318
|
+
```tsx
|
|
319
|
+
import { useIncrement } from "@uxf/core-react/hooks/use-increment";
|
|
320
|
+
|
|
321
|
+
const [count, increment, decrement, reset] = useIncrement(5, 1);
|
|
322
|
+
|
|
323
|
+
<button onClick={increment}>Toggle visibility</button>
|
|
324
|
+
```
|
|
325
|
+
---
|
|
326
|
+
### useDebounce
|
|
327
|
+
Returns the latest value after given delay.
|
|
328
|
+
```tsx
|
|
329
|
+
import { useDebounce } from "@uxf/core-react/hooks/use-debounce";
|
|
330
|
+
|
|
331
|
+
const debouncedValue = useDebounce<string>("some value", 300);
|
|
332
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function useDebounce<T>(value: T, delay?: number): T;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useDebounce = useDebounce;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const use_on_update_1 = require("./use-on-update");
|
|
6
|
+
function useDebounce(value, delay) {
|
|
7
|
+
const [debouncedValue, setDebouncedValue] = (0, react_1.useState)(value);
|
|
8
|
+
(0, use_on_update_1.useOnUpdate)(() => {
|
|
9
|
+
const timer = setTimeout(() => setDebouncedValue(value), delay !== null && delay !== void 0 ? delay : 500);
|
|
10
|
+
return () => {
|
|
11
|
+
clearTimeout(timer);
|
|
12
|
+
};
|
|
13
|
+
}, [value, delay]);
|
|
14
|
+
return debouncedValue;
|
|
15
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useIncrement = useIncrement;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
function useIncrement(defaultValue, step = 1) {
|
|
6
|
+
const [value, setValue] = (0, react_1.useState)(defaultValue);
|
|
7
|
+
const incrementHandler = (0, react_1.useCallback)(() => setValue((prev) => prev + step), [step]);
|
|
8
|
+
const decrementHandler = (0, react_1.useCallback)(() => setValue((prev) => prev - step), [step]);
|
|
9
|
+
const resetHandler = (0, react_1.useCallback)(() => setValue(defaultValue), [defaultValue]);
|
|
10
|
+
return [value, incrementHandler, decrementHandler, resetHandler];
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const react_1 = require("@testing-library/react");
|
|
4
|
+
const use_increment_1 = require("./use-increment"); // Adjust the import based on your file structure
|
|
5
|
+
describe("useIncrement Hook", () => {
|
|
6
|
+
it("should initialize with the default value", () => {
|
|
7
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_increment_1.useIncrement)(5));
|
|
8
|
+
const [value] = result.current;
|
|
9
|
+
expect(value).toBe(5);
|
|
10
|
+
});
|
|
11
|
+
it("should increment the value by the step value", () => {
|
|
12
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_increment_1.useIncrement)(5, 2));
|
|
13
|
+
const [value, incrementHandler] = result.current;
|
|
14
|
+
expect(value).toBe(5);
|
|
15
|
+
(0, react_1.act)(() => {
|
|
16
|
+
incrementHandler();
|
|
17
|
+
});
|
|
18
|
+
const [newValue] = result.current;
|
|
19
|
+
expect(newValue).toBe(7); // 5 + 2
|
|
20
|
+
});
|
|
21
|
+
it("should decrement the value by the step value", () => {
|
|
22
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_increment_1.useIncrement)(10, 3));
|
|
23
|
+
const [value, , decrementHandler] = result.current;
|
|
24
|
+
expect(value).toBe(10);
|
|
25
|
+
(0, react_1.act)(() => {
|
|
26
|
+
decrementHandler();
|
|
27
|
+
});
|
|
28
|
+
const [newValue] = result.current;
|
|
29
|
+
expect(newValue).toBe(7); // 10 - 3
|
|
30
|
+
});
|
|
31
|
+
it("should reset the value to the default value", () => {
|
|
32
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_increment_1.useIncrement)(20, 5));
|
|
33
|
+
const [value, incrementHandler, , resetHandler] = result.current;
|
|
34
|
+
expect(value).toBe(20);
|
|
35
|
+
(0, react_1.act)(() => {
|
|
36
|
+
incrementHandler();
|
|
37
|
+
});
|
|
38
|
+
const [newValue] = result.current;
|
|
39
|
+
expect(newValue).toBe(25); // 20 + 5
|
|
40
|
+
(0, react_1.act)(() => {
|
|
41
|
+
resetHandler();
|
|
42
|
+
});
|
|
43
|
+
const [resetValue] = result.current;
|
|
44
|
+
expect(resetValue).toBe(20); // Reset back to default
|
|
45
|
+
});
|
|
46
|
+
it("should use a step of 1 if no step is provided", () => {
|
|
47
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_increment_1.useIncrement)(10));
|
|
48
|
+
const [value, incrementHandler, decrementHandler] = result.current;
|
|
49
|
+
expect(value).toBe(10);
|
|
50
|
+
(0, react_1.act)(() => {
|
|
51
|
+
incrementHandler();
|
|
52
|
+
});
|
|
53
|
+
const [newValue] = result.current;
|
|
54
|
+
expect(newValue).toBe(11); // 10 + 1 (default step)
|
|
55
|
+
(0, react_1.act)(() => {
|
|
56
|
+
decrementHandler();
|
|
57
|
+
});
|
|
58
|
+
const [finalValue] = result.current;
|
|
59
|
+
expect(finalValue).toBe(10); // 11 - 1
|
|
60
|
+
});
|
|
61
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useToggle = useToggle;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
function useToggle(defaultValue) {
|
|
6
|
+
const [isOn, setIsOn] = (0, react_1.useState)(defaultValue);
|
|
7
|
+
const toggleHandler = (0, react_1.useCallback)(() => setIsOn((prev) => !prev), []);
|
|
8
|
+
const setTrueHandler = (0, react_1.useCallback)(() => setIsOn(true), []);
|
|
9
|
+
const setFalseHandler = (0, react_1.useCallback)(() => setIsOn(false), []);
|
|
10
|
+
return [isOn, toggleHandler, setTrueHandler, setFalseHandler];
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const react_1 = require("@testing-library/react");
|
|
4
|
+
const use_toggle_1 = require("./use-toggle");
|
|
5
|
+
describe("useToggle Hook", () => {
|
|
6
|
+
it("should initialize with the default value", () => {
|
|
7
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_toggle_1.useToggle)(false));
|
|
8
|
+
const [isOn] = result.current;
|
|
9
|
+
expect(isOn).toBe(false);
|
|
10
|
+
});
|
|
11
|
+
it("should toggle the value when toggleHandler is called", () => {
|
|
12
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_toggle_1.useToggle)(false));
|
|
13
|
+
const [isOn, toggleHandler] = result.current;
|
|
14
|
+
expect(isOn).toBe(false);
|
|
15
|
+
(0, react_1.act)(() => {
|
|
16
|
+
toggleHandler();
|
|
17
|
+
});
|
|
18
|
+
const [isOnNew] = result.current;
|
|
19
|
+
expect(isOnNew).toBe(true);
|
|
20
|
+
(0, react_1.act)(() => {
|
|
21
|
+
toggleHandler();
|
|
22
|
+
});
|
|
23
|
+
const [isOnFinal] = result.current;
|
|
24
|
+
expect(isOnFinal).toBe(false);
|
|
25
|
+
});
|
|
26
|
+
it("should set the value to true when setTrueHandler is called", () => {
|
|
27
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_toggle_1.useToggle)(false));
|
|
28
|
+
const [isOn, , setTrueHandler] = result.current;
|
|
29
|
+
expect(isOn).toBe(false);
|
|
30
|
+
(0, react_1.act)(() => {
|
|
31
|
+
setTrueHandler();
|
|
32
|
+
});
|
|
33
|
+
const [isOnNew] = result.current;
|
|
34
|
+
expect(isOnNew).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
it("should set the value to false when setFalseHandler is called", () => {
|
|
37
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_toggle_1.useToggle)(true));
|
|
38
|
+
const [isOn, , , setFalseHandler] = result.current;
|
|
39
|
+
expect(isOn).toBe(true);
|
|
40
|
+
(0, react_1.act)(() => {
|
|
41
|
+
setFalseHandler();
|
|
42
|
+
});
|
|
43
|
+
const [isOnNew] = result.current;
|
|
44
|
+
expect(isOnNew).toBe(false);
|
|
45
|
+
});
|
|
46
|
+
});
|
package/package.json
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
2
|
+
"name": "@uxf/core-react",
|
|
3
|
+
"version": "11.38.3",
|
|
4
|
+
"description": "UXF Core",
|
|
5
|
+
"author": "UX Fans s.r.o",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc -P tsconfig.json",
|
|
12
|
+
"typecheck": "tsc --noEmit --skipLibCheck"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@uxf/core": "11.35.0"
|
|
16
|
+
},
|
|
17
|
+
"peerDependencies": {
|
|
18
|
+
"react": ">=18.2.0"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/react": "18.3.5",
|
|
22
|
+
"react": "18.3.1"
|
|
23
|
+
}
|
|
24
|
+
}
|