@faasjs/react 3.7.0-beta.7 → 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 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
@@ -408,6 +408,22 @@ type FormInputElementProps = {
408
408
  onChange: (value: any) => void;
409
409
  };
410
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
+
411
427
  declare const FormDefaultLang: {
412
428
  submit: string;
413
429
  required: string;
@@ -416,17 +432,15 @@ declare const FormDefaultLang: {
416
432
  };
417
433
  type FormLang = typeof FormDefaultLang;
418
434
 
419
- type FormError = {
420
- message: string;
421
- };
422
- type FormRule<Options = any> = (value: any, options?: Options, lang?: FormLang) => Promise<FormError | undefined>;
423
- type InferRuleOption<T> = T extends (value: any, options: infer O, lang?: FormLang) => Promise<FormError | undefined> ? O : never;
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;
424
437
  type FormRules = Record<string, FormRule>;
425
438
  type InferFormRulesOptions<T> = {
426
439
  [K in keyof T]: InferRuleOption<T[K]>;
427
440
  };
428
441
  declare const FormDefaultRules: FormRules;
429
442
  type FormDefaultRulesOptions = InferFormRulesOptions<typeof FormDefaultRules>;
443
+ declare function validValues(rules: FormRules, items: FormItemProps[], values: Record<string, any>, lang: FormLang): Promise<Record<string, Error>>;
430
444
 
431
445
  type InferFormInputProps<T extends ComponentType<FormInputElementProps> | JSXElementConstructor<any>> = T extends ComponentType<FormInputElementProps> ? Omit<ComponentProps<T>, 'name' | 'value' | 'onChange'> : Omit<ComponentProps<T>, 'name' | 'value'>;
432
446
  type FormInputProps<FormElements extends FormElementTypes = FormElementTypes> = {
@@ -434,30 +448,46 @@ type FormInputProps<FormElements extends FormElementTypes = FormElementTypes> =
434
448
  props?: InferFormInputProps<FormElements['Input']>;
435
449
  };
436
450
 
437
- type FormLabelElementProps<FormElements extends FormElementTypes = FormElementTypes, FormRulesOptions extends Record<string, any> = FormDefaultRulesOptions> = {
438
- name: string;
439
- rules?: FormRulesOptions;
440
- title?: ReactNode;
441
- description?: ReactNode;
442
- Label?: FormElements['Label'];
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
+ };
443
457
  input?: FormInputProps<FormElements>;
458
+ rules?: FormRulesOptions;
444
459
  };
445
-
446
- type FormElementTypes = {
447
- Label: ComponentType<FormLabelElementProps>;
448
- Input: ComponentType<FormInputElementProps>;
449
- Button: ComponentType<FormButtonElementProps>;
450
- };
451
- declare const FormDefaultElements: FormElementTypes;
460
+ declare function FormItem(props: FormItemProps): react_jsx_runtime.JSX.Element;
461
+ declare namespace FormItem {
462
+ var displayName: string;
463
+ var whyDidYouRender: boolean;
464
+ }
452
465
 
453
466
  type FormProps<Values extends Record<string, any> = Record<string, any>, FormElements extends FormElementTypes = FormElementTypes, Rules extends FormRules = typeof FormDefaultRules> = {
454
- items: FormLabelElementProps<FormElements, InferFormRulesOptions<Rules>>[];
467
+ items: FormItemProps<FormElements, InferFormRulesOptions<Rules>>[];
455
468
  onSubmit?: (values: Values) => Promise<void>;
456
469
  Elements?: Partial<FormElements>;
457
470
  lang?: Partial<FormLang>;
458
471
  defaultValues?: Values;
459
472
  rules?: typeof FormDefaultRules & Rules;
460
473
  };
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
+ */
461
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;
462
492
  declare namespace FormContainer {
463
493
  var displayName: string;
@@ -474,8 +504,8 @@ type FormContextProps<Values extends Record<string, any> = Record<string, any>,
474
504
  setSubmitting: Dispatch<SetStateAction<boolean>>;
475
505
  values: Values;
476
506
  setValues: Dispatch<SetStateAction<Values>>;
477
- errors: Record<string, FormError>;
478
- setErrors: Dispatch<SetStateAction<Record<string, FormError>>>;
507
+ errors: Record<string, Error>;
508
+ setErrors: Dispatch<SetStateAction<Record<string, Error>>>;
479
509
  };
