mirror of
https://github.com/lowdefy/lowdefy.git
synced 2025-02-11 14:20:07 +08:00
feat(blocks-google-maps): Add google maps as a default block.
This commit is contained in:
parent
3133feeefe
commit
b0daaec9fa
372
packages/plugins/blocks/blocks-google-maps/README.md
Normal file
372
packages/plugins/blocks/blocks-google-maps/README.md
Normal file
@ -0,0 +1,372 @@
|
|||||||
|
# Lowdefy Google Maps Blocks
|
||||||
|
|
||||||
|
This repository provides Lowdefy blocks for the [Google Maps API](https://developers.google.com/maps/documentation/javascript/overview) is a feature rich javascript map API that lets you customize maps with your own content and imagery for display on web pages and mobile devices.
|
||||||
|
|
||||||
|
[google-map-react](https://github.com/google-map-react/google-map-react) is a component written over a small set of the [Google Maps API](https://developers.google.com/maps/).
|
||||||
|
|
||||||
|
## Blocks
|
||||||
|
|
||||||
|
To use this block, define a [Custom Block type](https://docs.lowdefy.com/custom-blocks) in your Lowdefy app:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: my-app
|
||||||
|
lowdefy: 3.22.0
|
||||||
|
types:
|
||||||
|
GoogleMaps:
|
||||||
|
url: https://blocks-cdn.lowdefy.com/v3.22.0/blocks-google-maps/meta/GoogleMaps.json
|
||||||
|
# ...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Block type Urls
|
||||||
|
|
||||||
|
- `GoogleMaps`: https://blocks-cdn.lowdefy.com/v3.22.0/blocks-google-maps/meta/GoogleMaps.json
|
||||||
|
|
||||||
|
### Properties
|
||||||
|
|
||||||
|
- `bootstrapURLKeys`: { key: '', language: 'en', region: 'en', libraries: ['places'], ...otherUrlParams, } If you want to include additional libraries to load with the maps api, indicate them in the libraries property of the bootstrapURLKeys object.
|
||||||
|
- `center`: Can be set to [lat, lng] or { lat: lat, lng: lng}. A position object for the center.
|
||||||
|
- `debounced`: Defaults to true. Whether map events are debounced.
|
||||||
|
- `defaultCenter`: Can be set to [lat, lng] or { lat: lat, lng: lng}. A position object for the center.
|
||||||
|
- `defaultZoom`: Map zoom level.
|
||||||
|
- `heatmap`: To use the heatmap layer, add visualization to the libraries property array on bootstrapURLKeys and provide the data & configuration for the heatmap in heatmap as props. If you have multiple maps in your project and require a heatmap layer in at least one of them, provide libraries:['visualization'] to all of them.
|
||||||
|
- `height`: The height of the map block.
|
||||||
|
- `hoverDistance`: Defaults to 30. Map hover distance.
|
||||||
|
- `layerTypes`: Examples ['TrafficLayer', 'TransitLayer']. The layer types to be included in the map.
|
||||||
|
- `mapOptions`: Custom map options.
|
||||||
|
- `margin`: Map margin.
|
||||||
|
- `markers`: A list of Markers with properties, `map` is provided by the default by the block, see [Javascript API Markers](https://developers.google.com/maps/documentation/javascript/markers) for configuration details.
|
||||||
|
- `resetBoundsOnResize`: Default: false, When true this will reset the map bounds if the parent resizes.
|
||||||
|
- `style`: Custom map css properties to apply to map block.
|
||||||
|
- `zoom`: Map zoom level.
|
||||||
|
|
||||||
|
### Events
|
||||||
|
|
||||||
|
- `onClick`: Trigger onClick actions when the map is clicked, returns `_event` object:
|
||||||
|
- `event`: event object
|
||||||
|
- `lat`: latitudinal coordinate
|
||||||
|
- `lng`: longitudinal coordinate
|
||||||
|
- `maps`: has functions removed
|
||||||
|
- `x`: position on map block
|
||||||
|
- `y`: position on map block
|
||||||
|
- `onClickMarker`: Trigger onClick actions when a marker is clicked, returns `_event` object:
|
||||||
|
- `domEvent`: event object
|
||||||
|
- `latLng`:
|
||||||
|
- `lat`: latitudinal coordinate
|
||||||
|
- `lng`: longitudinal coordinate
|
||||||
|
- `maps`: has functions removed
|
||||||
|
- `pixel`:
|
||||||
|
- `x`
|
||||||
|
- `y`
|
||||||
|
- `onDrag`: Trigger onDrag actions when a map is dragged, returns `_event` object:
|
||||||
|
- `maps`: has functions removed
|
||||||
|
- `onDragEnd`: Trigger onDragEnd actions when a map is finished being dragged, returns `_event` object:
|
||||||
|
- `maps`: has functions removed
|
||||||
|
- `onGoogleApiLoaded` Trigger onGoogleApiLoaded actions when the map api is loaded, returns `_event` object:
|
||||||
|
- `maps`: has functions removed
|
||||||
|
- `onMapTypeIdChange`: Trigger onMapTypeIdChange actions when the map type is changed, returns `_event` object:
|
||||||
|
- `maps`: has functions removed
|
||||||
|
- `type`: the map
|
||||||
|
- `onTilesLoaded`: Trigger onTilesLoaded actions when the map tiles are loaded, returns `_event` object:
|
||||||
|
- `maps`: has functions removed
|
||||||
|
- `onZoomAnimationStart`: Trigger onZoomAnimationStart actions when the map is zoomed, returns `_event` object:
|
||||||
|
- `maps`: has functions removed
|
||||||
|
- `zoom`: map zoom level
|
||||||
|
- `onZoomAnimationEnd`: Trigger onZoomAnimationEnd actions after the map is zoomed, returns `_event` object:
|
||||||
|
- `maps`: has functions removed
|
||||||
|
- `zoom`: map zoom level
|
||||||
|
|
||||||
|
### Methods
|
||||||
|
|
||||||
|
- `addMarker`: Accepts a single parameter object `marker` with marker properties.
|
||||||
|
- `removeMarker`: Accepts a single parameter object `marker` with position property.
|
||||||
|
- `fitBounds`: Accepts a two parameters, `bounds` and `mapSize`.
|
||||||
|
- `addHeatmap`: Accepts a single parameter object `heatmap` with heatmap properties.
|
||||||
|
- `toggleHeatmap`: Doesn't require any parameters.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
1. Add a list of markers, one with a tooltip:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- id: google_maps
|
||||||
|
type: GoogleMaps
|
||||||
|
properties:
|
||||||
|
bootstrapURLKeys:
|
||||||
|
key: ''
|
||||||
|
libraries: ['visualization']
|
||||||
|
mapOptions:
|
||||||
|
panControl: true
|
||||||
|
zoomControl: true
|
||||||
|
fullscreenControl: true
|
||||||
|
zoom: 14
|
||||||
|
center:
|
||||||
|
lat: -25.344
|
||||||
|
lng: 131.036
|
||||||
|
markers:
|
||||||
|
- position:
|
||||||
|
lat: -25.344
|
||||||
|
lng: 131.036
|
||||||
|
label: One
|
||||||
|
tooltip: '<div style="color:blue">Hello World!</div>'
|
||||||
|
- position:
|
||||||
|
lat: -25.348
|
||||||
|
lng: 131.038
|
||||||
|
label: Two
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Add a marker:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- id: google_maps
|
||||||
|
type: GoogleMaps
|
||||||
|
properties:
|
||||||
|
bootstrapURLKeys:
|
||||||
|
key: ''
|
||||||
|
libraries: ['visualization']
|
||||||
|
mapOptions:
|
||||||
|
panControl: true
|
||||||
|
zoomControl: true
|
||||||
|
fullscreenControl: true
|
||||||
|
zoom: 14
|
||||||
|
center:
|
||||||
|
lat: -25.344
|
||||||
|
lng: 131.036
|
||||||
|
events:
|
||||||
|
onClick:
|
||||||
|
- id: add_marker
|
||||||
|
type: CallMethod
|
||||||
|
params:
|
||||||
|
blockId: google_maps
|
||||||
|
method: addMarker
|
||||||
|
args:
|
||||||
|
- position:
|
||||||
|
lat:
|
||||||
|
_event: lat
|
||||||
|
lng:
|
||||||
|
_event: lng
|
||||||
|
label: Hi
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Remove a marker:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- id: google_maps
|
||||||
|
type: GoogleMaps
|
||||||
|
properties:
|
||||||
|
bootstrapURLKeys:
|
||||||
|
key: ''
|
||||||
|
libraries: ['visualization']
|
||||||
|
mapOptions:
|
||||||
|
panControl: true
|
||||||
|
zoomControl: true
|
||||||
|
fullscreenControl: true
|
||||||
|
zoom: 14
|
||||||
|
center:
|
||||||
|
lat: -25.344
|
||||||
|
lng: 131.036
|
||||||
|
events:
|
||||||
|
onClickMarker:
|
||||||
|
- id: set_click
|
||||||
|
type: SetState
|
||||||
|
params:
|
||||||
|
latLng:
|
||||||
|
_event: latLng
|
||||||
|
- id: remove_marker
|
||||||
|
type: CallMethod
|
||||||
|
params:
|
||||||
|
blockId: google_maps
|
||||||
|
method: removeMarker
|
||||||
|
args:
|
||||||
|
- position:
|
||||||
|
lat:
|
||||||
|
_state: latLng.lat
|
||||||
|
lng:
|
||||||
|
_state: latLng.lng
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Fit bounds:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- id: google_maps
|
||||||
|
type: GoogleMaps
|
||||||
|
properties:
|
||||||
|
bootstrapURLKeys:
|
||||||
|
key: ''
|
||||||
|
libraries: ['visualization']
|
||||||
|
mapOptions:
|
||||||
|
panControl: true
|
||||||
|
zoomControl: true
|
||||||
|
fullscreenControl: true
|
||||||
|
zoom: 14
|
||||||
|
center:
|
||||||
|
lat: -25.344
|
||||||
|
lng: 131.036
|
||||||
|
events:
|
||||||
|
onClick:
|
||||||
|
- id: fit_bounds
|
||||||
|
type: CallMethod
|
||||||
|
params:
|
||||||
|
blockId: google_maps
|
||||||
|
method: fitBounds
|
||||||
|
args:
|
||||||
|
- ne:
|
||||||
|
lat: 50.01038826014866
|
||||||
|
lng: -118.6525866875
|
||||||
|
sw:
|
||||||
|
lat: 32.698335045970396
|
||||||
|
lng: -92.0217273125
|
||||||
|
- width: 640 # Map width in pixels
|
||||||
|
height: 380 # Map height in pixels
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Add a heatmap:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- id: google_maps
|
||||||
|
type: GoogleMaps
|
||||||
|
properties:
|
||||||
|
bootstrapURLKeys:
|
||||||
|
key: ''
|
||||||
|
libraries: ['visualization']
|
||||||
|
mapOptions:
|
||||||
|
panControl: true
|
||||||
|
zoomControl: true
|
||||||
|
fullscreenControl: true
|
||||||
|
zoom: 10
|
||||||
|
center:
|
||||||
|
lat: 34.0522
|
||||||
|
lng: -118.2437
|
||||||
|
heatmap:
|
||||||
|
positions:
|
||||||
|
- lat: 34.091158
|
||||||
|
lng: -118.2795188
|
||||||
|
weight: 1
|
||||||
|
- lat: 34.0771192
|
||||||
|
lng: -118.2587199
|
||||||
|
weight: 2
|
||||||
|
- lat: 34.083527
|
||||||
|
lng: -118.370157
|
||||||
|
weight: 1
|
||||||
|
- lat: 34.0951843
|
||||||
|
lng: -118.283107
|
||||||
|
weight: 2
|
||||||
|
- lat: 34.1033401
|
||||||
|
lng: -118.2875469
|
||||||
|
weight: 4
|
||||||
|
- lat: 34.035798
|
||||||
|
lng: -118.251288
|
||||||
|
weight: 2
|
||||||
|
- lat: 34.0776068
|
||||||
|
lng: -118.2646526
|
||||||
|
weight: 3
|
||||||
|
- lat: 34.0919263
|
||||||
|
lng: -118.2820544
|
||||||
|
weight: 3
|
||||||
|
- lat: 34.0568525
|
||||||
|
lng: -118.3646369
|
||||||
|
weight: 3
|
||||||
|
- lat: 34.0285781
|
||||||
|
lng: -118.4115541
|
||||||
|
weight: 0
|
||||||
|
- lat: 34.017339
|
||||||
|
lng: -118.278469
|
||||||
|
weight: 0
|
||||||
|
- lat: 34.0764288
|
||||||
|
lng: -118.3661624
|
||||||
|
weight: 4
|
||||||
|
- lat: 33.9925942
|
||||||
|
lng: -118.4232475
|
||||||
|
weight: 4
|
||||||
|
- lat: 34.0764345
|
||||||
|
lng: -118.3730332
|
||||||
|
weight: 3
|
||||||
|
- lat: 34.093981
|
||||||
|
lng: -118.327638
|
||||||
|
weight: 0
|
||||||
|
- lat: 34.056385
|
||||||
|
lng: -118.2508724
|
||||||
|
weight: 1
|
||||||
|
- lat: 34.107701
|
||||||
|
lng: -118.2667943
|
||||||
|
weight: 4
|
||||||
|
- lat: 34.0450139
|
||||||
|
lng: -118.2388682
|
||||||
|
weight: 4
|
||||||
|
- lat: 34.1031997
|
||||||
|
lng: -118.2586152
|
||||||
|
weight: 1
|
||||||
|
- lat: 34.0828183
|
||||||
|
lng: -118.3241586
|
||||||
|
weight: 1
|
||||||
|
options:
|
||||||
|
radius: 20
|
||||||
|
opacity: 1
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Add a heatmap after api has loaded:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- id: google_maps
|
||||||
|
type: GoogleMaps
|
||||||
|
properties:
|
||||||
|
bootstrapURLKeys:
|
||||||
|
key: ''
|
||||||
|
libraries: ['visualization']
|
||||||
|
mapOptions:
|
||||||
|
panControl: true
|
||||||
|
zoomControl: true
|
||||||
|
fullscreenControl: true
|
||||||
|
zoom: 10
|
||||||
|
center:
|
||||||
|
lat: 34.0522
|
||||||
|
lng: -118.2437
|
||||||
|
events:
|
||||||
|
onMountAsync:
|
||||||
|
- id: add_heatmap
|
||||||
|
type: CallMethod
|
||||||
|
params:
|
||||||
|
blockId: google_maps
|
||||||
|
method: addHeatmap
|
||||||
|
args:
|
||||||
|
- data:
|
||||||
|
- location:
|
||||||
|
lat: 34.091158
|
||||||
|
lng: -118.2795188
|
||||||
|
weight: 1
|
||||||
|
- location:
|
||||||
|
lat: 34.0771192
|
||||||
|
lng: -118.2587199
|
||||||
|
weight: 2
|
||||||
|
- location:
|
||||||
|
lat: 34.0828183
|
||||||
|
lng: -118.3241586
|
||||||
|
weight: 1
|
||||||
|
radius: 20
|
||||||
|
opacity: 1
|
||||||
|
```
|
||||||
|
|
||||||
|
7. Toggle a heatmap
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- id: google_maps
|
||||||
|
type: GoogleMaps
|
||||||
|
properties:
|
||||||
|
bootstrapURLKeys:
|
||||||
|
key: ''
|
||||||
|
libraries: ['visualization']
|
||||||
|
mapOptions:
|
||||||
|
panControl: true
|
||||||
|
zoomControl: true
|
||||||
|
fullscreenControl: true
|
||||||
|
zoom: 10
|
||||||
|
center:
|
||||||
|
lat: 34.0522
|
||||||
|
lng: -118.2437
|
||||||
|
events:
|
||||||
|
onClick:
|
||||||
|
- id: toggle_heatmap
|
||||||
|
type: CallMethod
|
||||||
|
params:
|
||||||
|
blockId: google_maps
|
||||||
|
method: toggleHeatmap
|
||||||
|
```
|
22
packages/plugins/blocks/blocks-google-maps/jest.config.js
Normal file
22
packages/plugins/blocks/blocks-google-maps/jest.config.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
export default {
|
||||||
|
clearMocks: true,
|
||||||
|
collectCoverage: true,
|
||||||
|
collectCoverageFrom: ['src/**/*.js'],
|
||||||
|
coverageDirectory: 'coverage',
|
||||||
|
coveragePathIgnorePatterns: [
|
||||||
|
'<rootDir>/dist/',
|
||||||
|
'<rootDir>/src/test',
|
||||||
|
'<rootDir>/src/index.js',
|
||||||
|
'<rootDir>/src/blocks.js',
|
||||||
|
'<rootDir>/src/types.js',
|
||||||
|
],
|
||||||
|
coverageReporters: [['lcov', { projectRoot: '../../../..' }], 'text', 'clover'],
|
||||||
|
errorOnDeprecated: true,
|
||||||
|
testEnvironment: 'jsdom',
|
||||||
|
testPathIgnorePatterns: ['<rootDir>/dist/', '<rootDir>/src/test'],
|
||||||
|
transform: {
|
||||||
|
'^.+\\.(t|j)sx?$': ['@swc/jest', { configFile: '../../../../.swcrc.test' }],
|
||||||
|
'\\.yaml$': '@lowdefy/jest-yaml-transform',
|
||||||
|
},
|
||||||
|
snapshotSerializers: ['@emotion/jest/serializer', 'jest-serializer-html'],
|
||||||
|
};
|
70
packages/plugins/blocks/blocks-google-maps/package.json
Normal file
70
packages/plugins/blocks/blocks-google-maps/package.json
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
{
|
||||||
|
"name": "@lowdefy/blocks-google-maps",
|
||||||
|
"version": "4.0.0-alpha.12",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"description": "Google Maps Blocks for Lowdefy.",
|
||||||
|
"homepage": "https://lowdefy.com",
|
||||||
|
"keywords": [
|
||||||
|
"lowdefy",
|
||||||
|
"lowdefy blocks",
|
||||||
|
"google",
|
||||||
|
"maps",
|
||||||
|
"lowdefy plugin"
|
||||||
|
],
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/lowdefy/lowdefy/issues"
|
||||||
|
},
|
||||||
|
"contributors": [
|
||||||
|
{
|
||||||
|
"name": "Gerrie van Wyk",
|
||||||
|
"url": "https://github.com/Gervwyk"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/lowdefy/lowdefy.git"
|
||||||
|
},
|
||||||
|
"type": "module",
|
||||||
|
"exports": {
|
||||||
|
"./*": "./dist/*",
|
||||||
|
"./blocks": "./dist/blocks.js",
|
||||||
|
"./types": "./dist/types.js"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"dist/*"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"build": "yarn swc",
|
||||||
|
"clean": "rm -rf dist",
|
||||||
|
"copyfiles": "copyfiles -u 1 \"./src/**/*\" dist -e \"./src/**/*.js\" -e \"./src/**/*.yaml\" -e \"./src/**/*.snap\"",
|
||||||
|
"prepare": "yarn build",
|
||||||
|
"swc": "swc src --out-dir dist --config-file ../../../../.swcrc --delete-dir-on-start && yarn copyfiles",
|
||||||
|
"test:watch": "jest --coverage --watch",
|
||||||
|
"test": "jest --coverage"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@googlemaps/react-wrapper": "1.1.34",
|
||||||
|
"@lowdefy/block-utils": "4.0.0-alpha.12",
|
||||||
|
"react": "18.1.0",
|
||||||
|
"react-dom": "18.1.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@emotion/jest": "11.9.1",
|
||||||
|
"@lowdefy/block-dev": "4.0.0-alpha.12",
|
||||||
|
"@lowdefy/helpers": "4.0.0-alpha.12",
|
||||||
|
"@lowdefy/jest-yaml-transform": "4.0.0-alpha.12",
|
||||||
|
"@swc/cli": "0.1.57",
|
||||||
|
"@swc/core": "1.2.194",
|
||||||
|
"@swc/jest": "0.2.21",
|
||||||
|
"@testing-library/dom": "8.13.0",
|
||||||
|
"@testing-library/react": "13.3.0",
|
||||||
|
"@testing-library/user-event": "14.2.0",
|
||||||
|
"copyfiles": "2.4.1",
|
||||||
|
"jest": "28.1.0",
|
||||||
|
"jest-environment-jsdom": "28.1.0",
|
||||||
|
"jest-serializer-html": "7.1.0"
|
||||||
|
},
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
|
}
|
||||||
|
}
|
17
packages/plugins/blocks/blocks-google-maps/src/blocks.js
Normal file
17
packages/plugins/blocks/blocks-google-maps/src/blocks.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2020-2022 Lowdefy, Inc
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export { default as GoogleMaps } from './blocks/GoogleMaps/GoogleMaps.js';
|
@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2020-2022 Lowdefy, Inc
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { useEffect, useState, useRef } from 'react';
|
||||||
|
import { Wrapper, Status } from '@googlemaps/react-wrapper';
|
||||||
|
import { blockDefaultProps } from '@lowdefy/block-utils';
|
||||||
|
|
||||||
|
// see which libraries to load at https://developers.google.com/maps/documentation/javascript/libraries
|
||||||
|
// properties.map{} is an interface of MapOptions: https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions
|
||||||
|
// properties.heatmap{} is an interface of HeatmapLayerOptions: https://developers.google.com/maps/documentation/javascript/reference/visualization#HeatmapLayerOptions
|
||||||
|
// properties.markers[] is an interface of MarkerOptions: https://developers.google.com/maps/documentation/javascript/reference/marker#MarkerOptions
|
||||||
|
|
||||||
|
const MAP_DEFAULTS = {
|
||||||
|
zoom: 2,
|
||||||
|
center: {
|
||||||
|
lat: 0,
|
||||||
|
lng: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const render = (status) => {
|
||||||
|
// TODO: not sure how to implement status for now.
|
||||||
|
// switch (status) {
|
||||||
|
// case Status.LOADING:
|
||||||
|
// return <Spinner />;
|
||||||
|
// case Status.FAILURE:
|
||||||
|
// return <ErrorComponent />;
|
||||||
|
// case Status.SUCCESS:
|
||||||
|
// return <GoogleMaps />;
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Marker = (options) => {
|
||||||
|
const [marker, setMarker] = React.useState();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (!marker) {
|
||||||
|
setMarker(new window.google.maps.Marker());
|
||||||
|
}
|
||||||
|
return () => {
|
||||||
|
if (marker) {
|
||||||
|
marker.setMap(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [marker]);
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (marker) {
|
||||||
|
marker.setOptions(options);
|
||||||
|
}
|
||||||
|
}, [marker, options]);
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
function updateHeatmap(data) {
|
||||||
|
if (data.location) {
|
||||||
|
const latLng = new window.google.maps.LatLng(data.location);
|
||||||
|
latLng.weight = data.weight || 1;
|
||||||
|
return latLng;
|
||||||
|
}
|
||||||
|
return new window.google.maps.LatLng(data);
|
||||||
|
}
|
||||||
|
const Map = ({ blockId, properties, methods }) => {
|
||||||
|
const [map, setMap] = useState();
|
||||||
|
const [heatmap, setHeatmap] = useState();
|
||||||
|
const ref = useRef();
|
||||||
|
const triggerOnClick = (event) => {
|
||||||
|
methods.triggerEvent({
|
||||||
|
name: 'onClick',
|
||||||
|
event,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (ref.current) {
|
||||||
|
if (!map) {
|
||||||
|
const newMap = new window.google.maps.Map(ref.current, {
|
||||||
|
...MAP_DEFAULTS,
|
||||||
|
...properties.map,
|
||||||
|
});
|
||||||
|
setMap(newMap);
|
||||||
|
if (properties.heatmap) {
|
||||||
|
const newHeatmap = new window.google.maps.visualization.HeatmapLayer({
|
||||||
|
...properties.heatmap,
|
||||||
|
data: properties.heatmap.data?.map(updateHeatmap),
|
||||||
|
map: newMap,
|
||||||
|
});
|
||||||
|
setHeatmap(newHeatmap);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
map.setOptions({ ...MAP_DEFAULTS, ...properties.map });
|
||||||
|
if (heatmap) {
|
||||||
|
heatmap.setOptions({
|
||||||
|
...properties.heatmap,
|
||||||
|
data: properties.heatmap.data?.map(updateHeatmap),
|
||||||
|
map,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
useEffect(() => {
|
||||||
|
if (map) {
|
||||||
|
['click'].forEach((eventName) => window.google.maps.event.clearListeners(map, eventName));
|
||||||
|
if (triggerOnClick) {
|
||||||
|
map.addListener('click', triggerOnClick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [map, triggerOnClick]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={methods.makeCssClass([{ height: 300 }, properties.style])}
|
||||||
|
id={blockId}
|
||||||
|
ref={ref}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const GoogleMaps = ({ blockId, events, methods, properties, loading }) => {
|
||||||
|
const libraries = new Set(properties.libraries || []);
|
||||||
|
if (properties.heatmap) {
|
||||||
|
libraries.add('visualization');
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Wrapper apiKey={properties.apiKey} render={render} libraries={[...libraries]}>
|
||||||
|
<Map blockId={blockId} properties={properties} methods={methods}>
|
||||||
|
{(properties.markers || []).map((markerOptions, i) => (
|
||||||
|
<Marker key={i} {...markerOptions} />
|
||||||
|
))}
|
||||||
|
<Marker />
|
||||||
|
</Map>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
GoogleMaps.defaultProps = blockDefaultProps;
|
||||||
|
GoogleMaps.meta = {
|
||||||
|
category: 'display',
|
||||||
|
icons: [],
|
||||||
|
styles: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GoogleMaps;
|
@ -0,0 +1,111 @@
|
|||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"bootstrapURLKeys": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "{ key: '', language: 'en', region: 'en', libraries: ['places'], ...otherUrlParams, } If you want to include additional libraries to load with the maps api, indicate them in the libraries property of the bootstrapURLKeys object."
|
||||||
|
},
|
||||||
|
"center": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Can be set to [lat, lng] or { lat: lat, lng: lng}. A position object for the center."
|
||||||
|
},
|
||||||
|
"debounced": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Defaults to true. Whether map events are debounced."
|
||||||
|
},
|
||||||
|
"defaultCenter": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Can be set to [lat, lng] or { lat: lat, lng: lng}. A position object for the center."
|
||||||
|
},
|
||||||
|
"defaultZoom": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "Map zoom level."
|
||||||
|
},
|
||||||
|
"heatmap": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "To use the heatmap layer, add visualization to the libraries property array on bootstrapURLKeys and provide the data & configuration for the heatmap in heatmap as props. If you have multiple maps in your project and require a heatmap layer in at least one of them, provide libraries:['visualization'] to all of them."
|
||||||
|
},
|
||||||
|
"height": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "The height of the map block."
|
||||||
|
},
|
||||||
|
"hoverDistance": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "Defaults to 30. Map hover distance."
|
||||||
|
},
|
||||||
|
"layerTypes": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Examples ['TrafficLayer', 'TransitLayer']. The layer types to be included in the map."
|
||||||
|
},
|
||||||
|
"mapOptions": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Custom map options."
|
||||||
|
},
|
||||||
|
"margin": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Map margin."
|
||||||
|
},
|
||||||
|
"markers": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "A list of Markers with defined properties."
|
||||||
|
},
|
||||||
|
"resetBoundsOnResize": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Default: false, When true this will reset the map bounds if the parent resizes."
|
||||||
|
},
|
||||||
|
"style": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Custom map css properties to apply to map block."
|
||||||
|
},
|
||||||
|
"zoom": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "Map zoom level."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"onClick": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Trigger onClick actions when the map is clicked."
|
||||||
|
},
|
||||||
|
"onClickMarker": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Trigger onClick actions when a marker is clicked."
|
||||||
|
},
|
||||||
|
"onDrag": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Trigger onDrag actions when a map is dragged."
|
||||||
|
},
|
||||||
|
"onDragEnd": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Trigger onDragEnd actions when a map is finished being dragged."
|
||||||
|
},
|
||||||
|
"onGoogleApiLoaded": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Trigger onGoogleApiLoaded actions when the map api is loaded."
|
||||||
|
},
|
||||||
|
"onMapTypeIdChange": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Trigger onMapTypeIdChange actions when the map type is changed."
|
||||||
|
},
|
||||||
|
"onTilesLoaded": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Trigger onTilesLoaded actions when the map tiles are loaded."
|
||||||
|
},
|
||||||
|
"onZoomAnimationStart": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Trigger onZoomAnimationStart actions when the map is zoomed."
|
||||||
|
},
|
||||||
|
"onZoomAnimationEnd": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Trigger onZoomAnimationEnd actions after the map is zoomed."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
packages/plugins/blocks/blocks-google-maps/src/types.js
Normal file
30
packages/plugins/blocks/blocks-google-maps/src/types.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/* eslint-disable import/namespace */
|
||||||
|
/*
|
||||||
|
Copyright 2020-2022 Lowdefy, Inc
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as blocks from './blocks.js';
|
||||||
|
|
||||||
|
const icons = {};
|
||||||
|
const styles = {};
|
||||||
|
Object.keys(blocks).forEach((block) => {
|
||||||
|
icons[block] = blocks[block].meta.icons || [];
|
||||||
|
styles[block] = blocks[block].meta.styles || [];
|
||||||
|
});
|
||||||
|
export default {
|
||||||
|
blocks: Object.keys(blocks),
|
||||||
|
icons,
|
||||||
|
styles: { default: [], ...styles },
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user