Switch over to tabs

This commit is contained in:
lukasmartinelli 2016-09-10 15:15:17 +02:00
parent e27b88c6bc
commit 0e65ac8937
10 changed files with 80 additions and 75 deletions

View file

@ -12,10 +12,10 @@ import theme from './theme.js'
import layout from './layout.scss' import layout from './layout.scss'
export default class App extends React.Component { export default class App extends React.Component {
static childContextTypes = { static childContextTypes = {
rebass: React.PropTypes.object, rebass: React.PropTypes.object,
reactIconBase: React.PropTypes.object reactIconBase: React.PropTypes.object
} }
constructor(props) { constructor(props) {
super(props) super(props)
@ -26,8 +26,8 @@ export default class App extends React.Component {
} }
} }
getChildContext() { getChildContext() {
return { return {
rebass: theme, rebass: theme,
reactIconBase: { size: 20 } reactIconBase: { size: 20 }
} }
@ -35,7 +35,7 @@ export default class App extends React.Component {
onStyleDownload() { onStyleDownload() {
this.styleStore.save(newStyle) this.styleStore.save(newStyle)
const mapStyle = JSON.stringify(this.state.currentStyle.toJS(), null, 4) const mapStyle = JSON.stringify(this.state.currentStyle.toJS(), null, 4)
const blob = new Blob([mapStyle], {type: "application/json;charset=utf-8"}); const blob = new Blob([mapStyle], {type: "application/json;charset=utf-8"});
saveAs(blob, mapStyle.id + ".json"); saveAs(blob, mapStyle.id + ".json");
} }
@ -56,15 +56,15 @@ export default class App extends React.Component {
} }
onOpenSettings() { onOpenSettings() {
this.setState({ workContext: "settings", }) this.setState({ workContext: "settings" })
} }
onOpenLayers() { onOpenLayers() {
this.setState({ workContext: "layers", }) this.setState({ workContext: "layers", })
} }
render() { render() {
return <div style={{ fontFamily: theme.fontFamily, color: theme.color, fontWeight: 300 }}> return <div style={{ fontFamily: theme.fontFamily, color: theme.color, fontWeight: 300 }}>
<Toolbar <Toolbar
styleAvailable={this.state.currentStyle.get('layers').size > 0} styleAvailable={this.state.currentStyle.get('layers').size > 0}
onStyleSave={this.onStyleSave.bind(this)} onStyleSave={this.onStyleSave.bind(this)}
@ -82,5 +82,5 @@ export default class App extends React.Component {
<Map mapStyle={this.state.currentStyle} /> <Map mapStyle={this.state.currentStyle} />
</div> </div>
</div> </div>
} }
} }

View file

View file

@ -3,9 +3,9 @@ import { Input } from 'rebass'
export default class BackgroundLayer extends React.Component { export default class BackgroundLayer extends React.Component {
static propTypes = { static propTypes = {
layer: React.PropTypes.object.isRequired, layer: React.PropTypes.object.isRequired,
onPaintChanged: React.PropTypes.func.isRequired onPaintChanged: React.PropTypes.func.isRequired
} }
onPaintChanged(property, e) { onPaintChanged(property, e) {
let value = e.target.value let value = e.target.value

View file

@ -20,14 +20,14 @@ class UnsupportedLayer extends React.Component {
/** Layer editor supporting multiple types of layers. */ /** Layer editor supporting multiple types of layers. */
export class LayerEditor extends React.Component { export class LayerEditor extends React.Component {
static propTypes = { static propTypes = {
layer: React.PropTypes.object.isRequired, layer: React.PropTypes.object.isRequired,
onLayerChanged: React.PropTypes.func.isRequired, onLayerChanged: React.PropTypes.func.isRequired,
onLayerDestroyed: React.PropTypes.func.isRequired, onLayerDestroyed: React.PropTypes.func.isRequired,
} }
static childContextTypes = { static childContextTypes = {
reactIconBase: React.PropTypes.object reactIconBase: React.PropTypes.object
} }
constructor(props) { constructor(props) {
super(props); super(props);
@ -36,12 +36,12 @@ export class LayerEditor extends React.Component {
} }
} }
getChildContext () { getChildContext () {
return { return {
reactIconBase: { reactIconBase: {
size: theme.fontSizes[4], size: theme.fontSizes[4],
color: theme.colors.lowgray, color: theme.colors.lowgray,
} }
} }
} }
@ -115,7 +115,7 @@ export class LayerEditor extends React.Component {
</NavItem> </NavItem>
<Space auto x={1} /> <Space auto x={1} />
<NavItem onClick={this.toggleVisibility.bind(this)}> <NavItem onClick={this.toggleVisibility.bind(this)}>
{visibleIcon} {visibleIcon}
</NavItem> </NavItem>
<NavItem onClick={(e) => this.props.onLayerDestroyed(this.props.layer)}> <NavItem onClick={(e) => this.props.onLayerDestroyed(this.props.layer)}>
<MdDelete /> <MdDelete />

View file

@ -8,8 +8,8 @@ import scrollbars from '../scrollbars.scss'
export class LayerList extends React.Component { export class LayerList extends React.Component {
static propTypes = { static propTypes = {
layers: React.PropTypes.instanceOf(Immutable.List), layers: React.PropTypes.instanceOf(Immutable.List),
onLayersChanged: React.PropTypes.func.isRequired onLayersChanged: React.PropTypes.func.isRequired
} }
constructor(props) { constructor(props) {
super(props) super(props)

View file

@ -6,8 +6,8 @@ import Immutable from 'immutable'
export class Map extends React.Component { export class Map extends React.Component {
static propTypes = { static propTypes = {
mapStyle: React.PropTypes.instanceOf(Immutable.Map).isRequired, mapStyle: React.PropTypes.instanceOf(Immutable.Map).isRequired,
} }
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
// If the id has changed a new style has been uplaoded and // If the id has changed a new style has been uplaoded and
@ -31,9 +31,9 @@ export class Map extends React.Component {
} }
} }
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
return nextProps.mapStyle !== this.props.mapStyle return nextProps.mapStyle !== this.props.mapStyle
} }
componentDidMount() { componentDidMount() {
//TODO: Read MapboxGL token from settings //TODO: Read MapboxGL token from settings
@ -44,9 +44,9 @@ export class Map extends React.Component {
style: this.props.mapStyle.toJS(), style: this.props.mapStyle.toJS(),
}); });
map.on("style.load", (...args) => { map.on("style.load", (...args) => {
this.setState({ map }); this.setState({ map });
}); });
} }
render() { render() {

View file

@ -6,9 +6,9 @@ import Immutable from 'immutable'
/** Edit global settings within a style such as the name */ /** Edit global settings within a style such as the name */
export class SettingsEditor extends React.Component { export class SettingsEditor extends React.Component {
static propTypes = { static propTypes = {
mapStyle: React.PropTypes.instanceOf(Immutable.Map).isRequired, mapStyle: React.PropTypes.instanceOf(Immutable.Map).isRequired,
onStyleChanged: React.PropTypes.func.isRequired onStyleChanged: React.PropTypes.func.isRequired
} }
onChange(property, e) { onChange(property, e) {
const changedStyle = this.props.mapStyle.set(property, e.target.value) const changedStyle = this.props.mapStyle.set(property, e.target.value)

View file

@ -1,6 +1,6 @@
const caps = { const caps = {
textTransform: 'uppercase', textTransform: 'uppercase',
letterSpacing: '.2em' letterSpacing: '.2em'
} }
const baseColors = { const baseColors = {
@ -34,22 +34,22 @@ const scale = [3, 5, 10, 30, 40]
const fontSizes = [28, 24, 20, 16, 14, 12, 10] const fontSizes = [28, 24, 20, 16, 14, 12, 10]
const border = { const border = {
borderColor: colors.black, borderColor: colors.black,
borderRadius: 0, borderRadius: 0,
} }
const dark = { const dark = {
name: 'Dark', name: 'Dark',
color: colors.white, color: colors.white,
fontFamily: 'Roboto, sans-serif', fontFamily: 'Roboto, sans-serif',
scale, scale,
fontSizes, fontSizes,
colors, colors,
inverted: colors.midGray, inverted: colors.midGray,
...border, ...border,
Block: { Block: {
backgroundColor: colors.gray, backgroundColor: colors.gray,
...border, ...border,
borderLeft: 0, borderLeft: 0,
borderRight: 0, borderRight: 0,
@ -63,17 +63,17 @@ const dark = {
fontWeight: 400, fontWeight: 400,
color: colors.white, color: colors.white,
}, },
Button: { Button: {
color: '#00d9f7', color: '#00d9f7',
}, },
Menu: { Menu: {
color: '#00d9f7', color: '#00d9f7',
backgroundColor: '#000' backgroundColor: '#000'
}, },
Message: { Message: {
color: '#111', color: '#111',
opacity: 15/16 opacity: 15/16
}, },
Header: { Header: {
fontWeight: 400, fontWeight: 400,
}, },

View file

@ -14,25 +14,30 @@ import theme from './theme.js';
export class Toolbar extends React.Component { export class Toolbar extends React.Component {
static propTypes = { static propTypes = {
onStyleUpload: React.PropTypes.func.isRequired, // A new style has been uploaded
onStyleDownload: React.PropTypes.func.isRequired, onStyleUpload: React.PropTypes.func.isRequired,
onStyleSave: React.PropTypes.func, // Current style is requested for download
onOpenSettings: React.PropTypes.func, onStyleDownload: React.PropTypes.func.isRequired,
onOpenLayers: React.PropTypes.func, // Style is explicitely saved to local cache
onStyleSave: React.PropTypes.func,
// Open settings drawer
onOpenSettings: React.PropTypes.func,
// Open layers drawer
onOpenLayers: React.PropTypes.func,
// Whether a style is available for download or saving // Whether a style is available for download or saving
// A style with no layers should not be available // A style with no layers should not be available
styleAvailable: React.PropTypes.bool, styleAvailable: React.PropTypes.bool,
} }
onUpload(_, files) { onUpload(_, files) {
const [e, file] = files[0]; const [e, file] = files[0];
const reader = new FileReader(); const reader = new FileReader();
reader.readAsText(file, "UTF-8"); reader.readAsText(file, "UTF-8");
reader.onload = e => { reader.onload = e => {
const style = JSON.parse(e.target.result); const style = JSON.parse(e.target.result);
this.props.onStyleUpload(style); this.props.onStyleUpload(style);
} }
reader.onerror = e => console.log(e.target); reader.onerror = e => console.log(e.target);
} }
saveButton() { saveButton() {
@ -72,13 +77,13 @@ export class Toolbar extends React.Component {
backgroundColor: theme.colors.black } backgroundColor: theme.colors.black }
}> }>
<Block> <Block>
<FileReaderInput onChange={this.onUpload.bind(this)}> <FileReaderInput onChange={this.onUpload.bind(this)}>
<Button big={true} theme={this.props.styleAvailable ? "default" : "success"}> <Button big={true} theme={this.props.styleAvailable ? "default" : "success"}>
<Tooltip inverted rounded title="Upload style"> <Tooltip inverted rounded title="Upload style">
<MdFileUpload /> <MdFileUpload />
</Tooltip> </Tooltip>
</Button> </Button>
</FileReaderInput> </FileReaderInput>
</Block> </Block>
{this.downloadButton()} {this.downloadButton()}
{this.saveButton()} {this.saveButton()}
@ -86,14 +91,14 @@ export class Toolbar extends React.Component {
<Button big={true} onClick={this.props.onOpenLayers}> <Button big={true} onClick={this.props.onOpenLayers}>
<Tooltip inverted rounded title="Layers"> <Tooltip inverted rounded title="Layers">
<MdLayers /> <MdLayers />
</Tooltip> </Tooltip>
</Button> </Button>
</Block> </Block>
<Block> <Block>
<Button big={true} onClick={this.props.onOpenSettings}> <Button big={true} onClick={this.props.onOpenSettings}>
<Tooltip inverted rounded title="Settings"> <Tooltip inverted rounded title="Settings">
<MdSettings /> <MdSettings />
</Tooltip> </Tooltip>
</Button> </Button>
</Block> </Block>
</Container> </Container>

View file

@ -9,8 +9,8 @@ export class WorkspaceDrawer extends React.Component {
static propTypes = { static propTypes = {
mapStyle: React.PropTypes.object.isRequired, mapStyle: React.PropTypes.object.isRequired,
onStyleChanged: React.PropTypes.func.isRequired, onStyleChanged: React.PropTypes.func.isRequired,
workContext: React.PropTypes.oneOf(['layers', 'settings']).isRequired, workContext: React.PropTypes.oneOf(['layers', 'settings']).isRequired,
} }
onLayersChanged(changedLayers) { onLayersChanged(changedLayers) {
const changedStyle = this.props.mapStyle.set('layers', changedLayers) const changedStyle = this.props.mapStyle.set('layers', changedLayers)