480
510
  declare const FormContextProvider: <NewT extends FormContextProps<Record<string, any>, FormRules> = FormContextProps<Record<string, any>, FormRules>>(props: {
481
511
  value?: Partial<NewT>;
@@ -485,4 +515,4 @@ declare const FormContextProvider: <NewT extends FormContextProps<Record<string,
485
515
  }) => react.ReactNode;
486
516
  declare const useFormContext: <NewT extends FormContextProps<Record<string, any>, FormRules> = FormContextProps<Record<string, any>, FormRules>>() => Readonly<NewT>;
487
517
 
488
- 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
@@ -408,6 +408,22 @@ type FormInputElementProps = {
408
408
  onChange: (value: any) => void;
409
409
  };
410
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
+
411
427
  declare const FormDefaultLang: {
412
428
  submit: string;
413
429
  required: string;
@@ -416,17 +432,15 @@ declare const FormDefaultLang: {
416
432
  };
417
433
  type FormLang = typeof FormDefaultLang;
418
434
 
419
- type FormError = {
420
- message: string;
421
- };
422
- type FormRule<Options = any> = (value: any, options?: Options, lang?: FormLang) => Promise<FormError | undefined>;
423
- type InferRuleOption<T> = T extends (value: any, options: infer O, lang?: FormLang) => Promise<FormError | undefined> ? O : never;
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;
424
437
  type FormRules = Record<string, FormRule>;
425
438
  type InferFormRulesOptions<T> = {
426
439
  [K in keyof T]: InferRuleOption<T[K]>;
427
440
  };
428
441
  declare const FormDefaultRules: FormRules;
429
442
  type FormDefaultRulesOptions = InferFormRulesOptions<typeof FormDefaultRules>;
443
+ declare function validValues(rules: FormRules, items: FormItemProps[], values: Record<string, any>, lang: FormLang): Promise<Record<string, Error>>;
430
444
 
431
445
  type InferFormInputProps<T extends ComponentType<FormInputElementProps> | JSXElementConstructor<any>> = T extends ComponentType<FormInputElementProps> ? Omit<ComponentProps<T>, 'name' | 'value' | 'onChange'> : Omit<ComponentProps<T>, 'name' | 'value'>;
432
446
  type FormInputProps<FormElements extends FormElementTypes = FormElementTypes> = {
@@ -434,30 +448,46 @@ type FormInputProps<FormElements extends FormElementTypes = FormElementTypes> =
434
448
  props?: InferFormInputProps<FormElements['Input']>;
435
449
  };
436
450
 
437
- type FormLabelElementProps<FormElements extends FormElementTypes = FormElementTypes, FormRulesOptions extends Record<string, any> = FormDefaultRulesOptions> = {
438
- name: string;
439
- rules?: FormRulesOptions;
440
- title?: ReactNode;
441
- description?: ReactNode;
442
- Label?: FormElements['Label'];
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
+ };
443
457
  input?: FormInputProps<FormElements>;
458
+ rules?: FormRulesOptions;
444
459
  };
445
-
446
- type FormElementTypes = {
447
- Label: ComponentType<FormLabelElementProps>;
448
- Input: ComponentType<FormInputElementProps>;
449
- Button: ComponentType<FormButtonElementProps>;
450
- };
451
- declare const FormDefaultElements: FormElementTypes;
460
+ declare function FormItem(props: FormItemProps): react_jsx_runtime.JSX.Element;
461
+ declare namespace FormItem {
462
+ var displayName: string;
463
+ var whyDidYouRender: boolean;
464
+ }
452
465
 
