This summer, I had the opportunity to intern on the ArcGIS Maps SDK for JavaScript, and it was an amazing experience. I ended up learning how to build, test, and deploy my own library of Lit web components, which I then used in a React application. The learning curve was immense. But once I got through it, my teammates adored the project.
Try it out!
You can try the final application above or visit the app directly. The application is an inspired take on StoryMaps for telling a story about New York streets data.
The onboarding
It all started when my mentor sent me an internal technical onboarding website and asked me to explore different ArcGIS products, such as Map Viewer and Instant Apps. The onboarding docs listed useful resources to start with and where to search for help. It gave me a structured guide to explore but also absolute independence to build something that I was interested in.
Rather than programmatically building my map in JavaScript, I started looking for GeoJSON files from local government open data so that I could create a web map using Map Viewer. I spent time exploring ArcGIS Online by building maps, creating different charts to visualize the information, and even spending 25 mins to decide which color pair looks well on the map. During this process, I stumbled into “animated symbols” for one of my maps and was amazed at how beautiful it looked.
I then moved on to using these maps in a React app, which was easy. By this time, I had a good collection of pretty maps with insights on New York street. I want to have a text panel beside the map that describes what the map is about. Since I was interning with the team who built the <arcgis-map> component, it only made sense I learned how to create my own <story-panel> which would show the map alongside its description.
That’s when I got to know about Web Components and Lit. It felt overwhelming at the beginning but looked familiar. Web components had a similar life cycle to rendering components in React, but without needing a library. We can define our custom web components and render them in HTML using vanilla JavaScript. We don’t even need Lit for it, but Lit does provide some nice conveniences that make web component development easier.
How does Esri build their component packages?
They use web components. Before we dive into how to build them, let’s look at the three main technologies provided:
- Custom Elements—lets you define a new HTML tag, such as
<scope-tag> - Shadow DOM—encapsulates markup and styles so the component’s internal structure doesn’t conflict with the elements in the DOM
- HTML Templates
<template>—enables you to reuse markup templates<slot>—lets you reserve space in the layout to render other elements
Hello, Lit!
In Lit, all the boilerplate code you wire in becomes simple descriptors.
@customElement(‘story-panel’) registers the custom element with the component element registry, @property() for declaring properties, and html“ for templates. Way simpler.
GIS Learning: Renderer
Renderers are used to visualize features in a layer. A renderer object with styles is used to customize it. The renderer was behind all the lines, symbols, and colors that I clicked around earlier to customize the map.
To keep it simple, there are 3 kinds of renderer objects:
- Simple renderer—when there’s only one data point
- Unique value renderer—to differentiate between groups of features that have matching field values
- Vector Field renderer—to show the direction of the flow
This feature made me curious to see if I can have my own custom marker render, which can turn any image into a symbol on the map. Having a cat on the map does sound cute!
I created a customMarkerRenderer() with Lit, which helped me get a glimpse of how complex things can get.
Testing
Before we start using these components, we need to test if they work as expected.
That’s where Storybook helps. Storybook helps you test components in isolation to simulate user interaction and accessibility and document components. For reference, I ended up writing interaction tests and documenting these components.
Storybook preview of the different components
You can go through the Storybook above or visit it directly.
Production app
The application you saw at the beginning of this blog shows how I used all those components in the previous section.
Building an app using Lit would mean avoiding the opportunity to try out rendering custom components in a different framework, which was the whole purpose of the onboarding exercise.
I decided to stick with React. But it wasn’t as straightforward as I thought.
Since custom elements are basically HTML tags like <h1>, <div>, <p> etc, HTML attributes cannot be objects, arrays, or functions. They accept only primitive values like string, number, and boolean. If we are doing it in vanilla JS or any framework that doesn’t support custom elements, we must use a ref to add an event listener to update a value and handle cleaning up those event listeners when these components unmount.
But with React 19, we don’t have to worry about custom element support. We can use our custom element just like any other React component. The only caveat is that we need to define the types for our custom component to avoid any Typescript errors or warnings.
Conclusion
As they say, “Good engineering is invisible”. I was truly amazed to see the amount of engineering that goes behind creating a simple <arcgis-map> component. This was just a glimpse. They handle accessibility, internationalization, end-to-end testing, and much more to make sure these components work without any friction.
Commenting is not enabled for this article.