Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@ name: test
on:
push:
branches:
- master
- master
pull_request:

permissions:
contents: read

jobs:
test-node:
test-node-matrix:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
maplibre: ['^4.0.0', '^5.0.0']
permissions:
checks: write
contents: read
Expand All @@ -29,6 +33,9 @@ jobs:
- name: Enable Corepack
run: corepack enable yarn

- name: Install MapLibre GL JS ${{ matrix.maplibre }}
run: yarn workspace @vis.gl/react-maplibre add --dev "maplibre-gl@${{ matrix.maplibre }}"

- name: Install dependencies
run: yarn bootstrap

Expand All @@ -40,6 +47,16 @@ jobs:
yarn test ci

- name: Coveralls
if: matrix.maplibre == '^5.0.0'
uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2.3.6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

test-node:
runs-on: ubuntu-22.04
needs: test-node-matrix
if: ${{ always() }}

steps:
- name: Check test matrix
run: test "${{ needs.test-node-matrix.result }}" = "success"
2 changes: 2 additions & 0 deletions docs/api-reference/maplibre/globe-control.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

React component that wraps maplibre-gl's [GlobeControl](https://maplibre.org/maplibre-gl-js/docs/API/classes/GlobeControl/) class.

Requires `maplibre-gl` v5 or later.

```tsx
import * as React from 'react';
import {Map, GlobeControl} from 'react-map-gl/maplibre';
Expand Down
15 changes: 12 additions & 3 deletions modules/react-maplibre/src/components/globe-control.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,18 @@ export type GlobeControlProps = {
};

function _GlobeControl(props: GlobeControlProps) {
const ctrl = useControl(({mapLib}) => new mapLib.GlobeControl(props), {
position: props.position
});
const ctrl = useControl(
({mapLib}) => {
const GlobeControl = mapLib.GlobeControl;
if (!GlobeControl) {
throw new Error('GlobeControl is not supported by this version of MapLibre GL JS');

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GlobeControl exists only in MapLibre v5+

}
return new GlobeControl(props);
},
{
position: props.position
}
);

useEffect(() => {
applyReactStyle(ctrl._container, props.style);
Expand Down
2 changes: 2 additions & 0 deletions modules/react-maplibre/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export {NavigationControl} from './components/navigation-control';
export {ScaleControl} from './components/scale-control';
export {TerrainControl} from './components/terrain-control';
export {LogoControl} from './components/logo-control';
export {GlobeControl} from './components/globe-control';
export {Source} from './components/source';
export {Layer} from './components/layer';
export {useControl} from './components/use-control';
Expand All @@ -27,6 +28,7 @@ export type {NavigationControlProps} from './components/navigation-control';
export type {ScaleControlProps} from './components/scale-control';
export type {TerrainControlProps} from './components/terrain-control';
export type {LogoControlProps} from './components/logo-control';
export type {GlobeControlProps} from './components/globe-control';
export type {SourceProps} from './components/source';
export type {LayerProps} from './components/layer';

Expand Down
13 changes: 10 additions & 3 deletions modules/react-maplibre/src/types/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import type {
TerrainSpecification,
LogoControl,
LogoControlOptions,
GlobeControl
IControl
} from 'maplibre-gl';

export type {
Expand All @@ -44,10 +44,17 @@ export type {
TerrainControl as TerrainControlInstance,
LogoControl as LogoControlInstance,
LogoControlOptions,
GlobeControl as GlobeControlInstance,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Building against v4 produced three TypeScript errors: these two GlobeControl exports don't exist, and one incompatible MapLib assignment. The fix preserves v4 support while making GlobeControl explicitly optional and unavailable at runtime on versions that don’t provide it.

Wdyt, @Pessimistress? This was previously undetected since we don't run CI on v4 anymore

CustomLayerInterface
} from 'maplibre-gl';

type MaplibreModule = typeof import('maplibre-gl');

export type GlobeControlInstance = MaplibreModule extends {
GlobeControl: new () => infer Instance;
}
? Instance
: IControl & {_container: HTMLElement};

/**
* A user-facing type that represents the minimal intersection between Mapbox and Maplibre
* User provided `mapLib` is supposed to implement this interface
Expand Down Expand Up @@ -76,5 +83,5 @@ export interface MapLib {

LogoControl: {new (options: LogoControlOptions): LogoControl};

GlobeControl: {new (options: any): GlobeControl};
GlobeControl?: {new (options: any): GlobeControlInstance};
}
21 changes: 17 additions & 4 deletions test/src/exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,20 @@ const Components = [
'ScaleControl'
] as const;

function getMissingExports(module: any): null | string[] {
const MaplibreComponents = [
...Components,
'TerrainControl',
'LogoControl',
'GlobeControl'
] as const;

function getMissingExports(
module: any,
components = Components as readonly string[]
): null | string[] {
const missingExports: string[] = [];
for (const key of Components) {
if (!legacyComponents[key]) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems to be an old typo. the module param was not used. Also expanded this to cover Maplibre-specific components

for (const key of components) {
if (!module[key]) {
missingExports.push(key);
}
}
Expand All @@ -30,7 +40,10 @@ function getMissingExports(module: any): null | string[] {

test('Consistent component names#legacy', t => {
t.notOk(getMissingExports(legacyComponents), 'Legacy endpoint contains all components');
t.notOk(getMissingExports(maplibreComponents), 'Maplibre endpoint contains all components');
t.notOk(
getMissingExports(maplibreComponents, MaplibreComponents),
'Maplibre endpoint contains all components'
);
t.notOk(getMissingExports(mapboxComponents), 'Mapbox endpoint contains all components');
t.end();
});
Loading