Update frequencies to communications, fixed control icons
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { ReactNode } from 'react';
|
||||
import { ReactNode, useEffect, useRef } from 'react';
|
||||
import * as L from 'leaflet';
|
||||
import { useMap } from 'react-leaflet';
|
||||
import { createRoot, Root } from 'react-dom/client';
|
||||
@@ -19,56 +18,57 @@ interface GroupControlProps {
|
||||
export function GroupControl({ position = 'bottomright', buttons }: GroupControlProps) {
|
||||
const map = useMap();
|
||||
// References
|
||||
const buttonRefs = useRef<HTMLAnchorElement[]>([]);
|
||||
const reactRootRefs = useRef<Root[]>([]);
|
||||
const controlRef = useRef<L.Control>(null);
|
||||
const rootRef = useRef<Root>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const ctrl = new L.Control({ position });
|
||||
const current = reactRootRefs.current;
|
||||
controlRef.current = ctrl;
|
||||
|
||||
ctrl.onAdd = () => {
|
||||
const container = L.DomUtil.create('div', 'leaflet-bar leaflet-control custom-control');
|
||||
buttons.forEach((btnDef, i) => {
|
||||
const btn = L.DomUtil.create('a', '', container) as HTMLAnchorElement;
|
||||
btn.href = '#';
|
||||
btn.title = btnDef.title;
|
||||
|
||||
// standard leaflet click‐blocking magic
|
||||
L.DomEvent.disableClickPropagation(btn);
|
||||
L.DomEvent.disableScrollPropagation(btn);
|
||||
L.DomEvent.on(btn, 'click', L.DomEvent.stop)
|
||||
.on(btn, 'click', L.DomEvent.preventDefault)
|
||||
.on(btn, 'click', btnDef.onClick);
|
||||
|
||||
// Initial active status
|
||||
if (btnDef.active) btn.classList.add('active');
|
||||
|
||||
// Render root
|
||||
const rootRef = createRoot(btn);
|
||||
rootRef.render(btnDef.icon);
|
||||
reactRootRefs.current[i] = rootRef;
|
||||
buttonRefs.current[i] = btn;
|
||||
});
|
||||
return container;
|
||||
return L.DomUtil.create('div', 'leaflet-bar leaflet-control custom-control');
|
||||
};
|
||||
|
||||
ctrl.addTo(map);
|
||||
|
||||
// @ts-expect-error ctrl is a L.Control
|
||||
const container = (ctrl as unknown)._container as HTMLElement;
|
||||
rootRef.current = createRoot(container);
|
||||
|
||||
return () => {
|
||||
ctrl.remove();
|
||||
// unmount React roots
|
||||
current.forEach((r) => r.unmount());
|
||||
rootRef.current!.unmount();
|
||||
};
|
||||
}, [map, buttons, position]);
|
||||
}, [map, position]);
|
||||
|
||||
// if you want to toggle “.active” live when props change
|
||||
useEffect(() => {
|
||||
buttons.forEach((b, i) => {
|
||||
const btn = buttonRefs.current[i];
|
||||
if (!btn) return;
|
||||
if (b.active) btn.classList.add('active');
|
||||
else btn.classList.remove('active');
|
||||
});
|
||||
if (rootRef.current) {
|
||||
rootRef.current.render(
|
||||
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
||||
{buttons.map((b, i) => (
|
||||
<a
|
||||
key={i}
|
||||
href="#"
|
||||
title={b.title}
|
||||
className={b.active ? 'active' : ''}
|
||||
onClick={e => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
b.onClick();
|
||||
}}
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
padding: '4px'
|
||||
}}
|
||||
>
|
||||
{b.icon}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}, [buttons]);
|
||||
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user