From b9d3886b509aa9c896ce2e7970174ebdf8b6f0fe Mon Sep 17 00:00:00 2001 From: Lukas Martinelli Date: Sat, 17 Dec 2016 19:58:30 +0100 Subject: [PATCH] Drag and drop layer order --- package.json | 1 + src/app.jsx | 4 +-- src/layers/list.jsx | 61 +++++++++++++++++++++++++++++++---------- src/layers/listitem.jsx | 45 +++++++++++++++++------------- 4 files changed, 76 insertions(+), 35 deletions(-) diff --git a/package.json b/package.json index 951c8fe..8a63ace 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "react-height": "^2.1.1", "react-icons": "^2.2.1", "react-motion": "^0.4.4", + "react-sortable-hoc": "^0.4.5", "rebass": "^0.3.1", "request": "^2.79.0" }, diff --git a/src/app.jsx b/src/app.jsx index b56d3d7..f0e9067 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -86,8 +86,8 @@ export default class App extends React.Component { } onLayersChanged(changedLayers) { - const changedStyle = this.props.mapStyle.set('layers', changedLayers) - this.props.onStyleChanged(changedStyle) + const changedStyle = this.state.mapStyle.set('layers', changedLayers) + this.onStyleChanged(changedStyle) } mapRenderer() { diff --git a/src/layers/list.jsx b/src/layers/list.jsx index b548a48..12b6663 100644 --- a/src/layers/list.jsx +++ b/src/layers/list.jsx @@ -12,14 +12,18 @@ import scrollbars from '../scrollbars.scss' import PureRenderMixin from 'react-addons-pure-render-mixin'; import theme from '../theme.js' -// List of collapsible layer editors -export class LayerList extends React.Component { - static propTypes = { - layers: React.PropTypes.instanceOf(Immutable.OrderedMap), - onLayersChanged: React.PropTypes.func.isRequired, - onLayerSelected: React.PropTypes.func, - } +import {SortableContainer, SortableHandle, arrayMove} from 'react-sortable-hoc'; +const layerListPropTypes = { + layers: React.PropTypes.instanceOf(Immutable.OrderedMap), + onLayersChanged: React.PropTypes.func.isRequired, + onLayerSelected: React.PropTypes.func, +} + +// List of collapsible layer editors +@SortableContainer +class LayerListContainer extends React.Component { + static propTypes = {...layerListPropTypes} static defaultProps = { onLayerSelected: () => {}, } @@ -40,26 +44,55 @@ export class LayerList extends React.Component { } render() { - const layerPanels = this.props.layers.map(layer => { + const layerPanels = this.props.layers.toIndexedSeq().map((layer, index) => { const layerId = layer.get('id') return - }).toIndexedSeq() - - return
-
{layerPanels} -
-
+ + } +} + +export class LayerList extends React.Component { + static propTypes = {...layerListPropTypes} + + constructor(props) { + super(props) + this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this); + } + + onSortEnd(move) { + const { oldIndex, newIndex } = move + if(oldIndex === newIndex) return + + //TODO: Implement this more performant for immutable collections + // instead of converting back and forth + let layers = this.props.layers.toArray() + layers = arrayMove(layers, oldIndex, newIndex) + layers = Immutable.OrderedMap(layers.map(l => [l.get('id'), l])) + + this.props.onLayersChanged(layers) + } + + render() { + return } } diff --git a/src/layers/listitem.jsx b/src/layers/listitem.jsx index 61366ea..c4ee3d6 100644 --- a/src/layers/listitem.jsx +++ b/src/layers/listitem.jsx @@ -12,11 +12,16 @@ import { LayerEditor } from './editor.jsx' import scrollbars from '../scrollbars.scss' import PureRenderMixin from 'react-addons-pure-render-mixin'; import theme from '../theme.js' +import {SortableElement, SortableHandle} from 'react-sortable-hoc'; +import MdDragHandle from 'react-icons/lib/md/drag-handle' +const DragHandle = SortableHandle(() => ); + +@SortableElement @Radium class LayerListItem extends React.Component { static propTypes = { - layerId: React.PropTypes.number.isRequired, + layerId: React.PropTypes.string.isRequired, onLayerSelected: React.PropTypes.func.isRequired, } @@ -26,30 +31,32 @@ class LayerListItem extends React.Component { } render() { - return
this.props.onLayerSelected(this.props.layerId)} + style={{ + fontWeight: 400, + color: theme.colors.lowgray, + fontSize: theme.fontSizes[5], borderBottom: 1, borderLeft: 2, borderRight: 0, borderStyle: "solid", + userSelect: 'none', + listStyle: 'none', + zIndex: 2000, + cursor: 'pointer', + position: 'relative', + padding: theme.scale[1], borderColor: color(theme.colors.gray).lighten(0.1).hexString(), + backgroundColor: theme.colors.gray, + ":hover": { + backgroundColor: color(theme.colors.gray).lighten(0.15).hexString(), + } }}> -
this.props.onLayerSelected(this.props.layerId)} - style={{ - backgroundColor: theme.colors.gray, - ":hover": { - backgroundColor: color(theme.colors.gray).lighten(0.15).hexString(), - } - }} - > - - #{this.props.layerId} - -
-
+ + #{this.props.layerId} + } }