CartoLab Elements are a set of reusable and themeable React components for building user interfaces for map-based web applications.
Similar to paper maps, digital maps generally include a common set of elements – things like zoom controls, basemap options, and a layer list. A set of reusable and themeable components enables developers to rapidly build map-based applications that match existing brands and frees up their time to focus more on the specific business logic of their applications.
This idea has been realized to a degree in tools like Esri’s Web AppBuilder – a platform that lets non-developers to configure “widgets” for mapping applications. CartoLab Elements are similar in concept to these “widgets”; however, they are different in that:
a) They are primarily meant for developers, and
b) Unlike Esri’s widgets, which can only be used in specific application templates, CartoLab Elements will work in any React-based web application
CartoLab Elements currently works with MapboxGL.js. We chose Mapbox because:
a) It’s what we use most often at CartoLab in our daily work.
b) Compared to other mapping libraries, it has the fewest UI elements or plugins available.
In the future we may consider expanding support beyond Mapbox to multiple mapping libraries.
Elements is different from libraries like react-map-gl and react-mapbox-gl in that it is not an attempt to port the MapboxGL API into React Components. Instead, it is our philosphy that MapboxGL should manage the map and its WebGL Context, while React simply manages all the other UI elements in an application that need to interact with a map. Working with Elements, you should be able to use MapboxGL.js directly or use one of these wrapper libraries (as long as you can pass in the map instance to Elements' Context).
npm install @cartolab/elements
or
yarn add @cartolab/elements
Important: When cloning the full source from github you need to add a src/config.js
file that exports an object that has your Mapbox token. This is needed for the Storybook to run in dev mode. This should remain out of version control. There is a config.template.js
file in src
to get you started. Just copy it and remove 'template'. Example:
export default {
mapboxToken: 'your mapbox token'
};
In order to CartoLab Elements to work, your project must include the following packages:
- react
- react-dom
- mapbox-gl
In the entry point/top level of your application, enable Elements by importing and wrapping the app in the <ElementsProvider>
. The Elements Provider does two things:
a) It passes in theme information. See Theming section for more details. b) It creates a shared map context so that the state of the map can be read and controlled by the components.
Example in the index.js file of an app created with Create React App:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import { ElementsProvider } from '@cartolab/elements';
import defaultTheme from '@cartolab/elements/src/themes/defaultTheme';
import App from './App';
ReactDOM.render(
<ElementsProvider theme={defaultTheme}>
<App />
</ElementsProvider>,
document.getElementById('root')
);
Example App.js. Note how you can place CartoLab Elements as children or siblings of the Map component. Your choice may depend on how you want to position these components in your application. You can see more examples of usage in the source for our Storybook app and in the tests.
import React from 'react'
import {Map, Zoom, BasemapSwitcher} from @cartolab/elements
const App = () => {
return (
<div>
<Map mapOptions={
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: [-95.7742, 29.80814],
zoom: 10,
accessToken: /* use your own Mapbox Token if needed */
}>
<Zoom>
<BasemapSwitcher>
</Map>
<LayerList
baseType='panel'
layers={[
{
layerIds: ['water', 'water-shadow'], //fill
layerName: 'Water'
},
{
layerIds: ['road-motorway-trunk'], //line
layerName: 'Motorway'
}
]}
/>
</div>
)};
}
CartoLab Elements are built with ThemeUI, which uses Styled System and the System UI Theme Specification. This means that you can use any theme made for Rebass, Styled System, Theme-UI, or any other compliant theme with CartoLab Elements.
We've provided a default theme to help you get started quickly.
Styling can be overridden for each component by passing in an sx
prop that contains and object of styles (same format that Emotion uses). Like in ThemeUI, the sx
prop indicates that the component is "theme-aware" and thus can use theme values in the style object, alongside any other valid CSS.
In most cases the sx
prop is passed to the base container for the component and can be used for positioning, background color changes, etc. Styles can be passed into child components via nested style syntax. A good example of this is with the <Zoom>
component, which has two buttons as children of the base component. To change the color of the buttons in the Zoom component, you can do this:
<Zoom sx={{
button: {
backgroundColor: 'secondary'
}
}} />
You can explore CartoLab Elements in our interactive playground, built with Storybook. We've included documentation, code examples, and interactive exploration of various props and theming options.
To run the storybook application, clone and run: yarn dev
To run in development mode, install and run yarn dev
. This will launch a development version of Storybook to create a development environment. Running yarn test
will run tests against the code. We use Jest and React Testing Library for testing these components.
Important! See the instructions under Installation on adding a src/config.js
file for your Mapbox token or you will get errors when running yarn dev
If you have an idea, question, or issue please open an issue and let us know.