UNPKG

pagamio-frontend-commons-lib

Version:

Pagamio library for Frontend reusable components like the form engine and table container

57 lines (56 loc) 3.94 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import clsx from 'clsx'; import { useForm } from 'react-hook-form'; import { useEffect, useState } from 'react'; import { Button, SheetRoot, SheetTrigger } from '../components'; import { cn } from '../helpers'; import FieldWrapper from './components/FieldWrapper'; const CancelButton = ({ isSubmitting, onCancel, isNotTrigger }) => { const sharedClasses = 'bg-white border-customPurple-5 text-customPurple-5 hover:bg-customPurple-15 w-full mr-3'; // If `isNotTrigger` is true, render a plain button; otherwise wrap it in SheetRoot/SheetTrigger. return isNotTrigger ? (_jsx(Button, { className: sharedClasses, disabled: isSubmitting, onClick: onCancel, children: "Cancel" })) : (_jsx(SheetRoot, { children: _jsx(SheetTrigger, { asChild: true, children: _jsx(Button, { className: sharedClasses, disabled: isSubmitting, onClick: onCancel, children: "Cancel" }) }) })); }; const FormEngine = ({ fields, onSubmit, initialValues, layout = 'vertical', isNotTrigger, showCancelButton = true, submitButtonText = 'Save', showSubmittingText = true, submitButtonClass, onCancel, getFieldValues, formRef, className, }) => { const { control, handleSubmit, watch, formState: { errors, isSubmitting }, reset, setValue, } = useForm({ mode: 'onBlur', defaultValues: initialValues }); const allFields = watch(); useEffect(() => { if (getFieldValues) { getFieldValues(allFields); } }, [allFields, getFieldValues]); // Expose form control methods via ref useEffect(() => { if (formRef) { formRef.current = { reset: () => reset(initialValues), setValue: (name, value) => setValue(name, value), }; } }, [formRef, reset, setValue, initialValues]); const [submitError, setSubmitError] = useState(null); const password = watch('password'); const handleFormSubmit = async (data) => { setSubmitError(null); try { await onSubmit(data); // Auto-reset the form after successful submission when formRef is not provided if (!formRef) { reset(initialValues); } // When formRef is provided, let the parent component control form reset } catch (error) { setSubmitError(error instanceof Error ? error.message : 'An error occurred'); } }; return (_jsxs("form", { className: cn(`${layout === 'horizontal' ? 'flex flex-wrap -mx-4' : ''} mb-6 border-gray-400 p-3`, className), onSubmit: handleSubmit(handleFormSubmit), children: [_jsx("div", { className: `${layout === 'vertical' ? 'grid grid-cols-12 gap-2 align-middle' : 'w-full flex flex-wrap'}`, children: fields?.map((field) => (_jsx(FieldWrapper, { field: { ...field, validation: { ...field.validation, validate: field.name === 'confirmPassword' ? (value) => value === password || 'Passwords do not match' : field.validation?.validate, }, }, control: control, errors: errors, layout: layout }, field.name))) }), _jsxs("div", { className: clsx('flex col-span-2 mt-4 w-full', showCancelButton ? 'space-x-4' : 'justify-end'), children: [showCancelButton && (_jsx(CancelButton, { isSubmitting: isSubmitting, onCancel: onCancel, isNotTrigger: isNotTrigger })), _jsx(Button, { type: "submit", className: clsx('bg-core-add hover:bg-core-add-hover', showCancelButton ? 'w-full ml-3' : 'w-[20%]', submitButtonClass), disabled: isSubmitting, children: submitButtonText }), isSubmitting && showSubmittingText && _jsx("span", { children: "Submitting..." })] }), submitError && _jsx("p", { className: "text-red-500", children: submitError })] })); }; export default FormEngine;