migrate object and list widgets
This commit is contained in:
33
packages/netlify-cms-widget-object/package.json
Normal file
33
packages/netlify-cms-widget-object/package.json
Normal 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"
|
||||
}
|
||||
}
|
125
packages/netlify-cms-widget-object/src/ObjectControl.js
Normal file
125
packages/netlify-cms-widget-object/src/ObjectControl.js
Normal 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>;
|
||||
}
|
||||
}
|
13
packages/netlify-cms-widget-object/src/ObjectPreview.js
Normal file
13
packages/netlify-cms-widget-object/src/ObjectPreview.js
Normal 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;
|
2
packages/netlify-cms-widget-object/src/index.js
Normal file
2
packages/netlify-cms-widget-object/src/index.js
Normal file
@ -0,0 +1,2 @@
|
||||
export ObjectControl from './ObjectControl';
|
||||
export ObjectPreview from './ObjectPreview';
|
3
packages/netlify-cms-widget-object/webpack.config.js
Normal file
3
packages/netlify-cms-widget-object/webpack.config.js
Normal file
@ -0,0 +1,3 @@
|
||||
const { getConfig } = require('../../scripts/webpack.js');
|
||||
|
||||
module.exports = getConfig();
|
Reference in New Issue
Block a user