Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spike Replacing CodeMirror with Draft-js #93

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ node_modules
/live
/demo/test.html
/build-docs
/build
.DS_Store
.tern-port
*~
Expand Down
166 changes: 166 additions & 0 deletions build/lib/components/fields/array.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
// # array component

/*
Render a field to edit array values.
*/

'use strict';

Object.defineProperty(exports, "__esModule", {
value: true
});

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _createReactClass = require('create-react-class');

var _createReactClass2 = _interopRequireDefault(_createReactClass);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _field = require('../../mixins/field');

var _field2 = _interopRequireDefault(_field);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

exports.default = (0, _createReactClass2.default)({

displayName: 'Array',

mixins: [_field2.default],

nextLookupId: 0,

getInitialState: function getInitialState() {

// Need to create artificial keys for the array. Indexes are not good keys,
// since they change. So, map each position to an artificial key
var lookups = [];

var items = this.props.field.value;

items.forEach(function (item, i) {
lookups[i] = '_' + this.nextLookupId;
this.nextLookupId++;
}.bind(this));

return {
lookups: lookups
};
},

componentWillReceiveProps: function componentWillReceiveProps(newProps) {

var lookups = this.state.lookups;

var items = newProps.field.value;

// Need to set artificial keys for new array items.
if (items.length > lookups.length) {
for (var i = lookups.length; i < items.length; i++) {
lookups[i] = '_' + this.nextLookupId;
this.nextLookupId++;
}
}

this.setState({
lookups: lookups
});
},

onChange: function onChange(i, newValue, info) {
var newArrayValue = this.props.field.value.slice(0);
newArrayValue[i] = newValue;
this.onBubbleValue(newArrayValue, info);
},

onAppend: function onAppend(itemChoiceIndex) {
var config = this.props.config;
var field = this.props.field;

var newValue = config.createNewChildFieldValue(field, itemChoiceIndex);

var items = field.value;

items = items.concat(newValue);

this.onChangeValue(items);
},

onRemove: function onRemove(i) {
var lookups = this.state.lookups;
lookups.splice(i, 1);
this.setState({
lookups: lookups
});
var newItems = this.props.field.value.slice(0);
newItems.splice(i, 1);
this.onChangeValue(newItems);
},

onMove: function onMove(fromIndex, toIndex) {
var lookups = this.state.lookups;
var fromId = lookups[fromIndex];
var toId = lookups[toIndex];
lookups[fromIndex] = toId;
lookups[toIndex] = fromId;
this.setState({
lookups: lookups
});

var newItems = this.props.field.value.slice(0);
if (fromIndex !== toIndex && fromIndex >= 0 && fromIndex < newItems.length && toIndex >= 0 && toIndex < newItems.length) {
newItems.splice(toIndex, 0, newItems.splice(fromIndex, 1)[0]);
}
this.onChangeValue(newItems);
},

render: function render() {
return this.renderWithConfig();
},

renderDefault: function renderDefault() {

var config = this.props.config;
var field = this.props.field;

var fields = config.createChildFields(field);

var arrayControl = void 0;
if (!config.fieldIsReadOnly(field)) {
arrayControl = config.createElement('array-control', { field: field, onAppend: this.onAppend });
}

var tabIndex = this.isReadOnly() ? null : this.props.tabIndex || 0;

var numItems = field.value.length;

var content = config.cssTransitionWrapper(fields.map(function (childField, i) {
return config.createElement('array-item', {
key: this.state.lookups[i],
field: childField,
index: i,
numItems: numItems,
onMove: this.onMove,
onRemove: this.onRemove,
onChange: this.onChange,
onAction: this.onBubbleAction
});
}.bind(this)));

return config.createElement('field', {
field: field,
plain: this.props.plain
}, _react2.default.createElement(
'div',
{ className: (0, _classnames2.default)(this.props.classes), tabIndex: tabIndex },
content,
arrayControl
));
}
});
170 changes: 170 additions & 0 deletions build/lib/components/fields/assoc-list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
// # object component

/*
Render a field to edit a array of key / value objects, where duplicate keys are allowed.
*/

'use strict';

Object.defineProperty(exports, "__esModule", {
value: true
});

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _createReactClass = require('create-react-class');

var _createReactClass2 = _interopRequireDefault(_createReactClass);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _immutabilityHelper = require('immutability-helper');

var _immutabilityHelper2 = _interopRequireDefault(_immutabilityHelper);

var _field = require('../../mixins/field');

