From 0ab1d553421b52c868dcf55a53e1298a7b6a2ad4 Mon Sep 17 00:00:00 2001 From: Lucas Date: Wed, 26 Jul 2023 14:58:12 -0700 Subject: [PATCH] feat: adding formstate, register, setvalue + minor bug fixes --- .eslintrc.js | 14 +- .github/stale.yml | 2 +- .github/workflows/lock-issue.yml | 4 +- contentlayer.config.ts | 2 +- next.config.mjs => next.config.cjs | 3 - package.json | 40 +- src/components/ApiFormState.tsx | 85 - src/components/ApiGallery.tsx | 30 - src/components/ApiRefTable.tsx | 799 ------ src/components/BuilderPage.tsx | 8 +- src/components/CodeCompareSection.tsx | 1 - src/components/Form.tsx | 3 +- src/components/FormStateApi.tsx | 47 +- src/components/FormStateTable.tsx | 4 +- src/components/UseController.tsx | 3 +- src/components/UseControllerContent.tsx | 3 +- src/components/UseFieldArray.tsx | 3 +- src/components/UseFieldArrayContent.tsx | 3 +- src/components/UseFormState.tsx | 3 +- .../codeExamples/dependantFieldsTS.tsx | 48 - src/components/codeExamples/formState.ts | 20 - src/components/codeExamples/formStateTs.ts | 23 - .../codeExamples/formStateUseEffect.ts | 25 - .../codeExamples/formStateUseEffectTs.ts | 25 - src/components/codeExamples/register.ts | 39 - src/components/codeExamples/registerTs.ts | 24 - src/components/codeExamples/setValue.ts | 26 - src/components/codeExamples/setValueTs.tsx | 27 - src/components/codeExamples/setValueTypes.ts | 27 - src/components/layout.css | 16 +- src/components/mdx/mdx.tsx | 6 + src/components/mdx/theme.ts | 1 - src/components/useForm/FormState.tsx | 69 +- src/components/useForm/Register.tsx | 638 ++++- src/components/useForm/SetValue.tsx | 247 +- src/content/docs/useform.mdx | 8 +- src/content/docs/useform/formstate.mdx | 131 + src/content/docs/useform/register.mdx | 212 ++ src/content/docs/useform/reset.mdx | 22 +- src/content/docs/useform/setvalue.mdx | 201 ++ src/content/docs/usewatch.mdx | 2 +- src/content/get-started.mdx | 8 +- src/content/ts.mdx | 22 +- src/data/api.tsx | 2245 +---------------- src/pages/about-us.tsx | 66 +- src/pages/dev-tools.tsx | 3 +- src/pages/docs.tsx | 3 +- src/pages/docs/useform/formstate.tsx | 14 - src/pages/docs/useform/register.tsx | 14 - src/pages/docs/useform/setvalue.tsx | 14 - yarn.lock | 1327 +++++----- 51 files changed, 2235 insertions(+), 4375 deletions(-) rename next.config.mjs => next.config.cjs (89%) delete mode 100644 src/components/ApiFormState.tsx delete mode 100644 src/components/ApiRefTable.tsx delete mode 100644 src/components/codeExamples/dependantFieldsTS.tsx delete mode 100644 src/components/codeExamples/formState.ts delete mode 100644 src/components/codeExamples/formStateTs.ts delete mode 100644 src/components/codeExamples/formStateUseEffect.ts delete mode 100644 src/components/codeExamples/formStateUseEffectTs.ts delete mode 100644 src/components/codeExamples/register.ts delete mode 100644 src/components/codeExamples/registerTs.ts delete mode 100644 src/components/codeExamples/setValue.ts delete mode 100644 src/components/codeExamples/setValueTs.tsx delete mode 100644 src/components/codeExamples/setValueTypes.ts create mode 100644 src/content/docs/useform/formstate.mdx create mode 100644 src/content/docs/useform/register.mdx create mode 100644 src/content/docs/useform/setvalue.mdx delete mode 100644 src/pages/docs/useform/formstate.tsx delete mode 100644 src/pages/docs/useform/register.tsx delete mode 100644 src/pages/docs/useform/setvalue.tsx diff --git a/.eslintrc.js b/.eslintrc.js index 94b66c9b7..6ae393311 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -19,10 +19,9 @@ module.exports = { }, extends: [ "plugin:react/recommended", - "plugin:react-hooks/recommended", "plugin:@typescript-eslint/recommended", "plugin:jsx-a11y/recommended", - "next", + "next/core-web-vitals", "plugin:react/jsx-runtime", ], settings: { @@ -31,16 +30,7 @@ module.exports = { }, }, rules: { - // typescript - "@typescript-eslint/explicit-function-return-type": OFF, - "@typescript-eslint/interface-name-prefix": OFF, - "@typescript-eslint/explicit-module-boundary-types": OFF, - // react - "react/prop-types": OFF, "react/no-unescaped-entities": OFF, - "react/jsx-curly-brace-presence": "warn", - // jsx-ally - "jsx-a11y/no-onchange": WARN, - "import/no-anonymous-default-export": OFF, + "@typescript-eslint/no-explicit-any": OFF, }, } diff --git a/.github/stale.yml b/.github/stale.yml index 102a5d72a..7f194bc66 100644 --- a/.github/stale.yml +++ b/.github/stale.yml @@ -7,7 +7,7 @@ exemptLabels: - pinned - security # Label to use when marking an issue as stale -staleLabel: +staleLabel: # Comment to post when marking an issue as stale. Set to `false` to disable markComment: > This issue has been automatically marked as stale because it has not had diff --git a/.github/workflows/lock-issue.yml b/.github/workflows/lock-issue.yml index d0e6cbe43..c7b87af73 100644 --- a/.github/workflows/lock-issue.yml +++ b/.github/workflows/lock-issue.yml @@ -1,9 +1,9 @@ -name: 'Lock Issues' +name: "Lock Issues" on: workflow_dispatch: schedule: - - cron: '0 0,6,12,18 * * *' + - cron: "0 0,6,12,18 * * *" permissions: issues: write diff --git a/contentlayer.config.ts b/contentlayer.config.ts index 1c3a39456..477872b86 100644 --- a/contentlayer.config.ts +++ b/contentlayer.config.ts @@ -39,7 +39,7 @@ export const Doc = defineDocumentType(() => ({ }, pages: { type: "list", - resolve: (doc) => sidebar[doc.sidebar] ?? [], + resolve: (doc) => sidebar[doc.sidebar.trim()] ?? [], }, }, })) diff --git a/next.config.mjs b/next.config.cjs similarity index 89% rename from next.config.mjs rename to next.config.cjs index 1a5fcfa54..90176d9cb 100644 --- a/next.config.mjs +++ b/next.config.cjs @@ -3,9 +3,6 @@ import withBundleAnalyzer from "@next/bundle-analyzer" /** @type {import('next').NextConfig} */ const nextConfig = { - typescript: { - ignoreBuildErrors: true, - }, reactStrictMode: true, pageExtensions: ["ts", "tsx", "js", "jsx", "md", "mdx"], } diff --git a/package.json b/package.json index f3223c59d..a8fdf8cf5 100644 --- a/package.json +++ b/package.json @@ -5,24 +5,20 @@ "author": "beier luo", "dependencies": { "@hookform/devtools": "4.3.1", - "@mdx-js/loader": "^2.3.0", - "@mdx-js/react": "^2.3.0", - "@next/mdx": "^13.4.5", - "@types/node": "^20.3.1", - "class-variance-authority": "^0.6.0", - "clsx": "^1.2.1", - "contentlayer": "^0.3.3", - "date-fns": "^2.30.0", + "@types/node": "^20.4.5", + "class-variance-authority": "^0.7.0", + "clsx": "^2.0.0", + "contentlayer": "^0.3.4", "little-state-machine": "^4.8.0", - "next": "^13.4.5", - "next-contentlayer": "^0.3.3", + "next": "^13.4.12", + "next-contentlayer": "^0.3.4", "next-themes": "^0.2.1", - "prism-react-renderer": "^2.0.5", + "prism-react-renderer": "^2.0.6", "prismjs": "^1.29.0", "react": "18.2.0", "react-dom": "18.2.0", "react-github-btn": "1.4.0", - "react-hook-form": "7.44.3", + "react-hook-form": "7.45.2", "react-simple-animate": "^3.5.2", "react-simple-img": "3.0.0", "react-sortablejs": "1.5.1", @@ -33,21 +29,21 @@ "sortablejs": "1.15.0" }, "devDependencies": { - "@next/bundle-analyzer": "^13.4.5", + "@next/bundle-analyzer": "^13.4.12", "@types/react-helmet": "^6.1.6", - "@typescript-eslint/eslint-plugin": "^5.59.11", - "@typescript-eslint/parser": "^5.59.11", + "@typescript-eslint/eslint-plugin": "^6.2.0", + "@typescript-eslint/parser": "^6.2.0", "cross-env": "^7.0.3", - "eslint": "^8.42.0", - "eslint-config-next": "^13.4.5", + "eslint": "^8.45.0", + "eslint-config-next": "^13.4.12", "eslint-config-prettier": "^8.8.0", "eslint-plugin-jsx-a11y": "^6.7.1", - "eslint-plugin-react": "^7.32.2", + "eslint-plugin-react": "^7.33.0", "eslint-plugin-react-hooks": "^4.6.0", "husky": "^8.0.3", - "lint-staged": "^13.2.2", - "prettier": "^2.8.8", - "typescript": "^5.1.3" + "lint-staged": "^13.2.3", + "prettier": "^3.0.0", + "typescript": "^5.1.6" }, "keywords": [ "react-hook-form", @@ -58,7 +54,7 @@ "analyze": "cross-env ANALYZE=true next build", "build": "next build", "dev": "next dev", - "format": "prettier --write", + "format": "prettier . --write", "lint": "next lint --fix", "now-build": "npm run build", "start": "next start", diff --git a/src/components/ApiFormState.tsx b/src/components/ApiFormState.tsx deleted file mode 100644 index 63eda517b..000000000 --- a/src/components/ApiFormState.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { memo } from "react" -import typographyStyles from "../styles/typography.module.css" -import FormStateTable from "./FormStateTable" -import TabGroup from "./TabGroup" -import CodeArea from "./CodeArea" -import formStateUseEffect from "./codeExamples/formStateUseEffect" -import formStateUseEffectTs from "./codeExamples/formStateUseEffectTs" - -function ApiFormState({ api }: { api: any }) { - return ( - <> - -

- formState: Object -

-
- {api.formState.description} - - - -

- Rules -

- - - - ) -} - -export default memo(ApiFormState) diff --git a/src/components/ApiGallery.tsx b/src/components/ApiGallery.tsx index a3a1b9ca4..a44e3c045 100644 --- a/src/components/ApiGallery.tsx +++ b/src/components/ApiGallery.tsx @@ -1,4 +1,3 @@ -import { useEffect } from "react" import Link from "next/link" import Footer from "./Footer" import typographyStyles from "../styles/typography.module.css" @@ -20,35 +19,6 @@ export default function ApiGallery() { } } - useEffect(() => { - const name = window.location.hash.toLowerCase().slice(1) - - if (name === "controller") { - router.push(`/docs/usecontroller/${name}`) - } else if ( - [ - "register", - "unregister", - "watch", - "handlesubmit", - "reset", - "setError", - "clearerrors", - "setvalues", - "getvalues", - "trigger", - "control", - "formstate", - ].includes(name) - ) { - router.push(`/docs/useform/${name}`) - } else if ( - ["controller", "useformcontext", "usefieldarray"].includes(name) - ) { - router.push(`/docs/${name}`) - } - }, [router]) - return (

diff --git a/src/components/ApiRefTable.tsx b/src/components/ApiRefTable.tsx deleted file mode 100644 index 56c6fce88..000000000 --- a/src/components/ApiRefTable.tsx +++ /dev/null @@ -1,799 +0,0 @@ -import { useState } from "react" -import CodeArea from "./CodeArea" -import generic from "../data/generic" -import typographyStyles from "../styles/typography.module.css" -import tableStyles from "../styles/table.module.css" -import styles from "./ApiRefTable.module.css" -import register from "./codeExamples/register" -import registerTs from "./codeExamples/registerTs" - -export default function ApiRefTable({ api }: { api: any }) { - const [isStandard, toggleOption] = useState(true) - - return ( - <> - {api.register.description} - -
- - - - - - - - - - - - - - - - - - - -
- Input {generic.name} - {api.register.example}
- register("firstName") - - {`{firstName: 'value'}`} -
- register("name.firstName") - - {`{name: { firstName: 'value' }}`} -
- register("name.firstName.0") - - {`{name: { firstName: [ 'value' ] }}`} -
-
- -

Return

- -
-

- Tip:: What's happened to the - input after invoke register API: -

-
- - -// same as above - -`} - /> - -

- Options -

- -

{api.register.selectHelp}

- -
- {api.register.options.title} - - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- {generic.name} - - {generic.description} - - {generic.codeExample} -
- ref -
- React.Ref -
React element ref - `} - /> -
- required -
- - {isStandard - ? "boolean" - : `string | -{ - value: boolean, - message: string -}`} - -
{api.register.validation.required} - error message

TS only support string` - } - })} -/>`} - /> -
- maxLength -
- - - {isStandard - ? "number" - : `{ - value: number, - message: string -}`} - - -
{api.register.validation.maxLength} - error message

TS only support string - }` - } - })} -/>`} - /> -
- minLength -
- - - {isStandard - ? "number" - : `{ - value: number, - message: string -}`} - - -
{api.register.validation.minLength} - error message

TS only support string - }` - } - })} -/>`} - /> -
- max -
- - - {isStandard - ? "number" - : `{ - value: number, - message: string -}`} - - -
{api.register.validation.max} - error message

TS only support string - }` - } - })} -/>`} - /> -
- min -
- - - {isStandard - ? "number" - : `{ - value: number, - message: string -}`} - - -
{api.register.validation.min} - error message

TS only support string - }` - } - })} -/>`} - /> -
- pattern -
- - - {isStandard - ? "RegExp" - : `{ - value: RegExp, - message: string -}`} - - -
{api.register.validation.pattern} - error message

TS only support string - }` - } - })} -/>`} - /> -
- validate -
- - Function | Object - -
{api.register.validation.validate} - value === '1'` - : `value => value === '1' || 'error message' // JS only:

error message

TS only support string` - } - })} -/> -// object of callback functions - parseInt(v) > 0, - lessThanTen: v => parseInt(v) < 10, - validateNumber: (_, values) => - !!(values.number1 + values.number2), - checkUrl: async () => await fetch(), - }` - : `{ - positive: v => parseInt(v) > 0 || 'should be greater than 0', - lessThanTen: v => parseInt(v) < 10 || 'should be lower than 10', - validateNumber: (_: number, formValues: FormValues) => { - return formValues.number1 + formValues.number2 === 3 || 'Check sum number'; - }, - // you can do asynchronous validation as well - checkUrl: async () => await fetch() || 'error message', // JS only:

