mirror of
https://github.com/a-nyx/maputnik-with-pmtiles.git
synced 2024-12-27 07:35:23 +01:00
Tidy of components
- Moved all components into a single directory like nextjs - Made component names consistent with each other - Made component names consistent with their export class names - Added storybook for a few components with the aim to extend this further.
This commit is contained in:
parent
d07b40ccef
commit
624ccb5b00
88 changed files with 5167 additions and 513 deletions
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
|
@ -90,6 +90,7 @@ jobs:
|
||||||
${{ runner.os }}-node-
|
${{ runner.os }}-node-
|
||||||
- run: npm install
|
- run: npm install
|
||||||
- run: npm run build
|
- run: npm run build
|
||||||
|
- run: npm run build-storybook
|
||||||
- name: artifacts/editor
|
- name: artifacts/editor
|
||||||
uses: actions/upload-artifact@v1
|
uses: actions/upload-artifact@v1
|
||||||
with:
|
with:
|
||||||
|
@ -101,6 +102,11 @@ jobs:
|
||||||
with:
|
with:
|
||||||
name: editor-profiling
|
name: editor-profiling
|
||||||
path: build/profiling
|
path: build/profiling
|
||||||
|
- name: artifacts/storybook
|
||||||
|
uses: actions/upload-artifact@v1
|
||||||
|
with:
|
||||||
|
name: storybook
|
||||||
|
path: build/storybook
|
||||||
|
|
||||||
# build and test the editor in standalone-chrome
|
# build and test the editor in standalone-chrome
|
||||||
test_selenium_standalone_chrome:
|
test_selenium_standalone_chrome:
|
||||||
|
|
17
.storybook/main.js
Normal file
17
.storybook/main.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
const rules = require('../config/webpack.rules');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
stories: ['../stories/**/*.stories.js'],
|
||||||
|
addons: ['@storybook/addon-actions', '@storybook/addon-links'],
|
||||||
|
webpackFinal: async config => {
|
||||||
|
// do mutation to the config
|
||||||
|
|
||||||
|
return {
|
||||||
|
...config,
|
||||||
|
module: {
|
||||||
|
...config.module,
|
||||||
|
rules
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
7
.storybook/manager.js
Normal file
7
.storybook/manager.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { addons } from '@storybook/addons';
|
||||||
|
import { themes } from '@storybook/theming';
|
||||||
|
import theme from './maputnik.theme';
|
||||||
|
|
||||||
|
addons.setConfig({
|
||||||
|
theme: theme,
|
||||||
|
});
|
8
.storybook/maputnik.theme.js
Normal file
8
.storybook/maputnik.theme.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import { create } from '@storybook/theming/create';
|
||||||
|
|
||||||
|
export default create({
|
||||||
|
base: 'light',
|
||||||
|
|
||||||
|
brandTitle: 'Maputnik',
|
||||||
|
brandUrl: 'https://github.com/maputnik/editor',
|
||||||
|
});
|
4510
package-lock.json
generated
4510
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -13,7 +13,9 @@
|
||||||
"start-prod": "webpack-dev-server --progress --profile --colors --config config/webpack.production.config.js",
|
"start-prod": "webpack-dev-server --progress --profile --colors --config config/webpack.production.config.js",
|
||||||
"lint-js": "eslint --ext js --ext jsx src test",
|
"lint-js": "eslint --ext js --ext jsx src test",
|
||||||
"lint-css": "stylelint \"src/styles/*.scss\"",
|
"lint-css": "stylelint \"src/styles/*.scss\"",
|
||||||
"lint": "npm run lint-js && npm run lint-css"
|
"lint": "npm run lint-js && npm run lint-css",
|
||||||
|
"storybook": "start-storybook -h 0.0.0.0 -p 6006",
|
||||||
|
"build-storybook": "build-storybook -o build/storybook"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -119,6 +121,11 @@
|
||||||
"@babel/preset-flow": "^7.0.0",
|
"@babel/preset-flow": "^7.0.0",
|
||||||
"@babel/preset-react": "^7.6.3",
|
"@babel/preset-react": "^7.6.3",
|
||||||
"@mdi/js": "^5.0.45",
|
"@mdi/js": "^5.0.45",
|
||||||
|
"@storybook/addon-actions": "^5.3.19",
|
||||||
|
"@storybook/addon-links": "^5.3.19",
|
||||||
|
"@storybook/addons": "^5.3.19",
|
||||||
|
"@storybook/react": "^5.3.19",
|
||||||
|
"@storybook/theming": "^5.3.19",
|
||||||
"@wdio/cli": "^6.1.14",
|
"@wdio/cli": "^6.1.14",
|
||||||
"@wdio/local-runner": "^6.1.14",
|
"@wdio/local-runner": "^6.1.14",
|
||||||
"@wdio/mocha-framework": "^6.1.14",
|
"@wdio/mocha-framework": "^6.1.14",
|
||||||
|
|
|
@ -7,21 +7,21 @@ import {unset} from 'lodash'
|
||||||
import arrayMove from 'array-move'
|
import arrayMove from 'array-move'
|
||||||
import url from 'url'
|
import url from 'url'
|
||||||
|
|
||||||
import MapboxGlMap from './map/MapboxGlMap'
|
import MapMapboxGl from './MapMapboxGl'
|
||||||
import OpenLayersMap from './map/OpenLayersMap'
|
import MapOpenLayers from './MapOpenLayers'
|
||||||
import LayerList from './layers/LayerList'
|
import LayerList from './LayerList'
|
||||||
import LayerEditor from './layers/LayerEditor'
|
import LayerEditor from './LayerEditor'
|
||||||
import Toolbar from './Toolbar'
|
import AppToolbar from './AppToolbar'
|
||||||
import AppLayout from './AppLayout'
|
import AppLayout from './AppLayout'
|
||||||
import MessagePanel from './MessagePanel'
|
import MessagePanel from './AppMessagePanel'
|
||||||
|
|
||||||
import SettingsModal from './modals/SettingsModal'
|
import ModalSettings from './ModalSettings'
|
||||||
import ExportModal from './modals/ExportModal'
|
import ModalExport from './ModalExport'
|
||||||
import SourcesModal from './modals/SourcesModal'
|
import ModalSources from './ModalSources'
|
||||||
import OpenModal from './modals/OpenModal'
|
import ModalOpen from './ModalOpen'
|
||||||
import ShortcutsModal from './modals/ShortcutsModal'
|
import ModalShortcuts from './ModalShortcuts'
|
||||||
import SurveyModal from './modals/SurveyModal'
|
import ModalSurvey from './ModalSurvey'
|
||||||
import DebugModal from './modals/DebugModal'
|
import ModalDebug from './ModalDebug'
|
||||||
|
|
||||||
import { downloadGlyphsMetadata, downloadSpriteMetadata } from '../libs/metadata'
|
import { downloadGlyphsMetadata, downloadSpriteMetadata } from '../libs/metadata'
|
||||||
import {latest, validate} from '@mapbox/mapbox-gl-style-spec'
|
import {latest, validate} from '@mapbox/mapbox-gl-style-spec'
|
||||||
|
@ -36,7 +36,7 @@ import tokens from '../config/tokens.json'
|
||||||
import isEqual from 'lodash.isequal'
|
import isEqual from 'lodash.isequal'
|
||||||
import Debug from '../libs/debug'
|
import Debug from '../libs/debug'
|
||||||
import queryUtil from '../libs/query-util'
|
import queryUtil from '../libs/query-util'
|
||||||
import {formatLayerId} from './util/format';
|
import {formatLayerId} from '../util/format';
|
||||||
|
|
||||||
import MapboxGl from 'mapbox-gl'
|
import MapboxGl from 'mapbox-gl'
|
||||||
|
|
||||||
|
@ -668,14 +668,14 @@ export default class App extends React.Component {
|
||||||
|
|
||||||
// Check if OL code has been loaded?
|
// Check if OL code has been loaded?
|
||||||
if(renderer === 'ol') {
|
if(renderer === 'ol') {
|
||||||
mapElement = <OpenLayersMap
|
mapElement = <MapOpenLayers
|
||||||
{...mapProps}
|
{...mapProps}
|
||||||
onChange={this.onMapChange}
|
onChange={this.onMapChange}
|
||||||
debugToolbox={this.state.openlayersDebugOptions.debugToolbox}
|
debugToolbox={this.state.openlayersDebugOptions.debugToolbox}
|
||||||
onLayerSelect={this.onLayerSelect}
|
onLayerSelect={this.onLayerSelect}
|
||||||
/>
|
/>
|
||||||
} else {
|
} else {
|
||||||
mapElement = <MapboxGlMap {...mapProps}
|
mapElement = <MapMapboxGl {...mapProps}
|
||||||
onChange={this.onMapChange}
|
onChange={this.onMapChange}
|
||||||
options={this.state.mapboxGlDebugOptions}
|
options={this.state.mapboxGlDebugOptions}
|
||||||
inspectModeEnabled={this.state.mapState === "inspect"}
|
inspectModeEnabled={this.state.mapState === "inspect"}
|
||||||
|
@ -741,7 +741,7 @@ export default class App extends React.Component {
|
||||||
const selectedLayer = layers.length > 0 ? layers[this.state.selectedLayerIndex] : null
|
const selectedLayer = layers.length > 0 ? layers[this.state.selectedLayerIndex] : null
|
||||||
const metadata = this.state.mapStyle.metadata || {}
|
const metadata = this.state.mapStyle.metadata || {}
|
||||||
|
|
||||||
const toolbar = <Toolbar
|
const toolbar = <AppToolbar
|
||||||
renderer={this._getRenderer()}
|
renderer={this._getRenderer()}
|
||||||
mapState={this.state.mapState}
|
mapState={this.state.mapState}
|
||||||
mapStyle={this.state.mapStyle}
|
mapStyle={this.state.mapStyle}
|
||||||
|
@ -795,7 +795,7 @@ export default class App extends React.Component {
|
||||||
|
|
||||||
|
|
||||||
const modals = <div>
|
const modals = <div>
|
||||||
<DebugModal
|
<ModalDebug
|
||||||
renderer={this._getRenderer()}
|
renderer={this._getRenderer()}
|
||||||
mapboxGlDebugOptions={this.state.mapboxGlDebugOptions}
|
mapboxGlDebugOptions={this.state.mapboxGlDebugOptions}
|
||||||
openlayersDebugOptions={this.state.openlayersDebugOptions}
|
openlayersDebugOptions={this.state.openlayersDebugOptions}
|
||||||
|
@ -805,12 +805,12 @@ export default class App extends React.Component {
|
||||||
onOpenToggle={this.toggleModal.bind(this, 'debug')}
|
onOpenToggle={this.toggleModal.bind(this, 'debug')}
|
||||||
mapView={this.state.mapView}
|
mapView={this.state.mapView}
|
||||||
/>
|
/>
|
||||||
<ShortcutsModal
|
<ModalShortcuts
|
||||||
ref={(el) => this.shortcutEl = el}
|
ref={(el) => this.shortcutEl = el}
|
||||||
isOpen={this.state.isOpen.shortcuts}
|
isOpen={this.state.isOpen.shortcuts}
|
||||||
onOpenToggle={this.toggleModal.bind(this, 'shortcuts')}
|
onOpenToggle={this.toggleModal.bind(this, 'shortcuts')}
|
||||||
/>
|
/>
|
||||||
<SettingsModal
|
<ModalSettings
|
||||||
mapStyle={this.state.mapStyle}
|
mapStyle={this.state.mapStyle}
|
||||||
onStyleChanged={this.onStyleChanged}
|
onStyleChanged={this.onStyleChanged}
|
||||||
onChangeMetadataProperty={this.onChangeMetadataProperty}
|
onChangeMetadataProperty={this.onChangeMetadataProperty}
|
||||||
|
@ -818,24 +818,24 @@ export default class App extends React.Component {
|
||||||
onOpenToggle={this.toggleModal.bind(this, 'settings')}
|
onOpenToggle={this.toggleModal.bind(this, 'settings')}
|
||||||
openlayersDebugOptions={this.state.openlayersDebugOptions}
|
openlayersDebugOptions={this.state.openlayersDebugOptions}
|
||||||
/>
|
/>
|
||||||
<ExportModal
|
<ModalExport
|
||||||
mapStyle={this.state.mapStyle}
|
mapStyle={this.state.mapStyle}
|
||||||
onStyleChanged={this.onStyleChanged}
|
onStyleChanged={this.onStyleChanged}
|
||||||
isOpen={this.state.isOpen.export}
|
isOpen={this.state.isOpen.export}
|
||||||
onOpenToggle={this.toggleModal.bind(this, 'export')}
|
onOpenToggle={this.toggleModal.bind(this, 'export')}
|
||||||
/>
|
/>
|
||||||
<OpenModal
|
<ModalOpen
|
||||||
isOpen={this.state.isOpen.open}
|
isOpen={this.state.isOpen.open}
|
||||||
onStyleOpen={this.openStyle}
|
onStyleOpen={this.openStyle}
|
||||||
onOpenToggle={this.toggleModal.bind(this, 'open')}
|
onOpenToggle={this.toggleModal.bind(this, 'open')}
|
||||||
/>
|
/>
|
||||||
<SourcesModal
|
<ModalSources
|
||||||
mapStyle={this.state.mapStyle}
|
mapStyle={this.state.mapStyle}
|
||||||
onStyleChanged={this.onStyleChanged}
|
onStyleChanged={this.onStyleChanged}
|
||||||
isOpen={this.state.isOpen.sources}
|
isOpen={this.state.isOpen.sources}
|
||||||
onOpenToggle={this.toggleModal.bind(this, 'sources')}
|
onOpenToggle={this.toggleModal.bind(this, 'sources')}
|
||||||
/>
|
/>
|
||||||
<SurveyModal
|
<ModalSurvey
|
||||||
isOpen={this.state.isOpen.survey}
|
isOpen={this.state.isOpen.survey}
|
||||||
onOpenToggle={this.toggleModal.bind(this, 'survey')}
|
onOpenToggle={this.toggleModal.bind(this, 'survey')}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import {formatLayerId} from './util/format';
|
import {formatLayerId} from '../util/format';
|
||||||
|
|
||||||
class MessagePanel extends React.Component {
|
export default class AppMessagePanel extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
errors: PropTypes.array,
|
errors: PropTypes.array,
|
||||||
infos: PropTypes.array,
|
infos: PropTypes.array,
|
||||||
|
@ -60,5 +60,3 @@ class MessagePanel extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default MessagePanel
|
|
|
@ -101,7 +101,7 @@ class ToolbarAction extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Toolbar extends React.Component {
|
export default class AppToolbar extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
mapStyle: PropTypes.object.isRequired,
|
mapStyle: PropTypes.object.isRequired,
|
||||||
inspectModeEnabled: PropTypes.bool.isRequired,
|
inspectModeEnabled: PropTypes.bool.isRequired,
|
|
@ -1,12 +1,12 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import DocLabel from '../fields/DocLabel'
|
import FieldDocLabel from './FieldDocLabel'
|
||||||
import SpecDoc from './SpecDoc'
|
import Doc from './Doc'
|
||||||
|
|
||||||
|
|
||||||
/** Wrap a component with a label */
|
/** Wrap a component with a label */
|
||||||
class InputBlock extends React.Component {
|
export default class Block extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
"data-wd-key": PropTypes.string,
|
"data-wd-key": PropTypes.string,
|
||||||
label: PropTypes.oneOfType([
|
label: PropTypes.oneOfType([
|
||||||
|
@ -53,7 +53,7 @@ class InputBlock extends React.Component {
|
||||||
>
|
>
|
||||||
{this.props.fieldSpec &&
|
{this.props.fieldSpec &&
|
||||||
<div className="maputnik-input-block-label">
|
<div className="maputnik-input-block-label">
|
||||||
<DocLabel
|
<FieldDocLabel
|
||||||
label={this.props.label}
|
label={this.props.label}
|
||||||
onToggleDoc={this.onToggleDoc}
|
onToggleDoc={this.onToggleDoc}
|
||||||
fieldSpec={this.props.fieldSpec}
|
fieldSpec={this.props.fieldSpec}
|
||||||
|
@ -85,11 +85,10 @@ class InputBlock extends React.Component {
|
||||||
className="maputnik-doc-inline"
|
className="maputnik-doc-inline"
|
||||||
style={{display: this.state.showDoc ? '' : 'none'}}
|
style={{display: this.state.showDoc ? '' : 'none'}}
|
||||||
>
|
>
|
||||||
<SpecDoc fieldSpec={this.props.fieldSpec} />
|
<Doc fieldSpec={this.props.fieldSpec} />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default InputBlock
|
|
|
@ -1,10 +1,10 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import InputBlock from '../inputs/InputBlock'
|
import Block from './Block'
|
||||||
import StringInput from '../inputs/StringInput'
|
import FieldString from './FieldString'
|
||||||
|
|
||||||
class MetadataBlock extends React.Component {
|
export default class BlockComment extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
value: PropTypes.string,
|
value: PropTypes.string,
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
|
@ -15,19 +15,18 @@ class MetadataBlock extends React.Component {
|
||||||
doc: "Comments for the current layer. This is non-standard and not in the spec."
|
doc: "Comments for the current layer. This is non-standard and not in the spec."
|
||||||
};
|
};
|
||||||
|
|
||||||
return <InputBlock
|
return <Block
|
||||||
label={"Comments"}
|
label={"Comments"}
|
||||||
fieldSpec={fieldSpec}
|
fieldSpec={fieldSpec}
|
||||||
data-wd-key="layer-comment"
|
data-wd-key="layer-comment"
|
||||||
>
|
>
|
||||||
<StringInput
|
<FieldString
|
||||||
multi={true}
|
multi={true}
|
||||||
value={this.props.value}
|
value={this.props.value}
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
default="Comment..."
|
default="Comment..."
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MetadataBlock
|
|
|
@ -2,10 +2,10 @@ import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import {latest} from '@mapbox/mapbox-gl-style-spec'
|
import {latest} from '@mapbox/mapbox-gl-style-spec'
|
||||||
import InputBlock from '../inputs/InputBlock'
|
import Block from './Block'
|
||||||
import StringInput from '../inputs/StringInput'
|
import FieldString from './FieldString'
|
||||||
|
|
||||||
class LayerIdBlock extends React.Component {
|
export default class BlockId extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
value: PropTypes.string.isRequired,
|
value: PropTypes.string.isRequired,
|
||||||
wdKey: PropTypes.string.isRequired,
|
wdKey: PropTypes.string.isRequired,
|
||||||
|
@ -14,16 +14,15 @@ class LayerIdBlock extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <InputBlock label={"ID"} fieldSpec={latest.layer.id}
|
return <Block label={"ID"} fieldSpec={latest.layer.id}
|
||||||
data-wd-key={this.props.wdKey}
|
data-wd-key={this.props.wdKey}
|
||||||
error={this.props.error}
|
error={this.props.error}
|
||||||
>
|
>
|
||||||
<StringInput
|
<FieldString
|
||||||
value={this.props.value}
|
value={this.props.value}
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default LayerIdBlock
|
|
|
@ -2,10 +2,10 @@ import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import {latest} from '@mapbox/mapbox-gl-style-spec'
|
import {latest} from '@mapbox/mapbox-gl-style-spec'
|
||||||
import InputBlock from '../inputs/InputBlock'
|
import Block from './Block'
|
||||||
import NumberInput from '../inputs/NumberInput'
|
import FieldNumber from './FieldNumber'
|
||||||
|
|
||||||
class MaxZoomBlock extends React.Component {
|
export default class BlockMaxZoom extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
value: PropTypes.number,
|
value: PropTypes.number,
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
|
@ -13,11 +13,11 @@ class MaxZoomBlock extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <InputBlock label={"Max Zoom"} fieldSpec={latest.layer.maxzoom}
|
return <Block label={"Max Zoom"} fieldSpec={latest.layer.maxzoom}
|
||||||
error={this.props.error}
|
error={this.props.error}
|
||||||
data-wd-key="max-zoom"
|
data-wd-key="max-zoom"
|
||||||
>
|
>
|
||||||
<NumberInput
|
<FieldNumber
|
||||||
allowRange={true}
|
allowRange={true}
|
||||||
value={this.props.value}
|
value={this.props.value}
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
|
@ -25,8 +25,7 @@ class MaxZoomBlock extends React.Component {
|
||||||
max={latest.layer.maxzoom.maximum}
|
max={latest.layer.maxzoom.maximum}
|
||||||
default={latest.layer.maxzoom.maximum}
|
default={latest.layer.maxzoom.maximum}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MaxZoomBlock
|
|
|
@ -2,10 +2,10 @@ import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import {latest} from '@mapbox/mapbox-gl-style-spec'
|
import {latest} from '@mapbox/mapbox-gl-style-spec'
|
||||||
import InputBlock from '../inputs/InputBlock'
|
import Block from './Block'
|
||||||
import NumberInput from '../inputs/NumberInput'
|
import FieldNumber from './FieldNumber'
|
||||||
|
|
||||||
class MinZoomBlock extends React.Component {
|
export default class BlockMinZoom extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
value: PropTypes.number,
|
value: PropTypes.number,
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
|
@ -13,11 +13,11 @@ class MinZoomBlock extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <InputBlock label={"Min Zoom"} fieldSpec={latest.layer.minzoom}
|
return <Block label={"Min Zoom"} fieldSpec={latest.layer.minzoom}
|
||||||
error={this.props.error}
|
error={this.props.error}
|
||||||
data-wd-key="min-zoom"
|
data-wd-key="min-zoom"
|
||||||
>
|
>
|
||||||
<NumberInput
|
<FieldNumber
|
||||||
allowRange={true}
|
allowRange={true}
|
||||||
value={this.props.value}
|
value={this.props.value}
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
|
@ -25,8 +25,7 @@ class MinZoomBlock extends React.Component {
|
||||||
max={latest.layer.minzoom.maximum}
|
max={latest.layer.minzoom.maximum}
|
||||||
default={latest.layer.minzoom.minimum}
|
default={latest.layer.minzoom.minimum}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MinZoomBlock
|
|
|
@ -2,10 +2,10 @@ import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import {latest} from '@mapbox/mapbox-gl-style-spec'
|
import {latest} from '@mapbox/mapbox-gl-style-spec'
|
||||||
import InputBlock from '../inputs/InputBlock'
|
import Block from './Block'
|
||||||
import AutocompleteInput from '../inputs/AutocompleteInput'
|
import FieldAutocomplete from './FieldAutocomplete'
|
||||||
|
|
||||||
class LayerSourceBlock extends React.Component {
|
export default class BlockSource extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
value: PropTypes.string,
|
value: PropTypes.string,
|
||||||
wdKey: PropTypes.string,
|
wdKey: PropTypes.string,
|
||||||
|
@ -20,19 +20,18 @@ class LayerSourceBlock extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <InputBlock
|
return <Block
|
||||||
label={"Source"}
|
label={"Source"}
|
||||||
fieldSpec={latest.layer.source}
|
fieldSpec={latest.layer.source}
|
||||||
error={this.props.error}
|
error={this.props.error}
|
||||||
data-wd-key={this.props.wdKey}
|
data-wd-key={this.props.wdKey}
|
||||||
>
|
>
|
||||||
<AutocompleteInput
|
<FieldAutocomplete
|
||||||
value={this.props.value}
|
value={this.props.value}
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
options={this.props.sourceIds.map(src => [src, src])}
|
options={this.props.sourceIds.map(src => [src, src])}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default LayerSourceBlock
|
|
|
@ -2,10 +2,10 @@ import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import {latest} from '@mapbox/mapbox-gl-style-spec'
|
import {latest} from '@mapbox/mapbox-gl-style-spec'
|
||||||
import InputBlock from '../inputs/InputBlock'
|
import Block from './Block'
|
||||||
import AutocompleteInput from '../inputs/AutocompleteInput'
|
import FieldAutocomplete from './FieldAutocomplete'
|
||||||
|
|
||||||
class LayerSourceLayer extends React.Component {
|
export default class BlockSourceLayer extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
value: PropTypes.string,
|
value: PropTypes.string,
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
|
@ -20,17 +20,16 @@ class LayerSourceLayer extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <InputBlock label={"Source Layer"} fieldSpec={latest.layer['source-layer']}
|
return <Block label={"Source Layer"} fieldSpec={latest.layer['source-layer']}
|
||||||
data-wd-key="layer-source-layer"
|
data-wd-key="layer-source-layer"
|
||||||
>
|
>
|
||||||
<AutocompleteInput
|
<FieldAutocomplete
|
||||||
keepMenuWithinWindowBounds={!!this.props.isFixed}
|
keepMenuWithinWindowBounds={!!this.props.isFixed}
|
||||||
value={this.props.value}
|
value={this.props.value}
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
options={this.props.sourceLayerIds.map(l => [l, l])}
|
options={this.props.sourceLayerIds.map(l => [l, l])}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default LayerSourceLayer
|
|
|
@ -2,11 +2,11 @@ import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import {latest} from '@mapbox/mapbox-gl-style-spec'
|
import {latest} from '@mapbox/mapbox-gl-style-spec'
|
||||||
import InputBlock from '../inputs/InputBlock'
|
import Block from './Block'
|
||||||
import SelectInput from '../inputs/SelectInput'
|
import FieldSelect from './FieldSelect'
|
||||||
import StringInput from '../inputs/StringInput'
|
import FieldString from './FieldString'
|
||||||
|
|
||||||
class LayerTypeBlock extends React.Component {
|
export default class BlockType extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
value: PropTypes.string.isRequired,
|
value: PropTypes.string.isRequired,
|
||||||
wdKey: PropTypes.string,
|
wdKey: PropTypes.string,
|
||||||
|
@ -20,18 +20,18 @@ class LayerTypeBlock extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <InputBlock label={"Type"} fieldSpec={latest.layer.type}
|
return <Block label={"Type"} fieldSpec={latest.layer.type}
|
||||||
data-wd-key={this.props.wdKey}
|
data-wd-key={this.props.wdKey}
|
||||||
error={this.props.error}
|
error={this.props.error}
|
||||||
>
|
>
|
||||||
{this.props.disabled &&
|
{this.props.disabled &&
|
||||||
<StringInput
|
<FieldString
|
||||||
value={this.props.value}
|
value={this.props.value}
|
||||||
disabled={true}
|
disabled={true}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
{!this.props.disabled &&
|
{!this.props.disabled &&
|
||||||
<SelectInput
|
<FieldSelect
|
||||||
options={[
|
options={[
|
||||||
['background', 'Background'],
|
['background', 'Background'],
|
||||||
['fill', 'Fill'],
|
['fill', 'Fill'],
|
||||||
|
@ -47,8 +47,7 @@ class LayerTypeBlock extends React.Component {
|
||||||
value={this.props.value}
|
value={this.props.value}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
</InputBlock>
|
</Block>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default LayerTypeBlock
|
|
|
@ -1,10 +1,10 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import Collapse from 'react-collapse'
|
import Collapse as ReactCollapse from 'react-collapse'
|
||||||
import accessibility from '../../libs/accessibility'
|
import accessibility from '../../libs/accessibility'
|
||||||
|
|
||||||
|
|
||||||
export default class CollapseAlt extends React.Component {
|
export default class Collapse extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
isActive: PropTypes.bool.isRequired,
|
isActive: PropTypes.bool.isRequired,
|
||||||
children: PropTypes.element.isRequired
|
children: PropTypes.element.isRequired
|
||||||
|
@ -24,9 +24,9 @@ export default class CollapseAlt extends React.Component {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return (
|
return (
|
||||||
<Collapse isOpened={this.props.isActive}>
|
<ReactCollapse isOpened={this.props.isActive}>
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</Collapse>
|
</ReactCollapse>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
export default class SpecDoc extends React.Component {
|
export default class Doc extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
fieldSpec: PropTypes.object.isRequired,
|
fieldSpec: PropTypes.object.isRequired,
|
||||||
}
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import StringInput from './StringInput'
|
import FieldString from './FieldString'
|
||||||
import NumberInput from './NumberInput'
|
import FieldNumber from './FieldNumber'
|
||||||
|
|
||||||
class ArrayInput extends React.Component {
|
export default class FieldArray extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
value: PropTypes.array,
|
value: PropTypes.array,
|
||||||
type: PropTypes.string,
|
type: PropTypes.string,
|
||||||
|
@ -82,7 +82,7 @@ class ArrayInput extends React.Component {
|
||||||
|
|
||||||
const inputs = Array(this.props.length).fill(null).map((_, i) => {
|
const inputs = Array(this.props.length).fill(null).map((_, i) => {
|
||||||
if(this.props.type === 'number') {
|
if(this.props.type === 'number') {
|
||||||
return <NumberInput
|
return <FieldNumber
|
||||||
key={i}
|
key={i}
|
||||||
default={containsValues ? undefined : this.props.default[i]}
|
default={containsValues ? undefined : this.props.default[i]}
|
||||||
value={value[i]}
|
value={value[i]}
|
||||||
|
@ -90,7 +90,7 @@ class ArrayInput extends React.Component {
|
||||||
onChange={this.changeValue.bind(this, i)}
|
onChange={this.changeValue.bind(this, i)}
|
||||||
/>
|
/>
|
||||||
} else {
|
} else {
|
||||||
return <StringInput
|
return <FieldString
|
||||||
key={i}
|
key={i}
|
||||||
default={containsValues ? undefined : this.props.default[i]}
|
default={containsValues ? undefined : this.props.default[i]}
|
||||||
value={value[i]}
|
value={value[i]}
|
||||||
|
@ -106,4 +106,3 @@ class ArrayInput extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ArrayInput
|
|
|
@ -6,7 +6,7 @@ import Autocomplete from 'react-autocomplete'
|
||||||
|
|
||||||
const MAX_HEIGHT = 140;
|
const MAX_HEIGHT = 140;
|
||||||
|
|
||||||
class AutocompleteInput extends React.Component {
|
export default class FieldAutocomplete extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
value: PropTypes.string,
|
value: PropTypes.string,
|
||||||
options: PropTypes.array,
|
options: PropTypes.array,
|
||||||
|
@ -95,4 +95,3 @@ class AutocompleteInput extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AutocompleteInput
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
class CheckboxInput extends React.Component {
|
export default class FieldCheckbox extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
value: PropTypes.bool,
|
value: PropTypes.bool,
|
||||||
style: PropTypes.object,
|
style: PropTypes.object,
|
||||||
|
@ -32,4 +32,3 @@ class CheckboxInput extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CheckboxInput
|
|
|
@ -10,7 +10,7 @@ function formatColor(color) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** Number fields with support for min, max and units and documentation*/
|
/*** Number fields with support for min, max and units and documentation*/
|
||||||
class ColorField extends React.Component {
|
export default class FieldColor extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
name: PropTypes.string,
|
name: PropTypes.string,
|
||||||
|
@ -130,4 +130,3 @@ class ColorField extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ColorField
|
|
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import {MdInfoOutline, MdHighlightOff} from 'react-icons/md'
|
import {MdInfoOutline, MdHighlightOff} from 'react-icons/md'
|
||||||
|
|
||||||
export default class DocLabel extends React.Component {
|
export default class FieldDocLabel extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
label: PropTypes.oneOfType([
|
label: PropTypes.oneOfType([
|
||||||
PropTypes.object,
|
PropTypes.object,
|
|
@ -1,16 +1,16 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import StringInput from './StringInput'
|
import FieldString from './FieldString'
|
||||||
import NumberInput from './NumberInput'
|
import FieldNumber from './FieldNumber'
|
||||||
import Button from '../Button'
|
import Button from './Button'
|
||||||
import {MdDelete} from 'react-icons/md'
|
import {MdDelete} from 'react-icons/md'
|
||||||
import DocLabel from '../fields/DocLabel'
|
import FieldDocLabel from './FieldDocLabel'
|
||||||
import EnumInput from '../inputs/SelectInput'
|
import FieldEnum from './FieldEnum'
|
||||||
import capitalize from 'lodash.capitalize'
|
import capitalize from 'lodash.capitalize'
|
||||||
import UrlInput from '../inputs/UrlInput'
|
import FieldUrl from './FieldUrl'
|
||||||
|
|
||||||
|
|
||||||
class DynamicArrayInput extends React.Component {
|
export default class FieldDynamicArray extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
value: PropTypes.array,
|
value: PropTypes.array,
|
||||||
type: PropTypes.string,
|
type: PropTypes.string,
|
||||||
|
@ -62,13 +62,13 @@ class DynamicArrayInput extends React.Component {
|
||||||
const deleteValueBtn= <DeleteValueButton onClick={this.deleteValue.bind(this, i)} />
|
const deleteValueBtn= <DeleteValueButton onClick={this.deleteValue.bind(this, i)} />
|
||||||
let input;
|
let input;
|
||||||
if(this.props.type === 'url') {
|
if(this.props.type === 'url') {
|
||||||
input = <UrlInput
|
input = <FieldUrl
|
||||||
value={v}
|
value={v}
|
||||||
onChange={this.changeValue.bind(this, i)}
|
onChange={this.changeValue.bind(this, i)}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
else if (this.props.type === 'number') {
|
else if (this.props.type === 'number') {
|
||||||
input = <NumberInput
|
input = <FieldNumber
|
||||||
value={v}
|
value={v}
|
||||||
onChange={this.changeValue.bind(this, i)}
|
onChange={this.changeValue.bind(this, i)}
|
||||||
/>
|
/>
|
||||||
|
@ -76,14 +76,14 @@ class DynamicArrayInput extends React.Component {
|
||||||
else if (this.props.type === 'enum') {
|
else if (this.props.type === 'enum') {
|
||||||
const options = Object.keys(this.props.fieldSpec.values).map(v => [v, capitalize(v)]);
|
const options = Object.keys(this.props.fieldSpec.values).map(v => [v, capitalize(v)]);
|
||||||
|
|
||||||
input = <EnumInput
|
input = <FieldEnum
|
||||||
options={options}
|
options={options}
|
||||||
value={v}
|
value={v}
|
||||||
onChange={this.changeValue.bind(this, i)}
|
onChange={this.changeValue.bind(this, i)}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
input = <StringInput
|
input = <FieldString
|
||||||
value={v}
|
value={v}
|
||||||
onChange={this.changeValue.bind(this, i)}
|
onChange={this.changeValue.bind(this, i)}
|
||||||
/>
|
/>
|
||||||
|
@ -126,7 +126,7 @@ class DeleteValueButton extends React.Component {
|
||||||
onClick={this.props.onClick}
|
onClick={this.props.onClick}
|
||||||
title="Remove array item"
|
title="Remove array item"
|
||||||
>
|
>
|
||||||
<DocLabel
|
<FieldDocLabel
|
||||||
label={<MdDelete />}
|
label={<MdDelete />}
|
||||||
doc={"Remove array item."}
|
doc={"Remove array item."}
|
||||||
/>
|
/>
|
||||||
|
@ -134,4 +134,3 @@ class DeleteValueButton extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default DynamicArrayInput
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import SelectInput from '../inputs/SelectInput'
|
import FieldSelect from './FieldSelect'
|
||||||
import MultiButtonInput from '../inputs/MultiButtonInput'
|
import FieldMultiInput from './FieldMultiInput'
|
||||||
|
|
||||||
|
|
||||||
function optionsLabelLength(options) {
|
function optionsLabelLength(options) {
|
||||||
|
@ -13,7 +13,7 @@ function optionsLabelLength(options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class EnumInput extends React.Component {
|
export default class FieldEnum extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
"data-wd-key": PropTypes.string,
|
"data-wd-key": PropTypes.string,
|
||||||
value: PropTypes.string,
|
value: PropTypes.string,
|
||||||
|
@ -28,14 +28,14 @@ class EnumInput extends React.Component {
|
||||||
const {options, value, onChange, name} = this.props;
|
const {options, value, onChange, name} = this.props;
|
||||||
|
|
||||||
if(options.length <= 3 && optionsLabelLength(options) <= 20) {
|
if(options.length <= 3 && optionsLabelLength(options) <= 20) {
|
||||||
return <MultiButtonInput
|
return <FieldMultiInput
|
||||||
name={name}
|
name={name}
|
||||||
options={options}
|
options={options}
|
||||||
value={value || this.props.default}
|
value={value || this.props.default}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
/>
|
/>
|
||||||
} else {
|
} else {
|
||||||
return <SelectInput
|
return <FieldSelect
|
||||||
options={options}
|
options={options}
|
||||||
value={value || this.props.default}
|
value={value || this.props.default}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
|
@ -43,5 +43,3 @@ class EnumInput extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default EnumInput
|
|
|
@ -1,8 +1,8 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import AutocompleteInput from './AutocompleteInput'
|
import FieldAutocomplete from './FieldAutocomplete'
|
||||||
|
|
||||||
class FontInput extends React.Component {
|
export default class FieldFont extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
value: PropTypes.array,
|
value: PropTypes.array,
|
||||||
default: PropTypes.array,
|
default: PropTypes.array,
|
||||||
|
@ -39,7 +39,7 @@ class FontInput extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const inputs = this.values.map((value, i) => {
|
const inputs = this.values.map((value, i) => {
|
||||||
return <AutocompleteInput
|
return <FieldAutocomplete
|
||||||
key={i}
|
key={i}
|
||||||
value={value}
|
value={value}
|
||||||
options={this.props.fonts.map(f => [f, f])}
|
options={this.props.fonts.map(f => [f, f])}
|
||||||
|
@ -53,4 +53,3 @@ class FontInput extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default FontInput
|
|
|
@ -106,7 +106,7 @@ function getDataType (value, fieldSpec={}) {
|
||||||
/** Supports displaying spec field for zoom function objects
|
/** Supports displaying spec field for zoom function objects
|
||||||
* https://www.mapbox.com/mapbox-gl-style-spec/#types-function-zoom-property
|
* https://www.mapbox.com/mapbox-gl-style-spec/#types-function-zoom-property
|
||||||
*/
|
*/
|
||||||
export default class FunctionSpecProperty extends React.Component {
|
export default class FieldFunction extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
fieldName: PropTypes.string.isRequired,
|
fieldName: PropTypes.string.isRequired,
|
|
@ -2,8 +2,8 @@ import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
|
||||||
import InputBlock from '../inputs/InputBlock'
|
import Block from './Block'
|
||||||
import StringInput from '../inputs/StringInput'
|
import FieldString from './FieldString'
|
||||||
import CodeMirror from 'codemirror';
|
import CodeMirror from 'codemirror';
|
||||||
|
|
||||||
import 'codemirror/mode/javascript/javascript'
|
import 'codemirror/mode/javascript/javascript'
|
||||||
|
@ -16,7 +16,7 @@ import stringifyPretty from 'json-stringify-pretty-compact'
|
||||||
import '../util/codemirror-mgl';
|
import '../util/codemirror-mgl';
|
||||||
|
|
||||||
|
|
||||||
class JSONEditor extends React.Component {
|
export default class FieldJsonEditor extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
layer: PropTypes.any.isRequired,
|
layer: PropTypes.any.isRequired,
|
||||||
maxHeight: PropTypes.number,
|
maxHeight: PropTypes.number,
|
||||||
|
@ -173,4 +173,3 @@ class JSONEditor extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default JSONEditor
|
|
|
@ -1,9 +1,9 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import Button from '../Button'
|
import Button from './Button'
|
||||||
|
|
||||||
class MultiButtonInput extends React.Component {
|
export default class FieldMultiInput extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
value: PropTypes.string.isRequired,
|
value: PropTypes.string.isRequired,
|
||||||
|
@ -39,4 +39,3 @@ class MultiButtonInput extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MultiButtonInput
|
|
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
|
||||||
|
|
||||||
let IDX = 0;
|
let IDX = 0;
|
||||||
|
|
||||||
class NumberInput extends React.Component {
|
export default class FieldNumber extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
value: PropTypes.number,
|
value: PropTypes.number,
|
||||||
default: PropTypes.number,
|
default: PropTypes.number,
|
||||||
|
@ -230,4 +230,3 @@ class NumberInput extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default NumberInput
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
class SelectInput extends React.Component {
|
export default class FieldSelect extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
value: PropTypes.string.isRequired,
|
value: PropTypes.string.isRequired,
|
||||||
"data-wd-key": PropTypes.string,
|
"data-wd-key": PropTypes.string,
|
||||||
|
@ -31,4 +31,3 @@ class SelectInput extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SelectInput
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
class StringInput extends React.Component {
|
export default class FieldString extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
"data-wd-key": PropTypes.string,
|
"data-wd-key": PropTypes.string,
|
||||||
value: PropTypes.string,
|
value: PropTypes.string,
|
||||||
|
@ -90,4 +90,3 @@ class StringInput extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default StringInput
|
|
|
@ -1,9 +1,9 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import AutocompleteInput from './AutocompleteInput'
|
import FieldAutocomplete from './FieldAutocomplete'
|
||||||
|
|
||||||
|
|
||||||
class IconInput extends React.Component {
|
export default class FieldSymbol extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
value: PropTypes.string,
|
value: PropTypes.string,
|
||||||
icons: PropTypes.array,
|
icons: PropTypes.array,
|
||||||
|
@ -16,7 +16,7 @@ class IconInput extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <AutocompleteInput
|
return <FieldAutocomplete
|
||||||
value={this.props.value}
|
value={this.props.value}
|
||||||
options={this.props.icons.map(f => [f, f])}
|
options={this.props.icons.map(f => [f, f])}
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
|
@ -25,4 +25,3 @@ class IconInput extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default IconInput
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React, {Fragment} from 'react'
|
import React, {Fragment} from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import StringInput from './StringInput'
|
import FieldString from './FieldString'
|
||||||
import SmallError from '../util/SmallError'
|
import SmallError from './SmallError'
|
||||||
|
|
||||||
|
|
||||||
function validate (url) {
|
function validate (url) {
|
||||||
|
@ -48,7 +48,7 @@ function validate (url) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
class UrlInput extends React.Component {
|
export default class FieldUrl extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
"data-wd-key": PropTypes.string,
|
"data-wd-key": PropTypes.string,
|
||||||
value: PropTypes.string,
|
value: PropTypes.string,
|
||||||
|
@ -88,7 +88,7 @@ class UrlInput extends React.Component {
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<StringInput
|
<FieldString
|
||||||
{...this.props}
|
{...this.props}
|
||||||
onInput={this.onInput}
|
onInput={this.onInput}
|
||||||
onChange={this.onChange}
|
onChange={this.onChange}
|
||||||
|
@ -99,4 +99,3 @@ class UrlInput extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default UrlInput
|
|
|
@ -1,17 +1,16 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import { combiningFilterOps } from '../../libs/filterops.js'
|
import { combiningFilterOps } from '../libs/filterops.js'
|
||||||
import {mdiTableRowPlusAfter} from '@mdi/js';
|
import {mdiTableRowPlusAfter} from '@mdi/js';
|
||||||
|
|
||||||
import {latest, validate, migrate} from '@mapbox/mapbox-gl-style-spec'
|
import {latest, validate, migrate} from '@mapbox/mapbox-gl-style-spec'
|
||||||
import DocLabel from '../fields/DocLabel'
|
import FieldSelect from './FieldSelect'
|
||||||
import SelectInput from '../inputs/SelectInput'
|
import Block from './Block'
|
||||||
import InputBlock from '../inputs/InputBlock'
|
|
||||||
import SingleFilterEditor from './SingleFilterEditor'
|
import SingleFilterEditor from './SingleFilterEditor'
|
||||||
import FilterEditorBlock from './FilterEditorBlock'
|
import FilterEditorBlock from './FilterEditorBlock'
|
||||||
import Button from '../Button'
|
import Button from './Button'
|
||||||
import SpecDoc from '../inputs/SpecDoc'
|
import Doc from './Doc'
|
||||||
import ExpressionProperty from '../fields/_ExpressionProperty';
|
import ExpressionProperty from './_ExpressionProperty';
|
||||||
import {mdiFunctionVariant} from '@mdi/js';
|
import {mdiFunctionVariant} from '@mdi/js';
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,7 +93,7 @@ function hasNestedCombiningFilter(filter) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class CombiningFilterEditor extends React.Component {
|
export default class FilterEditor extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
/** Properties of the vector layer and the available fields */
|
/** Properties of the vector layer and the available fields */
|
||||||
properties: PropTypes.object,
|
properties: PropTypes.object,
|
||||||
|
@ -244,18 +243,18 @@ export default class CombiningFilterEditor extends React.Component {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<InputBlock
|
<Block
|
||||||
key="top"
|
key="top"
|
||||||
fieldSpec={fieldSpec}
|
fieldSpec={fieldSpec}
|
||||||
label={"Filter"}
|
label={"Filter"}
|
||||||
action={actions}
|
action={actions}
|
||||||
>
|
>
|
||||||
<SelectInput
|
<FieldSelect
|
||||||
value={combiningOp}
|
value={combiningOp}
|
||||||
onChange={this.onFilterPartChanged.bind(this, 0)}
|
onChange={this.onFilterPartChanged.bind(this, 0)}
|
||||||
options={[["all", "every filter matches"], ["none", "no filter matches"], ["any", "any filter matches"]]}
|
options={[["all", "every filter matches"], ["none", "no filter matches"], ["any", "any filter matches"]]}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
{editorBlocks}
|
{editorBlocks}
|
||||||
<div
|
<div
|
||||||
key="buttons"
|
key="buttons"
|
||||||
|
@ -276,7 +275,7 @@ export default class CombiningFilterEditor extends React.Component {
|
||||||
className="maputnik-doc-inline"
|
className="maputnik-doc-inline"
|
||||||
style={{display: this.state.showDoc ? '' : 'none'}}
|
style={{display: this.state.showDoc ? '' : 'none'}}
|
||||||
>
|
>
|
||||||
<SpecDoc fieldSpec={fieldSpec} />
|
<Doc fieldSpec={fieldSpec} />
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
|
@ -1,9 +1,9 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import Button from '../Button'
|
import Button from './Button'
|
||||||
import {MdDelete} from 'react-icons/md'
|
import {MdDelete} from 'react-icons/md'
|
||||||
|
|
||||||
class FilterEditorBlock extends React.Component {
|
export default class FilterEditorBlock extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
onDelete: PropTypes.func.isRequired,
|
onDelete: PropTypes.func.isRequired,
|
||||||
children: PropTypes.element.isRequired,
|
children: PropTypes.element.isRequired,
|
||||||
|
@ -27,4 +27,3 @@ class FilterEditorBlock extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default FilterEditorBlock
|
|
|
@ -2,7 +2,7 @@ import React from 'react'
|
||||||
import IconBase from 'react-icon-base'
|
import IconBase from 'react-icon-base'
|
||||||
|
|
||||||
|
|
||||||
export default class BackgroundIcon extends React.Component {
|
export default class IconBackground extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<IconBase viewBox="0 0 20 20" {...this.props}>
|
<IconBase viewBox="0 0 20 20" {...this.props}>
|
|
@ -2,7 +2,7 @@ import React from 'react'
|
||||||
import IconBase from 'react-icon-base'
|
import IconBase from 'react-icon-base'
|
||||||
|
|
||||||
|
|
||||||
export default class FillIcon extends React.Component {
|
export default class IconCircle extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<IconBase viewBox="0 0 20 20" {...this.props}>
|
<IconBase viewBox="0 0 20 20" {...this.props}>
|
|
@ -2,7 +2,7 @@ import React from 'react'
|
||||||
import IconBase from 'react-icon-base'
|
import IconBase from 'react-icon-base'
|
||||||
|
|
||||||
|
|
||||||
export default class FillIcon extends React.Component {
|
export default class IconFill extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<IconBase viewBox="0 0 20 20" {...this.props}>
|
<IconBase viewBox="0 0 20 20" {...this.props}>
|
33
src/components/IconLayer.jsx
Normal file
33
src/components/IconLayer.jsx
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import React from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
|
import IconLine from './IconLine.jsx'
|
||||||
|
import IconFill from './IconFill.jsx'
|
||||||
|
import IconSymbol from './IconSymbol.jsx'
|
||||||
|
import IconBackground from './IconBackground.jsx'
|
||||||
|
import IconCircle from './IconCircle.jsx'
|
||||||
|
import IconMissing from './IconMissing.jsx'
|
||||||
|
|
||||||
|
export default class IconLayer extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
type: PropTypes.string.isRequired,
|
||||||
|
style: PropTypes.object,
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const iconProps = { style: this.props.style }
|
||||||
|
switch(this.props.type) {
|
||||||
|
case 'fill-extrusion': return <IconBackground {...iconProps} />
|
||||||
|
case 'raster': return <IconFill {...iconProps} />
|
||||||
|
case 'hillshade': return <IconFill {...iconProps} />
|
||||||
|
case 'heatmap': return <IconFill {...iconProps} />
|
||||||
|
case 'fill': return <IconFill {...iconProps} />
|
||||||
|
case 'background': return <IconBackground {...iconProps} />
|
||||||
|
case 'line': return <IconLine {...iconProps} />
|
||||||
|
case 'symbol': return <IconSymbol {...iconProps} />
|
||||||
|
case 'circle': return <IconCircle {...iconProps} />
|
||||||
|
default: return <IconMissing {...iconProps} />
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react'
|
||||||
import IconBase from 'react-icon-base'
|
import IconBase from 'react-icon-base'
|
||||||
|
|
||||||
|
|
||||||
export default class FillIcon extends React.Component {
|
export default class IconLine extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<IconBase viewBox="0 0 20 20" {...this.props}>
|
<IconBase viewBox="0 0 20 20" {...this.props}>
|
|
@ -2,7 +2,7 @@ import React from 'react'
|
||||||
import {MdPriorityHigh} from 'react-icons/md'
|
import {MdPriorityHigh} from 'react-icons/md'
|
||||||
|
|
||||||
|
|
||||||
export default class MissingIcon extends React.Component {
|
export default class IconMissing extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<MdPriorityHigh {...this.props} />
|
<MdPriorityHigh {...this.props} />
|
|
@ -2,7 +2,7 @@ import React from 'react'
|
||||||
import IconBase from 'react-icon-base'
|
import IconBase from 'react-icon-base'
|
||||||
|
|
||||||
|
|
||||||
export default class SymbolIcon extends React.Component {
|
export default class IconSymbol extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<IconBase viewBox="0 0 20 20" {...this.props}>
|
<IconBase viewBox="0 0 20 20" {...this.props}>
|
|
@ -2,23 +2,23 @@ import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import { Wrapper, Button, Menu, MenuItem } from 'react-aria-menubutton'
|
import { Wrapper, Button, Menu, MenuItem } from 'react-aria-menubutton'
|
||||||
|
|
||||||
import JSONEditor from './JSONEditor'
|
import FieldJsonEditor from './FieldJsonEditor'
|
||||||
import FilterEditor from '../filter/FilterEditor'
|
import FilterEditor from './FilterEditor'
|
||||||
import PropertyGroup from '../fields/PropertyGroup'
|
import PropertyGroup from './PropertyGroup'
|
||||||
import LayerEditorGroup from './LayerEditorGroup'
|
import LayerEditorGroup from './LayerEditorGroup'
|
||||||
import LayerTypeBlock from './LayerTypeBlock'
|
import BlockType from './BlockType'
|
||||||
import LayerIdBlock from './LayerIdBlock'
|
import BlockId from './BlockId'
|
||||||
import MinZoomBlock from './MinZoomBlock'
|
import BlockMinZoom from './BlockMinZoom'
|
||||||
import MaxZoomBlock from './MaxZoomBlock'
|
import BlockMaxZoom from './BlockMaxZoom'
|
||||||
import CommentBlock from './CommentBlock'
|
import BlockComment from './BlockComment'
|
||||||
import LayerSourceBlock from './LayerSourceBlock'
|
import BlockSource from './BlockSource'
|
||||||
import LayerSourceLayerBlock from './LayerSourceLayerBlock'
|
import BlockSourceLayer from './BlockSourceLayer'
|
||||||
import {Accordion} from 'react-accessible-accordion';
|
import {Accordion} from 'react-accessible-accordion';
|
||||||
|
|
||||||
import {MdMoreVert} from 'react-icons/md'
|
import {MdMoreVert} from 'react-icons/md'
|
||||||
|
|
||||||
import { changeType, changeProperty } from '../../libs/layer'
|
import { changeType, changeProperty } from '../libs/layer'
|
||||||
import layout from '../../config/layout.json'
|
import layout from '../config/layout.json'
|
||||||
import {formatLayerId} from '../util/format';
|
import {formatLayerId} from '../util/format';
|
||||||
|
|
||||||
|
|
||||||
|
@ -152,13 +152,13 @@ export default class LayerEditor extends React.Component {
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case 'layer': return <div>
|
case 'layer': return <div>
|
||||||
<LayerIdBlock
|
<BlockId
|
||||||
value={this.props.layer.id}
|
value={this.props.layer.id}
|
||||||
wdKey="layer-editor.layer-id"
|
wdKey="layer-editor.layer-id"
|
||||||
error={errorData.id}
|
error={errorData.id}
|
||||||
onChange={newId => this.props.onLayerIdChange(this.props.layerIndex, this.props.layer.id, newId)}
|
onChange={newId => this.props.onLayerIdChange(this.props.layerIndex, this.props.layer.id, newId)}
|
||||||
/>
|
/>
|
||||||
<LayerTypeBlock
|
<BlockType
|
||||||
disabled={true}
|
disabled={true}
|
||||||
error={errorData.type}
|
error={errorData.type}
|
||||||
value={this.props.layer.type}
|
value={this.props.layer.type}
|
||||||
|
@ -167,7 +167,7 @@ export default class LayerEditor extends React.Component {
|
||||||
changeType(this.props.layer, newType)
|
changeType(this.props.layer, newType)
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
{this.props.layer.type !== 'background' && <LayerSourceBlock
|
{this.props.layer.type !== 'background' && <BlockSource
|
||||||
error={errorData.source}
|
error={errorData.source}
|
||||||
sourceIds={Object.keys(this.props.sources)}
|
sourceIds={Object.keys(this.props.sources)}
|
||||||
value={this.props.layer.source}
|
value={this.props.layer.source}
|
||||||
|
@ -175,24 +175,24 @@ export default class LayerEditor extends React.Component {
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
{['background', 'raster', 'hillshade', 'heatmap'].indexOf(this.props.layer.type) < 0 &&
|
{['background', 'raster', 'hillshade', 'heatmap'].indexOf(this.props.layer.type) < 0 &&
|
||||||
<LayerSourceLayerBlock
|
<BlockSourceLayer
|
||||||
error={errorData['source-layer']}
|
error={errorData['source-layer']}
|
||||||
sourceLayerIds={sourceLayerIds}
|
sourceLayerIds={sourceLayerIds}
|
||||||
value={this.props.layer['source-layer']}
|
value={this.props.layer['source-layer']}
|
||||||
onChange={v => this.changeProperty(null, 'source-layer', v)}
|
onChange={v => this.changeProperty(null, 'source-layer', v)}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
<MinZoomBlock
|
<BlockMinZoom
|
||||||
error={errorData.minzoom}
|
error={errorData.minzoom}
|
||||||
value={this.props.layer.minzoom}
|
value={this.props.layer.minzoom}
|
||||||
onChange={v => this.changeProperty(null, 'minzoom', v)}
|
onChange={v => this.changeProperty(null, 'minzoom', v)}
|
||||||
/>
|
/>
|
||||||
<MaxZoomBlock
|
<BlockMaxZoom
|
||||||
error={errorData.maxzoom}
|
error={errorData.maxzoom}
|
||||||
value={this.props.layer.maxzoom}
|
value={this.props.layer.maxzoom}
|
||||||
onChange={v => this.changeProperty(null, 'maxzoom', v)}
|
onChange={v => this.changeProperty(null, 'maxzoom', v)}
|
||||||
/>
|
/>
|
||||||
<CommentBlock
|
<BlockComment
|
||||||
error={errorData.comment}
|
error={errorData.comment}
|
||||||
value={comment}
|
value={comment}
|
||||||
onChange={v => this.changeProperty('metadata', 'maputnik:comment', v == "" ? undefined : v)}
|
onChange={v => this.changeProperty('metadata', 'maputnik:comment', v == "" ? undefined : v)}
|
||||||
|
@ -215,7 +215,7 @@ export default class LayerEditor extends React.Component {
|
||||||
spec={this.props.spec}
|
spec={this.props.spec}
|
||||||
onChange={this.changeProperty.bind(this)}
|
onChange={this.changeProperty.bind(this)}
|
||||||
/>
|
/>
|
||||||
case 'jsoneditor': return <JSONEditor
|
case 'jsoneditor': return <FieldJsonEditor
|
||||||
layer={this.props.layer}
|
layer={this.props.layer}
|
||||||
onChange={(layer) => {
|
onChange={(layer) => {
|
||||||
this.props.onLayerChanged(
|
this.props.onLayerChanged(
|
|
@ -5,7 +5,7 @@ import lodash from 'lodash';
|
||||||
|
|
||||||
import LayerListGroup from './LayerListGroup'
|
import LayerListGroup from './LayerListGroup'
|
||||||
import LayerListItem from './LayerListItem'
|
import LayerListItem from './LayerListItem'
|
||||||
import AddModal from '../modals/AddModal'
|
import ModalAdd from './ModalAdd'
|
||||||
|
|
||||||
import {SortableContainer} from 'react-sortable-hoc';
|
import {SortableContainer} from 'react-sortable-hoc';
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ class LayerListContainer extends React.Component {
|
||||||
aria-label="Layers list"
|
aria-label="Layers list"
|
||||||
ref={this.scrollContainerRef}
|
ref={this.scrollContainerRef}
|
||||||
>
|
>
|
||||||
<AddModal
|
<ModalAdd
|
||||||
key={this.state.keys.add}
|
key={this.state.keys.add}
|
||||||
layers={this.props.layers}
|
layers={this.props.layers}
|
||||||
sources={this.props.sources}
|
sources={this.props.sources}
|
|
@ -4,13 +4,13 @@ import classnames from 'classnames'
|
||||||
|
|
||||||
import {MdContentCopy, MdVisibility, MdVisibilityOff, MdDelete} from 'react-icons/md'
|
import {MdContentCopy, MdVisibility, MdVisibilityOff, MdDelete} from 'react-icons/md'
|
||||||
|
|
||||||
import LayerIcon from '../icons/LayerIcon'
|
import IconLayer from './IconLayer'
|
||||||
import {SortableElement, SortableHandle} from 'react-sortable-hoc'
|
import {SortableElement, SortableHandle} from 'react-sortable-hoc'
|
||||||
|
|
||||||
|
|
||||||
const DraggableLabel = SortableHandle((props) => {
|
const DraggableLabel = SortableHandle((props) => {
|
||||||
return <div className="maputnik-layer-list-item-handle">
|
return <div className="maputnik-layer-list-item-handle">
|
||||||
<LayerIcon
|
<IconLayer
|
||||||
className="layer-handle__icon"
|
className="layer-handle__icon"
|
||||||
type={props.layerType}
|
type={props.layerType}
|
||||||
/>
|
/>
|
|
@ -3,16 +3,16 @@ import PropTypes from 'prop-types'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import MapboxGl from 'mapbox-gl'
|
import MapboxGl from 'mapbox-gl'
|
||||||
import MapboxInspect from 'mapbox-gl-inspect'
|
import MapboxInspect from 'mapbox-gl-inspect'
|
||||||
import FeatureLayerPopup from './FeatureLayerPopup'
|
import MapMapboxGlLayerPopup from './MapMapboxGlLayerPopup'
|
||||||
import FeaturePropertyPopup from './FeaturePropertyPopup'
|
import MapMapboxGlFeaturePropertyPopup from './MapMapboxGlFeaturePropertyPopup'
|
||||||
import tokens from '../../config/tokens.json'
|
import tokens from '../config/tokens.json'
|
||||||
import colors from 'mapbox-gl-inspect/lib/colors'
|
import colors from 'mapbox-gl-inspect/lib/colors'
|
||||||
import Color from 'color'
|
import Color from 'color'
|
||||||
import ZoomControl from '../../libs/zoomcontrol'
|
import ZoomControl from '../libs/zoomcontrol'
|
||||||
import { colorHighlightedLayer } from '../../libs/highlight'
|
import { colorHighlightedLayer } from '../libs/highlight'
|
||||||
import 'mapbox-gl/dist/mapbox-gl.css'
|
import 'mapbox-gl/dist/mapbox-gl.css'
|
||||||
import '../../mapboxgl.css'
|
import '../mapboxgl.css'
|
||||||
import '../../libs/mapbox-rtl'
|
import '../libs/mapbox-rtl'
|
||||||
|
|
||||||
|
|
||||||
const IS_SUPPORTED = MapboxGl.supported();
|
const IS_SUPPORTED = MapboxGl.supported();
|
||||||
|
@ -52,7 +52,7 @@ function buildInspectStyle(originalMapStyle, coloredLayers, highlightedLayer) {
|
||||||
return inspectStyle
|
return inspectStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class MapboxGlMap extends React.Component {
|
export default class MapMapboxGl extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
onDataChange: PropTypes.func,
|
onDataChange: PropTypes.func,
|
||||||
onLayerSelect: PropTypes.func.isRequired,
|
onLayerSelect: PropTypes.func.isRequired,
|
||||||
|
@ -175,9 +175,9 @@ export default class MapboxGlMap extends React.Component {
|
||||||
buildInspectStyle: (originalMapStyle, coloredLayers) => buildInspectStyle(originalMapStyle, coloredLayers, this.props.highlightedLayer),
|
buildInspectStyle: (originalMapStyle, coloredLayers) => buildInspectStyle(originalMapStyle, coloredLayers, this.props.highlightedLayer),
|
||||||
renderPopup: features => {
|
renderPopup: features => {
|
||||||
if(this.props.inspectModeEnabled) {
|
if(this.props.inspectModeEnabled) {
|
||||||
return renderPopup(<FeaturePropertyPopup features={features} />, tmpNode);
|
return renderPopup(<MapMapboxGlFeaturePropertyPopup features={features} />, tmpNode);
|
||||||
} else {
|
} else {
|
||||||
return renderPopup(<FeatureLayerPopup features={features} onLayerSelect={this.onLayerSelectById} zoom={this.state.zoom} />, tmpNode);
|
return renderPopup(<MapMapboxGlLayerPopup features={features} onLayerSelect={this.onLayerSelectById} zoom={this.state.zoom} />, tmpNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import InputBlock from '../inputs/InputBlock'
|
import Block from './Block'
|
||||||
import StringInput from '../inputs/StringInput'
|
import FieldString from './FieldString'
|
||||||
|
|
||||||
function displayValue(value) {
|
function displayValue(value) {
|
||||||
if (typeof value === 'undefined' || value === null) return value;
|
if (typeof value === 'undefined' || value === null) return value;
|
||||||
|
@ -15,24 +15,24 @@ function displayValue(value) {
|
||||||
function renderProperties(feature) {
|
function renderProperties(feature) {
|
||||||
return Object.keys(feature.properties).map(propertyName => {
|
return Object.keys(feature.properties).map(propertyName => {
|
||||||
const property = feature.properties[propertyName]
|
const property = feature.properties[propertyName]
|
||||||
return <InputBlock key={propertyName} label={propertyName}>
|
return <Block key={propertyName} label={propertyName}>
|
||||||
<StringInput value={displayValue(property)} style={{backgroundColor: 'transparent'}}/>
|
<FieldString value={displayValue(property)} style={{backgroundColor: 'transparent'}}/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderFeatureId(feature) {
|
function renderFeatureId(feature) {
|
||||||
return <InputBlock key={"feature-id"} label={"feature_id"}>
|
return <Block key={"feature-id"} label={"feature_id"}>
|
||||||
<StringInput value={displayValue(feature.id)} style={{backgroundColor: 'transparent'}} />
|
<FieldString value={displayValue(feature.id)} style={{backgroundColor: 'transparent'}} />
|
||||||
</InputBlock>
|
</Block>
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderFeature(feature, idx) {
|
function renderFeature(feature, idx) {
|
||||||
return <div key={`${feature.sourceLayer}-${idx}`}>
|
return <div key={`${feature.sourceLayer}-${idx}`}>
|
||||||
<div className="maputnik-popup-layer-id">{feature.layer['source']}: {feature.layer['source-layer']}{feature.inspectModeCounter && <span> × {feature.inspectModeCounter}</span>}</div>
|
<div className="maputnik-popup-layer-id">{feature.layer['source']}: {feature.layer['source-layer']}{feature.inspectModeCounter && <span> × {feature.inspectModeCounter}</span>}</div>
|
||||||
<InputBlock key={"property-type"} label={"$type"}>
|
<Block key={"property-type"} label={"$type"}>
|
||||||
<StringInput value={feature.geometry.type} style={{backgroundColor: 'transparent'}} />
|
<FieldString value={feature.geometry.type} style={{backgroundColor: 'transparent'}} />
|
||||||
</InputBlock>
|
</Block>
|
||||||
{renderFeatureId(feature)}
|
{renderFeatureId(feature)}
|
||||||
{renderProperties(feature)}
|
{renderProperties(feature)}
|
||||||
</div>
|
</div>
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import LayerIcon from '../icons/LayerIcon'
|
import IconLayer from './IconLayer'
|
||||||
import {latest, expression, function as styleFunction} from '@mapbox/mapbox-gl-style-spec'
|
import {latest, expression, function as styleFunction} from '@mapbox/mapbox-gl-style-spec'
|
||||||
|
|
||||||
function groupFeaturesBySourceLayer(features) {
|
function groupFeaturesBySourceLayer(features) {
|
||||||
|
@ -96,7 +96,7 @@ class FeatureLayerPopup extends React.Component {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{feature.layer.type &&
|
{feature.layer.type &&
|
||||||
<LayerIcon type={feature.layer.type} style={{
|
<IconLayer type={feature.layer.type} style={{
|
||||||
width: 14,
|
width: 14,
|
||||||
height: 14,
|
height: 14,
|
||||||
paddingRight: 3
|
paddingRight: 3
|
|
@ -1,9 +1,9 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {throttle} from 'lodash';
|
import {throttle} from 'lodash';
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import { loadJSON } from '../../libs/urlopen'
|
import { loadJSON } from '../libs/urlopen'
|
||||||
|
|
||||||
import FeatureLayerPopup from './FeatureLayerPopup';
|
import MapMapboxGlLayerPopup from './MapMapboxGlLayerPopup';
|
||||||
|
|
||||||
import 'ol/ol.css'
|
import 'ol/ol.css'
|
||||||
import {apply} from 'ol-mapbox-style';
|
import {apply} from 'ol-mapbox-style';
|
||||||
|
@ -24,7 +24,7 @@ function renderCoords (coords) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class OpenLayersMap extends React.Component {
|
export default class MapOpenLayers extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
onDataChange: PropTypes.func,
|
onDataChange: PropTypes.func,
|
||||||
mapStyle: PropTypes.object.isRequired,
|
mapStyle: PropTypes.object.isRequired,
|
||||||
|
@ -152,7 +152,7 @@ export default class OpenLayersMap extends React.Component {
|
||||||
>
|
>
|
||||||
×
|
×
|
||||||
</button>
|
</button>
|
||||||
<FeatureLayerPopup
|
<MapMapboxGlLayerPopup
|
||||||
features={this.state.selectedFeatures || []}
|
features={this.state.selectedFeatures || []}
|
||||||
onLayerSelect={this.props.onLayerSelect}
|
onLayerSelect={this.props.onLayerSelect}
|
||||||
/>
|
/>
|
|
@ -5,7 +5,7 @@ import AriaModal from 'react-aria-modal'
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
|
||||||
|
|
||||||
class Modal extends React.Component {
|
export default class Modal extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
"data-wd-key": PropTypes.string,
|
"data-wd-key": PropTypes.string,
|
||||||
isOpen: PropTypes.bool.isRequired,
|
isOpen: PropTypes.bool.isRequired,
|
||||||
|
@ -73,4 +73,3 @@ class Modal extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Modal
|
|
|
@ -1,15 +1,15 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import Button from '../Button'
|
import Button from './Button'
|
||||||
import Modal from './Modal'
|
import Modal from './Modal'
|
||||||
|
|
||||||
import LayerTypeBlock from '../layers/LayerTypeBlock'
|
import BlockType from './BlockType'
|
||||||
import LayerIdBlock from '../layers/LayerIdBlock'
|
import BlockId from './BlockId'
|
||||||
import LayerSourceBlock from '../layers/LayerSourceBlock'
|
import BlockSource from './BlockSource'
|
||||||
import LayerSourceLayerBlock from '../layers/LayerSourceLayerBlock'
|
import BlockSourceLayer from './BlockSourceLayer'
|
||||||
|
|
||||||
class AddModal extends React.Component {
|
export default class ModalAdd extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
layers: PropTypes.array.isRequired,
|
layers: PropTypes.array.isRequired,
|
||||||
onLayersChange: PropTypes.func.isRequired,
|
onLayersChange: PropTypes.func.isRequired,
|
||||||
|
@ -129,20 +129,20 @@ class AddModal extends React.Component {
|
||||||
className="maputnik-add-modal"
|
className="maputnik-add-modal"
|
||||||
>
|
>
|
||||||
<div className="maputnik-add-layer">
|
<div className="maputnik-add-layer">
|
||||||
<LayerIdBlock
|
<BlockId
|
||||||
value={this.state.id}
|
value={this.state.id}
|
||||||
wdKey="add-layer.layer-id"
|
wdKey="add-layer.layer-id"
|
||||||
onChange={v => {
|
onChange={v => {
|
||||||
this.setState({ id: v })
|
this.setState({ id: v })
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<LayerTypeBlock
|
<BlockType
|
||||||
value={this.state.type}
|
value={this.state.type}
|
||||||
wdKey="add-layer.layer-type"
|
wdKey="add-layer.layer-type"
|
||||||
onChange={v => this.setState({ type: v })}
|
onChange={v => this.setState({ type: v })}
|
||||||
/>
|
/>
|
||||||
{this.state.type !== 'background' &&
|
{this.state.type !== 'background' &&
|
||||||
<LayerSourceBlock
|
<BlockSource
|
||||||
sourceIds={sources}
|
sourceIds={sources}
|
||||||
wdKey="add-layer.layer-source-block"
|
wdKey="add-layer.layer-source-block"
|
||||||
value={this.state.source}
|
value={this.state.source}
|
||||||
|
@ -150,7 +150,7 @@ class AddModal extends React.Component {
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
{['background', 'raster', 'hillshade', 'heatmap'].indexOf(this.state.type) < 0 &&
|
{['background', 'raster', 'hillshade', 'heatmap'].indexOf(this.state.type) < 0 &&
|
||||||
<LayerSourceLayerBlock
|
<BlockSourceLayer
|
||||||
isFixed={true}
|
isFixed={true}
|
||||||
sourceLayerIds={layers}
|
sourceLayerIds={layers}
|
||||||
value={this.state['source-layer']}
|
value={this.state['source-layer']}
|
||||||
|
@ -169,4 +169,3 @@ class AddModal extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AddModal
|
|
|
@ -4,7 +4,7 @@ import PropTypes from 'prop-types'
|
||||||
import Modal from './Modal'
|
import Modal from './Modal'
|
||||||
|
|
||||||
|
|
||||||
class DebugModal extends React.Component {
|
export default class ModalDebug extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
isOpen: PropTypes.bool.isRequired,
|
isOpen: PropTypes.bool.isRequired,
|
||||||
renderer: PropTypes.string.isRequired,
|
renderer: PropTypes.string.isRequired,
|
||||||
|
@ -70,4 +70,3 @@ class DebugModal extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default DebugModal;
|
|
|
@ -4,18 +4,18 @@ import Slugify from 'slugify'
|
||||||
import { saveAs } from 'file-saver'
|
import { saveAs } from 'file-saver'
|
||||||
|
|
||||||
import {format} from '@mapbox/mapbox-gl-style-spec'
|
import {format} from '@mapbox/mapbox-gl-style-spec'
|
||||||
import InputBlock from '../inputs/InputBlock'
|
import Block from './Block'
|
||||||
import StringInput from '../inputs/StringInput'
|
import FieldString from './FieldString'
|
||||||
import CheckboxInput from '../inputs/CheckboxInput'
|
import FieldCheckbox from './FieldCheckbox'
|
||||||
import Button from '../Button'
|
import Button from './Button'
|
||||||
import Modal from './Modal'
|
import Modal from './Modal'
|
||||||
import {MdFileDownload} from 'react-icons/md'
|
import {MdFileDownload} from 'react-icons/md'
|
||||||
import style from '../../libs/style'
|
import style from '../libs/style'
|
||||||
import fieldSpecAdditional from '../../libs/field-spec-additional'
|
import fieldSpecAdditional from '../libs/field-spec-additional'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ExportModal extends React.Component {
|
export default class ModalExport extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
mapStyle: PropTypes.object.isRequired,
|
mapStyle: PropTypes.object.isRequired,
|
||||||
onStyleChanged: PropTypes.func.isRequired,
|
onStyleChanged: PropTypes.func.isRequired,
|
||||||
|
@ -75,33 +75,33 @@ class ExportModal extends React.Component {
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<InputBlock
|
<Block
|
||||||
label={fieldSpecAdditional.maputnik.mapbox_access_token.label}
|
label={fieldSpecAdditional.maputnik.mapbox_access_token.label}
|
||||||
fieldSpec={fieldSpecAdditional.maputnik.mapbox_access_token}
|
fieldSpec={fieldSpecAdditional.maputnik.mapbox_access_token}
|
||||||
>
|
>
|
||||||
<StringInput
|
<FieldString
|
||||||
value={(this.props.mapStyle.metadata || {})['maputnik:mapbox_access_token']}
|
value={(this.props.mapStyle.metadata || {})['maputnik:mapbox_access_token']}
|
||||||
onChange={this.changeMetadataProperty.bind(this, "maputnik:mapbox_access_token")}
|
onChange={this.changeMetadataProperty.bind(this, "maputnik:mapbox_access_token")}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
<InputBlock
|
<Block
|
||||||
label={fieldSpecAdditional.maputnik.maptiler_access_token.label}
|
label={fieldSpecAdditional.maputnik.maptiler_access_token.label}
|
||||||
fieldSpec={fieldSpecAdditional.maputnik.maptiler_access_token}
|
fieldSpec={fieldSpecAdditional.maputnik.maptiler_access_token}
|
||||||
>
|
>
|
||||||
<StringInput
|
<FieldString
|
||||||
value={(this.props.mapStyle.metadata || {})['maputnik:openmaptiles_access_token']}
|
value={(this.props.mapStyle.metadata || {})['maputnik:openmaptiles_access_token']}
|
||||||
onChange={this.changeMetadataProperty.bind(this, "maputnik:openmaptiles_access_token")}
|
onChange={this.changeMetadataProperty.bind(this, "maputnik:openmaptiles_access_token")}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
<InputBlock
|
<Block
|
||||||
label={fieldSpecAdditional.maputnik.thunderforest_access_token.label}
|
label={fieldSpecAdditional.maputnik.thunderforest_access_token.label}
|
||||||
fieldSpec={fieldSpecAdditional.maputnik.thunderforest_access_token}
|
fieldSpec={fieldSpecAdditional.maputnik.thunderforest_access_token}
|
||||||
>
|
>
|
||||||
<StringInput
|
<FieldString
|
||||||
value={(this.props.mapStyle.metadata || {})['maputnik:thunderforest_access_token']}
|
value={(this.props.mapStyle.metadata || {})['maputnik:thunderforest_access_token']}
|
||||||
onChange={this.changeMetadataProperty.bind(this, "maputnik:thunderforest_access_token")}
|
onChange={this.changeMetadataProperty.bind(this, "maputnik:thunderforest_access_token")}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
@ -117,4 +117,3 @@ class ExportModal extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ExportModal
|
|
|
@ -1,11 +1,11 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import Button from '../Button'
|
import Button from './Button'
|
||||||
import Modal from './Modal'
|
import Modal from './Modal'
|
||||||
|
|
||||||
|
|
||||||
class LoadingModal extends React.Component {
|
export default class ModalLoading extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
isOpen: PropTypes.bool.isRequired,
|
isOpen: PropTypes.bool.isRequired,
|
||||||
onCancel: PropTypes.func.isRequired,
|
onCancel: PropTypes.func.isRequired,
|
||||||
|
@ -42,4 +42,3 @@ class LoadingModal extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default LoadingModal
|
|
|
@ -1,16 +1,16 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import LoadingModal from './LoadingModal'
|
import ModalLoading from './ModalLoading'
|
||||||
import Modal from './Modal'
|
import Modal from './Modal'
|
||||||
import Button from '../Button'
|
import Button from './Button'
|
||||||
import FileReaderInput from 'react-file-reader-input'
|
import FileReaderInput from 'react-file-reader-input'
|
||||||
import UrlInput from '../inputs/UrlInput'
|
import FieldUrl from './FieldUrl'
|
||||||
|
|
||||||
import {MdFileUpload} from 'react-icons/md'
|
import {MdFileUpload} from 'react-icons/md'
|
||||||
import {MdAddCircleOutline} from 'react-icons/md'
|
import {MdAddCircleOutline} from 'react-icons/md'
|
||||||
|
|
||||||
import style from '../../libs/style.js'
|
import style from '../libs/style.js'
|
||||||
import publicStyles from '../../config/styles.json'
|
import publicStyles from '../config/styles.json'
|
||||||
|
|
||||||
class PublicStyle extends React.Component {
|
class PublicStyle extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
@ -43,7 +43,7 @@ class PublicStyle extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OpenModal extends React.Component {
|
export default class ModalOpen extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
isOpen: PropTypes.bool.isRequired,
|
isOpen: PropTypes.bool.isRequired,
|
||||||
onOpenToggle: PropTypes.func.isRequired,
|
onOpenToggle: PropTypes.func.isRequired,
|
||||||
|
@ -211,7 +211,7 @@ class OpenModal extends React.Component {
|
||||||
Load from a URL. Note that the URL must have <a href="https://enable-cors.org" target="_blank" rel="noopener noreferrer">CORS enabled</a>.
|
Load from a URL. Note that the URL must have <a href="https://enable-cors.org" target="_blank" rel="noopener noreferrer">CORS enabled</a>.
|
||||||
</p>
|
</p>
|
||||||
<form onSubmit={this.onSubmitUrl}>
|
<form onSubmit={this.onSubmitUrl}>
|
||||||
<UrlInput
|
<FieldUrl
|
||||||
data-wd-key="modal:open.url.input"
|
data-wd-key="modal:open.url.input"
|
||||||
type="text"
|
type="text"
|
||||||
className="maputnik-input"
|
className="maputnik-input"
|
||||||
|
@ -242,7 +242,7 @@ class OpenModal extends React.Component {
|
||||||
</section>
|
</section>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
<LoadingModal
|
<ModalLoading
|
||||||
isOpen={!!this.state.activeRequest}
|
isOpen={!!this.state.activeRequest}
|
||||||
title={'Loading style'}
|
title={'Loading style'}
|
||||||
onCancel={(e) => this.onCancelActiveRequest(e)}
|
onCancel={(e) => this.onCancelActiveRequest(e)}
|
||||||
|
@ -253,4 +253,3 @@ class OpenModal extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default OpenModal
|
|
|
@ -2,18 +2,18 @@ import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import {latest} from '@mapbox/mapbox-gl-style-spec'
|
import {latest} from '@mapbox/mapbox-gl-style-spec'
|
||||||
import InputBlock from '../inputs/InputBlock'
|
import Block from './Block'
|
||||||
import ArrayInput from '../inputs/ArrayInput'
|
import FieldArray from './FieldArray'
|
||||||
import NumberInput from '../inputs/NumberInput'
|
import FieldNumber from './FieldNumber'
|
||||||
import StringInput from '../inputs/StringInput'
|
import FieldString from './FieldString'
|
||||||
import UrlInput from '../inputs/UrlInput'
|
import FieldUrl from './FieldUrl'
|
||||||
import SelectInput from '../inputs/SelectInput'
|
import FieldSelect from './FieldSelect'
|
||||||
import EnumInput from '../inputs/EnumInput'
|
import FieldEnum from './FieldEnum'
|
||||||
import ColorField from '../fields/ColorField'
|
import FieldColor from './FieldColor'
|
||||||
import Modal from './Modal'
|
import Modal from './Modal'
|
||||||
import fieldSpecAdditional from '../../libs/field-spec-additional'
|
import fieldSpecAdditional from '../libs/field-spec-additional'
|
||||||
|
|
||||||
class SettingsModal extends React.Component {
|
export default class ModalSettings extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
mapStyle: PropTypes.object.isRequired,
|
mapStyle: PropTypes.object.isRequired,
|
||||||
onStyleChanged: PropTypes.func.isRequired,
|
onStyleChanged: PropTypes.func.isRequired,
|
||||||
|
@ -87,108 +87,108 @@ class SettingsModal extends React.Component {
|
||||||
title={'Style Settings'}
|
title={'Style Settings'}
|
||||||
>
|
>
|
||||||
<div className="modal:settings">
|
<div className="modal:settings">
|
||||||
<InputBlock label={"Name"} fieldSpec={latest.$root.name}>
|
<Block label={"Name"} fieldSpec={latest.$root.name}>
|
||||||
<StringInput {...inputProps}
|
<FieldString {...inputProps}
|
||||||
data-wd-key="modal:settings.name"
|
data-wd-key="modal:settings.name"
|
||||||
value={this.props.mapStyle.name}
|
value={this.props.mapStyle.name}
|
||||||
onChange={this.changeStyleProperty.bind(this, "name")}
|
onChange={this.changeStyleProperty.bind(this, "name")}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
<InputBlock label={"Owner"} fieldSpec={{doc: "Owner ID of the style. Used by Mapbox or future style APIs."}}>
|
<Block label={"Owner"} fieldSpec={{doc: "Owner ID of the style. Used by Mapbox or future style APIs."}}>
|
||||||
<StringInput {...inputProps}
|
<FieldString {...inputProps}
|
||||||
data-wd-key="modal:settings.owner"
|
data-wd-key="modal:settings.owner"
|
||||||
value={this.props.mapStyle.owner}
|
value={this.props.mapStyle.owner}
|
||||||
onChange={this.changeStyleProperty.bind(this, "owner")}
|
onChange={this.changeStyleProperty.bind(this, "owner")}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
<InputBlock label={"Sprite URL"} fieldSpec={latest.$root.sprite}>
|
<Block label={"Sprite URL"} fieldSpec={latest.$root.sprite}>
|
||||||
<UrlInput {...inputProps}
|
<FieldUrl {...inputProps}
|
||||||
data-wd-key="modal:settings.sprite"
|
data-wd-key="modal:settings.sprite"
|
||||||
value={this.props.mapStyle.sprite}
|
value={this.props.mapStyle.sprite}
|
||||||
onChange={this.changeStyleProperty.bind(this, "sprite")}
|
onChange={this.changeStyleProperty.bind(this, "sprite")}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
|
|
||||||
<InputBlock label={"Glyphs URL"} fieldSpec={latest.$root.glyphs}>
|
<Block label={"Glyphs URL"} fieldSpec={latest.$root.glyphs}>
|
||||||
<UrlInput {...inputProps}
|
<FieldUrl {...inputProps}
|
||||||
data-wd-key="modal:settings.glyphs"
|
data-wd-key="modal:settings.glyphs"
|
||||||
value={this.props.mapStyle.glyphs}
|
value={this.props.mapStyle.glyphs}
|
||||||
onChange={this.changeStyleProperty.bind(this, "glyphs")}
|
onChange={this.changeStyleProperty.bind(this, "glyphs")}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
|
|
||||||
<InputBlock
|
<Block
|
||||||
label={fieldSpecAdditional.maputnik.mapbox_access_token.label}
|
label={fieldSpecAdditional.maputnik.mapbox_access_token.label}
|
||||||
fieldSpec={fieldSpecAdditional.maputnik.mapbox_access_token}
|
fieldSpec={fieldSpecAdditional.maputnik.mapbox_access_token}
|
||||||
>
|
>
|
||||||
<StringInput {...inputProps}
|
<FieldString {...inputProps}
|
||||||
data-wd-key="modal:settings.maputnik:mapbox_access_token"
|
data-wd-key="modal:settings.maputnik:mapbox_access_token"
|
||||||
value={metadata['maputnik:mapbox_access_token']}
|
value={metadata['maputnik:mapbox_access_token']}
|
||||||
onChange={onChangeMetadataProperty.bind(this, "maputnik:mapbox_access_token")}
|
onChange={onChangeMetadataProperty.bind(this, "maputnik:mapbox_access_token")}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
|
|
||||||
<InputBlock
|
<Block
|
||||||
label={fieldSpecAdditional.maputnik.maptiler_access_token.label}
|
label={fieldSpecAdditional.maputnik.maptiler_access_token.label}
|
||||||
fieldSpec={fieldSpecAdditional.maputnik.maptiler_access_token}
|
fieldSpec={fieldSpecAdditional.maputnik.maptiler_access_token}
|
||||||
>
|
>
|
||||||
<StringInput {...inputProps}
|
<FieldString {...inputProps}
|
||||||
data-wd-key="modal:settings.maputnik:openmaptiles_access_token"
|
data-wd-key="modal:settings.maputnik:openmaptiles_access_token"
|
||||||
value={metadata['maputnik:openmaptiles_access_token']}
|
value={metadata['maputnik:openmaptiles_access_token']}
|
||||||
onChange={onChangeMetadataProperty.bind(this, "maputnik:openmaptiles_access_token")}
|
onChange={onChangeMetadataProperty.bind(this, "maputnik:openmaptiles_access_token")}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
|
|
||||||
<InputBlock
|
<Block
|
||||||
label={fieldSpecAdditional.maputnik.thunderforest_access_token.label}
|
label={fieldSpecAdditional.maputnik.thunderforest_access_token.label}
|
||||||
fieldSpec={fieldSpecAdditional.maputnik.thunderforest_access_token}
|
fieldSpec={fieldSpecAdditional.maputnik.thunderforest_access_token}
|
||||||
>
|
>
|
||||||
<StringInput {...inputProps}
|
<FieldString {...inputProps}
|
||||||
data-wd-key="modal:settings.maputnik:thunderforest_access_token"
|
data-wd-key="modal:settings.maputnik:thunderforest_access_token"
|
||||||
value={metadata['maputnik:thunderforest_access_token']}
|
value={metadata['maputnik:thunderforest_access_token']}
|
||||||
onChange={onChangeMetadataProperty.bind(this, "maputnik:thunderforest_access_token")}
|
onChange={onChangeMetadataProperty.bind(this, "maputnik:thunderforest_access_token")}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
|
|
||||||
<InputBlock label={"Center"} fieldSpec={latest.$root.center}>
|
<Block label={"Center"} fieldSpec={latest.$root.center}>
|
||||||
<ArrayInput
|
<FieldArray
|
||||||
length={2}
|
length={2}
|
||||||
type="number"
|
type="number"
|
||||||
value={mapStyle.center}
|
value={mapStyle.center}
|
||||||
default={latest.$root.center.default || [0, 0]}
|
default={latest.$root.center.default || [0, 0]}
|
||||||
onChange={this.changeStyleProperty.bind(this, "center")}
|
onChange={this.changeStyleProperty.bind(this, "center")}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
|
|
||||||
<InputBlock label={"Zoom"} fieldSpec={latest.$root.zoom}>
|
<Block label={"Zoom"} fieldSpec={latest.$root.zoom}>
|
||||||
<NumberInput
|
<FieldNumber
|
||||||
{...inputProps}
|
{...inputProps}
|
||||||
value={mapStyle.zoom}
|
value={mapStyle.zoom}
|
||||||
default={latest.$root.zoom.default || 0}
|
default={latest.$root.zoom.default || 0}
|
||||||
onChange={this.changeStyleProperty.bind(this, "zoom")}
|
onChange={this.changeStyleProperty.bind(this, "zoom")}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
|
|
||||||
<InputBlock label={"Bearing"} fieldSpec={latest.$root.bearing}>
|
<Block label={"Bearing"} fieldSpec={latest.$root.bearing}>
|
||||||
<NumberInput
|
<FieldNumber
|
||||||
{...inputProps}
|
{...inputProps}
|
||||||
value={mapStyle.bearing}
|
value={mapStyle.bearing}
|
||||||
default={latest.$root.bearing.default}
|
default={latest.$root.bearing.default}
|
||||||
onChange={this.changeStyleProperty.bind(this, "bearing")}
|
onChange={this.changeStyleProperty.bind(this, "bearing")}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
|
|
||||||
<InputBlock label={"Pitch"} fieldSpec={latest.$root.pitch}>
|
<Block label={"Pitch"} fieldSpec={latest.$root.pitch}>
|
||||||
<NumberInput
|
<FieldNumber
|
||||||
{...inputProps}
|
{...inputProps}
|
||||||
value={mapStyle.pitch}
|
value={mapStyle.pitch}
|
||||||
default={latest.$root.pitch.default}
|
default={latest.$root.pitch.default}
|
||||||
onChange={this.changeStyleProperty.bind(this, "pitch")}
|
onChange={this.changeStyleProperty.bind(this, "pitch")}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
|
|
||||||
<InputBlock label={"Light anchor"} fieldSpec={latest.light.anchor}>
|
<Block label={"Light anchor"} fieldSpec={latest.light.anchor}>
|
||||||
<EnumInput
|
<FieldEnum
|
||||||
{...inputProps}
|
{...inputProps}
|
||||||
name="light-anchor"
|
name="light-anchor"
|
||||||
value={light.anchor}
|
value={light.anchor}
|
||||||
|
@ -196,28 +196,28 @@ class SettingsModal extends React.Component {
|
||||||
default={latest.light.anchor.default}
|
default={latest.light.anchor.default}
|
||||||
onChange={this.changeLightProperty.bind(this, "anchor")}
|
onChange={this.changeLightProperty.bind(this, "anchor")}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
|
|
||||||
<InputBlock label={"Light color"} fieldSpec={latest.light.color}>
|
<Block label={"Light color"} fieldSpec={latest.light.color}>
|
||||||
<ColorField
|
<FieldColor
|
||||||
{...inputProps}
|
{...inputProps}
|
||||||
value={light.color}
|
value={light.color}
|
||||||
default={latest.light.color.default}
|
default={latest.light.color.default}
|
||||||
onChange={this.changeLightProperty.bind(this, "color")}
|
onChange={this.changeLightProperty.bind(this, "color")}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
|
|
||||||
<InputBlock label={"Light intensity"} fieldSpec={latest.light.intensity}>
|
<Block label={"Light intensity"} fieldSpec={latest.light.intensity}>
|
||||||
<NumberInput
|
<FieldNumber
|
||||||
{...inputProps}
|
{...inputProps}
|
||||||
value={light.intensity}
|
value={light.intensity}
|
||||||
default={latest.light.intensity.default}
|
default={latest.light.intensity.default}
|
||||||
onChange={this.changeLightProperty.bind(this, "intensity")}
|
onChange={this.changeLightProperty.bind(this, "intensity")}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
|
|
||||||
<InputBlock label={"Light position"} fieldSpec={latest.light.position}>
|
<Block label={"Light position"} fieldSpec={latest.light.position}>
|
||||||
<ArrayInput
|
<FieldArray
|
||||||
{...inputProps}
|
{...inputProps}
|
||||||
type="number"
|
type="number"
|
||||||
length={latest.light.position.length}
|
length={latest.light.position.length}
|
||||||
|
@ -225,31 +225,31 @@ class SettingsModal extends React.Component {
|
||||||
default={latest.light.position.default}
|
default={latest.light.position.default}
|
||||||
onChange={this.changeLightProperty.bind(this, "position")}
|
onChange={this.changeLightProperty.bind(this, "position")}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
|
|
||||||
<InputBlock label={"Transition delay"} fieldSpec={latest.transition.delay}>
|
<Block label={"Transition delay"} fieldSpec={latest.transition.delay}>
|
||||||
<NumberInput
|
<FieldNumber
|
||||||
{...inputProps}
|
{...inputProps}
|
||||||
value={transition.delay}
|
value={transition.delay}
|
||||||
default={latest.transition.delay.default}
|
default={latest.transition.delay.default}
|
||||||
onChange={this.changeTransitionProperty.bind(this, "delay")}
|
onChange={this.changeTransitionProperty.bind(this, "delay")}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
|
|
||||||
<InputBlock label={"Transition duration"} fieldSpec={latest.transition.duration}>
|
<Block label={"Transition duration"} fieldSpec={latest.transition.duration}>
|
||||||
<NumberInput
|
<FieldNumber
|
||||||
{...inputProps}
|
{...inputProps}
|
||||||
value={transition.duration}
|
value={transition.duration}
|
||||||
default={latest.transition.duration.default}
|
default={latest.transition.duration.default}
|
||||||
onChange={this.changeTransitionProperty.bind(this, "duration")}
|
onChange={this.changeTransitionProperty.bind(this, "duration")}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
|
|
||||||
<InputBlock
|
<Block
|
||||||
label={fieldSpecAdditional.maputnik.style_renderer.label}
|
label={fieldSpecAdditional.maputnik.style_renderer.label}
|
||||||
fieldSpec={fieldSpecAdditional.maputnik.style_renderer}
|
fieldSpec={fieldSpecAdditional.maputnik.style_renderer}
|
||||||
>
|
>
|
||||||
<SelectInput {...inputProps}
|
<FieldSelect {...inputProps}
|
||||||
data-wd-key="modal:settings.maputnik:renderer"
|
data-wd-key="modal:settings.maputnik:renderer"
|
||||||
options={[
|
options={[
|
||||||
['mbgljs', 'MapboxGL JS'],
|
['mbgljs', 'MapboxGL JS'],
|
||||||
|
@ -258,7 +258,7 @@ class SettingsModal extends React.Component {
|
||||||
value={metadata['maputnik:renderer'] || 'mbgljs'}
|
value={metadata['maputnik:renderer'] || 'mbgljs'}
|
||||||
onChange={onChangeMetadataProperty.bind(this, 'maputnik:renderer')}
|
onChange={onChangeMetadataProperty.bind(this, 'maputnik:renderer')}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -267,4 +267,3 @@ class SettingsModal extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SettingsModal
|
|
|
@ -4,7 +4,7 @@ import PropTypes from 'prop-types'
|
||||||
import Modal from './Modal'
|
import Modal from './Modal'
|
||||||
|
|
||||||
|
|
||||||
class ShortcutsModal extends React.Component {
|
export default class ModalShortcuts extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
isOpen: PropTypes.bool.isRequired,
|
isOpen: PropTypes.bool.isRequired,
|
||||||
onOpenToggle: PropTypes.func.isRequired,
|
onOpenToggle: PropTypes.func.isRequired,
|
||||||
|
@ -130,4 +130,3 @@ class ShortcutsModal extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ShortcutsModal
|
|
|
@ -2,15 +2,15 @@ import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import {latest} from '@mapbox/mapbox-gl-style-spec'
|
import {latest} from '@mapbox/mapbox-gl-style-spec'
|
||||||
import Modal from './Modal'
|
import Modal from './Modal'
|
||||||
import Button from '../Button'
|
import Button from './Button'
|
||||||
import InputBlock from '../inputs/InputBlock'
|
import Block from './Block'
|
||||||
import StringInput from '../inputs/StringInput'
|
import FieldString from './FieldString'
|
||||||
import SelectInput from '../inputs/SelectInput'
|
import FieldSelect from './FieldSelect'
|
||||||
import SourceTypeEditor from '../sources/SourceTypeEditor'
|
import ModalSourcesTypeEditor from './ModalSourcesTypeEditor'
|
||||||
|
|
||||||
import style from '../../libs/style'
|
import style from '../libs/style'
|
||||||
import { deleteSource, addSource, changeSource } from '../../libs/source'
|
import { deleteSource, addSource, changeSource } from '../libs/source'
|
||||||
import publicSources from '../../config/tilesets.json'
|
import publicSources from '../config/tilesets.json'
|
||||||
|
|
||||||
import {MdAddCircleOutline, MdDelete} from 'react-icons/md'
|
import {MdAddCircleOutline, MdDelete} from 'react-icons/md'
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ function editorMode(source) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
class ActiveSourceTypeEditor extends React.Component {
|
class ActiveModalSourcesTypeEditor extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
sourceId: PropTypes.string.isRequired,
|
sourceId: PropTypes.string.isRequired,
|
||||||
source: PropTypes.object.isRequired,
|
source: PropTypes.object.isRequired,
|
||||||
|
@ -92,7 +92,7 @@ class ActiveSourceTypeEditor extends React.Component {
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div className="maputnik-active-source-type-editor-content">
|
<div className="maputnik-active-source-type-editor-content">
|
||||||
<SourceTypeEditor
|
<ModalSourcesTypeEditor
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
mode={editorMode(this.props.source)}
|
mode={editorMode(this.props.source)}
|
||||||
source={this.props.source}
|
source={this.props.source}
|
||||||
|
@ -207,14 +207,14 @@ class AddSource extends React.Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
return <div className="maputnik-add-source">
|
return <div className="maputnik-add-source">
|
||||||
<InputBlock label={"Source ID"} fieldSpec={{doc: "Unique ID that identifies the source and is used in the layer to reference the source."}}>
|
<Block label={"Source ID"} fieldSpec={{doc: "Unique ID that identifies the source and is used in the layer to reference the source."}}>
|
||||||
<StringInput
|
<FieldString
|
||||||
value={this.state.sourceId}
|
value={this.state.sourceId}
|
||||||
onChange={v => this.setState({ sourceId: v})}
|
onChange={v => this.setState({ sourceId: v})}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
<InputBlock label={"Source Type"} fieldSpec={sourceTypeFieldSpec}>
|
<Block label={"Source Type"} fieldSpec={sourceTypeFieldSpec}>
|
||||||
<SelectInput
|
<FieldSelect
|
||||||
options={[
|
options={[
|
||||||
['geojson_json', 'GeoJSON (JSON)'],
|
['geojson_json', 'GeoJSON (JSON)'],
|
||||||
['geojson_url', 'GeoJSON (URL)'],
|
['geojson_url', 'GeoJSON (URL)'],
|
||||||
|
@ -230,8 +230,8 @@ class AddSource extends React.Component {
|
||||||
onChange={mode => this.setState({mode: mode, source: this.defaultSource(mode)})}
|
onChange={mode => this.setState({mode: mode, source: this.defaultSource(mode)})}
|
||||||
value={this.state.mode}
|
value={this.state.mode}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
<SourceTypeEditor
|
<ModalSourcesTypeEditor
|
||||||
onChange={this.onChangeSource}
|
onChange={this.onChangeSource}
|
||||||
mode={this.state.mode}
|
mode={this.state.mode}
|
||||||
source={this.state.source}
|
source={this.state.source}
|
||||||
|
@ -246,7 +246,7 @@ class AddSource extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SourcesModal extends React.Component {
|
export default class ModalSources extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
mapStyle: PropTypes.object.isRequired,
|
mapStyle: PropTypes.object.isRequired,
|
||||||
isOpen: PropTypes.bool.isRequired,
|
isOpen: PropTypes.bool.isRequired,
|
||||||
|
@ -264,7 +264,7 @@ class SourcesModal extends React.Component {
|
||||||
const mapStyle = this.props.mapStyle
|
const mapStyle = this.props.mapStyle
|
||||||
const activeSources = Object.keys(mapStyle.sources).map(sourceId => {
|
const activeSources = Object.keys(mapStyle.sources).map(sourceId => {
|
||||||
const source = mapStyle.sources[sourceId]
|
const source = mapStyle.sources[sourceId]
|
||||||
return <ActiveSourceTypeEditor
|
return <ActiveModalSourcesTypeEditor
|
||||||
key={sourceId}
|
key={sourceId}
|
||||||
sourceId={sourceId}
|
sourceId={sourceId}
|
||||||
source={source}
|
source={source}
|
||||||
|
@ -317,4 +317,3 @@ class SourcesModal extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SourcesModal
|
|
|
@ -1,14 +1,14 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import {latest} from '@mapbox/mapbox-gl-style-spec'
|
import {latest} from '@mapbox/mapbox-gl-style-spec'
|
||||||
import InputBlock from '../inputs/InputBlock'
|
import Block from './Block'
|
||||||
import StringInput from '../inputs/StringInput'
|
import FieldString from './FieldString'
|
||||||
import UrlInput from '../inputs/UrlInput'
|
import FieldUrl from './FieldUrl'
|
||||||
import NumberInput from '../inputs/NumberInput'
|
import FieldNumber from './FieldNumber'
|
||||||
import SelectInput from '../inputs/SelectInput'
|
import FieldSelect from './FieldSelect'
|
||||||
import DynamicArrayInput from '../inputs/DynamicArrayInput'
|
import FieldDynamicArray from './FieldDynamicArray'
|
||||||
import ArrayInput from '../inputs/ArrayInput'
|
import FieldArray from './FieldArray'
|
||||||
import JSONEditor from '../layers/JSONEditor'
|
import FieldJsonEditor from './FieldJsonEditor'
|
||||||
|
|
||||||
|
|
||||||
class TileJSONSourceEditor extends React.Component {
|
class TileJSONSourceEditor extends React.Component {
|
||||||
|
@ -20,15 +20,15 @@ class TileJSONSourceEditor extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <div>
|
return <div>
|
||||||
<InputBlock label={"TileJSON URL"} fieldSpec={latest.source_vector.url}>
|
<Block label={"TileJSON URL"} fieldSpec={latest.source_vector.url}>
|
||||||
<UrlInput
|
<FieldUrl
|
||||||
value={this.props.source.url}
|
value={this.props.source.url}
|
||||||
onChange={url => this.props.onChange({
|
onChange={url => this.props.onChange({
|
||||||
...this.props.source,
|
...this.props.source,
|
||||||
url: url
|
url: url
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@ -50,36 +50,36 @@ class TileURLSourceEditor extends React.Component {
|
||||||
|
|
||||||
renderTileUrls() {
|
renderTileUrls() {
|
||||||
const tiles = this.props.source.tiles || [];
|
const tiles = this.props.source.tiles || [];
|
||||||
return <InputBlock label={"Tile URL"} fieldSpec={latest.source_vector.tiles}>
|
return <Block label={"Tile URL"} fieldSpec={latest.source_vector.tiles}>
|
||||||
<DynamicArrayInput
|
<FieldDynamicArray
|
||||||
type="url"
|
type="url"
|
||||||
value={tiles}
|
value={tiles}
|
||||||
onChange={this.changeTileUrls.bind(this)}
|
onChange={this.changeTileUrls.bind(this)}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <div>
|
return <div>
|
||||||
{this.renderTileUrls()}
|
{this.renderTileUrls()}
|
||||||
<InputBlock label={"Min Zoom"} fieldSpec={latest.source_vector.minzoom}>
|
<Block label={"Min Zoom"} fieldSpec={latest.source_vector.minzoom}>
|
||||||
<NumberInput
|
<FieldNumber
|
||||||
value={this.props.source.minzoom || 0}
|
value={this.props.source.minzoom || 0}
|
||||||
onChange={minzoom => this.props.onChange({
|
onChange={minzoom => this.props.onChange({
|
||||||
...this.props.source,
|
...this.props.source,
|
||||||
minzoom: minzoom
|
minzoom: minzoom
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
<InputBlock label={"Max Zoom"} fieldSpec={latest.source_vector.maxzoom}>
|
<Block label={"Max Zoom"} fieldSpec={latest.source_vector.maxzoom}>
|
||||||
<NumberInput
|
<FieldNumber
|
||||||
value={this.props.source.maxzoom || 22}
|
value={this.props.source.maxzoom || 22}
|
||||||
onChange={maxzoom => this.props.onChange({
|
onChange={maxzoom => this.props.onChange({
|
||||||
...this.props.source,
|
...this.props.source,
|
||||||
maxzoom: maxzoom
|
maxzoom: maxzoom
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -104,26 +104,26 @@ class ImageSourceEditor extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
<InputBlock label={"Image URL"} fieldSpec={latest.source_image.url}>
|
<Block label={"Image URL"} fieldSpec={latest.source_image.url}>
|
||||||
<UrlInput
|
<FieldUrl
|
||||||
value={this.props.source.url}
|
value={this.props.source.url}
|
||||||
onChange={url => this.props.onChange({
|
onChange={url => this.props.onChange({
|
||||||
...this.props.source,
|
...this.props.source,
|
||||||
url,
|
url,
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
{["top left", "top right", "bottom right", "bottom left"].map((label, idx) => {
|
{["top left", "top right", "bottom right", "bottom left"].map((label, idx) => {
|
||||||
return (
|
return (
|
||||||
<InputBlock label={`Coord ${label}`} key={label}>
|
<Block label={`Coord ${label}`} key={label}>
|
||||||
<ArrayInput
|
<FieldArray
|
||||||
length={2}
|
length={2}
|
||||||
type="number"
|
type="number"
|
||||||
value={this.props.source.coordinates[idx]}
|
value={this.props.source.coordinates[idx]}
|
||||||
default={[0, 0]}
|
default={[0, 0]}
|
||||||
onChange={(val) => changeCoord(idx, val)}
|
onChange={(val) => changeCoord(idx, val)}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
@ -155,25 +155,25 @@ class VideoSourceEditor extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
<InputBlock label={"Video URL"} fieldSpec={latest.source_video.urls}>
|
<Block label={"Video URL"} fieldSpec={latest.source_video.urls}>
|
||||||
<DynamicArrayInput
|
<FieldDynamicArray
|
||||||
type="string"
|
type="string"
|
||||||
value={this.props.source.urls}
|
value={this.props.source.urls}
|
||||||
default={""}
|
default={""}
|
||||||
onChange={changeUrls}
|
onChange={changeUrls}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
{["top left", "top right", "bottom right", "bottom left"].map((label, idx) => {
|
{["top left", "top right", "bottom right", "bottom left"].map((label, idx) => {
|
||||||
return (
|
return (
|
||||||
<InputBlock label={`Coord ${label}`} key={label}>
|
<Block label={`Coord ${label}`} key={label}>
|
||||||
<ArrayInput
|
<FieldArray
|
||||||
length={2}
|
length={2}
|
||||||
type="number"
|
type="number"
|
||||||
value={this.props.source.coordinates[idx]}
|
value={this.props.source.coordinates[idx]}
|
||||||
default={[0, 0]}
|
default={[0, 0]}
|
||||||
onChange={val => changeCoord(idx, val)}
|
onChange={val => changeCoord(idx, val)}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
@ -187,27 +187,27 @@ class GeoJSONSourceUrlEditor extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <InputBlock label={"GeoJSON URL"} fieldSpec={latest.source_geojson.data}>
|
return <Block label={"GeoJSON URL"} fieldSpec={latest.source_geojson.data}>
|
||||||
<UrlInput
|
<FieldUrl
|
||||||
value={this.props.source.data}
|
value={this.props.source.data}
|
||||||
onChange={data => this.props.onChange({
|
onChange={data => this.props.onChange({
|
||||||
...this.props.source,
|
...this.props.source,
|
||||||
data: data
|
data: data
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class GeoJSONSourceJSONEditor extends React.Component {
|
class GeoJSONSourceFieldJsonEditor extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
source: PropTypes.object.isRequired,
|
source: PropTypes.object.isRequired,
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <InputBlock label={"GeoJSON"} fieldSpec={latest.source_geojson.data}>
|
return <Block label={"GeoJSON"} fieldSpec={latest.source_geojson.data}>
|
||||||
<JSONEditor
|
<FieldJsonEditor
|
||||||
layer={this.props.source.data}
|
layer={this.props.source.data}
|
||||||
maxHeight={200}
|
maxHeight={200}
|
||||||
mode={{
|
mode={{
|
||||||
|
@ -222,11 +222,11 @@ class GeoJSONSourceJSONEditor extends React.Component {
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SourceTypeEditor extends React.Component {
|
export default class ModalSourcesTypeEditor extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
mode: PropTypes.string.isRequired,
|
mode: PropTypes.string.isRequired,
|
||||||
source: PropTypes.object.isRequired,
|
source: PropTypes.object.isRequired,
|
||||||
|
@ -240,15 +240,15 @@ class SourceTypeEditor extends React.Component {
|
||||||
}
|
}
|
||||||
switch(this.props.mode) {
|
switch(this.props.mode) {
|
||||||
case 'geojson_url': return <GeoJSONSourceUrlEditor {...commonProps} />
|
case 'geojson_url': return <GeoJSONSourceUrlEditor {...commonProps} />
|
||||||
case 'geojson_json': return <GeoJSONSourceJSONEditor {...commonProps} />
|
case 'geojson_json': return <GeoJSONSourceFieldJsonEditor {...commonProps} />
|
||||||
case 'tilejson_vector': return <TileJSONSourceEditor {...commonProps} />
|
case 'tilejson_vector': return <TileJSONSourceEditor {...commonProps} />
|
||||||
case 'tilexyz_vector': return <TileURLSourceEditor {...commonProps} />
|
case 'tilexyz_vector': return <TileURLSourceEditor {...commonProps} />
|
||||||
case 'tilejson_raster': return <TileJSONSourceEditor {...commonProps} />
|
case 'tilejson_raster': return <TileJSONSourceEditor {...commonProps} />
|
||||||
case 'tilexyz_raster': return <TileURLSourceEditor {...commonProps} />
|
case 'tilexyz_raster': return <TileURLSourceEditor {...commonProps} />
|
||||||
case 'tilejson_raster-dem': return <TileJSONSourceEditor {...commonProps} />
|
case 'tilejson_raster-dem': return <TileJSONSourceEditor {...commonProps} />
|
||||||
case 'tilexyz_raster-dem': return <TileURLSourceEditor {...commonProps}>
|
case 'tilexyz_raster-dem': return <TileURLSourceEditor {...commonProps}>
|
||||||
<InputBlock label={"Encoding"} fieldSpec={latest.source_raster_dem.encoding}>
|
<Block label={"Encoding"} fieldSpec={latest.source_raster_dem.encoding}>
|
||||||
<SelectInput
|
<FieldSelect
|
||||||
options={Object.keys(latest.source_raster_dem.encoding.values)}
|
options={Object.keys(latest.source_raster_dem.encoding.values)}
|
||||||
onChange={encoding => this.props.onChange({
|
onChange={encoding => this.props.onChange({
|
||||||
...this.props.source,
|
...this.props.source,
|
||||||
|
@ -256,7 +256,7 @@ class SourceTypeEditor extends React.Component {
|
||||||
})}
|
})}
|
||||||
value={this.props.source.encoding || latest.source_raster_dem.encoding.default}
|
value={this.props.source.encoding || latest.source_raster_dem.encoding.default}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
</TileURLSourceEditor>
|
</TileURLSourceEditor>
|
||||||
case 'image': return <ImageSourceEditor {...commonProps} />
|
case 'image': return <ImageSourceEditor {...commonProps} />
|
||||||
case 'video': return <VideoSourceEditor {...commonProps} />
|
case 'video': return <VideoSourceEditor {...commonProps} />
|
||||||
|
@ -265,4 +265,3 @@ class SourceTypeEditor extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SourceTypeEditor
|
|
|
@ -1,12 +1,12 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import Button from '../Button'
|
import Button from './Button'
|
||||||
import Modal from './Modal'
|
import Modal from './Modal'
|
||||||
|
|
||||||
import logoImage from 'maputnik-design/logos/logo-color.svg'
|
import logoImage from 'maputnik-design/logos/logo-color.svg'
|
||||||
|
|
||||||
class SurveyModal extends React.Component {
|
export default class ModalSurvey extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
isOpen: PropTypes.bool.isRequired,
|
isOpen: PropTypes.bool.isRequired,
|
||||||
onOpenToggle: PropTypes.func.isRequired,
|
onOpenToggle: PropTypes.func.isRequired,
|
||||||
|
@ -36,4 +36,3 @@ class SurveyModal extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SurveyModal
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import FunctionSpecField from './FunctionSpecField'
|
import FieldFunction from './FieldFunction'
|
||||||
const iconProperties = ['background-pattern', 'fill-pattern', 'line-pattern', 'fill-extrusion-pattern', 'icon-image']
|
const iconProperties = ['background-pattern', 'fill-pattern', 'line-pattern', 'fill-extrusion-pattern', 'icon-image']
|
||||||
|
|
||||||
/** Extract field spec by {@fieldName} from the {@layerType} in the
|
/** Extract field spec by {@fieldName} from the {@layerType} in the
|
||||||
|
@ -58,7 +58,7 @@ export default class PropertyGroup extends React.Component {
|
||||||
const fieldValue = fieldName in paint ? paint[fieldName] : layout[fieldName]
|
const fieldValue = fieldName in paint ? paint[fieldName] : layout[fieldName]
|
||||||
const fieldType = fieldName in paint ? 'paint' : 'layout';
|
const fieldType = fieldName in paint ? 'paint' : 'layout';
|
||||||
|
|
||||||
return <FunctionSpecField
|
return <FieldFunction
|
||||||
errors={errors}
|
errors={errors}
|
||||||
onChange={this.onPropertyChange}
|
onChange={this.onPropertyChange}
|
||||||
key={fieldName}
|
key={fieldName}
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
class ScrollContainer extends React.Component {
|
export default class ScrollContainer extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
children: PropTypes.node
|
children: PropTypes.node
|
||||||
}
|
}
|
||||||
|
@ -13,4 +13,3 @@ class ScrollContainer extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ScrollContainer
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import { otherFilterOps } from '../../libs/filterops.js'
|
import { otherFilterOps } from '../libs/filterops.js'
|
||||||
import StringInput from '../inputs/StringInput'
|
import FieldString from './FieldString'
|
||||||
import AutocompleteInput from '../inputs/AutocompleteInput'
|
import FieldAutocomplete from './FieldAutocomplete'
|
||||||
import SelectInput from '../inputs/SelectInput'
|
import FieldSelect from './FieldSelect'
|
||||||
|
|
||||||
function tryParseInt(v) {
|
function tryParseInt(v) {
|
||||||
if (v === '') return v
|
if (v === '') return v
|
||||||
|
@ -35,7 +35,7 @@ function parseFilter(v) {
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
class SingleFilterEditor extends React.Component {
|
export default class SingleFilterEditor extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
filter: PropTypes.array.isRequired,
|
filter: PropTypes.array.isRequired,
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
|
@ -64,14 +64,14 @@ class SingleFilterEditor extends React.Component {
|
||||||
|
|
||||||
return <div className="maputnik-filter-editor-single">
|
return <div className="maputnik-filter-editor-single">
|
||||||
<div className="maputnik-filter-editor-property">
|
<div className="maputnik-filter-editor-property">
|
||||||
<AutocompleteInput
|
<FieldAutocomplete
|
||||||
value={propertyName}
|
value={propertyName}
|
||||||
options={Object.keys(this.props.properties).map(propName => [propName, propName])}
|
options={Object.keys(this.props.properties).map(propName => [propName, propName])}
|
||||||
onChange={newPropertyName => this.onFilterPartChanged(filterOp, newPropertyName, filterArgs)}
|
onChange={newPropertyName => this.onFilterPartChanged(filterOp, newPropertyName, filterArgs)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="maputnik-filter-editor-operator">
|
<div className="maputnik-filter-editor-operator">
|
||||||
<SelectInput
|
<FieldSelect
|
||||||
value={filterOp}
|
value={filterOp}
|
||||||
onChange={newFilterOp => this.onFilterPartChanged(newFilterOp, propertyName, filterArgs)}
|
onChange={newFilterOp => this.onFilterPartChanged(newFilterOp, propertyName, filterArgs)}
|
||||||
options={otherFilterOps}
|
options={otherFilterOps}
|
||||||
|
@ -79,7 +79,7 @@ class SingleFilterEditor extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
{filterArgs.length > 0 &&
|
{filterArgs.length > 0 &&
|
||||||
<div className="maputnik-filter-editor-args">
|
<div className="maputnik-filter-editor-args">
|
||||||
<StringInput
|
<FieldString
|
||||||
value={filterArgs.join(',')}
|
value={filterArgs.join(',')}
|
||||||
onChange={ v=> this.onFilterPartChanged(filterOp, propertyName, v.split(','))}
|
onChange={ v=> this.onFilterPartChanged(filterOp, propertyName, v.split(','))}
|
||||||
/>
|
/>
|
||||||
|
@ -90,4 +90,3 @@ class SingleFilterEditor extends React.Component {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SingleFilterEditor
|
|
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
|
||||||
import './SmallError.scss';
|
import './SmallError.scss';
|
||||||
|
|
||||||
|
|
||||||
class SmallError extends React.Component {
|
export default class SmallError extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
}
|
}
|
||||||
|
@ -17,4 +17,3 @@ class SmallError extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SmallError
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import '../../styles/vars';
|
@import '../styles/vars';
|
||||||
|
|
||||||
.SmallError {
|
.SmallError {
|
||||||
color: #E57373;
|
color: #E57373;
|
|
@ -1,17 +1,17 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import ColorField from './ColorField'
|
import FieldColor from './FieldColor'
|
||||||
import NumberInput from '../inputs/NumberInput'
|
import FieldNumber from './FieldNumber'
|
||||||
import CheckboxInput from '../inputs/CheckboxInput'
|
import FieldCheckbox from './FieldCheckbox'
|
||||||
import StringInput from '../inputs/StringInput'
|
import FieldString from './FieldString'
|
||||||
import SelectInput from '../inputs/SelectInput'
|
import FieldSelect from './FieldSelect'
|
||||||
import MultiButtonInput from '../inputs/MultiButtonInput'
|
import FieldMultiInput from './FieldMultiInput'
|
||||||
import ArrayInput from '../inputs/ArrayInput'
|
import FieldArray from './FieldArray'
|
||||||
import DynamicArrayInput from '../inputs/DynamicArrayInput'
|
import FieldDynamicArray from './FieldDynamicArray'
|
||||||
import FontInput from '../inputs/FontInput'
|
import FieldFont from './FieldFont'
|
||||||
import IconInput from '../inputs/IconInput'
|
import FieldSymbol from './FieldSymbol'
|
||||||
import EnumInput from '../inputs/EnumInput'
|
import FieldEnum from './FieldEnum'
|
||||||
import capitalize from 'lodash.capitalize'
|
import capitalize from 'lodash.capitalize'
|
||||||
|
|
||||||
const iconProperties = ['background-pattern', 'fill-pattern', 'line-pattern', 'fill-extrusion-pattern', 'icon-image']
|
const iconProperties = ['background-pattern', 'fill-pattern', 'line-pattern', 'fill-extrusion-pattern', 'icon-image']
|
||||||
|
@ -62,7 +62,7 @@ export default class SpecField extends React.Component {
|
||||||
function childNodes() {
|
function childNodes() {
|
||||||
switch(this.props.fieldSpec.type) {
|
switch(this.props.fieldSpec.type) {
|
||||||
case 'number': return (
|
case 'number': return (
|
||||||
<NumberInput
|
<FieldNumber
|
||||||
{...commonProps}
|
{...commonProps}
|
||||||
min={this.props.fieldSpec.minimum}
|
min={this.props.fieldSpec.minimum}
|
||||||
max={this.props.fieldSpec.maximum}
|
max={this.props.fieldSpec.maximum}
|
||||||
|
@ -71,7 +71,7 @@ export default class SpecField extends React.Component {
|
||||||
case 'enum':
|
case 'enum':
|
||||||
const options = Object.keys(this.props.fieldSpec.values).map(v => [v, capitalize(v)])
|
const options = Object.keys(this.props.fieldSpec.values).map(v => [v, capitalize(v)])
|
||||||
|
|
||||||
return <EnumInput
|
return <FieldEnum
|
||||||
{...commonProps}
|
{...commonProps}
|
||||||
options={options}
|
options={options}
|
||||||
/>
|
/>
|
||||||
|
@ -79,40 +79,40 @@ export default class SpecField extends React.Component {
|
||||||
case 'formatted':
|
case 'formatted':
|
||||||
case 'string':
|
case 'string':
|
||||||
if(iconProperties.indexOf(this.props.fieldName) >= 0) {
|
if(iconProperties.indexOf(this.props.fieldName) >= 0) {
|
||||||
return <IconInput
|
return <FieldSymbol
|
||||||
{...commonProps}
|
{...commonProps}
|
||||||
icons={this.props.fieldSpec.values}
|
icons={this.props.fieldSpec.values}
|
||||||
/>
|
/>
|
||||||
} else {
|
} else {
|
||||||
return <StringInput
|
return <FieldString
|
||||||
{...commonProps}
|
{...commonProps}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
case 'color': return (
|
case 'color': return (
|
||||||
<ColorField
|
<FieldColor
|
||||||
{...commonProps}
|
{...commonProps}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
case 'boolean': return (
|
case 'boolean': return (
|
||||||
<CheckboxInput
|
<FieldCheckbox
|
||||||
{...commonProps}
|
{...commonProps}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
case 'array':
|
case 'array':
|
||||||
if(this.props.fieldName === 'text-font') {
|
if(this.props.fieldName === 'text-font') {
|
||||||
return <FontInput
|
return <FieldFont
|
||||||
{...commonProps}
|
{...commonProps}
|
||||||
fonts={this.props.fieldSpec.values}
|
fonts={this.props.fieldSpec.values}
|
||||||
/>
|
/>
|
||||||
} else {
|
} else {
|
||||||
if (this.props.fieldSpec.length) {
|
if (this.props.fieldSpec.length) {
|
||||||
return <ArrayInput
|
return <FieldArray
|
||||||
{...commonProps}
|
{...commonProps}
|
||||||
type={this.props.fieldSpec.value}
|
type={this.props.fieldSpec.value}
|
||||||
length={this.props.fieldSpec.length}
|
length={this.props.fieldSpec.length}
|
||||||
/>
|
/>
|
||||||
} else {
|
} else {
|
||||||
return <DynamicArrayInput
|
return <FieldDynamicArray
|
||||||
{...commonProps}
|
{...commonProps}
|
||||||
fieldSpec={this.props.fieldSpec}
|
fieldSpec={this.props.fieldSpec}
|
||||||
type={this.props.fieldSpec.value}
|
type={this.props.fieldSpec.value}
|
|
@ -2,15 +2,15 @@ import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import {mdiFunctionVariant, mdiTableRowPlusAfter} from '@mdi/js';
|
import {mdiFunctionVariant, mdiTableRowPlusAfter} from '@mdi/js';
|
||||||
|
|
||||||
import Button from '../Button'
|
import Button from './Button'
|
||||||
import SpecField from './SpecField'
|
import SpecField from './SpecField'
|
||||||
import NumberInput from '../inputs/NumberInput'
|
import FieldNumber from './FieldNumber'
|
||||||
import StringInput from '../inputs/StringInput'
|
import FieldString from './FieldString'
|
||||||
import SelectInput from '../inputs/SelectInput'
|
import FieldSelect from './FieldSelect'
|
||||||
import DocLabel from './DocLabel'
|
import Doc from './Doc'
|
||||||
import InputBlock from '../inputs/InputBlock'
|
import Block from './Block'
|
||||||
import docUid from '../../libs/document-uid'
|
import docUid from '../libs/document-uid'
|
||||||
import sortNumerically from '../../libs/sort-numerically'
|
import sortNumerically from '../libs/sort-numerically'
|
||||||
import {findDefaultFromSpec} from '../util/spec-helper';
|
import {findDefaultFromSpec} from '../util/spec-helper';
|
||||||
|
|
||||||
import labelFromFieldName from './_labelFromFieldName'
|
import labelFromFieldName from './_labelFromFieldName'
|
||||||
|
@ -195,16 +195,16 @@ export default class DataProperty extends React.Component {
|
||||||
|
|
||||||
let dataInput;
|
let dataInput;
|
||||||
if(this.props.value.type === "categorical") {
|
if(this.props.value.type === "categorical") {
|
||||||
dataInput = <StringInput {...dataProps} />
|
dataInput = <FieldString {...dataProps} />
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dataInput = <NumberInput {...dataProps} />
|
dataInput = <FieldNumber {...dataProps} />
|
||||||
}
|
}
|
||||||
|
|
||||||
let zoomInput = null;
|
let zoomInput = null;
|
||||||
if(zoomLevel !== undefined) {
|
if(zoomLevel !== undefined) {
|
||||||
zoomInput = <div className="maputnik-data-spec-property-stop-edit">
|
zoomInput = <div className="maputnik-data-spec-property-stop-edit">
|
||||||
<NumberInput
|
<FieldNumber
|
||||||
value={zoomLevel}
|
value={zoomLevel}
|
||||||
onChange={newZoom => this.changeStop(idx, {zoom: newZoom, value: dataLevel}, value)}
|
onChange={newZoom => this.changeStop(idx, {zoom: newZoom, value: dataLevel}, value)}
|
||||||
min={0}
|
min={0}
|
||||||
|
@ -223,7 +223,7 @@ export default class DataProperty extends React.Component {
|
||||||
}).join("");
|
}).join("");
|
||||||
const error = message ? {message} : undefined;
|
const error = message ? {message} : undefined;
|
||||||
|
|
||||||
return <InputBlock
|
return <Block
|
||||||
error={error}
|
error={error}
|
||||||
key={key}
|
key={key}
|
||||||
action={deleteStopBtn}
|
action={deleteStopBtn}
|
||||||
|
@ -241,22 +241,22 @@ export default class DataProperty extends React.Component {
|
||||||
onChange={(_, newValue) => this.changeStop(idx, {zoom: zoomLevel, value: dataLevel}, newValue)}
|
onChange={(_, newValue) => this.changeStop(idx, {zoom: zoomLevel, value: dataLevel}, newValue)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</InputBlock>
|
</Block>
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div className="maputnik-data-spec-block">
|
return <div className="maputnik-data-spec-block">
|
||||||
<div className="maputnik-data-spec-property">
|
<div className="maputnik-data-spec-property">
|
||||||
<InputBlock
|
<Block
|
||||||
fieldSpec={this.props.fieldSpec}
|
fieldSpec={this.props.fieldSpec}
|
||||||
label={labelFromFieldName(this.props.fieldName)}
|
label={labelFromFieldName(this.props.fieldName)}
|
||||||
>
|
>
|
||||||
<div className="maputnik-data-spec-property-group">
|
<div className="maputnik-data-spec-property-group">
|
||||||
<DocLabel
|
<Doc
|
||||||
label="Type"
|
label="Type"
|
||||||
/>
|
/>
|
||||||
<div className="maputnik-data-spec-property-input">
|
<div className="maputnik-data-spec-property-input">
|
||||||
<SelectInput
|
<FieldSelect
|
||||||
value={this.props.value.type}
|
value={this.props.value.type}
|
||||||
onChange={propVal => this.changeDataProperty("type", propVal)}
|
onChange={propVal => this.changeDataProperty("type", propVal)}
|
||||||
title={"Select a type of data scale (default is 'categorical')."}
|
title={"Select a type of data scale (default is 'categorical')."}
|
||||||
|
@ -265,11 +265,11 @@ export default class DataProperty extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="maputnik-data-spec-property-group">
|
<div className="maputnik-data-spec-property-group">
|
||||||
<DocLabel
|
<Doc
|
||||||
label="Property"
|
label="Property"
|
||||||
/>
|
/>
|
||||||
<div className="maputnik-data-spec-property-input">
|
<div className="maputnik-data-spec-property-input">
|
||||||
<StringInput
|
<FieldString
|
||||||
value={this.props.value.property}
|
value={this.props.value.property}
|
||||||
title={"Input a data property to base styles off of."}
|
title={"Input a data property to base styles off of."}
|
||||||
onChange={propVal => this.changeDataProperty("property", propVal)}
|
onChange={propVal => this.changeDataProperty("property", propVal)}
|
||||||
|
@ -278,7 +278,7 @@ export default class DataProperty extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
{dataFields &&
|
{dataFields &&
|
||||||
<div className="maputnik-data-spec-property-group">
|
<div className="maputnik-data-spec-property-group">
|
||||||
<DocLabel
|
<Doc
|
||||||
label="Default"
|
label="Default"
|
||||||
/>
|
/>
|
||||||
<div className="maputnik-data-spec-property-input">
|
<div className="maputnik-data-spec-property-input">
|
||||||
|
@ -291,7 +291,7 @@ export default class DataProperty extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</InputBlock>
|
</Block>
|
||||||
</div>
|
</div>
|
||||||
{dataFields &&
|
{dataFields &&
|
||||||
<>
|
<>
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import Button from '../Button'
|
import Button from './Button'
|
||||||
import {MdDelete} from 'react-icons/md'
|
import {MdDelete} from 'react-icons/md'
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import InputBlock from '../inputs/InputBlock'
|
import Block from './Block'
|
||||||
import Button from '../Button'
|
import Button from './Button'
|
||||||
import {MdDelete, MdUndo} from 'react-icons/md'
|
import {MdDelete, MdUndo} from 'react-icons/md'
|
||||||
import StringInput from '../inputs/StringInput'
|
import FieldString from './FieldString'
|
||||||
|
|
||||||
import labelFromFieldName from './_labelFromFieldName'
|
import labelFromFieldName from './_labelFromFieldName'
|
||||||
import stringifyPretty from 'json-stringify-pretty-compact'
|
import stringifyPretty from 'json-stringify-pretty-compact'
|
||||||
import JSONEditor from '../layers/JSONEditor'
|
import FieldJsonEditor from './FieldJsonEditor'
|
||||||
|
|
||||||
|
|
||||||
export default class ExpressionProperty extends React.Component {
|
export default class ExpressionProperty extends React.Component {
|
||||||
|
@ -107,14 +107,14 @@ export default class ExpressionProperty extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return <InputBlock
|
return <Block
|
||||||
error={foundErrors}
|
error={foundErrors}
|
||||||
fieldSpec={this.props.fieldSpec}
|
fieldSpec={this.props.fieldSpec}
|
||||||
label={labelFromFieldName(this.props.fieldName)}
|
label={labelFromFieldName(this.props.fieldName)}
|
||||||
action={deleteStopBtn}
|
action={deleteStopBtn}
|
||||||
wideMode={true}
|
wideMode={true}
|
||||||
>
|
>
|
||||||
<JSONEditor
|
<FieldJsonEditor
|
||||||
mode={{name: "mgl"}}
|
mode={{name: "mgl"}}
|
||||||
lint={{
|
lint={{
|
||||||
context: "expression",
|
context: "expression",
|
||||||
|
@ -132,6 +132,6 @@ export default class ExpressionProperty extends React.Component {
|
||||||
getValue={getValue}
|
getValue={getValue}
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
/>
|
/>
|
||||||
</InputBlock>
|
</Block>
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import Button from '../Button'
|
import Button from './Button'
|
||||||
import {MdFunctions, MdInsertChart} from 'react-icons/md'
|
import {MdFunctions, MdInsertChart} from 'react-icons/md'
|
||||||
import {mdiFunctionVariant} from '@mdi/js';
|
import {mdiFunctionVariant} from '@mdi/js';
|
||||||
|
|
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import SpecField from './SpecField'
|
import SpecField from './SpecField'
|
||||||
import FunctionButtons from './_FunctionButtons'
|
import FunctionButtons from './_FunctionButtons'
|
||||||
import InputBlock from '../inputs/InputBlock'
|
import Block from './Block'
|
||||||
|
|
||||||
import labelFromFieldName from './_labelFromFieldName'
|
import labelFromFieldName from './_labelFromFieldName'
|
||||||
|
|
||||||
|
@ -37,13 +37,13 @@ export default class SpecProperty extends React.Component {
|
||||||
|
|
||||||
const error = errors[fieldType+"."+fieldName];
|
const error = errors[fieldType+"."+fieldName];
|
||||||
|
|
||||||
return <InputBlock
|
return <Block
|
||||||
error={error}
|
error={error}
|
||||||
fieldSpec={this.props.fieldSpec}
|
fieldSpec={this.props.fieldSpec}
|
||||||
label={labelFromFieldName(this.props.fieldName)}
|
label={labelFromFieldName(this.props.fieldName)}
|
||||||
action={functionBtn}
|
action={functionBtn}
|
||||||
>
|
>
|
||||||
<SpecField {...this.props} />
|
<SpecField {...this.props} />
|
||||||
</InputBlock>
|
</Block>
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,16 +2,16 @@ import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import {mdiFunctionVariant, mdiTableRowPlusAfter} from '@mdi/js';
|
import {mdiFunctionVariant, mdiTableRowPlusAfter} from '@mdi/js';
|
||||||
|
|
||||||
import Button from '../Button'
|
import Button from './Button'
|
||||||
import SpecField from './SpecField'
|
import SpecField from './SpecField'
|
||||||
import NumberInput from '../inputs/NumberInput'
|
import FieldNumber from './FieldNumber'
|
||||||
import InputBlock from '../inputs/InputBlock'
|
import Block from './Block'
|
||||||
|
|
||||||
import DeleteStopButton from './_DeleteStopButton'
|
import DeleteStopButton from './_DeleteStopButton'
|
||||||
import labelFromFieldName from './_labelFromFieldName'
|
import labelFromFieldName from './_labelFromFieldName'
|
||||||
|
|
||||||
import docUid from '../../libs/document-uid'
|
import docUid from '../libs/document-uid'
|
||||||
import sortNumerically from '../../libs/sort-numerically'
|
import sortNumerically from '../libs/sort-numerically'
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -143,7 +143,7 @@ export default class ZoomProperty extends React.Component {
|
||||||
}).join("");
|
}).join("");
|
||||||
const error = message ? {message} : undefined;
|
const error = message ? {message} : undefined;
|
||||||
|
|
||||||
return <InputBlock
|
return <Block
|
||||||
error={error}
|
error={error}
|
||||||
key={key}
|
key={key}
|
||||||
fieldSpec={this.props.fieldSpec}
|
fieldSpec={this.props.fieldSpec}
|
||||||
|
@ -152,7 +152,7 @@ export default class ZoomProperty extends React.Component {
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div className="maputnik-zoom-spec-property-stop-edit">
|
<div className="maputnik-zoom-spec-property-stop-edit">
|
||||||
<NumberInput
|
<FieldNumber
|
||||||
value={zoomLevel}
|
value={zoomLevel}
|
||||||
onChange={changedStop => this.changeZoomStop(idx, changedStop, value)}
|
onChange={changedStop => this.changeZoomStop(idx, changedStop, value)}
|
||||||
min={0}
|
min={0}
|
||||||
|
@ -168,7 +168,7 @@ export default class ZoomProperty extends React.Component {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</InputBlock>
|
</Block>
|
||||||
});
|
});
|
||||||
|
|
||||||
return <div className="maputnik-zoom-spec-property">
|
return <div className="maputnik-zoom-spec-property">
|
|
@ -1,34 +0,0 @@
|
||||||
import React from 'react'
|
|
||||||
import PropTypes from 'prop-types'
|
|
||||||
|
|
||||||
import LineIcon from './LineIcon.jsx'
|
|
||||||
import FillIcon from './FillIcon.jsx'
|
|
||||||
import SymbolIcon from './SymbolIcon.jsx'
|
|
||||||
import BackgroundIcon from './BackgroundIcon.jsx'
|
|
||||||
import CircleIcon from './CircleIcon.jsx'
|
|
||||||
import MissingIcon from './MissingIcon.jsx'
|
|
||||||
|
|
||||||
class LayerIcon extends React.Component {
|
|
||||||
static propTypes = {
|
|
||||||
type: PropTypes.string.isRequired,
|
|
||||||
style: PropTypes.object,
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const iconProps = { style: this.props.style }
|
|
||||||
switch(this.props.type) {
|
|
||||||
case 'fill-extrusion': return <BackgroundIcon {...iconProps} />
|
|
||||||
case 'raster': return <FillIcon {...iconProps} />
|
|
||||||
case 'hillshade': return <FillIcon {...iconProps} />
|
|
||||||
case 'heatmap': return <FillIcon {...iconProps} />
|
|
||||||
case 'fill': return <FillIcon {...iconProps} />
|
|
||||||
case 'background': return <BackgroundIcon {...iconProps} />
|
|
||||||
case 'line': return <LineIcon {...iconProps} />
|
|
||||||
case 'symbol': return <SymbolIcon {...iconProps} />
|
|
||||||
case 'circle': return <CircleIcon {...iconProps} />
|
|
||||||
default: return <MissingIcon {...iconProps} />
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default LayerIcon
|
|
26
stories/0-Welcome.stories.js
Normal file
26
stories/0-Welcome.stories.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import '../src/styles/index.scss';
|
||||||
|
import React from 'react';
|
||||||
|
import {Describe} from './ui';
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Welcome',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ToStorybook = () => {
|
||||||
|
return (
|
||||||
|
<Describe>
|
||||||
|
<h1>Maputnik component library</h1>
|
||||||
|
<p>
|
||||||
|
This is the Maputnik component library, which shows the uses of some commonly used components from the Maputnik editor. This is a stand alone place where we can better refine them and improve their API separate from their use inside the editor.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
This should also help us better refine our CSS and make it more modular as currently we rely on the cascade quite a bit in a number of places.
|
||||||
|
</p>
|
||||||
|
</Describe>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ToStorybook.story = {
|
||||||
|
name: 'Intro',
|
||||||
|
};
|
18
stories/Button.stories.js
Normal file
18
stories/Button.stories.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import React from 'react';
|
||||||
|
import Button from '../src/components/Button';
|
||||||
|
import {action} from '@storybook/addon-actions';
|
||||||
|
import {Wrapper} from './ui';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Button',
|
||||||
|
component: Button,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Simple = () => (
|
||||||
|
<Wrapper>
|
||||||
|
<Button onClick={action('onClick')}>
|
||||||
|
Hello Button
|
||||||
|
</Button>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
|
25
stories/FieldColor.stories.js
Normal file
25
stories/FieldColor.stories.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import React from 'react';
|
||||||
|
import {useActionState} from './helper';
|
||||||
|
import FieldColor from '../src/components/FieldColor';
|
||||||
|
import {Wrapper} from './ui';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'FieldColor',
|
||||||
|
component: FieldColor,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const Simple = () => {
|
||||||
|
const [color, setColor] = useActionState("onChange", "#ff0000");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Wrapper>
|
||||||
|
<FieldColor
|
||||||
|
name="color"
|
||||||
|
value={color}
|
||||||
|
onChange={setColor}
|
||||||
|
/>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
41
stories/FieldNumber.stories.js
Normal file
41
stories/FieldNumber.stories.js
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import React from 'react';
|
||||||
|
import {useActionState} from './helper';
|
||||||
|
import FieldNumber from '../src/components/FieldNumber';
|
||||||
|
import {Wrapper} from './ui';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'FieldNumber',
|
||||||
|
component: FieldNumber,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Simple = () => {
|
||||||
|
const [value, setValue] = useActionState("onChange", 1);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Wrapper>
|
||||||
|
<FieldNumber
|
||||||
|
name="number"
|
||||||
|
value={value}
|
||||||
|
onChange={setValue}
|
||||||
|
/>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Range = () => {
|
||||||
|
const [value, setValue] = useActionState("onChange", 1);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Wrapper>
|
||||||
|
<FieldNumber
|
||||||
|
name="number"
|
||||||
|
value={value}
|
||||||
|
onChange={setValue}
|
||||||
|
min={1}
|
||||||
|
max={24}
|
||||||
|
allowRange={true}
|
||||||
|
rangeStep={1}
|
||||||
|
/>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
};
|
12
stories/helper.js
Normal file
12
stories/helper.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import React, {useState} from 'react';
|
||||||
|
import {action} from '@storybook/addon-actions';
|
||||||
|
|
||||||
|
export function useActionState (name, initialVal) {
|
||||||
|
const [val, fn] = useState(initialVal);
|
||||||
|
const actionFn = action(name);
|
||||||
|
function retFn(val) {
|
||||||
|
actionFn(val);
|
||||||
|
return fn(val);
|
||||||
|
}
|
||||||
|
return [val, retFn];
|
||||||
|
}
|
19
stories/ui.js
Normal file
19
stories/ui.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
|
||||||
|
export function Describe ({children}) {
|
||||||
|
return (
|
||||||
|
<div style={{maxWidth: "600px", margin: "0.8em"}}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Wrapper ({children}) {
|
||||||
|
return (
|
||||||
|
<div style={{maxWidth: "180px", margin: "0.4em"}}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in a new issue