@faasjs/react 3.7.0 → 3.7.1

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
@@ -404,18 +404,42 @@ declare const OptionalWrapper: React.FC<OptionalWrapperProps> & {
404
404
  whyDidYouRender: boolean;
405
405
  };
406
406
 
407
+ /**
408
+ * Props for the FormButtonElement component.
409
+ *
410
+ * @property {React.ReactNode} [children] - The content to be displayed inside the button.
411
+ * @property {boolean} disabled - Indicates whether the button is disabled.
412
+ * @property {() => Promise<void>} submit - A function to be called when the button is clicked, which returns a promise.
413
+ */
407
414
  type FormButtonElementProps = {
408
415
  children?: React.ReactNode;
409
416
  disabled: boolean;
410
417
  submit: () => Promise<void>;
411
418
  };
412
419
 
420
+ /**
421
+ * Props for the Form Input Element component.
422
+ *
423
+ * @property {string} name - The name of the input element.
424
+ * @property {any} value - The current value of the input element.
425
+ * @property {(value: any) => void} onChange - Callback function to handle changes to the input value.
426
+ */
413
427
  type FormInputElementProps = {
414
428
  name: string;
415
429
  value: any;
416
430
  onChange: (value: any) => void;
417
431
  };
418
432
 
433
+ /**
434
+ * Props for the FormLabelElement component.
435
+ *
436
+ * @typedef {Object} FormLabelElementProps
437
+ * @property {string} name - The name of the form element.
438
+ * @property {ReactNode} [title] - Optional title for the form element.
439
+ * @property {ReactNode} [description] - Optional description for the form element.
440
+ * @property {Error} [error] - Optional error associated with the form element.
441
+ * @property {ReactNode} children - The child elements, typically an input element.
442
+ */
419
443
  type FormLabelElementProps = {
420
444
  name: string;
421
445
  title?: ReactNode;
@@ -425,6 +449,14 @@ type FormLabelElementProps = {
425
449
  children: ReactNode;
426
450
  };
427
451
 
452
+ /**
453
+ * Represents the types of form elements used in the form.
454
+ *
455
+ * @typedef {Object} FormElementTypes
456
+ * @property {ComponentType<FormLabelElementProps>} Label - The component type for the form label element.
457
+ * @property {ComponentType<FormInputElementProps>} Input - The component type for the form input element.
458
+ * @property {ComponentType<FormButtonElementProps>} Button - The component type for the form button element.
459
+ */
428
460
  type FormElementTypes = {
429
461
  Label: ComponentType<FormLabelElementProps>;
430
462
  Input: ComponentType<FormInputElementProps>;
@@ -440,12 +472,44 @@ declare const FormDefaultLang: {
440
472
  };
441
473
  type FormLang = typeof FormDefaultLang;
442
474
 
475
+ /**
476
+ * A type representing a form validation rule.
477
+ *
478
+ * @template Options - The type of the options that can be passed to the rule.
479
+ *
480
+ * @param value - The value to be validated.
481
+ * @param options - Optional. Additional options that can be used in the validation.
482
+ * @param lang - Optional. The language settings that can be used in the validation.
483
+ *
484
+ * @returns A promise that resolves if the validation is successful, or rejects with an error if the validation fails.
485
+ *
486
+ * @example
487
+ * ```ts
488
+ * async function required(value: any, options: boolean, lang?: FormLang) {
489
+ * if (value === null || value === undefined || value === '' || Number.isNaN(value))
490
+ * throw Error(lang?.required)
491
+ * }
492
+ * ```
493
+ */
443
494
  type FormRule<Options = any> = (value: any, options?: Options, lang?: FormLang) => Promise<void>;
444
495
  type InferRuleOption<T> = T extends (value: any, options: infer O, lang?: FormLang) => Promise<void> ? O : never;
496
+ /**
497
+ * A type representing a set of form validation rules.
498
+ *
499
+ * @typedef {Record<string, FormRule>} FormRules
500
+ *
501
+ * Each key in the record represents the name of a form field, and the corresponding value is a `FormRule` object that defines the validation rules for that field.
502
+ */
445
503
  type FormRules = Record<string, FormRule>;
446
504
  type InferFormRulesOptions<T> = {
447
505
  [K in keyof T]: InferRuleOption<T[K]>;
448
506
  };
507
+ /**
508
+ * Default validation rules for a form.
509
+ *
510
+ * @constant
511
+ * @type {FormRules}
512
+ */
449
513
  declare const FormDefaultRules: FormRules;
450
514
  type FormDefaultRulesOptions = InferFormRulesOptions<typeof FormDefaultRules>;
451
515
  declare function validValues(rules: FormRules, items: FormItemProps[], values: Record<string, any>, lang: FormLang): Promise<Record<string, Error>>;
@@ -495,6 +559,19 @@ type FormProps<Values extends Record<string, any> = Record<string, any>, FormEle
495
559
  * @param {Partial<FormContextProps>} props - Additional properties for the form context.
496
560
  *
497
561
  * @returns {JSX.Element} The FormContainer component.
562
+ *
563
+ * @example
564
+ * ```tsx
565
+ * import { Form } from '@faasjs/react'
566
+ *
567
+ * function MyForm() {
568
+ * return <Form
569
+ * items={[
570
+ * { name: 'name' },
571
+ * ]}
572
+ * />
573
+ * }
574
+ * ```
498
575
  */
499
576
  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;
500
577
  declare namespace FormContainer {
package/dist/index.d.ts CHANGED
@@ -404,18 +404,42 @@ declare const OptionalWrapper: React.FC<OptionalWrapperProps> & {
404
404
  whyDidYouRender: boolean;
405
405
  };
406
406
 
407
+ /**
408
+ * Props for the FormButtonElement component.
409
+ *
410
+ * @property {React.ReactNode} [children] - The content to be displayed inside the button.
411
+ * @property {boolean} disabled - Indicates whether the button is disabled.
412
+ * @property {() => Promise<void>} submit - A function to be called when the button is clicked, which returns a promise.
413
+ */
407
414
  type FormButtonElementProps = {
408
415
  children?: React.ReactNode;
409
416
  disabled: boolean;
410
417
  submit: () => Promise<void>;
411
418
  };
412
419
 
420
+ /**
421
+ * Props for the Form Input Element component.
422
+ *
423
+ * @property {string} name - The name of the input element.
424
+ * @property {any} value - The current value of the input element.
425
+ * @property {(value: any) => void} onChange - Callback function to handle changes to the input value.
426
+ */
413
427
  type FormInputElementProps = {
414
428
  name: string;
415
429
  value: any;
416
430
  onChange: (value: any) => void;
417
431
  };
418
432
 
433
+ /**
434
+ * Props for the FormLabelElement component.
435
+ *
436
+ * @typedef {Object} FormLabelElementProps
437
+ * @property {string} name - The name of the form element.
438
+ * @property {ReactNode} [title] - Optional title for the form element.
439
+ * @property {ReactNode} [description] - Optional description for the form element.
440
+ * @property {Error} [error] - Optional error associated with the form element.
441
+ * @property {ReactNode} children - The child elements, typically an input element.
442
+ */
419
443
  type FormLabelElementProps = {
420
444
  name: string;
421
445
  title?: ReactNode;
@@ -425,6 +449,14 @@ type FormLabelElementProps = {
425
449
  children: ReactNode;
426
450
  };
427
451
 
452
+ /**
453
+ * Represents the types of form elements used in the form.
454
+ *
455
+ * @typedef {Object} FormElementTypes
456
+ * @property {ComponentType<FormLabelElementProps>} Label - The component type for the form label element.
457
+ * @property {ComponentType<FormInputElementProps>} Input - The component type for the form input element.
458
+ * @property {ComponentType<FormButtonElementProps>} Button - The component type for the form button element.
459
+ */
428
460
  type FormElementTypes = {
429
461
  Label: ComponentType<FormLabelElementProps>;
430
462
  Input: ComponentType<FormInputElementProps>;
@@ -440,12 +472,44 @@ declare const FormDefaultLang: {
440
472
  };
441
473
  type FormLang = typeof FormDefaultLang;
442
474
 
475
+ /**
476
+ * A type representing a form validation rule.
477
+ *
478
+ * @template Options - The type of the options that can be passed to the rule.
479
+ *
480
+ * @param value - The value to be validated.
481
+ * @param options - Optional. Additional options that can be used in the validation.
482
+ * @param lang - Optional. The language settings that can be used in the validation.
483
+ *
484
+ * @returns A promise that resolves if the validation is successful, or rejects with an error if the validation fails.
485
+ *
486
+ * @example
487
+ * ```ts
488
+ * async function required(value: any, options: boolean, lang?: FormLang) {
489
+ * if (value === null || value === undefined || value === '' || Number.isNaN(value))
490
+ * throw Error(lang?.required)
491
+ * }
492
+ * ```
493
+ */
443
494
  type FormRule<Options = any> = (value: any, options?: Options, lang?: FormLang) => Promise<void>;
444
495
  type InferRuleOption<T> = T extends (value: any, options: infer O, lang?: FormLang) => Promise<void> ? O : never;
496
+ /**
497
+ * A type representing a set of form validation rules.
498
+ *
499
+ * @typedef {Record<string, FormRule>} FormRules
500
+ *
501
+ * Each key in the record represents the name of a form field, and the corresponding value is a `FormRule` object that defines the validation rules for that field.
502
+ */
445
503
  type FormRules = Record<string, FormRule>;
446
504
  type InferFormRulesOptions<T> = {
447
505
  [K in keyof T]: InferRuleOption<T[K]>;
448
506
  };
507
+ /**
508
+ * Default validation rules for a form.
509
+ *
510
+ * @constant
511
+ * @type {FormRules}
512
+ */
449
513
  declare const FormDefaultRules: FormRules;
450
514
  type FormDefaultRulesOptions = InferFormRulesOptions<typeof FormDefaultRules>;
451
515
  declare function validValues(rules: FormRules, items: FormItemProps[], values: Record<string, any>, lang: FormLang): Promise<Record<string, Error>>;
@@ -495,6 +559,19 @@ type FormProps<Values extends Record<string, any> = Record<string, any>, FormEle
495
559
  * @param {Partial<FormContextProps>} props - Additional properties for the form context.
496
560
  *
497
561
  * @returns {JSX.Element} The FormContainer component.
562
+ *
563
+ * @example
564
+ * ```tsx
565
+ * import { Form } from '@faasjs/react'
566
+ *
567
+ * function MyForm() {
568
+ * return <Form
569
+ * items={[
570
+ * { name: 'name' },
571
+ * ]}
572
+ * />
573
+ * }
574
+ * ```
498
575
  */
499
576
  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;
500
577
  declare namespace FormContainer {
package/dist/index.js CHANGED
@@ -364,21 +364,56 @@ var FormContext = createSplittingContext([
364
364
  ]);
365
365
  var FormContextProvider = FormContext.Provider;
366
366
  var useFormContext = FormContext.use;
367
- function FormItem(props) {
368
- const { Elements, values, setValues, errors } = useFormContext();
369
- const Label = props.label?.Label ?? Elements.Label;
370
- const Input = props.input?.Input ?? Elements.Input;
371
- return /* @__PURE__ */ jsxRuntime.jsx(Label, { name: props.name, ...props.label, error: errors[props.name], children: /* @__PURE__ */ jsxRuntime.jsx(
372
- Input,
367
+ function processValue(input, rules) {
368
+ switch (rules?.type) {
369
+ case "number":
370
+ return Number(input);
371
+ case "string":
372
+ return String(input);
373
+ default:
374
+ return input;
375
+ }
376
+ }
377
+ function FormInput({
378
+ name,
379
+ rules,
380
+ ...rest
381
+ }) {
382
+ const { Elements, values, setValues } = useFormContext();
383
+ const value = values?.[name];
384
+ if (rest.Input) {
385
+ return /* @__PURE__ */ jsxRuntime.jsx(
386
+ rest.Input,
387
+ {
388
+ name,
389
+ value,
390
+ onChange: (v) => setValues((prev) => ({
391
+ ...prev,
392
+ [name]: processValue(v, rules)
393
+ })),
394
+ ...rest.props
395
+ }
396
+ );
397
+ }
398
+ return /* @__PURE__ */ jsxRuntime.jsx(
399
+ Elements.Input,
373
400
  {
374
- name: props.name,
375
- value: values[props.name],
401
+ name,
402
+ value,
376
403
  onChange: (v) => setValues((prev) => ({
377
404
  ...prev,
378
- [props.name]: v
379
- }))
405
+ [name]: processValue(v, rules)
406
+ })),
407
+ ...rest.props
380
408
  }
381
- ) });
409
+ );
410
+ }
411
+ FormInput.displayName = "FormInput";
412
+ FormInput.whyDidYouRender = true;
413
+ function FormItem(props) {
414
+ const { Elements, errors } = useFormContext();
415
+ const Label = props.label?.Label ?? Elements.Label;
416
+ return /* @__PURE__ */ jsxRuntime.jsx(Label, { name: props.name, ...props.label, error: errors[props.name], children: /* @__PURE__ */ jsxRuntime.jsx(FormInput, { name: props.name, rules: props.rules, ...props.input }) });
382
417
  }
383
418
  FormItem.displayName = "FormItem";
384
419
  FormItem.whyDidYouRender = true;
package/dist/index.mjs CHANGED
@@ -362,21 +362,56 @@ var FormContext = createSplittingContext([
362
362
  ]);
363
363
  var FormContextProvider = FormContext.Provider;
364
364
  var useFormContext = FormContext.use;
365
- function FormItem(props) {
366
- const { Elements, values, setValues, errors } = useFormContext();
367
- const Label = props.label?.Label ?? Elements.Label;
368
- const Input = props.input?.Input ?? Elements.Input;
369
- return /* @__PURE__ */ jsx(Label, { name: props.name, ...props.label, error: errors[props.name], children: /* @__PURE__ */ jsx(
370
- Input,
365
+ function processValue(input, rules) {
366
+ switch (rules?.type) {
367
+ case "number":
368
+ return Number(input);
369
+ case "string":
370
+ return String(input);
371
+ default:
372
+ return input;
373
+ }
374
+ }
375
+ function FormInput({
376
+ name,
377
+ rules,
378
+ ...rest
379
+ }) {
380
+ const { Elements, values, setValues } = useFormContext();
381
+ const value = values?.[name];
382
+ if (rest.Input) {
383
+ return /* @__PURE__ */ jsx(
384
+ rest.Input,
385
+ {
386
+ name,
387
+ value,
388
+ onChange: (v) => setValues((prev) => ({
389
+ ...prev,
390
+ [name]: processValue(v, rules)
391
+ })),
392
+ ...rest.props
393
+ }
394
+ );
395
+ }
396
+ return /* @__PURE__ */ jsx(
397
+ Elements.Input,
371
398
  {
372
- name: props.name,
373
- value: values[props.name],
399
+ name,
400
+ value,
374
401
  onChange: (v) => setValues((prev) => ({
375
402
  ...prev,
376
- [props.name]: v
377
- }))
403
+ [name]: processValue(v, rules)
404
+ })),
405
+ ...rest.props
378
406
  }
379
- ) });
407
+ );
408
+ }
409
+ FormInput.displayName = "FormInput";
410
+ FormInput.whyDidYouRender = true;
411
+ function FormItem(props) {
412
+ const { Elements, errors } = useFormContext();
413
+ const Label = props.label?.Label ?? Elements.Label;
414
+ return /* @__PURE__ */ jsx(Label, { name: props.name, ...props.label, error: errors[props.name], children: /* @__PURE__ */ jsx(FormInput, { name: props.name, rules: props.rules, ...props.input }) });
380
415
  }
381
416
  FormItem.displayName = "FormItem";
382
417
  FormItem.whyDidYouRender = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faasjs/react",
3
- "version": "3.7.0",
3
+ "version": "3.7.1",
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"
37
+ "@faasjs/browser": "3.7.1"
38
38
  },
39
39
  "devDependencies": {
40
- "@faasjs/browser": "3.7.0",
40
+ "@faasjs/browser": "3.7.1",
41
41
  "@types/react": "*",
42
42
  "react": "*"
43
43
  },