@faasjs/react 3.7.0-beta.6 → 3.7.0-beta.8
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 +10 -1
- package/dist/index.d.mts +82 -31
- package/dist/index.d.ts +82 -31
- package/dist/index.js +87 -80
- package/dist/index.mjs +86 -82
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@ React plugin for FaasJS.
|
|
|
34
34
|
## Install
|
|
35
35
|
|
|
36
36
|
```sh
|
|
37
|
-
npm install @faasjs/react
|
|
37
|
+
npm install @faasjs/react react
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
## Functions
|
|
@@ -46,6 +46,7 @@ npm install @faasjs/react
|
|
|
46
46
|
- [FaasReactClient](functions/FaasReactClient.md)
|
|
47
47
|
- [Form](functions/Form.md)
|
|
48
48
|
- [FormContextProvider](functions/FormContextProvider.md)
|
|
49
|
+
- [FormItem](functions/FormItem.md)
|
|
49
50
|
- [getClient](functions/getClient.md)
|
|
50
51
|
- [OptionalWrapper](functions/OptionalWrapper.md)
|
|
51
52
|
- [useConstant](functions/useConstant.md)
|
|
@@ -56,6 +57,7 @@ npm install @faasjs/react
|
|
|
56
57
|
- [useFaas](functions/useFaas.md)
|
|
57
58
|
- [useFormContext](functions/useFormContext.md)
|
|
58
59
|
- [useSplittingState](functions/useSplittingState.md)
|
|
60
|
+
- [validValues](functions/validValues.md)
|
|
59
61
|
- [withFaasData](functions/withFaasData.md)
|
|
60
62
|
|
|
61
63
|
## Classes
|
|
@@ -80,10 +82,16 @@ npm install @faasjs/react
|
|
|
80
82
|
- [FaasReactClientOptions](type-aliases/FaasReactClientOptions.md)
|
|
81
83
|
- [FormButtonElementProps](type-aliases/FormButtonElementProps.md)
|
|
82
84
|
- [FormContextProps](type-aliases/FormContextProps.md)
|
|
85
|
+
- [FormDefaultRulesOptions](type-aliases/FormDefaultRulesOptions.md)
|
|
83
86
|
- [FormElementTypes](type-aliases/FormElementTypes.md)
|
|
84
87
|
- [FormInputElementProps](type-aliases/FormInputElementProps.md)
|
|
88
|
+
- [FormItemName](type-aliases/FormItemName.md)
|
|
89
|
+
- [FormItemProps](type-aliases/FormItemProps.md)
|
|
85
90
|
- [FormLabelElementProps](type-aliases/FormLabelElementProps.md)
|
|
86
91
|
- [FormProps](type-aliases/FormProps.md)
|
|
92
|
+
- [FormRule](type-aliases/FormRule.md)
|
|
93
|
+
- [FormRules](type-aliases/FormRules.md)
|
|
94
|
+
- [InferFormRulesOptions](type-aliases/InferFormRulesOptions.md)
|
|
87
95
|
- [OnError](type-aliases/OnError.md)
|
|
88
96
|
- [OptionalWrapperProps](type-aliases/OptionalWrapperProps.md)
|
|
89
97
|
- [Options](type-aliases/Options.md)
|
|
@@ -93,3 +101,4 @@ npm install @faasjs/react
|
|
|
93
101
|
## Variables
|
|
94
102
|
|
|
95
103
|
- [FormDefaultElements](variables/FormDefaultElements.md)
|
|
104
|
+
- [FormDefaultRules](variables/FormDefaultRules.md)
|
package/dist/index.d.mts
CHANGED
|
@@ -124,7 +124,7 @@ declare function createSplittingContext<T extends Record<string, any>>(defaultVa
|
|
|
124
124
|
* ```
|
|
125
125
|
*/
|
|
126
126
|
Provider<NewT extends T = T>(props: {
|
|
127
|
-
value?: NewT
|
|
127
|
+
value?: Partial<NewT>;
|
|
128
128
|
children: ReactNode;
|
|
129
129
|
/**
|
|
130
130
|
* Whether to use memoization for the children.
|
|
@@ -135,6 +135,20 @@ declare function createSplittingContext<T extends Record<string, any>>(defaultVa
|
|
|
135
135
|
* `any[]`: memoize the children with specific dependencies.
|
|
136
136
|
*/
|
|
137
137
|
memo?: true | any[];
|
|
138
|
+
/**
|
|
139
|
+
* An object containing initial values that will be automatically converted into state variables using {@link useSplittingState} hook. Each property will create both a state value and its setter following the pattern: value/setValue.
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```tsx
|
|
143
|
+
* <Provider
|
|
144
|
+
* initializeStates={{
|
|
145
|
+
* value: 0,
|
|
146
|
+
* }}
|
|
147
|
+
* >
|
|
148
|
+
* // Children will have access to: value, setValue
|
|
149
|
+
* </Provider>
|
|
150
|
+
*/
|
|
151
|
+
initializeStates?: Partial<NewT>;
|
|
138
152
|
}): ReactNode;
|
|
139
153
|
/**
|
|
140
154
|
* The hook to use the splitting context.
|
|
@@ -394,21 +408,39 @@ type FormInputElementProps = {
|
|
|
394
408
|
onChange: (value: any) => void;
|
|
395
409
|
};
|
|
396
410
|
|
|
411
|
+
type FormLabelElementProps = {
|
|
412
|
+
name: string;
|
|
413
|
+
title?: ReactNode;
|
|
414
|
+
description?: ReactNode;
|
|
415
|
+
error?: Error;
|
|
416
|
+
/** as Input element */
|
|
417
|
+
children: ReactNode;
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
type FormElementTypes = {
|
|
421
|
+
Label: ComponentType<FormLabelElementProps>;
|
|
422
|
+
Input: ComponentType<FormInputElementProps>;
|
|
423
|
+
Button: ComponentType<FormButtonElementProps>;
|
|
424
|
+
};
|
|
425
|
+
declare const FormDefaultElements: FormElementTypes;
|
|
426
|
+
|
|
397
427
|
declare const FormDefaultLang: {
|
|
398
428
|
submit: string;
|
|
399
429
|
required: string;
|
|
430
|
+
string: string;
|
|
400
431
|
number: string;
|
|
401
432
|
};
|
|
402
433
|
type FormLang = typeof FormDefaultLang;
|
|
403
434
|
|
|
404
|
-
type
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
type FormError = {
|
|
410
|
-
message: string;
|
|
435
|
+
type FormRule<Options = any> = (value: any, options?: Options, lang?: FormLang) => Promise<void>;
|
|
436
|
+
type InferRuleOption<T> = T extends (value: any, options: infer O, lang?: FormLang) => Promise<void> ? O : never;
|
|
437
|
+
type FormRules = Record<string, FormRule>;
|
|
438
|
+
type InferFormRulesOptions<T> = {
|
|
439
|
+
[K in keyof T]: InferRuleOption<T[K]>;
|
|
411
440
|
};
|
|
441
|
+
declare const FormDefaultRules: FormRules;
|
|
442
|
+
type FormDefaultRulesOptions = InferFormRulesOptions<typeof FormDefaultRules>;
|
|
443
|
+
declare function validValues(rules: FormRules, items: FormItemProps[], values: Record<string, any>, lang: FormLang): Promise<Record<string, Error>>;
|
|
412
444
|
|
|
413
445
|
type InferFormInputProps<T extends ComponentType<FormInputElementProps> | JSXElementConstructor<any>> = T extends ComponentType<FormInputElementProps> ? Omit<ComponentProps<T>, 'name' | 'value' | 'onChange'> : Omit<ComponentProps<T>, 'name' | 'value'>;
|
|
414
446
|
type FormInputProps<FormElements extends FormElementTypes = FormElementTypes> = {
|
|
@@ -416,52 +448,71 @@ type FormInputProps<FormElements extends FormElementTypes = FormElementTypes> =
|
|
|
416
448
|
props?: InferFormInputProps<FormElements['Input']>;
|
|
417
449
|
};
|
|
418
450
|
|
|
419
|
-
type
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
451
|
+
type FormItemName = string;
|
|
452
|
+
type FormItemProps<FormElements extends FormElementTypes = FormElementTypes, FormRulesOptions extends Record<string, any> = FormDefaultRulesOptions> = {
|
|
453
|
+
name: FormItemName;
|
|
454
|
+
label?: Omit<FormLabelElementProps, 'name'> & {
|
|
455
|
+
Label?: ComponentType<FormLabelElementProps>;
|
|
456
|
+
};
|
|
425
457
|
input?: FormInputProps<FormElements>;
|
|
458
|
+
rules?: FormRulesOptions;
|
|
426
459
|
};
|
|
460
|
+
declare function FormItem(props: FormItemProps): react_jsx_runtime.JSX.Element;
|
|
461
|
+
declare namespace FormItem {
|
|
462
|
+
var displayName: string;
|
|
463
|
+
var whyDidYouRender: boolean;
|
|
464
|
+
}
|
|
427
465
|
|
|
428
|
-
type FormElementTypes = {
|
|
429
|
-
|
|
430
|
-
Input: ComponentType<FormInputElementProps>;
|
|
431
|
-
Button: ComponentType<FormButtonElementProps>;
|
|
432
|
-
};
|
|
433
|
-
declare const FormDefaultElements: FormElementTypes;
|
|
434
|
-
|
|
435
|
-
type FormProps<Values extends Record<string, any> = Record<string, any>, FormElements extends FormElementTypes = FormElementTypes> = {
|
|
436
|
-
items: FormLabelElementProps<FormElements>[];
|
|
466
|
+
type FormProps<Values extends Record<string, any> = Record<string, any>, FormElements extends FormElementTypes = FormElementTypes, Rules extends FormRules = typeof FormDefaultRules> = {
|
|
467
|
+
items: FormItemProps<FormElements, InferFormRulesOptions<Rules>>[];
|
|
437
468
|
onSubmit?: (values: Values) => Promise<void>;
|
|
438
469
|
Elements?: Partial<FormElements>;
|
|
439
470
|
lang?: Partial<FormLang>;
|
|
440
471
|
defaultValues?: Values;
|
|
472
|
+
rules?: typeof FormDefaultRules & Rules;
|
|
441
473
|
};
|
|
442
|
-
|
|
474
|
+
/**
|
|
475
|
+
* FormContainer component is a wrapper that provides context and state management for form elements.
|
|
476
|
+
* It initializes form states such as values, errors, submitting status, elements, language, and rules.
|
|
477
|
+
*
|
|
478
|
+
* @template Values - The type of form values, defaults to Record<string, any>.
|
|
479
|
+
* @template FormElements - The type of form elements, defaults to FormElementTypes.
|
|
480
|
+
* @template Rules - The type of form rules, defaults to FormDefaultRules.
|
|
481
|
+
*
|
|
482
|
+
* @param {FormProps<Values, FormElements, Rules>} props - The properties for the FormContainer component.
|
|
483
|
+
* @param {Values} props.defaultValues - The default values for the form fields.
|
|
484
|
+
* @param {FormElements} props.Elements - The form elements to be used in the form.
|
|
485
|
+
* @param {Rules} props.rules - The validation rules for the form fields.
|
|
486
|
+
* @param {FormLang} props.lang - The language settings for the form.
|
|
487
|
+
* @param {Partial<FormContextProps>} props - Additional properties for the form context.
|
|
488
|
+
*
|
|
489
|
+
* @returns {JSX.Element} The FormContainer component.
|
|
490
|
+
*/
|
|
491
|
+
declare function FormContainer<Values extends Record<string, any> = Record<string, any>, FormElements extends FormElementTypes = FormElementTypes, Rules extends FormRules = typeof FormDefaultRules>({ defaultValues, Elements, rules, lang, ...props }: FormProps<Values, FormElements, Rules>): react_jsx_runtime.JSX.Element;
|
|
443
492
|
declare namespace FormContainer {
|
|
444
493
|
var displayName: string;
|
|
445
494
|
var whyDidYouRender: boolean;
|
|
446
495
|
}
|
|
447
496
|
|
|
448
|
-
type FormContextProps<Values extends Record<string, any> = Record<string, any
|
|
497
|
+
type FormContextProps<Values extends Record<string, any> = Record<string, any>, Rules extends FormRules = typeof FormDefaultRules> = {
|
|
449
498
|
items: FormLabelElementProps[];
|
|
450
499
|
onSubmit: (values: Values) => Promise<void>;
|
|
451
500
|
Elements: FormElementTypes;
|
|
452
501
|
lang: FormLang;
|
|
502
|
+
rules: typeof FormDefaultRules & Rules;
|
|
453
503
|
submitting: boolean;
|
|
454
504
|
setSubmitting: Dispatch<SetStateAction<boolean>>;
|
|
455
505
|
values: Values;
|
|
456
506
|
setValues: Dispatch<SetStateAction<Values>>;
|
|
457
|
-
errors: Record<string,
|
|
458
|
-
setErrors: Dispatch<SetStateAction<Record<string,
|
|
507
|
+
errors: Record<string, Error>;
|
|
508
|
+
setErrors: Dispatch<SetStateAction<Record<string, Error>>>;
|
|
459
509
|
};
|
|
460
|
-
declare const FormContextProvider: <NewT extends FormContextProps<Record<string, any
|
|
461
|
-
value?: NewT
|
|
510
|
+
declare const FormContextProvider: <NewT extends FormContextProps<Record<string, any>, FormRules> = FormContextProps<Record<string, any>, FormRules>>(props: {
|
|
511
|
+
value?: Partial<NewT>;
|
|
462
512
|
children: react.ReactNode;
|
|
463
513
|
memo?: true | any[];
|
|
514
|
+
initializeStates?: Partial<NewT>;
|
|
464
515
|
}) => react.ReactNode;
|
|
465
|
-
declare const useFormContext: <NewT extends FormContextProps<Record<string, any
|
|
516
|
+
declare const useFormContext: <NewT extends FormContextProps<Record<string, any>, FormRules> = FormContextProps<Record<string, any>, FormRules>>() => Readonly<NewT>;
|
|
466
517
|
|
|
467
|
-
export { ErrorBoundary, type ErrorBoundaryProps, type ErrorChildrenProps, type FaasDataInjection, FaasDataWrapper, type FaasDataWrapperProps, FaasReactClient, type FaasReactClientInstance, type FaasReactClientOptions, FormContainer as Form, type FormButtonElementProps, type FormContextProps, FormContextProvider, FormDefaultElements, type FormElementTypes, type FormInputElementProps, type FormLabelElementProps, type FormProps, type OnError, OptionalWrapper, type OptionalWrapperProps, createSplittingContext, equal, faas, getClient, useConstant, useEqualCallback, useEqualEffect, useEqualMemo, useEqualMemoize, useFaas, type useFaasOptions, useFormContext, useSplittingState, withFaasData };
|
|
518
|
+
export { ErrorBoundary, type ErrorBoundaryProps, type ErrorChildrenProps, type FaasDataInjection, FaasDataWrapper, type FaasDataWrapperProps, FaasReactClient, type FaasReactClientInstance, type FaasReactClientOptions, FormContainer as Form, type FormButtonElementProps, type FormContextProps, FormContextProvider, FormDefaultElements, FormDefaultRules, type FormDefaultRulesOptions, type FormElementTypes, type FormInputElementProps, FormItem, type FormItemName, type FormItemProps, type FormLabelElementProps, type FormProps, type FormRule, type FormRules, type InferFormRulesOptions, type OnError, OptionalWrapper, type OptionalWrapperProps, createSplittingContext, equal, faas, getClient, useConstant, useEqualCallback, useEqualEffect, useEqualMemo, useEqualMemoize, useFaas, type useFaasOptions, useFormContext, useSplittingState, validValues, withFaasData };
|
package/dist/index.d.ts
CHANGED
|
@@ -124,7 +124,7 @@ declare function createSplittingContext<T extends Record<string, any>>(defaultVa
|
|
|
124
124
|
* ```
|
|
125
125
|
*/
|
|
126
126
|
Provider<NewT extends T = T>(props: {
|
|
127
|
-
value?: NewT
|
|
127
|
+
value?: Partial<NewT>;
|
|
128
128
|
children: ReactNode;
|
|
129
129
|
/**
|
|
130
130
|
* Whether to use memoization for the children.
|
|
@@ -135,6 +135,20 @@ declare function createSplittingContext<T extends Record<string, any>>(defaultVa
|
|
|
135
135
|
* `any[]`: memoize the children with specific dependencies.
|
|
136
136
|
*/
|
|
137
137
|
memo?: true | any[];
|
|
138
|
+
/**
|
|
139
|
+
* An object containing initial values that will be automatically converted into state variables using {@link useSplittingState} hook. Each property will create both a state value and its setter following the pattern: value/setValue.
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```tsx
|
|
143
|
+
* <Provider
|
|
144
|
+
* initializeStates={{
|
|
145
|
+
* value: 0,
|
|
146
|
+
* }}
|
|
147
|
+
* >
|
|
148
|
+
* // Children will have access to: value, setValue
|
|
149
|
+
* </Provider>
|
|
150
|
+
*/
|
|
151
|
+
initializeStates?: Partial<NewT>;
|
|
138
152
|
}): ReactNode;
|
|
139
153
|
/**
|
|
140
154
|
* The hook to use the splitting context.
|
|
@@ -394,21 +408,39 @@ type FormInputElementProps = {
|
|
|
394
408
|
onChange: (value: any) => void;
|
|
395
409
|
};
|
|
396
410
|
|
|
411
|
+
type FormLabelElementProps = {
|
|
412
|
+
name: string;
|
|
413
|
+
title?: ReactNode;
|
|
414
|
+
description?: ReactNode;
|
|
415
|
+
error?: Error;
|
|
416
|
+
/** as Input element */
|
|
417
|
+
children: ReactNode;
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
type FormElementTypes = {
|
|
421
|
+
Label: ComponentType<FormLabelElementProps>;
|
|
422
|
+
Input: ComponentType<FormInputElementProps>;
|
|
423
|
+
Button: ComponentType<FormButtonElementProps>;
|
|
424
|
+
};
|
|
425
|
+
declare const FormDefaultElements: FormElementTypes;
|
|
426
|
+
|
|
397
427
|
declare const FormDefaultLang: {
|
|
398
428
|
submit: string;
|
|
399
429
|
required: string;
|
|
430
|
+
string: string;
|
|
400
431
|
number: string;
|
|
401
432
|
};
|
|
402
433
|
type FormLang = typeof FormDefaultLang;
|
|
403
434
|
|
|
404
|
-
type
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
type FormError = {
|
|
410
|
-
message: string;
|
|
435
|
+
type FormRule<Options = any> = (value: any, options?: Options, lang?: FormLang) => Promise<void>;
|
|
436
|
+
type InferRuleOption<T> = T extends (value: any, options: infer O, lang?: FormLang) => Promise<void> ? O : never;
|
|
437
|
+
type FormRules = Record<string, FormRule>;
|
|
438
|
+
type InferFormRulesOptions<T> = {
|
|
439
|
+
[K in keyof T]: InferRuleOption<T[K]>;
|
|
411
440
|
};
|
|
441
|
+
declare const FormDefaultRules: FormRules;
|
|
442
|
+
type FormDefaultRulesOptions = InferFormRulesOptions<typeof FormDefaultRules>;
|
|
443
|
+
declare function validValues(rules: FormRules, items: FormItemProps[], values: Record<string, any>, lang: FormLang): Promise<Record<string, Error>>;
|
|
412
444
|
|
|
413
445
|
type InferFormInputProps<T extends ComponentType<FormInputElementProps> | JSXElementConstructor<any>> = T extends ComponentType<FormInputElementProps> ? Omit<ComponentProps<T>, 'name' | 'value' | 'onChange'> : Omit<ComponentProps<T>, 'name' | 'value'>;
|
|
414
446
|
type FormInputProps<FormElements extends FormElementTypes = FormElementTypes> = {
|
|
@@ -416,52 +448,71 @@ type FormInputProps<FormElements extends FormElementTypes = FormElementTypes> =
|
|
|
416
448
|
props?: InferFormInputProps<FormElements['Input']>;
|
|
417
449
|
};
|
|
418
450
|
|
|
419
|
-
type
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
451
|
+
type FormItemName = string;
|
|
452
|
+
type FormItemProps<FormElements extends FormElementTypes = FormElementTypes, FormRulesOptions extends Record<string, any> = FormDefaultRulesOptions> = {
|
|
453
|
+
name: FormItemName;
|
|
454
|
+
label?: Omit<FormLabelElementProps, 'name'> & {
|
|
455
|
+
Label?: ComponentType<FormLabelElementProps>;
|
|
456
|
+
};
|
|
425
457
|
input?: FormInputProps<FormElements>;
|
|
458
|
+
rules?: FormRulesOptions;
|
|
426
459
|
};
|
|
460
|
+
declare function FormItem(props: FormItemProps): react_jsx_runtime.JSX.Element;
|
|
461
|
+
declare namespace FormItem {
|
|
462
|
+
var displayName: string;
|
|
463
|
+
var whyDidYouRender: boolean;
|
|
464
|
+
}
|
|
427
465
|
|
|
428
|
-
type FormElementTypes = {
|
|
429
|
-
|
|
430
|
-
Input: ComponentType<FormInputElementProps>;
|
|
431
|
-
Button: ComponentType<FormButtonElementProps>;
|
|
432
|
-
};
|
|
433
|
-
declare const FormDefaultElements: FormElementTypes;
|
|
434
|
-
|
|
435
|
-
type FormProps<Values extends Record<string, any> = Record<string, any>, FormElements extends FormElementTypes = FormElementTypes> = {
|
|
436
|
-
items: FormLabelElementProps<FormElements>[];
|
|
466
|
+
type FormProps<Values extends Record<string, any> = Record<string, any>, FormElements extends FormElementTypes = FormElementTypes, Rules extends FormRules = typeof FormDefaultRules> = {
|
|
467
|
+
items: FormItemProps<FormElements, InferFormRulesOptions<Rules>>[];
|
|
437
468
|
onSubmit?: (values: Values) => Promise<void>;
|
|
438
469
|
Elements?: Partial<FormElements>;
|
|
439
470
|
lang?: Partial<FormLang>;
|
|
440
471
|
defaultValues?: Values;
|
|
472
|
+
rules?: typeof FormDefaultRules & Rules;
|
|
441
473
|
};
|
|
442
|
-
|
|
474
|
+
/**
|
|
475
|
+
* FormContainer component is a wrapper that provides context and state management for form elements.
|
|
476
|
+
* It initializes form states such as values, errors, submitting status, elements, language, and rules.
|
|
477
|
+
*
|
|
478
|
+
* @template Values - The type of form values, defaults to Record<string, any>.
|
|
479
|
+
* @template FormElements - The type of form elements, defaults to FormElementTypes.
|
|
480
|
+
* @template Rules - The type of form rules, defaults to FormDefaultRules.
|
|
481
|
+
*
|
|
482
|
+
* @param {FormProps<Values, FormElements, Rules>} props - The properties for the FormContainer component.
|
|
483
|
+
* @param {Values} props.defaultValues - The default values for the form fields.
|
|
484
|
+
* @param {FormElements} props.Elements - The form elements to be used in the form.
|
|
485
|
+
* @param {Rules} props.rules - The validation rules for the form fields.
|
|
486
|
+
* @param {FormLang} props.lang - The language settings for the form.
|
|
487
|
+
* @param {Partial<FormContextProps>} props - Additional properties for the form context.
|
|
488
|
+
*
|
|
489
|
+
* @returns {JSX.Element} The FormContainer component.
|
|
490
|
+
*/
|
|
491
|
+
declare function FormContainer<Values extends Record<string, any> = Record<string, any>, FormElements extends FormElementTypes = FormElementTypes, Rules extends FormRules = typeof FormDefaultRules>({ defaultValues, Elements, rules, lang, ...props }: FormProps<Values, FormElements, Rules>): react_jsx_runtime.JSX.Element;
|
|
443
492
|
declare namespace FormContainer {
|
|
444
493
|
var displayName: string;
|
|
445
494
|
var whyDidYouRender: boolean;
|
|
446
495
|
}
|
|
447
496
|
|
|
448
|
-
type FormContextProps<Values extends Record<string, any> = Record<string, any
|
|
497
|
+
type FormContextProps<Values extends Record<string, any> = Record<string, any>, Rules extends FormRules = typeof FormDefaultRules> = {
|
|
449
498
|
items: FormLabelElementProps[];
|
|
450
499
|
onSubmit: (values: Values) => Promise<void>;
|
|
451
500
|
Elements: FormElementTypes;
|
|
452
501
|
lang: FormLang;
|
|
502
|
+
rules: typeof FormDefaultRules & Rules;
|
|
453
503
|
submitting: boolean;
|
|
454
504
|
setSubmitting: Dispatch<SetStateAction<boolean>>;
|
|
455
505
|
values: Values;
|
|
456
506
|
setValues: Dispatch<SetStateAction<Values>>;
|
|
457
|
-
errors: Record<string,
|
|
458
|
-
setErrors: Dispatch<SetStateAction<Record<string,
|
|
507
|
+
errors: Record<string, Error>;
|
|
508
|
+
setErrors: Dispatch<SetStateAction<Record<string, Error>>>;
|
|
459
509
|
};
|
|
460
|
-
declare const FormContextProvider: <NewT extends FormContextProps<Record<string, any
|
|
461
|
-
value?: NewT
|
|
510
|
+
declare const FormContextProvider: <NewT extends FormContextProps<Record<string, any>, FormRules> = FormContextProps<Record<string, any>, FormRules>>(props: {
|
|
511
|
+
value?: Partial<NewT>;
|
|
462
512
|
children: react.ReactNode;
|
|
463
513
|
memo?: true | any[];
|
|
514
|
+
initializeStates?: Partial<NewT>;
|
|
464
515
|
}) => react.ReactNode;
|
|
465
|
-
declare const useFormContext: <NewT extends FormContextProps<Record<string, any
|
|
516
|
+
declare const useFormContext: <NewT extends FormContextProps<Record<string, any>, FormRules> = FormContextProps<Record<string, any>, FormRules>>() => Readonly<NewT>;
|
|
466
517
|
|
|
467
|
-
export { ErrorBoundary, type ErrorBoundaryProps, type ErrorChildrenProps, type FaasDataInjection, FaasDataWrapper, type FaasDataWrapperProps, FaasReactClient, type FaasReactClientInstance, type FaasReactClientOptions, FormContainer as Form, type FormButtonElementProps, type FormContextProps, FormContextProvider, FormDefaultElements, type FormElementTypes, type FormInputElementProps, type FormLabelElementProps, type FormProps, type OnError, OptionalWrapper, type OptionalWrapperProps, createSplittingContext, equal, faas, getClient, useConstant, useEqualCallback, useEqualEffect, useEqualMemo, useEqualMemoize, useFaas, type useFaasOptions, useFormContext, useSplittingState, withFaasData };
|
|
518
|
+
export { ErrorBoundary, type ErrorBoundaryProps, type ErrorChildrenProps, type FaasDataInjection, FaasDataWrapper, type FaasDataWrapperProps, FaasReactClient, type FaasReactClientInstance, type FaasReactClientOptions, FormContainer as Form, type FormButtonElementProps, type FormContextProps, FormContextProvider, FormDefaultElements, FormDefaultRules, type FormDefaultRulesOptions, type FormElementTypes, type FormInputElementProps, FormItem, type FormItemName, type FormItemProps, type FormLabelElementProps, type FormProps, type FormRule, type FormRules, type InferFormRulesOptions, type OnError, OptionalWrapper, type OptionalWrapperProps, createSplittingContext, equal, faas, getClient, useConstant, useEqualCallback, useEqualEffect, useEqualMemo, useEqualMemoize, useFaas, type useFaasOptions, useFormContext, useSplittingState, validValues, withFaasData };
|
package/dist/index.js
CHANGED
|
@@ -49,7 +49,6 @@ function equal(a, b) {
|
|
|
49
49
|
return a === b;
|
|
50
50
|
case Object: {
|
|
51
51
|
const keys = Object.keys(a);
|
|
52
|
-
if (keys.length !== Object.keys(b).length) return false;
|
|
53
52
|
for (const key of keys) {
|
|
54
53
|
if (!equal(a[key], b[key])) return false;
|
|
55
54
|
}
|
|
@@ -80,6 +79,17 @@ function useEqualCallback(callback, dependencies) {
|
|
|
80
79
|
useEqualMemoize(dependencies)
|
|
81
80
|
);
|
|
82
81
|
}
|
|
82
|
+
function useSplittingState(initialStates) {
|
|
83
|
+
const states = {};
|
|
84
|
+
for (const key of Object.keys(initialStates)) {
|
|
85
|
+
const state = react.useState(initialStates[key]);
|
|
86
|
+
Object.assign(states, {
|
|
87
|
+
[key]: state[0],
|
|
88
|
+
[`set${String(key).charAt(0).toUpperCase()}${String(key).slice(1)}`]: state[1]
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
return states;
|
|
92
|
+
}
|
|
83
93
|
function createSplittingContext(defaultValue) {
|
|
84
94
|
const keys = Array.isArray(defaultValue) ? defaultValue : Object.keys(defaultValue);
|
|
85
95
|
const defaultValues = Array.isArray(defaultValue) ? keys.reduce((prev, cur) => {
|
|
@@ -89,13 +99,14 @@ function createSplittingContext(defaultValue) {
|
|
|
89
99
|
const contexts = {};
|
|
90
100
|
for (const key of keys) contexts[key] = react.createContext(defaultValues[key]);
|
|
91
101
|
function Provider(props) {
|
|
102
|
+
const states = props.initializeStates ? useSplittingState(props.initializeStates) : {};
|
|
92
103
|
let children = props.memo ? useEqualMemo(
|
|
93
104
|
() => props.children,
|
|
94
105
|
props.memo === true ? [] : props.memo
|
|
95
106
|
) : props.children;
|
|
96
107
|
for (const key of keys) {
|
|
97
108
|
const Context = contexts[key];
|
|
98
|
-
const value = props.value?.[key] ?? defaultValues[key];
|
|
109
|
+
const value = props.value?.[key] ?? states[key] ?? defaultValues[key];
|
|
99
110
|
children = /* @__PURE__ */ jsxRuntime.jsx(Context.Provider, { value, children });
|
|
100
111
|
}
|
|
101
112
|
return children;
|
|
@@ -119,17 +130,6 @@ function createSplittingContext(defaultValue) {
|
|
|
119
130
|
use
|
|
120
131
|
};
|
|
121
132
|
}
|
|
122
|
-
function useSplittingState(initialStates) {
|
|
123
|
-
const states = {};
|
|
124
|
-
for (const key of Object.keys(initialStates)) {
|
|
125
|
-
const state = react.useState(initialStates[key]);
|
|
126
|
-
Object.assign(states, {
|
|
127
|
-
[key]: state[0],
|
|
128
|
-
[`set${String(key).charAt(0).toUpperCase()}${String(key).slice(1)}`]: state[1]
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
return states;
|
|
132
|
-
}
|
|
133
133
|
function FaasDataWrapper(props) {
|
|
134
134
|
const request = getClient(props.baseUrl).useFaas(
|
|
135
135
|
props.action,
|
|
@@ -354,40 +354,71 @@ var FormContext = createSplittingContext([
|
|
|
354
354
|
"values",
|
|
355
355
|
"setValues",
|
|
356
356
|
"errors",
|
|
357
|
-
"setErrors"
|
|
357
|
+
"setErrors",
|
|
358
|
+
"rules"
|
|
358
359
|
]);
|
|
359
360
|
var FormContextProvider = FormContext.Provider;
|
|
360
361
|
var useFormContext = FormContext.use;
|
|
361
|
-
function
|
|
362
|
-
const { Elements } = useFormContext();
|
|
363
|
-
|
|
364
|
-
|
|
362
|
+
function FormItem(props) {
|
|
363
|
+
const { Elements, values, setValues } = useFormContext();
|
|
364
|
+
const Label = props.label?.Label ?? Elements.Label;
|
|
365
|
+
const Input = props.input?.Input ?? Elements.Input;
|
|
366
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Label, { name: props.name, ...props.label, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
367
|
+
Input,
|
|
368
|
+
{
|
|
369
|
+
name: props.name,
|
|
370
|
+
value: values[props.name],
|
|
371
|
+
onChange: (v) => setValues((prev) => ({
|
|
372
|
+
...prev,
|
|
373
|
+
[props.name]: v
|
|
374
|
+
}))
|
|
375
|
+
}
|
|
376
|
+
) });
|
|
365
377
|
}
|
|
366
|
-
|
|
367
|
-
|
|
378
|
+
FormItem.displayName = "FormItem";
|
|
379
|
+
FormItem.whyDidYouRender = true;
|
|
368
380
|
function FormBody() {
|
|
369
381
|
const { items } = useFormContext();
|
|
370
|
-
return items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
382
|
+
return items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(FormItem, { ...item }, item.name));
|
|
371
383
|
}
|
|
372
384
|
FormBody.displayName = "FormBody";
|
|
373
385
|
FormBody.whyDidYouRender = true;
|
|
374
386
|
|
|
375
387
|
// src/Form/rules.ts
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
388
|
+
var FormDefaultRules = {
|
|
389
|
+
required: async (value, _, lang) => {
|
|
390
|
+
if (value === null || value === void 0 || value === "" || Number.isNaN(value)) {
|
|
391
|
+
throw Error(lang?.required);
|
|
392
|
+
}
|
|
393
|
+
},
|
|
394
|
+
type: async (value, options, lang) => {
|
|
395
|
+
switch (options) {
|
|
396
|
+
case "string":
|
|
397
|
+
if (typeof value !== "string") throw Error(lang?.string);
|
|
398
|
+
break;
|
|
399
|
+
case "number":
|
|
400
|
+
if (Number.isNaN(Number(value))) throw Error(lang?.number);
|
|
401
|
+
break;
|
|
402
|
+
}
|
|
403
|
+
},
|
|
404
|
+
custom: async (value, options) => {
|
|
405
|
+
return options(value);
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
async function validValues(rules, items, values, lang) {
|
|
384
409
|
const errors = {};
|
|
385
410
|
for (const item of items) {
|
|
386
411
|
const value = values[item.name];
|
|
387
|
-
const
|
|
388
|
-
if (
|
|
389
|
-
const
|
|
390
|
-
|
|
412
|
+
const rulesOptions = item.rules;
|
|
413
|
+
if (rulesOptions) {
|
|
414
|
+
for (const [name, options] of Object.entries(rulesOptions)) {
|
|
415
|
+
try {
|
|
416
|
+
await rules[name](value, options, lang);
|
|
417
|
+
} catch (error) {
|
|
418
|
+
errors[item.name] = error;
|
|
419
|
+
break;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
391
422
|
}
|
|
392
423
|
}
|
|
393
424
|
return errors;
|
|
@@ -401,7 +432,8 @@ function FormFooter() {
|
|
|
401
432
|
Elements,
|
|
402
433
|
items,
|
|
403
434
|
setErrors,
|
|
404
|
-
lang
|
|
435
|
+
lang,
|
|
436
|
+
rules
|
|
405
437
|
} = useFormContext();
|
|
406
438
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
407
439
|
Elements.Button,
|
|
@@ -409,7 +441,7 @@ function FormFooter() {
|
|
|
409
441
|
disabled: submitting,
|
|
410
442
|
submit: async () => {
|
|
411
443
|
setSubmitting(true);
|
|
412
|
-
const errors = await validValues(items, values, lang);
|
|
444
|
+
const errors = await validValues(rules, items, values, lang);
|
|
413
445
|
if (Object.keys(errors).length) {
|
|
414
446
|
setErrors(errors);
|
|
415
447
|
setSubmitting(false);
|
|
@@ -443,45 +475,14 @@ var FormLabelElement = ({
|
|
|
443
475
|
name,
|
|
444
476
|
title,
|
|
445
477
|
description,
|
|
446
|
-
|
|
447
|
-
|
|
478
|
+
error,
|
|
479
|
+
children
|
|
448
480
|
}) => {
|
|
449
|
-
const { values, setValues, errors } = useFormContext();
|
|
450
|
-
if (Label)
|
|
451
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
452
|
-
Label,
|
|
453
|
-
{
|
|
454
|
-
name,
|
|
455
|
-
title,
|
|
456
|
-
description,
|
|
457
|
-
input
|
|
458
|
-
}
|
|
459
|
-
);
|
|
460
481
|
return /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
|
|
461
482
|
title ?? name,
|
|
462
|
-
|
|
463
|
-
input.Input,
|
|
464
|
-
{
|
|
465
|
-
name,
|
|
466
|
-
value: values[name],
|
|
467
|
-
onChange: (v) => setValues((prev) => ({
|
|
468
|
-
...prev,
|
|
469
|
-
[name]: v
|
|
470
|
-
}))
|
|
471
|
-
}
|
|
472
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
473
|
-
FormInputElement,
|
|
474
|
-
{
|
|
475
|
-
name,
|
|
476
|
-
value: values[name],
|
|
477
|
-
onChange: (v) => setValues((prev) => ({
|
|
478
|
-
...prev,
|
|
479
|
-
[name]: v
|
|
480
|
-
}))
|
|
481
|
-
}
|
|
482
|
-
),
|
|
483
|
+
children,
|
|
483
484
|
description,
|
|
484
|
-
|
|
485
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "red" }, children: error.message })
|
|
485
486
|
] });
|
|
486
487
|
};
|
|
487
488
|
FormLabelElement.displayName = "FormLabelElement";
|
|
@@ -498,6 +499,7 @@ var FormDefaultElements = {
|
|
|
498
499
|
var FormDefaultLang = {
|
|
499
500
|
submit: "Submit",
|
|
500
501
|
required: "This field is required",
|
|
502
|
+
string: "This field must be a string",
|
|
501
503
|
number: "This field must be a number"
|
|
502
504
|
};
|
|
503
505
|
function mergeValues(items, defaultValues = {}) {
|
|
@@ -509,23 +511,25 @@ function mergeValues(items, defaultValues = {}) {
|
|
|
509
511
|
function FormContainer({
|
|
510
512
|
defaultValues,
|
|
511
513
|
Elements,
|
|
514
|
+
rules,
|
|
512
515
|
lang,
|
|
513
516
|
...props
|
|
514
517
|
}) {
|
|
515
|
-
const states = useSplittingState({
|
|
516
|
-
values: mergeValues(props.items, defaultValues),
|
|
517
|
-
errors: {},
|
|
518
|
-
submitting: false,
|
|
519
|
-
Elements: Object.assign(FormDefaultElements, Elements),
|
|
520
|
-
lang: Object.assign(FormDefaultLang, lang)
|
|
521
|
-
});
|
|
522
518
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
523
519
|
FormContextProvider,
|
|
524
520
|
{
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
521
|
+
initializeStates: {
|
|
522
|
+
values: mergeValues(props.items, defaultValues),
|
|
523
|
+
errors: {},
|
|
524
|
+
submitting: false,
|
|
525
|
+
Elements: Object.assign(
|
|
526
|
+
FormDefaultElements,
|
|
527
|
+
Elements
|
|
528
|
+
),
|
|
529
|
+
lang: Object.assign(FormDefaultLang, lang),
|
|
530
|
+
rules: Object.assign(FormDefaultRules, rules)
|
|
528
531
|
},
|
|
532
|
+
value: props,
|
|
529
533
|
memo: true,
|
|
530
534
|
children: [
|
|
531
535
|
/* @__PURE__ */ jsxRuntime.jsx(FormBody, {}),
|
|
@@ -543,6 +547,8 @@ exports.FaasReactClient = FaasReactClient;
|
|
|
543
547
|
exports.Form = FormContainer;
|
|
544
548
|
exports.FormContextProvider = FormContextProvider;
|
|
545
549
|
exports.FormDefaultElements = FormDefaultElements;
|
|
550
|
+
exports.FormDefaultRules = FormDefaultRules;
|
|
551
|
+
exports.FormItem = FormItem;
|
|
546
552
|
exports.OptionalWrapper = OptionalWrapper;
|
|
547
553
|
exports.createSplittingContext = createSplittingContext;
|
|
548
554
|
exports.equal = equal;
|
|
@@ -556,4 +562,5 @@ exports.useEqualMemoize = useEqualMemoize;
|
|
|
556
562
|
exports.useFaas = useFaas;
|
|
557
563
|
exports.useFormContext = useFormContext;
|
|
558
564
|
exports.useSplittingState = useSplittingState;
|
|
565
|
+
exports.validValues = validValues;
|
|
559
566
|
exports.withFaasData = withFaasData;
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { forwardRef, useRef, useMemo, useEffect, useCallback,
|
|
1
|
+
import { forwardRef, useRef, useMemo, useEffect, useCallback, useState, createContext, cloneElement, Component, useContext } from 'react';
|
|
2
2
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
3
|
import { FaasBrowserClient } from '@faasjs/browser';
|
|
4
4
|
|
|
@@ -47,7 +47,6 @@ function equal(a, b) {
|
|
|
47
47
|
return a === b;
|
|
48
48
|
case Object: {
|
|
49
49
|
const keys = Object.keys(a);
|
|
50
|
-
if (keys.length !== Object.keys(b).length) return false;
|
|
51
50
|
for (const key of keys) {
|
|
52
51
|
if (!equal(a[key], b[key])) return false;
|
|
53
52
|
}
|
|
@@ -78,6 +77,17 @@ function useEqualCallback(callback, dependencies) {
|
|
|
78
77
|
useEqualMemoize(dependencies)
|
|
79
78
|
);
|
|
80
79
|
}
|
|
80
|
+
function useSplittingState(initialStates) {
|
|
81
|
+
const states = {};
|
|
82
|
+
for (const key of Object.keys(initialStates)) {
|
|
83
|
+
const state = useState(initialStates[key]);
|
|
84
|
+
Object.assign(states, {
|
|
85
|
+
[key]: state[0],
|
|
86
|
+
[`set${String(key).charAt(0).toUpperCase()}${String(key).slice(1)}`]: state[1]
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
return states;
|
|
90
|
+
}
|
|
81
91
|
function createSplittingContext(defaultValue) {
|
|
82
92
|
const keys = Array.isArray(defaultValue) ? defaultValue : Object.keys(defaultValue);
|
|
83
93
|
const defaultValues = Array.isArray(defaultValue) ? keys.reduce((prev, cur) => {
|
|
@@ -87,13 +97,14 @@ function createSplittingContext(defaultValue) {
|
|
|
87
97
|
const contexts = {};
|
|
88
98
|
for (const key of keys) contexts[key] = createContext(defaultValues[key]);
|
|
89
99
|
function Provider(props) {
|
|
100
|
+
const states = props.initializeStates ? useSplittingState(props.initializeStates) : {};
|
|
90
101
|
let children = props.memo ? useEqualMemo(
|
|
91
102
|
() => props.children,
|
|
92
103
|
props.memo === true ? [] : props.memo
|
|
93
104
|
) : props.children;
|
|
94
105
|
for (const key of keys) {
|
|
95
106
|
const Context = contexts[key];
|
|
96
|
-
const value = props.value?.[key] ?? defaultValues[key];
|
|
107
|
+
const value = props.value?.[key] ?? states[key] ?? defaultValues[key];
|
|
97
108
|
children = /* @__PURE__ */ jsx(Context.Provider, { value, children });
|
|
98
109
|
}
|
|
99
110
|
return children;
|
|
@@ -117,17 +128,6 @@ function createSplittingContext(defaultValue) {
|
|
|
117
128
|
use
|
|
118
129
|
};
|
|
119
130
|
}
|
|
120
|
-
function useSplittingState(initialStates) {
|
|
121
|
-
const states = {};
|
|
122
|
-
for (const key of Object.keys(initialStates)) {
|
|
123
|
-
const state = useState(initialStates[key]);
|
|
124
|
-
Object.assign(states, {
|
|
125
|
-
[key]: state[0],
|
|
126
|
-
[`set${String(key).charAt(0).toUpperCase()}${String(key).slice(1)}`]: state[1]
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
return states;
|
|
130
|
-
}
|
|
131
131
|
function FaasDataWrapper(props) {
|
|
132
132
|
const request = getClient(props.baseUrl).useFaas(
|
|
133
133
|
props.action,
|
|
@@ -352,40 +352,71 @@ var FormContext = createSplittingContext([
|
|
|
352
352
|
"values",
|
|
353
353
|
"setValues",
|
|
354
354
|
"errors",
|
|
355
|
-
"setErrors"
|
|
355
|
+
"setErrors",
|
|
356
|
+
"rules"
|
|
356
357
|
]);
|
|
357
358
|
var FormContextProvider = FormContext.Provider;
|
|
358
359
|
var useFormContext = FormContext.use;
|
|
359
|
-
function
|
|
360
|
-
const { Elements } = useFormContext();
|
|
361
|
-
|
|
362
|
-
|
|
360
|
+
function FormItem(props) {
|
|
361
|
+
const { Elements, values, setValues } = useFormContext();
|
|
362
|
+
const Label = props.label?.Label ?? Elements.Label;
|
|
363
|
+
const Input = props.input?.Input ?? Elements.Input;
|
|
364
|
+
return /* @__PURE__ */ jsx(Label, { name: props.name, ...props.label, children: /* @__PURE__ */ jsx(
|
|
365
|
+
Input,
|
|
366
|
+
{
|
|
367
|
+
name: props.name,
|
|
368
|
+
value: values[props.name],
|
|
369
|
+
onChange: (v) => setValues((prev) => ({
|
|
370
|
+
...prev,
|
|
371
|
+
[props.name]: v
|
|
372
|
+
}))
|
|
373
|
+
}
|
|
374
|
+
) });
|
|
363
375
|
}
|
|
364
|
-
|
|
365
|
-
|
|
376
|
+
FormItem.displayName = "FormItem";
|
|
377
|
+
FormItem.whyDidYouRender = true;
|
|
366
378
|
function FormBody() {
|
|
367
379
|
const { items } = useFormContext();
|
|
368
|
-
return items.map((item) => /* @__PURE__ */ jsx(
|
|
380
|
+
return items.map((item) => /* @__PURE__ */ jsx(FormItem, { ...item }, item.name));
|
|
369
381
|
}
|
|
370
382
|
FormBody.displayName = "FormBody";
|
|
371
383
|
FormBody.whyDidYouRender = true;
|
|
372
384
|
|
|
373
385
|
// src/Form/rules.ts
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
386
|
+
var FormDefaultRules = {
|
|
387
|
+
required: async (value, _, lang) => {
|
|
388
|
+
if (value === null || value === void 0 || value === "" || Number.isNaN(value)) {
|
|
389
|
+
throw Error(lang?.required);
|
|
390
|
+
}
|
|
391
|
+
},
|
|
392
|
+
type: async (value, options, lang) => {
|
|
393
|
+
switch (options) {
|
|
394
|
+
case "string":
|
|
395
|
+
if (typeof value !== "string") throw Error(lang?.string);
|
|
396
|
+
break;
|
|
397
|
+
case "number":
|
|
398
|
+
if (Number.isNaN(Number(value))) throw Error(lang?.number);
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
},
|
|
402
|
+
custom: async (value, options) => {
|
|
403
|
+
return options(value);
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
async function validValues(rules, items, values, lang) {
|
|
382
407
|
const errors = {};
|
|
383
408
|
for (const item of items) {
|
|
384
409
|
const value = values[item.name];
|
|
385
|
-
const
|
|
386
|
-
if (
|
|
387
|
-
const
|
|
388
|
-
|
|
410
|
+
const rulesOptions = item.rules;
|
|
411
|
+
if (rulesOptions) {
|
|
412
|
+
for (const [name, options] of Object.entries(rulesOptions)) {
|
|
413
|
+
try {
|
|
414
|
+
await rules[name](value, options, lang);
|
|
415
|
+
} catch (error) {
|
|
416
|
+
errors[item.name] = error;
|
|
417
|
+
break;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
389
420
|
}
|
|
390
421
|
}
|
|
391
422
|
return errors;
|
|
@@ -399,7 +430,8 @@ function FormFooter() {
|
|
|
399
430
|
Elements,
|
|
400
431
|
items,
|
|
401
432
|
setErrors,
|
|
402
|
-
lang
|
|
433
|
+
lang,
|
|
434
|
+
rules
|
|
403
435
|
} = useFormContext();
|
|
404
436
|
return /* @__PURE__ */ jsx(
|
|
405
437
|
Elements.Button,
|
|
@@ -407,7 +439,7 @@ function FormFooter() {
|
|
|
407
439
|
disabled: submitting,
|
|
408
440
|
submit: async () => {
|
|
409
441
|
setSubmitting(true);
|
|
410
|
-
const errors = await validValues(items, values, lang);
|
|
442
|
+
const errors = await validValues(rules, items, values, lang);
|
|
411
443
|
if (Object.keys(errors).length) {
|
|
412
444
|
setErrors(errors);
|
|
413
445
|
setSubmitting(false);
|
|
@@ -441,45 +473,14 @@ var FormLabelElement = ({
|
|
|
441
473
|
name,
|
|
442
474
|
title,
|
|
443
475
|
description,
|
|
444
|
-
|
|
445
|
-
|
|
476
|
+
error,
|
|
477
|
+
children
|
|
446
478
|
}) => {
|
|
447
|
-
const { values, setValues, errors } = useFormContext();
|
|
448
|
-
if (Label)
|
|
449
|
-
return /* @__PURE__ */ jsx(
|
|
450
|
-
Label,
|
|
451
|
-
{
|
|
452
|
-
name,
|
|
453
|
-
title,
|
|
454
|
-
description,
|
|
455
|
-
input
|
|
456
|
-
}
|
|
457
|
-
);
|
|
458
479
|
return /* @__PURE__ */ jsxs("label", { children: [
|
|
459
480
|
title ?? name,
|
|
460
|
-
|
|
461
|
-
input.Input,
|
|
462
|
-
{
|
|
463
|
-
name,
|
|
464
|
-
value: values[name],
|
|
465
|
-
onChange: (v) => setValues((prev) => ({
|
|
466
|
-
...prev,
|
|
467
|
-
[name]: v
|
|
468
|
-
}))
|
|
469
|
-
}
|
|
470
|
-
) : /* @__PURE__ */ jsx(
|
|
471
|
-
FormInputElement,
|
|
472
|
-
{
|
|
473
|
-
name,
|
|
474
|
-
value: values[name],
|
|
475
|
-
onChange: (v) => setValues((prev) => ({
|
|
476
|
-
...prev,
|
|
477
|
-
[name]: v
|
|
478
|
-
}))
|
|
479
|
-
}
|
|
480
|
-
),
|
|
481
|
+
children,
|
|
481
482
|
description,
|
|
482
|
-
|
|
483
|
+
error && /* @__PURE__ */ jsx("div", { style: { color: "red" }, children: error.message })
|
|
483
484
|
] });
|
|
484
485
|
};
|
|
485
486
|
FormLabelElement.displayName = "FormLabelElement";
|
|
@@ -496,6 +497,7 @@ var FormDefaultElements = {
|
|
|
496
497
|
var FormDefaultLang = {
|
|
497
498
|
submit: "Submit",
|
|
498
499
|
required: "This field is required",
|
|
500
|
+
string: "This field must be a string",
|
|
499
501
|
number: "This field must be a number"
|
|
500
502
|
};
|
|
501
503
|
function mergeValues(items, defaultValues = {}) {
|
|
@@ -507,23 +509,25 @@ function mergeValues(items, defaultValues = {}) {
|
|
|
507
509
|
function FormContainer({
|
|
508
510
|
defaultValues,
|
|
509
511
|
Elements,
|
|
512
|
+
rules,
|
|
510
513
|
lang,
|
|
511
514
|
...props
|
|
512
515
|
}) {
|
|
513
|
-
const states = useSplittingState({
|
|
514
|
-
values: mergeValues(props.items, defaultValues),
|
|
515
|
-
errors: {},
|
|
516
|
-
submitting: false,
|
|
517
|
-
Elements: Object.assign(FormDefaultElements, Elements),
|
|
518
|
-
lang: Object.assign(FormDefaultLang, lang)
|
|
519
|
-
});
|
|
520
516
|
return /* @__PURE__ */ jsxs(
|
|
521
517
|
FormContextProvider,
|
|
522
518
|
{
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
519
|
+
initializeStates: {
|
|
520
|
+
values: mergeValues(props.items, defaultValues),
|
|
521
|
+
errors: {},
|
|
522
|
+
submitting: false,
|
|
523
|
+
Elements: Object.assign(
|
|
524
|
+
FormDefaultElements,
|
|
525
|
+
Elements
|
|
526
|
+
),
|
|
527
|
+
lang: Object.assign(FormDefaultLang, lang),
|
|
528
|
+
rules: Object.assign(FormDefaultRules, rules)
|
|
526
529
|
},
|
|
530
|
+
value: props,
|
|
527
531
|
memo: true,
|
|
528
532
|
children: [
|
|
529
533
|
/* @__PURE__ */ jsx(FormBody, {}),
|
|
@@ -535,4 +539,4 @@ function FormContainer({
|
|
|
535
539
|
FormContainer.displayName = "FormContainer";
|
|
536
540
|
FormContainer.whyDidYouRender = true;
|
|
537
541
|
|
|
538
|
-
export { ErrorBoundary, FaasDataWrapper, FaasReactClient, FormContainer as Form, FormContextProvider, FormDefaultElements, OptionalWrapper, createSplittingContext, equal, faas, getClient, useConstant, useEqualCallback, useEqualEffect, useEqualMemo, useEqualMemoize, useFaas, useFormContext, useSplittingState, withFaasData };
|
|
542
|
+
export { ErrorBoundary, FaasDataWrapper, FaasReactClient, FormContainer as Form, FormContextProvider, FormDefaultElements, FormDefaultRules, FormItem, OptionalWrapper, createSplittingContext, equal, faas, getClient, useConstant, useEqualCallback, useEqualEffect, useEqualMemo, useEqualMemoize, useFaas, useFormContext, useSplittingState, validValues, withFaasData };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@faasjs/react",
|
|
3
|
-
"version": "3.7.0-beta.
|
|
3
|
+
"version": "3.7.0-beta.8",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
"dist"
|
|
35
35
|
],
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@faasjs/browser": "3.7.0-beta.
|
|
37
|
+
"@faasjs/browser": "3.7.0-beta.8"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@faasjs/browser": "3.7.0-beta.
|
|
40
|
+
"@faasjs/browser": "3.7.0-beta.8",
|
|
41
41
|
"@types/react": "*",
|
|
42
42
|
"react": "*"
|
|
43
43
|
},
|