453
466
  type FormProps<Values extends Record<string, any> = Record<string, any>, FormElements extends FormElementTypes = FormElementTypes, Rules extends FormRules = typeof FormDefaultRules> = {
454
- items: FormLabelElementProps<FormElements, InferFormRulesOptions<Rules>>[];
467
+ items: FormItemProps<FormElements, InferFormRulesOptions<Rules>>[];
455
468
  onSubmit?: (values: Values) => Promise<void>;
456
469
  Elements?: Partial<FormElements>;
457
470
  lang?: Partial<FormLang>;
458
471
  defaultValues?: Values;
459
472
  rules?: typeof FormDefaultRules & Rules;
460
473
  };
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
+ */
461
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;
462
492
  declare namespace FormContainer {
463
493
  var displayName: string;
@@ -474,8 +504,8 @@ type FormContextProps<Values extends Record<string, any> = Record<string, any>,
474
504
  setSubmitting: Dispatch<SetStateAction<boolean>>;
475
505
  values: Values;
476
506
  setValues: Dispatch<SetStateAction<Values>>;
477
- errors: Record<string, FormError>;
478
- setErrors: Dispatch<SetStateAction<Record<string, FormError>>>;
507
+ errors: Record<string, Error>;
508
+ setErrors: Dispatch<SetStateAction<Record<string, Error>>>;
479
509
  };
480
510
  declare const FormContextProvider: <NewT extends FormContextProps<Record<string, any>, FormRules> = FormContextProps<Record<string, any>, FormRules>>(props: {
481
511
  value?: Partial<NewT>;
@@ -485,4 +515,4 @@ declare const FormContextProvider: <NewT extends FormContextProps<Record<string,
485
515
  }) => react.ReactNode;
486
516
  declare const useFormContext: <NewT extends FormContextProps<Record<string, any>, FormRules> = FormContextProps<Record<string, any>, FormRules>>() => Readonly<NewT>;
487
517
 
488
- 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
  }
@@ -360,16 +359,27 @@ var FormContext = createSplittingContext([
360
359
  ]);
361
360
  var FormContextProvider = FormContext.Provider;
362
361
  var useFormContext = FormContext.use;
363
- function FormLabel(props) {
364
- const { Elements } = useFormContext();
365
- if (props.Label) return /* @__PURE__ */ jsxRuntime.jsx(props.Label, { ...props });
366
- return /* @__PURE__ */ jsxRuntime.jsx(Elements.Label, { ...props });
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
+ ) });
367
377
  }
368
- FormLabel.displayName = "FormLabel";
369
- FormLabel.whyDidYouRender = true;
378
+ FormItem.displayName = "FormItem";
379
+ FormItem.whyDidYouRender = true;
370
380
  function FormBody() {
371
381
  const { items } = useFormContext();
372
- return items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(FormLabel, { ...item }, item.name));
382
+ return items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(FormItem, { ...item }, item.name));
373
383
  }
374
384
  FormBody.displayName = "FormBody";
375
385
  FormBody.whyDidYouRender = true;
