From b8874fd1e0a19557c359fdc85bca76b6498872da Mon Sep 17 00:00:00 2001 From: Kamran Ahmed Date: Sun, 14 May 2023 21:22:28 +0100 Subject: [PATCH] Add popover rendering --- index.html | 6 ++++ src/driver.ts | 3 +- src/highlight.ts | 6 ++-- src/popover.ts | 90 ++++++++++++++++++++++++++++++++++++++++++++++-- src/style.css | 15 ++++++++ 5 files changed, 114 insertions(+), 6 deletions(-) diff --git a/index.html b/index.html index dfbc8a6..ceebcb0 100644 --- a/index.html +++ b/index.html @@ -285,6 +285,12 @@ npm install driver.js { driver({ animate: false }).highlight({ element: "#large-paragraph-text", + popover: { + title: "driver.js", + description: "Highlight anything, anywhere on the page", + align: "end", + preferredPosition: "top", + }, }); }); diff --git a/src/driver.ts b/src/driver.ts index 68f0f5a..ac1864d 100644 --- a/src/driver.ts +++ b/src/driver.ts @@ -1,4 +1,4 @@ -import { Popover } from "./popover"; +import { destroyPopover, Popover } from "./popover"; import { destroyStage } from "./stage"; import { destroyEvents, initEvents } from "./events"; import { Config, configure, getConfig } from "./config"; @@ -52,6 +52,7 @@ export function driver(options: Config = {}) { ); destroyEvents(); + destroyPopover(); destroyHighlight(); destroyStage(); destroyEmitter(); diff --git a/src/highlight.ts b/src/highlight.ts index 1c997fa..d3acf39 100644 --- a/src/highlight.ts +++ b/src/highlight.ts @@ -50,13 +50,12 @@ function transferHighlight(from: Element, to: Element) { transitionStage(elapsed, duration, from, to); } else { trackActiveElement(to); - renderPopover(to); currentTransitionCallback = undefined; } - refreshStage(); - refreshPopover(); + // refreshStage(); + // refreshPopover(); window.requestAnimationFrame(animate); }; @@ -64,6 +63,7 @@ function transferHighlight(from: Element, to: Element) { window.requestAnimationFrame(animate); bringInView(to); + renderPopover(to); from.classList.remove("driver-active-element"); to.classList.add("driver-active-element"); diff --git a/src/popover.ts b/src/popover.ts index d8af4f4..a519d4c 100644 --- a/src/popover.ts +++ b/src/popover.ts @@ -1,3 +1,5 @@ +import { bringInView } from "./utils"; + export type Popover = { title?: string; description: string; @@ -5,8 +7,92 @@ export type Popover = { align?: "start" | "center" | "end"; }; +let popoverEl: HTMLElement | undefined; + export function renderPopover(element: Element) { - console.log("rendering", element); + if (!popoverEl) { + const popover = createPopover(); + document.body.appendChild(popover.popoverWrapper); + + popoverEl = popover.popoverWrapper; + } + + popoverEl.style.display = "block"; + popoverEl.style.left = "0"; + popoverEl.style.top = "0"; + popoverEl.style.bottom = ""; + popoverEl.style.right = ""; + + refreshPopover(); + bringInView(popoverEl); } -export function refreshPopover() {} +export function refreshPopover() { + console.log("rendering popover"); +} + +function createPopover() { + const popoverWrapper = document.createElement("div"); + popoverWrapper.classList.add("driver-popover"); + + const popoverTip = document.createElement("div"); + popoverTip.classList.add("driver-popover-tip"); + + const popoverTitle = document.createElement("div"); + popoverTitle.classList.add("driver-popover-title"); + popoverTitle.innerText = "Popover Title"; + + const popoverDescription = document.createElement("div"); + popoverDescription.classList.add("driver-popover-description"); + popoverDescription.innerText = "Popover Description"; + + const popoverFooter = document.createElement("div"); + popoverFooter.classList.add("driver-popover-footer"); + + const popoverCloseBtn = document.createElement("button"); + popoverCloseBtn.classList.add("driver-popover-close-btn"); + popoverCloseBtn.innerText = "Close"; + + const popoverFooterBtnGroup = document.createElement("span"); + popoverFooterBtnGroup.classList.add("driver-popover-footer-btns"); + + const popoverPrevBtn = document.createElement("button"); + popoverPrevBtn.classList.add("driver-popover-prev-btn"); + popoverPrevBtn.innerHTML = "← Previous"; + + const popoverNextBtn = document.createElement("button"); + popoverNextBtn.classList.add("driver-popover-next-btn"); + popoverNextBtn.innerHTML = "Next →"; + + popoverFooterBtnGroup.appendChild(popoverPrevBtn); + popoverFooterBtnGroup.appendChild(popoverNextBtn); + + popoverFooter.appendChild(popoverCloseBtn); + popoverFooter.appendChild(popoverFooterBtnGroup); + + popoverWrapper.appendChild(popoverTip); + popoverWrapper.appendChild(popoverTitle); + popoverWrapper.appendChild(popoverDescription); + popoverWrapper.appendChild(popoverFooter); + + return { + popoverWrapper, + popoverTip, + popoverTitle, + popoverDescription, + popoverFooter, + popoverPrevBtn, + popoverNextBtn, + popoverCloseBtn, + popoverFooterBtnGroup, + }; +} + +export function destroyPopover() { + if (!popoverEl) { + return; + } + + popoverEl.parentElement?.removeChild(popoverEl); + popoverEl = undefined; +} diff --git a/src/style.css b/src/style.css index c38c9fa..eed7c4e 100644 --- a/src/style.css +++ b/src/style.css @@ -24,3 +24,18 @@ .driver-fade .driver-stage { animation: animate-fade-in 100ms ease-in-out; } + +/* Popover styles */ +.driver-popover { + color: #2d2d2d; + margin: 0; + border-radius: 5px; + min-width: 250px; + max-width: 300px; + box-shadow: 0 1px 10px #0006; + z-index: 1000000000; + position: fixed; + top: 0; + right: 0; + background-color: #fff; +}