diff --git a/packages/netlify-cms-widget-list/src/ListControl.js b/packages/netlify-cms-widget-list/src/ListControl.js index 5c9748dd..baccefe9 100644 --- a/packages/netlify-cms-widget-list/src/ListControl.js +++ b/packages/netlify-cms-widget-list/src/ListControl.js @@ -4,8 +4,8 @@ import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import styled from '@emotion/styled'; import { jsx, css, ClassNames } from '@emotion/core'; -import { List, Map } from 'immutable'; -import { partial } from 'lodash'; +import { List, Map, fromJS } from 'immutable'; +import { partial, isEmpty } from 'lodash'; import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc'; import NetlifyCmsWidgetObject from 'netlify-cms-widget-object'; import { @@ -165,19 +165,64 @@ export default class ListControl extends React.Component { handleAdd = e => { e.preventDefault(); - const { value, onChange } = this.props; - const parsedValue = this.getValueType() === valueTypes.SINGLE ? null : Map(); + const { value, onChange, field } = this.props; + const parsedValue = + this.getValueType() === valueTypes.SINGLE + ? this.singleDefault() + : fromJS(this.multipleDefault(field.get('fields'))); this.setState({ itemsCollapsed: this.state.itemsCollapsed.push(false) }); onChange((value || List()).push(parsedValue)); }; + singleDefault = () => { + return this.props.field.getIn(['field', 'default'], null); + }; + + multipleDefault = fields => { + return this.getFieldsDefault(fields); + }; + handleAddType = (type, typeKey) => { const { value, onChange } = this.props; - let parsedValue = Map().set(typeKey, type); + let parsedValue = fromJS(this.mixedDefault(typeKey, type)); this.setState({ itemsCollapsed: this.state.itemsCollapsed.push(false) }); onChange((value || List()).push(parsedValue)); }; + mixedDefault = (typeKey, type) => { + const selectedType = this.props.field.get(TYPES_KEY).find(f => f.get('name') === type); + const fields = selectedType.get('fields') || [selectedType.get('field')]; + + return this.getFieldsDefault(fields, { [typeKey]: type }); + }; + + getFieldsDefault = (fields, initialValue = {}) => { + return fields.reduce((acc, item) => { + const subfields = item.get('field') || item.get('fields'); + const object = item.get('widget') == 'object'; + const name = item.get('name'); + const defaultValue = item.get('default', null); + + if (List.isList(subfields) && object) { + const subDefaultValue = this.getFieldsDefault(subfields); + !isEmpty(subDefaultValue) && (acc[name] = subDefaultValue); + return acc; + } + + if (Map.isMap(subfields) && object) { + const subDefaultValue = this.getFieldsDefault([subfields]); + !isEmpty(subDefaultValue) && (acc[name] = subDefaultValue); + return acc; + } + + if (defaultValue !== null) { + acc[name] = defaultValue; + } + + return acc; + }, initialValue); + }; + processControlRef = ref => { if (!ref) return; this.validations.push(ref.validate);