Added UrlInput component to tidy things up a little.

This commit is contained in:
orangemug 2019-10-27 17:08:23 +00:00
parent 663f295623
commit 566201fb45
8 changed files with 126 additions and 38 deletions

View file

@ -8,10 +8,15 @@ class StringInput extends React.Component {
style: PropTypes.object, style: PropTypes.object,
default: PropTypes.string, default: PropTypes.string,
onChange: PropTypes.func, onChange: PropTypes.func,
onInput: PropTypes.func,
multi: PropTypes.bool, multi: PropTypes.bool,
required: PropTypes.bool, required: PropTypes.bool,
} }
static defaultProps = {
onInput: () => {},
}
constructor(props) { constructor(props) {
super(props) super(props)
this.state = { this.state = {
@ -57,7 +62,9 @@ class StringInput extends React.Component {
this.setState({ this.setState({
editing: true, editing: true,
value: e.target.value value: e.target.value
}) }, () => {
this.props.onInput(this.state.value);
});
}, },
onBlur: () => { onBlur: () => {
if(this.state.value!==this.props.value) { if(this.state.value!==this.props.value) {

View file

@ -0,0 +1,61 @@
import React from 'react'
import PropTypes from 'prop-types'
import StringInput from './StringInput'
import SmallError from '../util/SmallError'
class UrlInput extends React.Component {
static propTypes = {
"data-wd-key": PropTypes.string,
value: PropTypes.string,
style: PropTypes.object,
default: PropTypes.string,
onChange: PropTypes.func,
multi: PropTypes.bool,
required: PropTypes.bool,
}
state = {
error: null,
}
onInput = (url) => {
let error;
const getProtocol = (url) => {
try {
const urlObj = new URL(url);
return urlObj.protocol;
}
catch (err) {
return undefined;
}
};
const protocol = getProtocol(url);
if (
protocol &&
protocol === "https:" &&
window.location.protocol !== "http:"
) {
error = (
<SmallError>
CORs policy won't allow fetching resources served over http from https, use a <code>https://</code> domain
</SmallError>
);
}
this.setState({error});
}
render () {
return (
<div>
<StringInput
{...this.props}
onInput={this.onInput}
/>
{this.state.error}
</div>
);
}
}
export default UrlInput

View file

@ -158,15 +158,12 @@ class AddSource extends React.Component {
} }
onAdd = () => { onAdd = () => {
this.props.onAdd(this.state.sourceId, this.state.source); const {source, sourceId} = this.state;
this.props.onAdd(sourceId, source);
} }
onChangeSource = (source) => { onChangeSource = (source) => {
// let error = "CORs policy won't allow fetching resources served over http from https"; this.setState({source});
this.setState({
source,
error,
});
} }
render() { render() {
@ -198,15 +195,9 @@ class AddSource extends React.Component {
mode={this.state.mode} mode={this.state.mode}
source={this.state.source} source={this.state.source}
/> />
{this.state.error &&
<div className="maputnik-add-source-error" style={{fontSize: "12px", color: "#E57373"}}>
Error: {this.state.error}
</div>
}
<Button <Button
className="maputnik-add-source-button" className="maputnik-add-source-button"
onClick={this.onAdd} onClick={this.onAdd}
disabled={!!this.state.error}
> >
Add Source Add Source
</Button> </Button>

View file

@ -3,6 +3,7 @@ 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 InputBlock from '../inputs/InputBlock'
import StringInput from '../inputs/StringInput' import StringInput from '../inputs/StringInput'
import UrlInput from '../inputs/UrlInput'
import NumberInput from '../inputs/NumberInput' import NumberInput from '../inputs/NumberInput'
import SelectInput from '../inputs/SelectInput' import SelectInput from '../inputs/SelectInput'
import JSONEditor from '../layers/JSONEditor' import JSONEditor from '../layers/JSONEditor'
@ -18,7 +19,7 @@ class TileJSONSourceEditor extends React.Component {
render() { render() {
return <div> return <div>
<InputBlock label={"TileJSON URL"} doc={latest.source_vector.url.doc}> <InputBlock label={"TileJSON URL"} doc={latest.source_vector.url.doc}>
<StringInput <UrlInput
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,
@ -52,7 +53,7 @@ class TileURLSourceEditor extends React.Component {
const tiles = this.props.source.tiles || [] const tiles = this.props.source.tiles || []
return tiles.map((tileUrl, tileIndex) => { return tiles.map((tileUrl, tileIndex) => {
return <InputBlock key={tileIndex} label={prefix[tileIndex] + " Tile URL"} doc={latest.source_vector.tiles.doc}> return <InputBlock key={tileIndex} label={prefix[tileIndex] + " Tile URL"} doc={latest.source_vector.tiles.doc}>
<StringInput <UrlInput
value={tileUrl} value={tileUrl}
onChange={this.changeTileUrl.bind(this, tileIndex)} onChange={this.changeTileUrl.bind(this, tileIndex)}
/> />

View file

@ -0,0 +1,20 @@
import React from 'react'
import PropTypes from 'prop-types'
import './SmallError.scss';
class SmallError extends React.Component {
static propTypes = {
children: PropTypes.node,
}
render () {
return (
<div className="SmallError">
Error: {this.props.children}
</div>
);
}
}
export default SmallError

View file

@ -0,0 +1,7 @@
@import '../../styles/vars';
.SmallError {
color: #E57373;
font-size: $font-size-5;
margin-top: $margin-2
}

23
src/styles/_vars.scss Normal file
View file

@ -0,0 +1,23 @@
$color-black: #191b20;
$color-gray: #222429;
$color-midgray: #303237;
$color-lowgray: #a4a4a4;
$color-white: #f0f0f0;
$color-red: #cf4a4a;
$color-green: #53b972;
$margin-1: 3px;
$margin-2: 5px;
$margin-3: 10px;
$margin-4: 30px;
$margin-5: 40px;
$font-size-1: 24px;
$font-size-2: 20px;
$font-size-3: 18px;
$font-size-4: 16px;
$font-size-5: 14px;
$font-size-6: 12px;
$font-family: Roboto, sans-serif;
$toolbar-height: 40px;
$toolbar-offset: 0;

View file

@ -1,26 +1,4 @@
$color-black: #191b20; @import 'vars';
$color-gray: #222429;
$color-midgray: #303237;
$color-lowgray: #a4a4a4;
$color-white: #f0f0f0;
$color-red: #cf4a4a;
$color-green: #53b972;
$margin-1: 3px;
$margin-2: 5px;
$margin-3: 10px;
$margin-4: 30px;
$margin-5: 40px;
$font-size-1: 24px;
$font-size-2: 20px;
$font-size-3: 18px;
$font-size-4: 16px;
$font-size-5: 14px;
$font-size-6: 12px;
$font-family: Roboto, sans-serif;
$toolbar-height: 40px;
$toolbar-offset: 0;
@import 'mixins'; @import 'mixins';
@import 'reset'; @import 'reset';
@import 'base'; @import 'base';