Skip to content

Commit c3d3bdf

Browse files
author
wgj
committed
feature: new Component Point.Content
Signed-off-by: wgj <wgj>
1 parent 2b6d930 commit c3d3bdf

File tree

38 files changed

+316
-196
lines changed

38 files changed

+316
-196
lines changed

README.md

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,18 @@
3434

3535
- [TileLayer](#TileLayer)
3636

37+
- [TileLayer.BMap](#TileLayer) `(v1.2.0+)`
38+
39+
- [TileLayer.AMap](#TileLayer) `(v1.2.0+)`
40+
41+
- [TileLayer.OpenStreetMap](#TileLayer) `(v1.2.0+)`
42+
43+
- [TileLayer.GoogleMap](#TileLayer) `(v1.2.0+)`
44+
3745
- [Point](#Point)
3846

47+
- [Point.Content](#Point) `(v1.2.0+)`
48+
3949
- [MassPoints](#MassPoints) `(v1.1.0+)`
4050

4151
- [ClusterPoints](#ClusterPoints) `(v1.1.0+)`
@@ -195,7 +205,7 @@ import { RCMap } from 'rc-leaflet'
195205
196206
const { TileLayers } = Config
197207
198-
console.log(TileLayers.BMap, TileLayers.AMap)
208+
console.log(TileLayers.BMap, TileLayers.AMap, TileLayers.OpenStreetMap, TileLayers.GoogleMap)
199209
```
200210

201211
- minZoom
@@ -345,6 +355,22 @@ import { RCMap, TileLayer } from 'rc-leaflet'
345355
<RCMap>
346356
<TileLayer />
347357
</RCMap>
358+
359+
<RCMap>
360+
<TileLayer.BMap />
361+
</RCMap>
362+
363+
<RCMap>
364+
<TileLayer.AMap />
365+
</RCMap>
366+
367+
<RCMap>
368+
<TileLayer.OpenStreetMap />
369+
</RCMap>
370+
371+
<RCMap>
372+
<TileLayer.GoogleMap />
373+
</RCMap>
348374
)
349375
```
350376

@@ -372,6 +398,13 @@ import { RCMap, Point } from 'rc-leaflet'
372398
(
373399
<RCMap>
374400
<Point />
401+
402+
<Point>
403+
<Point.Content className>
404+
<div>first row.</div>
405+
<div>second row.</div>
406+
</Point.Content>
407+
</Point>
375408
</RCMap>
376409
)
377410
```
@@ -811,12 +844,16 @@ import { RCMap, DivIcon, Point } from 'rc-leaflet'
811844
812845
(
813846
<RCMap>
814-
<DivIcon content={<div>must be single jsx element content.</div>}>
815-
<Point />
847+
<DivIcon>
848+
<Point>
849+
<Point.Content />
850+
</Point>
816851
</DivIcon>
817852
818853
<Point>
819-
<DivIcon content={<div>must be single jsx element content.</div>} />
854+
<DivIcon>
855+
<Point.Content />
856+
</DivIcon>
820857
</Point>
821858
</RCMap>
822859
)
@@ -834,16 +871,6 @@ import { RCMap, DivIcon, Point } from 'rc-leaflet'
834871
835872
- the className of DivIcon container.
836873
837-
- content
838-
839-
- type: `React.ReactElement`
840-
841-
- default: `null`
842-
843-
- required: `false`
844-
845-
- custom `JSX` code to put inside the div element, empty by default. Alternatively, an instance of `React.ReactElement`.
846-
847874
- bgPos
848875
849876
- type: [Pixel](#Data-Structure)

UPDATE.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
## v1.2.0
2+
3+
- remove: remove `content` prop of `DivIcon`, there are too many edge cases to handle with.
4+
5+
- feature: new Component `Point.Content`, used to replace `content` prop of `DivIcon`.
6+
7+
- feature: new Components, export all abstract Components for plugin development.
8+
9+
- feature: add `TileLayers.OpenStreetMap`, `TileLayers.GoogleMap` config.
10+
11+
- feature: new Components `TileLayer.BMap`, `TileLayer.AMap`, `TileLayer.OpenStreetMap`, `TileLayer.GoogleMap`
12+
113
## v1.1.3
214

315
- fix: handle the edge case when layer of `DivOverlay` is changed.

build/rollup.config.js

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,7 @@ export default {
1818
dir: dist,
1919
format: 'umd',
2020
name: 'RCLeaflet',
21-
exports: 'named',
22-
globals: {
23-
react: 'React',
24-
'react-dom': 'ReactDOM',
25-
'prop-types': 'PropTypes',
26-
'airbnb-prop-types': 'Airbnb',
27-
classnames: 'classNames',
28-
leaflet: 'L'
29-
}
21+
exports: 'named'
3022
},
3123
external: ['react', 'react-dom', 'prop-types', 'airbnb-prop-types', 'classnames', 'leaflet', 'proj4', 'proj4leaflet', 'leaflet.markercluster'],
3224
plugins: [

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "rc-leaflet",
3-
"version": "1.1.3",
3+
"version": "1.2.0",
44
"description": "React components of Leaflet",
55
"keywords": [
66
"leaflet",

src/components/BaseIcon/index.tsx renamed to src/components/BaseIcon/index.ts

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import React, { PureComponent, Children, isValidElement, cloneElement } from 'react'
22
import PropTypes from 'prop-types'
33
import L from 'leaflet'
4-
import { Types } from '../../config'
5-
import { defaultIcon } from '../DivIcon/creator'
4+
import * as Types from '../Util/PropTypes'
65

76
interface PartialProps {
87
layer: L.Marker
@@ -13,7 +12,8 @@ export type Props = Readonly<Partial<PartialProps>>
1312

1413
export default abstract class BaseIcon<T extends L.Icon | L.DivIcon, P extends L.BaseIconOptions> extends PureComponent<Props & P, { instance: T }> {
1514
public static propTypes = {
16-
...Types.LayerOptionsShape,
15+
pane: PropTypes.string,
16+
attribution: PropTypes.string,
1717
iconUrl: PropTypes.string,
1818
iconRetinaUrl: PropTypes.string,
1919
iconSize: Types.Pixel,
@@ -29,27 +29,10 @@ export default abstract class BaseIcon<T extends L.Icon | L.DivIcon, P extends L
2929
children: PropTypes.node
3030
}
3131

32-
protected constructor (props: Props & P) {
33-
super(props)
34-
const { layer, children, ...options } = props
35-
36-
this.state = {
37-
instance: this.createInstance(options as P)
38-
}
32+
public readonly state: { instance: T } = {
33+
instance: undefined
3934
}
4035

41-
public componentWillUnmount (): void {
42-
const { layer } = this.props
43-
44-
if (layer) {
45-
setTimeout(() => {
46-
layer.setIcon(defaultIcon)
47-
}, 0)
48-
}
49-
}
50-
51-
protected abstract createInstance (options: P): T
52-
5336
public render (): React.ReactNode {
5437
const { children } = this.props
5538
const { instance: icon } = this.state
File renamed without changes.

src/components/CircleMarker/index.tsx renamed to src/components/CircleMarker/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import Path from '../Path'
21
import PropTypes from 'prop-types'
3-
import { Types } from '../../config'
42
import L from 'leaflet'
3+
import * as Types from '../Util/PropTypes'
4+
import Path from '../Path'
55

66
export type CircleMarkerOptions = Omit<L.CircleMarkerOptions, 'radius'>
77

src/components/ClusterPoints/index.tsx

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
import 'leaflet.markercluster/dist/MarkerCluster.css'
22
import 'leaflet.markercluster/dist/MarkerCluster.Default.css'
33
import React from 'react'
4-
import { createPortal } from 'react-dom'
54
import PropTypes from 'prop-types'
65
import L from 'leaflet'
76
import 'leaflet.markercluster'
8-
import { Types } from '../../config'
9-
import { ContextType } from '../RCMap'
7+
import * as Types from '../Util/PropTypes'
8+
import { ContextType } from '../RCMap/Context'
109
import Layer from '../Layer'
10+
import PointContext from '../Point/Context'
1111
import { PolylinePropTypes } from '../Polyline'
12-
import { Consumer as DivIconConsumer } from '../DivIcon'
1312
import { defaultIcon } from '../DivIcon/creator'
1413

14+
type Icon = L.Icon | L.DivIcon
15+
1516
interface RequiredProps {
1617
points: L.LatLngExpression[]
1718
}
1819

1920
interface PartialProps {
20-
icon: L.Icon | L.DivIcon
21+
icon: Icon
2122
clusterPane: string
2223
chunkProgress (processed?: number, total?: number, time?: number): void
2324
}
@@ -71,6 +72,7 @@ export default class ClusterPoints extends Layer<L.MarkerClusterGroup, Props> {
7172
if (points !== prevPoints || icon !== prevIcon) {
7273
this.instance.clearLayers()
7374
this.addPoints()
75+
this.forceUpdate()
7476
}
7577
}
7678

@@ -98,16 +100,12 @@ export default class ClusterPoints extends Layer<L.MarkerClusterGroup, Props> {
98100
}
99101

100102
public render (): React.ReactNode {
101-
const { icon } = this.props
102-
const layers = this.instance.getLayers()
103+
const { icon = defaultIcon } = this.props
103104

104105
return (
105-
<>
106+
<PointContext.Provider value={{ instance: this.instance, icon }}>
106107
{ super.render() }
107-
<DivIconConsumer>
108-
{ content => (icon instanceof L.DivIcon ? layers.filter(layer => layer instanceof L.Marker && layer.getElement()).map((point: L.Marker) => createPortal(content, point.getElement())) : null) }
109-
</DivIconConsumer>
110-
</>
108+
</PointContext.Provider>
111109
)
112110
}
113111
}

src/components/DivIcon/creator.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ const defaultIcon = creator(defaultOptions)
1919
export default creator
2020

2121
export {
22+
defaultOptions,
2223
defaultIcon
2324
}

src/components/DivIcon/index.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import PropTypes from 'prop-types'
2+
import L from 'leaflet'
3+
import * as Types from '../Util/PropTypes'
4+
import creator, { defaultIcon } from './creator'
5+
import BaseIcon, { Props as BaseIconProps } from '../BaseIcon'
6+
7+
type Props = Readonly<BaseIconProps & L.DivIconOptions>
8+
9+
interface State {
10+
instance: L.DivIcon
11+
}
12+
13+
export const keepPrevHTML = (point: L.Marker, icon: L.DivIcon): void => {
14+
if (point) {
15+
const element = point.getElement()
16+
const html = element && element.lastElementChild
17+
point.setIcon(icon)
18+
if (html) {
19+
element.appendChild(html)
20+
}
21+
}
22+
}
23+
24+
export default class DivIcon extends BaseIcon<L.DivIcon, Props> {
25+
public static propTypes = {
26+
...BaseIcon.propTypes,
27+
html: PropTypes.oneOfType([PropTypes.string, PropTypes.oneOf<false>([false])]),
28+
bgPos: Types.Pixel,
29+
iconSize: Types.Pixel,
30+
iconAnchor: Types.Pixel,
31+
popupAnchor: Types.Pixel,
32+
className: PropTypes.string
33+
}
34+
35+
public static getDerivedStateFromProps (nextProps: Props, prevState: State): State {
36+
const { layer, children, html, ...options } = nextProps
37+
let { instance: icon } = prevState
38+
39+
icon = creator(options)
40+
keepPrevHTML(layer, icon)
41+
return { instance: icon }
42+
}
43+
44+
public componentWillUnmount (): void {
45+
keepPrevHTML(this.props.layer, defaultIcon)
46+
}
47+
}

0 commit comments

Comments
 (0)