@@ -378,20 +388,16 @@ FormBody.whyDidYouRender = true;
378
388
  var FormDefaultRules = {
379
389
  required: async (value, _, lang) => {
380
390
  if (value === null || value === void 0 || value === "" || Number.isNaN(value)) {
381
- return { message: lang?.required };
391
+ throw Error(lang?.required);
382
392
  }
383
393
  },
384
394
  type: async (value, options, lang) => {
385
395
  switch (options) {
386
396
  case "string":
387
- if (typeof value !== "string") {
388
- return { message: lang?.string };
389
- }
397
+ if (typeof value !== "string") throw Error(lang?.string);
390
398
  break;
391
399
  case "number":
392
- if (Number.isNaN(Number(value))) {
393
- return { message: lang?.number };
394
- }
400
+ if (Number.isNaN(Number(value))) throw Error(lang?.number);
395
401
  break;
396
402
  }
397
403
  },
@@ -406,13 +412,9 @@ async function validValues(rules, items, values, lang) {
406
412
  const rulesOptions = item.rules;
407
413
  if (rulesOptions) {
408
414
  for (const [name, options] of Object.entries(rulesOptions)) {
409
- const handler = rules[name];
410
- if (!handler) {
411
- console.warn(`Rule "${name}" is not defined`);
412
- continue;
413
- }
414
- const error = await handler(value, options, lang);
415
- if (error) {
415
+ try {
416
+ await rules[name](value, options, lang);
417
+ } catch (error) {
416
418
  errors[item.name] = error;
417
419
  break;
418
420
  }
@@ -473,45 +475,14 @@ var FormLabelElement = ({
473
475
  name,
474
476
  title,
475
477
  description,
476
- Label,
477
- input
478
+ error,
479
+ children
478
480
  }) => {
479
- const { values, setValues, errors } = useFormContext();
480
- if (Label)
481
- return /* @__PURE__ */ jsxRuntime.jsx(
482
- Label,
483
- {
484
- name,
485
- title,
486
- description,
487
- input
488
- }
489
- );
490
481
  return /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
491
482
  title ?? name,
492
- input?.Input ? /* @__PURE__ */ jsxRuntime.jsx(
493
- input.Input,
494
- {
495
- name,
496
- value: values[name],
497
- onChange: (v) => setValues((prev) => ({
498
- ...prev,
499
- [name]: v
500
- }))
501
- }
502
- ) : /* @__PURE__ */ jsxRuntime.jsx(
503
- FormInputElement,
504
- {
505
- name,
506
- value: values[name],
507
- onChange: (v) => setValues((prev) => ({
508
- ...prev,
509
- [name]: v
510
- }))
511
- }
512
- ),
483
+ children,
513
484
  description,
514
- errors[name]?.message
485
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "red" }, children: error.message })
515
486
  ] });
516
487
  };
517
488
  FormLabelElement.displayName = "FormLabelElement";
@@ -576,6 +547,8 @@ exports.FaasReactClient = FaasReactClient;
576
547
  exports.Form = FormContainer;
577
548
  exports.FormContextProvider = FormContextProvider;
578
549
  exports.FormDefaultElements = FormDefaultElements;
550
+ exports.FormDefaultRules = FormDefaultRules;
551
+ exports.FormItem = FormItem;
579
552
  exports.OptionalWrapper = OptionalWrapper;
580
553
  exports.createSplittingContext = createSplittingContext;
581
554
  exports.equal = equal;
@@ -589,4 +562,5 @@ exports.useEqualMemoize = useEqualMemoize;
589
562
  exports.useFaas = useFaas;
590
563
  exports.useFormContext = useFormContext;
591
564
  exports.useSplittingState = useSplittingState;
565
+ exports.validValues = validValues;
592
566
  exports.withFaasData = withFaasData;
package/dist/index.mjs CHANGED
@@ -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
  }
@@ -358,16 +357,27 @@ var FormContext = createSplittingContext([
358
357
  ]);
359
358
  var FormContextProvider = FormContext.Provider;
360
359
  var useFormContext = FormContext.use;
361
- function FormLabel(props) {
362
- const { Elements } = useFormContext();
363
- if (props.Label) return /* @__PURE__ */ jsx(props.Label, { ...props });
364
- return /* @__PURE__ */ jsx(Elements.Label, { ...props });
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
+ ) });
365
375
  }
