@faasjs/react 3.7.0-beta.4 → 3.7.0-beta.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -264,6 +264,14 @@ type FaasReactClientOptions = {
264
264
  /** @default `/` */
265
265
  baseUrl?: BaseUrl;
266
266
  options?: Options;
267
+ /**
268
+ * @example
269
+ * ```ts
270
+ * onError: (action, params) => async (res) => {
271
+ * console.error(action, params, res)
272
+ * }
273
+ * ```
274
+ */
267
275
  onError?: OnError;
268
276
  };
269
277
  type FaasReactClientInstance = {
@@ -376,8 +384,8 @@ declare const OptionalWrapper: React.FC<OptionalWrapperProps> & {
376
384
 
377
385
  type FormButtonElementProps = {
378
386
  children?: React.ReactNode;
379
- disabled?: boolean;
380
- submit?: () => void;
387
+ disabled: boolean;
388
+ submit: () => Promise<void>;
381
389
  };
382
390
 
383
391
  type FormInputElementProps = {
@@ -386,9 +394,20 @@ type FormInputElementProps = {
386
394
  onChange: (value: any) => void;
387
395
  };
388
396
 
397
+ declare const FormDefaultLang: {
398
+ submit: string;
399
+ required: string;
400
+ number: string;
401
+ };
402
+ type FormLang = typeof FormDefaultLang;
403
+
389
404
  type FormRules = {
390
405
  type?: 'string' | 'number';
391
406
  required?: boolean;
407
+ custom?: (value: any) => Promise<FormError | undefined>;
408
+ };
409
+ type FormError = {
410
+ message: string;
392
411
  };
393
412
 
394
413
  type InferFormInputProps<T extends ComponentType<FormInputElementProps> | JSXElementConstructor<any>> = T extends ComponentType<FormInputElementProps> ? Omit<ComponentProps<T>, 'name' | 'value' | 'onChange'> : Omit<ComponentProps<T>, 'name' | 'value'>;
@@ -416,10 +435,11 @@ declare const FormDefaultElements: FormElementTypes;
416
435
  type FormProps<Values extends Record<string, any> = Record<string, any>, FormElements extends FormElementTypes = FormElementTypes> = {
417
436
  items: FormLabelElementProps<FormElements>[];
418
437
  onSubmit?: (values: Values) => Promise<void>;
419
- elements?: Partial<FormElements>;
438
+ Elements?: Partial<FormElements>;
439
+ lang?: Partial<FormLang>;
420
440
  defaultValues?: Values;
421
441
  };
422
- declare function FormContainer<Values extends Record<string, any> = Record<string, any>, FormElements extends FormElementTypes = FormElementTypes>({ defaultValues, elements, ...props }: FormProps<Values, FormElements>): react_jsx_runtime.JSX.Element;
442
+ declare function FormContainer<Values extends Record<string, any> = Record<string, any>, FormElements extends FormElementTypes = FormElementTypes>({ defaultValues, Elements, lang, ...props }: FormProps<Values, FormElements>): react_jsx_runtime.JSX.Element;
423
443
  declare namespace FormContainer {
424
444
  var displayName: string;
425
445
  var whyDidYouRender: boolean;
@@ -429,10 +449,13 @@ type FormContextProps<Values extends Record<string, any> = Record<string, any>>
429
449
  items: FormLabelElementProps[];
430
450
  onSubmit: (values: Values) => Promise<void>;
431
451
  Elements: FormElementTypes;
452
+ lang: FormLang;
432
453
  submitting: boolean;
433
- setSubmitting: React.Dispatch<React.SetStateAction<boolean>>;
454
+ setSubmitting: Dispatch<SetStateAction<boolean>>;
434
455
  values: Values;
435
- setValues: React.Dispatch<React.SetStateAction<Values>>;
456
+ setValues: Dispatch<SetStateAction<Values>>;
457
+ errors: Record<string, FormError>;
458
+ setErrors: Dispatch<SetStateAction<Record<string, FormError>>>;
436
459
  };
437
460
  declare const FormContextProvider: <NewT extends FormContextProps<Record<string, any>> = FormContextProps<Record<string, any>>>(props: {
438
461
  value?: NewT;
package/dist/index.d.ts CHANGED
@@ -264,6 +264,14 @@ type FaasReactClientOptions = {
264
264
  /** @default `/` */
265
265
  baseUrl?: BaseUrl;
266
266
  options?: Options;
267
+ /**
268
+ * @example
269
+ * ```ts
270
+ * onError: (action, params) => async (res) => {
271
+ * console.error(action, params, res)
272
+ * }
273
+ * ```
274
+ */
267
275
  onError?: OnError;
268
276
  };
269
277
  type FaasReactClientInstance = {
@@ -376,8 +384,8 @@ declare const OptionalWrapper: React.FC<OptionalWrapperProps> & {
376
384
 
377
385
  type FormButtonElementProps = {
378
386
  children?: React.ReactNode;
379
- disabled?: boolean;
380
- submit?: () => void;
387
+ disabled: boolean;
388
+ submit: () => Promise<void>;
381
389
  };
382
390
 
383
391
  type FormInputElementProps = {
@@ -386,9 +394,20 @@ type FormInputElementProps = {
386
394
  onChange: (value: any) => void;
387
395
  };
388
396
 
397
+ declare const FormDefaultLang: {
398
+ submit: string;
399
+ required: string;
400
+ number: string;
401
+ };
402
+ type FormLang = typeof FormDefaultLang;
403
+
389
404
  type FormRules = {
390
405
  type?: 'string' | 'number';
391
406
  required?: boolean;
407
+ custom?: (value: any) => Promise<FormError | undefined>;
408
+ };
409
+ type FormError = {
410
+ message: string;
392
411
  };
393
412
 
394
413
  type InferFormInputProps<T extends ComponentType<FormInputElementProps> | JSXElementConstructor<any>> = T extends ComponentType<FormInputElementProps> ? Omit<ComponentProps<T>, 'name' | 'value' | 'onChange'> : Omit<ComponentProps<T>, 'name' | 'value'>;
@@ -416,10 +435,11 @@ declare const FormDefaultElements: FormElementTypes;
416
435
  type FormProps<Values extends Record<string, any> = Record<string, any>, FormElements extends FormElementTypes = FormElementTypes> = {
417
436
  items: FormLabelElementProps<FormElements>[];
418
437
  onSubmit?: (values: Values) => Promise<void>;
419
- elements?: Partial<FormElements>;
438
+ Elements?: Partial<FormElements>;
439
+ lang?: Partial<FormLang>;
420
440
  defaultValues?: Values;
421
441
  };
422
- declare function FormContainer<Values extends Record<string, any> = Record<string, any>, FormElements extends FormElementTypes = FormElementTypes>({ defaultValues, elements, ...props }: FormProps<Values, FormElements>): react_jsx_runtime.JSX.Element;
442
+ declare function FormContainer<Values extends Record<string, any> = Record<string, any>, FormElements extends FormElementTypes = FormElementTypes>({ defaultValues, Elements, lang, ...props }: FormProps<Values, FormElements>): react_jsx_runtime.JSX.Element;
423
443
  declare namespace FormContainer {
424
444
  var displayName: string;
425
445
  var whyDidYouRender: boolean;
@@ -429,10 +449,13 @@ type FormContextProps<Values extends Record<string, any> = Record<string, any>>
429
449
  items: FormLabelElementProps[];
430
450
  onSubmit: (values: Values) => Promise<void>;
431
451
  Elements: FormElementTypes;
452
+ lang: FormLang;
432
453
  submitting: boolean;
433
- setSubmitting: React.Dispatch<React.SetStateAction<boolean>>;
454
+ setSubmitting: Dispatch<SetStateAction<boolean>>;
434
455
  values: Values;
435
- setValues: React.Dispatch<React.SetStateAction<Values>>;
456
+ setValues: Dispatch<SetStateAction<Values>>;
457
+ errors: Record<string, FormError>;
458
+ setErrors: Dispatch<SetStateAction<Record<string, FormError>>>;
436
459
  };
437
460
  declare const FormContextProvider: <NewT extends FormContextProps<Record<string, any>> = FormContextProps<Record<string, any>>>(props: {
438
461
  value?: NewT;
package/dist/index.js CHANGED
@@ -20,6 +20,7 @@ function equal(a, b) {
20
20
  if ((a === null || a === void 0) && (b === null || b === void 0))
21
21
  return true;
22
22
  if (typeof a !== typeof b) return false;
23
+ if (b === null || b === void 0) return false;
23
24
  const ctor = a.constructor;
24
25
  if (ctor !== b.constructor) return false;
25
26
  switch (ctor) {
@@ -347,10 +348,13 @@ var FormContext = createSplittingContext([
347
348
  "items",
348
349
  "onSubmit",
349
350
  "Elements",
351
+ "lang",
350
352
  "submitting",
351
353
  "setSubmitting",
352
354
  "values",
353
- "setValues"
355
+ "setValues",
356
+ "errors",
357
+ "setErrors"
354
358
  ]);
355
359
  var FormContextProvider = FormContext.Provider;
356
360
  var useFormContext = FormContext.use;
@@ -367,17 +371,53 @@ function FormBody() {
367
371
  }
368
372
  FormBody.displayName = "FormBody";
369
373
  FormBody.whyDidYouRender = true;
374
+
375
+ // src/Form/rules.ts
376
+ async function validValue(rules, value, lang) {
377
+ if (rules.required && (value === null || value === void 0 || value === "" || Number.isNaN(value)))
378
+ return { message: lang.required };
379
+ if (rules.type === "number" && Number.isNaN(Number(value)))
380
+ return { message: lang.number };
381
+ return rules.custom?.(value);
382
+ }
383
+ async function validValues(items, values, lang) {
384
+ const errors = {};
385
+ for (const item of items) {
386
+ const value = values[item.name];
387
+ const rules = item.rules;
388
+ if (rules) {
389
+ const error = await validValue(rules, value, lang);
390
+ if (error) errors[item.name] = error;
391
+ }
392
+ }
393
+ return errors;
394
+ }
370
395
  function FormFooter() {
371
- const { submitting, setSubmitting, onSubmit, values, Elements } = useFormContext();
396
+ const {
397
+ submitting,
398
+ setSubmitting,
399
+ onSubmit,
400
+ values,
401
+ Elements,
402
+ items,
403
+ setErrors,
404
+ lang
405
+ } = useFormContext();
372
406
  return /* @__PURE__ */ jsxRuntime.jsx(
373
407
  Elements.Button,
374
408
  {
375
409
  disabled: submitting,
376
- submit: () => {
410
+ submit: async () => {
377
411
  setSubmitting(true);
412
+ const errors = await validValues(items, values, lang);
413
+ if (Object.keys(errors).length) {
414
+ setErrors(errors);
415
+ setSubmitting(false);
416
+ return;
417
+ }
378
418
  onSubmit(values).finally(() => setSubmitting(false));
379
419
  },
380
- children: "Submit"
420
+ children: lang.submit
381
421
  }
382
422
  );
383
423
  }
@@ -406,7 +446,7 @@ var FormLabelElement = ({
406
446
  Label,
407
447
  input
408
448
  }) => {
409
- const { values, setValues } = useFormContext();
449
+ const { values, setValues, errors } = useFormContext();
410
450
  if (Label)
411
451
  return /* @__PURE__ */ jsxRuntime.jsx(
412
452
  Label,
@@ -440,7 +480,8 @@ var FormLabelElement = ({
440
480
  }))
441
481
  }
442
482
  ),
443
- description
483
+ description,
484
+ errors[name]?.message
444
485
  ] });
445
486
  };
446
487
  FormLabelElement.displayName = "FormLabelElement";
@@ -452,17 +493,31 @@ var FormDefaultElements = {
452
493
  Input: FormInputElement,
453
494
  Button: FormButtonElement
454
495
  };
496
+
497
+ // src/Form/lang.ts
498
+ var FormDefaultLang = {
499
+ submit: "Submit",
500
+ required: "This field is required",
501
+ number: "This field must be a number"
502
+ };
455
503
  function mergeValues(items, defaultValues = {}) {
456
504
  const values = {};
457
505
  for (const item of items)
458
506
  values[item.name] = defaultValues[item.name] ?? "";
459
507
  return values;
460
508
  }
461
- function FormContainer({ defaultValues, elements, ...props }) {
509
+ function FormContainer({
510
+ defaultValues,
511
+ Elements,
512
+ lang,
513
+ ...props
514
+ }) {
462
515
  const states = useSplittingState({
463
516
  values: mergeValues(props.items, defaultValues),
517
+ errors: {},
464
518
  submitting: false,
465
- Elements: Object.assign(FormDefaultElements, elements)
519
+ Elements: Object.assign(FormDefaultElements, Elements),
520
+ lang: Object.assign(FormDefaultLang, lang)
466
521
  });
467
522
  return /* @__PURE__ */ jsxRuntime.jsxs(
468
523
  FormContextProvider,
package/dist/index.mjs CHANGED
@@ -18,6 +18,7 @@ function equal(a, b) {
18
18
  if ((a === null || a === void 0) && (b === null || b === void 0))
19
19
  return true;
20
20
  if (typeof a !== typeof b) return false;
21
+ if (b === null || b === void 0) return false;
21
22
  const ctor = a.constructor;
22
23
  if (ctor !== b.constructor) return false;
23
24
  switch (ctor) {
@@ -345,10 +346,13 @@ var FormContext = createSplittingContext([
345
346
  "items",
346
347
  "onSubmit",
347
348
  "Elements",
349
+ "lang",
348
350
  "submitting",
349
351
  "setSubmitting",
350
352
  "values",
351
- "setValues"
353
+ "setValues",
354
+ "errors",
355
+ "setErrors"
352
356
  ]);
353
357
  var FormContextProvider = FormContext.Provider;
354
358
  var useFormContext = FormContext.use;
@@ -365,17 +369,53 @@ function FormBody() {
365
369
  }
366
370
  FormBody.displayName = "FormBody";
367
371
  FormBody.whyDidYouRender = true;
372
+
373
+ // src/Form/rules.ts
374
+ async function validValue(rules, value, lang) {
375
+ if (rules.required && (value === null || value === void 0 || value === "" || Number.isNaN(value)))
376
+ return { message: lang.required };
377
+ if (rules.type === "number" && Number.isNaN(Number(value)))
378
+ return { message: lang.number };
379
+ return rules.custom?.(value);
380
+ }
381
+ async function validValues(items, values, lang) {
382
+ const errors = {};
383
+ for (const item of items) {
384
+ const value = values[item.name];
385
+ const rules = item.rules;
386
+ if (rules) {
387
+ const error = await validValue(rules, value, lang);
388
+ if (error) errors[item.name] = error;
389
+ }
390
+ }
391
+ return errors;
392
+ }
368
393
  function FormFooter() {
369
- const { submitting, setSubmitting, onSubmit, values, Elements } = useFormContext();
394
+ const {
395
+ submitting,
396
+ setSubmitting,
397
+ onSubmit,
398
+ values,
399
+ Elements,
400
+ items,
401
+ setErrors,
402
+ lang
403
+ } = useFormContext();
370
404
  return /* @__PURE__ */ jsx(
371
405
  Elements.Button,
372
406
  {
373
407
  disabled: submitting,
374
- submit: () => {
408
+ submit: async () => {
375
409
  setSubmitting(true);
410
+ const errors = await validValues(items, values, lang);
411
+ if (Object.keys(errors).length) {
412
+ setErrors(errors);
413
+ setSubmitting(false);
414
+ return;
415
+ }
376
416
  onSubmit(values).finally(() => setSubmitting(false));
377
417
  },
378
- children: "Submit"
418
+ children: lang.submit
379
419
  }
380
420
  );
381
421
  }
@@ -404,7 +444,7 @@ var FormLabelElement = ({
404
444
  Label,
405
445
  input
406
446
  }) => {
407
- const { values, setValues } = useFormContext();
447
+ const { values, setValues, errors } = useFormContext();
408
448
  if (Label)
409
449
  return /* @__PURE__ */ jsx(
410
450
  Label,
@@ -438,7 +478,8 @@ var FormLabelElement = ({
438
478
  }))
439
479
  }
440
480
  ),
441
- description
481
+ description,
482
+ errors[name]?.message
442
483
  ] });
443
484
  };
444
485
  FormLabelElement.displayName = "FormLabelElement";
@@ -450,17 +491,31 @@ var FormDefaultElements = {
450
491
  Input: FormInputElement,
451
492
  Button: FormButtonElement
452
493
  };
494
+
495
+ // src/Form/lang.ts
496
+ var FormDefaultLang = {
497
+ submit: "Submit",
498
+ required: "This field is required",
499
+ number: "This field must be a number"
500
+ };
453
501
  function mergeValues(items, defaultValues = {}) {
454
502
  const values = {};
455
503
  for (const item of items)
456
504
  values[item.name] = defaultValues[item.name] ?? "";
457
505
  return values;
458
506
  }
459
- function FormContainer({ defaultValues, elements, ...props }) {
507
+ function FormContainer({
508
+ defaultValues,
509
+ Elements,
510
+ lang,
511
+ ...props
512
+ }) {
460
513
  const states = useSplittingState({
461
514
  values: mergeValues(props.items, defaultValues),
515
+ errors: {},
462
516
  submitting: false,
463
- Elements: Object.assign(FormDefaultElements, elements)
517
+ Elements: Object.assign(FormDefaultElements, Elements),
518
+ lang: Object.assign(FormDefaultLang, lang)
464
519
  });
465
520
  return /* @__PURE__ */ jsxs(
466
521
  FormContextProvider,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faasjs/react",
3
- "version": "3.7.0-beta.4",
3
+ "version": "3.7.0-beta.6",
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.4"
37
+ "@faasjs/browser": "3.7.0-beta.6"
38
38
  },
39
39
  "devDependencies": {
40
- "@faasjs/browser": "3.7.0-beta.4",
40
+ "@faasjs/browser": "3.7.0-beta.6",
41
41
  "@types/react": "*",
42
42
  "react": "*"
43
43
  },