extra-react-hooks 0.8.9 → 0.8.10
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/lib/use-number-input.js +31 -26
- package/lib/use-number-input.js.map +1 -1
- package/package.json +1 -1
- package/src/use-number-input.ts +33 -38
package/lib/use-number-input.js
CHANGED
|
@@ -1,29 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useRef } from 'react';
|
|
2
2
|
import { isntNaN } from 'extra-utils';
|
|
3
3
|
import { useIIFE } from './use-iife.js';
|
|
4
|
+
import { useForceUpdate } from './use-force-update.js';
|
|
4
5
|
export function useNumberInput({ value, lazy, onChange }) {
|
|
5
|
-
const [displayValue, setDisplayValue] =
|
|
6
|
-
useIIFE(() => {
|
|
7
|
-
if (!lazy) {
|
|
8
|
-
const oldValue = Number(displayValue);
|
|
9
|
-
if (oldValue !== value)
|
|
10
|
-
setDisplayValue(value.toString());
|
|
11
|
-
}
|
|
12
|
-
}, [lazy, value, displayValue]);
|
|
13
|
-
useIIFE(() => {
|
|
14
|
-
if (lazy) {
|
|
15
|
-
setDisplayValue(value.toString());
|
|
16
|
-
}
|
|
17
|
-
}, [lazy, value]);
|
|
6
|
+
const [displayValue, setDisplayValue] = useDerivedState(value.toString());
|
|
18
7
|
return {
|
|
19
8
|
getInputProps() {
|
|
20
9
|
return {
|
|
21
10
|
type: 'number',
|
|
22
11
|
value: displayValue,
|
|
23
12
|
onChange(e) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
13
|
+
if (lazy) {
|
|
14
|
+
e.target.reportValidity();
|
|
15
|
+
setDisplayValue(e.target.value);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
if (e.target.reportValidity()) {
|
|
27
19
|
const newValue = e.target.valueAsNumber;
|
|
28
20
|
if (isntNaN(newValue) && newValue !== value) {
|
|
29
21
|
onChange(newValue, false);
|
|
@@ -34,23 +26,36 @@ export function useNumberInput({ value, lazy, onChange }) {
|
|
|
34
26
|
onBlur(e) {
|
|
35
27
|
if (e.target.checkValidity()) {
|
|
36
28
|
const newValue = e.target.valueAsNumber;
|
|
37
|
-
if (
|
|
38
|
-
onChange(newValue, true);
|
|
29
|
+
if (isntNaN(newValue) && newValue !== value) {
|
|
39
30
|
setDisplayValue(newValue.toString());
|
|
40
|
-
|
|
31
|
+
onChange(newValue, true);
|
|
41
32
|
}
|
|
42
|
-
|
|
43
|
-
else {
|
|
44
|
-
if (!lazy) {
|
|
45
|
-
onChange(value, true);
|
|
33
|
+
else {
|
|
46
34
|
setDisplayValue(value.toString());
|
|
47
|
-
return;
|
|
48
35
|
}
|
|
49
36
|
}
|
|
50
|
-
|
|
37
|
+
else {
|
|
38
|
+
setDisplayValue(value.toString());
|
|
39
|
+
}
|
|
51
40
|
}
|
|
52
41
|
};
|
|
53
42
|
}
|
|
54
43
|
};
|
|
55
44
|
}
|
|
45
|
+
function useDerivedState(dep) {
|
|
46
|
+
const forceUpdate = useForceUpdate();
|
|
47
|
+
const stateRef = useRef(dep);
|
|
48
|
+
useIIFE(() => {
|
|
49
|
+
stateRef.current = dep;
|
|
50
|
+
}, [dep]);
|
|
51
|
+
return [
|
|
52
|
+
stateRef.current,
|
|
53
|
+
newState => {
|
|
54
|
+
if (stateRef.current !== newState) {
|
|
55
|
+
stateRef.current = newState;
|
|
56
|
+
forceUpdate();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
];
|
|
60
|
+
}
|
|
56
61
|
//# sourceMappingURL=use-number-input.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-number-input.js","sourceRoot":"","sources":["../src/use-number-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"use-number-input.js","sourceRoot":"","sources":["../src/use-number-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEtD,MAAM,UAAU,cAAc,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAKrD;IASC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,eAAe,CAAS,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;IAEjF,OAAO;QACL,aAAa;YACX,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,YAAY;gBACnB,QAAQ,CAAC,CAAC;oBACR,IAAI,IAAI,EAAE,CAAC;wBACT,CAAC,CAAC,MAAM,CAAC,cAAc,EAAE,CAAA;wBAEzB,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;oBACjC,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,CAAC;4BAC9B,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,aAAa,CAAA;4BAEvC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;gCAC5C,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;4BAC3B,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;gBACD,MAAM,CAAC,CAAC;oBACN,IAAI,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,CAAC;wBAC7B,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,aAAa,CAAA;wBAEvC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;4BAC5C,eAAe,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAA;4BAEpC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;wBAC1B,CAAC;6BAAM,CAAC;4BACN,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;wBACnC,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;oBACnC,CAAC;gBACH,CAAC;aACF,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAED,SAAS,eAAe,CAAI,GAAM;IAChC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IACpC,MAAM,QAAQ,GAAG,MAAM,CAAI,GAAG,CAAC,CAAA;IAE/B,OAAO,CAAC,GAAG,EAAE;QACX,QAAQ,CAAC,OAAO,GAAG,GAAG,CAAA;IACxB,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;IAET,OAAO;QACL,QAAQ,CAAC,OAAO;QAChB,QAAQ,CAAC,EAAE;YACT,IAAI,QAAQ,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAClC,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAA;gBAE3B,WAAW,EAAE,CAAA;YACf,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
|
package/package.json
CHANGED
package/src/use-number-input.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useRef } from 'react'
|
|
2
2
|
import { isntNaN } from 'extra-utils'
|
|
3
3
|
import { useIIFE } from './use-iife.js'
|
|
4
|
+
import { useForceUpdate } from './use-force-update.js'
|
|
4
5
|
|
|
5
6
|
export function useNumberInput({ value, lazy, onChange }: {
|
|
6
7
|
value: number
|
|
@@ -16,24 +17,7 @@ export function useNumberInput({ value, lazy, onChange }: {
|
|
|
16
17
|
| 'onBlur'
|
|
17
18
|
>>
|
|
18
19
|
} {
|
|
19
|
-
const [displayValue, setDisplayValue] =
|
|
20
|
-
|
|
21
|
-
useIIFE(() => {
|
|
22
|
-
if (!lazy) {
|
|
23
|
-
const oldValue = Number(displayValue)
|
|
24
|
-
|
|
25
|
-
// 以传入的值为准, 但只有在实际代表的值不同时, 才更新.
|
|
26
|
-
if (oldValue !== value) setDisplayValue(value.toString())
|
|
27
|
-
}
|
|
28
|
-
}, [lazy, value, displayValue])
|
|
29
|
-
|
|
30
|
-
useIIFE(() => {
|
|
31
|
-
if (lazy) {
|
|
32
|
-
// 以传入的值为准.
|
|
33
|
-
// 由于onChange是惰性调用, 不需要检查值的相等性.
|
|
34
|
-
setDisplayValue(value.toString())
|
|
35
|
-
}
|
|
36
|
-
}, [lazy, value])
|
|
20
|
+
const [displayValue, setDisplayValue] = useDerivedState<string>(value.toString())
|
|
37
21
|
|
|
38
22
|
return {
|
|
39
23
|
getInputProps() {
|
|
@@ -41,10 +25,12 @@ export function useNumberInput({ value, lazy, onChange }: {
|
|
|
41
25
|
type: 'number'
|
|
42
26
|
, value: displayValue
|
|
43
27
|
, onChange(e) {
|
|
44
|
-
|
|
28
|
+
if (lazy) {
|
|
29
|
+
e.target.reportValidity()
|
|
45
30
|
|
|
46
|
-
|
|
47
|
-
|
|
31
|
+
setDisplayValue(e.target.value)
|
|
32
|
+
} else {
|
|
33
|
+
if (e.target.reportValidity()) {
|
|
48
34
|
const newValue = e.target.valueAsNumber
|
|
49
35
|
|
|
50
36
|
if (isntNaN(newValue) && newValue !== value) {
|
|
@@ -57,29 +43,38 @@ export function useNumberInput({ value, lazy, onChange }: {
|
|
|
57
43
|
if (e.target.checkValidity()) {
|
|
58
44
|
const newValue = e.target.valueAsNumber
|
|
59
45
|
|
|
60
|
-
if (
|
|
61
|
-
onChange(newValue, true)
|
|
62
|
-
|
|
63
|
-
// 使用格式化后的新值.
|
|
64
|
-
// 若hook的调用方决定不接受新值, 则displayValue的值会被覆盖.
|
|
46
|
+
if (isntNaN(newValue) && newValue !== value) {
|
|
65
47
|
setDisplayValue(newValue.toString())
|
|
66
48
|
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
} else {
|
|
70
|
-
if (!lazy) {
|
|
71
|
-
onChange(value, true)
|
|
72
|
-
|
|
49
|
+
onChange(newValue, true)
|
|
50
|
+
} else {
|
|
73
51
|
setDisplayValue(value.toString())
|
|
74
|
-
|
|
75
|
-
return
|
|
76
52
|
}
|
|
53
|
+
} else {
|
|
54
|
+
setDisplayValue(value.toString())
|
|
77
55
|
}
|
|
78
|
-
|
|
79
|
-
// 继续使用旧值, 但对旧值格式化.
|
|
80
|
-
setDisplayValue(value.toString())
|
|
81
56
|
}
|
|
82
57
|
}
|
|
83
58
|
}
|
|
84
59
|
}
|
|
85
60
|
}
|
|
61
|
+
|
|
62
|
+
function useDerivedState<T>(dep: T): [state: T, setState: (newState: T) => void] {
|
|
63
|
+
const forceUpdate = useForceUpdate()
|
|
64
|
+
const stateRef = useRef<T>(dep)
|
|
65
|
+
|
|
66
|
+
useIIFE(() => {
|
|
67
|
+
stateRef.current = dep
|
|
68
|
+
}, [dep])
|
|
69
|
+
|
|
70
|
+
return [
|
|
71
|
+
stateRef.current
|
|
72
|
+
, newState => {
|
|
73
|
+
if (stateRef.current !== newState) {
|
|
74
|
+
stateRef.current = newState
|
|
75
|
+
|
|
76
|
+
forceUpdate()
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
}
|