error message

TS only support string - messages: v => !v && ['test', 'test2'] - }` - } - })} -/> -`} - /> -
- valueAsNumber: -
- boolean -
-

- Returns a Number normally. If something goes wrong{" "} - NaN will be returned. -

-
    -
  • -

    - valueAs process is happening{" "} - before validation. -

    -
  • -
  • -

    - Only applicable and support to {``} - , but we still cast to number type without trim or any - other data manipulation. -

    -
  • -
  • - Does not transform defaultValue or{" "} - defaultValues. -
  • -
-
- `} - /> -
- valueAsDate: -
- boolean -
-

- Returns a Date object normally. If something goes - wrong Invalid Date will be returned. -

-
    -
  • -

    - valueAs process is happening{" "} - before validation. -

    -
  • -
  • -

    Only applies to {``}.

    -
  • -
  • - Does not transform defaultValue or{" "} - defaultValues. -
  • -
-
- `} - /> -
- setValueAs: -
- {`(value: any) => T`} -
-

Return input value by running through the function.

-
    -
  • -

    - valueAs process is happening{" "} - before validation. Also,{" "} - setValueAs is ignored if either{" "} - valueAsNumber or valueAsDate are{" "} - true. -

    -
  • -
  • -

    Only applies to text input.

    -
  • -
  • - Does not transform defaultValue or{" "} - defaultValues. -
  • -
