@etsoo/react 1.7.94 → 1.7.95

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.
Files changed (93) hide show
  1. package/README.md +2 -1
  2. package/__tests__/EventWatcher.tsx +21 -21
  3. package/__tests__/ReactUtils.ts +4 -4
  4. package/__tests__/tsconfig.json +17 -17
  5. package/babel.config.json +8 -8
  6. package/lib/app/CoreConstants.js +2 -2
  7. package/lib/app/EventWatcher.d.ts +1 -1
  8. package/lib/app/EventWatcher.js +3 -5
  9. package/lib/app/InputDialogProps.d.ts +2 -2
  10. package/lib/app/ReactUtils.d.ts +2 -2
  11. package/lib/app/ReactUtils.js +20 -19
  12. package/lib/components/DnDList.d.ts +3 -3
  13. package/lib/components/DnDList.js +4 -4
  14. package/lib/components/DynamicRouter.d.ts +2 -2
  15. package/lib/components/DynamicRouter.js +2 -2
  16. package/lib/components/GridColumn.d.ts +6 -6
  17. package/lib/components/GridColumn.js +7 -7
  18. package/lib/components/GridLoader.d.ts +4 -4
  19. package/lib/components/GridLoader.js +2 -2
  20. package/lib/components/GridMethodRef.d.ts +2 -2
  21. package/lib/components/ListItemReact.d.ts +2 -2
  22. package/lib/components/ScrollRestoration.js +3 -3
  23. package/lib/components/ScrollerGrid.d.ts +7 -12
  24. package/lib/components/ScrollerGrid.js +13 -17
  25. package/lib/components/ScrollerList.d.ts +6 -10
  26. package/lib/components/ScrollerList.js +15 -14
  27. package/lib/custom/CustomFieldReact.d.ts +1 -1
  28. package/lib/index.d.ts +32 -32
  29. package/lib/index.js +31 -31
  30. package/lib/notifier/Notifier.d.ts +5 -5
  31. package/lib/notifier/Notifier.js +7 -7
  32. package/lib/states/CultureState.d.ts +3 -3
  33. package/lib/states/CultureState.js +3 -3
  34. package/lib/states/IState.d.ts +2 -2
  35. package/lib/states/PageState.d.ts +2 -2
  36. package/lib/states/PageState.js +2 -3
  37. package/lib/states/State.d.ts +3 -3
  38. package/lib/states/State.js +2 -2
  39. package/lib/states/UserState.d.ts +2 -2
  40. package/lib/states/UserState.js +5 -5
  41. package/lib/uses/useAsyncState.d.ts +1 -1
  42. package/lib/uses/useAsyncState.js +1 -1
  43. package/lib/uses/useCombinedRefs.js +2 -2
  44. package/lib/uses/useDelayedExecutor.d.ts +1 -1
  45. package/lib/uses/useDelayedExecutor.js +2 -2
  46. package/lib/uses/useDimensions.d.ts +1 -1
  47. package/lib/uses/useDimensions.js +3 -3
  48. package/lib/uses/useParamsEx.d.ts +1 -1
  49. package/lib/uses/useParamsEx.js +2 -2
  50. package/lib/uses/useRefs.d.ts +2 -2
  51. package/lib/uses/useRefs.js +1 -1
  52. package/lib/uses/useSearchParamsEx.d.ts +1 -1
  53. package/lib/uses/useSearchParamsEx.js +3 -3
  54. package/lib/uses/useTimeout.js +2 -2
  55. package/lib/uses/useWindowScroll.js +3 -3
  56. package/lib/uses/useWindowSize.js +4 -5
  57. package/package.json +72 -74
  58. package/src/app/CoreConstants.ts +8 -8
  59. package/src/app/EventWatcher.ts +50 -52
  60. package/src/app/InputDialogProps.ts +16 -16
  61. package/src/app/ReactUtils.ts +206 -208
  62. package/src/components/DnDList.tsx +268 -283
  63. package/src/components/DynamicRouter.tsx +35 -35
  64. package/src/components/GridColumn.ts +201 -201
  65. package/src/components/GridLoader.ts +121 -121
  66. package/src/components/GridMethodRef.ts +26 -26
  67. package/src/components/ListItemReact.ts +2 -2
  68. package/src/components/ScrollRestoration.tsx +24 -24
  69. package/src/components/ScrollerGrid.tsx +428 -448
  70. package/src/components/ScrollerList.tsx +320 -332
  71. package/src/custom/CustomFieldReact.ts +12 -12
  72. package/src/index.ts +35 -35
  73. package/src/notifier/Notifier.ts +229 -240
  74. package/src/states/CultureState.ts +51 -52
  75. package/src/states/IState.ts +19 -19
  76. package/src/states/PageState.ts +63 -66
  77. package/src/states/State.tsx +47 -51
  78. package/src/states/UserState.ts +98 -98
  79. package/src/uses/useAsyncState.ts +37 -39
  80. package/src/uses/useCombinedRefs.ts +16 -16
  81. package/src/uses/useDelayedExecutor.ts +8 -8
  82. package/src/uses/useDimensions.ts +102 -103
  83. package/src/uses/useParamsEx.ts +6 -6
  84. package/src/uses/useRefs.ts +6 -6
  85. package/src/uses/useSearchParamsEx.ts +13 -13
  86. package/src/uses/useTimeout.ts +17 -17
  87. package/src/uses/useWindowScroll.ts +43 -43
  88. package/src/uses/useWindowSize.ts +46 -49
  89. package/tsconfig.json +17 -17
  90. package/.eslintignore +0 -3
  91. package/.eslintrc.json +0 -38
  92. package/.prettierignore +0 -5
  93. package/.prettierrc +0 -6
