Skip to content

refactor: enable typescript strict mode #1104

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ module.exports = {
// react
"react/prop-types": OFF,
"react/no-unescaped-entities": OFF,
"react/jsx-curly-brace-presence": "warn",
"react/jsx-curly-brace-presence": WARN,
// jsx-ally
"jsx-a11y/no-onchange": WARN,
// import
"import/no-anonymous-default-export": OFF,
// next
"@next/next/no-img-element": OFF,
Expand Down
13 changes: 12 additions & 1 deletion src/components/Admonition.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { ReactNode } from "react"
import styles from "./Admonition.module.css"
import { cva } from "class-variance-authority"

Expand Down Expand Up @@ -100,7 +101,17 @@ const admonition = cva(styles.admonition, {
},
})

export const Admonition = ({ type, title, children }) => {
type AdmonitionType = keyof typeof svgMap

export const Admonition = ({
type,
title,
children,
}: {
type: AdmonitionType
title: string
children: ReactNode
}) => {
return (
<div className={admonition({ type })}>
<div className={styles.admonitionHeading}>
Expand Down
5 changes: 3 additions & 2 deletions src/components/ApiGallery.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useEffect } from "react"
import type { MouseEventHandler } from "react"
import Link from "next/link"
import Footer from "./Footer"
import typographyStyles from "../styles/typography.module.css"
Expand All @@ -10,8 +11,8 @@ import { useRouter } from "next/router"
export default function ApiGallery() {
const router = useRouter()

const onChange = (e) => {
const version = parseInt(e.target.value)
const onChange: MouseEventHandler<HTMLButtonElement> = (e) => {
const version = parseInt((e.target as HTMLElement).getAttribute("value")!)

if (version !== 7) {
router.push(`https://legacy.react-hook-form.com/v${version}/api`)
Expand Down
50 changes: 26 additions & 24 deletions src/components/BuilderPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { useState, useRef, useEffect, memo, RefObject } from "react"
import { useRouter } from "next/router"
import { Animate } from "react-simple-animate"
import { useForm } from "react-hook-form"
import type { SubmitHandler } from "react-hook-form"
import SortableContainer from "./SortableContainer"
import { useStateMachine } from "little-state-machine"
import type { GlobalState } from "little-state-machine"
import type { GlobalState, FormDataItem } from "little-state-machine"
import colors from "../styles/colors"
import generateCode from "./logic/generateCode"
import copyClipBoard from "./utils/copyClipBoard"
Expand All @@ -27,7 +28,9 @@ const errorStyle = {
background: colors.errorPink,
}

const defaultValue = {
type FormFieldDefinitionItem = Partial<FormDataItem> & { toggle?: boolean }

const defaultValue: FormFieldDefinitionItem = {
max: undefined,
min: undefined,
pattern: undefined,
Expand All @@ -36,7 +39,7 @@ const defaultValue = {
required: undefined,
name: "",
type: "",
options: [],
options: "",
}

function BuilderPage({
Expand All @@ -61,41 +64,43 @@ function BuilderPage({
}
},
})
const [editFormData, setFormData] = useState(defaultValue)
const [editFormData, setEditFormData] = useState(defaultValue)
const { register, handleSubmit, watch, setValue, reset, formState } =
useForm()
useForm<FormFieldDefinitionItem>()
const errors = formState.errors
const [editIndex, setEditIndex] = useState(-1)
const copyFormData = useRef<GlobalState["formData"]>([])
const closeButton = useRef<HTMLButtonElement>(null)
const [showValidation, toggleValidation] = useState(false)
const onSubmit = (data) => {

const onSubmit: SubmitHandler<FormFieldDefinitionItem> = (data) => {
toggleValidation(false)
if (editIndex >= 0) {
formData[editIndex] = data
formData[editIndex] = data as FormDataItem
updateFormData([...formData.filter((formInput) => formInput)])
setFormData(defaultValue)
setEditFormData(defaultValue)
setEditIndex(-1)
} else {
updateFormData([...formData, ...[data]])
}
reset()
}

const form = useRef<HTMLHeadingElement>(null)
const type = watch("type")
const shouldToggleOn =
editFormData.max ||
editFormData.min ||
editFormData.pattern ||
editFormData.maxLength ||
editFormData.minLength ||
!!editFormData.max ||
!!editFormData.min ||
!!editFormData.pattern ||
!!editFormData.maxLength ||
!!editFormData.minLength ||
editFormData.required
copyFormData.current = formData
const editIndexRef = useRef<number | null>(null)
editIndexRef.current = editIndex
const router = useRouter()

const validate = (value) => {
const validate = (value: unknown) => {
return (
!Object.values(copyFormData.current).find(
(data) => data.name === value
Expand All @@ -118,7 +123,7 @@ function BuilderPage({
}, [editFormData.type, setValue])

useEffect(() => {
setValue("required", editFormData.required)
setValue("required", !!editFormData.required)
}, [editFormData.required, editIndex, setValue])

const child = (
Expand All @@ -140,15 +145,12 @@ function BuilderPage({
</p>

<SortableContainer
{...{
updateFormData,
formData,
editIndex,
setEditIndex,
setFormData,
editFormData,
reset,
}}
updateFormData={updateFormData}
formData={formData}
editIndex={editIndex}
setEditIndex={setEditIndex}
setFormData={setEditFormData}
reset={reset}
/>
</section>

Expand Down
3 changes: 2 additions & 1 deletion src/components/DevTools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type { DevtoolUIProps } from "@hookform/devtools/dist/devToolUI"

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

const { control } = methods

const onSubmit = (data) => console.log(data)
const onSubmit = (data: unknown) => console.log(data)

return (
<div className={containerStyles.container}>
Expand Down
10 changes: 5 additions & 5 deletions src/components/Form.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { memo } from "react"
import { Animate } from "react-simple-animate"
import { useStateMachine } from "little-state-machine"
import FormFields from "./FormFields"
import goToBuilder from "./utils/goToBuilder"
import { FieldValues, UseFormReturn } from "react-hook-form"
import type { FieldValues, UseFormReturn } from "react-hook-form"
import home from "../data/home"
import generic from "../data/generic"
import buttonStyles from "../styles/button.module.css"
import containerStyles from "../styles/container.module.css"
import typographyStyles from "../styles/typography.module.css"
import FormFields from "./FormFields"
import goToBuilder from "./utils/goToBuilder"
import styles from "./Form.module.css"

const animationProps = {
Expand Down Expand Up @@ -76,7 +76,7 @@ function Form({
Example
</h2>

<FormFields {...{ formData, errors, register }} />
<FormFields formData={formData} errors={errors} register={register} />

<button className={buttonStyles.pinkButton}>
{home.liveDemo.submit}
Expand Down Expand Up @@ -136,7 +136,7 @@ function Form({
<pre className={styles.code}>
{Object.keys(errors).length > 0 &&
JSON.stringify(
Object.entries(errors).reduce(
Object.entries(errors).reduce<Record<string, unknown>>(
// @ts-expect-error needed for previous
// eslint-disable-next-line @typescript-eslint/no-unused-vars
(previous, [key, { ref, ...rest }]) => {
Expand Down
36 changes: 29 additions & 7 deletions src/components/FormFields.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { GlobalState } from "little-state-machine"
import type { FieldErrors, UseFormRegister } from "react-hook-form"
import colors from "../styles/colors"
import styles from "./FormFields.module.css"

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

const FormFields = ({ formData, errors, register }) => {
function getNumericValidationFor<
TKey extends "maxLength" | "minLength" | "min" | "max",
>(name: TKey, value: string): Record<TKey, number> | null {
const number = parseInt(value, 10)
if (typeof number === "number" && !Number.isNaN(number)) {
return { [name]: number } as Record<TKey, number>
}
return null
}

const FormFields = ({
formData,
errors,
register,
}: {
formData: GlobalState["formData"]
errors: FieldErrors
register: UseFormRegister<Record<string, unknown>>
}) => {
return (formData || []).map((field, i) => {
switch (field.type) {
case "select":
Expand Down Expand Up @@ -38,8 +58,8 @@ const FormFields = ({ formData, errors, register }) => {
placeholder={field.name}
{...register(field.name, {
required: field.required,
...(field.maxLength ? { maxLength: field.maxLength } : null),
...(field.minLength ? { minLength: field.minLength } : null),
...getNumericValidationFor("maxLength", field.maxLength),
...getNumericValidationFor("minLength", field.minLength),
})}
key={field.name}
style={{
Expand Down Expand Up @@ -96,13 +116,15 @@ const FormFields = ({ formData, errors, register }) => {
placeholder={field.name}
{...register(field.name, {
required: field.required,

...(field.pattern
? { pattern: new RegExp(field.pattern) }
: null),
...(field.max ? { max: field.max } : null),
...(field.min ? { min: field.min } : null),
...(field.maxLength ? { maxLength: field.maxLength } : null),
...(field.minLength ? { minLength: field.minLength } : null),

...getNumericValidationFor("max", field.max),
...getNumericValidationFor("min", field.min),
...getNumericValidationFor("maxLength", field.maxLength),
...getNumericValidationFor("minLength", field.minLength),
})}
/>
)
Expand Down
20 changes: 10 additions & 10 deletions src/components/HomePage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { useState, useRef, useEffect, memo } from "react"
import { useForm } from "react-hook-form"
import type { SubmitHandler } from "react-hook-form"
import Link from "next/link"
import Form from "./Form"
import Header from "./Header"
import Watcher from "./Watcher"
Expand All @@ -16,8 +19,6 @@ import styles from "./HomePage.module.css"
import { SponsorsList } from "./sponsorsList"
import { useRouter } from "next/router"
import { GeneralObserver } from "./general-observer"
import Link from "next/link"
import { useForm } from "react-hook-form"

function HomePage() {
const [submitData, updateSubmitData] = useState({})
Expand All @@ -33,7 +34,8 @@ function HomePage() {
const [watchPlay, setWatchPlay] = useState(false)
const { query } = useRouter()
const methods = useForm()
const onSubmit = (data) => {

const onSubmit: SubmitHandler<Record<string, unknown>> = (data) => {
updateSubmitData(data)
}

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

<Form
{...{
methods,
onSubmit,
submitData,
toggleBuilder,
formUpdated,
}}
methods={methods}
onSubmit={onSubmit}
submitData={submitData}
toggleBuilder={toggleBuilder}
formUpdated={formUpdated}
/>

<section className={containerStyles.centerContent}>
Expand Down
3 changes: 2 additions & 1 deletion src/components/IsolateRender.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { memo, useState } from "react"
import type React from "react"
import { AnimateKeyframes, Animate } from "react-simple-animate"
import colors from "../styles/colors"
import home from "../data/home"
Expand Down Expand Up @@ -39,7 +40,7 @@ const IsoLateInput = () => {
)
}

const ControlledInputs = ({ style }) => {
const ControlledInputs = ({ style }: { style?: React.CSSProperties }) => {
const [play, setPlay] = useState(false)

return (
Expand Down
9 changes: 8 additions & 1 deletion src/components/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import searchStyles from "./Search.module.css"
import useWindowSize from "./utils/useWindowSize"
import { LARGE_SCREEN } from "../styles/breakpoints"

const Search = ({ focus, setFocus }: { focus: boolean; setFocus }) => {
const Search = ({
focus,
setFocus,
}: {
focus: boolean
setFocus: (value: boolean) => void
}) => {
const { width } = useWindowSize()
const searchRef = useRef<HTMLInputElement>(null)

Expand Down Expand Up @@ -55,4 +61,5 @@ const Search = ({ focus, setFocus }: { focus: boolean; setFocus }) => {
</>
)
}

export default Search
Loading
Loading