-
- parseInt(v), - })} -/>`} - /> -
- disabled -
- - boolean = false - -
-

- Set disabled to true will lead input - value to be undefined and input control to be - disabled. -

-
    -

    - Disabled prop will also omit{" "} - built-in validation rules. -

    -

    - For schema validation, you can leverage the{" "} - undefined value returned from input or context - object. -

    -
-
- `} - /> -
- onChange -
- {`(e: SyntheticEvent) => void`} -
-

- onChange function event to be invoked in the - change event. -

-
- console.log(e) -})`} - /> -
- onBlur -
- {`(e: SyntheticEvent) => void`} -
-

- onBlur function event to be invoked in the blur - event. -

-
- console.log(e) -})`} - /> -
- value -
- unknown -
-

- Set up value for the registered input. This prop should be - utilised inside useEffect or invoke once, each - re-run will update or overwrite the input value which you have - supplied. -

-
- -
- shouldUnregister: -
- boolean -
-

- Input will be unregistered after unmount and defaultValues - will be removed as well. -

-

- Note: this prop should be avoided when using with{" "} - useFieldArray as unregister function - gets called after input unmount/remount and reorder. -

-
- `} - /> -
- deps: -
- - string | string[] - -
-

- Validation will be triggered for the dependent inputs,it only - limited to register api not trigger. -

-
- `} - /> -
- -

