diff --git a/package.json b/package.json
index d716aece..ba8d623c 100644
--- a/package.json
+++ b/package.json
@@ -4,6 +4,7 @@
"description": "A MapboxGL visual style editor",
"main": "''",
"scripts": {
+ "stats": "webpack --config webpack.production.config.js --profile --json > stats.json",
"build": "webpack --config webpack.production.config.js --progress --profile --colors",
"start": "webpack-dev-server --progress --profile --colors",
"lint": "eslint --ext js --ext jsx src"
@@ -18,7 +19,6 @@
"dependencies": {
"file-saver": "^1.3.2",
"immutable": "^3.8.1",
- "lodash": "^4.15.0",
"mapbox-gl": "^0.23.0",
"mapbox-gl-style-spec": "^8.8.0",
"node-sass": "^3.9.2",
@@ -27,13 +27,9 @@
"react-collapse": "^2.3.3",
"react-dom": "15.3.0",
"react-file-reader-input": "^1.1.0",
- "react-geomicons": "^2.0.5",
"react-height": "^2.1.1",
"react-icons": "^2.2.1",
- "react-mapbox-gl": "^0.11.0",
"react-motion": "^0.4.4",
- "react-scrollbar": "^0.4.1",
- "react-tap-event-plugin": "^1.0.0",
"rebass": "^0.3.1",
"sass-loader": "^4.0.1"
},
diff --git a/src/app.jsx b/src/app.jsx
index c9424af5..b3529123 100644
--- a/src/app.jsx
+++ b/src/app.jsx
@@ -10,7 +10,6 @@ import { WorkspaceDrawer } from './workspace.jsx'
import theme from './theme.js'
import layout from './layout.scss'
-import 'react-virtualized/styles.css'
export default class App extends React.Component {
static childContextTypes = {
diff --git a/src/layers.jsx b/src/layers.jsx
index db83c220..e69de29b 100644
--- a/src/layers.jsx
+++ b/src/layers.jsx
@@ -1,266 +0,0 @@
-import React from 'react'
-import randomColor from 'randomcolor'
-import { Block, ButtonCircle, Heading, Checkbox, Slider, Switch, Input, Panel, PanelHeader, Toolbar, NavItem, Tooltip, Container, Space} from 'rebass'
-import { Button, Text } from 'rebass'
-import {MdVisibility, MdArrowDropDown, MdArrowDropUp, MdAddToPhotos, MdDelete, MdVisibilityOff} from 'react-icons/lib/md';
-import Collapse from 'react-collapse'
-import theme from './theme.js'
-import scrollbars from './scrollbars.scss'
-import _ from 'lodash'
-import Immutable from 'immutable'
-
-export class FillLayer extends React.Component {
- static propTypes = {
- layer: React.PropTypes.object.isRequired,
- onPaintChanged: React.PropTypes.func.isRequired
- }
-
- onPaintChanged(property, e) {
- let value = e.target.value
- if (property == "fill-opacity") {
- value = parseFloat(value)
- }
-
- this.props.onPaintChanged(property, value)
- }
-
- render() {
- const paint = this.props.layer.get('paint')
- return
-
-
-
-
-
-
-
- }
-}
-
-export class BackgroundLayer extends React.Component {
- static propTypes = {
- layer: React.PropTypes.object.isRequired,
- onPaintChanged: React.PropTypes.func.isRequired
- }
-
- onPaintChanged(property, e) {
- let value = e.target.value
- if (property == "background-opacity" && !isNaN(parseFloat(value))) {
- value = parseFloat(value)
- }
- this.props.onPaintChanged(property, value)
- }
-
- render() {
- const paint = this.props.layer.get('paint')
- return
-
-
-
- }
-}
-
-export class LineLayer extends React.Component {
- render() {
- return
- }
-}
-
-export class SymbolLayer extends React.Component {
- render() {
- return
- }
-}
-
-export class NoLayer extends React.Component {
- render() {
- return
- }
-}
-
-export class LayerPanel extends React.Component {
- static propTypes = {
- layer: React.PropTypes.object.isRequired,
- onLayerChanged: React.PropTypes.func.isRequired,
- onLayerDestroyed: React.PropTypes.func.isRequired,
- }
-
- static childContextTypes = {
- reactIconBase: React.PropTypes.object
- }
-
- constructor(props) {
- super(props);
- this.state = {
- isOpened: false,
- }
- }
-
- getChildContext () {
- return {
- reactIconBase: {
- size: theme.fontSizes[4],
- color: theme.colors.lowgray,
- }
- }
- }
-
- onPaintChanged(property, newValue) {
- const changedLayer = this.props.layer.setIn(['paint', property], newValue)
- this.props.onLayerChanged(changedLayer)
- }
-
- onLayoutChanged(property, newValue) {
- const changedLayer = this.props.layer.setIn(['layout', property], newValue)
- this.props.onLayerChanged(changedLayer)
- }
-
- toggleLayer() {
- this.setState({isOpened: !this.state.isOpened})
- }
-
- layerFromType(type) {
- if (type === "fill") {
- return
- }
-
- if (type === "background") {
- return
- }
-
- if (type === "line") {
- return
- }
-
- if (type === "symbol") {
- return
- }
-
- return
- }
-
- toggleVisibility() {
- if(this.props.layer.layout.visibility === 'none') {
- this.onLayoutChanged('visibility', 'visible')
- } else {
- this.onLayoutChanged('visibility', 'none')
- }
- }
-
- render() {
- let visibleIcon =
- if(this.props.layer.layout && this.props.layer.layout.visibility === 'none') {
- visibleIcon =
- }
-
- return
-
-
- #{this.props.layer.get('id')}
-
-
-
- {visibleIcon}
-
- this.props.onLayerDestroyed(this.props.layer)}>
-
-
-
-
-
- {this.layerFromType(this.props.layer.get('type'))}
-
-
-
- }
-}
-
-export class LayerEditor extends React.Component {
- static propTypes = {
- layers: React.PropTypes.instanceOf(Immutable.List),
- onLayersChanged: React.PropTypes.func.isRequired
- }
-
- constructor(props) {
- super(props)
- }
-
- onLayerDestroyed(deletedLayer) {
- //TODO: That's just horrible...
- let deleteIdx = -1
-
- for (let i = 0; i < this.props.layers.length; i++) {
- if(this.props.layers[i].id == deletedLayer.id) {
- deleteIdx = i
- break
- }
- }
-
- const remainingLayers = this.props.layers.slice(0)
- remainingLayers.splice(deleteIdx, 0)
- this.props.onLayersChanged(remainingLayers)
- }
-
- onLayerChanged(changedLayer) {
- //TODO: That's just horrible...
- let changeIdx = -1
- for (let entry of this.props.layers.entries()) {
- let [i, layer] = entry
- if(layer.get('id') == changedLayer.get('id')) {
- changeIdx = i
- break
- }
- }
-
- const changedLayers = this.props.layers.set(changeIdx, changedLayer)
- this.props.onLayersChanged(changedLayers)
- }
-
- render() {
- var layerPanels = []
-
- for(let layer of this.props.layers) {
- layerPanels.push()
- }
-
- return
-
-
- Layers
-
-
-
-
-
- {layerPanels}
-
-
- }
-}
diff --git a/src/layers/background.jsx b/src/layers/background.jsx
new file mode 100644
index 00000000..3cd97612
--- /dev/null
+++ b/src/layers/background.jsx
@@ -0,0 +1,26 @@
+import React from 'react'
+import { Input } from 'rebass'
+
+export default class BackgroundLayer extends React.Component {
+ static propTypes = {
+ layer: React.PropTypes.object.isRequired,
+ onPaintChanged: React.PropTypes.func.isRequired
+ }
+
+ onPaintChanged(property, e) {
+ let value = e.target.value
+ if (property == "background-opacity" && !isNaN(parseFloat(value))) {
+ value = parseFloat(value)
+ }
+ this.props.onPaintChanged(property, value)
+ }
+
+ render() {
+ const paint = this.props.layer.get('paint')
+ return
+
+
+
+ }
+}
+
diff --git a/src/layers/editor.jsx b/src/layers/editor.jsx
new file mode 100644
index 00000000..9aa75bec
--- /dev/null
+++ b/src/layers/editor.jsx
@@ -0,0 +1,129 @@
+import React from 'react'
+import { Toolbar, NavItem, Space} from 'rebass'
+import { MdVisibility, MdDelete, MdVisibilityOff } from 'react-icons/lib/md';
+import Collapse from 'react-collapse'
+import theme from '../theme.js'
+import FillLayer from './fill.jsx'
+import LineLayer from './line.jsx'
+import SymbolLayer from './line.jsx'
+import BackgroundLayer from './background.jsx'
+
+class UnsupportedLayer extends React.Component {
+ render() {
+ return
+ }
+}
+
+/** Layer editor supporting multiple types of layers. */
+export class LayerEditor extends React.Component {
+ static propTypes = {
+ layer: React.PropTypes.object.isRequired,
+ onLayerChanged: React.PropTypes.func.isRequired,
+ onLayerDestroyed: React.PropTypes.func.isRequired,
+ }
+
+ static childContextTypes = {
+ reactIconBase: React.PropTypes.object
+ }
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ isOpened: false,
+ }
+ }
+
+ getChildContext () {
+ return {
+ reactIconBase: {
+ size: theme.fontSizes[4],
+ color: theme.colors.lowgray,
+ }
+ }
+ }
+
+ onPaintChanged(property, newValue) {
+ const changedLayer = this.props.layer.setIn(['paint', property], newValue)
+ this.props.onLayerChanged(changedLayer)
+ }
+
+ onLayoutChanged(property, newValue) {
+ const changedLayer = this.props.layer.setIn(['layout', property], newValue)
+ this.props.onLayerChanged(changedLayer)
+ }
+
+ toggleLayer() {
+ this.setState({isOpened: !this.state.isOpened})
+ }
+
+ layerFromType(type) {
+ if (type === "fill") {
+ return
+ }
+
+ if (type === "background") {
+ return
+ }
+
+ if (type === "line") {
+ return
+ }
+
+ if (type === "symbol") {
+ return
+ }
+
+ return
+ }
+
+ toggleVisibility() {
+ if(this.props.layer.layout.visibility === 'none') {
+ this.onLayoutChanged('visibility', 'visible')
+ } else {
+ this.onLayoutChanged('visibility', 'none')
+ }
+ }
+
+ render() {
+ let visibleIcon =
+ if(this.props.layer.layout && this.props.layer.layout.visibility === 'none') {
+ visibleIcon =
+ }
+
+ return
+
+
+ #{this.props.layer.get('id')}
+
+
+
+ {visibleIcon}
+
+ this.props.onLayerDestroyed(this.props.layer)}>
+
+
+
+
+
+ {this.layerFromType(this.props.layer.get('type'))}
+
+
+
+ }
+}
+
diff --git a/src/layers/fill.jsx b/src/layers/fill.jsx
new file mode 100644
index 00000000..bd9c9312
--- /dev/null
+++ b/src/layers/fill.jsx
@@ -0,0 +1,30 @@
+import React from 'react'
+import { Checkbox, Input } from 'rebass'
+
+export default class FillLayer extends React.Component {
+ static propTypes = {
+ layer: React.PropTypes.object.isRequired,
+ onPaintChanged: React.PropTypes.func.isRequired
+ }
+
+ onPaintChanged(property, e) {
+ let value = e.target.value
+ if (property == "fill-opacity") {
+ value = parseFloat(value)
+ }
+
+ this.props.onPaintChanged(property, value)
+ }
+
+ render() {
+ const paint = this.props.layer.get('paint')
+ return
+
+
+
+
+
+
+
+ }
+}
diff --git a/src/layers/line.jsx b/src/layers/line.jsx
new file mode 100644
index 00000000..898f4f9c
--- /dev/null
+++ b/src/layers/line.jsx
@@ -0,0 +1,7 @@
+import React from 'react'
+
+export default class LineLayer extends React.Component {
+ render() {
+ return
+ }
+}
diff --git a/src/layers/list.jsx b/src/layers/list.jsx
new file mode 100644
index 00000000..56e4eebf
--- /dev/null
+++ b/src/layers/list.jsx
@@ -0,0 +1,81 @@
+import React from 'react'
+import Immutable from 'immutable'
+import { Heading, Toolbar, NavItem, Space} from 'rebass'
+import { LayerEditor } from './editor.jsx'
+import scrollbars from '../scrollbars.scss'
+
+// List of collapsible layer editors
+export class LayerList extends React.Component {
+ static propTypes = {
+ layers: React.PropTypes.instanceOf(Immutable.List),
+ onLayersChanged: React.PropTypes.func.isRequired
+ }
+
+ constructor(props) {
+ super(props)
+ }
+
+ onLayerDestroyed(deletedLayer) {
+ //TODO: That's just horrible...
+ let deleteIdx = -1
+
+ for (let i = 0; i < this.props.layers.length; i++) {
+ if(this.props.layers[i].id == deletedLayer.id) {
+ deleteIdx = i
+ break
+ }
+ }
+
+ const remainingLayers = this.props.layers.slice(0)
+ remainingLayers.splice(deleteIdx, 0)
+ this.props.onLayersChanged(remainingLayers)
+ }
+
+ onLayerChanged(changedLayer) {
+ //TODO: That's just horrible...
+ let changeIdx = -1
+ for (let entry of this.props.layers.entries()) {
+ let [i, layer] = entry
+ if(layer.get('id') == changedLayer.get('id')) {
+ changeIdx = i
+ break
+ }
+ }
+
+ const changedLayers = this.props.layers.set(changeIdx, changedLayer)
+ this.props.onLayersChanged(changedLayers)
+ }
+
+ render() {
+ var layerPanels = []
+
+ for(let layer of this.props.layers) {
+ layerPanels.push()
+ }
+
+ return
+
+
+ Layers
+
+
+
+
+
+ {layerPanels}
+
+
+ }
+}
diff --git a/src/layers/symbol.jsx b/src/layers/symbol.jsx
new file mode 100644
index 00000000..69e20248
--- /dev/null
+++ b/src/layers/symbol.jsx
@@ -0,0 +1,7 @@
+import React from 'react'
+
+export default class SymbolLayer extends React.Component {
+ render() {
+ return
+ }
+}
diff --git a/src/workspace.jsx b/src/workspace.jsx
index eb3683f8..2a5350d4 100644
--- a/src/workspace.jsx
+++ b/src/workspace.jsx
@@ -1,5 +1,5 @@
import React from 'react'
-import { LayerEditor } from './layers.jsx'
+import { LayerList } from './layers/list.jsx'
import { SettingsEditor } from './settings.jsx'
import theme from './theme.js'
@@ -21,7 +21,7 @@ export class WorkspaceDrawer extends React.Component {
let workspaceContent = null
if(this.props.workContext === "layers") {
- workspaceContent =