Group layers #66

This commit is contained in:
Lukas Martinelli 2017-01-11 17:52:21 +01:00
parent 76d2d06e77
commit d0f047d88a
6 changed files with 142 additions and 38 deletions

View file

@ -0,0 +1,20 @@
import React from 'react'
import CollapseOpenIcon from 'react-icons/lib/md/arrow-drop-down'
import CollapseCloseIcon from 'react-icons/lib/md/arrow-drop-up'
export default class Collapser extends React.Component {
static propTypes = {
isCollapsed: React.PropTypes.bool.isRequired,
style: React.PropTypes.object,
}
render() {
const iconStyle = {
width: 20,
height: 20,
...this.props.style,
}
return this.props.isCollapsed ? <CollapseCloseIcon style={iconStyle}/> : <CollapseOpenIcon style={iconStyle} />
}
}

View file

@ -1,22 +1,6 @@
import React from 'react'
import Collapse from 'react-collapse'
import CollapseOpenIcon from 'react-icons/lib/md/arrow-drop-down'
import CollapseCloseIcon from 'react-icons/lib/md/arrow-drop-up'
class Collapser extends React.Component {
static propTypes = {
isCollapsed: React.PropTypes.bool.isRequired,
}
render() {
const iconStyle = {
width: 20,
height: 20,
}
return this.props.isCollapsed ? <CollapseCloseIcon style={iconStyle}/> : <CollapseOpenIcon style={iconStyle} />
}
}
import Collapser from './Collapser'
export default class LayerEditorGroup extends React.Component {
static propTypes = {

View file

@ -2,6 +2,7 @@ import React from 'react'
import cloneDeep from 'lodash.clonedeep'
import Button from '../Button'
import LayerListGroup from './LayerListGroup'
import LayerListItem from './LayerListItem'
import AddIcon from 'react-icons/lib/md/add-circle-outline'
import AddModal from '../modals/AddModal'
@ -9,6 +10,8 @@ import AddModal from '../modals/AddModal'
import style from '../../libs/style.js'
import {SortableContainer, SortableHandle, arrayMove} from 'react-sortable-hoc';
const layerPrefix = name => name.replace(' ', '-').replace('_', '-').split('-')[0]
const layerListPropTypes = {
layers: React.PropTypes.array.isRequired,
selectedLayerIndex: React.PropTypes.number.isRequired,
@ -73,22 +76,69 @@ class LayerListContainer extends React.Component {
})
}
render() {
const layerPanels = this.props.layers.map((layer, index) => {
const layerId = layer.id
return <LayerListItem
index={index}
key={layerId}
layerId={layerId}
layerType={layer.type}
visibility={(layer.layout || {}).visibility}
isSelected={index === this.props.selectedLayerIndex}
onLayerSelect={this.props.onLayerSelect}
onLayerDestroy={this.onLayerDestroy.bind(this)}
onLayerCopy={this.onLayerCopy.bind(this)}
onLayerVisibilityToggle={this.onLayerVisibilityToggle.bind(this)}
/>
groupedLayers() {
const groups = []
for (let i = 0; i < this.props.layers.length; i++) {
const previousLayer = this.props.layers[i-1]
const layer = this.props.layers[i]
if(previousLayer && layerPrefix(previousLayer.id) == layerPrefix(layer.id)) {
const lastGroup = groups[groups.length - 1]
lastGroup.push(layer)
} else {
groups.push([layer])
}
}
return groups
}
toggleLayerGroup(groupPrefix) {
groupedLayers().forEach(layers => {
if(groupPrefix === layerPrefix(layers[0].id)) {
layers.forEach(layer => {
//HACK
//In this case it is ok to modify the metadata
//because no one else depends on it
layer.metadata = {
...layer.metadata,
'maputnik:visible': false
}
})
}
})
}
render() {
const listItems = []
let idx = 0
this.groupedLayers().forEach(layers => {
if(layers.length > 1) {
const groupPrefix = layerPrefix(layers[0].id)
const grp = <LayerListGroup
key={'group-'+groupPrefix}
title={groupPrefix}
isActive={true}
/>
listItems.push(grp)
}
layers.forEach(layer => {
const listItem = <LayerListItem
index={idx}
key={layer.id}
layerId={layer.id}
layerType={layer.type}
visibility={(layer.layout || {}).visibility}
isSelected={idx === this.props.selectedLayerIndex}
onLayerSelect={this.props.onLayerSelect}
onLayerDestroy={this.onLayerDestroy.bind(this)}
onLayerCopy={this.onLayerCopy.bind(this)}
onLayerVisibilityToggle={this.onLayerVisibilityToggle.bind(this)}
/>
listItems.push(listItem)
idx += 1
})
})
return <div className="maputnik-layer-list">
<AddModal
layers={this.props.layers}
@ -107,7 +157,7 @@ class LayerListContainer extends React.Component {
</Button>
</header>
<ul className="maputnik-layer-list-container">
{layerPanels}
{listItems}
</ul>
</div>
}

View file

@ -0,0 +1,26 @@
import React from 'react'
import Collapser from './Collapser'
export default class LayerEditorGroup extends React.Component {
static propTypes = {
title: React.PropTypes.string.isRequired,
children: React.PropTypes.element.isRequired,
isActive: React.PropTypes.bool.isRequired,
onActiveToggle: React.PropTypes.func.isRequired
}
render() {
return <div className="maputnik-layer-list-group">
<div className="maputnik-layer-list-group-header"
onClick={e => this.props.onActiveToggle(!this.props.isActive)}
>
<span className="maputnik-layer-list-group-title">{this.props.title}</span>
<span className="maputnik-space" />
<Collapser
style={{ height: 14, width: 14 }}
isCollapsed={this.props.isActive}
/>
</div>
</div>
}
}

View file

@ -80,10 +80,6 @@ class LayerListItem extends React.Component {
reactIconBase: React.PropTypes.object
}
constructor(props) {
super(props)
}
getChildContext() {
return {
reactIconBase: { size: 14 }

View file

@ -37,7 +37,6 @@
cursor: pointer;
position: relative;
padding: 5px 10px;
background-color: $color-black;
line-height: 1.3;
display: flex;
display: -ms-flexbox;
@ -69,6 +68,35 @@
overflow: hidden;
text-overflow: ellipsis;
}
&-group {
//border-bottom: 2px solid $color-gray;
}
&-group-header {
font-size: $font-size-6;
color: $color-lowgray;
background-color: lighten($color-black, 2);
cursor: pointer;
user-select: none;
padding: $margin-2;
display: flex;
display: -ms-flexbox;
@include vendor-prefix(flex-direction, row)
svg {
width: 14px;
height: 14px;
}
}
&-group-title {
vertical-align: middle;
}
&-group-content {
margin-left: $margin-3;
}
}