Skip to content

Commit

Permalink
Use popover API everywhere
Browse files Browse the repository at this point in the history
  • Loading branch information
elite174 committed Apr 24, 2024
1 parent 2914c34 commit 76dfd9d
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 74 deletions.
8 changes: 2 additions & 6 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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"
/>
Expand Down
10 changes: 5 additions & 5 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -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(() => <App />, root!)
render(() => <App />, root!);
69 changes: 6 additions & 63 deletions src/lib/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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");
Expand All @@ -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
Expand Down Expand Up @@ -222,9 +192,6 @@ export const Popover: VoidComponent<PopoverProps> = (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;

Expand All @@ -244,39 +211,15 @@ export const Popover: VoidComponent<PopoverProps> = (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
Expand Down

0 comments on commit 76dfd9d

Please sign in to comment.