From 40235fe473d3056620b79c31c392fd2634cd9694 Mon Sep 17 00:00:00 2001 From: orangemug Date: Wed, 8 Nov 2017 13:45:34 +0000 Subject: [PATCH 1/4] Initial work to reorder zoom fields. --- src/components/fields/FunctionSpecField.jsx | 79 +++++++++++++++++++-- src/libs/document-uid.js | 9 +++ src/libs/sort-numerically.js | 14 ++++ 3 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 src/libs/document-uid.js create mode 100644 src/libs/sort-numerically.js diff --git a/src/components/fields/FunctionSpecField.jsx b/src/components/fields/FunctionSpecField.jsx index 36c1e41..d074c89 100644 --- a/src/components/fields/FunctionSpecField.jsx +++ b/src/components/fields/FunctionSpecField.jsx @@ -17,6 +17,9 @@ import MdInsertChart from 'react-icons/lib/md/insert-chart' import PropTypes from 'prop-types' import capitalize from 'lodash.capitalize' +import docUid from '../../libs/document-uid' +import sortNumerically from '../../libs/sort-numerically' + function isZoomField(value) { return typeof value === 'object' && value.stops && typeof value.property === 'undefined' } @@ -43,6 +46,70 @@ export default class FunctionSpecProperty extends React.Component { ]), } + constructor() { + super() + this.state = { + refs: {} + } + } + + /** + * We cache a reference for each stop by its index. + * + * When the stops are reordered the references are also updated (see this.orderStops) this allows React to use the same key for the element and keep keyboard focus. + */ + setStopRefs(props) { + // This is initialsed below only if required to improved performance. + let newRefs; + + if(props.value && props.value.stops) { + props.value.stops.forEach((val, idx) => { + if(!this.state.refs.hasOwnProperty(idx)) { + if(!newRefs) { + newRefs = {...this.state.refs}; + } + newRefs[idx] = docUid("stop-"); + } + }) + } + + if(newRefs) { + this.setState({ + refs: newRefs + }) + } + } + + componentWillReceiveProps(nextProps) { + this.setStopRefs(nextProps); + } + + // Order the stops altering the refs to reflect their new position. + orderStopsByZoom(stops) { + const mappedWithRef = stops + .map((stop, idx) => { + return { + ref: this.state.refs[idx], + data: stop + } + }) + // Sort by zoom + .sort((a, b) => sortNumerically(a.data[0], b.data[0])); + + // Fetch the new position of the stops + const newRefs = {}; + mappedWithRef + .forEach((stop, idx) =>{ + newRefs[idx] = stop.ref; + }) + + this.setState({ + refs: newRefs + }); + + return mappedWithRef.map((item) => item.data); + } + addStop() { const stops = this.props.value.stops.slice(0) const lastStop = stops[stops.length - 1] @@ -122,11 +189,14 @@ export default class FunctionSpecProperty extends React.Component { } changeStop(changeIdx, stopData, value) { - const stops = this.props.value.stops.slice(0) - stops[changeIdx] = [stopData, value] + const stops = this.props.value.stops.slice(0); + stops[changeIdx] = [stopData, value]; + + const orderedStops = this.orderStopsByZoom(stops); + const changedValue = { ...this.props.value, - stops: stops, + stops: orderedStops } this.props.onChange(this.props.fieldName, changedValue) } @@ -241,11 +311,12 @@ export default class FunctionSpecProperty extends React.Component { renderZoomProperty() { const zoomFields = this.props.value.stops.map((stop, idx) => { const zoomLevel = stop[0] + const key = this.state.refs[idx]; const value = stop[1] const deleteStopBtn= return b) { + return 1 + } + else { + return 0; + } +} From 030d469d7c182fdd7503671dbe01fa698521b66f Mon Sep 17 00:00:00 2001 From: orangemug Date: Fri, 17 Nov 2017 17:17:53 +0000 Subject: [PATCH 2/4] Broke into smaller parts. --- src/components/fields/FunctionSpecField.jsx | 385 ++----------------- src/components/fields/_DataProperty.jsx | 171 ++++++++ src/components/fields/_DeleteStopButton.jsx | 25 ++ src/components/fields/_FunctionButtons.jsx | 49 +++ src/components/fields/_SpecProperty.jsx | 32 ++ src/components/fields/_ZoomProperty.jsx | 149 +++++++ src/components/fields/_labelFromFieldName.js | 6 + src/components/inputs/InputBlock.jsx | 2 +- 8 files changed, 470 insertions(+), 349 deletions(-) create mode 100644 src/components/fields/_DataProperty.jsx create mode 100644 src/components/fields/_DeleteStopButton.jsx create mode 100644 src/components/fields/_FunctionButtons.jsx create mode 100644 src/components/fields/_SpecProperty.jsx create mode 100644 src/components/fields/_ZoomProperty.jsx create mode 100644 src/components/fields/_labelFromFieldName.js diff --git a/src/components/fields/FunctionSpecField.jsx b/src/components/fields/FunctionSpecField.jsx index d074c89..9772a33 100644 --- a/src/components/fields/FunctionSpecField.jsx +++ b/src/components/fields/FunctionSpecField.jsx @@ -1,24 +1,10 @@ import React from 'react' -import Color from 'color' - -import Button from '../Button' -import SpecField from './SpecField' -import NumberInput from '../inputs/NumberInput' -import StringInput from '../inputs/StringInput' -import SelectInput from '../inputs/SelectInput' -import DocLabel from './DocLabel' -import InputBlock from '../inputs/InputBlock' - -import AddIcon from 'react-icons/lib/md/add-circle-outline' -import DeleteIcon from 'react-icons/lib/md/delete' -import FunctionIcon from 'react-icons/lib/md/functions' -import MdInsertChart from 'react-icons/lib/md/insert-chart' - import PropTypes from 'prop-types' -import capitalize from 'lodash.capitalize' -import docUid from '../../libs/document-uid' -import sortNumerically from '../../libs/sort-numerically' +import SpecProperty from './_SpecProperty' +import DataProperty from './_DataProperty' +import ZoomProperty from './_ZoomProperty' + function isZoomField(value) { return typeof value === 'object' && value.stops && typeof value.property === 'undefined' @@ -46,70 +32,6 @@ export default class FunctionSpecProperty extends React.Component { ]), } - constructor() { - super() - this.state = { - refs: {} - } - } - - /** - * We cache a reference for each stop by its index. - * - * When the stops are reordered the references are also updated (see this.orderStops) this allows React to use the same key for the element and keep keyboard focus. - */ - setStopRefs(props) { - // This is initialsed below only if required to improved performance. - let newRefs; - - if(props.value && props.value.stops) { - props.value.stops.forEach((val, idx) => { - if(!this.state.refs.hasOwnProperty(idx)) { - if(!newRefs) { - newRefs = {...this.state.refs}; - } - newRefs[idx] = docUid("stop-"); - } - }) - } - - if(newRefs) { - this.setState({ - refs: newRefs - }) - } - } - - componentWillReceiveProps(nextProps) { - this.setStopRefs(nextProps); - } - - // Order the stops altering the refs to reflect their new position. - orderStopsByZoom(stops) { - const mappedWithRef = stops - .map((stop, idx) => { - return { - ref: this.state.refs[idx], - data: stop - } - }) - // Sort by zoom - .sort((a, b) => sortNumerically(a.data[0], b.data[0])); - - // Fetch the new position of the stops - const newRefs = {}; - mappedWithRef - .forEach((stop, idx) =>{ - newRefs[idx] = stop.ref; - }) - - this.setState({ - refs: newRefs - }); - - return mappedWithRef.map((item) => item.data); - } - addStop() { const stops = this.props.value.stops.slice(0) const lastStop = stops[stops.length - 1] @@ -157,25 +79,6 @@ export default class FunctionSpecProperty extends React.Component { this.props.onChange(this.props.fieldName, zoomFunc) } - getFieldFunctionType(fieldSpec) { - if (fieldSpec.function === "interpolated") { - return "exponential" - } - if (fieldSpec.type === "number") { - return "interval" - } - return "categorical" - } - - getDataFunctionTypes(functionType) { - if (functionType === "interpolated") { - return ["categorical", "interval", "exponential"] - } - else { - return ["categorical", "interval"] - } - } - makeDataFunction() { const dataFunc = { property: "", @@ -188,264 +91,50 @@ export default class FunctionSpecProperty extends React.Component { this.props.onChange(this.props.fieldName, dataFunc) } - changeStop(changeIdx, stopData, value) { - const stops = this.props.value.stops.slice(0); - stops[changeIdx] = [stopData, value]; - - const orderedStops = this.orderStopsByZoom(stops); - - const changedValue = { - ...this.props.value, - stops: orderedStops - } - this.props.onChange(this.props.fieldName, changedValue) - } - - changeDataProperty(propName, propVal) { - if (propVal) { - this.props.value[propName] = propVal - } - else { - delete this.props.value[propName] - } - this.props.onChange(this.props.fieldName, this.props.value) - } - - renderDataProperty() { - if (typeof this.props.value.type === "undefined") { - this.props.value.type = this.getFieldFunctionType(this.props.fieldSpec) - } - const dataFields = this.props.value.stops.map((stop, idx) => { - const zoomLevel = stop[0].zoom - const dataLevel = stop[0].value - const value = stop[1] - const deleteStopBtn = - - const dataProps = { - label: "Data value", - value: dataLevel, - onChange: newData => this.changeStop(idx, { zoom: zoomLevel, value: newData }, value) - } - const dataInput = this.props.value.type === "categorical" ? : - - return -
- this.changeStop(idx, {zoom: newZoom, value: dataLevel}, value)} - min={0} - max={22} - /> -
-
- {dataInput} -
-
- this.changeStop(idx, {zoom: zoomLevel, value: dataLevel}, newValue)} - /> -
-
- }) - - return
-
- -
- -
- this.changeDataProperty("property", propVal)} - /> -
-
-
- -
- this.changeDataProperty("type", propVal)} - options={this.getDataFunctionTypes(this.props.fieldSpec.function)} - /> -
-
-
- -
- this.changeDataProperty("default", propVal)} - /> -
-
-
-
- {dataFields} - -
- } - - renderZoomProperty() { - const zoomFields = this.props.value.stops.map((stop, idx) => { - const zoomLevel = stop[0] - const key = this.state.refs[idx]; - const value = stop[1] - const deleteStopBtn= - - return -
-
- this.changeStop(idx, changedStop, value)} - min={0} - max={22} - /> -
-
- this.changeStop(idx, zoomLevel, newValue)} - /> -
-
-
- }) - - return
- {zoomFields} - -
- } - - renderProperty() { - const functionBtn = - return - - - } - render() { const propClass = this.props.fieldSpec.default === this.props.value ? "maputnik-default-property" : "maputnik-modified-property" - let specField + let specField; + if (isZoomField(this.props.value)) { - specField = this.renderZoomProperty() + specField = ( + + ) } else if (isDataField(this.props.value)) { - specField = this.renderDataProperty() + specField = ( + + ) } else { - specField = this.renderProperty() + specField = ( + + ) } + return
{specField}
} } -class MakeFunctionButtons extends React.Component { - static propTypes = { - fieldSpec: PropTypes.object, - onZoomClick: PropTypes.func, - onDataClick: PropTypes.func, - } - - render() { - let makeZoomButton, makeDataButton - if (this.props.fieldSpec['zoom-function']) { - makeZoomButton = - - if (this.props.fieldSpec['property-function'] && ['piecewise-constant', 'interpolated'].indexOf(this.props.fieldSpec['function']) !== -1) { - makeDataButton = - } - return
{makeDataButton}{makeZoomButton}
- } - else { - return null - } - } -} - -class DeleteStopButton extends React.Component { - static propTypes = { - onClick: PropTypes.func, - } - - render() { - return - } -} - -function labelFromFieldName(fieldName) { - let label = fieldName.split('-').slice(1).join(' ') - return capitalize(label) -} diff --git a/src/components/fields/_DataProperty.jsx b/src/components/fields/_DataProperty.jsx new file mode 100644 index 0000000..c13d828 --- /dev/null +++ b/src/components/fields/_DataProperty.jsx @@ -0,0 +1,171 @@ +import React from 'react' +import PropTypes from 'prop-types' + +import Button from '../Button' +import SpecField from './SpecField' +import NumberInput from '../inputs/NumberInput' +import StringInput from '../inputs/StringInput' +import SelectInput from '../inputs/SelectInput' +import DocLabel from './DocLabel' +import InputBlock from '../inputs/InputBlock' + +import labelFromFieldName from './_labelFromFieldName' +import DeleteStopButton from './_DeleteStopButton' + + +export default class DataProperty extends React.Component { + static propTypes = { + value: PropTypes.oneOfType([ + PropTypes.object, + PropTypes.string, + PropTypes.number, + PropTypes.bool, + PropTypes.array + ]), + } + + getFieldFunctionType(fieldSpec) { + if (fieldSpec.function === "interpolated") { + return "exponential" + } + if (fieldSpec.type === "number") { + return "interval" + } + return "categorical" + } + + getDataFunctionTypes(functionType) { + if (functionType === "interpolated") { + return ["categorical", "interval", "exponential"] + } + else { + return ["categorical", "interval"] + } + } + + + changeStop(changeIdx, stopData, value) { + const stops = this.props.value.stops.slice(0) + stops[changeIdx] = [stopData, value] + const changedValue = { + ...this.props.value, + stops: stops, + } + this.props.onChange(this.props.fieldName, changedValue) + } + + changeDataProperty(propName, propVal) { + if (propVal) { + this.props.value[propName] = propVal + } + else { + delete this.props.value[propName] + } + this.props.onChange(this.props.fieldName, this.props.value) + } + + render() { + if (typeof this.props.value.type === "undefined") { + this.props.value.type = this.getFieldFunctionType(this.props.fieldSpec) + } + + const dataFields = this.props.value.stops.map((stop, idx) => { + const zoomLevel = stop[0].zoom + const dataLevel = stop[0].value + const value = stop[1] + const deleteStopBtn = + + const dataProps = { + label: "Data value", + value: dataLevel, + onChange: newData => this.changeStop(idx, { zoom: zoomLevel, value: newData }, value) + } + + let dataInput; + if(this.props.value.type === "categorical") { + dataInput = + } + else { + dataInput = + } + + return +
+ this.changeStop(idx, {zoom: newZoom, value: dataLevel}, value)} + min={0} + max={22} + /> +
+
+ {dataInput} +
+
+ this.changeStop(idx, {zoom: zoomLevel, value: dataLevel}, newValue)} + /> +
+
+ }) + + return
+
+ +
+ +
+ this.changeDataProperty("property", propVal)} + /> +
+
+
+ +
+ this.changeDataProperty("type", propVal)} + options={this.getDataFunctionTypes(this.props.fieldSpec.function)} + /> +
+
+
+ +
+ this.changeDataProperty("default", propVal)} + /> +
+
+
+
+ {dataFields} + +
+ } +} diff --git a/src/components/fields/_DeleteStopButton.jsx b/src/components/fields/_DeleteStopButton.jsx new file mode 100644 index 0000000..ef64f43 --- /dev/null +++ b/src/components/fields/_DeleteStopButton.jsx @@ -0,0 +1,25 @@ +import React from 'react' +import PropTypes from 'prop-types' + +import DocLabel from './DocLabel' +import Button from '../Button' +import DeleteIcon from 'react-icons/lib/md/delete' + + +export default class DeleteStopButton extends React.Component { + static propTypes = { + onClick: PropTypes.func, + } + + render() { + return + } +} diff --git a/src/components/fields/_FunctionButtons.jsx b/src/components/fields/_FunctionButtons.jsx new file mode 100644 index 0000000..9e66398 --- /dev/null +++ b/src/components/fields/_FunctionButtons.jsx @@ -0,0 +1,49 @@ +import React from 'react' +import PropTypes from 'prop-types' + +import DocLabel from './DocLabel' +import Button from '../Button' +import FunctionIcon from 'react-icons/lib/md/functions' +import MdInsertChart from 'react-icons/lib/md/insert-chart' + + +export default class FunctionButtons extends React.Component { + static propTypes = { + fieldSpec: PropTypes.object, + onZoomClick: PropTypes.func, + onDataClick: PropTypes.func, + } + + render() { + let makeZoomButton, makeDataButton + if (this.props.fieldSpec['zoom-function']) { + makeZoomButton = + + if (this.props.fieldSpec['property-function'] && ['piecewise-constant', 'interpolated'].indexOf(this.props.fieldSpec['function']) !== -1) { + makeDataButton = + } + return
{makeDataButton}{makeZoomButton}
+ } + else { + return null + } + } +} diff --git a/src/components/fields/_SpecProperty.jsx b/src/components/fields/_SpecProperty.jsx new file mode 100644 index 0000000..583bffa --- /dev/null +++ b/src/components/fields/_SpecProperty.jsx @@ -0,0 +1,32 @@ +import React from 'react' +import PropTypes from 'prop-types' + +import SpecField from './SpecField' +import FunctionButtons from './_FunctionButtons' +import InputBlock from '../inputs/InputBlock' + +import labelFromFieldName from './_labelFromFieldName' + + +export default class SpecProperty extends React.Component { + static propTypes = { + onZoomClick: PropTypes.func.isRequired, + onDataClick: PropTypes.func.isRequired + } + + render() { + const functionBtn = + + return + + + } +} diff --git a/src/components/fields/_ZoomProperty.jsx b/src/components/fields/_ZoomProperty.jsx new file mode 100644 index 0000000..e670af3 --- /dev/null +++ b/src/components/fields/_ZoomProperty.jsx @@ -0,0 +1,149 @@ +import React from 'react' +import PropTypes from 'prop-types' + +import Button from '../Button' +import SpecField from './SpecField' +import NumberInput from '../inputs/NumberInput' +import InputBlock from '../inputs/InputBlock' + +import DeleteStopButton from './_DeleteStopButton' +import labelFromFieldName from './_labelFromFieldName' + +import docUid from '../../libs/document-uid' +import sortNumerically from '../../libs/sort-numerically' + + +export default class ZoomProperty extends React.Component { + static propTypes = { + } + + + constructor() { + super() + this.state = { + refs: {} + } + } + + componentWillMount() { + this.setState({ + refs: this.setStopRefs(this.props) + }) + } + + /** + * We cache a reference for each stop by its index. + * + * When the stops are reordered the references are also updated (see this.orderStops) this allows React to use the same key for the element and keep keyboard focus. + */ + setStopRefs(props) { + // This is initialsed below only if required to improved performance. + let newRefs; + + if(props.value && props.value.stops) { + props.value.stops.forEach((val, idx) => { + if(!this.state.refs.hasOwnProperty(idx)) { + if(!newRefs) { + newRefs = {...this.state.refs}; + } + newRefs[idx] = docUid("stop-"); + } + }) + } + + return newRefs; + } + + componentWillReceiveProps(nextProps) { + const newRefs = this.setStopRefs(nextProps); + if(newRefs) { + this.setState({ + refs: newRefs + }) + } + } + + // Order the stops altering the refs to reflect their new position. + orderStopsByZoom(stops) { + const mappedWithRef = stops + .map((stop, idx) => { + return { + ref: this.state.refs[idx], + data: stop + } + }) + // Sort by zoom + .sort((a, b) => sortNumerically(a.data[0], b.data[0])); + + // Fetch the new position of the stops + const newRefs = {}; + mappedWithRef + .forEach((stop, idx) =>{ + newRefs[idx] = stop.ref; + }) + + this.setState({ + refs: newRefs + }); + + return mappedWithRef.map((item) => item.data); + } + + changeZoomStop(changeIdx, stopData, value) { + const stops = this.props.value.stops.slice(0); + stops[changeIdx] = [stopData, value]; + + const orderedStops = this.orderStopsByZoom(stops); + + const changedValue = { + ...this.props.value, + stops: orderedStops + } + this.props.onChange(this.props.fieldName, changedValue) + } + + render() { + const zoomFields = this.props.value.stops.map((stop, idx) => { + const zoomLevel = stop[0] + const key = this.state.refs[idx]; + const value = stop[1] + const deleteStopBtn= + + return +
+
+ this.changeZoomStop(idx, changedStop, value)} + min={0} + max={22} + /> +
+
+ this.changeZoomStop(idx, zoomLevel, newValue)} + /> +
+
+
+ }); + + return
+ {zoomFields} + +
+ } +} diff --git a/src/components/fields/_labelFromFieldName.js b/src/components/fields/_labelFromFieldName.js new file mode 100644 index 0000000..fea405f --- /dev/null +++ b/src/components/fields/_labelFromFieldName.js @@ -0,0 +1,6 @@ +import capitalize from 'lodash.capitalize' + +export default function labelFromFieldName(fieldName) { + let label = fieldName.split('-').slice(1).join(' ') + return capitalize(label) +} diff --git a/src/components/inputs/InputBlock.jsx b/src/components/inputs/InputBlock.jsx index 37c1d0a..8fff767 100644 --- a/src/components/inputs/InputBlock.jsx +++ b/src/components/inputs/InputBlock.jsx @@ -12,7 +12,7 @@ class InputBlock extends React.Component { ]).isRequired, doc: PropTypes.string, action: PropTypes.element, - children: PropTypes.element.isRequired, + children: PropTypes.node.isRequired, style: PropTypes.object, onChange: PropTypes.func, } From 3c97fbe5872475ab5f8b6c04f20b3fd29782bb95 Mon Sep 17 00:00:00 2001 From: orangemug Date: Fri, 17 Nov 2017 17:27:16 +0000 Subject: [PATCH 3/4] tabs -> spaces. --- src/components/fields/_ZoomProperty.jsx | 60 ++++++++++++------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/components/fields/_ZoomProperty.jsx b/src/components/fields/_ZoomProperty.jsx index e670af3..24af0f8 100644 --- a/src/components/fields/_ZoomProperty.jsx +++ b/src/components/fields/_ZoomProperty.jsx @@ -18,12 +18,12 @@ export default class ZoomProperty extends React.Component { } - constructor() { - super() - this.state = { - refs: {} - } - } + constructor() { + super() + this.state = { + refs: {} + } + } componentWillMount() { this.setState({ @@ -31,37 +31,37 @@ export default class ZoomProperty extends React.Component { }) } - /** - * We cache a reference for each stop by its index. + /** + * We cache a reference for each stop by its index. * * When the stops are reordered the references are also updated (see this.orderStops) this allows React to use the same key for the element and keep keyboard focus. - */ - setStopRefs(props) { - // This is initialsed below only if required to improved performance. - let newRefs; + */ + setStopRefs(props) { + // This is initialsed below only if required to improved performance. + let newRefs; - if(props.value && props.value.stops) { - props.value.stops.forEach((val, idx) => { - if(!this.state.refs.hasOwnProperty(idx)) { - if(!newRefs) { - newRefs = {...this.state.refs}; - } - newRefs[idx] = docUid("stop-"); - } - }) - } + if(props.value && props.value.stops) { + props.value.stops.forEach((val, idx) => { + if(!this.state.refs.hasOwnProperty(idx)) { + if(!newRefs) { + newRefs = {...this.state.refs}; + } + newRefs[idx] = docUid("stop-"); + } + }) + } return newRefs; - } + } - componentWillReceiveProps(nextProps) { - const newRefs = this.setStopRefs(nextProps); + componentWillReceiveProps(nextProps) { + const newRefs = this.setStopRefs(nextProps); if(newRefs) { - this.setState({ - refs: newRefs - }) + this.setState({ + refs: newRefs + }) } - } + } // Order the stops altering the refs to reflect their new position. orderStopsByZoom(stops) { @@ -72,7 +72,7 @@ export default class ZoomProperty extends React.Component { data: stop } }) - // Sort by zoom + // Sort by zoom .sort((a, b) => sortNumerically(a.data[0], b.data[0])); // Fetch the new position of the stops From 61808d5939f125d13fa85ad3a459c14faf99d78d Mon Sep 17 00:00:00 2001 From: orangemug Date: Wed, 29 Nov 2017 15:03:37 +0000 Subject: [PATCH 4/4] Fixed lint errors. --- src/components/fields/_DataProperty.jsx | 7 ++++++- src/components/fields/_SpecProperty.jsx | 4 +++- src/components/fields/_ZoomProperty.jsx | 12 ++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/components/fields/_DataProperty.jsx b/src/components/fields/_DataProperty.jsx index c13d828..a4aefa2 100644 --- a/src/components/fields/_DataProperty.jsx +++ b/src/components/fields/_DataProperty.jsx @@ -15,7 +15,12 @@ import DeleteStopButton from './_DeleteStopButton' export default class DataProperty extends React.Component { static propTypes = { - value: PropTypes.oneOfType([ + onChange: PropTypes.func, + onDeleteStop: PropTypes.func, + onAddStop: PropTypes.func, + fieldName: PropTypes.string, + fieldSpec: PropTypes.object, + value: PropTypes.oneOfType([ PropTypes.object, PropTypes.string, PropTypes.number, diff --git a/src/components/fields/_SpecProperty.jsx b/src/components/fields/_SpecProperty.jsx index 583bffa..0e0fd9f 100644 --- a/src/components/fields/_SpecProperty.jsx +++ b/src/components/fields/_SpecProperty.jsx @@ -11,7 +11,9 @@ import labelFromFieldName from './_labelFromFieldName' export default class SpecProperty extends React.Component { static propTypes = { onZoomClick: PropTypes.func.isRequired, - onDataClick: PropTypes.func.isRequired + onDataClick: PropTypes.func.isRequired, + fieldName: PropTypes.string, + fieldSpec: PropTypes.object } render() { diff --git a/src/components/fields/_ZoomProperty.jsx b/src/components/fields/_ZoomProperty.jsx index 24af0f8..5659b14 100644 --- a/src/components/fields/_ZoomProperty.jsx +++ b/src/components/fields/_ZoomProperty.jsx @@ -15,6 +15,18 @@ import sortNumerically from '../../libs/sort-numerically' export default class ZoomProperty extends React.Component { static propTypes = { + onChange: PropTypes.func, + onDeleteStop: PropTypes.func, + onAddStop: PropTypes.func, + fieldName: PropTypes.string, + fieldSpec: PropTypes.object, + value: PropTypes.oneOfType([ + PropTypes.object, + PropTypes.string, + PropTypes.number, + PropTypes.bool, + PropTypes.array + ]), }