UNPKG

@next-safe-action/adapter-react-hook-form

Version:

This adapter offers a way to seamlessly integrate next-safe-action with react-hook-form.

97 lines (93 loc) 2.62 kB
"use client"; // src/hooks.ts import { useAction, useOptimisticAction } from "next-safe-action/hooks"; import * as React from "react"; import { useForm } from "react-hook-form"; // src/index.ts function mapToHookFormErrors(validationErrors, props) { if (!validationErrors || Object.keys(validationErrors).length === 0) { return void 0; } const fieldErrors = {}; function mapper(ve, paths = []) { for (const key of Object.keys(ve)) { if (typeof ve[key] === "object" && ve[key] && !Array.isArray(ve[key])) { mapper(ve[key], [...paths, key]); } if (key === "_errors" && Array.isArray(ve[key])) { let ref = fieldErrors; for (let i = 0; i < paths.length - 1; i++) { const p = paths[i]; ref[p] ??= {}; ref = ref[p]; } const path = paths.at(-1) ?? "root"; ref[path] = { type: "validate", message: ve[key].join(props?.joinBy ?? " "), }; } } } mapper(validationErrors ?? {}); return fieldErrors; } // src/hooks.ts function useHookFormActionErrorMapper(validationErrors, props) { const propsRef = React.useRef(props); const hookFormValidationErrors = React.useMemo( () => mapToHookFormErrors(validationErrors, propsRef.current), [validationErrors] ); return { hookFormValidationErrors, }; } function useHookFormAction(safeAction, hookFormResolver, props) { const action = useAction(safeAction, props?.actionProps); const { hookFormValidationErrors } = useHookFormActionErrorMapper( action.result.validationErrors, props?.errorMapProps ); const form = useForm({ ...props?.formProps, resolver: hookFormResolver, errors: hookFormValidationErrors, }); const handleSubmitWithAction = form.handleSubmit(action.executeAsync); const resetFormAndAction = () => { form.reset(); action.reset(); }; return { action, form, handleSubmitWithAction, resetFormAndAction, }; } function useHookFormOptimisticAction(safeAction, hookFormResolver, props) { const action = useOptimisticAction(safeAction, props.actionProps); const { hookFormValidationErrors } = useHookFormActionErrorMapper( action.result.validationErrors, props.errorMapProps ); const form = useForm({ ...props?.formProps, resolver: hookFormResolver, errors: hookFormValidationErrors, }); const handleSubmitWithAction = form.handleSubmit(action.executeAsync); const resetFormAndAction = () => { form.reset(); action.reset(); }; return { action, form, handleSubmitWithAction, resetFormAndAction, }; } export { useHookFormAction, useHookFormActionErrorMapper, useHookFormOptimisticAction }; //# sourceMappingURL=hooks.mjs.map