mirror of
https://github.com/jlengrand/leaflet-geosearch.git
synced 2026-03-10 08:31:26 +00:00
add better docs
This commit is contained in:
28
.babelrc
28
.babelrc
@@ -1,28 +0,0 @@
|
|||||||
{
|
|
||||||
"presets": ["es2015", "power-assert"],
|
|
||||||
"plugins": [
|
|
||||||
["fast-async", {
|
|
||||||
"runtimePattern": null,
|
|
||||||
"useRuntimeModule": true
|
|
||||||
}],
|
|
||||||
["transform-react-jsx", { "pragma": "preact.h"}],
|
|
||||||
["transform-export-extensions"],
|
|
||||||
["transform-class-properties"],
|
|
||||||
["transform-object-rest-spread"],
|
|
||||||
["babel-plugin-espower", {
|
|
||||||
"embedAst": true,
|
|
||||||
"patterns": [
|
|
||||||
"t.truthy(value, [message])",
|
|
||||||
"t.falsy(value, [message])",
|
|
||||||
"t.true(value, [message])",
|
|
||||||
"t.false(value, [message])",
|
|
||||||
"t.is(value, expected, [message])",
|
|
||||||
"t.not(value, expected, [message])",
|
|
||||||
"t.deepEqual(value, expected, [message])",
|
|
||||||
"t.notDeepEqual(value, expected, [message])",
|
|
||||||
"t.regex(contents, regex, [message])",
|
|
||||||
"t.notRegex(contents, regex, [message])"
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
16
.eslintrc.js
Normal file
16
.eslintrc.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
module.exports = {
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
extends: [
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
'prettier/@typescript-eslint',
|
||||||
|
'plugin:prettier/recommended',
|
||||||
|
'plugin:react/recommended',
|
||||||
|
],
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2020,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'@typescript-eslint/ban-ts-ignore': 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
extends: "airbnb"
|
|
||||||
|
|
||||||
env:
|
|
||||||
browser: true
|
|
||||||
|
|
||||||
parser: "babel-eslint"
|
|
||||||
parserOptions:
|
|
||||||
ecmaVersion: 6
|
|
||||||
ecmaFeatures:
|
|
||||||
experimentalObjectRestSpread: true
|
|
||||||
jsx: true
|
|
||||||
sourceType: "module"
|
|
||||||
|
|
||||||
rules:
|
|
||||||
# we need this to test leaflet private vars
|
|
||||||
no-underscore-dangle: "off"
|
|
||||||
|
|
||||||
# force else and catch to a new line
|
|
||||||
brace-style:
|
|
||||||
- "error"
|
|
||||||
- "stroustrup"
|
|
||||||
- allowSingleLine: true
|
|
||||||
|
|
||||||
quote-props:
|
|
||||||
- "error"
|
|
||||||
- "consistent-as-needed"
|
|
||||||
- keywords: true
|
|
||||||
|
|
||||||
class-methods-use-this: "off"
|
|
||||||
|
|
||||||
import/no-extraneous-dependencies:
|
|
||||||
- "warn"
|
|
||||||
- devDependencies:
|
|
||||||
- "**/*.spec.js"
|
|
||||||
- "**/test_helpers/**/*.js"
|
|
||||||
- "docs/**/*.js"
|
|
||||||
|
|
||||||
react/jsx-filename-extension:
|
|
||||||
- "error"
|
|
||||||
- extensions:
|
|
||||||
- ".js"
|
|
||||||
|
|
||||||
react/prop-types: "off"
|
|
||||||
|
|
||||||
jsx-a11y/anchor-has-content: "off"
|
|
||||||
|
|
||||||
globals:
|
|
||||||
L: false
|
|
||||||
fetch: false
|
|
||||||
document: false
|
|
||||||
location: false
|
|
||||||
|
|
||||||
settings:
|
|
||||||
react:
|
|
||||||
pragma: "preact"
|
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,3 +6,4 @@ dist/
|
|||||||
.idea
|
.idea
|
||||||
.env
|
.env
|
||||||
.tmp
|
.tmp
|
||||||
|
.docz
|
||||||
|
|||||||
7
.prettierrc.js
Normal file
7
.prettierrc.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
module.exports = {
|
||||||
|
semi: true,
|
||||||
|
trailingComma: 'all',
|
||||||
|
singleQuote: true,
|
||||||
|
printWidth: 120,
|
||||||
|
tabWidth: 2,
|
||||||
|
};
|
||||||
3
assets/css/docs.css
Normal file
3
assets/css/docs.css
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
pre .token-line {
|
||||||
|
height: 1.5em;
|
||||||
|
}
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
.code {
|
|
||||||
position: absolute;
|
|
||||||
top: 110px;
|
|
||||||
right: 10px;
|
|
||||||
bottom: 10px;
|
|
||||||
width: 425px;
|
|
||||||
|
|
||||||
background: rgba(0, 0, 0, .7);
|
|
||||||
color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 24px;
|
|
||||||
font-family: Roboto, monospace;
|
|
||||||
white-space: pre;
|
|
||||||
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 22px;
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
import preact, { Component } from 'preact';
|
|
||||||
import microlight from 'microlight';
|
|
||||||
import styles from './Code.css';
|
|
||||||
|
|
||||||
class Code extends Component {
|
|
||||||
componentDidMount() {
|
|
||||||
microlight.reset('code');
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate() {
|
|
||||||
const { children } = this.props;
|
|
||||||
this.container.innerHTML = children.join('\n\n');
|
|
||||||
microlight.reset('code');
|
|
||||||
}
|
|
||||||
|
|
||||||
defineContainer = (ref) => {
|
|
||||||
this.container = ref;
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { children } = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div ref={this.defineContainer} className={styles.code}>
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Code;
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
.header {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
height: 100px;
|
|
||||||
padding: 0 0 0 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header h1 {
|
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-size: 32px;
|
|
||||||
font-weight: 300;
|
|
||||||
line-height: 64px;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header ul {
|
|
||||||
list-style: none;
|
|
||||||
display: block;
|
|
||||||
overflow: hidden;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
line-height: 32px
|
|
||||||
}
|
|
||||||
|
|
||||||
.header ul li {
|
|
||||||
float: left;
|
|
||||||
display: block;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header ul li:hover {
|
|
||||||
border-bottom: 4px solid #00bcd4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header ul :global(li.active) {
|
|
||||||
border-bottom: 4px solid #2196f3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header ul li a {
|
|
||||||
text-decoration: none;
|
|
||||||
color: inherit;
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
padding: 0 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
position: absolute;
|
|
||||||
top: 100px;
|
|
||||||
bottom: 0;
|
|
||||||
left: 20px;
|
|
||||||
right: 465px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fullWidth {
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
import preact, { Component } from 'preact';
|
|
||||||
import Code from './Code';
|
|
||||||
import styles from './Layout.css';
|
|
||||||
|
|
||||||
class Layout extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
hash: window.location.hash.slice(1),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
window.addEventListener('hashchange', this.changePage, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
window.removeEventListener('hashchange', this.changePage, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
changePage = () => {
|
|
||||||
this.setState({
|
|
||||||
hash: window.location.hash.slice(1),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { pages } = this.props;
|
|
||||||
const { hash } = this.state;
|
|
||||||
const page = pages.find(p => p.slug === (hash || 'search'));
|
|
||||||
|
|
||||||
const contentClassName = hash === 'search'
|
|
||||||
? styles.content
|
|
||||||
: [styles.content, styles.fullWidth].join(' ');
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div className={styles.header}>
|
|
||||||
<h1>{`GeoSearch / ${page.title}`}</h1>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
{pages.map((p, idx) => (
|
|
||||||
<li key={idx} className={p.slug === hash && 'active'}>
|
|
||||||
<a href={`#${p.slug}`}>{p.title}</a>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={contentClassName}>
|
|
||||||
{page && page.view()}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{page.code && (
|
|
||||||
<Code>
|
|
||||||
{page.code}
|
|
||||||
</Code>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Layout;
|
|
||||||
9
docs/components/Leaflet.module.css
Normal file
9
docs/components/Leaflet.module.css
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
.root {
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
67
docs/components/Leaflet.tsx
Normal file
67
docs/components/Leaflet.tsx
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
import React, { ReactElement, useRef, useEffect } from 'react';
|
||||||
|
import 'leaflet/dist/leaflet.css';
|
||||||
|
import { Map, TileLayer } from 'react-leaflet';
|
||||||
|
import styles from './Leaflet.module.css';
|
||||||
|
import '../../assets/css/leaflet.css';
|
||||||
|
import useConfigureLeaflet from '../hooks/useConfigureLeaflet';
|
||||||
|
import * as providers from '../../src/providers';
|
||||||
|
import GeoSearchControl from '../../src/leafletControl';
|
||||||
|
|
||||||
|
import { MapProps } from './Map';
|
||||||
|
|
||||||
|
const providerMap = {
|
||||||
|
Bing: new providers.BingProvider({
|
||||||
|
params: { key: process.env.GATSBY_BING_API_KEY },
|
||||||
|
}),
|
||||||
|
Esri: new providers.EsriProvider(),
|
||||||
|
Google: new providers.GoogleProvider({
|
||||||
|
params: { key: process.env.GATSBY_GOOGLE_API_KEY },
|
||||||
|
}),
|
||||||
|
LocationIQ: new providers.LocationIQProvider({
|
||||||
|
params: { key: process.env.GATSBY_LOCATIONIQ_API_KEY },
|
||||||
|
}),
|
||||||
|
OpenCage: new providers.OpenCageProvider({
|
||||||
|
params: { key: process.env.GATSBY_OPENCAGE_API_KEY },
|
||||||
|
}),
|
||||||
|
OpenStreetMap: new providers.OpenStreetMapProvider(),
|
||||||
|
};
|
||||||
|
|
||||||
|
function Leaflet(props: MapProps): ReactElement {
|
||||||
|
const { provider = 'OpenStreetMap' } = props;
|
||||||
|
|
||||||
|
const ref = useRef(null);
|
||||||
|
const control = useRef(null);
|
||||||
|
|
||||||
|
const { viewport } = useConfigureLeaflet();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (ref.current) {
|
||||||
|
if (!providerMap[provider]) {
|
||||||
|
throw new Error('unknown provider');
|
||||||
|
}
|
||||||
|
|
||||||
|
control.current = GeoSearchControl({
|
||||||
|
style: 'bar',
|
||||||
|
provider: providerMap[provider],
|
||||||
|
});
|
||||||
|
|
||||||
|
ref.current.leafletElement.addControl(control.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (control.current) {
|
||||||
|
ref.current.leafletElement.removeControl(control.current);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [ref.current, control.current, provider]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.root}>
|
||||||
|
<Map ref={ref} viewport={viewport} className={styles.map}>
|
||||||
|
<TileLayer url="//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
|
||||||
|
</Map>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Leaflet;
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
.map {
|
|
||||||
position: absolute;
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
import preact, { Component } from 'preact';
|
|
||||||
import merge from 'lodash.merge';
|
|
||||||
import L from 'leaflet';
|
|
||||||
import styles from './Map.css';
|
|
||||||
|
|
||||||
import {
|
|
||||||
GeoSearchControl,
|
|
||||||
OpenStreetMapProvider,
|
|
||||||
Provider as BaseProvider,
|
|
||||||
} from '../../src';
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-confusing-arrow
|
|
||||||
const ensureInstance = Provider => Provider instanceof BaseProvider ? Provider : new Provider();
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-bitwise
|
|
||||||
const protocol = ~location.protocol.indexOf('http') ? location.protocol : 'https:';
|
|
||||||
|
|
||||||
const mapOptions = () => ({
|
|
||||||
layers: [
|
|
||||||
new L.TileLayer(`${protocol}//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png`, {
|
|
||||||
maxZoom: 18,
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
center: new L.LatLng(53.2, 5.8),
|
|
||||||
zoom: 12,
|
|
||||||
});
|
|
||||||
|
|
||||||
class Map extends Component {
|
|
||||||
componentDidMount() {
|
|
||||||
const { options, Provider } = this.props;
|
|
||||||
this.map = this.map || new L.Map(this.container, mapOptions());
|
|
||||||
|
|
||||||
const provider = (Provider) ? ensureInstance(Provider) : new OpenStreetMapProvider();
|
|
||||||
|
|
||||||
this.searchControl = new GeoSearchControl({
|
|
||||||
...options,
|
|
||||||
provider,
|
|
||||||
}).addTo(this.map);
|
|
||||||
|
|
||||||
window.search = this.searchControl;
|
|
||||||
window.map = this.map;
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate() {
|
|
||||||
this.map.removeControl(this.searchControl);
|
|
||||||
this.componentDidMount();
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
this.map.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
bindContainer = (container) => {
|
|
||||||
this.container = container;
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div className={styles.map} ref={this.bindContainer} />
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Map;
|
|
||||||
20
docs/components/Map.tsx
Normal file
20
docs/components/Map.tsx
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import React, { ReactElement, lazy, Suspense } from 'react';
|
||||||
|
import 'leaflet/dist/leaflet.css';
|
||||||
|
|
||||||
|
const Leaflet = lazy(() => import('./Leaflet'));
|
||||||
|
const Loader = () => <div>loading...</div>;
|
||||||
|
|
||||||
|
export interface MapProps {
|
||||||
|
provider: 'OpenStreetMap' | 'Google' | 'Bing';
|
||||||
|
providerOptions: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Map(props: MapProps): ReactElement {
|
||||||
|
return (
|
||||||
|
<Suspense fallback={<Loader />}>
|
||||||
|
<Leaflet provider={props.provider} />
|
||||||
|
</Suspense>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Map;
|
||||||
13
docs/components/Playground.module.css
Normal file
13
docs/components/Playground.module.css
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
.root > div > :nth-child(1) > :nth-child(2), .root > div > :nth-child(2) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.root + div > pre {
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
background-color: var(--theme-ui-colors-playground-bg,#FFFFFF);
|
||||||
|
border: 1px solid var(--theme-ui-colors-playground-border,#CED4DE);
|
||||||
|
border-top: 0;
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
13
docs/components/Playground.tsx
Normal file
13
docs/components/Playground.tsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { Playground, PlaygroundProps } from 'docz'
|
||||||
|
import styles from './Playground.module.css';
|
||||||
|
|
||||||
|
|
||||||
|
export default (props: PlaygroundProps) => {
|
||||||
|
return (
|
||||||
|
<div className={styles.root}>
|
||||||
|
<Playground {...props} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
import preact, { Component } from 'preact';
|
|
||||||
import debounce from 'lodash.debounce';
|
|
||||||
import * as providers from '../../src/providers';
|
|
||||||
import SearchResults from './SearchResults';
|
|
||||||
import styles from './Search.css';
|
|
||||||
|
|
||||||
const specialKeys = ['ArrowDown', 'ArrowUp', 'Escape'];
|
|
||||||
|
|
||||||
class Search extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
const Provider = providers[`${props.provider}Provider`] ||
|
|
||||||
providers.OpenStreetMapProvider;
|
|
||||||
|
|
||||||
this.provider = new Provider();
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit = async (event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
const { query } = this.state;
|
|
||||||
|
|
||||||
const results = await this.provider.search({ query });
|
|
||||||
this.setState({
|
|
||||||
results,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onKeyUp = (event) => {
|
|
||||||
if (specialKeys.includes(event.code)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const query = event.target.value;
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
query,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.autoSearch(event);
|
|
||||||
};
|
|
||||||
|
|
||||||
onKeyDown = (event) => {
|
|
||||||
if (event.code === 'Escape') {
|
|
||||||
this.reset();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.code !== 'ArrowDown' && event.code !== 'ArrowUp') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
const { selected = -1, results } = this.state;
|
|
||||||
const max = results.length - 1;
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-bitwise
|
|
||||||
const next = (event.code === 'ArrowDown') ? ~~selected + 1 : ~~selected - 1;
|
|
||||||
// eslint-disable-next-line no-nested-ternary
|
|
||||||
const idx = (next < 0) ? max : (next > max) ? 0 : next;
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
selected: idx,
|
|
||||||
query: results[idx].label,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onFocus = () => {
|
|
||||||
this.setState({ isActive: true });
|
|
||||||
};
|
|
||||||
|
|
||||||
onBlur = () => {
|
|
||||||
this.setState({ isActive: false });
|
|
||||||
};
|
|
||||||
|
|
||||||
autoSearch = debounce((event) => {
|
|
||||||
this.onSubmit(event);
|
|
||||||
}, 250);
|
|
||||||
|
|
||||||
reset() {
|
|
||||||
this.setState({
|
|
||||||
results: [],
|
|
||||||
selected: -1,
|
|
||||||
query: '',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { results, selected, query, isActive } = this.state;
|
|
||||||
|
|
||||||
const className = [
|
|
||||||
styles.search,
|
|
||||||
(isActive ? 'active' : ''),
|
|
||||||
].join(' ').trim();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={className}>
|
|
||||||
<form onSubmit={this.onSubmit}>
|
|
||||||
<input
|
|
||||||
onKeyUp={this.onKeyUp}
|
|
||||||
onKeyDown={this.onKeyDown}
|
|
||||||
onFocus={this.onFocus}
|
|
||||||
onBlur={this.onBlur}
|
|
||||||
type="text"
|
|
||||||
placeholder="search"
|
|
||||||
value={query}
|
|
||||||
/>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
{results &&
|
|
||||||
<SearchResults results={results} selected={selected} />
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Search;
|
|
||||||
@@ -25,3 +25,19 @@
|
|||||||
text-indent: 18px;
|
text-indent: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.result > * {
|
||||||
|
border: 1px solid transparent;
|
||||||
|
line-height: 32px;
|
||||||
|
padding: 0 18px;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result > *:hover,
|
||||||
|
.result > :global(.active) {
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
border-color: #c6c6c6;
|
||||||
|
}
|
||||||
38
docs/components/Search.tsx
Normal file
38
docs/components/Search.tsx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import React, { useState, useEffect, ReactElement } from 'react';
|
||||||
|
import * as providers from '../../src/providers';
|
||||||
|
import styles from './Search.module.css';
|
||||||
|
import { MapProps } from './Map';
|
||||||
|
|
||||||
|
interface SearchProps {
|
||||||
|
provider: MapProps['provider'];
|
||||||
|
providerOptions: MapProps['providerOptions'];
|
||||||
|
}
|
||||||
|
|
||||||
|
function Search(props: SearchProps): ReactElement {
|
||||||
|
// @ts-ignore
|
||||||
|
const Provider = providers[`${props.provider}Provider`] || providers.OpenStreetMapProvider;
|
||||||
|
const provider = new Provider(props.providerOptions || {});
|
||||||
|
|
||||||
|
const [query, setQuery] = useState('');
|
||||||
|
const [results, setResults] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
provider.search({ query }).then((results: object[]) => setResults(results.slice(0, 5)));
|
||||||
|
}, [query]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.search}>
|
||||||
|
<form>
|
||||||
|
<input type="text" placeholder="search" value={query} onChange={(e) => setQuery(e.target.value)} />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div className={styles.result}>
|
||||||
|
{results.map((result, idx) => (
|
||||||
|
<div key={idx}>{result.label}</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Search;
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
.item > * {
|
|
||||||
border: 1px solid transparent;
|
|
||||||
line-height: 32px;
|
|
||||||
padding: 0 18px;
|
|
||||||
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item > *:hover,
|
|
||||||
.item > :global(.active) {
|
|
||||||
background-color: #f8f8f8;
|
|
||||||
border-color: #c6c6c6;
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import preact from 'preact';
|
|
||||||
import styles from './SearchResults.css';
|
|
||||||
|
|
||||||
const SearchResults = ({ results = [], selected }) => (
|
|
||||||
<div className={styles.item}>
|
|
||||||
{results.map((result, idx) => (
|
|
||||||
<div className={idx === selected && 'active'}>{result.label}</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default SearchResults;
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
export { default as Layout } from './Layout';
|
|
||||||
export { default as Map } from './Map';
|
|
||||||
export { default as Search } from './Search';
|
|
||||||
10
docs/dist/bundle.min.js
vendored
10
docs/dist/bundle.min.js
vendored
File diff suppressed because one or more lines are too long
1
docs/dist/style.css
vendored
1
docs/dist/style.css
vendored
@@ -1 +0,0 @@
|
|||||||
.Code__code___31Vg8{position:absolute;top:110px;right:10px;bottom:10px;width:425px;background:rgba(0,0,0,.7);color:#fff;border-radius:4px;padding:24px;font-family:Roboto,monospace;white-space:pre;font-size:14px;line-height:22px}.Layout__header___33oX6{position:relative;width:100%;height:100px;padding:0 0 0 20px}.Layout__header___33oX6 h1{font-family:Roboto,sans-serif;font-size:32px;font-weight:300;line-height:64px;margin:0;padding:0}.Layout__header___33oX6 ul{list-style:none;display:block;overflow:hidden;margin:0;padding:0;line-height:32px}.Layout__header___33oX6 ul li{float:left;display:block;cursor:pointer}.Layout__header___33oX6 ul li:hover{border-bottom:4px solid #00bcd4}.Layout__header___33oX6 ul li.active{border-bottom:4px solid #2196f3}.Layout__header___33oX6 ul li a{text-decoration:none;color:inherit;display:block;width:100%;height:100%;padding:0 24px}.Layout__content___GDRpI{position:absolute;top:100px;bottom:0;left:20px;right:465px}.Layout__fullWidth___2Qlah{left:0;right:0}.Map__map___2UbOE{position:absolute;display:block;width:100%;height:100%}.SearchResults__item___3yUT->*{border:1px solid transparent;line-height:32px;padding:0 18px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.SearchResults__item___3yUT->.active,.SearchResults__item___3yUT->:hover{background-color:#f8f8f8;border-color:#c6c6c6}.Search__search___2kQjw form{position:relative;margin:32px 0;background-color:#fff;vertical-align:top;border-radius:2px;box-shadow:0 2px 2px 0 rgba(0,0,0,.16),0 0 0 1px rgba(0,0,0,.08);transition:box-shadow .2s cubic-bezier(.4,0,.2,1)}.Search__search___2kQjw.active form,.Search__search___2kQjw form:hover{box-shadow:0 3px 8px 0 rgba(0,0,0,.2),0 0 0 1px rgba(0,0,0,.08)}.Search__search___2kQjw input{border:none;padding:0;margin:0;width:100%;outline:none;font:16px arial,sans-serif;line-height:48px;height:48px;text-indent:18px}body,html{font-family:Open Sans,sans-serif;margin:0;padding:0;height:100%;width:100%}*,:after,:before,body,html{box-sizing:border-box}.leaflet-control-geosearch.bar{position:absolute!important;left:50px;right:515px}
|
|
||||||
34
docs/hooks/useConfigureLeaflet.ts
Normal file
34
docs/hooks/useConfigureLeaflet.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import L from 'leaflet';
|
||||||
|
|
||||||
|
import isDomAvailable from '../lib/isDomAvailable';
|
||||||
|
import { Viewport } from 'react-leaflet';
|
||||||
|
|
||||||
|
const viewport: Viewport = {
|
||||||
|
center: [53.2, 5.8],
|
||||||
|
zoom: 12,
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface LeafletConfig {
|
||||||
|
viewport: Viewport;
|
||||||
|
}
|
||||||
|
|
||||||
|
const useConfigureLeaflet = (): LeafletConfig => {
|
||||||
|
if (!isDomAvailable()) return;
|
||||||
|
|
||||||
|
// To get around an issue with the default icon not being set up right between using React
|
||||||
|
// and importing the leaflet library, we need to reset the image imports
|
||||||
|
// See https://github.com/PaulLeCam/react-leaflet/issues/453#issuecomment-410450387
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
delete L.Icon.Default.prototype._getIconUrl;
|
||||||
|
|
||||||
|
L.Icon.Default.mergeOptions({
|
||||||
|
iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
|
||||||
|
iconUrl: require('leaflet/dist/images/marker-icon.png'),
|
||||||
|
shadowUrl: require('leaflet/dist/images/marker-shadow.png'),
|
||||||
|
});
|
||||||
|
|
||||||
|
return { viewport };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useConfigureLeaflet;
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Leaflet.GeoSearch / Google Provider</title>
|
|
||||||
|
|
||||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans|Roboto" rel="stylesheet">
|
|
||||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@0.7.7/dist/leaflet.css" />
|
|
||||||
<script src="https://unpkg.com/leaflet@0.7.7/dist/leaflet.js"></script>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
handleOnLoad = function() {
|
|
||||||
L.Icon.Default.imagePath = 'https://unpkg.com/leaflet@0.7.7/dist/images/';
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="dist/style.css" />
|
|
||||||
<link rel="stylesheet" href="https://unpkg.com/leaflet-geosearch@latest/assets/css/leaflet.css" />
|
|
||||||
</head>
|
|
||||||
<body onload="handleOnLoad()">
|
|
||||||
<div id="app"></div>
|
|
||||||
|
|
||||||
<script type="text/javascript" src="dist/bundle.min.js" charset="utf-8"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
44
docs/introduction.mdx
Normal file
44
docs/introduction.mdx
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
---
|
||||||
|
name: Introduction
|
||||||
|
route: /
|
||||||
|
---
|
||||||
|
|
||||||
|
import { Link } from 'docz';
|
||||||
|
import Playground from './components/Playground';
|
||||||
|
import Map from './components/Map';
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
`leaflet-geosearch` adds support for geocoding (address lookup, a.k.a. geoseaching) to your (web) application. It comes with controls to be embedded in your Leaflet map.
|
||||||
|
|
||||||
|
|
||||||
|
We support the following providers out-of-the-box; [Bing](/providers/bing), [Esri](/providers/esri), [Google](/providers/google), [OpenStreetMap](/providers/openstreetmap), [LocationIQ](/providers/locationiq), [OpenCage](/providers/opencage).
|
||||||
|
|
||||||
|
Although this project is named `leaflet-geosearch`, this library is also usable without LeafletJS, and does not have any dependencies on Leaflet whatsoever.
|
||||||
|
|
||||||
|
<Playground>
|
||||||
|
<Map />
|
||||||
|
</Playground>
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save leaflet-geosearch
|
||||||
|
```
|
||||||
|
|
||||||
|
## Providers
|
||||||
|
`leaflet-geosearch` uses so-called "providers" to take care of building the correct service URL and parsing the retrieved data into a uniform format. Thanks to this architecture, it is trivial to add your own providers, so you can use your own geocoding service.
|
||||||
|
|
||||||
|
When [`OpenStreetMap`](/providers/openstreet) does not match your needs; you can also choose to use the [`Bing`](/providers/bing), [`Esri`](/providers/esri), [`Google`](/providers/google), [`LocationIQ`](/providers/locationiq), or [`OpenCage`](/providers/opencage) providers. Most of those providers do however require `API keys`. See the documentation pages on the relevant organisations on how to obtain these keys.
|
||||||
|
|
||||||
|
In case you decide to write your own provider, please consider submitting a PR to share your work with us.
|
||||||
|
|
||||||
|
Providers are unaware of any options you can give them. They are simple proxies to their endpoints. There is only one special property, and that is the `params` option. The difference being; that `params` will be included in the endpoint url. Being Often used for `API KEYS`, while the other attributes can be used for provider configuration.
|
||||||
|
|
||||||
|
## Browser support / Polyfills
|
||||||
|
This project is written with the latest technologies in mind. Thereby it is required to include some polyfills when you wish to support older browsers. These polyfills are recommended for IE and Safari support:
|
||||||
|
|
||||||
|
- [babel-polyfill][1], for `array.includes` support.
|
||||||
|
- [unfetch][2], for `fetch` requests.
|
||||||
|
|
||||||
|
[1]: https://npm.im/babel-polyfill
|
||||||
|
[2]: https://npm.im/unfetch
|
||||||
24
docs/main.js
24
docs/main.js
@@ -1,24 +0,0 @@
|
|||||||
// polyfills
|
|
||||||
import 'babel-polyfill';
|
|
||||||
import 'whatwg-fetch';
|
|
||||||
|
|
||||||
import preact, { render } from 'preact';
|
|
||||||
import { Layout } from './components';
|
|
||||||
import pages from './pages';
|
|
||||||
|
|
||||||
import './assets/css/style.css';
|
|
||||||
|
|
||||||
// import css to enable hot reloading
|
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
|
||||||
/* eslint-disable global-require */
|
|
||||||
require('./index.html');
|
|
||||||
require('../assets/css/leaflet.css');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (location.hash === '') {
|
|
||||||
location.hash = 'search';
|
|
||||||
}
|
|
||||||
|
|
||||||
render((
|
|
||||||
<Layout pages={pages} />
|
|
||||||
), document.getElementById('app'));
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
import preact from 'preact';
|
|
||||||
|
|
||||||
import { Search, Map } from './components';
|
|
||||||
import {
|
|
||||||
OpenStreetMapProvider,
|
|
||||||
GoogleProvider,
|
|
||||||
BingProvider,
|
|
||||||
EsriProvider,
|
|
||||||
} from '../src/providers';
|
|
||||||
|
|
||||||
const BING_KEY = 'AtUDjSVEBxo8BwgYUPdfnzHpznaYwDdjjS27jyFDj18nhTUDUjrhc0NwMndZvrXs';
|
|
||||||
const GOOGLE_KEY = 'AIzaSyDigZ5WMPoTj_gnkUn3p1waYPDa5oE8WOw';
|
|
||||||
|
|
||||||
/* eslint-disable import/no-webpack-loader-syntax, global-require, import/no-unresolved */
|
|
||||||
export default [
|
|
||||||
{
|
|
||||||
slug: 'search',
|
|
||||||
title: 'Search',
|
|
||||||
view: () => (<Search />),
|
|
||||||
code: require('!!raw!./snippets/search'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
slug: 'openstreetmap',
|
|
||||||
title: 'OpenStreetMap',
|
|
||||||
view: () => (<Map Provider={OpenStreetMapProvider} options={{ style: 'bar' }} />),
|
|
||||||
code: require('!!raw!./snippets/openstreetmap'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
slug: 'google',
|
|
||||||
title: 'Google',
|
|
||||||
view: () => {
|
|
||||||
const Provider = new GoogleProvider({ params: {
|
|
||||||
key: GOOGLE_KEY,
|
|
||||||
} });
|
|
||||||
|
|
||||||
return <Map Provider={Provider} />;
|
|
||||||
},
|
|
||||||
code: require('!!raw!./snippets/google'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
slug: 'bing',
|
|
||||||
title: 'Bing',
|
|
||||||
view: () => {
|
|
||||||
const Provider = new BingProvider({ params: {
|
|
||||||
key: BING_KEY,
|
|
||||||
} });
|
|
||||||
|
|
||||||
return <Map Provider={Provider} />;
|
|
||||||
},
|
|
||||||
code: require('!!raw!./snippets/bing'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
slug: 'esri',
|
|
||||||
title: 'Esri',
|
|
||||||
view: () => (<Map Provider={EsriProvider} />),
|
|
||||||
code: require('!!raw!./snippets/esri'),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
38
docs/providers/bing.mdx
Normal file
38
docs/providers/bing.mdx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
name: Bing
|
||||||
|
menu: Providers
|
||||||
|
route: /providers/bing
|
||||||
|
---
|
||||||
|
|
||||||
|
import Playground from '../components/Playground';
|
||||||
|
import Map from '../components/Map';
|
||||||
|
|
||||||
|
# Bing Provider
|
||||||
|
|
||||||
|
**note**: Bing services require an API key. [Obtain here][1].
|
||||||
|
For more options and configurations, see the [Microsoft developer docs][2].
|
||||||
|
|
||||||
|
<Playground>
|
||||||
|
<Map provider="Bing" />
|
||||||
|
</Playground>
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { BingProvider } from 'leaflet-geosearch';
|
||||||
|
|
||||||
|
const provider = new BingProvider({
|
||||||
|
params: {
|
||||||
|
key: '__YOUR_BING_KEY__'
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// add to leaflet
|
||||||
|
import { GeoSearchControl } from 'leaflet-geosearch';
|
||||||
|
|
||||||
|
map.addControl(new GeoSearchControl({
|
||||||
|
provider,
|
||||||
|
}));
|
||||||
|
```
|
||||||
|
|
||||||
|
[1]: https://docs.microsoft.com/en-us/bingmaps/getting-started/bing-maps-dev-center-help/getting-a-bing-maps-key
|
||||||
|
[2]: https://docs.microsoft.com/en-us/bingmaps/rest-services/locations/find-a-location-by-address
|
||||||
31
docs/providers/esri.mdx
Normal file
31
docs/providers/esri.mdx
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
name: Esri
|
||||||
|
menu: Providers
|
||||||
|
route: /providers/esri
|
||||||
|
---
|
||||||
|
|
||||||
|
import Playground from '../components/Playground';
|
||||||
|
import Map from '../components/Map';
|
||||||
|
|
||||||
|
# Esri Provider
|
||||||
|
For more options and configurations, see the [ArcGIS developer docs][1].
|
||||||
|
|
||||||
|
<Playground>
|
||||||
|
<Map provider="Esri" />
|
||||||
|
</Playground>
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { EsriProvider } from 'leaflet-geosearch';
|
||||||
|
|
||||||
|
const provider = new EsriProvider();
|
||||||
|
|
||||||
|
// add to leaflet
|
||||||
|
import { GeoSearchControl } from 'leaflet-geosearch';
|
||||||
|
|
||||||
|
map.addControl(new GeoSearchControl({
|
||||||
|
provider,
|
||||||
|
}));
|
||||||
|
```
|
||||||
|
|
||||||
|
[1]: https://developers.arcgis.com/rest/geocode/api-reference/overview-world-geocoding-service.htm
|
||||||
38
docs/providers/google.mdx
Normal file
38
docs/providers/google.mdx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
name: Google
|
||||||
|
menu: Providers
|
||||||
|
route: /providers/google
|
||||||
|
---
|
||||||
|
|
||||||
|
import Playground from '../components/Playground';
|
||||||
|
import Map from '../components/Map';
|
||||||
|
|
||||||
|
# Google Provider
|
||||||
|
|
||||||
|
**note**: Google services require an API key. [Obtain here][1].
|
||||||
|
For more options and configurations, see the [Google Maps developer docs][2].
|
||||||
|
|
||||||
|
<Playground>
|
||||||
|
<Map provider="Google" />
|
||||||
|
</Playground>
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { GoogleProvider } from 'leaflet-geosearch';
|
||||||
|
|
||||||
|
const provider = new GoogleProvider({
|
||||||
|
params: {
|
||||||
|
key: '__YOUR_GOOGLE_KEY__'
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// add to leaflet
|
||||||
|
import { GeoSearchControl } from 'leaflet-geosearch';
|
||||||
|
|
||||||
|
map.addControl(new GeoSearchControl({
|
||||||
|
provider,
|
||||||
|
}));
|
||||||
|
```
|
||||||
|
|
||||||
|
[1]: https://developers.google.com/maps/documentation/javascript/get-api-key
|
||||||
|
[2]: https://developers.google.com/maps/documentation/geocoding/start
|
||||||
38
docs/providers/locationIq.mdx
Normal file
38
docs/providers/locationIq.mdx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
name: LocationIQ
|
||||||
|
menu: Providers
|
||||||
|
route: /providers/locationiq
|
||||||
|
---
|
||||||
|
|
||||||
|
import Playground from '../components/Playground';
|
||||||
|
import Map from '../components/Map';
|
||||||
|
|
||||||
|
# LocationIQ Provider
|
||||||
|
|
||||||
|
**note**: LocationIQ services require an API key. [Obtain here][1].
|
||||||
|
For more options and configurations, see the [LocationIQ developer docs][2].
|
||||||
|
|
||||||
|
<Playground>
|
||||||
|
<Map provider="LocationIQ" />
|
||||||
|
</Playground>
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { LocationIQProvider } from 'leaflet-geosearch';
|
||||||
|
|
||||||
|
const provider = new LocationIQProvider({
|
||||||
|
params: {
|
||||||
|
key: '__YOUR_LOCATIONIQ_KEY__'
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// add to leaflet
|
||||||
|
import { GeoSearchControl } from 'leaflet-geosearch';
|
||||||
|
|
||||||
|
map.addControl(new GeoSearchControl({
|
||||||
|
provider,
|
||||||
|
}));
|
||||||
|
```
|
||||||
|
|
||||||
|
[1]: https://locationiq.org
|
||||||
|
[2]: https://locationiq.org/#docs
|
||||||
38
docs/providers/opencage.mdx
Normal file
38
docs/providers/opencage.mdx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
name: OpenCage
|
||||||
|
menu: Providers
|
||||||
|
route: /providers/opencage
|
||||||
|
---
|
||||||
|
|
||||||
|
import Playground from '../components/Playground';
|
||||||
|
import Map from '../components/Map';
|
||||||
|
|
||||||
|
# OpenCage Provider
|
||||||
|
|
||||||
|
**note**: OpenCage services require an API key. [Obtain here][1].
|
||||||
|
For more options and configurations, see the [OpenCage developer docs][2].
|
||||||
|
|
||||||
|
<Playground>
|
||||||
|
<Map provider="OpenCage" />
|
||||||
|
</Playground>
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { OpenCageProvider } from 'leaflet-geosearch';
|
||||||
|
|
||||||
|
const provider = new OpenCageProvider({
|
||||||
|
params: {
|
||||||
|
key: '__YOUR_OPENCAGE_KEY__'
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// add to leaflet
|
||||||
|
import { GeoSearchControl } from 'leaflet-geosearch';
|
||||||
|
|
||||||
|
map.addControl(new GeoSearchControl({
|
||||||
|
provider,
|
||||||
|
}));
|
||||||
|
```
|
||||||
|
|
||||||
|
[1]: https://geocoder.opencagedata.com
|
||||||
|
[2]: https://geocoder.opencagedata.com/api
|
||||||
32
docs/providers/openstreetmap.mdx
Normal file
32
docs/providers/openstreetmap.mdx
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
name: OpenStreetMap
|
||||||
|
menu: Providers
|
||||||
|
route: /providers/openstreetmap
|
||||||
|
---
|
||||||
|
|
||||||
|
import Playground from '../components/Playground';
|
||||||
|
import Map from '../components/Map';
|
||||||
|
|
||||||
|
# OpenStreetMap Provider
|
||||||
|
|
||||||
|
For more options and configurations, see the [OpenStreetMap Nominatim wiki][1].
|
||||||
|
|
||||||
|
<Playground>
|
||||||
|
<Map provider="OpenStreetMap" />
|
||||||
|
</Playground>
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { OpenStreetMapProvider } from 'leaflet-geosearch';
|
||||||
|
|
||||||
|
const provider = new OpenStreetMapProvider();
|
||||||
|
|
||||||
|
// add to leaflet
|
||||||
|
import { GeoSearchControl } from 'leaflet-geosearch'; import {OpenStreetMapProvider} from "./index";
|
||||||
|
|
||||||
|
map.addControl(new GeoSearchControl({
|
||||||
|
provider,
|
||||||
|
}));
|
||||||
|
```
|
||||||
|
|
||||||
|
[1]: http://wiki.openstreetmap.org/wiki/Nominatim
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import L from 'leaflet';
|
|
||||||
import {
|
|
||||||
GeoSearchControl,
|
|
||||||
BingProvider,
|
|
||||||
} from 'leaflet-geosearch';
|
|
||||||
|
|
||||||
const provider = new BingProvider({ params: {
|
|
||||||
key: '__YOUR_BING_KEY__'
|
|
||||||
} });
|
|
||||||
|
|
||||||
const searchControl = new GeoSearchControl({
|
|
||||||
provider: provider,
|
|
||||||
});
|
|
||||||
|
|
||||||
const map = new L.Map('map');
|
|
||||||
map.addControl(searchControl);
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import L from 'leaflet';
|
|
||||||
import {
|
|
||||||
GeoSearchControl,
|
|
||||||
EsriProvider,
|
|
||||||
} from 'leaflet-geosearch';
|
|
||||||
|
|
||||||
const provider = new EsriProvider();
|
|
||||||
|
|
||||||
const searchControl = new GeoSearchControl({
|
|
||||||
provider: provider,
|
|
||||||
});
|
|
||||||
|
|
||||||
const map = new L.Map('map');
|
|
||||||
map.addControl(searchControl);
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import L from 'leaflet';
|
|
||||||
import {
|
|
||||||
GeoSearchControl,
|
|
||||||
GoogleProvider,
|
|
||||||
} from 'leaflet-geosearch';
|
|
||||||
|
|
||||||
const provider = new GoogleProvider({ params: {
|
|
||||||
key: '__YOUR_GOOGLE_KEY__',
|
|
||||||
} });
|
|
||||||
|
|
||||||
const searchControl = new GeoSearchControl({
|
|
||||||
provider: provider,
|
|
||||||
});
|
|
||||||
|
|
||||||
const map = new L.Map('map');
|
|
||||||
map.addControl(searchControl);
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import L from 'leaflet';
|
|
||||||
import {
|
|
||||||
GeoSearchControl,
|
|
||||||
OpenStreetMapProvider,
|
|
||||||
} from 'leaflet-geosearch';
|
|
||||||
|
|
||||||
const provider = new OpenStreetMapProvider();
|
|
||||||
|
|
||||||
const searchControl = new GeoSearchControl({
|
|
||||||
provider: provider,
|
|
||||||
});
|
|
||||||
|
|
||||||
const map = new L.Map('map');
|
|
||||||
map.addControl(searchControl);
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import {
|
|
||||||
OpenStreetMapProvider,
|
|
||||||
} from 'leaflet-geosearch';
|
|
||||||
|
|
||||||
const provider = new OpenStreetMapProvider();
|
|
||||||
|
|
||||||
const form = document.querySelector('form');
|
|
||||||
const input = form.querySelector('input[type="text"]');
|
|
||||||
|
|
||||||
form.addEventListener('submit', (event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
provider.search({ query: input.value }).then((results) => {
|
|
||||||
console.log(results);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
62
docs/usage.mdx
Normal file
62
docs/usage.mdx
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
---
|
||||||
|
name: Usage
|
||||||
|
route: /usage
|
||||||
|
---
|
||||||
|
|
||||||
|
import Playground from './components/Playground';
|
||||||
|
import Map from './components/Map';
|
||||||
|
import Search from './components/Search';
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
There are two ways in which `leaflet-geosearch` can be used. Direct usage, for example for address forms, or embedded in a leaflet map to search for points of interest.
|
||||||
|
|
||||||
|
## Using the providers directly
|
||||||
|
|
||||||
|
All providers can be used without leaflet. You might want to bind them to a form;
|
||||||
|
|
||||||
|
<Playground>
|
||||||
|
<Search provider="OpenStreetMap" />
|
||||||
|
</Playground>
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { OpenStreetMapProvider } from 'leaflet-geosearch';
|
||||||
|
|
||||||
|
const provider = new OpenStreetMapProvider();
|
||||||
|
const results = await provider.search({ query: input.value });
|
||||||
|
```
|
||||||
|
|
||||||
|
## Using the leaflet control
|
||||||
|
Or add the `GeoSearchControl` to the leaflet map instance, to render a search control on your map;
|
||||||
|
|
||||||
|
<Playground>
|
||||||
|
<Map provider="OpenStreetMap" />
|
||||||
|
</Playground>
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { GeoSearchControl, OpenStreetMapProvider } from 'leaflet-geosearch';
|
||||||
|
|
||||||
|
const searchControl = new GeoSearchControl({
|
||||||
|
provider: new OpenStreetMapProvider(),
|
||||||
|
});
|
||||||
|
|
||||||
|
map.addControl(searchControl);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Results
|
||||||
|
|
||||||
|
The search event of all providers return an array of `result` objects. The base structure is uniform between the providers. It contains objects matching the following interface:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
interface result {
|
||||||
|
x: number; // lon
|
||||||
|
y: number; // lat
|
||||||
|
label: string; // formatted address
|
||||||
|
bounds: [
|
||||||
|
[number, number], // south, west - lat, lon
|
||||||
|
[number, number], // north, east - lat, lon
|
||||||
|
],
|
||||||
|
raw: any, // raw provider result
|
||||||
|
}
|
||||||
|
```
|
||||||
16
doczrc.js
Normal file
16
doczrc.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
export default {
|
||||||
|
title: 'Leaflet GeoSearch',
|
||||||
|
typescript: true,
|
||||||
|
themeConfig: {
|
||||||
|
showPlaygroundEditor: true,
|
||||||
|
},
|
||||||
|
src: 'docs',
|
||||||
|
dest: '.docz/dist',
|
||||||
|
public: 'assets',
|
||||||
|
ignore: ['CODE_OF_CONDUCT.md', 'CONTRIBUTING.md', 'LICENSE.md'],
|
||||||
|
menu: [
|
||||||
|
{ name: 'Introduction' },
|
||||||
|
{ name: 'Usage' },
|
||||||
|
{ name: 'Providers', menu: ['Bing', 'Esri', 'Google', 'LocationIQ', 'OpenCage', 'OpenStreetMap'] },
|
||||||
|
],
|
||||||
|
};
|
||||||
1
gatsby-browser.js
Normal file
1
gatsby-browser.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import './static/assets/css/docs.css';
|
||||||
3
gatsby-config.js
Normal file
3
gatsby-config.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
require('dotenv').config({
|
||||||
|
path: '.env',
|
||||||
|
});
|
||||||
16
gatsby-node.js
Normal file
16
gatsby-node.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
exports.onCreateWebpackConfig = ({ stage, rules, loaders, actions }) => {
|
||||||
|
switch (stage) {
|
||||||
|
case 'build-html':
|
||||||
|
actions.setWebpackConfig({
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /react-leaflet|leaflet/,
|
||||||
|
use: [loaders.null()],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
26408
package-lock.json
generated
Normal file
26408
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
94
package.json
94
package.json
@@ -8,22 +8,11 @@
|
|||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"module": "src/index.js",
|
"module": "src/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:commonjs": "babel src --out-dir lib --ignore *.spec.js",
|
"lint": "tsc --noEmit && eslint 'src/**/*.{js,ts,tsx}' --quiet --fix",
|
||||||
"build:umd": "cross-env NODE_ENV=development webpack",
|
"docz:dev": "docz dev",
|
||||||
"build:umd:min": "cross-env NODE_ENV=production webpack",
|
"docz:build": "docz build",
|
||||||
"build:watch": "npm run build:umd -- --watch",
|
"docz:serve": "docz build && docz serve",
|
||||||
"build": "npm run clean && npm run build:commonjs && npm run build:umd && npm run build:umd:min && npm run build:docs",
|
"docz:publish": "git stash && git checkout -b gh-pages && git checkout stash@{0} -- ./docs && git add . && git commit -m \"update docs\" && git checkout - && git stash pop"
|
||||||
"build:docs": "cross-env NODE_ENV=production webpack --config webpack.docs.config.babel.js",
|
|
||||||
"clean": "rimraf lib dist",
|
|
||||||
"lint": "esw src webpack.config --color",
|
|
||||||
"lint:fix": "npm run lint -- --fix",
|
|
||||||
"lint:watch": "npm run lint -- --watch",
|
|
||||||
"prepublish": "npm run lint && npm run test && npm run build",
|
|
||||||
"test": "ava",
|
|
||||||
"test:watch": "ava -w",
|
|
||||||
"test:cover": "nyc ava",
|
|
||||||
"test:report": "nyc report --reporter html",
|
|
||||||
"start": "webpack-dev-server"
|
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"src",
|
"src",
|
||||||
@@ -34,6 +23,9 @@
|
|||||||
"directories": {
|
"directories": {
|
||||||
"example": "example"
|
"example": "example"
|
||||||
},
|
},
|
||||||
|
"resolutions": {
|
||||||
|
"docz/**/webpack": "4.28.4"
|
||||||
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"geolocation",
|
"geolocation",
|
||||||
"geocoding",
|
"geocoding",
|
||||||
@@ -53,59 +45,25 @@
|
|||||||
"homepage": "https://github.com/smeijer/leaflet-geosearch#readme",
|
"homepage": "https://github.com/smeijer/leaflet-geosearch#readme",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"ava": "^0.17.0",
|
"@types/lodash.debounce": "^4.0.6",
|
||||||
"babel-cli": "^6.18.0",
|
"@types/react-leaflet": "^2.5.1",
|
||||||
"babel-core": "^6.21.0",
|
"@typescript-eslint/eslint-plugin": "^2.27.0",
|
||||||
"babel-eslint": "^7.1.1",
|
"@typescript-eslint/parser": "^2.27.0",
|
||||||
"babel-loader": "^6.2.10",
|
"docz": "^2.3.1",
|
||||||
"babel-plugin-transform-class-properties": "^6.19.0",
|
"docz-theme-default": "^1.2.0",
|
||||||
"babel-plugin-transform-export-extensions": "^6.8.0",
|
"eslint": "^6.8.0",
|
||||||
"babel-plugin-transform-object-rest-spread": "^6.20.2",
|
"eslint-config-prettier": "^6.10.1",
|
||||||
"babel-plugin-transform-react-jsx": "^6.8.0",
|
"eslint-plugin-prettier": "^3.1.2",
|
||||||
"babel-polyfill": "^6.23.0",
|
"eslint-plugin-react": "^7.19.0",
|
||||||
"babel-preset-es2015": "^6.18.0",
|
"gatsby-plugin-react-leaflet": "^2.0.12",
|
||||||
"babel-preset-power-assert": "^1.0.0",
|
"leaflet": "^1.6.0",
|
||||||
"browser-env": "^2.0.19",
|
"prettier": "^2.0.4",
|
||||||
"cross-env": "^3.1.3",
|
"react": "^16.13.1",
|
||||||
"css-loader": "^0.26.1",
|
"react-dom": "^16.13.1",
|
||||||
"dotenv": "^2.0.0",
|
"react-leaflet": "^2.6.3",
|
||||||
"eslint": "^3.12.2",
|
"typescript": "^3.8.3"
|
||||||
"eslint-config-airbnb": "^13.0.0",
|
|
||||||
"eslint-plugin-import": "^2.2.0",
|
|
||||||
"eslint-plugin-jsx-a11y": "^2.2.3",
|
|
||||||
"eslint-plugin-react": "^6.8.0",
|
|
||||||
"eslint-watch": "^2.1.14",
|
|
||||||
"extract-text-webpack-plugin": "^1.0.1",
|
|
||||||
"fast-async": "^6.1.2",
|
|
||||||
"leaflet": "^1.0.2",
|
|
||||||
"lodash.merge": "^4.6.0",
|
|
||||||
"microlight": "0.0.7",
|
|
||||||
"node-fetch": "^1.6.3",
|
|
||||||
"npm": "^4.0.5",
|
|
||||||
"power-assert": "^1.4.2",
|
|
||||||
"preact": "^8.1.0",
|
|
||||||
"raw-loader": "^0.5.1",
|
|
||||||
"rimraf": "^2.5.4",
|
|
||||||
"style-loader": "^0.13.1",
|
|
||||||
"testdouble": "^1.10.1",
|
|
||||||
"webpack": "^1.14.0",
|
|
||||||
"webpack-dev-server": "^3.1.11",
|
|
||||||
"whatwg-fetch": "^2.0.3"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lodash.debounce": "^4.0.8",
|
"lodash.debounce": "^4.0.8"
|
||||||
"nodent-runtime": "^3.0.4"
|
|
||||||
},
|
|
||||||
"ava": {
|
|
||||||
"files": [
|
|
||||||
"./src/**/__tests__/**.spec.js"
|
|
||||||
],
|
|
||||||
"require": [
|
|
||||||
"nodent-runtime",
|
|
||||||
"dotenv/config",
|
|
||||||
"babel-core/register",
|
|
||||||
"./test/browserEnv"
|
|
||||||
],
|
|
||||||
"babel": "inherit"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,4 +2,7 @@ export { default as BingProvider } from './bingProvider';
|
|||||||
export { default as EsriProvider } from './esriProvider';
|
export { default as EsriProvider } from './esriProvider';
|
||||||
export { default as GoogleProvider } from './googleProvider';
|
export { default as GoogleProvider } from './googleProvider';
|
||||||
export { default as OpenStreetMapProvider } from './openStreetMapProvider';
|
export { default as OpenStreetMapProvider } from './openStreetMapProvider';
|
||||||
|
export { default as OpenCageProvider } from './openCageProvider';
|
||||||
|
export { default as LocationIQProvider } from './locationIQProvider';
|
||||||
|
|
||||||
export { default as Provider } from './provider';
|
export { default as Provider } from './provider';
|
||||||
|
|||||||
24
tsconfig.json
Normal file
24
tsconfig.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"removeComments": true,
|
||||||
|
"preserveConstEnums": true,
|
||||||
|
"outFile": "./dist/tsc.js",
|
||||||
|
"sourceMap": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"allowJs": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"jsx": "preserve"
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*",
|
||||||
|
"docs/**/*",
|
||||||
|
"typings"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"**/*.spec.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
1
typings/declarations.d.ts
vendored
Normal file
1
typings/declarations.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
declare module '*.module.css';
|
||||||
36
wallaby.js
36
wallaby.js
@@ -1,36 +0,0 @@
|
|||||||
/* eslint-disable no-unused-vars, global-require, import/no-extraneous-dependencies */
|
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
process.env.BABEL_ENV = 'test';
|
|
||||||
process.env.NODE_ENV = 'production';
|
|
||||||
|
|
||||||
module.exports = wallaby => ({
|
|
||||||
files: [
|
|
||||||
'src/**/*.js',
|
|
||||||
'test/**/*.js',
|
|
||||||
'!src/**/__tests__/**/*.spec.js',
|
|
||||||
],
|
|
||||||
tests: [
|
|
||||||
'src/**/__tests__/**/*.spec.js',
|
|
||||||
],
|
|
||||||
compilers: {
|
|
||||||
'**/*.js': wallaby.compilers.babel(),
|
|
||||||
},
|
|
||||||
env: {
|
|
||||||
type: 'node',
|
|
||||||
params: {
|
|
||||||
env: [
|
|
||||||
'NODE_ENV=production',
|
|
||||||
].join(';'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
debug: false,
|
|
||||||
testFramework: 'ava',
|
|
||||||
setup: () => {
|
|
||||||
require('dotenv').config({
|
|
||||||
path: `${wallaby.localProjectDir}/.env`,
|
|
||||||
});
|
|
||||||
|
|
||||||
require('./test/browserEnv');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
import webpack from 'webpack';
|
|
||||||
import path from 'path';
|
|
||||||
import ExtractTextPlugin from 'extract-text-webpack-plugin';
|
|
||||||
|
|
||||||
const { NODE_ENV } = process.env;
|
|
||||||
const production = NODE_ENV === 'production';
|
|
||||||
|
|
||||||
const plugins = [
|
|
||||||
new webpack.optimize.OccurenceOrderPlugin(),
|
|
||||||
new webpack.DefinePlugin({
|
|
||||||
'process.env.NODE_ENV': JSON.stringify(NODE_ENV),
|
|
||||||
}),
|
|
||||||
new ExtractTextPlugin('style.css', { allChunks: true }),
|
|
||||||
];
|
|
||||||
|
|
||||||
if (production) {
|
|
||||||
plugins.push(
|
|
||||||
new webpack.optimize.UglifyJsPlugin({
|
|
||||||
compressor: {
|
|
||||||
pure_getters: true,
|
|
||||||
unsafe: true,
|
|
||||||
unsafe_comps: true,
|
|
||||||
screw_ie8: true,
|
|
||||||
warnings: false,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const entryFiles = [
|
|
||||||
'nodent-runtime',
|
|
||||||
path.join(__dirname, 'src/index.js'),
|
|
||||||
];
|
|
||||||
|
|
||||||
if (!production) {
|
|
||||||
entryFiles.push(path.join(__dirname, 'docs/main.js'));
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
entry: entryFiles,
|
|
||||||
output: {
|
|
||||||
path: path.join(__dirname, 'dist'),
|
|
||||||
filename: `bundle${production ? '.min' : ''}.js`,
|
|
||||||
library: 'GeoSearch',
|
|
||||||
libraryTarget: 'umd',
|
|
||||||
},
|
|
||||||
devTool: 'inline-source-map',
|
|
||||||
devServer: {
|
|
||||||
// contentBase: './example',
|
|
||||||
inline: true,
|
|
||||||
},
|
|
||||||
module: {
|
|
||||||
loaders: [
|
|
||||||
{
|
|
||||||
test: /\.css$/,
|
|
||||||
loader: ExtractTextPlugin.extract(
|
|
||||||
'style-loader',
|
|
||||||
'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]',
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.html$/,
|
|
||||||
loader: 'raw-loader',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.js$/,
|
|
||||||
loaders: ['babel-loader'],
|
|
||||||
exclude: /node_modules/,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
plugins,
|
|
||||||
};
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
import webpack from 'webpack';
|
|
||||||
import path from 'path';
|
|
||||||
import ExtractTextPlugin from 'extract-text-webpack-plugin';
|
|
||||||
|
|
||||||
const { NODE_ENV } = process.env;
|
|
||||||
const production = NODE_ENV === 'production';
|
|
||||||
|
|
||||||
const plugins = [
|
|
||||||
new webpack.optimize.OccurenceOrderPlugin(),
|
|
||||||
new webpack.DefinePlugin({
|
|
||||||
'process.env.NODE_ENV': JSON.stringify(NODE_ENV),
|
|
||||||
}),
|
|
||||||
new ExtractTextPlugin('style.css', { allChunks: true }),
|
|
||||||
];
|
|
||||||
|
|
||||||
if (production) {
|
|
||||||
plugins.push(
|
|
||||||
new webpack.optimize.UglifyJsPlugin({
|
|
||||||
compressor: {
|
|
||||||
pure_getters: true,
|
|
||||||
unsafe: true,
|
|
||||||
unsafe_comps: true,
|
|
||||||
screw_ie8: true,
|
|
||||||
warnings: false,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const entryFiles = [
|
|
||||||
'nodent-runtime',
|
|
||||||
path.join(__dirname, 'docs/main.js'),
|
|
||||||
];
|
|
||||||
|
|
||||||
export default {
|
|
||||||
entry: entryFiles,
|
|
||||||
output: {
|
|
||||||
path: path.join(__dirname, 'docs/dist'),
|
|
||||||
filename: `bundle${production ? '.min' : ''}.js`,
|
|
||||||
},
|
|
||||||
devTool: 'inline-source-map',
|
|
||||||
devServer: {
|
|
||||||
// contentBase: './example',
|
|
||||||
inline: true,
|
|
||||||
},
|
|
||||||
module: {
|
|
||||||
loaders: [
|
|
||||||
{
|
|
||||||
test: /\.css$/,
|
|
||||||
loader: ExtractTextPlugin.extract(
|
|
||||||
'style-loader',
|
|
||||||
'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]',
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.html$/,
|
|
||||||
loader: 'raw-loader',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.js$/,
|
|
||||||
loaders: ['babel-loader'],
|
|
||||||
exclude: /node_modules/,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
plugins,
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user