Skip to main content
Version: 1.0

Usage

Create a components library

We will put our components in a folder and return the appropriate input by calling the default function in index.js. For example we will name our folder components/felwine-library.

index.js

import input from './input'
import inputPassword from './inputPassword'
import submit from './submit'

export default (props) => {
const { type } = props
switch (type) {
case 'input':
return input
case 'inputPassword':
return inputPassword
case 'submit':
return submit
default:
return null;
}
}

Create input components

An input component is standardized, it follows the input interface api

Text input: */input/index.js

import { useCallback, useEffect, useState, } from 'react'
import TextField from '@mui/material/TextField'
import { useDebouncedCallback } from 'use-debounce'

export default (props) => {
const {
value,
error,
disabled,
onValueChanged,
item: {
layoutMode = 'form',
label,
params = {},
id }
} = props

const {
placeholder,
inputDelay = 1000,
className = '',
multiline = true,
inputPropsStyle = {},
inputLabelPropsStyle = {},
variant = "outlined" } = params

const [innerValue, setInnerValue] = useState(value ? value : '')

useEffect(() => {
setInnerValue(value ? value : '')
}, [value])

const debouncedHandleOnChange = useDebouncedCallback(
(event) => {
const value = event.target.value
onValueChanged(value)
console.log('textArea debouncedHandleOnChange', value)
},
inputDelay
)

const handleOnChange = useCallback((event) => {
event.persist()
const newValue = event.target.value
setInnerValue(newValue)
debouncedHandleOnChange(event)
console.log('textArea handleOnChange', value)
}, [])

const layoutModeProps = () => {
switch (layoutMode) {
default:
case 'form': {
return {

}
}
case 'inline': {
return {
variant: "standard",
}
}
}
}

const layoutModeClassName = () => {
switch (layoutMode) {
default:
case 'form': {
return `
`
}
case 'inline': {
return `
`
}
}
}

const onBlur = () => {
console.log('onblur')
}

return <TextField
variant={variant}
fullWidth
disabled={props.disabled}
inputProps={{
style: {
...inputPropsStyle,
}
}}
InputLabelProps={{ style: inputLabelPropsStyle }}
value={innerValue}
multiline={multiline}
className={`transition-all ease-in-out duration-1000 ${error ? 'bg-red-50' : ''}
${className}
${layoutModeClassName()}`}
onBlur={onBlur}
onChange={handleOnChange}
{...layoutModeProps()}
{...params}
/>
}

Build the form

import { useState } from 'react'
import Felwine from '@felwine/react'
import OvideLocal from 'components/felwine-library'
import * as Yup from 'yup'

const inputs = [
{
type: 'input',
schema: 'email',
id: 'email',
label: 'Email',
params: {
type: 'email',
placeholder: "email@domain.com"
}
},
{
type: 'inputPassword',
schema: 'password',
label: 'Password',
id: 'password',
params: {
type: 'password',
autoComplete: "current-password",
placeholder: "xxxx-xxxx-xxxx"
}
},
{
type: 'submit',
params: {
text: 'Continue'
}
},
]

const validationSchema = Yup.object().shape({
email: Yup.string()
.email('Invalid email format')
.required("This field can't be blank"),
password: Yup.string()
.required("This field can't be blank")
.min(7, 'Must contain at least 8 characters')
.max(18, 'Must contain at most 18 characters')
.matches(/[a-zA-Z]/, 'Password can only contain Latin letters.')
})

export default (props) => {
const [error, setError] = useState(null)

const onSubmit = async (values, { setSubmitting }) => {
try {
const { email, password } = values
//... do login
setError(null)
} catch (e) {
console.log(e)
setError(e)
}

setSubmitting(false)
}

const values = {

}

return <div>
<h1>Login</h1>
<Felwine
components={[OvideLocal,]}
values={values}
validationSchema={validationSchema}
inputs={inputs}
onSubmit={onSubmit}
error={error} />
</div>
}