react-hook-core 0.0.1 → 0.1.0
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/components.js +370 -486
- package/lib/core.js +89 -27
- package/lib/diff.js +3 -0
- package/lib/edit.js +35 -33
- package/lib/formutil.js +5 -2
- package/lib/index.js +7 -0
- package/lib/merge.js +1 -1
- package/lib/state.js +17 -10
- package/lib/update.js +36 -55
- package/lib/useEdit.js +181 -327
- package/lib/useMessage.js +25 -0
- package/lib/useSearch.js +118 -238
- package/lib/useView.js +70 -161
- package/lib/util.js +6 -2
- package/package.json +7 -9
- package/src/components.ts +345 -301
- package/src/core.ts +110 -49
- package/src/diff.ts +4 -1
- package/src/edit.ts +44 -42
- package/src/formutil.ts +7 -4
- package/src/index.ts +8 -0
- package/src/merge.ts +3 -3
- package/src/state.ts +25 -19
- package/src/update.ts +35 -58
- package/src/useEdit.ts +165 -244
- package/src/useMessage.ts +37 -0
- package/src/useSearch.ts +145 -225
- package/src/useView.ts +64 -101
- package/src/util.ts +8 -4
- package/tsconfig.json +1 -0
package/src/core.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as H from 'history';
|
|
2
|
+
import {RouteComponentProps} from 'react-router';
|
|
2
3
|
import {match} from 'react-router-dom';
|
|
3
4
|
import {focusFirstElement} from './formutil';
|
|
4
5
|
|
|
@@ -76,7 +77,7 @@ export function createDiffStatus(status?: DiffStatusConfig): DiffStatusConfig {
|
|
|
76
77
|
return s;
|
|
77
78
|
}
|
|
78
79
|
|
|
79
|
-
export interface
|
|
80
|
+
export interface Filter {
|
|
80
81
|
q?: string;
|
|
81
82
|
page?: number;
|
|
82
83
|
limit?: number;
|
|
@@ -90,12 +91,12 @@ export interface SearchResult<T> {
|
|
|
90
91
|
nextPageToken?: string;
|
|
91
92
|
last?: boolean;
|
|
92
93
|
}
|
|
93
|
-
export interface SearchState<T, S extends
|
|
94
|
+
export interface SearchState<T, S extends Filter> {
|
|
94
95
|
model?: S;
|
|
95
96
|
q?: string;
|
|
96
97
|
list?: T[];
|
|
97
98
|
}
|
|
98
|
-
export interface SearchService<T, S extends
|
|
99
|
+
export interface SearchService<T, S extends Filter> {
|
|
99
100
|
keys?(): string[];
|
|
100
101
|
search(s: S, limit?: number, offset?: number|string, fields?: string[]): Promise<SearchResult<T>>;
|
|
101
102
|
}
|
|
@@ -156,8 +157,14 @@ export class resource {
|
|
|
156
157
|
static _cache: any = {};
|
|
157
158
|
static cache = true;
|
|
158
159
|
}
|
|
159
|
-
export function getCurrencyCode(form
|
|
160
|
-
|
|
160
|
+
export function getCurrencyCode(form?: HTMLFormElement|null): string|undefined {
|
|
161
|
+
if (form) {
|
|
162
|
+
const x = form.getAttribute('currency-code');
|
|
163
|
+
if (x) {
|
|
164
|
+
return x;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return undefined;
|
|
161
168
|
}
|
|
162
169
|
export function removePhoneFormat(phone: string): string {
|
|
163
170
|
if (phone) {
|
|
@@ -176,33 +183,38 @@ export interface ResourceService {
|
|
|
176
183
|
}
|
|
177
184
|
export interface Message {
|
|
178
185
|
message: string;
|
|
179
|
-
title
|
|
186
|
+
title: string;
|
|
180
187
|
yes?: string;
|
|
181
188
|
no?: string;
|
|
182
189
|
}
|
|
183
|
-
export function
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (title && title.length > 0) {
|
|
189
|
-
m.title = gv(title);
|
|
190
|
-
}
|
|
191
|
-
if (yes && yes.length > 0) {
|
|
192
|
-
m.yes = gv(yes);
|
|
193
|
-
}
|
|
194
|
-
if (no && no.length > 0) {
|
|
195
|
-
m.no = gv(no);
|
|
190
|
+
export function getString(key: string, gv: StringMap|((key: string) => string)): string {
|
|
191
|
+
if (typeof gv === 'function') {
|
|
192
|
+
return gv(key);
|
|
193
|
+
} else {
|
|
194
|
+
return gv[key];
|
|
196
195
|
}
|
|
197
|
-
return m;
|
|
198
196
|
}
|
|
199
|
-
export function
|
|
197
|
+
export function message(gv: StringMap|((key: string) => string), msg: string, title?: string, yes?: string, no?: string): Message {
|
|
198
|
+
const m2 = (msg && msg.length > 0 ? getString(msg, gv) : '');
|
|
199
|
+
const m: Message = { message: m2, title: '' };
|
|
200
|
+
if (title && title.length > 0) {
|
|
201
|
+
m.title = getString(title, gv);
|
|
202
|
+
}
|
|
203
|
+
if (yes && yes.length > 0) {
|
|
204
|
+
m.yes = getString(yes, gv);
|
|
205
|
+
}
|
|
206
|
+
if (no && no.length > 0) {
|
|
207
|
+
m.no = getString(no, gv);
|
|
208
|
+
}
|
|
209
|
+
return m;
|
|
210
|
+
}
|
|
211
|
+
export function messageByHttpStatus(status: number, gv: StringMap|((key: string) => string)): string {
|
|
200
212
|
const k = 'status_' + status;
|
|
201
|
-
let msg =
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
213
|
+
let msg = getString(k, gv);
|
|
214
|
+
if (!msg || msg.length === 0) {
|
|
215
|
+
msg = getString('error_internal', gv);
|
|
216
|
+
}
|
|
217
|
+
return msg;
|
|
206
218
|
}
|
|
207
219
|
|
|
208
220
|
export interface Locale {
|
|
@@ -230,20 +242,21 @@ export interface ErrorMessage {
|
|
|
230
242
|
}
|
|
231
243
|
export interface UIService {
|
|
232
244
|
getValue(el: HTMLInputElement, locale?: Locale, currencyCode?: string): string|number|boolean;
|
|
233
|
-
decodeFromForm(form: HTMLFormElement, locale?: Locale, currencyCode?: string): any;
|
|
245
|
+
decodeFromForm(form: HTMLFormElement, locale?: Locale, currencyCode?: string|null): any;
|
|
234
246
|
|
|
235
|
-
validateForm(form
|
|
247
|
+
validateForm(form?: HTMLFormElement, locale?: Locale, focusFirst?: boolean, scroll?: boolean): boolean;
|
|
236
248
|
removeFormError(form: HTMLFormElement): void;
|
|
237
249
|
removeError(el: HTMLInputElement): void;
|
|
238
|
-
showFormError(form
|
|
250
|
+
showFormError(form?: HTMLFormElement, errors?: ErrorMessage[], focusFirst?: boolean): ErrorMessage[];
|
|
239
251
|
buildErrorMessage(errors: ErrorMessage[]): string;
|
|
240
252
|
|
|
241
253
|
registerEvents?(form: HTMLFormElement): void;
|
|
242
254
|
}
|
|
243
255
|
|
|
244
256
|
export type DataType = 'ObjectId' | 'date' | 'datetime' | 'time'
|
|
245
|
-
|
|
246
|
-
|
|
257
|
+
| 'boolean' | 'number' | 'integer' | 'string' | 'text'
|
|
258
|
+
| 'object' | 'array' | 'binary'
|
|
259
|
+
| 'primitives' | 'booleans' | 'numbers' | 'integers' | 'strings' | 'dates' | 'datetimes' | 'times';
|
|
247
260
|
/*
|
|
248
261
|
export interface Metadata {
|
|
249
262
|
name?: string;
|
|
@@ -277,11 +290,11 @@ export function buildKeys(attributes: Attributes): string[] {
|
|
|
277
290
|
return ps;
|
|
278
291
|
}
|
|
279
292
|
|
|
280
|
-
export function buildId<ID>(props:
|
|
293
|
+
export function buildId<ID>(props: RouteComponentProps, keys?: string[]): ID|null {
|
|
281
294
|
if (!props) {
|
|
282
295
|
return null;
|
|
283
296
|
}
|
|
284
|
-
const sp = (props.match ? props : props['props']);
|
|
297
|
+
const sp: any = ((props as any).match ? props : (props as any)['props']);
|
|
285
298
|
if (!keys || keys.length === 0 || keys.length === 1) {
|
|
286
299
|
if (keys && keys.length === 1) {
|
|
287
300
|
const x = sp.match.params[keys[0]];
|
|
@@ -401,7 +414,10 @@ export function error(err: any, gv: (key: string) => string, ae: (msg: string, h
|
|
|
401
414
|
ae(msg, title);
|
|
402
415
|
}
|
|
403
416
|
}
|
|
404
|
-
export function
|
|
417
|
+
export function getName(d: string, n?: string): string {
|
|
418
|
+
return (n && n.length > 0 ? n : d);
|
|
419
|
+
}
|
|
420
|
+
export function getModelName(form?: HTMLFormElement|null, name?: string): string {
|
|
405
421
|
if (form) {
|
|
406
422
|
const a = form.getAttribute('model-name');
|
|
407
423
|
if (a && a.length > 0) {
|
|
@@ -415,28 +431,73 @@ export function getModelName(form: HTMLFormElement): string {
|
|
|
415
431
|
return b;
|
|
416
432
|
}
|
|
417
433
|
}
|
|
434
|
+
if (name && name.length > 0) {
|
|
435
|
+
return name;
|
|
436
|
+
}
|
|
418
437
|
return '';
|
|
419
438
|
}
|
|
420
439
|
|
|
421
440
|
export const scrollToFocus = (e: any, isUseTimeOut?: boolean) => {
|
|
422
441
|
try {
|
|
423
442
|
const element = e.target as HTMLInputElement;
|
|
424
|
-
const
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
443
|
+
const form = element.form;
|
|
444
|
+
if (form) {
|
|
445
|
+
const container = form.childNodes[1] as HTMLElement;
|
|
446
|
+
const elementRect = element.getBoundingClientRect();
|
|
447
|
+
const absoluteElementTop = elementRect.top + window.pageYOffset;
|
|
448
|
+
const middle = absoluteElementTop - (window.innerHeight / 2);
|
|
449
|
+
const scrollTop = container.scrollTop;
|
|
450
|
+
const timeOut = isUseTimeOut ? 300 : 0;
|
|
451
|
+
const isChrome = navigator.userAgent.search('Chrome') > 0;
|
|
452
|
+
setTimeout(() => {
|
|
453
|
+
if (isChrome) {
|
|
454
|
+
const scrollPosition = scrollTop === 0 ? (elementRect.top + 64) : (scrollTop + middle);
|
|
455
|
+
container.scrollTo(0, Math.abs(scrollPosition));
|
|
456
|
+
} else {
|
|
457
|
+
container.scrollTo(0, Math.abs(scrollTop + middle));
|
|
458
|
+
}
|
|
459
|
+
}, timeOut);
|
|
460
|
+
}
|
|
439
461
|
} catch (e) {
|
|
440
462
|
console.log(e);
|
|
441
463
|
}
|
|
442
464
|
};
|
|
465
|
+
export interface LoadingParameter {
|
|
466
|
+
loading?: LoadingService;
|
|
467
|
+
}
|
|
468
|
+
export function showLoading(s?: LoadingService): void {
|
|
469
|
+
if (s) {
|
|
470
|
+
s.showLoading();
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
export function hideLoading(s?: LoadingService): void {
|
|
474
|
+
if (s) {
|
|
475
|
+
s.hideLoading();
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
export interface UIParameter {
|
|
479
|
+
ui?: UIService;
|
|
480
|
+
}
|
|
481
|
+
export function getRemoveError(u?: UIParameter, rmErr?: (el: HTMLInputElement) => void): ((el: HTMLInputElement) => void)|undefined {
|
|
482
|
+
if (rmErr) {
|
|
483
|
+
return rmErr;
|
|
484
|
+
}
|
|
485
|
+
return (u && u.ui ? u.ui.removeError : undefined);
|
|
486
|
+
}
|
|
487
|
+
export function removeFormError(u?: UIParameter, f?: HTMLFormElement): void {
|
|
488
|
+
if (f && u && u.ui) {
|
|
489
|
+
u.ui.removeFormError(f);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
export function getValidateForm(u?: UIParameter, vf?: (form: HTMLFormElement, locale?: Locale, focusFirst?: boolean, scroll?: boolean) => boolean): ((form: HTMLFormElement, locale?: Locale, focusFirst?: boolean, scroll?: boolean) => boolean)|undefined {
|
|
493
|
+
if (vf) {
|
|
494
|
+
return vf;
|
|
495
|
+
}
|
|
496
|
+
return (u && u.ui ? u.ui.validateForm : undefined);
|
|
497
|
+
}
|
|
498
|
+
export function getDecodeFromForm(u?: UIParameter, d?: (form: HTMLFormElement, locale?: Locale, currencyCode?: string) => any): ((form: HTMLFormElement, locale?: Locale, currencyCode?: string) => any)|undefined {
|
|
499
|
+
if (d) {
|
|
500
|
+
return d;
|
|
501
|
+
}
|
|
502
|
+
return (u && u.ui ? u.ui.decodeFromForm : undefined);
|
|
503
|
+
}
|
package/src/diff.ts
CHANGED
|
@@ -29,8 +29,11 @@ export function formatDiffModel<T, ID>(obj: DiffModel<T, ID>, formatFields?: (ob
|
|
|
29
29
|
return obj2;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
export function getDataFields(form
|
|
32
|
+
export function getDataFields(form?: HTMLElement|null): HTMLElement[] {
|
|
33
33
|
let results: HTMLElement[] = [];
|
|
34
|
+
if (!form) {
|
|
35
|
+
return results;
|
|
36
|
+
}
|
|
34
37
|
const attributeValue = form.getAttribute('data-field');
|
|
35
38
|
if (attributeValue && attributeValue.length > 0) {
|
|
36
39
|
results.push(form);
|
package/src/edit.ts
CHANGED
|
@@ -10,7 +10,7 @@ export interface EditParameter {
|
|
|
10
10
|
resource: ResourceService;
|
|
11
11
|
showMessage: (msg: string, option?: string) => void;
|
|
12
12
|
showError: (m: string, header?: string, detail?: string, callback?: () => void) => void;
|
|
13
|
-
confirm: (m2: string, header
|
|
13
|
+
confirm: (m2: string, header?: string, yesCallback?: () => void, btnLeftText?: string, btnRightText?: string, noCallback?: () => void) => void;
|
|
14
14
|
ui?: UIService;
|
|
15
15
|
getLocale?: (profile?: string) => Locale;
|
|
16
16
|
loading?: LoadingService;
|
|
@@ -26,9 +26,9 @@ export interface MetaModel {
|
|
|
26
26
|
keys?: string[];
|
|
27
27
|
version?: string;
|
|
28
28
|
}
|
|
29
|
-
export function build(attributes: Attributes, name?: string): MetaModel {
|
|
29
|
+
export function build(attributes: Attributes, name?: string): MetaModel|undefined {
|
|
30
30
|
if (!attributes) {
|
|
31
|
-
return
|
|
31
|
+
return undefined;
|
|
32
32
|
}
|
|
33
33
|
if (resource.cache && name && name.length > 0) {
|
|
34
34
|
let meta: MetaModel = resource._cache[name];
|
|
@@ -77,53 +77,55 @@ export function createModel<T>(attributes?: Attributes): T {
|
|
|
77
77
|
const attrs = Object.keys(attributes);
|
|
78
78
|
for (const k of attrs) {
|
|
79
79
|
const attr = attributes[k];
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
case 'integer':
|
|
86
|
-
case 'number':
|
|
87
|
-
obj[attr.name] = 0;
|
|
88
|
-
break;
|
|
89
|
-
case 'array':
|
|
90
|
-
obj[attr.name] = [];
|
|
91
|
-
break;
|
|
92
|
-
case 'boolean':
|
|
93
|
-
obj[attr.name] = false;
|
|
94
|
-
break;
|
|
95
|
-
case 'date':
|
|
96
|
-
obj[attr.name] = new Date();
|
|
97
|
-
break;
|
|
98
|
-
case 'object':
|
|
99
|
-
if (attr.typeof) {
|
|
100
|
-
const object = createModel(attr.typeof);
|
|
101
|
-
obj[attr.name] = object;
|
|
80
|
+
if (attr.name) {
|
|
81
|
+
switch (attr.type) {
|
|
82
|
+
case 'string':
|
|
83
|
+
case 'text':
|
|
84
|
+
obj[attr.name] = '';
|
|
102
85
|
break;
|
|
103
|
-
|
|
104
|
-
|
|
86
|
+
case 'integer':
|
|
87
|
+
case 'number':
|
|
88
|
+
obj[attr.name] = 0;
|
|
105
89
|
break;
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
90
|
+
case 'array':
|
|
91
|
+
obj[attr.name] = [];
|
|
92
|
+
break;
|
|
93
|
+
case 'boolean':
|
|
94
|
+
obj[attr.name] = false;
|
|
95
|
+
break;
|
|
96
|
+
case 'date':
|
|
97
|
+
obj[attr.name] = new Date();
|
|
98
|
+
break;
|
|
99
|
+
case 'object':
|
|
100
|
+
if (attr.typeof) {
|
|
101
|
+
const object = createModel(attr.typeof);
|
|
102
|
+
obj[attr.name] = object;
|
|
103
|
+
break;
|
|
104
|
+
} else {
|
|
105
|
+
obj[attr.name] = {};
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
case 'ObjectId':
|
|
109
|
+
obj[attr.name] = null;
|
|
110
|
+
break;
|
|
111
|
+
default:
|
|
112
|
+
obj[attr.name] = '';
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
113
115
|
}
|
|
114
116
|
}
|
|
115
117
|
return obj;
|
|
116
118
|
}
|
|
117
119
|
|
|
118
|
-
export function initPropertyNullInModel<T>(obj: T, m
|
|
120
|
+
export function initPropertyNullInModel<T>(obj: T, m?: Attributes): T {
|
|
119
121
|
if (!m) {
|
|
120
122
|
const x: any = {};
|
|
121
123
|
return x;
|
|
122
124
|
}
|
|
123
125
|
const model = createModel(m);
|
|
124
|
-
for (const key of Object.keys(model)) {
|
|
125
|
-
if (obj && !obj.hasOwnProperty(key)) {
|
|
126
|
-
obj[key] = model[key];
|
|
126
|
+
for (const key of Object.keys(model as any)) {
|
|
127
|
+
if (obj && !(obj as any).hasOwnProperty(key)) {
|
|
128
|
+
(obj as any)[key] = (model as any)[key];
|
|
127
129
|
}
|
|
128
130
|
}
|
|
129
131
|
return obj;
|
|
@@ -138,13 +140,13 @@ export function handleStatus(x: number|string, st: EditStatusConfig, gv: (k: str
|
|
|
138
140
|
se(gv('error_internal'), title);
|
|
139
141
|
}
|
|
140
142
|
}
|
|
141
|
-
export function handleVersion<T>(obj: T, version
|
|
143
|
+
export function handleVersion<T>(obj: T, version?: string): void {
|
|
142
144
|
if (obj && version && version.length > 0) {
|
|
143
|
-
const v = obj[version];
|
|
145
|
+
const v = (obj as any)[version];
|
|
144
146
|
if (v && typeof v === 'number') {
|
|
145
|
-
obj[version] = v + 1;
|
|
147
|
+
(obj as any)[version] = v + 1;
|
|
146
148
|
} else {
|
|
147
|
-
obj[version] = 1;
|
|
149
|
+
(obj as any)[version] = 1;
|
|
148
150
|
}
|
|
149
151
|
}
|
|
150
152
|
}
|
package/src/formutil.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export function readOnly(form
|
|
1
|
+
export function readOnly(form?: HTMLFormElement|null): void {
|
|
2
2
|
if (!form) {
|
|
3
3
|
return;
|
|
4
4
|
}
|
|
@@ -64,14 +64,17 @@ export function focusFirstElement(form: HTMLFormElement): void {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
-
export function focusFirstError(form
|
|
67
|
+
export function focusFirstError(form?: HTMLFormElement|null, className?: string): void {
|
|
68
|
+
if (!form) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
68
71
|
const len = form.length;
|
|
69
72
|
if (className && className.length > 0) {
|
|
70
73
|
for (let i = 0; i < len; i++) {
|
|
71
74
|
const ctrl = form[i] as HTMLInputElement;
|
|
72
75
|
const parent = ctrl.parentElement;
|
|
73
76
|
if (ctrl.classList.contains(className)
|
|
74
|
-
|| parent.classList.contains(className)) {
|
|
77
|
+
|| parent && parent.classList.contains(className)) {
|
|
75
78
|
ctrl.focus();
|
|
76
79
|
ctrl.scrollIntoView();
|
|
77
80
|
return;
|
|
@@ -83,7 +86,7 @@ export function focusFirstError(form: HTMLFormElement, className?: string): void
|
|
|
83
86
|
const parent = ctrl.parentElement;
|
|
84
87
|
if (ctrl.classList.contains('invalid')
|
|
85
88
|
|| ctrl.classList.contains('.ng-invalid')
|
|
86
|
-
|| parent.classList.contains('invalid')) {
|
|
89
|
+
|| parent && parent.classList.contains('invalid')) {
|
|
87
90
|
ctrl.focus();
|
|
88
91
|
ctrl.scrollIntoView();
|
|
89
92
|
return;
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { RouteComponentProps } from 'react-router';
|
|
1
3
|
export * from './formutil';
|
|
2
4
|
export * from './util';
|
|
3
5
|
export * from './core';
|
|
@@ -12,3 +14,9 @@ export * from './update';
|
|
|
12
14
|
export * from './useView';
|
|
13
15
|
export * from './useEdit';
|
|
14
16
|
export * from './useSearch';
|
|
17
|
+
export * from './useMessage';
|
|
18
|
+
|
|
19
|
+
export const withDefaultProps = (Component: any) => (props: RouteComponentProps) => {
|
|
20
|
+
// return <Component props={props} history={props.history} />;
|
|
21
|
+
return React.createElement(Component, { props: props, history: props.history });
|
|
22
|
+
};
|
package/src/merge.ts
CHANGED
|
@@ -3,15 +3,15 @@ import {useCallback, useEffect, useRef, useState} from 'react';
|
|
|
3
3
|
export type Callback<T> = (value?: T) => void;
|
|
4
4
|
export type DispatchWithCallback<T> = (value: T, callback?: Callback<T>) => void;
|
|
5
5
|
|
|
6
|
-
export function useMergeState<T>(initialState
|
|
7
|
-
const [state, _setState] = useState(initialState);
|
|
6
|
+
export function useMergeState<T>(initialState?: T | (() => T)): [T, DispatchWithCallback<Partial<T>>] {
|
|
7
|
+
const [state, _setState] = useState(initialState ? initialState : {} as any);
|
|
8
8
|
|
|
9
9
|
const callbackRef = useRef<Callback<T>>();
|
|
10
10
|
const isFirstCallbackCall = useRef<boolean>(true);
|
|
11
11
|
|
|
12
12
|
const setState = useCallback((newState: Partial<T>, callback?: Callback<T>): void => {
|
|
13
13
|
callbackRef.current = callback;
|
|
14
|
-
_setState(prevState => Object.assign({}, prevState, newState));
|
|
14
|
+
_setState((prevState: any) => Object.assign({}, prevState, newState));
|
|
15
15
|
}, []);
|
|
16
16
|
|
|
17
17
|
useEffect(() => {
|
package/src/state.ts
CHANGED
|
@@ -14,11 +14,15 @@ export const enLocale = {
|
|
|
14
14
|
'currencySymbol': '$',
|
|
15
15
|
'currencyPattern': 0
|
|
16
16
|
};
|
|
17
|
-
export function localeOf(lc?: Locale, glc?: () => Locale): Locale {
|
|
18
|
-
let l: Locale = lc;
|
|
17
|
+
export function localeOf(lc?: Locale, glc?: (() => Locale) | Locale): Locale {
|
|
18
|
+
let l: Locale|undefined = lc;
|
|
19
19
|
if (!l) {
|
|
20
20
|
if (glc) {
|
|
21
|
-
|
|
21
|
+
if (typeof glc === 'function') {
|
|
22
|
+
l = glc();
|
|
23
|
+
} else {
|
|
24
|
+
l = glc;
|
|
25
|
+
}
|
|
22
26
|
}
|
|
23
27
|
if (!l) {
|
|
24
28
|
l = enLocale;
|
|
@@ -41,31 +45,33 @@ export function handleEvent(e: any, removeErr?: (ctrl: HTMLInputElement) => void
|
|
|
41
45
|
removeErr(ctrl);
|
|
42
46
|
}
|
|
43
47
|
}
|
|
44
|
-
export function handleProps<P extends ModelProps>(e: any, props: P, ctrl: HTMLInputElement, modelName: string, tloc: Locale, prepareData
|
|
48
|
+
export function handleProps<P extends ModelProps>(e: any, props: P, ctrl: HTMLInputElement, modelName: string, tloc: Locale, prepareData?: (data: any) => void) {
|
|
45
49
|
if (props.setGlobalState) {
|
|
46
50
|
const res = valueOf(ctrl, tloc, e.type);
|
|
47
51
|
if (res.mustChange) {
|
|
48
52
|
const dataField = ctrl.getAttribute('data-field');
|
|
49
53
|
const field = (dataField ? dataField : ctrl.name);
|
|
50
|
-
const propsDataForm = props[modelName];
|
|
54
|
+
const propsDataForm = (props as any)[modelName];
|
|
51
55
|
const form = ctrl.form;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
if (form) {
|
|
57
|
+
const formName = form.name;
|
|
58
|
+
if (field.indexOf('.') < 0 && field.indexOf('[') < 0) {
|
|
59
|
+
const data = props.shouldBeCustomized && prepareData ? prepareData({ [ctrl.name]: res.value }) : { [ctrl.name]: res.value };
|
|
60
|
+
props.setGlobalState({ [formName]: { ...propsDataForm, ...data } });
|
|
61
|
+
} else {
|
|
62
|
+
setValue(propsDataForm, field, ctrl.value);
|
|
63
|
+
props.setGlobalState({ [formName]: { ...propsDataForm } });
|
|
64
|
+
}
|
|
59
65
|
}
|
|
60
66
|
}
|
|
61
67
|
}
|
|
62
68
|
}
|
|
63
|
-
export function buildState<S, K extends keyof S>(e: any, state: Readonly<S>, ctrl: HTMLInputElement, modelName: string, tloc: Locale): K {
|
|
69
|
+
export function buildState<S, K extends keyof S>(e: any, state: Readonly<S>, ctrl: HTMLInputElement, modelName: string, tloc: Locale): K|undefined {
|
|
64
70
|
const form = ctrl.form;
|
|
65
71
|
if (form) {
|
|
66
72
|
if (modelName && modelName !== '') {
|
|
67
73
|
const type = ctrl.getAttribute('type');
|
|
68
|
-
const ex = state[modelName];
|
|
74
|
+
const ex = (state as any)[modelName];
|
|
69
75
|
const dataField = ctrl.getAttribute('data-field');
|
|
70
76
|
const field = (dataField ? dataField : ctrl.name);
|
|
71
77
|
const model = Object.assign({}, ex);
|
|
@@ -75,7 +81,7 @@ export function buildState<S, K extends keyof S>(e: any, state: Readonly<S>, ctr
|
|
|
75
81
|
if (!value || !Array.isArray(value)) {
|
|
76
82
|
value = [];
|
|
77
83
|
}
|
|
78
|
-
value.includes(ctrl.value) ? value = value.filter(v => v !== ctrl.value) : value.push(ctrl.value);
|
|
84
|
+
value.includes(ctrl.value) ? value = value.filter((v: string) => v !== ctrl.value) : value.push(ctrl.value);
|
|
79
85
|
model[field] = value;
|
|
80
86
|
} else {
|
|
81
87
|
const v = valueOfCheckbox(ctrl);
|
|
@@ -124,7 +130,7 @@ export function valueOfCheckbox(ctrl: HTMLInputElement): string|number|boolean {
|
|
|
124
130
|
return ctrl.checked === true;
|
|
125
131
|
}
|
|
126
132
|
}
|
|
127
|
-
export function buildFlatState<S, K extends keyof S>(e: any, state: Readonly<S>, l
|
|
133
|
+
export function buildFlatState<S, K extends keyof S>(e: any, state: Readonly<S>, l?: Locale): K|undefined {
|
|
128
134
|
const ctrl = e.currentTarget as HTMLInputElement;
|
|
129
135
|
const stateName = ctrl.name;
|
|
130
136
|
const objSet: any = {};
|
|
@@ -135,8 +141,8 @@ export function buildFlatState<S, K extends keyof S>(e: any, state: Readonly<S>,
|
|
|
135
141
|
objSet[stateName] = v;
|
|
136
142
|
return objSet;
|
|
137
143
|
} else {
|
|
138
|
-
let value = state[stateName];
|
|
139
|
-
value.includes(ctrl.value) ? value = value.filter(v => v !== ctrl.value) : value.push(ctrl.value);
|
|
144
|
+
let value = (state as any)[stateName];
|
|
145
|
+
value.includes(ctrl.value) ? value = value.filter((v: string) => v !== ctrl.value) : value.push(ctrl.value);
|
|
140
146
|
const objSet2: any = {[ctrl.name]: value};
|
|
141
147
|
return objSet2;
|
|
142
148
|
}
|
|
@@ -146,7 +152,7 @@ export function buildFlatState<S, K extends keyof S>(e: any, state: Readonly<S>,
|
|
|
146
152
|
objSet[stateName] = data.value;
|
|
147
153
|
return objSet;
|
|
148
154
|
} else {
|
|
149
|
-
return
|
|
155
|
+
return undefined;
|
|
150
156
|
}
|
|
151
157
|
}
|
|
152
158
|
}
|