@kwiz/fluentui 1.0.76 → 1.0.78
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/controls/horizontal.js +1 -1
- package/dist/controls/horizontal.js.map +1 -1
- package/dist/controls/vertical.js +1 -1
- package/dist/controls/vertical.js.map +1 -1
- package/dist/helpers/hooks.d.ts +1 -1
- package/dist/helpers/hooks.js +43 -30
- package/dist/helpers/hooks.js.map +1 -1
- package/package.json +2 -2
- package/src/controls/horizontal.tsx +1 -1
- package/src/controls/vertical.tsx +1 -1
- package/src/helpers/hooks.tsx +47 -35
@@ -29,6 +29,6 @@ export const Horizontal = React.forwardRef((props, ref) => {
|
|
29
29
|
css.push(cssNames.hCentered);
|
30
30
|
if (isNotEmptyArray(props.css))
|
31
31
|
css.push(...props.css);
|
32
|
-
return (_jsx(Section, Object.assign({}, props, { css: css })));
|
32
|
+
return (_jsx(Section, Object.assign({}, props, { css: css, ref: ref })));
|
33
33
|
});
|
34
34
|
//# sourceMappingURL=horizontal.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"horizontal.js","sourceRoot":"","sources":["../../src/controls/horizontal.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAiB,OAAO,EAAE,MAAM,WAAW,CAAC;AAEnD,MAAM,SAAS,GAAG,UAAU,CAAC;IACzB,UAAU,kCACH,MAAM,CAAC,IAAI,KACd,aAAa,EAAE,KAAK,GACvB;IACD,IAAI,EAAE,MAAM,CAAC,IAAI;IACjB,KAAK,EAAE,MAAM,CAAC,KAAK;IACnB,QAAQ,EAAE;QACN,UAAU,EAAE,QAAQ;KACvB;IACD,SAAS,EAAE;QACP,cAAc,EAAE,QAAQ;KAC3B;CACJ,CAAC,CAAA;AAUF,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAkD,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACvG,MAAM,QAAQ,GAAG,SAAS,EAAE,CAAC;IAC7B,IAAI,GAAG,GAAa,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;IAEjD,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC9B,IAAI,KAAK,CAAC,IAAI;QACV,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,KAAK,CAAC,KAAK;QACX,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,KAAK,CAAC,QAAQ;QACd,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAChC,IAAI,KAAK,CAAC,SAAS;QACf,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAEjC,IAAI,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC;QAAE,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IAEvD,OAAO,CACH,KAAC,OAAO,oBAAK,KAAK,IAAE,GAAG,EAAE,GAAG,IAAI,
|
1
|
+
{"version":3,"file":"horizontal.js","sourceRoot":"","sources":["../../src/controls/horizontal.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAiB,OAAO,EAAE,MAAM,WAAW,CAAC;AAEnD,MAAM,SAAS,GAAG,UAAU,CAAC;IACzB,UAAU,kCACH,MAAM,CAAC,IAAI,KACd,aAAa,EAAE,KAAK,GACvB;IACD,IAAI,EAAE,MAAM,CAAC,IAAI;IACjB,KAAK,EAAE,MAAM,CAAC,KAAK;IACnB,QAAQ,EAAE;QACN,UAAU,EAAE,QAAQ;KACvB;IACD,SAAS,EAAE;QACP,cAAc,EAAE,QAAQ;KAC3B;CACJ,CAAC,CAAA;AAUF,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAkD,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACvG,MAAM,QAAQ,GAAG,SAAS,EAAE,CAAC;IAC7B,IAAI,GAAG,GAAa,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;IAEjD,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC9B,IAAI,KAAK,CAAC,IAAI;QACV,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,KAAK,CAAC,KAAK;QACX,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,KAAK,CAAC,QAAQ;QACd,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAChC,IAAI,KAAK,CAAC,SAAS;QACf,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAEjC,IAAI,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC;QAAE,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IAEvD,OAAO,CACH,KAAC,OAAO,oBAAK,KAAK,IAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAC7C,CAAC;AACN,CAAC,CAAC,CAAC"}
|
@@ -24,6 +24,6 @@ export const Vertical = React.forwardRef((props, ref) => {
|
|
24
24
|
css.push(cssNames.vCentered);
|
25
25
|
if (isNotEmptyArray(props.css))
|
26
26
|
css.push(...props.css);
|
27
|
-
return (_jsx(Section, Object.assign({}, props, { css: css })));
|
27
|
+
return (_jsx(Section, Object.assign({}, props, { css: css, ref: ref })));
|
28
28
|
});
|
29
29
|
//# sourceMappingURL=vertical.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"vertical.js","sourceRoot":"","sources":["../../src/controls/vertical.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAiB,OAAO,EAAE,MAAM,WAAW,CAAC;AAEnD,MAAM,SAAS,GAAG,UAAU,CAAC;IACzB,QAAQ,kCACD,MAAM,CAAC,IAAI,KACd,aAAa,EAAE,QAAQ,GAC1B;IACD,IAAI,EAAE,MAAM,CAAC,IAAI;IACjB,KAAK,EAAE,MAAM,CAAC,KAAK;IACnB,SAAS,EAAE;QACP,cAAc,EAAE,QAAQ;KAC3B;CAEJ,CAAC,CAAA;AAQF,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAkD,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACrG,MAAM,QAAQ,GAAG,SAAS,EAAE,CAAC;IAC7B,IAAI,GAAG,GAAa,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;IAE/C,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC5B,IAAI,KAAK,CAAC,IAAI;QACV,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,KAAK,CAAC,KAAK;QACX,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,KAAK,CAAC,SAAS;QACf,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAEjC,IAAI,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC;QAAE,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IAEvD,OAAO,CACH,KAAC,OAAO,oBAAK,KAAK,IAAE,GAAG,EAAE,GAAG,IAAI,
|
1
|
+
{"version":3,"file":"vertical.js","sourceRoot":"","sources":["../../src/controls/vertical.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAiB,OAAO,EAAE,MAAM,WAAW,CAAC;AAEnD,MAAM,SAAS,GAAG,UAAU,CAAC;IACzB,QAAQ,kCACD,MAAM,CAAC,IAAI,KACd,aAAa,EAAE,QAAQ,GAC1B;IACD,IAAI,EAAE,MAAM,CAAC,IAAI;IACjB,KAAK,EAAE,MAAM,CAAC,KAAK;IACnB,SAAS,EAAE;QACP,cAAc,EAAE,QAAQ;KAC3B;CAEJ,CAAC,CAAA;AAQF,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAkD,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACrG,MAAM,QAAQ,GAAG,SAAS,EAAE,CAAC;IAC7B,IAAI,GAAG,GAAa,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;IAE/C,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC5B,IAAI,KAAK,CAAC,IAAI;QACV,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,KAAK,CAAC,KAAK;QACX,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,KAAK,CAAC,SAAS;QACf,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAEjC,IAAI,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC;QAAE,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IAEvD,OAAO,CACH,KAAC,OAAO,oBAAK,KAAK,IAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAC7C,CAAC;AACN,CAAC,CAAC,CAAC"}
|
package/dist/helpers/hooks.d.ts
CHANGED
@@ -2,7 +2,7 @@ import { HTMLAttributes, MutableRefObject, SetStateAction } from "react";
|
|
2
2
|
/** Empty array ensures that effect is only run on mount */
|
3
3
|
export declare const useEffectOnlyOnMount: any[];
|
4
4
|
type stateExOptions<ValueType> = {
|
5
|
-
onChange?: (newValue:
|
5
|
+
onChange?: (newValue: ValueType, isValueChanged: boolean) => ValueType;
|
6
6
|
skipUpdateIfSame?: boolean;
|
7
7
|
name?: string;
|
8
8
|
};
|
package/dist/helpers/hooks.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { makeStyles } from "@fluentui/react-components";
|
2
|
-
import { isFunction, isNotEmptyArray, isNullOrEmptyString, isPrimitiveValue, jsonClone, jsonStringify, LoggerLevel, objectsEqual
|
2
|
+
import { isFunction, isNotEmptyArray, isNullOrEmptyString, isPrimitiveValue, jsonClone, jsonStringify, LoggerLevel, objectsEqual } from "@kwiz/common";
|
3
3
|
import { useCallback, useEffect, useRef, useState } from "react";
|
4
4
|
import { GetLogger } from "../_modules/config";
|
5
5
|
import { mixins } from "../styles/styles";
|
@@ -32,7 +32,15 @@ export function useStateEX(initialValue, options) {
|
|
32
32
|
let logger = GetLogger(`useStateWithTrack${isNullOrEmptyString(name) ? '' : ` ${name}`}`);
|
33
33
|
logger.setLevel(LoggerLevel.WARN);
|
34
34
|
const [value, setValueInState] = useState(initialValue);
|
35
|
-
const currentValue = useRef(
|
35
|
+
const currentValue = useRef();
|
36
|
+
//json clone complex/ref values so we can compare if value changed, in case caller makes chagnes on the value object directly.
|
37
|
+
const currentValueForChecks = useRef();
|
38
|
+
useEffect(() => {
|
39
|
+
updateCurrentRef(initialValue);
|
40
|
+
}, useEffectOnlyOnMount);
|
41
|
+
//keep a ref to onChange so the caller's latet state is accessible
|
42
|
+
const onChange = useRef(options.onChange);
|
43
|
+
onChange.current = options.onChange;
|
36
44
|
/** make this a collection in case several callers are awaiting the same propr update */
|
37
45
|
const resolveState = useRef([]);
|
38
46
|
const isMounted = useRef(false);
|
@@ -52,49 +60,43 @@ export function useStateEX(initialValue, options) {
|
|
52
60
|
;
|
53
61
|
useEffect(() => {
|
54
62
|
resolvePromises();
|
55
|
-
|
56
|
-
logger.log(`resolved after render`);
|
57
|
-
let resolvers = resolveState.current.slice();
|
58
|
-
resolveState.current = []; //clear
|
59
|
-
resolvers.map(r => r(value));
|
60
|
-
}
|
61
|
-
}, [value, resolveState.current]);
|
63
|
+
}, [value]);
|
62
64
|
function getIsValueChanged(newValue) {
|
65
|
+
let error = null;
|
63
66
|
let result;
|
64
|
-
|
65
|
-
|
67
|
+
try {
|
68
|
+
if (!objectsEqual(newValue, currentValueForChecks.current)) {
|
69
|
+
result = true;
|
70
|
+
}
|
71
|
+
else {
|
72
|
+
result = false;
|
73
|
+
}
|
66
74
|
}
|
67
|
-
|
68
|
-
|
75
|
+
catch (e) {
|
76
|
+
error = e;
|
77
|
+
result = true;
|
69
78
|
}
|
70
79
|
return logger.groupSync(result ? 'value changed' : 'value not changed', log => {
|
71
80
|
if (logger.getLevel() === LoggerLevel.VERBOSE) {
|
72
|
-
log('old: ' + extractStringValue(
|
81
|
+
log('old: ' + extractStringValue(currentValueForChecks.current));
|
73
82
|
log('new: ' + extractStringValue(newValue));
|
83
|
+
if (error)
|
84
|
+
log({ label: "Error", value: error });
|
74
85
|
}
|
75
86
|
return result;
|
76
87
|
});
|
77
88
|
}
|
78
89
|
;
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
setValueInState(newValue);
|
83
|
-
}
|
84
|
-
else {
|
85
|
-
resolvePromises();
|
86
|
-
}
|
87
|
-
};
|
88
|
-
let setValueWithEvents = wrapFunction(setValueWithCheck, {
|
89
|
-
before: (newValue) => isFunction(options.onChange) ? options.onChange(newValue, getIsValueChanged(newValue)) : newValue,
|
90
|
-
after: (newValue) => currentValue.current = isPrimitiveValue(newValue) || isFunction(newValue)
|
90
|
+
function updateCurrentRef(newValue) {
|
91
|
+
currentValue.current = newValue;
|
92
|
+
currentValueForChecks.current = isPrimitiveValue(newValue) || isFunction(newValue)
|
91
93
|
? newValue
|
92
94
|
//fix skipUpdateIfSame for complex objects
|
93
95
|
//if we don't clone it, currentValue.current will be a ref to the value in the owner
|
94
96
|
//and will be treated as unchanged object, and it will be out of sync
|
95
97
|
//this leads to skipUpdateIfSame failing after just 1 unchanged update
|
96
|
-
: jsonClone(newValue)
|
97
|
-
}
|
98
|
+
: jsonClone(newValue);
|
99
|
+
}
|
98
100
|
const setValue = useCallback((newState) => new Promise(resolve => {
|
99
101
|
if (!isMounted.current) {
|
100
102
|
//unmounted may never resolve
|
@@ -103,9 +105,20 @@ export function useStateEX(initialValue, options) {
|
|
103
105
|
}
|
104
106
|
else {
|
105
107
|
resolveState.current.push(resolve);
|
106
|
-
|
108
|
+
const isChanged = isFunction(onChange.current) || options.skipUpdateIfSame
|
109
|
+
? getIsValueChanged(newState) //don't call this if there is no onChange handler and if we don't need to monitor skipUpdateIfSame
|
110
|
+
: true;
|
111
|
+
if (isFunction(onChange.current))
|
112
|
+
newState = onChange.current(newState, isChanged);
|
113
|
+
//keep current value ref up to date
|
114
|
+
updateCurrentRef(newState);
|
115
|
+
//set state
|
116
|
+
if (!options.skipUpdateIfSame || isChanged)
|
117
|
+
setValueInState(newState);
|
118
|
+
else //don't set in state - just resolve pending promises, UI will not be updated.
|
119
|
+
resolvePromises();
|
107
120
|
}
|
108
|
-
}),
|
121
|
+
}), useEffectOnlyOnMount);
|
109
122
|
return [value, setValue, currentValue];
|
110
123
|
}
|
111
124
|
/** use a ref, that can be tracked as useEffect dependency */
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/helpers/hooks.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/helpers/hooks.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@kwiz/fluentui",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.78",
|
4
4
|
"description": "KWIZ common controls for FluentUI",
|
5
5
|
"module": "dist/index.js",
|
6
6
|
"types": "dist/index.d.ts",
|
@@ -61,7 +61,7 @@
|
|
61
61
|
"dependencies": {
|
62
62
|
"@fluentui/react-datepicker-compat": "^0.4.53",
|
63
63
|
"@fluentui/react-timepicker-compat": "^0.2.42",
|
64
|
-
"@kwiz/common": "^1.0.
|
64
|
+
"@kwiz/common": "^1.0.128",
|
65
65
|
"@mismerge/core": "^1.2.1",
|
66
66
|
"@mismerge/react": "^1.0.1",
|
67
67
|
"esbuild": "^0.19.12",
|
package/src/helpers/hooks.tsx
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { makeStyles } from "@fluentui/react-components";
|
2
|
-
import { isFunction, isNotEmptyArray, isNullOrEmptyString, isPrimitiveValue, jsonClone, jsonStringify, LoggerLevel, objectsEqual
|
2
|
+
import { isFunction, isNotEmptyArray, isNullOrEmptyString, isPrimitiveValue, jsonClone, jsonStringify, LoggerLevel, objectsEqual } from "@kwiz/common";
|
3
3
|
import { HTMLAttributes, MutableRefObject, SetStateAction, useCallback, useEffect, useRef, useState } from "react";
|
4
4
|
import { GetLogger } from "../_modules/config";
|
5
5
|
import { mixins } from "../styles/styles";
|
@@ -8,7 +8,7 @@ import { mixins } from "../styles/styles";
|
|
8
8
|
export const useEffectOnlyOnMount = [];
|
9
9
|
|
10
10
|
type stateExOptions<ValueType> = {
|
11
|
-
onChange?: (newValue:
|
11
|
+
onChange?: (newValue: ValueType, isValueChanged: boolean) => ValueType;
|
12
12
|
//will not set state if value did not change
|
13
13
|
skipUpdateIfSame?: boolean;
|
14
14
|
//optional, provide a name for better logging
|
@@ -38,8 +38,18 @@ export function useStateEX<ValueType>(initialValue: ValueType, options?: stateEx
|
|
38
38
|
let logger = GetLogger(`useStateWithTrack${isNullOrEmptyString(name) ? '' : ` ${name}`}`);
|
39
39
|
logger.setLevel(LoggerLevel.WARN);
|
40
40
|
|
41
|
-
const [value, setValueInState] = useState(initialValue);
|
42
|
-
|
41
|
+
const [value, setValueInState] = useState<ValueType>(initialValue);
|
42
|
+
|
43
|
+
const currentValue = useRef<ValueType>();
|
44
|
+
//json clone complex/ref values so we can compare if value changed, in case caller makes chagnes on the value object directly.
|
45
|
+
const currentValueForChecks = useRef<ValueType>();
|
46
|
+
useEffect(() => {
|
47
|
+
updateCurrentRef(initialValue);
|
48
|
+
}, useEffectOnlyOnMount);
|
49
|
+
|
50
|
+
//keep a ref to onChange so the caller's latet state is accessible
|
51
|
+
const onChange = useRef(options.onChange);
|
52
|
+
onChange.current = options.onChange;
|
43
53
|
|
44
54
|
/** make this a collection in case several callers are awaiting the same propr update */
|
45
55
|
const resolveState = useRef<((v: ValueType) => void)[]>([]);
|
@@ -62,53 +72,42 @@ export function useStateEX<ValueType>(initialValue: ValueType, options?: stateEx
|
|
62
72
|
};
|
63
73
|
useEffect(() => {
|
64
74
|
resolvePromises();
|
65
|
-
|
66
|
-
logger.log(`resolved after render`);
|
67
|
-
let resolvers = resolveState.current.slice();
|
68
|
-
resolveState.current = [];//clear
|
69
|
-
resolvers.map(r => r(value));
|
70
|
-
}
|
71
|
-
}, [value, resolveState.current]);
|
75
|
+
}, [value]);
|
72
76
|
|
73
77
|
function getIsValueChanged(newValue: ValueType): boolean {
|
78
|
+
let error: Error = null;
|
74
79
|
let result: boolean;
|
75
|
-
|
80
|
+
try {
|
81
|
+
if (!objectsEqual(newValue as object, currentValueForChecks.current as object)) {
|
82
|
+
result = true;
|
83
|
+
}
|
84
|
+
else {
|
85
|
+
result = false;
|
86
|
+
}
|
87
|
+
} catch (e) {
|
88
|
+
error = e;
|
76
89
|
result = true;
|
77
90
|
}
|
78
|
-
else {
|
79
|
-
result = false;
|
80
|
-
}
|
81
91
|
|
82
92
|
return logger.groupSync(result ? 'value changed' : 'value not changed', log => {
|
83
93
|
if (logger.getLevel() === LoggerLevel.VERBOSE) {
|
84
|
-
log('old: ' + extractStringValue(
|
94
|
+
log('old: ' + extractStringValue(currentValueForChecks.current));
|
85
95
|
log('new: ' + extractStringValue(newValue));
|
96
|
+
if (error) log({ label: "Error", value: error });
|
86
97
|
}
|
87
98
|
return result;
|
88
99
|
});
|
89
100
|
};
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
if (isValueChanged) {
|
94
|
-
setValueInState(newValue);
|
95
|
-
}
|
96
|
-
else {
|
97
|
-
resolvePromises();
|
98
|
-
}
|
99
|
-
}
|
100
|
-
|
101
|
-
|
102
|
-
let setValueWithEvents = wrapFunction(setValueWithCheck, {
|
103
|
-
before: (newValue: ValueType) => isFunction(options.onChange) ? options.onChange(newValue, getIsValueChanged(newValue)) : newValue,
|
104
|
-
after: (newValue: ValueType) => currentValue.current = isPrimitiveValue(newValue) || isFunction(newValue)
|
101
|
+
function updateCurrentRef(newValue: ValueType) {
|
102
|
+
currentValue.current = newValue;
|
103
|
+
currentValueForChecks.current = isPrimitiveValue(newValue) || isFunction(newValue)
|
105
104
|
? newValue
|
106
105
|
//fix skipUpdateIfSame for complex objects
|
107
106
|
//if we don't clone it, currentValue.current will be a ref to the value in the owner
|
108
107
|
//and will be treated as unchanged object, and it will be out of sync
|
109
108
|
//this leads to skipUpdateIfSame failing after just 1 unchanged update
|
110
|
-
: jsonClone(newValue) as ValueType
|
111
|
-
}
|
109
|
+
: jsonClone(newValue) as ValueType;
|
110
|
+
}
|
112
111
|
|
113
112
|
const setValue = useCallback((newState: ValueType) => new Promise<ValueType>(resolve => {
|
114
113
|
if (!isMounted.current) {
|
@@ -118,9 +117,22 @@ export function useStateEX<ValueType>(initialValue: ValueType, options?: stateEx
|
|
118
117
|
}
|
119
118
|
else {
|
120
119
|
resolveState.current.push(resolve);
|
121
|
-
|
120
|
+
const isChanged = isFunction(onChange.current) || options.skipUpdateIfSame
|
121
|
+
? getIsValueChanged(newState)//don't call this if there is no onChange handler and if we don't need to monitor skipUpdateIfSame
|
122
|
+
: true;
|
123
|
+
if (isFunction(onChange.current))
|
124
|
+
newState = onChange.current(newState, isChanged);
|
125
|
+
|
126
|
+
//keep current value ref up to date
|
127
|
+
updateCurrentRef(newState);
|
128
|
+
|
129
|
+
//set state
|
130
|
+
if (!options.skipUpdateIfSame || isChanged)
|
131
|
+
setValueInState(newState);
|
132
|
+
else//don't set in state - just resolve pending promises, UI will not be updated.
|
133
|
+
resolvePromises();
|
122
134
|
}
|
123
|
-
}),
|
135
|
+
}), useEffectOnlyOnMount);
|
124
136
|
|
125
137
|
return [value, setValue, currentValue];
|
126
138
|
}
|