npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@adimis/react-schema-form

v0.6.8

Published

The `@adimis/react-schema-form` is a React component library that provides a schema-based approach to form creation, built using React, Typescript, React Hook Form and Shadcn components for styling. This package simplifies the development of complex forms

Readme

@adimis/react-schema-form

The @adimis/react-schema-form is a React component library that provides a schema-based approach to form creation, built using React, Typescript, React Hook Form and Shadcn components for styling. This package simplifies the development of complex forms within React 18.2.0 or Next.js App Router 14.2.3 environments, incorporating Zod for robust form validation capabilities.

Features

  • ShadcnForm Component: Dynamically render forms from schema definitions with integrated Zod validation. This component ensures data integrity and simplifies form handling.
  • MultiStepShadcnForm Component: Facilitates the creation of multi-step forms with a tabbed user interface, allowing for segmented form data collection and enhanced user experience. This component manages form state across multiple steps, provides navigation controls, and integrates with the existing validation logic.
  • SchemaFormProvider and useSchemaFormContext: Manage and share form state across components using React's Context API. This setup allows for complex, customizable form behaviors without the need for additional libraries.
  • Advanced Validation: Employ Zod to validate complex data structures including nested objects and arrays, enhancing form validation beyond basic types.
  • Conditional Logic: Implement dynamic form behaviors such as conditional visibility and validation of fields based on user interactions or specific conditions.
  • Theme Customization: Supports light and dark modes, and facilitates the creation of custom themes via a theme provider, allowing for seamless integration into various design systems.

Installation

To start using @adimis/react-schema-form, follow these steps:

  1. Install the package via npm:

    npm install @adimis/react-schema-form
  2. Import the necessary CSS for styling if you are using the ShadcnForm Component:

    import "@adimis/react-schema-form/dist/style.css";

These steps ensure that all the necessary dependencies and styles are set up for the component to function and look correctly in your application.

Usage

Below is an example of how to use @adimis/react-schema-form in a React or NextJs application:

"use client";

import React from "react";
import "@adimis/react-schema-form/dist/style.css";
import {
  IMultiStepShadcnSchemaFormProps,
  IShadcnSchemaFormProps,
  ThemeColors,
  MultiStepShadcnForm,
  ShadcnForm,
} from "@adimis/react-schema-form";
import { z } from "zod";
import {
  Select,
  SelectTrigger,
  SelectValue,
  SelectContent,
  SelectItem,
} from "./ui/select";
import { Card } from "./ui/card";

interface SignUp {
  username: string;
  email: string;
  address: string;
  phone: string;
  password: string;
  gender: string;
}

