"use client"; import { CheckIcon } from "@heroicons/react/20/solid"; import { EllipsisVerticalIcon } from "@heroicons/react/24/solid"; import * as PopoverPrimitive from "@radix-ui/react-popover"; import { Link } from "@remix-run/react"; import * as React from "react"; import { DropdownIcon } from "~/assets/icons/DropdownIcon"; import * as useShortcutKeys from "~/hooks/useShortcutKeys"; import { cn } from "~/utils/cn"; import { ButtonContent, type ButtonContentPropsType } from "./Buttons"; import { type RenderIcon } from "./Icon"; import { Paragraph, type ParagraphVariant } from "./Paragraph"; import { ShortcutKey } from "./ShortcutKey"; const Popover = PopoverPrimitive.Root; const PopoverTrigger = PopoverPrimitive.Trigger; const PopoverContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( )); PopoverContent.displayName = PopoverPrimitive.Content.displayName; function PopoverSectionHeader({ title, variant = "extra-small", }: { title: string; variant?: ParagraphVariant; }) { return ( {title} ); } const PopoverMenuItem = React.forwardRef< HTMLButtonElement | HTMLAnchorElement, { to?: string; icon?: RenderIcon; title: React.ReactNode; isSelected?: boolean; variant?: ButtonContentPropsType; leadingIconClassName?: string; className?: string; onClick?: React.MouseEventHandler; disabled?: boolean; openInNewTab?: boolean; name?: string; value?: string; type?: React.ComponentProps<"button">["type"]; danger?: boolean; } >( ( { to, icon, title, isSelected, variant = { variant: "small-menu-item" }, leadingIconClassName, className, onClick, disabled, openInNewTab = false, name, value, type, danger = false, }, ref ) => { const contentProps = { variant: variant.variant, LeadingIcon: icon, leadingIconClassName: danger ? cn(leadingIconClassName, "transition-colors group-hover/button:text-error") : leadingIconClassName, fullWidth: true, textAlignLeft: true, TrailingIcon: isSelected ? CheckIcon : undefined, className: cn( danger ? "transition-colors group-hover/button:bg-error/10 group-hover/button:text-error [&_span]:transition-colors group-hover/button:[&_span]:text-error" : "group-hover:bg-background-raised", isSelected ? "bg-background-hover group-hover:bg-surface-control/50" : undefined, className ), } as const; if (to) { return ( } className={cn("group/button focus-custom", contentProps.fullWidth ? "w-full" : "")} onClick={onClick as any} target={openInNewTab ? "_blank" : undefined} rel={openInNewTab ? "noopener noreferrer" : undefined} > {title} ); } return ( ); } ); PopoverMenuItem.displayName = "PopoverMenuItem"; function PopoverCustomTrigger({ isOpen, children, className, ...props }: { isOpen?: boolean } & React.ComponentPropsWithoutRef) { return ( {children} ); } function PopoverSideMenuTrigger({ isOpen, children, className, shortcut, hideShortcutKey = false, ...props }: { isOpen?: boolean; shortcut?: useShortcutKeys.ShortcutDefinition; hideShortcutKey?: boolean; } & React.ComponentPropsWithoutRef) { const ref = React.useRef(null); useShortcutKeys.useShortcutKeys({ shortcut: shortcut, action: (e) => { e.preventDefault(); e.stopPropagation(); if (ref.current) { ref.current.click(); } }, }); return ( {children} {shortcut && !hideShortcutKey && ( )} ); } const popoverArrowTriggerVariants = { minimal: { trigger: "text-text-dimmed hover:bg-background-raised hover:text-text-bright", text: "group-hover:text-text-bright", icon: "text-text-dimmed group-hover:text-text-bright", }, primary: { trigger: "bg-indigo-600 border border-indigo-500 text-text-bright hover:bg-indigo-500 hover:border-indigo-400 disabled:opacity-50 disabled:pointer-events-none", text: "text-text-bright hover:text-white", icon: "text-text-bright", }, secondary: { trigger: "bg-secondary border border-border-bright text-text-bright hover:bg-surface-control hover:border-border-brighter disabled:opacity-60 disabled:pointer-events-none", text: "text-text-bright", icon: "text-text-bright", }, tertiary: { trigger: "bg-tertiary text-text-bright hover:bg-surface-control", text: "text-text-bright", icon: "text-text-bright", }, } as const; type PopoverArrowTriggerVariant = keyof typeof popoverArrowTriggerVariants; function PopoverArrowTrigger({ isOpen, children, fullWidth = false, overflowHidden = false, variant = "minimal", className, ...props }: { isOpen?: boolean; fullWidth?: boolean; overflowHidden?: boolean; variant?: PopoverArrowTriggerVariant; } & React.ComponentPropsWithoutRef) { const variantStyles = popoverArrowTriggerVariants[variant]; return ( {children} ); } const popoverVerticalEllipseVariants = { minimal: { trigger: "size-6 rounded-[3px] text-text-dimmed hover:bg-tertiary hover:text-text-bright", icon: "size-5", }, secondary: { trigger: "size-6 rounded border border-border-bright bg-secondary text-text-bright hover:bg-surface-control hover:border-border-brighter", icon: "size-4", }, } as const; type PopoverVerticalEllipseVariant = keyof typeof popoverVerticalEllipseVariants; function PopoverVerticalEllipseTrigger({ isOpen, variant = "minimal", className, ...props }: { isOpen?: boolean; variant?: PopoverVerticalEllipseVariant; } & React.ComponentPropsWithoutRef) { const styles = popoverVerticalEllipseVariants[variant]; return ( ); } export { Popover, PopoverArrowTrigger, PopoverContent, PopoverCustomTrigger, PopoverMenuItem, PopoverSectionHeader, PopoverSideMenuTrigger, PopoverTrigger, PopoverVerticalEllipseTrigger, }; export type { PopoverArrowTriggerVariant };