366
- FormLabel.displayName = "FormLabel";
367
- FormLabel.whyDidYouRender = true;
376
+ FormItem.displayName = "FormItem";
377
+ FormItem.whyDidYouRender = true;
368
378
  function FormBody() {
369
379
  const { items } = useFormContext();
370
- return items.map((item) => /* @__PURE__ */ jsx(FormLabel, { ...item }, item.name));
380
+ return items.map((item) => /* @__PURE__ */ jsx(FormItem, { ...item }, item.name));
371
381
  }
372
382
  FormBody.displayName = "FormBody";
373
383
  FormBody.whyDidYouRender = true;
@@ -376,20 +386,16 @@ FormBody.whyDidYouRender = true;
376
386
  var FormDefaultRules = {
377
387
  required: async (value, _, lang) => {
378
388
  if (value === null || value === void 0 || value === "" || Number.isNaN(value)) {
379
- return { message: lang?.required };
389
+ throw Error(lang?.required);
380
390
  }
381
391
  },
382
392
  type: async (value, options, lang) => {
383
393
  switch (options) {
384
394
  case "string":
385
- if (typeof value !== "string") {
386
- return { message: lang?.string };
387
- }
395
+ if (typeof value !== "string") throw Error(lang?.string);
388
396
  break;
389
397
  case "number":
390
- if (Number.isNaN(Number(value))) {
391
- return { message: lang?.number };
392
- }
398
+ if (Number.isNaN(Number(value))) throw Error(lang?.number);
393
399
  break;
394
400
  }
395
401
  },
@@ -404,13 +410,9 @@ async function validValues(rules, items, values, lang) {
404
410
  const rulesOptions = item.rules;
405
411
  if (rulesOptions) {
406
412
  for (const [name, options] of Object.entries(rulesOptions)) {
407
- const handler = rules[name];
408
- if (!handler) {
409
- console.warn(`Rule "${name}" is not defined`);
410
- continue;
411
- }
412
- const error = await handler(value, options, lang);
413
- if (error) {
413
+ try {
414
+ await rules[name](value, options, lang);
415
+ } catch (error) {
414
416
  errors[item.name] = error;
415
417
  break;
416
418
  }
@@ -471,45 +473,14 @@ var FormLabelElement = ({
471
473
  name,
472
474
  title,
473
475
  description,
474
- Label,
475
- input
476
+ error,
477
+ children
476
478
  }) => {
477
- const { values, setValues, errors } = useFormContext();
478
- if (Label)
479
- return /* @__PURE__ */ jsx(
480
- Label,
481
- {
482
- name,
483
- title,
484
- description,
485
- input
486
- }
487
- );
488
479
  return /* @__PURE__ */ jsxs("label", { children: [
489
480
  title ?? name,
490
- input?.Input ? /* @__PURE__ */ jsx(
491
- input.Input,
492
- {
493
- name,
494
- value: values[name],
495
- onChange: (v) => setValues((prev) => ({
496
- ...prev,
497
- [name]: v
498
- }))
499
- }
500
- ) : /* @__PURE__ */ jsx(
501
- FormInputElement,
502
- {
503
- name,
504
- value: values[name],
505
- onChange: (v) => setValues((prev) => ({
506
- ...prev,
507
- [name]: v
508
- }))
509
- }
510
- ),
481
+ children,
511
482
  description,
512
- errors[name]?.message
483
+ error && /* @__PURE__ */ jsx("div", { style: { color: "red" }, children: error.message })
513
484
  ] });
514
485
  };
515
486
  FormLabelElement.displayName = "FormLabelElement";
@@ -568,4 +539,4 @@ function FormContainer({
568
539
  FormContainer.displayName = "FormContainer";
569
540
  FormContainer.whyDidYouRender = true;
570
541
 
571
- 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.7",
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.7"
37
+ "@faasjs/browser": "3.7.0-beta.8"
38
38
  },
39
39
  "devDependencies": {
40
- "@faasjs/browser": "3.7.0-beta.7",
40
+ "@faasjs/browser": "3.7.0-beta.8",
41
41
  "@types/react": "*",
42
42
  "react": "*"
43
43
  },