This package has been deprecated

Author message:

This package has been deprecated.

react-formtype

1.2.0 • Public • Published

react-formtype

NPM JavaScript Style Guide

✏️ React library alternative for building TypeForm style forms.

See an example.

Contents

Usage

import React from 'react'
import { FormContainer, ShortTextField, NumberField, DateField, MultipleChoiceFIeld,
         InformationField, SubmitField } from 'react-formtype'
 
export default () => (
  <FormContainer 
    showProgress={true} 
    onSubmit={data => console.log(data)}
    progressStyle={{ innerBar: { backgroundColor: 'black' } }}
  >
    <InformationField 
      title="Hello, Welcome To The Fruit Order Form" 
      description="Ready to start?" 
      nextBtnText="Lets Go"
    />
    <ShortTextField 
      title="First off, what's your name?" 
      name="name" 
      minTextLength={2} 
      required 
    />
    <MultipleChoiceFIeld 
      title="Nice to meet you {{_.name}}, what fruit would you like?" 
      name="fruits" 
      options={['Banana', 'Apple', 'Orange', 'Pear']} 
      multiple
      style={{ 
        optionButtonActive: { 
          borderColor: '#66aef7', color: 'black', fontWeight: 'bold'
        }
      }}
    />
    <NumberField 
      title="How many free oranges do you want?" 
      name="noranges"
      min={0}
      defaultValue={5}
    />
    <DateField 
      title="When would you like your {{_.noranges}} oranges?" 
      name="orrangedate" 
      required
    />
    <SubmitField 
      title="Thanks!" 
      description="You will have your fruit shortly." 
      nextBtnText="Send Form" 
    />
  </FormContainer>
)

Fields should have unique name props as values are stored in the FormContainer as {fieldName: value} pairs. And will be passed to the onSubmit callback in this format.

Assuming a value is given for each field in the above example, when the user hits submit, the submit method will receive:

data = { name: ..., fruits: [...], noranges: ..., orangedate: { day: ..., month: ..., year: ... } }

The last child contained in FormContainer will act as the submit field and when a user clicks the button for that field it will run the onSubmit callback method.

Features

  • Typeform style scrolling behaviour
  • Custom styling
  • Reference user inputs in field titles
  • Progress bar
  • Easy validation
  • Ability to build Custom Fields

Reference User Inputs In Titles

Field titles can reference previous user inputs in the titles of other fields. This is achieved by:

  • using {{_.FIELD_NAME}} in the title prop.

Custom Styling

Custom styling is applied to fields through a style prop.

All Field Components can change the styling of the title, description, next button etc using the keys listed below. Some components have addional style options which can be seen in the props for the component below.

<SomeFieldComponent 
  style={{
    fieldContainer: {/*css styles here*/},
    title: {},
    description: {},
    nextButton: {},
    pressEnter: {},
    pressEnterInner: {},
    errorBar: {}
  }} />

Components

FormContainer

Container component for handling form state and transitions between form fields.

All Fields in the form must be children of the FormContainer component.

FormContainer.propTypes = {
  /**
   * onSubmit: Function to call upon submission. Recieve form data object as arg.
   * Returns: object of errors, or true if there are none.
   * returned errors object should look like: { fieldName: [ 'err' ], field2: [ 'err' ], ... }
   */
  onSubmit: func.isRequired,
  children: oneOfType( [ arrayOf( // Array of fields (form body)
    instanceOf( Object ),
  ), instanceOf( Object ) ] ).isRequired,
  showProgress: bool, // Whether to show progress bar
  scrollDuration: number, // Scroll animation time
  edgeOffset: number, // Add offset to scroll to prevent field from being hidden by a header
  progressStyle: shape( {
    container: instanceOf( Object ),
    label: instanceOf( Object ),
    bar: instanceOf( Object ),
    innerBar: instanceOf( Object ),
  } ),
}
 
FormContainer.defaultProps = {
  showProgress: true,
  scrollDuration: 777,
  edgeOffset: 0,
  progressStyle: {},
}

Field Components

Field components are always children of the FormContainer component

All fields have a common set of props as shown below, as well as additional props relevant only to themselves

commonPropTypes = {
  title: string,
  description: string,
  name: string, // Input name - values entered by user are stored as [name]: value. Must be unique.
  defaultValue: any,
  required: bool,
  placeholder: string,
  nextBtnText: string,
  style: instanceOf( Object ), // Custom styling
}
const commonDefaultProps = {
  title: '',
  description: '',
  name: '',
  defaultValue: null,
  required: false,
  placeholder: 'Type your answer here...',
  nextBtnText: 'Next',
  style: {},
}

ShortTextField

ShortTextField.propTypes = {
  ...commonPropTypes,
  maxLength: number,
  style: shape( { textInput: instanceOf( Object ) } ),
}
 
