diff --git a/example/index.html b/example/index.html index 86e3541c..ffd26667 100644 --- a/example/index.html +++ b/example/index.html @@ -33,7 +33,7 @@ content: '{"site_title": "CMS Demo"}' }, "authors.yml": { - content: 'authors:\n - name: Mathias\n description: Co-founder @ Netlify\n' + content: 'authors:\n - name: Mathias\n description: Co-founder @ Netlify\n - name: Chris\n description: Co-founder @ Netlify\n' } } } diff --git a/package.json b/package.json index 9f123f68..4da9aac2 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,6 @@ "@kadira/storybook": "^1.36.0", "autoprefixer": "^6.3.3", "bricks.js": "^1.7.0", - "textarea-caret-position": "^0.1.1", "dateformat": "^1.0.12", "fuzzy": "^0.1.1", "immutability-helper": "^2.0.0", @@ -120,6 +119,7 @@ "react-router": "^2.5.1", "react-router-redux": "^4.0.5", "react-simple-dnd": "^0.1.2", + "react-sortable": "^1.2.0", "react-toolbox": "^1.2.1", "react-topbar-progress-indicator": "^1.0.0", "react-waypoint": "^3.1.3", @@ -131,6 +131,7 @@ "semaphore": "^1.0.5", "slate": "^0.14.14", "slate-drop-or-paste-images": "^0.2.0", + "textarea-caret-position": "^0.1.1", "uuid": "^2.0.3", "whatwg-fetch": "^1.0.0" }, diff --git a/src/components/Widgets/ListControl.css b/src/components/Widgets/ListControl.css index fedcd1dc..8fab091e 100644 --- a/src/components/Widgets/ListControl.css +++ b/src/components/Widgets/ListControl.css @@ -1,3 +1,7 @@ +:global(.list-item-dragging) { + opacity: 0.5; +} + .addButton { display: block; cursor: pointer; diff --git a/src/components/Widgets/ListControl.js b/src/components/Widgets/ListControl.js index 50a9ec35..62c634b5 100644 --- a/src/components/Widgets/ListControl.js +++ b/src/components/Widgets/ListControl.js @@ -1,17 +1,30 @@ import React, { Component, PropTypes } from 'react'; -import { List, Map } from 'immutable'; +import { List, Map, fromJS } from 'immutable'; +import { sortable } from 'react-sortable'; import ObjectControl from './ObjectControl'; import styles from './ListControl.css'; +function ListItem(props) { + return
{props.children}
; +} +ListItem.propTypes = { + className: PropTypes.string, + children: PropTypes.node, +}; +ListItem.displayName = 'list-item'; + +const SortableListItem = sortable(ListItem); + export default class ListControl extends Component { static propTypes = { onChange: PropTypes.func.isRequired, value: PropTypes.node, + field: PropTypes.node, }; constructor(props) { super(props); - this.state = {itemStates: Map()}; + this.state = { itemStates: Map() }; } handleChange = (e) => { @@ -55,36 +68,52 @@ export default class ListControl extends Component { const fields = field.get('fields'); const first = fields.first(); const value = item.get(first.get('name')); - return value || `No ${first.get('name')}`; + return value || `No ${ first.get('name') }`; } + handleSort = (obj) => { + this.setState({ draggingIndex: obj.draggingIndex }); + if ('items' in obj) { + this.props.onChange(fromJS(obj.items)); + } + }; + renderItem(item, index) { - const { field, getMedia, onAddMedia, onRemoveMedia } = this.props; - const { itemStates } = this.state; + const { value, field, getMedia, onAddMedia, onRemoveMedia } = this.props; + const { itemStates, draggedItem } = this.state; const collapsed = itemStates.getIn([index, 'collapsed']); const classNames = [styles.item, collapsed ? styles.collapsed : styles.expanded]; - return (
-
{this.objectLabel(item)}
-
- + return ( +
+
{this.objectLabel(item)}
+
+ +
+ +
- - -
); + ); } renderListControl() { - const { value } = this.props; + const { value, field } = this.props; return (
{value && value.map((item, index) => this.renderItem(item, index))}
@@ -93,7 +122,6 @@ export default class ListControl extends Component { render() { const { value, field } = this.props; - console.log('field: %o', field.toJS()); if (field.get('fields')) { return this.renderListControl(); diff --git a/src/components/Widgets/ListPreview.js b/src/components/Widgets/ListPreview.js index 1b68a1ec..ed9542ca 100644 --- a/src/components/Widgets/ListPreview.js +++ b/src/components/Widgets/ListPreview.js @@ -1,11 +1,33 @@ -import React, { PropTypes } from 'react'; +import React, { PropTypes, Component } from 'react'; +import { resolveWidget } from '../Widgets'; -export default function ListPreview({ value }) { - return (); +export default class ObjectPreview extends Component { + widgetFor = (field, value) => { + const { getMedia } = this.props; + const widget = resolveWidget(field.get('widget')); + return (
{React.createElement(widget.preview, { + key: field.get('name'), + value: value && value.get(field.get('name')), + field, + getMedia, + })}
); + }; + + render() { + const { field, value } = this.props; + const fields = field && field.get('fields'); + if (fields) { + return value ? (
{value.map((val, index) =>
+ {fields && fields.map(f => this.widgetFor(f, val))} +
)}
) : null; + } + + return value ? value.join(', ') : null; + } } -ListPreview.propTypes = { +ObjectPreview.propTypes = { value: PropTypes.node, + field: PropTypes.node, + getMedia: PropTypes.func.isRequired, }; diff --git a/src/components/Widgets/ObjectControl.js b/src/components/Widgets/ObjectControl.js index 953fc913..4c7ed706 100644 --- a/src/components/Widgets/ObjectControl.js +++ b/src/components/Widgets/ObjectControl.js @@ -18,7 +18,7 @@ export default class ObjectControl extends Component { const widget = resolveWidget(field.get('widget') || 'string'); const fieldValue = value && value.get(field.get('name')); - return (
+ return (
{ diff --git a/src/formats/formats.js b/src/formats/formats.js index 2b7d9648..48fa5367 100644 --- a/src/formats/formats.js +++ b/src/formats/formats.js @@ -33,7 +33,6 @@ export function resolveFormat(collectionOrEntity, entry) { if (typeof collectionOrEntity === 'string') { return formatByType(collectionOrEntity); } - console.log('entry: %o', entry); const path = entry && entry.path; if (path) { return formatByExtension(path.split('.').pop());