forms.ts 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import { useEffect, useState, FormEvent, ChangeEvent, SyntheticEvent } from 'react'
  2. import { getValue, setValue } from '../../lib/array'
  3. import TextInput from './TextInput'
  4. export interface InputProps {
  5. id: string,
  6. name: string,
  7. value: any,
  8. onChange: (event: ChangeEvent) => void,
  9. onBlur: (event: SyntheticEvent) => void,
  10. placeholder: string,
  11. label: string
  12. }
  13. export interface InputPropsOptions {
  14. label?: string
  15. subtree?: string
  16. }
  17. interface FormHandler<ValueObject> {
  18. values: ValueObject,
  19. errors: Dict,
  20. isSubmitting: boolean,
  21. setValues: (values: ValueObject) => void
  22. inputProps: (name: string) => InputProps,
  23. handleChange: (event: ChangeEvent) => void,
  24. handleBlur: (event: SyntheticEvent) => void,
  25. handleSubmit: (event: FormEvent, data: any) => void
  26. }
  27. /**
  28. * Provides hooks for forms.
  29. *
  30. * @remarks
  31. * You can use it like this
  32. * ```ts
  33. * const {inputParams, formParams} = useFormHandler()
  34. * ```
  35. *
  36. * @param initialValues - Initial values of inputs
  37. * @param validate - validation function for the form
  38. * @returns hooks to handle the form
  39. */
  40. function useFormHandler<ValueObject>(
  41. initialValues: ValueObject,
  42. validate?: (values: Dict) => {},
  43. submit?: (data: any) => {}
  44. ): FormHandler<ValueObject> {
  45. const [values, setValues] = useState(initialValues)
  46. const [errors, setErrors] = useState({})
  47. const [isSubmitting, setIsSubmitting] = useState(false)
  48. function handleChange(event: ChangeEvent): void {
  49. const target = (event.target as HTMLInputElement)
  50. console.log('change', values, target.name)
  51. setValues({
  52. ...values,
  53. [target.name]: target.value
  54. })
  55. }
  56. function handleBlur(event: SyntheticEvent): void {
  57. if (validate) {
  58. const validationErrors = validate(values)
  59. setErrors(validationErrors)
  60. }
  61. }
  62. function handleSubmit(event: FormEvent, data: any): void {
  63. event.preventDefault()
  64. if (submit) {
  65. submit(data)
  66. }
  67. }
  68. // users[3].name
  69. function inputProps(name: string, options?: InputPropsOptions): InputProps {
  70. const subtree = options && options.subtree
  71. return {
  72. id: [subtree, name].join('.'),
  73. name: name,
  74. value: getValue(values, name),
  75. onChange: handleChange,
  76. onBlur: handleBlur,
  77. placeholder: options && options.label || name,
  78. label: options && options.label || name
  79. }
  80. }
  81. return {
  82. values,
  83. errors,
  84. isSubmitting,
  85. setValues,
  86. inputProps,
  87. handleChange,
  88. handleBlur,
  89. handleSubmit
  90. }
  91. }
  92. export { useFormHandler, TextInput }