diff --git a/src/components/Widgets/ControlHOC.js b/src/components/Widgets/ControlHOC.js index 74cdeea495be..aede65fdfaf9 100644 --- a/src/components/Widgets/ControlHOC.js +++ b/src/components/Widgets/ControlHOC.js @@ -18,7 +18,7 @@ class ControlHOC extends Component { mediaPaths: ImmutablePropTypes.map.isRequired, metadata: ImmutablePropTypes.map, onChange: PropTypes.func.isRequired, - onValidate: PropTypes.func.isRequired, + onValidate: PropTypes.func, onOpenMediaLibrary: PropTypes.func.isRequired, onAddAsset: PropTypes.func.isRequired, onRemoveAsset: PropTypes.func.isRequired, diff --git a/src/components/Widgets/ListControl.js b/src/components/Widgets/ListControl.js index ebd0df344cda..406aee4b93e2 100644 --- a/src/components/Widgets/ListControl.js +++ b/src/components/Widgets/ListControl.js @@ -46,6 +46,16 @@ export default class ListControl extends Component { this.valueType = null; } + /** + * Always update so that each nested widget has the option to update. This is + * required because ControlHOC provides a default `shouldComponentUpdate` + * which only updates if the value changes, but every widget must be allowed + * to override this. + */ + shouldComponentUpdate() { + return true; + } + componentDidMount() { const { field } = this.props; if (field.get('fields')) { diff --git a/src/components/Widgets/ObjectControl.js b/src/components/Widgets/ObjectControl.js index 8598f17a3d63..ca4736c7aee3 100644 --- a/src/components/Widgets/ObjectControl.js +++ b/src/components/Widgets/ObjectControl.js @@ -2,6 +2,7 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; import { Map } from 'immutable'; import ImmutablePropTypes from 'react-immutable-proptypes'; +import ControlHOC from './ControlHOC'; import { resolveWidget } from '../Widgets'; import controlStyles from '../ControlPanel/ControlPane.css'; import styles from './ObjectControl.css'; @@ -24,6 +25,23 @@ export default class ObjectControl extends Component { className: PropTypes.string, }; + /** + * Always update so that each nested widget has the option to update. This is + * required because ControlHOC provides a default `shouldComponentUpdate` + * which only updates if the value changes, but every widget must be allowed + * to override this. + */ + shouldComponentUpdate() { + return true; + } + + onChange = (fieldName, newValue, newMetadata) => { + const { value, onChange } = this.props; + const objectValue = value || Map(); + const newObjectValue = objectValue.set(fieldName, newValue); + return this.props.onChange(newObjectValue, newMetadata); + }; + controlFor(field) { const { onAddAsset, onOpenMediaLibrary, mediaPaths, onRemoveAsset, getAsset, value, onChange } = this.props; if (field.get('widget') === 'hidden') { @@ -35,22 +53,18 @@ export default class ObjectControl extends Component { return (
- { - React.createElement(widget.control, { - id: field.get('name'), - field, - value: fieldValue, - onChange: (val, metadata) => { - onChange((value || Map()).set(field.get('name'), val), metadata); - }, - onOpenMediaLibrary, - mediaPaths, - onAddAsset, - onRemoveAsset, - getAsset, - forID: field.get('name'), - }) - } +
); }