{"id":20305102,"url":"https://github.com/avcs06/react-form","last_synced_at":"2025-10-08T11:05:13.391Z","repository":{"id":57925270,"uuid":"508667221","full_name":"avcs06/react-form","owner":"avcs06","description":"A context \u0026 hook based react form. Supports dirty-check, validation, reset and save functionalities of form","archived":false,"fork":false,"pushed_at":"2023-01-27T14:21:54.000Z","size":834,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-03-25T09:46:25.372Z","etag":null,"topics":["dirty","dirty-check","form","form-validation","forms","react","react-hooks","reactjs","reset-form","submit-form"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/avcs06.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-06-29T11:41:24.000Z","updated_at":"2022-10-25T08:50:46.000Z","dependencies_parsed_at":"2023-02-15T10:01:39.547Z","dependency_job_id":null,"html_url":"https://github.com/avcs06/react-form","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/avcs06/react-form","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avcs06%2Freact-form","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avcs06%2Freact-form/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avcs06%2Freact-form/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avcs06%2Freact-form/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/avcs06","download_url":"https://codeload.github.com/avcs06/react-form/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avcs06%2Freact-form/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278931654,"owners_count":26070789,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dirty","dirty-check","form","form-validation","forms","react","react-hooks","reactjs","reset-form","submit-form"],"created_at":"2024-11-14T17:07:16.689Z","updated_at":"2025-10-08T11:05:13.370Z","avatar_url":"https://github.com/avcs06.png","language":"TypeScript","readme":"\n# react-form\nA context \u0026 hook based react form. Supports dirty-check, validation, reset and save functionalities of form\n\n## Features\n- Dirty Checking\n  - Dirty checks for both individual fields and whole form\n  - Marks current values as pristine on successful submit\n  - Single method tp reset the complete form to last known pristine values\n\n- Validation\n  - Supports writing your own custom validation rules\n  - Live validation at both individual field level and whole form level\n  - Does not check for required field errors until first submit\n  - Live validation for required fields after first submit\n\n- General\n  - Supports changing the initial form data\n  - Pure API, can be integrated with all available UI libraries seamlessly\n  - [Small size, tree-shakable and no dependancies](https://bundlephobia.com/package/@avcs/react-form@latest)\n\n## Installation\n```bash\n npm i --save @avcs/react-form\n```\n\n## Documentation\n```typescript\nuseForm: ReactHook\n\narguments: [{\n  // initial form object\n  formData: { [string | symbol]: any };\\\n  // Optional Event handler if you want to listen to changes in form\n  onFormChange?: (formMeta: { isFormDirty: boolean, formData: { [string | symbol]: any } }) =\u003e void;\n  // Optional Event handler if you want to listen to changes in form errors\n  onErrorChange?: (errorMeta: { hasErrors: boolean, errors: { [string | symbol]: any } }) =\u003e void;\n}]\n\nreturnValue: {\n  /* Handle submit action, accepts 2 params onSubmit \u0026 onError. validates required errors\n   *     any changes from this state will be considered dirty in future\n   *   will execute onSubmit if there are no errors\n   *   will mark the form as pristine if onSubmit returns anything other than false\n   *   will execute onError if there are any errors\n   */\n  handleSubmit: (\n    onSubmit: (formData: { [string | symbol]: any }) =\u003e any,\n    onError: (errors: { [string | symbol]: any }) =\u003e any\n  ) =\u003e void;\n\n  // Resets the form to last known pristine state\n  clearForm: () =\u003e void;\n\n  /* Provider to wrap any child components with,\n   *   so that they and useFormState in them can access FormContext\n   *\n   * If using useFormState in the same component where useForm is used,\n   *   this can be passed in options.provider to useFormState\n   */\n  FormProvider: React.Element\n}\n```\n\n```typescript\nuseFormContext: ReactHook\n\nreturnValue: {\n  // Same as useForm except FormProvider\n}\n```\n\n```typescript\nuseFormState\u003cT\u003e: ReactHook\n\narguments: [\n  // key to identify which value from form,\n  //   this field is associated with\n  key: string | symbol,\n  // Options for this field\n  {\n    // default value is applied if the key doesn't exist in the initial form\n    defaultValue?: any,\n    // validate the value and return error or undefined if no errors\n    validate?: (value: any) =\u003e any | undefined,\n    // Validates value for required on submit, if true\n    required?: boolean,\n    // Error info to record when there is a require error\n    requiredErrorMessage?: any,\n    // Pass the Provider manually if this hook is not used inside a component thats wrapped in Provider\n    provider?: React.Element\n  }\n]\n\nreturnValue: [\n  // current state of the field\n  state: T,\n  // setState method for the field\n  setState: ReactSetState\u003cT\u003e,\n  // true if current state of the field is\n  //   different from last known pristine state\n  isDirty: boolean,\n  // error info if the state is not valid\n  error: any,\n]\n```\n\n\u003e Please note: error is any instead of string, this is there so you can pass anything.\n\n\u003e Example: You can pass reference to the error node so you can scroll to specific error when clicking submit\n\n## Usage\nCan be used in 2 different formats. Form \u0026 Fields in a single component or in separate components,\nplease refer below for an example of both the use cases\n\n### Form\n```typescript\n// Form.tsx\nimport React from 'react';\nimport { useForm } from '@avcs/react-form';\n\nconst Form = () =\u003e {\n  const {\n    handleSubmit, clearForm, FormProvider\n  } = useForm({ formData: initialForm });\n\n  // using useFormField in the same component as useForm\n  // check how we are passing provider here but not in FormField component\n  const [field, setField, isFieldDirty, fieldError] = useFormField(key, {\n    defaultValue:  'some value',\n    validate:  (value)  =\u003e  {\n      if  (value !==  'some value')  return  'some error';\n    },\n    required:  true,\n    requiredErrorMessage:  'this field is required',\n    provider: FormProvider\n  });\n\n  const handleChange = useCallback((e) =\u003e {\n    setData(e.target.value);\n  }, []);\n\n  const submitForm = useCallback((e) =\u003e {\n    handleSubmit(\n      formData =\u003e {\n        // API call to save data\n      },\n      errors =\u003e {\n        // Process errors\n      }\n    );\n  }, []);\n\n  return (\n    \u003cform\u003e\n      {/* OPTION 1: using form fields separately,\n          see below for definition of FormField */}\n      \u003cFormProvider\u003e\n        \u003cFormField /\u003e\n      \u003c/FormProvider\u003e\n\n      {/* OPTION 2: using form field in same component as form */}\n      \u003cinput type=\"text\" onChange={handleChange} value={field}  /\u003e\n\n      \u003cbutton onClick={submitForm}\u003eSubmit\u003c/input\u003e\n      \u003cbutton onClick={clearForm}\u003eClear\u003c/button\u003e\n    \u003c/form\u003e\n  );\n};\n\nexport default Form;\n```\n\n### FormField\n```typescript\n  import React from 'react';\n  import { useFormState } from '@avcs/react-form';\n\n  const FormField = () =\u003e {\n    const [data, setData, isDirty, error] = useFormState(key, {\n      defaultValue: 'some value',\n      validate: (value) =\u003e {\n        if (value !== 'some value') return 'some error';\n      },\n      required: true,\n      requiredErrorMessage: 'this field is required',\n    });\n\n    const handleChange = useCallback((e) =\u003e {\n      setData(e.target.value);\n    }, []);\n\n    return (\n      \u003cinput type=\"text\" onChange={handleChange} value={data} /\u003e\n    );\n  };\n\n  export default FormField;\n```\n\n## Performance\n- **useForm**: re-renders once per load, submit, reset\n- **useFormContext**: re-renders once per load\n- **useFormField**: re-renders once per load, submit, reset, value-change\n- **onFormChange**: triggers once per value-change\n- **oErrorChange**: triggers once per error-change (adding a new error, clearing an error)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favcs06%2Freact-form","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Favcs06%2Freact-form","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favcs06%2Freact-form/lists"}