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

@codewizard-dt/use-form-hook

v1.3.22

Published

A hook that provides a dynamic form handling component for React & Semantic UI

Downloads

32

Readme

Dynamic React Forms

License: MIT

A Form component exposed by a hook

Hooking up forms in React can be a real pain in the butt, but this package makes it EASY. It automatically handles form data in a way that prevents unnecessary component re-renders and helps you write the LEAST CODE possible. This package also relies on Semantic UI.

Table of Contents

Installation

npm i @codewizard-dt/use-form-hook
  • Run npm install
  • Install peer dependencies
    • semantic-ui-css
    • semantic-ui-react
    • lodash
    • path
    • react of course

Usage

This is a reusable React form template, complete with buttons and submission/response handling. The logic is built in, so all you need to provide is the names and attributes of the form fields.

Import Semantic UI Global Css

First off, you need to install the Semantic UI style sheet. After installing via npm, make sure you import the file into a top-level component. In NextJs, you need to add this line in _app.(tsx|jsx).

import "semantic-ui-css/semantic.min.css";

Put FormProvider in your app layout

The FormProvider gives a reusable context that stores the state of the form data, form errors, and the methods to update them. You MUST have the FormProvider in your DOM in order to use the hook. You can only have one active form at a time. If you need more, you'll have to provide multiple FormProviders.

import { FormProvider } from "@codewizard-dt/use-form-hook";
<FormProvider>
  ...
  {children} // Any child of `FormProvider` can use the hook */
  ...
</FormProvider>

Call useForm hook to expose the Form component

Any child component of FormProvider will have access to the form logic. Just use the hook by calling useForm. It return an object, the most important part of which is the Form component. Render the Form component and provide an array of fields.

There are defaults for the submit and respond properties. If you don't include them initially, the Form will console.log your data for you.

import { useForm } from "@codewizard-dt/use-form-hook";
const ChildComponent = (props) => {
  const { Form } = useForm();
  return <Form fields={[]} submit={submitHandler} respond={responseHandler} />;
};

Provide the Form element with fields, submit, and respond properties

| Form property | Description | Required | | ----------- | ----------- | ----------- | | fields | Array(object) an array of objects with properties that will be mapped onto FormField components from Semantic UI | true | | submit | (function) called with the form data when the form is submitted | false | | respond | (function) called with the API response when the request is finished. Can contain data or errors | false | | buttons | Array(object) an array of objects with properties that will be mapped onto Button components from Semantic UI. Accepts all properties of the Button component | false | | submitBtnText | (string) custom text for the submit button | false |

Provide fields property as an array of objects

The smallest object that can render an input field is just a name. The Form component will construct all of the components and connect them for you.

// Example.. Notice all you need is a `name`
fields={[
  { name: "username" }, 
  { name: "password", type: "password" },
  { name: "address", fields: [
    {name: "street", width: "6"},
    {name: "city", width: "3"},
    {name: "state", width: "3"}
  ]}
]}

Example

Creating Fields

The fields property is an array. It can include any number of Fields and/or FieldGroups, in any order. The form data object will reflect any nested structures that you create.

Field Properties

A field object can use any property that a FormField component from Semantic UI can use. | Field Property | Description | Required | | ----------- | ----------- | ----------- | | name | (string) used as a string key for form data | true | | initial | (string) initial field value | false | | type | (string) describes data type, ie 'text', 'number', 'password' | false | | label | (string) a label to display alongside | false | | useLabel | (boolean) if true and label not given, name is used | false | | required | (boolean) shows indicator and affects form behavior as normal | false | | control | (any) HTML tag (ie 'input', 'select') or a Semantic UI form control component | false | | options | Array(string|object) rendered as <option> for <select> tags | false | | disabled | (boolean) | false | | width | (SemanticWIDTHS) width as determined by Semantic UI | false |

Field Group Properties

A field group object can use any property that a FormGroup component from Semantic UI can use. | Property | Description | Required | | ----------- | ----------- | ----------- | | name | (string) used as a string key for form data. If you use an empty string, the form data object will not be nested. | true | | fields | Array(Field) creates nested form groups | false | | widths | (SemanticWIDTHS) determines width for nested form fields | false |

The Form Data Object

Automatically constructed data object for all fields in the form. If the form fields are nested, the data is nested too.

// Example, no nested fields
fields = {[
  { name: "username" }, 
  { name: "password", type: "password" },
]}

...

data = {
  username: '',
  password: ''
}

Example

// Example, nested fields
fields = {[
  { 
    name: "city",
    widths: "two",
    fields: [
      { name: 'best_restaurant' },
      { name: 'worst_restaurant' }
    ] 
  }
]}

...

data = {
  city: {
    best_restaurant: '',
    worst_restaurant: ''
  }
}

Example

// Example, nested fields but the group has no name
// When group has no name, data is flattened
// You might want to do this for styling but don't want the data nested
fields = {[
  { 
    name: "",
    fields: [
      { name: 'best_restaurant' },
      { name: 'worst_restaurant' }
    ] 
  }
]}

...

data = {
  best_restaurant: '',
  worst_restaurant: ''
}

Example

Provide submit property as a function

/**
 * Defines the `submit` property which sends the form data to the Api 
 * Must return a promise
 */

export type OnSubmitHandler = (data: DataMap) => Promise<ApiResponse<any>>

const submit:FormSubmitHanlder = (data) =>{
  return post('url',data)
}

Provide respond property as a function

/**
 * Defines the `respond` property which receives the ApiResponse
 * Where <T> is the data type you expect from the API
 */
export type ApiResponse<T> = {
  data?: T,
  error?: any,
  errors?: {
    [key: string]: string
  }
}
export type ApiResponseHandler<T> = (response: ApiResponse<T>) => void

const respond:ApiResponseHandler<YourDataType> = (response) =>{
  // data = your API data
  // error = generic error or specific form error, either way automatically displayed under the form
  // errors = specific form errors, validation for instance. Displayed under any Field whose name matches one of the objects' keys
  let { data, error, errors } = response
}

License

This project is provisioned under the MIT License

Contributing

Repo link

Do you want to help make this project better? Visit the the repo to check out existing issues or create a new branch to start working on a suggested feature

Tests

None yet!

Questions

If you have any questions, please contact me on Github or email.

Gimme Readme

This file was initialized by the Gimme Readme command line README generator