Skip to main content

withKingpin

Basics

Modern forms require more than just <input /> and <textarea /> components.

Kingpin plan is to add pluggable external components like Typeaheads, Slider, Dropdown ecc. specifically desinged and developed to work within a Kingpin Form out of the box.

In order to make Kingpin extensible by anyone it's possible create custom components with the withKingpin HOC.

Following an example to learn how to use the withKingpin HOC.

Props

The created element will have the following props.

NameMandatoryPurpose
nametrueA string which describe the element. Will be the element key in the submit payload
initialValuefalseThe element initial value
validationfalseA single (or an array/object of) function(s) to validate the element. Check the doc
errorClassNamefalseA className that is attached to the className on error. Check validation for more.
Custom attributesfalseAll your custom attributes

Example: Kingpin and react-select

Let's say that for our form we need an "enhanced" select component (compared to the plain HTML <select />) and for this reason we decide to use react-select (you can use whatever third part component or even build your own).

After having installed react-select with your favourite package manager let's create the new custom component.

// File: ./Select.tsx
import { withKingpin } from 'kingpin-react-form'
import { useState } from 'react'
import Select, { SingleValue } from 'react-select'

type Option = { value: string; label: string }

const options: Option[] = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' },
]

type CustomSelectProps = {
updateState: (val: SingleValue<Option>) => void
initialValue?: SingleValue<Option>
}

function CustomSelect({ updateState, initialValue }: CustomSelectProps): JSX.Element {
const [selectedOption, setSelectedOption] = useState<SingleValue<Option>>(initialValue)

return (
<div className="App">
<Select
defaultValue={selectedOption}
onChange={(val) => {
setSelectedOption(val)
updateState(val)
}}
options={options}
/>
</div>
)
}

export default withKingpin<CustomSelectProps, SingleValue<Option>>(CustomSelect)

Now we are ready to use our new component within our Form component.

// File: ./App.tsx
import CustomSelect './Select'
import type { FormEvent } from 'react'
import { Form, FormResult } from 'kingpin-react-form'

function App(): JSX.Element {
const submit = (e: FormEvent<HTMLFormElement>, data: FormResult) => {
e.preventDefault()
console.log(data)

// data: {
// isValid: true,
// payload: {
// hoc-select: null
// }
// }
}

return (
<Form onSubmit={submit}>
<CustomSelect name="hoc-select" />
<button type="submit">Submit</button>
</Form>
)
}