ShortTextField.defaultProps = {
  ...commonDefaultProps,
  maxLength: 524288,
}

NumberField

NumberField.propTypes = {
  ...commonPropTypes,
  min: number,
  max: number,
  style: shape( { numberInput: instanceOf( Object ) } ),
}
 
NumberField.defaultProps = {
  ...commonDefaultProps,
  min: Number.MIN_VALUE,
  max: Number.MAX_VALUE,
}

DateField

DateField.propTypes = {
  ...commonPropTypes,
  includeTime: bool, // Whether to display time input field
  style: shape( {
    dateInput: instanceOf( Object ),
    dateInputContainer: instanceOf( Object ),
    dateInputLabel: instanceOf( Object ),
  } ),
}
 
DateField.defaultProps = {
  ...commonDefaultProps,
  includeTime: false,
}

MultipleChoiceField

MultipleChoiceField.propTypes = {
  ...commonPropTypes,
  options: arrayOf( string ).isRequired, // The possible options to pick from
  multiple: bool, // Whether the user can select multiple options
  style: shape( {
    optionButton: instanceOf( Object ),
    optionButtonActive: instanceOf( Object ),
  } ),
}
 
MultipleChoiceField.defaultProps = {
  ...commonDefaultProps,
  multiple: false,
}

InformationField

This field is used to display information to the user, e.g. a welcome screen.

SubmitField

This component should be used as the last child within FormContainer as the last child component within FormContainer is always assumed to be the submit field and will run the submit call back when the next button is pressed.

Custom Fields

Fields can be created using the withValidationAndTransition higher order component and the <Field /> component which are both exported by react-formtype.

The <Field /> Component

This is the default way to display the field components, it displays the title, description, validation errors and the next button. See src/components/fields/NumberField.js for example usage in the render method.

Field.propTypes = {
  children: instanceOf( Object ), // The input element
  title: string.isRequired, // The title of the field
  description: string, // Description for additional instructions
  next: func, // The function to call to scroll to the next field
  nextBtnText: string, // Text to display in the next button
  err: arrayOf( string ), // Any errors in the input given by a user
  required: bool,
  containerRef: shape( { current: instanceOf( Element ) } ), // Reference for container to scroll to
  style: shape( {
    fieldContainer: instanceOf( Object ),
    title: instanceOf( Object ),
    description: instanceOf( Object ),
    nextButton: instanceOf( Object ),
    pressEnter: instanceOf( Object ),
    pressEnterInner: instanceOf( Object ),
    errorBar: instanceOf( Object ),
  } ),
}
 
Field.defaultProps = {
  description: '',
  next: null,
  nextBtnText: 'Next',
  err: [],
  required: false,
  containerRef: null,
  children: null,
  style: {},
}

You can create your own Field component for use with your own fields. (Future feature: ability to pass in custom Field component to FormContainer so you can reuse all the premade fields with your own UI structure for the title/description/next buttons/errors).

The withValidationAndTransition HOC

This component adds shared functionality to all field components.

  • It provides validation checking and modifications
  • Registering validation errors with the parent component (FormContainer)
  • Passing the input value up to the parent component for centralised management of the form state.
  • Handles when a field can transition to the next section after a user clicks the next button or hits enter.

Validation For Custom Fields

Fields wrapped with the HOC come with default validation methods and usage is determined by the props passed when a form is created, e.g. if a form field is passed a min={5} prop, then the min function will be used during validation and tests the input value with the test value of 5. These default methods can be found in /src/utils/validation.js

Custom validation methods specific to a field component can be created. When a custom validation method is called it is passed 3 arguments:

  • value the value input by a user
  • test the value to test against (e.g. min would test if value >= test)
  • props the field component props. This allows validation methods to use prop values inside it

The HOC passes 2 functions to the wrapped field component to allow custom validation for a specific field:

  • addValidationChecks(checks) adds checks to be made each time an input is validated. This can be custom validation that is specific to your field component. The checks input should have the following structure { min: {func: <function>, test: <value>}, max: {func: <function>, test: <value> } } where func is the method to run and test is the value to check against.
  • updateValidationChecks(methods) allows you to update a method being used in the defaultValidationMethods in /src/utils/validation.js for example the required check may be more complex than just seeing if an value is null/empty string/empty array. E.g. with DateField we must check that {day, month, year} are all given. methods should look like { methodName: <function>, methodName: <function> }. E.g. To override the default required method call updateValidationChecks({required: newRequiredFunc }) inside the field component onComponentDidMount method.

By using the above methods you can customise the validation for your own field components that are wrapped with the withValidationAndTransition HOC.

License

MIT © Sam-Ogden

Readme

Keywords

none

Package Sidebar

Install

npm i react-formtype

Weekly Downloads

3

Version

1.2.0

License

MIT

Unpacked Size

3.13 MB

Total Files

6

Last publish

Collaborators

  • samogden