- Rules -

- -
    -
  • -

    - name is required and unique (except - native radio and checkbox). Input name supports both dot and - bracket syntax, which allows you to easily create nested form - fields. -

    -
  • -
  • -

    - name can neither start with a number nor use number - as key name. Please avoid special characters as well. -

    -
  • -
  • -

    - we are using dot syntax only for typescript usage consistency, so - bracket [] will not work for array form value. -

    - - -
  • -
  • -

    - disabled input will result in an{" "} - undefined form value. If you want to prevent users - from updating the input, you can use readOnly or - disable the entire {`

    `}. Here is an{" "} - - example - - . -

    -
  • -
  • -

    - To produce an array of fields, input names should be followed by a{" "} - dot and number. For example: test.0.data -

    -
  • -
  • -

    - Changing the name on each render will result in new inputs being - registered. It's recommend to keep static names for each - registered input. -

    -
  • -
  • -

    - Input value and reference will no longer gets removed based on - unmount. You can invoke unregister to remove that value and - reference. -

    -
  • -
  • -

    - Individual register option can't be removed by{" "} - undefined or {`{}`}. You can update - individual attribute instead. -

    - - -
  • -
  • -

    - There are certain keyword which need to avoid before conflicting - with type check. They are ref, _f -

    -
  • -
- -

- Examples -

- - - -

Video

-

- The following video explain register API in detail. -

- -