chore: remove formik

This commit is contained in:
Henry
2024-08-24 07:25:37 +01:00
parent 015020185f
commit 8c6e50ed2f
8 changed files with 151 additions and 167 deletions

BIN
bun.lockb

Binary file not shown.

View File

@@ -31,7 +31,6 @@
"@trpc/server": "next", "@trpc/server": "next",
"@vercel/postgres": "^0.7.2", "@vercel/postgres": "^0.7.2",
"drizzle-orm": "^0.28.5", "drizzle-orm": "^0.28.5",
"formik": "^2.4.5",
"next": "^14.1.3", "next": "^14.1.3",
"postgres": "^3.4.4", "postgres": "^3.4.4",
"react": "18.2.0", "react": "18.2.0",

View File

@@ -1,7 +1,7 @@
import { type ReactNode } from "react"; import { type ReactNode } from "react";
import { HiOutlinePlusSmall } from "react-icons/hi2"; import { HiOutlinePlusSmall } from "react-icons/hi2";
import { Draggable } from "react-beautiful-dnd"; import { Draggable } from "react-beautiful-dnd";
import { useFormik } from "formik"; import { useForm } from "react-hook-form";
import { api } from "~/utils/api"; import { api } from "~/utils/api";
import { useModal } from "~/providers/modal"; import { useModal } from "~/providers/modal";
@@ -42,20 +42,20 @@ export default function List({
const updateList = api.list.update.useMutation(); const updateList = api.list.update.useMutation();
const formik = useFormik({ const { register, handleSubmit, setValue } = useForm<FormValues>({
initialValues: { defaultValues: {
listPublicId: list.publicId, listPublicId: list.publicId,
name: list.name, name: list.name,
}, },
onSubmit: (values: FormValues) => {
updateList.mutate({
listPublicId: values.listPublicId,
name: values.name,
});
},
enableReinitialize: true,
}); });
const onSubmit = (values: FormValues) => {
updateList.mutate({
listPublicId: values.listPublicId,
name: values.name,
});
};
return ( return (
<Draggable key={list.publicId} draggableId={list.publicId} index={index}> <Draggable key={list.publicId} draggableId={list.publicId} index={index}>
{(provided) => ( {(provided) => (
@@ -68,17 +68,15 @@ export default function List({
> >
<div className="flex justify-between"> <div className="flex justify-between">
<form <form
onSubmit={formik.handleSubmit} onSubmit={handleSubmit(onSubmit)}
className="focus-visible:outline-none" className="focus-visible:outline-none"
> >
<input <input
type="name"
id="name" id="name"
name="name" type="text"
value={formik.values.name} {...register("name")}
onChange={formik.handleChange} onBlur={handleSubmit(onSubmit)}
onBlur={formik.submitForm} className="mb-4 block border-0 bg-transparent px-4 pt-1 text-sm font-medium text-neutral-900 focus:ring-0 focus-visible:outline-none dark:text-dark-1000"
className="font-mediumfocus:ring-0 mb-4 block border-0 bg-transparent px-4 pt-1 text-sm text-neutral-900 focus-visible:outline-none dark:text-dark-1000"
/> />
</form> </form>
<div> <div>

View File

@@ -8,7 +8,7 @@ import {
type DropResult, type DropResult,
Draggable, Draggable,
} from "react-beautiful-dnd"; } from "react-beautiful-dnd";
import { useFormik } from "formik"; import { useForm } from "react-hook-form";
import { api } from "~/utils/api"; import { api } from "~/utils/api";
import { useBoard } from "~/providers/board"; import { useBoard } from "~/providers/board";
@@ -40,20 +40,20 @@ export default function BoardPage() {
const updateBoard = api.board.update.useMutation(); const updateBoard = api.board.update.useMutation();
const formik = useFormik({ const { register, handleSubmit, setValue } = useForm<UpdateBoardInput>({
initialValues: { values: {
boardPublicId: boardId ?? "", boardPublicId: boardId ?? "",
name: boardData?.name ? boardData.name : "", name: "",
}, },
onSubmit: (values: UpdateBoardInput) => {
updateBoard.mutate({
boardPublicId: values.boardPublicId,
name: values.name,
});
},
enableReinitialize: true,
}); });
const onSubmit = (values: UpdateBoardInput) => {
updateBoard.mutate({
boardPublicId: values.boardPublicId,
name: values.name,
});
};
const { data, isSuccess, isLoading } = api.board.byId.useQuery( const { data, isSuccess, isLoading } = api.board.byId.useQuery(
{ boardPublicId: boardId ?? "" }, { boardPublicId: boardId ?? "" },
{ {
@@ -64,8 +64,9 @@ export default function BoardPage() {
useEffect(() => { useEffect(() => {
if (isSuccess && data) { if (isSuccess && data) {
setBoardData(data); setBoardData(data);
setValue("name", data.name || "");
} }
}, [isSuccess, data, setBoardData]); }, [isSuccess, data, setBoardData, setValue]);
if (!boardId || !boardData) return <></>; if (!boardId || !boardData) return <></>;
@@ -136,16 +137,14 @@ export default function BoardPage() {
</div> </div>
) : ( ) : (
<form <form
onSubmit={formik.handleSubmit} onSubmit={handleSubmit(onSubmit)}
className="focus-visible:outline-none" className="focus-visible:outline-none"
> >
<input <input
type="name"
id="name" id="name"
name="name" type="text"
value={formik.values.name} {...register("name")}
onChange={formik.handleChange} onBlur={handleSubmit(onSubmit)}
onBlur={formik.submitForm}
className="block border-0 bg-transparent p-0 py-0 font-medium leading-[2.3rem] tracking-tight text-neutral-900 focus:ring-0 focus-visible:outline-none dark:text-dark-1000 sm:text-[1.2rem]" className="block border-0 bg-transparent p-0 py-0 font-medium leading-[2.3rem] tracking-tight text-neutral-900 focus:ring-0 focus-visible:outline-none dark:text-dark-1000 sm:text-[1.2rem]"
/> />
</form> </form>

View File

@@ -2,7 +2,7 @@ import { Fragment } from "react";
import { api } from "~/utils/api"; import { api } from "~/utils/api";
import { Menu, Transition } from "@headlessui/react"; import { Menu, Transition } from "@headlessui/react";
import { HiMiniPlus } from "react-icons/hi2"; import { HiMiniPlus } from "react-icons/hi2";
import { useFormik } from "formik"; import { useForm } from "react-hook-form";
import { useModal } from "~/providers/modal"; import { useModal } from "~/providers/modal";
@@ -33,18 +33,16 @@ export default function LabelSelector({
}, },
}); });
const formik = useFormik({ const { register, handleSubmit, setValue, watch } = useForm({
initialValues: { values: Object.fromEntries(
...Object.fromEntries( labels?.map((label) => [label.publicId, label.selected]) ?? [],
labels?.map((label) => [label.publicId, label.selected]) ?? [], ),
),
},
onSubmit: (values) => {
console.log({ values });
},
enableReinitialize: true,
}); });
const onSubmit = (values: Record<string, boolean>) => {
console.log({ values });
};
const selectedLabels = labels.filter((label) => label.selected); const selectedLabels = labels.filter((label) => label.selected);
return ( return (
@@ -99,36 +97,32 @@ export default function LabelSelector({
> >
<Menu.Items className="absolute right-[200px] top-[30px] z-10 mt-2 w-56 origin-top-right rounded-md border-[1px] border-light-600 bg-light-50 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:border-dark-500 dark:bg-dark-200"> <Menu.Items className="absolute right-[200px] top-[30px] z-10 mt-2 w-56 origin-top-right rounded-md border-[1px] border-light-600 bg-light-50 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:border-dark-500 dark:bg-dark-200">
<div className="p-2"> <div className="p-2">
<form onSubmit={formik.handleSubmit}> <form onSubmit={handleSubmit(onSubmit)}>
{labels?.map((label) => ( {labels?.map((label) => (
<Menu.Item key={label.publicId}> <Menu.Item key={label.publicId}>
{() => ( {() => (
<div <div
key={label.publicId} key={label.publicId}
className="flex items-center rounded-[5px] p-2 hover:bg-light-200 dark:hover:bg-dark-300" className="flex items-center rounded-[5px] p-2 hover:bg-light-200 dark:hover:bg-dark-300"
onClick={async (e) => { onClick={async () => {
e.preventDefault(); const newValue = !watch(label.publicId);
await formik.setFieldValue( setValue(label.publicId, newValue);
label.publicId,
!formik.values[label.publicId],
);
addOrRemoveLabel.mutate({ addOrRemoveLabel.mutate({
cardPublicId, cardPublicId,
labelPublicId: label.publicId, labelPublicId: label.publicId,
}); });
await formik.submitForm(); handleSubmit(onSubmit)();
}} }}
> >
<input <input
id={label.publicId} id={label.publicId}
name={label.publicId}
type="checkbox" type="checkbox"
className="h-[14px] w-[14px] rounded bg-transparent" className="h-[14px] w-[14px] rounded bg-transparent"
onClick={(event) => event.stopPropagation()} onClick={(event) => event.stopPropagation()}
onChange={formik.handleChange} {...register(label.publicId)}
checked={formik.values[label.publicId]} checked={watch(label.publicId)}
/> />
<label <label
htmlFor={label.publicId} htmlFor={label.publicId}

View File

@@ -1,7 +1,7 @@
import { Fragment } from "react"; import { Fragment } from "react";
import { api } from "~/utils/api"; import { api } from "~/utils/api";
import { Menu, Transition } from "@headlessui/react"; import { Menu, Transition } from "@headlessui/react";
import { useFormik } from "formik"; import { useForm } from "react-hook-form";
interface ListSelectorProps { interface ListSelectorProps {
cardPublicId: string; cardPublicId: string;
@@ -28,18 +28,16 @@ export default function ListSelector({
}, },
}); });
const formik = useFormik({ const { register, handleSubmit, setValue, watch } = useForm({
initialValues: { values: Object.fromEntries(
...Object.fromEntries( lists?.map((list) => [list.publicId, list.selected]) ?? [],
lists?.map((list) => [list.publicId, list.selected]) ?? [], ),
),
},
onSubmit: (values) => {
console.log({ values });
},
enableReinitialize: true,
}); });
const onSubmit = (values: Record<string, boolean>) => {
console.log({ values });
};
const selectedList = lists.find((list) => list.selected); const selectedList = lists.find((list) => list.selected);
return ( return (
@@ -68,40 +66,41 @@ export default function ListSelector({
> >
<Menu.Items className="absolute right-[200px] top-[30px] z-10 mt-2 w-56 origin-top-right rounded-md border-[1px] border-light-600 bg-light-50 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:border-dark-500 dark:bg-dark-200"> <Menu.Items className="absolute right-[200px] top-[30px] z-10 mt-2 w-56 origin-top-right rounded-md border-[1px] border-light-600 bg-light-50 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:border-dark-500 dark:bg-dark-200">
<div className="p-2"> <div className="p-2">
<form onSubmit={formik.handleSubmit}> <form onSubmit={handleSubmit(onSubmit)}>
{lists?.map((list) => ( {lists?.map((list) => (
<Menu.Item key={list.publicId}> <Menu.Item key={list.publicId}>
<div {() => (
key={list.publicId} <div
className="flex items-center rounded-[5px] p-2 hover:bg-light-200 dark:hover:bg-dark-300" key={list.publicId}
onClick={async (e) => { className="flex items-center rounded-[5px] p-2 hover:bg-light-200 dark:hover:bg-dark-300"
e.preventDefault(); onClick={async () => {
await formik.setFieldValue( const newValue = !watch(list.publicId);
list.publicId, setValue(list.publicId, newValue);
!formik.values[list.publicId],
);
updateCardList.mutate({ updateCardList.mutate({
cardId: cardPublicId, cardId: cardPublicId,
newListId: list.publicId, newListId: list.publicId,
}); });
await formik.submitForm(); handleSubmit(onSubmit)();
}} }}
> >
<input <input
id={list.publicId} id={list.publicId}
name={list.publicId} type="checkbox"
type="checkbox" className="h-[14px] w-[14px] rounded bg-transparent"
className="h-[14px] w-[14px] rounded bg-transparent" onClick={(event) => event.stopPropagation()}
onClick={(event) => event.stopPropagation()} {...register(list.publicId)}
onChange={formik.handleChange} checked={watch(list.publicId)}
checked={formik.values[list.publicId]} />
/> <label
<label htmlFor={list.publicId} className="ml-3 text-sm"> htmlFor={list.publicId}
{list.name} className="ml-3 text-sm"
</label> >
</div> {list.name}
</label>
</div>
)}
</Menu.Item> </Menu.Item>
))} ))}
</form> </form>

View File

@@ -2,7 +2,7 @@ import { Fragment } from "react";
import { api } from "~/utils/api"; import { api } from "~/utils/api";
import { Menu, Transition } from "@headlessui/react"; import { Menu, Transition } from "@headlessui/react";
import { HiMiniPlus } from "react-icons/hi2"; import { HiMiniPlus } from "react-icons/hi2";
import { useFormik } from "formik"; import { useForm } from "react-hook-form";
interface MemberSelectorProps { interface MemberSelectorProps {
cardPublicId: string; cardPublicId: string;
@@ -17,7 +17,7 @@ interface MemberSelectorProps {
isLoading: boolean; isLoading: boolean;
} }
export default function LabelSelector({ export default function MemberSelector({
cardPublicId, cardPublicId,
members, members,
isLoading, isLoading,
@@ -32,18 +32,16 @@ export default function LabelSelector({
}, },
}); });
const formik = useFormik({ const { register, handleSubmit, setValue, watch } = useForm({
initialValues: { values: Object.fromEntries(
...Object.fromEntries( members?.map((member) => [member.publicId, member.selected]) ?? [],
members?.map((member) => [member.publicId, member.selected]) ?? [], ),
),
},
onSubmit: (values) => {
console.log({ values });
},
enableReinitialize: true,
}); });
const onSubmit = (values: Record<string, boolean>) => {
console.log({ values });
};
const selectedMembers = members.filter((member) => member.selected); const selectedMembers = members.filter((member) => member.selected);
return ( return (
@@ -95,43 +93,41 @@ export default function LabelSelector({
> >
<Menu.Items className="absolute right-[200px] top-[30px] z-10 mt-2 w-56 origin-top-right rounded-md border-[1px] border-light-600 bg-light-50 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:border-dark-500 dark:bg-dark-200"> <Menu.Items className="absolute right-[200px] top-[30px] z-10 mt-2 w-56 origin-top-right rounded-md border-[1px] border-light-600 bg-light-50 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:border-dark-500 dark:bg-dark-200">
<div className="p-2"> <div className="p-2">
<form onSubmit={formik.handleSubmit}> <form onSubmit={handleSubmit(onSubmit)}>
{members?.map((member) => ( {members?.map((member) => (
<Menu.Item key={member.publicId}> <Menu.Item key={member.publicId}>
<div {() => (
key={member.publicId} <div
className="flex items-center rounded-[5px] p-2 hover:bg-light-200 dark:hover:bg-dark-300" key={member.publicId}
onClick={async (e) => { className="flex items-center rounded-[5px] p-2 hover:bg-light-200 dark:hover:bg-dark-300"
e.preventDefault(); onClick={async () => {
await formik.setFieldValue( const newValue = !watch(member.publicId);
member.publicId, setValue(member.publicId, newValue);
!formik.values[member.publicId],
);
addOrRemoveMember.mutate({ addOrRemoveMember.mutate({
cardPublicId, cardPublicId,
workspaceMemberPublicId: member.publicId, workspaceMemberPublicId: member.publicId,
}); });
await formik.submitForm(); handleSubmit(onSubmit)();
}} }}
>
<input
id={member.publicId}
name={member.publicId}
type="checkbox"
className="h-[14px] w-[14px] rounded bg-transparent"
onClick={(event) => event.stopPropagation()}
onChange={formik.handleChange}
checked={formik.values[member.publicId]}
/>
<label
htmlFor={member.publicId}
className="ml-3 text-sm"
> >
{member?.user?.name} <input
</label> id={member.publicId}
</div> type="checkbox"
className="h-[14px] w-[14px] rounded bg-transparent"
onClick={(event) => event.stopPropagation()}
{...register(member.publicId)}
checked={watch(member.publicId)}
/>
<label
htmlFor={member.publicId}
className="ml-3 text-sm"
>
{member?.user?.name}
</label>
</div>
)}
</Menu.Item> </Menu.Item>
))} ))}
</form> </form>

View File

@@ -1,6 +1,6 @@
import Link from "next/link"; import Link from "next/link";
import { useParams } from "next/navigation"; import { useParams } from "next/navigation";
import { useFormik } from "formik"; import { useForm } from "react-hook-form";
import ContentEditable from "react-contenteditable"; import ContentEditable from "react-contenteditable";
import { IoChevronForwardSharp } from "react-icons/io5"; import { IoChevronForwardSharp } from "react-icons/io5";
@@ -74,22 +74,22 @@ export default function CardPage() {
const updateCard = api.card.update.useMutation(); const updateCard = api.card.update.useMutation();
const formik = useFormik({ const { register, handleSubmit, setValue, watch } = useForm<FormValues>({
initialValues: { values: {
cardId: cardId ?? "", cardId: cardId ?? "",
title: data?.title ? data.title : "", title: data?.title ?? "",
description: data?.description ? data.description : "", description: data?.description ?? "",
}, },
onSubmit: (values: FormValues) => {
updateCard.mutate({
cardId: values.cardId,
title: values.title,
description: values.description,
});
},
enableReinitialize: true,
}); });
const onSubmit = (values: FormValues) => {
updateCard.mutate({
cardId: values.cardId,
title: values.title,
description: values.description,
});
};
if (!cardId) return <></>; if (!cardId) return <></>;
return ( return (
@@ -113,15 +113,16 @@ export default function CardPage() {
size={18} size={18}
className="mx-2 text-light-900 dark:text-dark-900" className="mx-2 text-light-900 dark:text-dark-900"
/> />
<form onSubmit={formik.handleSubmit} className="w-full space-y-6"> <form
onSubmit={handleSubmit(onSubmit)}
className="w-full space-y-6"
>
<div> <div>
<input <input
type="text" type="text"
id="title" id="title"
name="title" {...register("title")}
value={formik.values.title} onBlur={handleSubmit(onSubmit)}
onChange={formik.handleChange}
onBlur={formik.submitForm}
className="block w-full border-0 bg-transparent p-0 py-0 font-medium tracking-tight text-neutral-900 focus:ring-0 dark:text-dark-1000 sm:text-[1.2rem]" className="block w-full border-0 bg-transparent p-0 py-0 font-medium tracking-tight text-neutral-900 focus:ring-0 dark:text-dark-1000 sm:text-[1.2rem]"
/> />
</div> </div>
@@ -133,16 +134,14 @@ export default function CardPage() {
)} )}
</div> </div>
<div className="mb-8 flex w-full max-w-2xl justify-between"> <div className="mb-8 flex w-full max-w-2xl justify-between">
<form onSubmit={formik.handleSubmit} className="w-full space-y-6"> <form onSubmit={handleSubmit(onSubmit)} className="w-full space-y-6">
<div className="mt-2"> <div className="mt-2">
<ContentEditable <ContentEditable
placeholder="Add description..." placeholder="Add description..."
html={formik.values.description} html={watch("description")}
disabled={false} disabled={false}
onChange={(e) => onChange={(e) => setValue("description", e.target.value)}
formik.setFieldValue("description", e.target.value) onBlur={handleSubmit(onSubmit)}
}
onBlur={formik.submitForm}
className="block w-full border-0 bg-transparent py-1.5 text-light-900 focus-visible:outline-none dark:text-dark-1000 sm:text-sm sm:leading-6" className="block w-full border-0 bg-transparent py-1.5 text-light-900 focus-visible:outline-none dark:text-dark-1000 sm:text-sm sm:leading-6"
/> />
</div> </div>