From 76dfd9de92d592bc7e1b17197622a4688f1baa5f Mon Sep 17 00:00:00 2001 From: Vladislav Lipatov Date: Wed, 24 Apr 2024 10:14:24 +0700 Subject: [PATCH] Use popover API everywhere --- src/App.tsx | 8 ++---- src/index.tsx | 10 +++---- src/lib/index.tsx | 69 +++++------------------------------------------ 3 files changed, 13 insertions(+), 74 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 383c6b0..0be13ee 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,7 +1,8 @@ +import { flip } from "@floating-ui/dom"; + import { Popover } from "./lib"; import "./App.css"; -import { flip } from "@floating-ui/dom"; function App() { let anchorRef: HTMLDivElement | undefined; @@ -27,12 +28,7 @@ function App() { // Full control over position autoUpdate computePositionOptions={{ placement: "bottom-start", middleware: [flip()] }} - // Popover API support (where possible) - // When popover API is not supported, fallback to mounting content to body - //popoverAPIMountFallback="body" dataAttributeName="data-open" - // SSR support - //mount="body" anchorElement={anchorRef} contentElementSelector="div" /> diff --git a/src/index.tsx b/src/index.tsx index af7bf04..f330751 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,9 +1,9 @@ /* @refresh reload */ -import { render } from 'solid-js/web' +import { render } from "solid-js/web"; -import './index.css' -import App from './App' +import App from "./App"; +import "./index.css"; -const root = document.getElementById('root') +const root = document.getElementById("root"); -render(() => , root!) +render(() => , root!); diff --git a/src/lib/index.tsx b/src/lib/index.tsx index 35aa826..db93105 100644 --- a/src/lib/index.tsx +++ b/src/lib/index.tsx @@ -39,10 +39,6 @@ export type PopoverProps = { * @example "pointerdown.capture.once.prevent|click" */ triggerEvents?: string | null; - /** - * HTMLElement or CSS selector (can be used in SSR) to mount popover content into - */ - mount?: HTMLElement | string; /** * Close popover on interaction outside * @default true @@ -76,29 +72,15 @@ export type PopoverProps = { * @see https://floating-ui.com/docs/autoupdate#options */ autoUpdateOptions?: AutoUpdateOptions; - /** - * Use popover API where possible - * @default true - */ - usePopoverAPI?: boolean; /** * Close popover on escape key press. * Uses 'keydown' event with 'Escape' key. * @default true */ closeOnEscape?: boolean; - /** - * HTMLElement or CSS selector (can be used in SSR) to mount popover content into - * Fallback for browsers that don't support Popover API - * @default body - */ - popoverAPIMountFallback?: HTMLElement | string; onOpenChange?: (open: boolean) => void; }; -// Remove this when Firefox supports Popover API -const checkPopoverSupport = () => HTMLElement.prototype.hasOwnProperty("popover"); - const getElement = (childrenReturn: ChildrenReturn, elementSelector?: string): HTMLElement => { let element = childrenReturn(); if (!(element instanceof HTMLElement)) throw new Error("trigger and content must be HTML elements"); @@ -112,23 +94,11 @@ const getElement = (childrenReturn: ChildrenReturn, elementSelector?: string): H return element; }; -const getMountElement = (mountTarget: HTMLElement | string): HTMLElement => { - if (mountTarget instanceof HTMLElement) return mountTarget; - - const element = document.querySelector(mountTarget); - if (!element || !(element instanceof HTMLElement)) - throw new Error(`Unable to find mount element with selector "${mountTarget}"`); - - return element; -}; - const DEFAULT_PROPS = Object.freeze({ triggerEvents: "pointerdown", dataAttributeName: "data-popover-open", closeOnEscape: true, closeOnOutsideInteraction: true, - usePopoverAPI: true, - popoverAPIMountFallback: "body", computePositionOptions: { /** * Default position here is absolute, because there might be some bugs in safari with "fixed" position @@ -222,9 +192,6 @@ export const Popover: VoidComponent = (initialProps) => { if (!(anchorElement instanceof HTMLElement)) throw new Error("Unable to find anchor element"); - // Hack for astro - const contentToMount = getElement(resolvedContent); - createEffect(() => { if (!props.closeOnOutsideInteraction) return; @@ -244,39 +211,15 @@ export const Popover: VoidComponent = (initialProps) => { }); createEffect(() => { - const mount = props.mount; - if (!mount) return; - - const mountElement = getMountElement(mount); - - mountElement.appendChild(contentToMount); - onCleanup(() => contentToMount.remove()); - }); - - createEffect(() => { - if (!props.usePopoverAPI) return; - - const isPopoverSupported = checkPopoverSupport(); - - if (isPopoverSupported) { - const popoverId = createUniqueId(); - - trigger.setAttribute("popovertarget", popoverId); - content.setAttribute("popover", "manual"); - content.setAttribute("id", `popover-${popoverId}`); - - if (!content.matches(":popover-open")) content.showPopover(); + const popoverId = createUniqueId(); - onCleanup(() => trigger.removeAttribute("popovertarget")); - } else { - const mount = props.popoverAPIMountFallback; - if (!mount) return; + trigger.setAttribute("popovertarget", popoverId); + content.setAttribute("popover", "manual"); + content.setAttribute("id", `popover-${popoverId}`); - const mountElement = getMountElement(mount); + if (!content.matches(":popover-open")) content.showPopover(); - mountElement.appendChild(contentToMount); - onCleanup(() => contentToMount.remove()); - } + onCleanup(() => trigger.removeAttribute("popovertarget")); }); // Listen to escape key down to close popup