mirror of
https://github.com/a-nyx/maputnik-with-pmtiles.git
synced 2024-12-28 17:11:17 +01:00
Drag and drop layer order
This commit is contained in:
parent
7fae257130
commit
b9d3886b50
4 changed files with 76 additions and 35 deletions
|
@ -35,6 +35,7 @@
|
||||||
"react-height": "^2.1.1",
|
"react-height": "^2.1.1",
|
||||||
"react-icons": "^2.2.1",
|
"react-icons": "^2.2.1",
|
||||||
"react-motion": "^0.4.4",
|
"react-motion": "^0.4.4",
|
||||||
|
"react-sortable-hoc": "^0.4.5",
|
||||||
"rebass": "^0.3.1",
|
"rebass": "^0.3.1",
|
||||||
"request": "^2.79.0"
|
"request": "^2.79.0"
|
||||||
},
|
},
|
||||||
|
|
|
@ -86,8 +86,8 @@ export default class App extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
onLayersChanged(changedLayers) {
|
onLayersChanged(changedLayers) {
|
||||||
const changedStyle = this.props.mapStyle.set('layers', changedLayers)
|
const changedStyle = this.state.mapStyle.set('layers', changedLayers)
|
||||||
this.props.onStyleChanged(changedStyle)
|
this.onStyleChanged(changedStyle)
|
||||||
}
|
}
|
||||||
|
|
||||||
mapRenderer() {
|
mapRenderer() {
|
||||||
|
|
|
@ -12,14 +12,18 @@ import scrollbars from '../scrollbars.scss'
|
||||||
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||||
import theme from '../theme.js'
|
import theme from '../theme.js'
|
||||||
|
|
||||||
// List of collapsible layer editors
|
import {SortableContainer, SortableHandle, arrayMove} from 'react-sortable-hoc';
|
||||||
export class LayerList extends React.Component {
|
|
||||||
static propTypes = {
|
const layerListPropTypes = {
|
||||||
layers: React.PropTypes.instanceOf(Immutable.OrderedMap),
|
layers: React.PropTypes.instanceOf(Immutable.OrderedMap),
|
||||||
onLayersChanged: React.PropTypes.func.isRequired,
|
onLayersChanged: React.PropTypes.func.isRequired,
|
||||||
onLayerSelected: React.PropTypes.func,
|
onLayerSelected: React.PropTypes.func,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// List of collapsible layer editors
|
||||||
|
@SortableContainer
|
||||||
|
class LayerListContainer extends React.Component {
|
||||||
|
static propTypes = {...layerListPropTypes}
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
onLayerSelected: () => {},
|
onLayerSelected: () => {},
|
||||||
}
|
}
|
||||||
|
@ -40,26 +44,55 @@ export class LayerList extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const layerPanels = this.props.layers.map(layer => {
|
const layerPanels = this.props.layers.toIndexedSeq().map((layer, index) => {
|
||||||
const layerId = layer.get('id')
|
const layerId = layer.get('id')
|
||||||
return <LayerListItem
|
return <LayerListItem
|
||||||
|
index={index}
|
||||||
key={layerId}
|
key={layerId}
|
||||||
layerId={layerId}
|
layerId={layerId}
|
||||||
onLayerSelected={this.props.onLayerSelected}
|
onLayerSelected={this.props.onLayerSelected}
|
||||||
/>
|
/>
|
||||||
}).toIndexedSeq()
|
})
|
||||||
|
return <ul className={scrollbars.darkScrollbar} style={{
|
||||||
return <div>
|
|
||||||
<div className={scrollbars.darkScrollbar} style={{
|
|
||||||
overflowY: "scroll",
|
overflowY: "scroll",
|
||||||
bottom:0,
|
bottom:0,
|
||||||
left:0,
|
left:0,
|
||||||
right:0,
|
right:0,
|
||||||
top:1,
|
top:1,
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
|
padding: theme.scale[2],
|
||||||
}}>
|
}}>
|
||||||
{layerPanels}
|
{layerPanels}
|
||||||
</div>
|
</ul>
|
||||||
</div>
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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}
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,16 @@ import { LayerEditor } from './editor.jsx'
|
||||||
import scrollbars from '../scrollbars.scss'
|
import scrollbars from '../scrollbars.scss'
|
||||||
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||||
import theme from '../theme.js'
|
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
|
@Radium
|
||||||
class LayerListItem extends React.Component {
|
class LayerListItem extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
layerId: React.PropTypes.number.isRequired,
|
layerId: React.PropTypes.string.isRequired,
|
||||||
onLayerSelected: React.PropTypes.func.isRequired,
|
onLayerSelected: React.PropTypes.func.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,30 +31,32 @@ class LayerListItem extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
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,
|
borderBottom: 1,
|
||||||
borderLeft: 2,
|
borderLeft: 2,
|
||||||
borderRight: 0,
|
borderRight: 0,
|
||||||
borderStyle: "solid",
|
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(),
|
borderColor: color(theme.colors.gray).lighten(0.1).hexString(),
|
||||||
}}>
|
|
||||||
<div
|
|
||||||
onClick={() => this.props.onLayerSelected(this.props.layerId)}
|
|
||||||
style={{
|
|
||||||
backgroundColor: theme.colors.gray,
|
backgroundColor: theme.colors.gray,
|
||||||
":hover": {
|
":hover": {
|
||||||
backgroundColor: color(theme.colors.gray).lighten(0.15).hexString(),
|
backgroundColor: color(theme.colors.gray).lighten(0.15).hexString(),
|
||||||
}
|
}
|
||||||
}}
|
|
||||||
>
|
|
||||||
<NavItem style={{
|
|
||||||
fontWeight: 400,
|
|
||||||
color: theme.colors.lowgray,
|
|
||||||
}}>
|
}}>
|
||||||
#{this.props.layerId}
|
<DragHandle />
|
||||||
</NavItem>
|
<span>#{this.props.layerId}</span>
|
||||||
</div>
|
</li>
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue