diff --git a/modules/react-maplibre/src/components/layer.ts b/modules/react-maplibre/src/components/layer.ts index d927e380a..8e25815d7 100644 --- a/modules/react-maplibre/src/components/layer.ts +++ b/modules/react-maplibre/src/components/layer.ts @@ -1,5 +1,6 @@ import {useContext, useEffect, useMemo, useState, useRef} from 'react'; import {MapContext} from './map'; +import { SourceIdContext } from './source'; import assert from '../utils/assert'; import {deepEqual} from '../utils/deep-equal'; @@ -106,6 +107,13 @@ export function Layer(props: LayerProps) { return undefined; }, [map]); + const sourceId = useContext(SourceIdContext) + // @ts-ignore source is not a key for every type + if (props.source === undefined && sourceId !== null) { + // @ts-ignore source is not a key for every type + props = { ...props, source: sourceId } + } + // @ts-ignore const layer = map && map.style && map.getLayer(id); if (layer) { diff --git a/modules/react-maplibre/src/components/source.ts b/modules/react-maplibre/src/components/source.tsx similarity index 92% rename from modules/react-maplibre/src/components/source.ts rename to modules/react-maplibre/src/components/source.tsx index 1a704a377..b832024d1 100644 --- a/modules/react-maplibre/src/components/source.ts +++ b/modules/react-maplibre/src/components/source.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import {useContext, useEffect, useMemo, useState, useRef, cloneElement} from 'react'; +import {useContext, useEffect, useMemo, useState, useRef} from 'react'; import {MapContext} from './map'; import assert from '../utils/assert'; import {deepEqual} from '../utils/deep-equal'; @@ -128,16 +128,10 @@ export function Source(props: SourceProps) { } propsRef.current = props; - return ( - (source && - React.Children.map( - props.children, - child => - child && - cloneElement(child, { - source: id - }) - )) || - null - ); + return + {props.children} + } + +export const SourceIdContext = + React.createContext(null); diff --git a/modules/react-maplibre/test/components/source.spec.jsx b/modules/react-maplibre/test/components/source.spec.jsx index f0c3a5a28..a6b813de0 100644 --- a/modules/react-maplibre/test/components/source.spec.jsx +++ b/modules/react-maplibre/test/components/source.spec.jsx @@ -2,7 +2,7 @@ import test from 'tape-promise/tape'; import * as React from 'react'; import {createRoot} from 'react-dom/client'; -import {Map, Source} from '@vis.gl/react-maplibre'; +import {Map, Source, Layer} from '@vis.gl/react-maplibre'; import {sleep, waitForMapLoad} from '../utils/test-utils'; test('Source/Layer', async t => { @@ -53,3 +53,39 @@ test('Source/Layer', async t => { t.end(); }); + +test('Composable Layers', async t => { + + const root = createRoot(document.createElement('div')); + const mapRef = {current: null}; + + const geoJSON = { + type: 'Point', + coordinates: [0, 0] + }; + const MyLayer = () => + + + + root.render( + + + + + + ); + await waitForMapLoad(mapRef); + await sleep(1); + t.ok(mapRef.current.getLayer('my-layer'), 'Layer is added'); + + root.unmount(); + + t.end(); +}) \ No newline at end of file