var _field2 = _interopRequireDefault(_field);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var keyCountsByKey = function keyCountsByKey(assocList) {
var counts = {};
assocList.forEach(function (row) {
if (!counts[row.key]) {
counts[row.key] = 0;
}
counts[row.key] += 1;
});
return counts;
};

exports.default = (0, _createReactClass2.default)({

displayName: 'AssocList',

mixins: [_field2.default],

nextLookupId: 0,

getNextLookupId: function getNextLookupId() {
return '_' + this.nextLookupId++;
},
getInitialState: function getInitialState() {
var _this = this;

var field = this.props.field;

// maintain artificial keys, keyed by row index, to have persistent key
var lookups = [];
field.value.forEach(function (row, i) {
lookups[i] = _this.getNextLookupId();
});

return { lookups: lookups };
},
componentWillReceiveProps: function componentWillReceiveProps(newProps) {
var rows = newProps.field.value;

// set artificial keys for new rows
if (rows.length > this.state.lookups.length) {
var lookupsToPush = [];
for (var i = this.state.lookups.length; i < rows.length; i++) {
lookupsToPush.push(this.getNextLookupId());
}
var lookups = (0, _immutabilityHelper2.default)(this.state.lookups, {
$push: lookupsToPush
});
this.setState({ lookups: lookups });
}
},
onChange: function onChange(index, newValue) {
var field = this.props.field;

var updatedRow = { key: field.value[index].key, value: newValue };
var rows = (0, _immutabilityHelper2.default)(field.value, {
$splice: [[index, 1, updatedRow]]
});

// this.onBubbleValue(rows, info);
this.onChangeValue(rows);
},
onAppend: function onAppend() {
var field = this.props.field;

var newRow = { key: '', value: '' };
var rows = (0, _immutabilityHelper2.default)(field.value, {
$push: [newRow]
});

// componentWillReceiveProps will add the new artificial key to lookups
this.onChangeValue(rows);
},
onRemove: function onRemove(index) {
var field = this.props.field;

// componentWillReceiveProps can't know which item was deleted, so
// put new artificial key in lookups here
var lookups = (0, _immutabilityHelper2.default)(this.state.lookups, {
$splice: [[index, 1]]
});
this.setState({ lookups: lookups });

var rows = (0, _immutabilityHelper2.default)(field.value, {
$splice: [[index, 1]]
});
this.onChangeValue(rows);
},
onChangeKey: function onChangeKey(index, newKey) {
var field = this.props.field;

var updatedRow = { key: newKey, value: field.value[index].value };
var rows = (0, _immutabilityHelper2.default)(field.value, {
$splice: [[index, 1, updatedRow]]
});

this.onChangeValue(rows);
},
render: function render() {
return this.renderWithConfig();
},
renderDefault: function renderDefault() {
var config = this.props.config;
var field = this.props.field;
var fields = config.createChildFields(field);
var keyCounts = keyCountsByKey(field.value);

var content = config.cssTransitionWrapper(field.value.map(function (row, i) {
return config.createElement('assoc-list-item', {
key: this.state.lookups[i],
index: i,
displayKey: row.key,
field: fields[i],
isDuplicateKey: keyCounts[row.key] > 1,
onChangeKey: this.onChangeKey,
onChange: this.onChange,
onRemove: this.onRemove,
onAction: this.onBubbleAction
});
}.bind(this)));

var assocList = config.createElement('assoc-list-control', {
field: field,
onAppend: this.onAppend
});

return config.createElement('field', {
field: field,
plain: this.props.plain
}, _react2.default.createElement(
'div',
{ className: (0, _classnames2.default)(this.props.classes) },
content,
assocList
));
}
});
50 changes: 50 additions & 0 deletions build/lib/components/fields/boolean.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// # boolean component

/*
Render a dropdown to handle yes/no boolean values.
*/

'use strict';

Object.defineProperty(exports, "__esModule", {
value: true
});

var _createReactClass = require('create-react-class');

var _createReactClass2 = _interopRequireDefault(_createReactClass);

var _field = require('../../mixins/field');

var _field2 = _interopRequireDefault(_field);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

exports.default = (0, _createReactClass2.default)({

displayName: 'Boolean',

mixins: [_field2.default],

onChange: function onChange(newValue) {
this.onChangeValue(newValue);
},

render: function render() {
return this.renderWithConfig();
},

renderDefault: function renderDefault() {

var config = this.props.config;
var field = this.props.field;

var choices = config.fieldBooleanChoices(field);

return config.createElement('field', {
field: field, plain: this.props.plain
}, config.createElement('select-value', {
choices: choices, field: field, onChange: this.onChange, onAction: this.onBubbleAction
}));
}
});
Loading