Skip to content

Instantly share code, notes, and snippets.

@talves
Forked from domtalbot/control.js
Last active March 21, 2018 20:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save talves/97b67bfb269cad6d89ad2f57ccc4e797 to your computer and use it in GitHub Desktop.
Save talves/97b67bfb269cad6d89ad2f57ccc4e797 to your computer and use it in GitHub Desktop.
Netlify Custom Widget
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Map } from 'immutable';
import CMS from 'netlify-cms';
export default class DynamicControl extends React.Component {
constructor(props) {
super(props);
// this.props.value = Map({
// 'slide': 'string',
// 'slide_selected': 'Hey! Change me'
// });
const fieldValue = this.props.value && Map.isMap(this.props.value) ?
this.props.value.get(this.props.field.get('name')) :
'';
if (!fieldValue) {
this.state = {
widget: null,
};
} else {
this.state = {
widget: CMS.getWidget(fieldValue),
};
}
}
handleChange = (e) => {
this.props.onChange(Map().set(e.target.id, e.target.value));
if (!e.target.value) {
this.setState({
widget: null,
});
} else {
this.setState({
widget: CMS.getWidget(e.target.value),
});
}
};
altChange = (target, val) => {
this.props.onChange(this.props.value.set(target, val));
}
linkChange = (target, val) => {
this.props.onChange(this.props.value.set(target, val));
}
render() {
const { field, value, forID, onChange, onAddAsset, onRemoveAsset, getAsset } = this.props;
const { widget } = this.state;
const name = field.get('name');
const selectedName = `${ field.get('name') }_selected`;
const selectedNameAlt = `${ field.get('name') }_selected_alt`;
const selectedNameLink = `${ field.get('name') }_selected_link`;
const fieldValue = value && Map.isMap(value) ?
value.get(name || '') :
'';
const fieldValueSelected = value && Map.isMap(value) ?
value.get(selectedName || '') :
'';
const fieldValueSelectedAlt = value && Map.isMap(value) ?
value.get(selectedNameAlt || '') :
'';
const fieldValueSelectedLink = value && Map.isMap(value) ?
value.get(selectedNameLink || '') :
'';
let options = field.get('dynamicWidgets').map((option) => {
if (typeof option === 'string') {
return { label: option, value: option };
}
return option;
});
options = options.insert(0, {
label: 'Please Select',
value: '',
});
return (
<div>
<div>
<select id={forID} value={fieldValue || ''} onChange={this.handleChange}>
{options.map((option, idx) => <option key={idx} value={option.value}>
{option.label}
</option>)}
</select>
</div>
<div>
{
widget ?
<div key={selectedName}>
<div key={selectedName}>
<label htmlFor={selectedName}>{`${ field.get('label') } Data`}</label>
{
React.createElement(widget.control, {
id: selectedName,
field,
value: '',
onChange: (val, metadata) => {
onChange((value || Map()).set(selectedName, val), metadata);
},
onAddAsset,
onRemoveAsset,
getAsset,
forID: selectedName,
})
}
</div>
</div>
:
''
}
</div>
<div>
{
fieldValue === 'image' ?
<div key={selectedNameAlt}>
<div key={selectedNameAlt}>
<label htmlFor={selectedNameAlt}>{`${ field.get('label') } Data Alt`}</label>
<input type="text" id={selectedNameAlt} value={fieldValueSelectedAlt || ''} onChange={(e) => { this.altChange(selectedNameAlt, e.target.value) }}/>
</div>
</div>
:
''
}
</div>
<div>
{
fieldValue === 'string' ?
<div key={selectedNameLink}>
<div key={selectedNameLink}>
<label htmlFor={selectedNameLink}>{`${field.get('label')} Data Link`}</label>
<input type="text" id={selectedNameLink} value={fieldValueSelectedLink || ''} onChange={(e) => { this.linkChange(selectedNameLink, e.target.value) }} />
</div>
</div>
:
''
}
</div>
</div>
);
}
}
DynamicControl.propTypes = {
onChange: PropTypes.func.isRequired,
onAddAsset: PropTypes.func.isRequired,
onRemoveAsset: PropTypes.func.isRequired,
getAsset: PropTypes.func.isRequired,
value: PropTypes.oneOfType([
PropTypes.node,
PropTypes.object,
PropTypes.bool,
]),
field: PropTypes.object,
forID: PropTypes.string,
dynamicWidgets: PropTypes.object
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment