rilaykit
Forms

Rendering Forms

How to render forms and their components.

Once you have a formConfig, the @rilaykit/forms package provides a set of components to render it. Remember, these components rely on the mandatory renderers you configured on your ril instance.

The <Form> Component

The <Form> component is the root of your form. It's a stateful component that manages the entire form lifecycle.

import { Form } from '@rilaykit/forms';
import { formConfig } from '@/config/my-form';

function MyFormPage() {
  const handleSubmit = (data) => {
    // This is called only when the form is valid
    console.log('Form submitted:', data);
  };

  const handleFieldChange = (fieldId, value, allData) => {
    console.log(`Field '${fieldId}' changed to:`, value);
    console.log('Current form data:', allData);
  };

  return (
    <Form
      formConfig={formConfig}
      onSubmit={handleSubmit}
      onFieldChange={handleFieldChange}
      defaultValues={{ firstName: 'Jane' }}
    >
      {/* Form layout components go here */}
    </Form>
  );
}

Props

  • formConfig: The configuration object generated by the formBuilder.
  • onSubmit: A callback function that receives the form data when the form is successfully submitted. By default, it will not be called if the form is invalid. This behavior can be changed with submit options.
  • onFieldChange (optional): A callback that fires whenever any field's value changes. It receives the fieldId, the new value, and a snapshot of the entire form's data.
  • defaultValues (optional): An object to populate the form with initial values. The keys should match the id of your fields.

Layout Components

Inside the <Form> component, you can use layout components to control how the fields are rendered.

<FormBody>

This is the simplest way to render your form. The <FormBody> component will iterate through the rows in your formConfig and render them using your registered FormBodyRenderer and FormRowRenderer.

<Form {...props}>
  <FormBody />
  <FormSubmitButton>Submit</FormSubmitButton>
</Form>

<FormField> for Custom Layouts

If you need a fully custom layout that doesn't follow the row structure defined in your formConfig, you can use the <FormField> component. This allows you to place any field, anywhere you want.

<Form {...props}>
  <div className="my-custom-layout">
    <div className="sidebar">
      <FormField fieldId="profilePicture" />
    </div>
    <div className="main-content">
      <h2>User Details</h2>
      <FormField fieldId="firstName" />
      <FormField fieldId="lastName" />
      <hr />
      <FormField fieldId="bio" />
    </div>
  </div>
  <FormSubmitButton>Save Changes</FormSubmitButton>
</Form>

When using <FormField>, you are responsible for the layout. The FormRowRenderer is not used. This gives you maximum flexibility.

<FormSubmitButton>

This is a smart component that handles form submission using your FormSubmitButtonRenderer. It is automatically disabled if the form is invalid or currently submitting. You can customize its content via its children.

<FormSubmitButton>
  {(props) => (
    props.isSubmitting ? 'Saving...' : 'Save Profile'
  )}
</FormSubmitButton>

The children can also be a simple string or element, like <FormSubmitButton>Submit</FormSubmitButton>.

On this page