import * as React from "react"; import * as uuid from "uuid"; import { createLayer, removeLayer, useLayerSubscription } from "../Layer/LayersStore"; import { Popout, PopoutProps, PopoutRenderProps } from "./Popout"; export function openPopout( render: (props: PopoutRenderProps) => React.ReactNode, target: Element, options: Omit = {}, name: string = `popout-${uuid.v4()}`, ): string { createLayer({ name, render: () => ( render(props)} close={() => removeLayer(name)} /> ), }); return name; } /** * Create a Popout that is tied to the lifecycle of the calling component. When * the parent unmounts, the Popout will automatically be closed. * * Returns a 2-tuple of: * - a callback function to open the Popout (e.g., from a button click) * - a boolean of whether the Popout is currently open. */ export function usePopout( render: (props: PopoutRenderProps) => React.ReactNode, targetRef: React.RefObject, options: Omit = {}, ): [() => unknown, boolean] { const nameRef = React.useRef(`popout-${uuid.v4()}`); const open = React.useCallback(() => { const target = targetRef.current; if (target == null) { console.log( "[Popout] targetRef was not set. Make sure the given ref is being attached to a DOM element", ); return; } openPopout(render, target, options, nameRef.current); }, [render, targetRef, options]); React.useEffect(() => { const name = nameRef.current; return () => removeLayer(name); }, []); const layer = useLayerSubscription(nameRef.current); const isOpen = layer != null; return [open, isOpen]; }