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 relative 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 ${props.className}
51 `}
52 side={props.side}
53 align={props.align ? props.align : "center"}
54 sideOffset={props.sideOffset ? props.sideOffset : 4}
55 collisionPadding={16}
56 onOpenAutoFocus={props.onOpenAutoFocus}
57 >
58 {props.children}
59 {!props.noArrow && (
60 <RadixPopover.Arrow
61 asChild
62 width={16}
63 height={8}
64 viewBox="0 0 16 8"
65 >
66 <PopoverArrow
67 arrowFill={
68 props.arrowFill
69 ? props.arrowFill
70 : props.background
71 ? props.background
72 : theme.colors["bg-page"]
73 }
74 arrowStroke={
75 props.border ? props.border : theme.colors["border"]
76 }
77 />
78 </RadixPopover.Arrow>
79 )}
80 </RadixPopover.Content>
81 </NestedCardThemeProvider>
82 </RadixPopover.Portal>
83 </PopoverOpenContext>
84 </RadixPopover.Root>
85 );
86};