a tool for shared writing and social publishing
1"use client";
2import * as RadixPopover from "@radix-ui/react-popover";
3import { theme } from "tailwind.config";
4import { NestedCardThemeProvider } from "../ThemeManager/ThemeProvider";
5import { useEffect, useState } from "react";
6import { PopoverArrow } from "../Icons/PopoverArrow";
7import { PopoverOpenContext } from "./PopoverContext";
8export const Popover = (props: {
9 trigger: React.ReactNode;
10 disabled?: boolean;
11 children: React.ReactNode;
12 align?: "start" | "end" | "center";
13 side?: "top" | "bottom" | "left" | "right";
14 sideOffset?: number;
15 background?: string;
16 border?: string;
17 className?: string;
18 open?: boolean;
19 onOpenChange?: (open: boolean) => void;
20 onOpenAutoFocus?: (e: Event) => void;
21 asChild?: boolean;
22 arrowFill?: string;
23 noArrow?: boolean;
24}) => {
25 let [open, setOpen] = useState(props.open || false);
26 useEffect(() => {
27 if (props.open !== undefined) setOpen(props.open);
28 }, [props.open]);
29 return (
30 <RadixPopover.Root
31 open={props.open}
32 onOpenChange={(o) => {
33 setOpen(o);
34 props.onOpenChange?.(o);
35 }}
36 >
37 <PopoverOpenContext value={open}>
38 <RadixPopover.Trigger disabled={props.disabled} asChild={props.asChild}>
39 {props.trigger}
40 </RadixPopover.Trigger>
41 <RadixPopover.Portal>
42 <NestedCardThemeProvider>
43 <RadixPopover.Content
44 className={`
45 z-20 bg-bg-page
46 px-3 py-2 text-primary
47 max-w-(--radix-popover-content-available-width)
48 max-h-(--radix-popover-content-available-height)
49 border border-border rounded-md shadow-md
50 overflow-y-scroll
51 ${props.className}
52 `}
53 side={props.side}
54 align={props.align ? props.align : "center"}
55 sideOffset={props.sideOffset ? props.sideOffset : 4}
56 collisionPadding={16}
57 onOpenAutoFocus={props.onOpenAutoFocus}
58 >
59 {props.children}
60 {!props.noArrow && (
61 <RadixPopover.Arrow
62 asChild
63 width={16}
64 height={8}
65 viewBox="0 0 16 8"
66 >
67 <PopoverArrow
68 arrowFill={
69 props.arrowFill
70 ? props.arrowFill
71 : props.background
72 ? props.background
73 : theme.colors["bg-page"]
74 }
75 arrowStroke={
76 props.border ? props.border : theme.colors["border"]
77 }
78 />
79 </RadixPopover.Arrow>
80 )}
81 </RadixPopover.Content>
82 </NestedCardThemeProvider>
83 </RadixPopover.Portal>
84 </PopoverOpenContext>
85 </RadixPopover.Root>
86 );
87};