Form

A form component that provides validation and error handling for form inputs.

form-demo.tsx
"use client";

import { useState } from "react";
import {
  Form,
  FormField,
  FormControl,
  FormLabel,
  FormError,
  FormActions,
} from "@/components/ui/form/form";
import { Button } from "@/components/ui/button/button";

export default function FormDemo() {
  const [errors, setErrors] = useState({});
  const [loading, setLoading] = useState(false);

  return (
    <Form
      errors={errors}
      onClearErrors={setErrors}
      onSubmit={async (event) => {
        event.preventDefault();
        const formData = new FormData(event.currentTarget);
        const url = formData.get("url") as string;

        setLoading(true);
        const response = await submitForm(url);
        const serverErrors = {
          url: response.error,
        };

        setErrors(serverErrors);
        setLoading(false);
      }}
      style={{ maxWidth: "400px" }}
    >
      <FormField name="url">
        <FormLabel>Homepage</FormLabel>
        <FormControl
          type="url"
          required
          placeholder="https://example.com"
          pattern="https?://[^/]+\.com(/.*)?$"
        />
        <FormError />
      </FormField>

      <FormActions>
        <Button disabled={loading} type="submit" style={{ width: "100%" }}>
          {loading ? "Submitting..." : "Submit"}
        </Button>
      </FormActions>
    </Form>
  );
}

async function submitForm(value: string) {
  await new Promise((resolve) => {
    setTimeout(resolve, 1000);
  });

  try {
    const url = new URL(value);

    if (url.hostname.endsWith("example.com")) {
      return { error: "The example domain is not allowed" };
    }
  } catch {
    return { error: "This is not a valid URL" };
  }

  return { success: true };
}

Installation

npx shadcn@latest add https://roiui.com/r/form.json

Anatomy

anatomy
import {
Form,
FormField,
FormControl,
FormLabel,
FormDescription,
FormError,
FormGroup,
FormRow,
FormActions,
} from '../ui/form'

<Form>
  <FormGroup>
      <FormField>
          <FormLabel />
          <FormDescription />
          <FormControl />
          <FormError />
      </FormField>
  </FormGroup>
  <FormActions></FormActions>
</Form>