React-Leaflet Sidebar-v2
A react-leaflet plugin for leaflet-sidebar-v2 (which is a leaflet-only fork of sidebar-v2)
The twist is the implementation of sidebar-v2 isn't very compatible with React, so this plugin actually renders all markup via React, including event handling, and just leverages the CSS from sidebar-v2.
Getting Started
You will need to include the sidebar-v2 css in your page somehow, for example via a CDN. The close icons default to fontawesome, so this will also need to be included.
You will typically include Sidebar
as a sibling component of
react-leaflet Map
, contained in a wrapper div so the sidebar is
positioned relative to the map, with whatever Tab
children are
required for your layout. This is because of event handling: if the
sidebar is a child of the map element, events will bubble up and be
handled by leaflet first (this is because React events are actually
handled by a single handler at the document root, so they will always
bubble up through leaflet first). A previous commit
(a9156e8bb7)
attempted to solve this by disabling native events at the sidebar
root, but I found too many complications. If anyone solves this I
would love a PR!
The Sidebar
component is stateless; all state information should be
passed as props, and desired state changes communicated upwards via
the onOpen
and onClose
callback. A minimal example might look
like the following (also note that to work with the default css, the
Map
needs a sidebar-map
class, and the Sidebar
needs to be
before the Map
):
import React, { Component } from 'react';
import { Map, TileLayer } from 'react-leaflet';
import { Sidebar, Tab } from 'react-leaflet-sidebarv2';
export default class SidebarExample extends Component {
constructor(props) {
super(props);
this.state = {
collapsed: false,
selected: 'home'
};
}
onClose() {
this.setState({ collapsed: true });
}
onOpen(id) {
this.setState({
collapsed: false,
selected: id
});
}
render() {
return (
<div>
<Sidebar
id="sidebar"
collapsed={this.state.collapsed}
selected={this.state.selected}
onOpen={this.onOpen.bind(this)}
onClose={this.onClose.bind(this)}
>
<Tab id="home" header="Home" icon="fa fa-home">
<p>No place like home!</p>
</Tab>
<Tab id="settings" header="Settings" icon="fa fa-cog" anchor="bottom">
<p>Settings dialogue.</p>
</Tab>
</Sidebar>
<Map
className="sidebar-map"
center={[51.505, -0.09]}
zoom={13}
zoomControl={false}
>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="http://{s}.tile.osm.org/{z}/{x}/{y}.png"
/>
</Map>
</div>
);
}
}
API
Sidebar
id
: String Required ID of sidebarposition
: String position of sidebar. Values: "left", "right"collapsed
: Boolean initial collapsed stateselected
: String ID of selected tabcloseIcon
: String/Component Required Icon for close button, E.g. "fa fa-times", or React componentonOpen
: Func EventonClose
: Func Event
Tab
id
: String Required ID of tab for use with stateheader
: String Required Title of tabicon
: String/Component Required Icon for the tab E.g. "fa fa-cog", or React componentanchor
: String Fix tab to top or bottom. Values: "top", "bottom"active
: Boolean Initial active statedisabled
: Boolean