migrate object and list widgets

This commit is contained in:
Shawn Erquhart
2018-07-24 17:13:48 -04:00
parent 2efd09ba94
commit 3f47fe6dbf
29 changed files with 289 additions and 422 deletions

View File

@ -0,0 +1,33 @@
{
"name": "netlify-cms-widget-object",
"description": "Widget for displaying an object of fields for Netlify CMS.",
"version": "2.0.0-alpha.0",
"main": "dist/netlify-cms-widget-object.js",
"license": "MIT",
"keywords": [
"netlify",
"netlify-cms",
"widget",
"fields",
"object",
"nested"
],
"sideEffects": false,
"scripts": {
"watch": "webpack -w",
"build": "webpack"
},
"devDependencies": {
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0"
},
"peerDependencies": {
"immutable": "^3.7.6",
"lodash": "^4.17.10",
"netlify-cms-ui-default": "^2.0.0-alpha.0",
"prop-types": "^15.5.10",
"react": "^16.4.1",
"react-emotion": "^9.2.6",
"react-immutable-proptypes": "^2.1.0"
}
}

View File

@ -0,0 +1,125 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import styled, { css, cx } from 'react-emotion';
import { Map } from 'immutable';
import { partial } from 'lodash';
import { ObjectWidgetTopBar, Icon, colors, components } from 'netlify-cms-ui-default';
const styles = {
nestedObjectControl: css`
padding: 6px 14px 14px;
border-top: 0;
border-top-left-radius: 0;
border-top-right-radius: 0;
`,
};
export default class ObjectControl extends Component {
static propTypes = {
onChangeObject: PropTypes.func.isRequired,
onOpenMediaLibrary: PropTypes.func.isRequired,
mediaPaths: ImmutablePropTypes.map.isRequired,
onAddAsset: PropTypes.func.isRequired,
onRemoveInsertedMedia: PropTypes.func.isRequired,
getAsset: PropTypes.func.isRequired,
value: PropTypes.oneOfType([
PropTypes.node,
PropTypes.object,
PropTypes.bool,
]),
field: PropTypes.object,
forID: PropTypes.string,
classNameWrapper: PropTypes.string.isRequired,
forList: PropTypes.bool,
editorControl: PropTypes.func.isRequired,
resolveWidget: PropTypes.func.isRequired,
};
static defaultProps = {
value: Map(),
};
constructor(props) {
super(props);
this.state = {
collapsed: false,
};
}
/*
* 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;
}
controlFor(field, key) {
const {
onAddAsset,
onOpenMediaLibrary,
mediaPaths,
onRemoveInsertedMedia,
getAsset,
value,
onChangeObject,
editorControl: EditorControl,
resolveWidget,
} = this.props;
if (field.get('widget') === 'hidden') {
return null;
}
const widgetName = field.get('widget') || 'string';
const widget = resolveWidget(widgetName);
const fieldName = field.get('name');
const fieldValue = value && Map.isMap(value) ? value.get(fieldName) : value;
return (
<EditorControl
key={key}
field={field}
value={fieldValue}
mediaPaths={mediaPaths}
getAsset={getAsset}
onChange={onChangeObject}
onOpenMediaLibrary={onOpenMediaLibrary}
onAddAsset={onAddAsset}
onRemoveInsertedMedia={onRemoveInsertedMedia}
/>
);
}
handleCollapseToggle = () => {
this.setState({ collapsed: !this.state.collapsed });
}
render() {
const { field, forID, classNameWrapper, forList } = this.props;
const { collapsed } = this.state;
const multiFields = field.get('fields');
const singleField = field.get('field');
if (multiFields) {
return (
<div id={forID} className={cx(
classNameWrapper,
components.objectWidgetTopBarContainer,
{ [styles.nestedObjectControl]: forList },
)}>
{forList ? null :
<ObjectWidgetTopBar collapsed={collapsed} onCollapseToggle={this.handleCollapseToggle} />
}
{collapsed ? null : multiFields.map((f, idx) => this.controlFor(f, idx))}
</div>
);
} else if (singleField) {
return this.controlFor(singleField);
}
return <h3>No field(s) defined for this widget</h3>;
}
}

View File

@ -0,0 +1,13 @@
import React from 'react';
import PropTypes from 'prop-types';
import { WidgetPreviewContainer } from 'netlify-cms-ui-default';
const ObjectPreview = ({ field }) => (
<WidgetPreviewContainer>{(field && field.get('fields')) || null}</WidgetPreviewContainer>
);
ObjectPreview.propTypes = {
field: PropTypes.node,
};
export default ObjectPreview;

View File

@ -0,0 +1,2 @@
export ObjectControl from './ObjectControl';
export ObjectPreview from './ObjectPreview';

View File

@ -0,0 +1,3 @@
const { getConfig } = require('../../scripts/webpack.js');
module.exports = getConfig();