Last active
September 5, 2017 15:26
-
-
Save bryzettler/4c064da68c905427ee83452030395b05 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @flow | |
import React from 'react'; | |
import { | |
Form, | |
Input, | |
Checkbox, | |
Radio, | |
Select, | |
Dropdown, | |
TextArea, | |
Label, | |
} from 'semantic-ui-react'; | |
/** | |
* Ment to work in tenem with redux-form | |
*/ | |
const FormField = ({ | |
input, | |
label, | |
type, | |
meta: { touched, error }, | |
...field, | |
}) => { | |
const { width, inline, errorPosition, labelVisible } = field; | |
const handleValueChange = (key) => (e, obj) => { | |
const value = obj[key]; | |
input.onChange(value); | |
}; | |
const renderField = () => ({ | |
'text': <Input {...input} {...field} />, | |
'textarea': <TextArea {...input} {...field} />, | |
'select': ( | |
<Select | |
{...input} | |
{...field} | |
onChange={handleValueChange('value')} | |
/> | |
), | |
'checkbox': ( | |
<Checkbox | |
{...input} | |
{...field} | |
label={label || input.value} | |
onChange={handleValueChange('checked')} | |
/> | |
), | |
'radio': ( | |
<Radio | |
{...input} | |
{...field} | |
label={label || input.value} | |
onChange={handleValueChange('value')} | |
/> | |
), | |
'dropdown': ( | |
<Dropdown | |
{...input} | |
{...field} | |
search | |
selection | |
multiple | |
onBlur={handleValueChange('value')} | |
onChange={handleValueChange('value')} | |
/> | |
) | |
}[type]); | |
const getErrorPointerPosition = () => ({ | |
"left": "right", | |
"right": "left", | |
"top": "below", | |
"bottom": "above", | |
undefined: (() => inline ? "left" : "above")(), | |
}[errorPosition]) | |
return ( | |
<Form.Field | |
width={width} | |
inline={inline || (!!errorPosition && ["left", "right"].includes(errorPosition))} | |
> | |
{/* | |
If input is checkbox || radio we dont want to show the label as it | |
also appears next the input itself. | |
*/} | |
{(labelVisible !== false && !["checkbox", "radio"].includes(type)) && ( | |
<label htmlFor={field.name}>{label}</label> | |
)} | |
{/* | |
Render error label above the input if errorPosition is left || top | |
*/} | |
{touched && (error && ["left", "top"].includes(errorPosition) && ( | |
<Label basic color="red" pointing={getErrorPointerPosition()}>{error}</Label> | |
))} | |
{renderField()} | |
{/* | |
if type is checkbox || radio that is not inline and errorPosition is bottom || undefined (default) | |
we require a <br /> to bump the error to the next line | |
*/} | |
{ | |
(error && ["checkbox", "radio"].includes(type)) && | |
(!inline && ["bottom", undefined].includes(errorPosition)) && | |
(<br />) | |
} | |
{/* | |
Render error label below the input if errorPosition is right || bottom || undefined (default) | |
*/} | |
{touched && (error && ["right", "bottom", undefined].includes(errorPosition) && ( | |
<Label basic color="red" pointing={getErrorPointerPosition()}>{error}</Label> | |
))} | |
</Form.Field> | |
) | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment