Created
January 31, 2017 09:02
-
-
Save karlbright/8ff8347e01ab167bf26fd0647202466c to your computer and use it in GitHub Desktop.
This file contains 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
import React from 'react' | |
import classnames from 'classnames' | |
import Input from './input' | |
import ColorPicker from './color_picker' | |
import FieldLabel from './field_label' | |
import ImageGrid from './image_grid' | |
import ImageField from './image_field' | |
import Divider from './divider' | |
import LargeButton from './large_button' | |
import camelcase from 'camelcase' | |
import {omit} from 'lodash' | |
import './experimental_form.sass' | |
const getAvailableFieldEventHandlers = (props, name) => { | |
if (!name) return {} | |
const events = [ | |
'key down', 'key press', 'key up', | |
'focus', 'blur', | |
'change', 'input', 'submit', | |
'click', 'double click', | |
'drag', 'drag end', 'drag enter', 'drag exit', 'drag leave', 'drag over', 'drag start', 'drop', | |
'mouse down', 'mouse enter', 'mouse leave', 'mouse move', 'mouse out', 'mouse over', 'mouse up', | |
'select', | |
'touch cancel', 'touch end', 'touch move', 'touch start' | |
] | |
return events.reduce((obj, event, index) => { | |
const target = props[camelcase(`on ${name} ${event}`)] | |
if (target) obj[camelcase(`on ${event}`)] = target | |
return obj | |
}, {}) | |
} | |
const getValidFieldProps = (field) => { | |
return omit(field, ['help', 'label']) | |
} | |
const getFieldComponent = (type) => { | |
switch (type) { | |
case 'color': return ColorPicker | |
case 'text': return Input | |
case 'image': return ImageField | |
case 'image-grid': return ImageGrid | |
default: return null | |
} | |
} | |
const getFieldValue = (props, field) => { | |
const valueOverrideProp = props[`${field.name}Value`] | |
if (valueOverrideProp) return valueOverrideProp | |
return props.values[field.name] ? props.values[field.name] : field.value | |
} | |
const renderField = (props, field) => { | |
const fieldValidProps = getValidFieldProps(field) | |
const fieldEventHandlers = getAvailableFieldEventHandlers(props, field.name) | |
const fieldComponent = getFieldComponent(field.type) | |
const fieldValue = getFieldValue(props, field) | |
return React.createElement(fieldComponent, { | |
...fieldValidProps, | |
...fieldEventHandlers, | |
value: props.values[field.name] ? props.values[field.name] : fieldValidProps.value | |
}) | |
} | |
const renderSchema = (props) => props.schema.map((field, index) => { | |
const isLastField = index === props.schema.length | |
const labelClassNames = classnames('experimental-form__label', { '-with-help': field.help }) | |
const renderedField = renderField(props, field) | |
if (!renderedField) { | |
console.warn(`Unable to render field type: ${field.type}`, field) | |
return null | |
} | |
return ( | |
<div key={index}> | |
<div className={labelClassNames}><FieldLabel {...field} /></div> | |
<div className='experimental-form__field'>{renderedField}</div> | |
{isLastField ? null : <div className='experimental-form__divider'><Divider /></div>} | |
</div> | |
) | |
}) | |
const renderSubmit = (props) => { | |
if (!props.onSubmit) return null | |
const label = props.submitLabel || 'Submit' | |
return ( | |
<div className='experimental-form__action'> | |
<LargeButton success type='submit'>{label}</LargeButton> | |
</div> | |
) | |
} | |
const renderCancel = (props) => { | |
if (!props.onCancel) return null | |
const label = props.cancelLabel || 'Cancel' | |
return ( | |
<div className='experimental-form__action'> | |
<LargeButton danger onClick={props.onCancel}>{label}</LargeButton> | |
</div> | |
) | |
} | |
const ExperimentalForm = (props) => { | |
return ( | |
<form onSubmit={props.onSubmit}> | |
{renderSchema(props)} | |
{renderSubmit(props)} | |
{renderCancel(props)} | |
</form> | |
) | |
} | |
export default ExperimentalForm |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment