0.0.9 • Published 9 months ago

@blogcode/next-form v0.0.9

Weekly downloads
-
License
-
Repository
github
Last release
9 months ago

@blogcode/next-form

@blogcode/next-form is a flexible and powerful form management library for Next.js applications. It provides an easy-to-use API for handling form state, validation, and submission in both client-side and server-side rendering scenarios.

CHANGE LOG

  • 0.0.9:
    • Restruct output build
  • 0.0.8:
    • Add exports for package.json to alias import.
  • 0.0.7:
    • Export Form and Controller components to support CSR.
    • Clean dist and rebuild
  • 0.0.6
    • createFormData function support fully type.
  • 0.0.5:

    • Add action function for error Warning: Extra attributes from the server: action;
      • If using as CSR, set action as a void function.
    • throw new Error('React form unexpectedly submitted.').
      • Cannot using import via exported to index.tsx of package.
      • Import directly to file contain Form will fix this.
      • Removed exported to index.tsx. If using Form and Controller, let's import directly to file.
        • import { Form } from "@blogcode/next-form/Form";
        • import { Controller } from "@blogcode/next-form/Controller";
    • javascript:throw new Error('A React form was unexpectedly submitted. If you called form.submit() manually, consider using form.requestSubmit() instead. If you\'re trying to use event.stopPropagation() in a submit event handler, consider also calling event.preventDefault().')
      • This error is caused by hot reload so it will not appear in production environment. Therefore we will not try to fix it.
    • The logic handler from server action (action) to client (onAfterSubmit) removed.
      • Although it has been tested in a real project and it works fine, in order to fix the Server Action errors listed here, it is temporarily removed.
      • It may reappear in the future if it does not cause errors. We are still working around it.
    • Removed props.ssr. Because server and client threads will be used independently, this flag has no effect anymore.
    • Some types have been redefined to better accommodate the new treatment.
  • 0.0.4:

    • Fix Controller component does not required props.form.
    • That mean when using without Form Component wrapped it, you must be passed form for Controller.
  • 0.0.3:

    • Fix typeof value of ControllerRenderField from unknown to string.
  • 0.0.2:

    • Fix export value as set default as empty string for getInputProps.
    • Change type of value from unknown to string.

Installation

To install @blogcode/next-form, run the following command in your project directory:

npm i @blogcode/next-form

Or if you're using yarn:

yarn add @blogcode/next-form

Check demo code at here

Features

  • Easy form state management with useForm hook
  • Built-in form validation
  • Support for both client-side and server-side rendering
  • Flexible form submission handling
  • Integration with popular validation libraries (Zod, Yup, Joi)
  • Customizable input props
  • Controlled and uncontrolled component support

useForm hook

The useForm hook is the core of @blogcode/next-form. It provides form state management, validation, and submission handling.

Basic usage

import { useForm } from '@blogcode/next-form';

function MyForm() {
  const { form, formProps } = useForm({
    values: { name: '', email: '' },
    onSubmit: (e, data) => {
      console.log(data);
    },
  });

  return (
    <form {...formProps}>
      <input {...form.getInputProps('name')} />
      <input {...form.getInputProps('email')} />
      <button type="submit">Submit</button>
    </form>
  );
}

UseFormProps

The useForm hook accepts the following props:

  • action?: FormAction<unknown>: A function to handle form submission on the server-side.
  • onSubmit?(data: FormData): void: A function to handle form submission on the client-side.
  • onAfterSubmit?(data: unknown): void: A function called after successful form submission.
  • onError?(error: Record<string, FormError>): void: A function to handle validation or submission errors.
  • enhanceGetInputProps?(form: FormInstance): Partial<InputHTMLAttributes<HTMLInputElement>>: A function to customize input props.
  • resolver?: FormResolver: A custom validation resolver function.
  • values?: FormValues: Initial form values.
  • schema?: FormSchema: A schema object for built-in validation.
  • ssr?: boolean: Enable server-side rendering support.
  • mode?: FormMode: Validation mode ('change', 'blur', or 'submit').

Using with built-in schema

@blogcode/next-form provides a built-in validation system using a schema object:

const { form, formProps } = useForm({
  values: { name: '', email: '' },
  schema: {
    name: { required: true, minLength: 2 },
    email: { required: true, pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/ },
  },
  onSubmit: (e, data) => {
    console.log(data);
  },
});

Using with SSR

For server-side rendering support, use the ssr prop and provide an action function:

const { form, formProps } = useForm({
  ssr: true,
  action: async (formData) => {
    // Handle server-side form submission
    const result = await submitToServer(formData);
    return result;
  },
  onAfterSubmit: (result) => {
    console.log('Server response:', result);
  },
  onError: (errors) => {
    console.error('Submission errors:', errors);
  },
});

Using with CSR

For client-side rendering, use the onSubmit prop:

const { form, formProps } = useForm({
  onSubmit: (e, formData) => {
    // Handle client-side form submission
    console.log('Form data:', formData);
  },
  onError: (errors) => {
    console.error('Validation errors:', errors);
  },
});

Form component

The Form component is a wrapper that simplifies form creation and management.

Using with children as ReactElement

import { Form } from '@blogcode/next-form';

function MyForm() {
  return (
    <Form
      values={{ name: '', email: '' }}
      onSubmit={(e, data) => console.log(data)}
    >
      <input name="name" />
      <input name="email" type="email" />
      <button type="submit">Submit</button>
    </Form>
  );
}

Using with children as function

import { Form } from '@blogcode/next-form';

function MyForm() {
  return (
    <Form
      values={{ name: '', email: '' }}
      onSubmit={(e, data) => console.log(data)}
    >
      {(form) => (
        <>
          <input {...form.getInputProps('name')} />
          <input {...form.getInputProps('email')} type="email" />
          <button type="submit">Submit</button>
        </>
      )}
    </Form>
  );
}

Controller component

The Controller component allows you to create controlled inputs with ease:

import { Form, Controller } from '@blogcode/next-form';

function MyForm() {
  return (
    <Form
      values={{ name: '', email: '' }}
      onSubmit={(e, data) => console.log(data)}
    >
      <Controller
        name="name"
        render={({ field, fieldState }) => (
          <input
            {...field}
            placeholder="Name"
            style={{ borderColor: fieldState.error ? 'red' : 'initial' }}
          />
        )}
      />
      <Controller
        name="email"
        render={({ field, fieldState }) => (
          <input
            {...field}
            type="email"
            placeholder="Email"
            style={{ borderColor: fieldState.error ? 'red' : 'initial' }}
          />
        )}
      />
      <button type="submit">Submit</button>
    </Form>
  );
}

Using with Validation Libraries

@blogcode/next-form can be integrated with popular validation libraries for more advanced validation scenarios.

Zod

import { z } from 'zod';
import { useForm } from '@blogcode/next-form';
import { zodResolver } from '@blogcode/next-form/zod';

const schema = z.object({
  name: z.string().min(2),
  email: z.string().email(),
});

function MyForm() {
  const { form, formProps } = useForm({
    resolver: zodResolver(schema),
    onSubmit: (data) => console.log(data),
  });

  // ... rest of the component
}

Yup

import * as yup from 'yup';
import { useForm } from '@blogcode/next-form';
import { yupResolver } from '@blogcode/next-form/yup';

const schema = yup.object().shape({
  name: yup.string().required().min(2),
  email: yup.string().required().email(),
});

function MyForm() {
  const { form, formProps } = useForm({
    resolver: yupResolver(schema),
    onSubmit: (data) => console.log(data),
  });

  // ... rest of the component
}

Joi

import Joi from 'joi';
import { useForm } from '@blogcode/next-form';
import { joiResolver } from '@blogcode/next-form/joi';

const schema = Joi.object({
  name: Joi.string().required().min(2),
  email: Joi.string().required().email(),
});

function MyForm() {
  const { form, formProps } = useForm({
    resolver: joiResolver(schema),
    onSubmit: (data) => console.log(data),
  });

  // ... rest of the component
}

Known issues

  • When using the Controller component, the onChange and onBlur handlers may not behave correctly in all scenarios. We are working on resolving this issue in future updates.
0.0.9

9 months ago

0.0.7

9 months ago

0.0.6

9 months ago

0.0.5

9 months ago

0.0.4

9 months ago

0.0.3

9 months ago

0.0.2

9 months ago

0.0.1

9 months ago