Support for object widget
This commit is contained in:
@ -3,6 +3,8 @@ import UnknownControl from './Widgets/UnknownControl';
|
||||
import UnknownPreview from './Widgets/UnknownPreview';
|
||||
import StringControl from './Widgets/StringControl';
|
||||
import StringPreview from './Widgets/StringPreview';
|
||||
import NumberControl from './Widgets/NumberControl';
|
||||
import NumberPreview from './Widgets/NumberPreview';
|
||||
import ListControl from './Widgets/ListControl';
|
||||
import ListPreview from './Widgets/ListPreview';
|
||||
import TextControl from './Widgets/TextControl';
|
||||
@ -13,13 +15,17 @@ import ImageControl from './Widgets/ImageControl';
|
||||
import ImagePreview from './Widgets/ImagePreview';
|
||||
import DateTimeControl from './Widgets/DateTimeControl';
|
||||
import DateTimePreview from './Widgets/DateTimePreview';
|
||||
import ObjectControl from './Widgets/ObjectControl';
|
||||
import ObjectPreview from './Widgets/ObjectPreview';
|
||||
|
||||
registry.registerWidget('string', StringControl, StringPreview);
|
||||
registry.registerWidget('text', TextControl, TextPreview);
|
||||
registry.registerWidget('number', NumberControl, NumberPreview);
|
||||
registry.registerWidget('list', ListControl, ListPreview);
|
||||
registry.registerWidget('markdown', MarkdownControl, MarkdownPreview);
|
||||
registry.registerWidget('image', ImageControl, ImagePreview);
|
||||
registry.registerWidget('datetime', DateTimeControl, DateTimePreview);
|
||||
registry.registerWidget('object', ObjectControl, ObjectPreview);
|
||||
registry.registerWidget('unknown', UnknownControl, UnknownPreview);
|
||||
|
||||
export function resolveWidget(name) {
|
||||
|
16
src/components/Widgets/NumberControl.js
Normal file
16
src/components/Widgets/NumberControl.js
Normal file
@ -0,0 +1,16 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
|
||||
export default class StringControl extends React.Component {
|
||||
handleChange = e => {
|
||||
this.props.onChange(e.target.value);
|
||||
};
|
||||
|
||||
render() {
|
||||
return <input type="number" value={this.props.value || ''} onChange={this.handleChange}/>;
|
||||
}
|
||||
}
|
||||
|
||||
StringControl.propTypes = {
|
||||
onChange: PropTypes.func.isRequired,
|
||||
value: PropTypes.node,
|
||||
};
|
9
src/components/Widgets/NumberPreview.js
Normal file
9
src/components/Widgets/NumberPreview.js
Normal file
@ -0,0 +1,9 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
|
||||
export default function StringPreview({ value }) {
|
||||
return <span>{value}</span>;
|
||||
}
|
||||
|
||||
StringPreview.propTypes = {
|
||||
value: PropTypes.node,
|
||||
};
|
51
src/components/Widgets/ObjectControl.js
Normal file
51
src/components/Widgets/ObjectControl.js
Normal file
@ -0,0 +1,51 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { Map } from 'immutable';
|
||||
import { resolveWidget } from '../Widgets';
|
||||
import styles from '../ControlPanel/ControlPane.css';
|
||||
|
||||
export default class ObjectControl extends Component {
|
||||
static propTypes = {
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onAddMedia: PropTypes.func.isRequired,
|
||||
getMedia: PropTypes.func.isRequired,
|
||||
value: PropTypes.node,
|
||||
field: PropTypes.node,
|
||||
};
|
||||
|
||||
controlFor(field) {
|
||||
const { onAddMedia, onRemoveMedia, getMedia, value, onChange } = this.props;
|
||||
const widget = resolveWidget(field.get('widget') || 'string');
|
||||
const fieldValue = value && value.get(field.get('name'));
|
||||
|
||||
return (
|
||||
<div className={styles.control} key={field.get('name')}>
|
||||
<label className={styles.label}>{field.get('label')}</label>
|
||||
{
|
||||
React.createElement(widget.control, {
|
||||
field,
|
||||
value: fieldValue,
|
||||
onChange: (val) => {
|
||||
onChange((value || Map()).set(field.get('name'), val));
|
||||
},
|
||||
onAddMedia,
|
||||
onRemoveMedia,
|
||||
getMedia,
|
||||
})
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { field } = this.props;
|
||||
const fields = field.get('fields');
|
||||
|
||||
if (!fields) {
|
||||
return <h3>No fields defined for this widget</h3>;
|
||||
}
|
||||
|
||||
return (<div>
|
||||
{field.get('fields').map(field => this.controlFor(field))}
|
||||
</div>);
|
||||
}
|
||||
}
|
28
src/components/Widgets/ObjectPreview.js
Normal file
28
src/components/Widgets/ObjectPreview.js
Normal file
@ -0,0 +1,28 @@
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import { resolveWidget } from '../Widgets';
|
||||
|
||||
export default class ObjectPreview extends Component {
|
||||
widgetFor = (field) => {
|
||||
const { value, getMedia } = this.props;
|
||||
const widget = resolveWidget(field.get('widget'));
|
||||
return (<div key={field.get('name')}>{React.createElement(widget.preview, {
|
||||
key: field.get('name'),
|
||||
value: value && value.get(field.get('name')),
|
||||
field,
|
||||
getMedia,
|
||||
})}</div>);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { field } = this.props;
|
||||
const fields = field && field.get('fields');
|
||||
|
||||
return <div>{fields && fields.map(f => this.widgetFor(f))}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
ObjectPreview.propTypes = {
|
||||
value: PropTypes.node,
|
||||
field: PropTypes.node,
|
||||
getMedia: PropTypes.func.isRequired,
|
||||
};
|
Reference in New Issue
Block a user