Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit cc6ed5a

Browse files
refactor: enable typescript strict mode (react-hook-form#1104)
* refactor: enable typescript `strict` mode * refactor(tsconfig): rearrange options
1 parent 4b4b39d commit cc6ed5a

24 files changed

+217
-123
lines changed

‎.eslintrc.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,10 @@ module.exports = {
3939
// react
4040
"react/prop-types": OFF,
4141
"react/no-unescaped-entities": OFF,
42-
"react/jsx-curly-brace-presence": "warn",
42+
"react/jsx-curly-brace-presence": WARN,
4343
// jsx-ally
4444
"jsx-a11y/no-onchange": WARN,
45+
// import
4546
"import/no-anonymous-default-export": OFF,
4647
// next
4748
"@next/next/no-img-element": OFF,

‎src/components/Admonition.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { ReactNode } from "react"
12
import styles from "./Admonition.module.css"
23
import { cva } from "class-variance-authority"
34

@@ -100,7 +101,17 @@ const admonition = cva(styles.admonition, {
100101
},
101102
})
102103

103-
export const Admonition = ({ type, title, children }) => {
104+
type AdmonitionType = keyof typeof svgMap
105+
106+
export const Admonition = ({
107+
type,
108+
title,
109+
children,
110+
}: {
111+
type: AdmonitionType
112+
title: string
113+
children: ReactNode
114+
}) => {
104115
return (
105116
<div className={admonition({ type })}>
106117
<div className={styles.admonitionHeading}>

‎src/components/ApiGallery.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useEffect } from "react"
2+
import type { MouseEventHandler } from "react"
23
import Link from "next/link"
34
import Footer from "./Footer"
45
import typographyStyles from "../styles/typography.module.css"
@@ -10,8 +11,8 @@ import { useRouter } from "next/router"
1011
export default function ApiGallery() {
1112
const router = useRouter()
1213

13-
const onChange = (e) => {
14-
const version = parseInt(e.target.value)
14+
const onChange: MouseEventHandler<HTMLButtonElement> = (e) => {
15+
const version = parseInt((e.targetasHTMLElement).getAttribute("value")!)
1516

1617
if (version !== 7) {
1718
router.push(`https://legacy.react-hook-form.com/v${version}/api`)

‎src/components/BuilderPage.tsx

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import { useState, useRef, useEffect, memo, RefObject } from "react"
22
import { useRouter } from "next/router"
33
import { Animate } from "react-simple-animate"
44
import { useForm } from "react-hook-form"
5+
import type { SubmitHandler } from "react-hook-form"
56
import SortableContainer from "./SortableContainer"
67
import { useStateMachine } from "little-state-machine"
7-
import type { GlobalState } from "little-state-machine"
8+
import type { GlobalState,FormDataItem } from "little-state-machine"
89
import colors from "../styles/colors"
910
import generateCode from "./logic/generateCode"
1011
import copyClipBoard from "./utils/copyClipBoard"
@@ -27,7 +28,9 @@ const errorStyle = {
2728
background: colors.errorPink,
2829
}
2930

30-
const defaultValue = {
31+
type FormFieldDefinitionItem = Partial<FormDataItem> & { toggle?: boolean }
32+
33+
const defaultValue: FormFieldDefinitionItem = {
3134
max: undefined,
3235
min: undefined,
3336
pattern: undefined,
@@ -36,7 +39,7 @@ const defaultValue = {
3639
required: undefined,
3740
name: "",
3841
type: "",
39-
options: [],
42+
options: "",
4043
}
4144

4245
function BuilderPage({
@@ -61,41 +64,43 @@ function BuilderPage({
6164
}
6265
},
6366
})
64-
const [editFormData, setFormData] = useState(defaultValue)
67+
const [editFormData, setEditFormData] = useState(defaultValue)
6568
const { register, handleSubmit, watch, setValue, reset, formState } =
66-
useForm()
69+
useForm<FormFieldDefinitionItem>()
6770
const errors = formState.errors
6871
const [editIndex, setEditIndex] = useState(-1)
6972
const copyFormData = useRef<GlobalState["formData"]>([])
7073
const closeButton = useRef<HTMLButtonElement>(null)
7174
const [showValidation, toggleValidation] = useState(false)
72-
const onSubmit = (data) => {
75+
76+
const onSubmit: SubmitHandler<FormFieldDefinitionItem> = (data) => {
7377
toggleValidation(false)
7478
if (editIndex >= 0) {
75-
formData[editIndex] = data
79+
formData[editIndex] = dataasFormDataItem
7680
updateFormData([...formData.filter((formInput) => formInput)])
77-
setFormData(defaultValue)
81+
setEditFormData(defaultValue)
7882
setEditIndex(-1)
7983
} else {
8084
updateFormData([...formData, ...[data]])
8185
}
8286
reset()
8387
}
88+
8489
const form = useRef<HTMLHeadingElement>(null)
8590
const type = watch("type")
8691
const shouldToggleOn =
87-
editFormData.max ||
88-
editFormData.min ||
89-
editFormData.pattern ||
90-
editFormData.maxLength ||
91-
editFormData.minLength ||
92+
!!editFormData.max ||
93+
!!editFormData.min ||
94+
!!editFormData.pattern ||
95+
!!editFormData.maxLength ||
96+
!!editFormData.minLength ||
9297
editFormData.required
9398
copyFormData.current = formData
9499
const editIndexRef = useRef<number | null>(null)
95100
editIndexRef.current = editIndex
96101
const router = useRouter()
97102

98-
const validate = (value) => {
103+
const validate = (value: unknown) => {
99104
return (
100105
!Object.values(copyFormData.current).find(
101106
(data) => data.name === value
@@ -118,7 +123,7 @@ function BuilderPage({
118123
}, [editFormData.type, setValue])
119124

120125
useEffect(() => {
121-
setValue("required", editFormData.required)
126+
setValue("required", !!editFormData.required)
122127
}, [editFormData.required, editIndex, setValue])
123128

124129
const child = (
@@ -140,15 +145,12 @@ function BuilderPage({
140145
</p>
141146

142147
<SortableContainer
143-
{...{
144-
updateFormData,
145-
formData,
146-
editIndex,
147-
setEditIndex,
148-
setFormData,
149-
editFormData,
150-
reset,
151-
}}
148+
updateFormData={updateFormData}
149+
formData={formData}
150+
editIndex={editIndex}
151+
setEditIndex={setEditIndex}
152+
setFormData={setEditFormData}
153+
reset={reset}
152154
/>
153155
</section>
154156

‎src/components/DevTools.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import type { DevtoolUIProps } from "@hookform/devtools/dist/devToolUI"
2020

2121
const DevTool = dynamic<DevtoolUIProps>(
2222
() =>
23+
// @ts-expect-error no types are available
2324
import("@hookform/devtools/dist/index.cjs.development").then(
2425
(mod) => mod.DevTool
2526
),
@@ -37,7 +38,7 @@ export default function DevTools() {
3738

3839
const { control } = methods
3940

40-
const onSubmit = (data) => console.log(data)
41+
const onSubmit = (data: unknown) => console.log(data)
4142

4243
return (
4344
<div className={containerStyles.container}>

‎src/components/Form.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { memo } from "react"
22
import { Animate } from "react-simple-animate"
33
import { useStateMachine } from "little-state-machine"
4-
import FormFields from "./FormFields"
5-
import goToBuilder from "./utils/goToBuilder"
6-
import { FieldValues, UseFormReturn } from "react-hook-form"
4+
import type { FieldValues, UseFormReturn } from "react-hook-form"
75
import home from "../data/home"
86
import generic from "../data/generic"
97
import buttonStyles from "../styles/button.module.css"
108
import containerStyles from "../styles/container.module.css"
119
import typographyStyles from "../styles/typography.module.css"
10+
import FormFields from "./FormFields"
11+
import goToBuilder from "./utils/goToBuilder"
1212
import styles from "./Form.module.css"
1313

1414
const animationProps = {
@@ -76,7 +76,7 @@ function Form({
7676
Example
7777
</h2>
7878

79-
<FormFields {...{formData, errors, register}} />
79+
<FormFields formData={formData} errors={errors} register={register} />
8080

8181
<button className={buttonStyles.pinkButton}>
8282
{home.liveDemo.submit}
@@ -136,7 +136,7 @@ function Form({
136136
<pre className={styles.code}>
137137
{Object.keys(errors).length > 0 &&
138138
JSON.stringify(
139-
Object.entries(errors).reduce(
139+
Object.entries(errors).reduce<Record<string,unknown>>(
140140
// @ts-expect-error needed for previous
141141
// eslint-disable-next-line @typescript-eslint/no-unused-vars
142142
(previous, [key, { ref, ...rest }]) => {

‎src/components/FormFields.tsx

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import type { GlobalState } from "little-state-machine"
2+
import type { FieldErrors, UseFormRegister } from "react-hook-form"
13
import colors from "../styles/colors"
24
import styles from "./FormFields.module.css"
35

@@ -7,7 +9,25 @@ const errorStyle = {
79
borderLeft: `10px solid ${colors.lightPink}`,
810
}
911

10-
const FormFields = ({ formData, errors, register }) => {
12+
function getNumericValidationFor<
13+
TKey extends "maxLength" | "minLength" | "min" | "max",
14+
>(name: TKey, value: string): Record<TKey, number> | null {
15+
const number = parseInt(value, 10)
16+
if (typeof number === "number" && !Number.isNaN(number)) {
17+
return { [name]: number } as Record<TKey, number>
18+
}
19+
return null
20+
}
21+
22+
const FormFields = ({
23+
formData,
24+
errors,
25+
register,
26+
}: {
27+
formData: GlobalState["formData"]
28+
errors: FieldErrors
29+
register: UseFormRegister<Record<string, unknown>>
30+
}) => {
1131
return (formData || []).map((field, i) => {
1232
switch (field.type) {
1333
case "select":
@@ -38,8 +58,8 @@ const FormFields = ({ formData, errors, register }) => {
3858
placeholder={field.name}
3959
{...register(field.name, {
4060
required: field.required,
41-
...(field.maxLength ? {maxLength: field.maxLength} : null),
42-
...(field.minLength ? {minLength: field.minLength} : null),
61+
...getNumericValidationFor("maxLength",field.maxLength),
62+
...getNumericValidationFor("minLength",field.minLength),
4363
})}
4464
key={field.name}
4565
style={{
@@ -96,13 +116,15 @@ const FormFields = ({ formData, errors, register }) => {
96116
placeholder={field.name}
97117
{...register(field.name, {
98118
required: field.required,
119+
99120
...(field.pattern
100121
? { pattern: new RegExp(field.pattern) }
101122
: null),
102-
...(field.max ? { max: field.max } : null),
103-
...(field.min ? { min: field.min } : null),
104-
...(field.maxLength ? { maxLength: field.maxLength } : null),
105-
...(field.minLength ? { minLength: field.minLength } : null),
123+
124+
...getNumericValidationFor("max", field.max),
125+
...getNumericValidationFor("min", field.min),
126+
...getNumericValidationFor("maxLength", field.maxLength),
127+
...getNumericValidationFor("minLength", field.minLength),
106128
})}
107129
/>
108130
)

‎src/components/HomePage.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import { useState, useRef, useEffect, memo } from "react"
2+
import { useForm } from "react-hook-form"
3+
import type { SubmitHandler } from "react-hook-form"
4+
import Link from "next/link"
25
import Form from "./Form"
36
import Header from "./Header"
47
import Watcher from "./Watcher"
@@ -16,8 +19,6 @@ import styles from "./HomePage.module.css"
1619
import { SponsorsList } from "./sponsorsList"
1720
import { useRouter } from "next/router"
1821
import { GeneralObserver } from "./general-observer"
19-
import Link from "next/link"
20-
import { useForm } from "react-hook-form"
2122

2223
function HomePage() {
2324
const [submitData, updateSubmitData] = useState({})
@@ -33,7 +34,8 @@ function HomePage() {
3334
const [watchPlay, setWatchPlay] = useState(false)
3435
const { query } = useRouter()
3536
const methods = useForm()
36-
const onSubmit = (data) => {
37+
38+
const onSubmit: SubmitHandler<Record<string, unknown>> = (data) => {
3739
updateSubmitData(data)
3840
}
3941

@@ -273,13 +275,11 @@ function HomePage() {
273275
<div ref={HomeRef} />
274276

275277
<Form
276-
{...{
277-
methods,
278-
onSubmit,
279-
submitData,
280-
toggleBuilder,
281-
formUpdated,
282-
}}
278+
methods={methods}
279+
onSubmit={onSubmit}
280+
submitData={submitData}
281+
toggleBuilder={toggleBuilder}
282+
formUpdated={formUpdated}
283283
/>
284284

285285
<section className={containerStyles.centerContent}>

‎src/components/IsolateRender.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { memo, useState } from "react"
2+
import type React from "react"
23
import { AnimateKeyframes, Animate } from "react-simple-animate"
34
import colors from "../styles/colors"
45
import home from "../data/home"
@@ -39,7 +40,7 @@ const IsoLateInput = () => {
3940
)
4041
}
4142

42-
const ControlledInputs = ({ style }) => {
43+
const ControlledInputs = ({ style }: {style?: React.CSSProperties}) => {
4344
const [play, setPlay] = useState(false)
4445

4546
return (

‎src/components/Search.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ import searchStyles from "./Search.module.css"
33
import useWindowSize from "./utils/useWindowSize"
44
import { LARGE_SCREEN } from "../styles/breakpoints"
55

6-
const Search = ({ focus, setFocus }: { focus: boolean; setFocus }) => {
6+
const Search = ({
7+
focus,
8+
setFocus,
9+
}: {
10+
focus: boolean
11+
setFocus: (value: boolean) => void
12+
}) => {
713
const { width } = useWindowSize()
814
const searchRef = useRef<HTMLInputElement>(null)
915

@@ -55,4 +61,5 @@ const Search = ({ focus, setFocus }: { focus: boolean; setFocus }) => {
5561
</>
5662
)
5763
}
64+
5865
export default Search

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /