diff --git a/src/config.ts b/src/config.ts index 7696f921..aa5b186c 100644 --- a/src/config.ts +++ b/src/config.ts @@ -37,6 +37,10 @@ export type Config = { prevBtnText?: string; doneBtnText?: string; + // Attach the popover and overlay to a specific element, defaults to document.body + // but the position is still calculated based on window + attach?: string; + // Called after the popover is rendered onPopoverRender?: (popover: PopoverDOM, opts: { config: Config; state: State, driver: Driver }) => void; @@ -88,3 +92,7 @@ export function setCurrentDriver(driver: Driver) { export function getCurrentDriver() { return currentDriver; } + +export function getAttachElement() { + return currentConfig.attach && document.querySelector(currentConfig.attach) || document.body; +} \ No newline at end of file diff --git a/src/highlight.ts b/src/highlight.ts index 0e5e55f8..7d4d04ef 100644 --- a/src/highlight.ts +++ b/src/highlight.ts @@ -1,6 +1,6 @@ import { DriveStep } from "./driver"; import { refreshOverlay, trackActiveElement, transitionStage } from "./overlay"; -import { getConfig, getCurrentDriver } from "./config"; +import { getAttachElement, getConfig, getCurrentDriver } from "./config"; import { hidePopover, renderPopover, repositionPopover } from "./popover"; import { bringInView } from "./utils"; import { getState, setState } from "./state"; @@ -22,7 +22,7 @@ function mountDummyElement(): Element { element.style.top = "50%"; element.style.left = "50%"; - document.body.appendChild(element); + getAttachElement().appendChild(element); return element; } diff --git a/src/overlay.ts b/src/overlay.ts index cffb4e16..87ecc92e 100644 --- a/src/overlay.ts +++ b/src/overlay.ts @@ -1,7 +1,7 @@ import { easeInOutQuad } from "./utils"; import { onDriverClick } from "./events"; import { emit } from "./emitter"; -import { getConfig } from "./config"; +import { getAttachElement, getConfig } from "./config"; import { getState, setState } from "./state"; export type StageDefinition = { @@ -75,7 +75,7 @@ export function refreshOverlay() { function mountOverlay(stagePosition: StageDefinition) { const overlaySvg = createOverlaySvg(stagePosition); - document.body.appendChild(overlaySvg); + getAttachElement().appendChild(overlaySvg); onDriverClick(overlaySvg, e => { const target = e.target as SVGElement; diff --git a/src/popover.ts b/src/popover.ts index 2e04dbb4..b7b7bf74 100644 --- a/src/popover.ts +++ b/src/popover.ts @@ -1,4 +1,4 @@ -import { Config, DriverHook, getConfig, getCurrentDriver } from "./config"; +import { Config, DriverHook, getAttachElement, getConfig, getCurrentDriver } from "./config"; import { Driver, DriveStep } from "./driver"; import { emit } from "./emitter"; import { onDriverClick } from "./events"; @@ -61,11 +61,11 @@ export function hidePopover() { export function renderPopover(element: Element, step: DriveStep) { let popover = getState("popover"); if (popover) { - document.body.removeChild(popover.wrapper); + getAttachElement().removeChild(popover.wrapper); } popover = createPopover(); - document.body.appendChild(popover.wrapper); + getAttachElement().appendChild(popover.wrapper); const { title,