new-personal-site/components/lib/form/Form.tsx
Benjamin Toby a0a0ab8ee4 Updates
2025-07-20 10:35:54 +01:00

50 lines
1.7 KiB
TypeScript

import _ from "lodash";
import { DetailedHTMLProps, FormHTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
type Props<T extends { [key: string]: any } = { [key: string]: any }> =
DetailedHTMLProps<FormHTMLAttributes<HTMLFormElement>, HTMLFormElement> & {
submitHandler?: (e: React.FormEvent<HTMLFormElement>, data: T) => void;
changeHandler?: (e: React.FormEvent<HTMLFormElement>, data: T) => void;
};
/**
* # Form Element
* @className twui-form
*/
export default function Form<
T extends { [key: string]: any } = { [key: string]: any }
>({ ...props }: Props<T>) {
const finalProps = _.omit(props, ["submitHandler", "changeHandler"]);
return (
<form
{...finalProps}
className={twMerge(
"flex flex-col items-stretch gap-2 w-full bg-transparent",
"twui-form",
props.className
)}
onSubmit={(e) => {
e.preventDefault();
const formEl = e.target as HTMLFormElement;
const formData = new FormData(formEl);
const data = Object.fromEntries(formData.entries()) as T;
props.submitHandler?.(e, data);
props.onSubmit?.(e);
}}
onChange={(e) => {
e.preventDefault();
const taregtEl = e.target as HTMLElement;
const formEl = taregtEl.closest("form") as HTMLFormElement;
const formData = new FormData(formEl);
const data = Object.fromEntries(formData.entries()) as T;
props.changeHandler?.(e, data);
props.onChange?.(e);
}}
>
{props.children}
</form>
);
}