@@ -1,221 +1,219 @@
1
- import { DataTypes, DateUtils, DomUtils, Utils } from '@etsoo/shared';
2
- import React from 'react';
1
+ import { DataTypes, DateUtils, DomUtils, Utils } from "@etsoo/shared";
2
+ import React from "react";
3
3
 
4
4
  /**
5
5
  * React utils
6
6
  */
7
7
  export namespace ReactUtils {
8
- /**
9
- * Format input value
10
- * @param value Input value
11
- * @returns Formatted value
12
- */
13
- export function formatInputValue(value: unknown) {
14
- if (value === null) return undefined;
15
-
16
- if (typeof value === 'number') return value;
17
-
18
- if (typeof value === 'string') return value;
19
-
20
- if (Array.isArray(value)) return value;
21
-
22
- return String(value);
8
+ /**
9
+ * Format input value
10
+ * @param value Input value
11
+ * @returns Formatted value
12
+ */
13
+ export function formatInputValue(value: unknown) {
14
+ if (value === null) return undefined;
15
+
16
+ if (typeof value === "number") return value;
17
+
18
+ if (typeof value === "string") return value;
19
+
20
+ if (Array.isArray(value)) return value;
21
+
22
+ return String(value);
23
+ }
24
+
25
+ /**
26
+ * Is safe click
27
+ * @param event Mouse event
28
+ * @returns Result
29
+ */
30
+ export function isSafeClick(event: React.MouseEvent<HTMLElement>) {
31
+ // No target
32
+ // HTMLElement <= Element, SVGElement <= Element
33
+ if (!(event.target instanceof Element)) return true;
34
+
35
+ // Outside of the currentTarget
36
+ let target: Element | null = event.target;
37
+ if (!event.currentTarget.contains(target)) return false;
38
+
39
+ while (target != null && target != event.currentTarget) {
40
+ const nodeName = target.nodeName.toUpperCase();
41
+ if (
42
+ nodeName === "INPUT" ||
43
+ nodeName === "BUTTON" ||
44
+ nodeName === "A" ||
45
+ target.hasAttribute("onClick")
46
+ )
47
+ return false;
48
+
49
+ target = target.parentElement;
23
50
  }
24
51
 
25
- /**
26
- * Is safe click
27
- * @param event Mouse event
28
- * @returns Result
29
- */
30
- export function isSafeClick(event: React.MouseEvent<HTMLElement>) {
31
- // No target
32
- // HTMLElement <= Element, SVGElement <= Element
33
- if (!(event.target instanceof Element)) return true;
34
-
35
- // Outside of the currentTarget
36
- let target: Element | null = event.target;
37
- if (!event.currentTarget.contains(target)) return false;
38
-
39
- while (target != null && target != event.currentTarget) {
40
- const nodeName = target.nodeName.toUpperCase();
41
- if (
42
- nodeName === 'INPUT' ||
43
- nodeName === 'BUTTON' ||
44
- nodeName === 'A' ||
45
- target.hasAttribute('onClick')
46
- )
47
- return false;
48
-
49
- target = target.parentElement;
50
- }
51
-
52
- return true;
52
+ return true;
53
+ }
54
+
55
+ /**
56
+ * Trigger input change event
57
+ * @param input Form input
58
+ * @param value New value
59
+ * @param cancelable Cancelable
60
+ */
61
+ export function triggerChange(
62
+ input: HTMLInputElement,
63
+ value: string,
64
+ cancelable: boolean = false
65
+ ) {
66
+ // Radio type not supported
67
+ if (input.type === "radio") return;
68
+
69
+ // checked?
70
+ const checked = input.type === "checkbox";
71
+
72
+ // Property name
73
+ const property = checked ? "checked" : "value";
74
+
75
+ // input.value = newValue will not trigger the change event
76
+ // input type = 'hidden' will also not trigger the event
77
+ // https://coryrylan.com/blog/trigger-input-updates-with-react-controlled-inputs
78
+ var nativeInputValueSetter = Object.getOwnPropertyDescriptor(
79
+ HTMLInputElement.prototype,
80
+ property
81
+ )?.set;
82
+
83
+ if (checked) {
84
+ const checkedValue = input.value == value;
85
+ nativeInputValueSetter?.call(input, checkedValue);
86
+
87
+ const clickEvent = new Event("click", {
88
+ bubbles: true,
89
+ cancelable
90
+ });
91
+ input.dispatchEvent(clickEvent);
92
+ } else {
93
+ nativeInputValueSetter?.call(input, value);
94
+
95
+ const inputEvent = new Event("change", {
96
+ bubbles: true,
97
+ cancelable
98
+ });
99
+ input.dispatchEvent(inputEvent);
53
100
  }
54
-
55
- /**
56
- * Trigger input change event
57
- * @param input Form input
58
- * @param value New value
59
- * @param cancelable Cancelable
60
- */
61
- export function triggerChange(
62
- input: HTMLInputElement,
63
- value: string,
64
- cancelable: boolean = false
65
- ) {
66
- // Radio type not supported
67
- if (input.type === 'radio') return;
68
-
69
- // checked?
70
- const checked = input.type === 'checkbox';
71
-
72
- // Property name
73
- const property = checked ? 'checked' : 'value';
74
-
75
- // input.value = newValue will not trigger the change event
76
- // input type = 'hidden' will also not trigger the event
77
- // https://coryrylan.com/blog/trigger-input-updates-with-react-controlled-inputs
78
- var nativeInputValueSetter = Object.getOwnPropertyDescriptor(
79
- HTMLInputElement.prototype,
80
- property
81
- )?.set;
82
-
83
- if (checked) {
84
- const checkedValue = input.value == value;
85
- nativeInputValueSetter?.call(input, checkedValue);
86
-
87
- const clickEvent = new Event('click', {
88
- bubbles: true,
89
- cancelable
90
- });
91
- input.dispatchEvent(clickEvent);
101
+ }
102
+
103
+ /**
104
+ * Update refs
105
+ * @param refs Refs
106
+ * @param data Data
107
+ * @param callback Callback to update refs' value, return false continue to process
108
+ */
109
+ export function updateRefs<D extends object, T = HTMLInputElement>(
110
+ refs: Partial<
111
+ DataTypes.DI<
112
+ ReadonlyArray<keyof D & string>,
113
+ React.MutableRefObject<T | null>
114
+ >
115
+ >,
116
+ data: D,
117
+ callback?:
118
+ | ((item: T, value: D[keyof D & string]) => void | boolean)
119
+ | keyof T
120
+ ) {
121
+ const local: typeof callback =
122
+ callback == null
123
+ ? undefined
124
+ : typeof callback === "function"
125
+ ? callback
126
+ : (item, value) => {
127
+ item[callback] = value as any;
128
+ };
129
+
130
+ let k: keyof typeof refs;
131
+ for (k in refs) {
132
+ const ref = refs[k];
133
+ const item = ref?.current;
134
+ if (item == null) continue;
135
+
136
+ if (local && local(item, data[k]) !== false) {
137
+ continue;
138
+ } else if (
139
+ item instanceof HTMLInputElement ||
140
+ item instanceof HTMLTextAreaElement ||
141
+ item instanceof HTMLSelectElement
142
+ ) {
143
+ const value = Utils.getNestedValue(data, item.name || k);
144
+
145
+ const isDateTime = item.type === "datetime-local";
146
+ if (isDateTime || item.type === "date") {
147
+ item.value =
148
+ DateUtils.formatForInput(value, isDateTime ? false : undefined) ??
149
+ "";
92
150
  } else {
93
- nativeInputValueSetter?.call(input, value);
94
-
95
- const inputEvent = new Event('change', {
96
- bubbles: true,
97
- cancelable
98
- });
99
- input.dispatchEvent(inputEvent);
100
- }
101
- }
102
-
103
- /**
104
- * Update refs
105
- * @param refs Refs
106
- * @param data Data
107
- * @param callback Callback to update refs' value, return false continue to process
108
- */
109
- export function updateRefs<D extends object, T = HTMLInputElement>(
110
- refs: Partial<
111
- DataTypes.DI<
112
- ReadonlyArray<keyof D & string>,
113
- React.MutableRefObject<T | null>
114
- >
115
- >,
116
- data: D,
117
- callback?:
118
- | ((item: T, value: D[keyof D & string]) => void | boolean)
119
- | keyof T
120
- ) {
121
- const local: typeof callback =
122
- callback == null
123
- ? undefined
124
- : typeof callback === 'function'
125
- ? callback
126
- : (item, value) => {
127
- item[callback] = value as any;
128
- };
129
-
130
- let k: keyof typeof refs;
131
- for (k in refs) {
132
- const ref = refs[k];
133
- const item = ref?.current;
134
- if (item == null) continue;
135
-
136
- if (local && local(item, data[k]) !== false) {
137
- continue;
138
- } else if (
139
- item instanceof HTMLInputElement ||
140
- item instanceof HTMLTextAreaElement ||
141
- item instanceof HTMLSelectElement
142
- ) {
143
- const value = Utils.getNestedValue(data, item.name || k);
144
-
145
- const isDateTime = item.type === 'datetime-local';
146
- if (isDateTime || item.type === 'date') {
147
- item.value =
148
- DateUtils.formatForInput(
149
- value,
150
- isDateTime ? false : undefined
151
- ) ?? '';
152
- } else {
153
- item.value = `${value ?? ''}`;
154
- }
155
- } else {
156
- (item as any).value = data[k];
157
- }
151
+ item.value = `${value ?? ""}`;
158
152
  }
153
+ } else {
154
+ (item as any).value = data[k];
155
+ }
159
156
  }
160
-
161
- /**
162
- * Update data with refs
163
- * @param refs Refs
164
- * @param data Data
165
- * @param callback Callback to return new value
166
- * @param ignoreEmpty Ignore empty string or not, default true
167
- */
168
- export function updateRefValues<D extends object, T = HTMLInputElement>(
169
- refs: Partial<
170
- DataTypes.DI<
171
- ReadonlyArray<keyof D & string>,
172
- React.MutableRefObject<T | null>
173
- >
174
- >,
175
- data: D,
176
- callback?: ((item: T) => any) | keyof T,
177
- ignoreEmpty: boolean = true
178
- ) {
179
- const local: typeof callback =
180
- callback == null
181
- ? undefined
182
- : typeof callback === 'function'
183
- ? callback
184
- : (item) => item[callback];
185
-
186
- const formatValue = (value: unknown) => {
187
- if (ignoreEmpty && value === '') return null;
188
- return value;
189
- };
190
-
191
- let k: keyof typeof refs;
192
- for (k in refs) {
193
- const ref = refs[k];
194
- const item = ref?.current;
195
- if (item == null) continue;
196
-
197
- if (local) {
198
- data[k] = local(item);
199
- } else if (item instanceof HTMLInputElement) {
200
- Utils.setNestedValue(
201
- data,
202
- item.name || k,
203
- formatValue(DomUtils.getInputValue(item)),
204
- true
205
- );
206
- } else if (
207
- item instanceof HTMLTextAreaElement ||
208
- item instanceof HTMLSelectElement
209
- ) {
210
- Utils.setNestedValue(
211
- data,
212
- item.name || k,
213
- formatValue(item.value),
214
- true
215
- );
216
- } else {
217
- data[k] = (item as any).value;
218
- }
219
- }
157
+ }
158
+
159
+ /**
160
+ * Update data with refs
161
+ * @param refs Refs
162
+ * @param data Data
163
+ * @param callback Callback to return new value
164
+ * @param ignoreEmpty Ignore empty string or not, default true
165
+ */
166
+ export function updateRefValues<D extends object, T = HTMLInputElement>(
167
+ refs: Partial<
168
+ DataTypes.DI<
169
+ ReadonlyArray<keyof D & string>,
170
+ React.MutableRefObject<T | null>
171
+ >
172
+ >,
173
+ data: D,
174
+ callback?: ((item: T) => any) | keyof T,
175
+ ignoreEmpty: boolean = true
176
+ ) {
177
+ const local: typeof callback =
178
+ callback == null
179
+ ? undefined
180
+ : typeof callback === "function"
181
+ ? callback
182
+ : (item) => item[callback];
183
+
184
+ const formatValue = (value: unknown) => {
185
+ if (ignoreEmpty && value === "") return null;
186
+ return value;
187
+ };
188
+
189
+ let k: keyof typeof refs;
190
+ for (k in refs) {
191
+ const ref = refs[k];
192
+ const item = ref?.current;
193
+ if (item == null) continue;
194
+
195
+ if (local) {
196
+ data[k] = local(item);
197
+ } else if (item instanceof HTMLInputElement) {
198
+ Utils.setNestedValue(
199
+ data,
200
+ item.name || k,
201
+ formatValue(DomUtils.getInputValue(item)),
202
+ true
203
+ );
204
+ } else if (
205
+ item instanceof HTMLTextAreaElement ||
206
+ item instanceof HTMLSelectElement
207
+ ) {
208
+ Utils.setNestedValue(
209
+ data,
210
+ item.name || k,
211
+ formatValue(item.value),
212
+ true
213
+ );
214
+ } else {
215
+ data[k] = (item as any).value;
216
+ }
220
217
  }
218
+ }
221
219
  }