const Form = () => {
  const defaultThemeColors: ThemeColors = {
    root: {
      background: "0 0% 100%",
      foreground: "0 0% 3.9%",
      card: "0 0% 100%",
      "card-foreground": "0 0% 3.9%",
      popover: "0 0% 100%",
      "popover-foreground": "0 0% 3.9%",
      primary: "0 72.2% 50.6%",
      "primary-foreground": "0 85.7% 97.3%",
      secondary: "0 0% 96.1%",
      "secondary-foreground": "0 0% 9%",
      muted: "0 0% 96.1%",
      "muted-foreground": "0 0% 45.1%",
      accent: "0 0% 96.1%",
      "accent-foreground": "0 0% 9%",
      destructive: "0 84.2% 60.2%",
      "destructive-foreground": "0 0% 98%",
      border: "0 0% 89.8%",
      input: "0 0% 89.8%",
      ring: "0 72.2% 50.6%",
      radius: "1rem",
    },
    dark: {
      background: "0 0% 3.9%",
      foreground: "0 0% 98%",
      card: "0 0% 3.9%",
      "card-foreground": "0 0% 98%",
      popover: "0 0% 3.9%",
      "popover-foreground": "0 0% 98%",
      primary: "0 72.2% 50.6%",
      "primary-foreground": "0 85.7% 97.3%",
      secondary: "0 0% 14.9%",
      "secondary-foreground": "0 0% 98%",
      muted: "0 0% 14.9%",
      "muted-foreground": "0 0% 63.9%",
      accent: "0 0% 14.9%",
      "accent-foreground": "0 0% 98%",
      destructive: "0 62.8% 30.6%",
      "destructive-foreground": "0 0% 98%",
      border: "0 0% 14.9%",
      input: "0 0% 14.9%",
      ring: "0 72.2% 50.6%",
    },
  };

  const schemaFormProps: IShadcnSchemaFormProps<SignUp> = {
    formLabel: "Example Form",
    formName: "example-form",
    card: true,
    theme: "dark",
    themeColors: defaultThemeColors,
    schema: [
      {
        key: "username",
        title: "Username",
        description: "Enter your desired username.",
        autoComplete: "username",
        type: "text",
        placeholder: "Your username",
        defaultValue: "",
        validations: z
          .string()
          .min(1, "Username is required")
          .max(20, "Username must not exceed 20 characters"),
      },
      {
        key: "email",
        title: "Email",
        description: "Enter your email address.",
        autoComplete: "email",
        type: "email",
        placeholder: "Your email",
        defaultValue: "",
        validations: z
          .string()
          .email("Enter a valid email address")
          .min(1, "Email is required"),
      },
      {
        key: "gender",
        title: "Gender",
        description: "Select your gender.",
        autoComplete: "gender",
        type: "select",
        options: [
          {
            label: "Male",
            value: "male",
          },
          {
            label: "Female",
            value: "female",
          },
        ],
        defaultValue: "male",
        placeholder: "Your gender",
        render: (formItem, field) => (
          <Select disabled={formItem.disabled} {...field}>
            <SelectTrigger>
              <SelectValue
                placeholder={formItem.placeholder || "Select option"}
              />
            </SelectTrigger>
            <SelectContent position="popper">
              {formItem.options?.map((option) => (
                <SelectItem key={option.value} value={option.value}>
                  {option.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        ),
      },
      {
        key: "address",
        title: "Address",
        description: "Enter your full address.",
        autoComplete: "address-line1",
        type: "text",
        placeholder: "Your address",
        defaultValue: "",
        validations: z
          .string()
          .min(10, "Address should be at least 10 characters"),
      },
      {
        key: "phone",
        title: "Phone",
        description: "Enter your phone number with country code.",
        autoComplete: "tel",
        type: "tel",
        placeholder: "+1234567890",
        defaultValue: "",
        validations: z
          .string()
          .regex(/^\+?(\d.*){10,}$/, "Enter a valid phone number"),
      },
      {
        key: "password",
        title: "Password",
        description: "Enter a strong password.",
        autoComplete: "new-password",
        type: "password",
        placeholder: "Your password",
        defaultValue: "",
        validations: z
          .string()
          .min(8, "Password should be at least 8 characters")
          .max(20, "Password must not exceed 20 characters"),
        displayConditions: [
          {
            dependentField: "email",
            dependentFieldValue: "[email protected]",
            operator: "===",
          },
        ],
        removeValidationConditions: [
          {
            dependentField: "email",
            dependentFieldValue: "[email protected]",
            operator: "!==",
          },
        ],
      },
    ],
    persistFormResponse: "sessionStorage",
    devTools: true,
    defaultValues: {
      email: "[email protected]",
      phone: "919625183597",
    },
    onChange: (formResponse, fieldValidations, canIgnoreErrors) =>
      console.log(
        "Form OnChange: ",
        formResponse,
        fieldValidations,
        canIgnoreErrors
      ),
    onSubmit: (values) =>
      console.log(
        "On Submit Example Form Response: ",
        JSON.stringify(values, null, 4)
      ),
    onInvalidSubmit: (values) =>
      console.log(
        "On Submit Invalid Example Form Response: ",
        JSON.stringify(values, null, 4)
      ),
  };

  const multiStepschemaFormProps: IMultiStepShadcnSchemaFormProps<SignUp> = {
    formLabel: "Example Form",
    formName: "example-form",
    card: true,
    theme: "dark",
    themeColors: defaultThemeColors,
    multiStepFormSteps: {
      step_1: {
        stageLabel: "Step 1",
        fields: ["username", "email"],
      },
      step_2: {
        stageLabel: "Step 2",
        fields: ["gender", "address"],
      },
      step_3: {
        stageLabel: "Step 3",
        fields: ["phone", "password"],
      },
    },
    schema: [
      {
        key: "username",
        title: "Username",
        description: "Enter your desired username.",
        autoComplete: "username",
        type: "text",
        placeholder: "Your username",
        defaultValue: "",
        validations: z
          .string()
          .min(1, "Username is required")
          .max(20, "Username must not exceed 20 characters"),
      },
      {
        key: "email",
        title: "Email",
        description: "Enter your email address.",
        autoComplete: "email",
        type: "email",
        placeholder: "Your email",
        defaultValue: "",
        validations: z
          .string()
          .email("Enter a valid email address")
          .min(1, "Email is required"),
      },
      {
        key: "gender",
        type: "select",
        options: [
          {
            label: "Male",
            value: "male",
          },
          {
            label: "Female",
            value: "female",
          },
        ],
        defaultValue: "male",
        placeholder: "Your gender",
        render: (formItem, field) => (
          <Select disabled={formItem.disabled} {...field}>
            <SelectTrigger>
              <SelectValue
                placeholder={formItem.placeholder || "Select option"}
              />
            </SelectTrigger>
            <SelectContent position="popper">
              {formItem.options?.map((option) => (
                <SelectItem key={option.value} value={option.value}>
                  {option.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        ),
      },
      {
        key: "address",
        title: "Address",
        description: "Enter your full address.",
        autoComplete: "address-line1",
        type: "text",
        placeholder: "Your address",
        defaultValue: "",
        validations: z
          .string()
          .min(10, "Address should be at least 10 characters"),
      },
      {
        key: "phone",
        title: "Phone",
        description: "Enter your phone number with country code.",
        autoComplete: "tel",
        type: "tel",
        placeholder: "+1234567890",
        defaultValue: "",
        validations: z
          .string()
          .regex(/^\+?(\d.*){10,}$/, "Enter a valid phone number"),
      },
      {
        key: "password",
        title: "Password",
        description: "Enter a strong password.",
        autoComplete: "new-password",
        type: "password",
        placeholder: "Your password",
        defaultValue: "",
        validations: z
          .string()
          .min(8, "Password should be at least 8 characters")
          .max(20, "Password must not exceed 20 characters"),
        displayConditions: [
          {
            dependentField: "email",
            dependentFieldValue: "[email protected]",
            operator: "===",
          },
        ],
        removeValidationConditions: [
          {
            dependentField: "email",
            dependentFieldValue: "[email protected]",
            operator: "!==",
          },
        ],
      },
    ],
    persistFormResponse: "sessionStorage",
    devTools: true,
    defaultValues: {
      email: "[email protected]",
      phone: "919625183597",
    },
    onChange: (formResponse, fieldValidations, canIgnoreErrors) =>
      console.log(
        "Form OnChange: ",
        formResponse,
        fieldValidations,
        canIgnoreErrors
      ),
    onSubmit: (values) =>
      console.log(
        "On Submit Example Form Response: ",
        JSON.stringify(values, null, 4)
      ),
    onInvalidSubmit: (values) =>
      console.log(
        "On Submit Invalid Example Form Response: ",
        JSON.stringify(values, null, 4)
      ),
  };

  return (
    <Card>
      <MultiStepShadcnForm {...multiStepschemaFormProps} />
      <ShadcnForm {...schemaFormProps} />
    </Card>
  );
};

export default Form;

Contributing

Contributions are welcome! Please see the repository's issues page for pending features and bugs. Submit pull requests to the repository at GitHub.

License

This project is licensed under the GNU General Public License v3.0. Please see the LICENSE file for more details.

More Information

For more details, please visit the project homepage.

This README provides a comprehensive guide for developers looking to utilize @adimis/react-schema-form in their projects, covering installation, basic usage, and features.