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;
+ }
+}