react-bkoi-gl
Version:
React components for Barikoi GL JS
69 lines (59 loc) • 1.87 kB
text/typescript
import { useContext, useMemo, useEffect } from "react";
import type { IControl, ControlPosition } from "../types/lib";
import { MapContext } from "./map";
import type { MapContextValue } from "./map";
type ControlOptions = {
position?: ControlPosition;
};
export function useControl<T extends IControl>(
onCreate: (context: MapContextValue) => T,
opts?: ControlOptions,
): T;
export function useControl<T extends IControl>(
onCreate: (context: MapContextValue) => T,
onRemove: (context: MapContextValue) => void,
opts?: ControlOptions,
): T;
export function useControl<T extends IControl>(
onCreate: (context: MapContextValue) => T,
onAdd: (context: MapContextValue) => void,
onRemove: (context: MapContextValue) => void,
opts?: ControlOptions,
): T;
export function useControl<T extends IControl>(
onCreate: (context: MapContextValue) => T,
arg1?: ((context: MapContextValue) => void) | ControlOptions,
arg2?: ((context: MapContextValue) => void) | ControlOptions,
arg3?: ControlOptions,
): T {
const context = useContext(MapContext);
const ctrl = useMemo(() => onCreate(context), []);
useEffect(() => {
const opts = (arg3 || arg2 || arg1) as ControlOptions;
const onAdd =
typeof arg1 === "function" && typeof arg2 === "function" ? arg1 : null;
const onRemove =
typeof arg2 === "function"
? arg2
: typeof arg1 === "function"
? arg1
: null;
const { map } = context;
if (!map.hasControl(ctrl)) {
map.addControl(ctrl, opts?.position);
if (onAdd) {
onAdd(context);
}
}
return () => {
if (onRemove) {
onRemove(context);
}
// Map might have been removed (parent effects are destroyed before child ones)
if (map.hasControl(ctrl)) {
map.removeControl(ctrl);
}
};
}, []);
return ctrl;
}