Skip to content

Commit 392266a

Browse files
authored
Per-layer styling, picker toggle, resizable panel, dark-mode icon fix (#3)
* Add per-layer styling, picker toggle, panel resize, dark-mode icon fix - Each theme now expands to its individual source layers; every layer has its own visibility checkbox, color picker, and opacity slider, with a theme master checkbox that reflects indeterminate state. State moves to a per-layer model (OvertureLayerState) and new setLayer*/setThemeExpanded methods drive the map sources/layers - Add an "Inspect features on click" checkbox to enable/disable the picker at runtime (setInspect); inspect state is part of OvertureMapsState - Make the panel width drag-resizable; the handle sits on the edge away from the anchored corner so it works at top-left and top-right alike - Fix the toggle icon contrast in dark mode by raising the control background specificity above maplibre's default white control group * Reorder themes and replace the plugin icon - Reorder the theme panel to Addresses, Places, Transportation, Buildings, Divisions, Base (top to bottom). Layers are inserted with a beforeId so the first listed theme always draws on top of the map regardless of the order layers are toggled, keeping detail themes above the base background. - Replace the stacked-layers toggle icon with a folded-map icon to avoid visual confusion with other layer controls. * Use overlapping-circles icon for the plugin toggle Replace the folded-map icon (which collided with other plugins) with three overlapping ring outlines echoing the Overture Maps brand motif. Distinct from the default MapLibre layer, globe, and compass controls, with good contrast in light and dark modes. * Add a per-layer style editor button (color, size, opacity) Replace the fixed per-layer color swatch with a style button that opens an inline editor exposing the layer's color, size (circle radius for points, line width for lines and polygon outlines), and opacity. Adds a `size` field to the layer state, threads it through the spec builders, and adds `setLayerSize` plus `sizePropertyForLayerType` / `defaultSizeForGeometry` helpers. A small read-only color swatch stays on the collapsed row as a preview. * Address CodeRabbit review feedback - Clarify the exported-types list in the README: ReleasesResponse is main entry only and OvertureMapsControlReactProps is React entry only, rather than implying every type is exported from both - Add a :focus-visible outline to the per-layer color input so keyboard users get a visible focus ring * Add per-layer GeoJSON export of features in the current view Add a download button to each layer row that exports the features rendered in the current map view to a GeoJSON file. The export is gated by a new exportMinZoom option (default 12) so it only ever covers a small area, and the button is disabled when the layer is hidden. Features are deduplicated across tile boundaries. Adds public exportLayer and getRenderedLayerGeoJSON methods and a transient panel notice for export feedback. * Follow the system color scheme live in auto theme mode In auto mode, resolve the color scheme from prefers-color-scheme and apply it as an explicit ovt-theme-light/dark class, and subscribe to a matchMedia listener so the panel, container, and newly created popups adapt live when the OS theme changes (not just at load). The CSS media query remains as a fallback. * Address CodeRabbit review feedback - Lowercase the SVG stroke keyword (currentColor -> currentcolor) for the style/export buttons to satisfy stylelint value-keyword-case - Make the export notice an aria-live region (role=status, aria-live, aria-atomic) and hide it via a CSS :empty rule instead of display toggling so screen readers announce export feedback - Coalesce exportMinZoom against the default in exportLayer so passing exportMinZoom: undefined cannot bypass the zoom gate - Align the exportMinZoom README description with the feature list wording
1 parent 56d67d1 commit 392266a

9 files changed

Lines changed: 1626 additions & 174 deletions

File tree

README.md

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ A [MapLibre GL JS](https://maplibre.org/) plugin for visualizing [Overture Maps]
1111

1212
- **All six Overture themes** - Addresses, base, buildings, divisions, places, and transportation, each loaded from the official Overture PMTiles distribution
1313
- **Dynamic releases** - Fetches the latest [Overture release list](https://labs.overturemaps.org/data/releases.json) at runtime, with a dropdown to switch releases and an option to pin one
14-
- **Theme controls** - Checkbox, color swatch, and opacity slider per theme
15-
- **Feature inspection** - Click any rendered Overture feature to see its properties in a popup (can be disabled)
14+
- **Per-layer styling** - Expand a theme to toggle each source layer individually; a style button opens an inline editor for the layer's color, size (point radius / line width), and opacity
15+
- **GeoJSON export** - A download button on each layer exports the features rendered in the current map view to a GeoJSON file. Gated by a minimum zoom (`exportMinZoom`) so exports stay limited to a small area
16+
- **Feature inspection** - Click any rendered Overture feature to see its properties in a popup; toggle the picker on or off from the panel
17+
- **Resizable panel** - Drag the panel edge to resize its width; the handle adapts to whichever corner the control sits in
1618
- **Dark and light mode** - The control UI follows `prefers-color-scheme` by default and can be forced light or dark
1719
- **Small-screen friendly** - The panel stays within the viewport and scrolls vertically when space is tight
1820
- **TypeScript Support** - Full TypeScript support with exported type definitions
@@ -135,6 +137,7 @@ The main control class implementing MapLibre's `IControl` interface.
135137
| `releasesUrl` | `string` | Overture labs releases.json | Endpoint listing available releases |
136138
| `tilesBaseUrl` | `string` | Official Overture S3 tiles URL | Base URL of the PMTiles distribution |
137139
| `inspect` | `boolean` | `true` | Click a rendered feature to open a properties popup |
140+
| `exportMinZoom` | `number` | `12` | Minimum zoom required to export a layer to GeoJSON (keeps exports limited to a small area) |
138141
| `visibleThemes` | `OvertureTheme[]` | `['buildings', 'transportation', 'places']` | Themes that start visible |
139142
| `themeColors` | `Partial<Record<OvertureTheme, string>>` | x-ray palette | Per-theme color overrides |
140143
| `themeOpacity` | `Partial<Record<OvertureTheme, number>>` | `0.8` | Per-theme initial opacity (0..1) |
@@ -144,8 +147,16 @@ The main control class implementing MapLibre's `IControl` interface.
144147
- `toggle()` / `expand()` / `collapse()` - Control the panel
145148
- `getState()` / `setState(state)` - Read or update the state
146149
- `setRelease(release)` - Switch the active Overture release
147-
- `setThemeVisible(theme, visible)` - Show or hide a theme
148-
- `setThemeOpacity(theme, opacity)` - Set a theme's opacity (0..1)
150+
- `setThemeVisible(theme, visible)` - Show or hide every layer of a theme
151+
- `setThemeOpacity(theme, opacity)` - Set the opacity of every layer of a theme (0..1)
152+
- `setThemeExpanded(theme, expanded)` - Expand or collapse a theme's layer list
153+
- `setLayerVisible(theme, sourceLayer, visible)` - Show or hide a single source layer
154+
- `setLayerOpacity(theme, sourceLayer, opacity)` - Set a single layer's opacity (0..1)
155+
- `setLayerColor(theme, sourceLayer, color)` - Set a single layer's color
156+
- `setLayerSize(theme, sourceLayer, size)` - Set a single layer's size (point radius / line width)
157+
- `setInspect(enabled)` - Enable or disable the feature inspection picker
158+
- `exportLayer(theme, sourceLayer)` - Download the layer's in-view features as GeoJSON (gated by `exportMinZoom`); returns the FeatureCollection or null
159+
- `getRenderedLayerGeoJSON(theme, sourceLayer)` - Get the layer's in-view features as a GeoJSON FeatureCollection without downloading
149160
- `refreshReleases()` - Re-fetch the release list
150161
- `on(event, handler)` / `off(event, handler)` - Manage event handlers
151162
- `getMap()` / `getContainer()` - Access the map and container
@@ -191,7 +202,9 @@ const {
191202

192203
### Exported Types
193204

194-
`OvertureMapsControlOptions`, `OvertureMapsState`, `OvertureThemeState`, `OvertureMapsControlReactProps`, `OvertureMapsEvent`, `OvertureMapsEventHandler`, `OvertureTheme`, `OvertureGeometry`, `OvertureLayerDef`, `ThemeDefinition`, `ControlColorScheme`, and `ReleasesResponse` are exported from both entry points (React-specific types from `/react`).
205+
Exported from both entry points: `OvertureMapsControlOptions`, `OvertureMapsState`, `OvertureThemeState`, `OvertureLayerState`, `OvertureMapsEvent`, `OvertureMapsEventHandler`, `OvertureTheme`, `OvertureGeometry`, `OvertureLayerDef`, `ThemeDefinition`, and `ControlColorScheme`.
206+
207+
Main entry only (`.`): `ReleasesResponse`. React entry only (`/react`): `OvertureMapsControlReactProps`.
195208

196209
Helpers are also exported: `THEMES`, `THEME_IDS`, `buildLayerSpecs`, `layerIdsForTheme`, `sourceIdForTheme`, `tileUrlForTheme`, `fetchReleases`, `ensurePmtilesProtocol`, and more.
197210

src/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,15 @@ export {
99
THEMES,
1010
THEME_IDS,
1111
buildLayerSpecs,
12+
buildSourceLayerSpecs,
1213
layerIdsForTheme,
14+
layerIdsForSourceLayer,
1315
sourceIdForTheme,
1416
tileUrlForTheme,
1517
opacityPropertyForLayerType,
18+
colorPropertyForLayerType,
19+
sizePropertyForLayerType,
20+
defaultSizeForGeometry,
1621
} from './lib/core/themes';
1722

1823
// Releases helpers
@@ -31,6 +36,7 @@ export type {
3136
OvertureMapsControlOptions,
3237
OvertureMapsState,
3338
OvertureThemeState,
39+
OvertureLayerState,
3440
OvertureMapsEvent,
3541
OvertureMapsEventHandler,
3642
ControlColorScheme,

0 commit comments

Comments
 (0)