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

@eitje/form

v3.1.0

Published

Beautiful forms made easy

Downloads

348

Readme

Forms: opiononated React (web & native) forms library

This library empowers you to write feature-packed forms with only a few lines of code.rts It exports three main components, the most important/core component being 'Form':

Base example

import Form from 'initializers/form'
import {Input} from '@eitje/form-fields-web'

<Form onSubmit={data => login(data) }>
  <Input required field="email"/>
  <Input required secure field="password"/>
  <div fieldWrapper>
    <p> hello im just text </p>
    <Input required field="name"/>
  </div>
  <Button submitButton> Submit </Button>
</Form>

Idea

The Form component is the 'brain' of your form and manages the state of all fields & enhances all fields with some extra powers. To work efficiently, it's wise to create your own form fields components and re-use them through the application, for an example look in the form-fields-web GH library.

It knows which of its children are fields because they have the 'field' prop, just as in the example above. If you omit the field prop, the child will not be 'formified'.

Nested fields (fieldWrapper)

To 'formify' nested fields, you have to pass the prop fieldWrapper to the container (arbitrary HTML element). You can also pass namespace to the fieldWrapper to provide all of its field children with that namespace

Props

| Key | Explanation | Default value | | ------------- |:-------------:| -----:| | initialValues | Initial values of the form, provided as an object | {} | | submitInitialValues | also submits initialValues that aren't part of the form (normally, we filter out all extra initialValues to prevent you from accidentally posting data you don't want to post | false | | onSubmit | What to do when form is submitted, provides formData as first arg | data => {} | | afterSubmit | Functions to run after submit was successfull | () => {} | | afterSubmMessage | Message to display after successfull submit, will use eitje utils.toast | null | disabled | disable whole form, prop will be passed to all children | false | | nestedField | Useful if you want to edit multiple nested items in one form. This builds your nested params | | | afterChange | callback you can use after any field changes. Invoked with arguments (fieldName, value) | | | resetAfterSubmit | reset form to initialValues after submit | false | | fieldProps | props to be passed down to all form children with a field prop | {} | | hiddenFields | array of fields that should be hidden (hidden means: not visible, wont be sent along with request, wont be validated) | [] |

Imperative actions

There are also some actions you can call directly on the form instance. You unlock this by adding a ref to your instance.

Example:

const ref = useRef(null)

<Form ref={ref} onSubmit={data => login(data) }>

</Form>

<Button onClick={() => ref.current.resetValues() }> 
   Reset your form
</Button>

Actions:

| Action | Explanation | Params | | ------------- |:-------------:| -----:| | setValues(vals) | Set values imperatively | {key: value} | | resetValues(empty) | Reset form state to default | If empty is false (default), form will reset to initialValues, otherwise empty object. | | getValue(field) | Get value of field | | | submit | Submit the form | | | validate | Validate the form (renders errors) | | | getValues(fields | return values as object {field: value, field2: value} | array of fields | blockSubmit(field, blocked) | blocks or de-blocks the form from submitting, automatically re-enables it after 15 seconds | field is name of the field to allow your UI components to render a special 'blocked' state, blocked is a boolean designating whether it's a block or a de-block

MultiForm

The second component is 'MultiForm', which 'duplicates' its children. Useful if you're editing multiple resources at the same time. You can pass it field children, just as you do with form, and it will render that children x amount of times (controllable by you through the amtForms prop). There's also built-in support for adding/deleting forms. An example might help:

<MultiForm  formProps={{styleKind: 'modal', allowEmpty: true}}  afterSubmit={onCancel} onSubmit={data => inviteUser(data)} 
                       autoAdd  amtForms={3}>
      <div className="fRow" fieldWrapper>
        <Input field="email" required/>
        <DropdownPicker  containerStyle={ContainerStyleRow} multiple field="team_ids" labelField="naam" items={teams} />
      </div>

  <Button type="primary" ignoreForm submitButton>{t('submitS')}</Button>
</MultiForm>

This MultiForm will render three forms and will automatically add another form when the last form is changed.

Building your own fields

Props passed to every field

These props are passed by the form to the fields, making them 'formified', which you must implement when building your own.

| Key | Explanation | Default value | | ------------- |:-------------:| -----:| | onChange | function to update the form's state, do not override this as it will break the form | | | submitForm | Way of submitting form inside a field (useful when you want to submit on enter in an input for example) | | | formData | Current state of input data | | | blockSubmit | Temporarily block submitting of the form, useful if you need to wait on something like asset upload. Will auto unblock after 5 sec, blockSubmit(false) opens the submit again | | | error | error text | | | value | current value | | | getNext | function to get the next form child, useful for setting focus | |

NOTE: Further info about field props can be found on the form-fields-web page

You can use the above ^ props to build your own form fields, made even easier by the following methods:

Easy way (HOC)

This library exports an HOC to simplify the field building process, called makeField. This HOC renders a container and automatically sets the opacity to 0.2 when the field is disabled. Also, it renders the label & potential error. This HOC uses the useFormField hook internally, you can also use the hooks yourself if you have more custom needs. That's explained underneath.

Example of building an input field:

const _Input = (props) => {
  const {value, secure, onChange, ...rest} = props
  const InputEl = secure ? AntInput.Password : AntInput

  return (
        <InputEl {...rest} value={value} onChange={e => onChange(e.target.value)}/>
    )
}

export const Input = makeField(props) 

Now you can import this component to make the first example work!

Advanced way (hooks)

This library also exports two hooks, these hooks simplify the props a bit. You should always use useFormField, usePicker only when working with a select-like input

  • useFormField: returns {error, disabled, label, value}
  • usePicker: returns {pickerItems, selectedItem, selectedBaseItem}

To clarify: pickerItems is an array of objects structured like {key, label, value}. This way it can easily be consumed by any input without that input having to know about the structure of your record

selectedItem is the currently selected item(s) in {key, label, value} style, while selectedBaseItem is the original record (before conversion).