-
Notifications
You must be signed in to change notification settings - Fork 890
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Leaflet Map Panes #227
Leaflet Map Panes #227
Conversation
Conflicts: src/MapPane.js src/index.js
Conflicts with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this PR, I think it's going in the right direction but it seems like many parts could be simplified.
@@ -30,6 +30,7 @@ Check Leaflet documentation for the events associated to each component. | |||
- [BaseTileLayer](Components.md#basetilelayer) | |||
- [Path](Components.md#path) | |||
- [Map](Components.md#map) | |||
- [MapPanes](Components.md#map-pane) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you rename it to just Pane
to match Leaflet API please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Done
@@ -11,6 +11,7 @@ You can directly access the Leaflet element created by a component using `this.l | |||
- [MapLayer](#maplayer) | |||
- [Path](#path) | |||
- [Map](#map) | |||
- [MapPane](#map-pane) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MapPane
-> Pane
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Done
/* @flow */ | ||
import { PropTypes } from 'react' | ||
|
||
export default PropTypes.string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to create an extra PropType if it is as simple as a string I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Done
@@ -24,3 +24,4 @@ export TileLayer from './TileLayer' | |||
export Tooltip from './Tooltip' | |||
export WMSTileLayer from './WMSTileLayer' | |||
export ZoomControl from './ZoomControl' | |||
export MapPane from './MapPane' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MapPane
-> Pane
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Done
_isMounted: false, | ||
} | ||
|
||
this._name = name || `pane-${uniqueId()}` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for this._name
and this.state._isMounted
, we could just have this.state.name
to check if the children should be rendered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Done
const map = this.context.map || this.props.map | ||
|
||
if (this._name && map && map._panes) { | ||
map._panes = omit(map._panes, this._name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems a bit of a hack, is there any other way to cleanup the pane from Leaflet using more public APIs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There isn't at the moment as far I can find. Browsing Leaflet's source code I could only find:
createPane
,getPane
, andgetPanes
Calling L.DomUtil.remove(pane) only removes it from the DOM but not the references leaflet keeps in map._panes
and map._paneRenderers
I had to dig for _paneRenderers
. It was keeping a reference to the detached pane node causing leaflet to render layers inside it if the pane was added back again.
I find this 'hacky' as well but I couldn't find a cleaner method or api for it at the moment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK thanks for the explanation, hopefully Leaflet won't remove these anytime soon!
name: PropTypes.string, | ||
children: childrenType, | ||
map: mapType, | ||
zIndex: PropTypes.number, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
zIndex
should be part of the style
, unless there is a particular reason to treat it differently?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Syntactic sugar. Since the main purpose of leaflet panes is to have more control over of zIndexes I included it as a prop. Let me know if you want this dropped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I think it's better to just rely on style
, I prefer to make the components as "dumb" as possible with no specific logic and let the applications implement custom behavior on top of them.
this.setStyle(props) | ||
} | ||
|
||
setStyle ({ style, zIndex } = this.props) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't need that, React can render the styles itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but React in this case is not in charge of the DOM node right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, sorry I missed that from Leaflet's createPane()
implementation.
} | ||
} | ||
|
||
componentWillReceiveProps (props) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't be needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since React is unaware of the actual DOM node, I have to apply incoming style changes to the pane node.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, yes I missed the fact Leaflet is creating a new DOM node rather than using the one provided. It's too bad it doesn't allow it as we could have completely leveraged React for this, but in that case I think your implementation is needed as such.
@@ -72,4 +72,17 @@ export default class MapComponent extends Component<any, any, any> { | |||
const el = this.leafletElement | |||
if (el) el.fire(type, data) | |||
} | |||
|
|||
getInstanceOptions (props = {}) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be simply named getOptions()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Done
@rjdestigter thanks for the changes and explanations. |
I suggest we still allow using default leaflet panes but don't set their style in that case. Pane doesn't actually really override existing panes, it just receives them from Todo's:
|
I also realised Also, yes, let's disallow using default names. I thought I needed that feature, but if I want other components such as Popup or any component for that matter to be added to a default pane even if it is nested inside a Pane component, I can just use prop.pane for them.
I will disallow default pane names. |
Ok, done, using default pane names or that of existing panes will throw an error. |
I'm good with that if you approve of today's changes. The only thing that I'd like to revisit myself is I'm not sure if React.cloneElement is really necessary. |
Also, thanks by the way for letting me collaborate on this project! |
I acutally went ahead and removed the usage of Also when |
Thanks for this PR! |
Developed component implementing Leaflet's new 'panes' concept.
Component name:
MapPane
Accepted props:
className
style
name
(Not required, unique id wiill be created if not passed.)Does Leaflet allow to override its existing panes?
No it does not seem like that. I've allowed passing a "blacklisted" name as prop.
Lifecycle:
constructor
will create a unique id if no name is passedcomponentDidMount
will check if the pane exists or not and callmap.createPane
if not.componentWillUnmount
will remove the pane from the DOM and map