1 | import { LeafletProvider, addClassName, useLeafletContext } from '@react-leaflet/core';
|
2 | import React, { forwardRef, useState, useEffect, useImperativeHandle, useMemo } from 'react';
|
3 | import { createPortal } from 'react-dom';
|
4 | const DEFAULT_PANES = [
|
5 | 'mapPane',
|
6 | 'markerPane',
|
7 | 'overlayPane',
|
8 | 'popupPane',
|
9 | 'shadowPane',
|
10 | 'tilePane',
|
11 | 'tooltipPane'
|
12 | ];
|
13 | function omitPane(obj, pane) {
|
14 | const { [pane]: _p , ...others } = obj;
|
15 | return others;
|
16 | }
|
17 | function createPane(name, props, context) {
|
18 | if (DEFAULT_PANES.indexOf(name) !== -1) {
|
19 | throw new Error(`You must use a unique name for a pane that is not a default Leaflet pane: ${name}`);
|
20 | }
|
21 | if (context.map.getPane(name) != null) {
|
22 | throw new Error(`A pane with this name already exists: ${name}`);
|
23 | }
|
24 | const parentPaneName = props.pane ?? context.pane;
|
25 | const parentPane = parentPaneName ? context.map.getPane(parentPaneName) : undefined;
|
26 | const element = context.map.createPane(name, parentPane);
|
27 | if (props.className != null) {
|
28 | addClassName(element, props.className);
|
29 | }
|
30 | if (props.style != null) {
|
31 | Object.keys(props.style).forEach((key)=>{
|
32 |
|
33 | element.style[key] = props.style[key];
|
34 | });
|
35 | }
|
36 | return element;
|
37 | }
|
38 | function PaneComponent(props, forwardedRef) {
|
39 | const [paneName] = useState(props.name);
|
40 | const [paneElement, setPaneElement] = useState(null);
|
41 | useImperativeHandle(forwardedRef, ()=>paneElement, [
|
42 | paneElement
|
43 | ]);
|
44 | const context = useLeafletContext();
|
45 |
|
46 | const newContext = useMemo(()=>({
|
47 | ...context,
|
48 | pane: paneName
|
49 | }), [
|
50 | context
|
51 | ]);
|
52 | useEffect(()=>{
|
53 | setPaneElement(createPane(paneName, props, context));
|
54 | return function removeCreatedPane() {
|
55 | const pane = context.map.getPane(paneName);
|
56 | pane?.remove?.();
|
57 |
|
58 | if (context.map._panes != null) {
|
59 |
|
60 | context.map._panes = omitPane(context.map._panes, paneName);
|
61 |
|
62 | context.map._paneRenderers = omitPane(
|
63 | context.map._paneRenderers, paneName);
|
64 | }
|
65 | };
|
66 |
|
67 | }, []);
|
68 | return props.children != null && paneElement != null ? createPortal( React.createElement(LeafletProvider, {
|
69 | value: newContext
|
70 | }, props.children), paneElement) : null;
|
71 | }
|
72 | export const Pane = forwardRef(PaneComponent);
|