Drag and drop layer order

This commit is contained in:
Lukas Martinelli 2016-12-17 19:58:30 +01:00
parent 7fae257130
commit b9d3886b50
4 changed files with 76 additions and 35 deletions

View file

@ -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"
},

View file

@ -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() {

View file

@ -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 <LayerListItem
index={index}
key={layerId}
layerId={layerId}
onLayerSelected={this.props.onLayerSelected}
/>
}).toIndexedSeq()
return <div>
<div className={scrollbars.darkScrollbar} style={{
})
return <ul className={scrollbars.darkScrollbar} style={{
overflowY: "scroll",
bottom:0,
left:0,
right:0,
top:1,
position: "absolute",
padding: theme.scale[2],
}}>
{layerPanels}
</div>
</div>
</ul>
}
}
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 <LayerListContainer
{...this.props}
onSortEnd={this.onSortEnd.bind(this)}
useDragHandle={true}
/>
}
}

View file

@ -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(() => <MdDragHandle />);
@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 <div key={this.props.layerId} style={{
return <li
key={this.props.layerId}
onClick={() => 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(),
}
}}>
<div
onClick={() => this.props.onLayerSelected(this.props.layerId)}
style={{
backgroundColor: theme.colors.gray,
":hover": {
backgroundColor: color(theme.colors.gray).lighten(0.15).hexString(),
}
}}
>
<NavItem style={{
fontWeight: 400,
color: theme.colors.lowgray,
}}>
#{this.props.layerId}
</NavItem>
</div>
</div>
<DragHandle />
<span>#{this.props.layerId}</span>
</li>
}
}