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