refactor: enhance citation components with mobile support and improved styling for better user experience

This commit is contained in:
Anish Sarkar 2026-05-15 03:56:01 +05:30
parent 01d7379914
commit 4dd5871318
4 changed files with 92 additions and 53 deletions

View file

@ -2,6 +2,7 @@
import type { ComponentProps, HTMLAttributes, ReactElement, ReactNode } from "react";
import { useCallback, useEffect, useRef, useSyncExternalStore } from "react";
import { useMediaQuery } from "@/hooks/use-media-query";
import { Popover, PopoverContent, PopoverTrigger } from "./_adapter";
type PopoverContentProps = ComponentProps<typeof PopoverContent>;
@ -113,6 +114,7 @@ export function CitationHoverPopover({
sideOffset = 6,
onContentClick,
}: CitationHoverPopoverProps) {
const isTouchLike = useMediaQuery("(hover: none), (pointer: coarse)");
const { open, scheduleOpen, scheduleClose, handleOpenChange } = useCitationHoverState(id);
const hoverProps = {
onPointerEnter: scheduleOpen,
@ -121,6 +123,10 @@ export function CitationHoverPopover({
onBlur: scheduleClose,
} satisfies CitationHoverTriggerProps;
if (isTouchLike) {
return trigger({});
}
return (
<Popover open={open} onOpenChange={handleOpenChange}>
<PopoverTrigger asChild>{trigger(hoverProps)}</PopoverTrigger>

View file

@ -95,7 +95,7 @@ export function Citation(props: CitationProps) {
return (
<CitationHoverPopover
id={id}
contentClassName="w-72 cursor-pointer p-0"
contentClassName="w-72 cursor-pointer overflow-hidden p-0"
onContentClick={handleClick}
trigger={(hoverProps) => (
<Button
@ -107,20 +107,16 @@ export function Citation(props: CitationProps) {
onClick={handleClick}
{...hoverProps}
className={cn(
"h-auto cursor-pointer gap-1.5 rounded-md px-2 py-1",
"bg-muted/60 text-sm outline-none",
"transition-colors duration-150",
"hover:bg-accent hover:text-accent-foreground",
"focus-visible:ring-ring focus-visible:ring-2",
"ml-0.5 inline-flex h-5 min-w-5 cursor-pointer items-center justify-center gap-1.5 rounded-md bg-popover px-1.5 text-[11px] font-medium text-popover-foreground/80 align-baseline",
className
)}
>
{iconElement}
<span className="text-muted-foreground">{domain}</span>
<span>{domain}</span>
</Button>
)}
>
<div className="hover:bg-accent hover:text-accent-foreground flex flex-col gap-2 p-3 transition-colors">
<div className="flex flex-col gap-2 p-3">
<div className="flex items-start gap-2">
{iconElement}
<span className="text-muted-foreground text-xs">{domain}</span>