Updates to account, ui, etc
This commit is contained in:
75
ui/src/components/GroupControl.tsx
Normal file
75
ui/src/components/GroupControl.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { ReactNode } from 'react';
|
||||
import * as L from 'leaflet';
|
||||
import { useMap } from 'react-leaflet';
|
||||
import { createRoot, Root } from 'react-dom/client';
|
||||
|
||||
export interface ButtonDef {
|
||||
title: string;
|
||||
active: boolean;
|
||||
onClick: () => void;
|
||||
icon: ReactNode;
|
||||
}
|
||||
|
||||
interface GroupControlProps {
|
||||
position?: L.ControlPosition;
|
||||
buttons: ButtonDef[];
|
||||
}
|
||||
|
||||
export function GroupControl({ position = 'bottomright', buttons }: GroupControlProps) {
|
||||
const map = useMap();
|
||||
// References
|
||||
const buttonRefs = useRef<HTMLAnchorElement[]>([]);
|
||||
const reactRootRefs = useRef<Root[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const ctrl = new L.Control({ position });
|
||||
const current = reactRootRefs.current;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
ctrl.addTo(map);
|
||||
|
||||
return () => {
|
||||
ctrl.remove();
|
||||
// unmount React roots
|
||||
current.forEach((r) => r.unmount());
|
||||
};
|
||||
}, [map, buttons, 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');
|
||||
});
|
||||
}, [buttons]);
|
||||
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user