feat: add tooltip functionality to DocumentNode for title overflow handling and refactor ChatShareButton by removing unnecessary Tooltip wrapper

This commit is contained in:
Anish Sarkar 2026-04-05 22:50:36 +05:30
parent c6e94188eb
commit 1f162f52c3
2 changed files with 34 additions and 16 deletions

View file

@ -12,6 +12,7 @@ import {
Trash2, Trash2,
} from "lucide-react"; } from "lucide-react";
import React, { useCallback, useRef, useState } from "react"; import React, { useCallback, useRef, useState } from "react";
import { useIsMobile } from "@/hooks/use-mobile";
import { useDrag } from "react-dnd"; import { useDrag } from "react-dnd";
import { getDocumentTypeIcon } from "@/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentTypeIcon"; import { getDocumentTypeIcon } from "@/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentTypeIcon";
import { ExportContextItems, ExportDropdownItems } from "@/components/shared/ExportMenuItems"; import { ExportContextItems, ExportDropdownItems } from "@/components/shared/ExportMenuItems";
@ -106,7 +107,10 @@ export const DocumentNode = React.memo(function DocumentNode({
const isProcessing = statusState === "pending" || statusState === "processing"; const isProcessing = statusState === "pending" || statusState === "processing";
const [dropdownOpen, setDropdownOpen] = useState(false); const [dropdownOpen, setDropdownOpen] = useState(false);
const [exporting, setExporting] = useState<string | null>(null); const [exporting, setExporting] = useState<string | null>(null);
const [titleTooltipOpen, setTitleTooltipOpen] = useState(false);
const rowRef = useRef<HTMLDivElement>(null); const rowRef = useRef<HTMLDivElement>(null);
const titleRef = useRef<HTMLSpanElement>(null);
const isMobile = useIsMobile();
const handleExport = useCallback( const handleExport = useCallback(
(format: string) => { (format: string) => {
@ -118,6 +122,18 @@ export const DocumentNode = React.memo(function DocumentNode({
[doc, onExport] [doc, onExport]
); );
const handleTitleTooltipOpenChange = useCallback(
(open: boolean) => {
if (isMobile) return;
if (open && titleRef.current) {
setTitleTooltipOpen(titleRef.current.scrollWidth > titleRef.current.clientWidth);
} else {
setTitleTooltipOpen(false);
}
},
[isMobile]
);
const attachRef = useCallback( const attachRef = useCallback(
(node: HTMLDivElement | null) => { (node: HTMLDivElement | null) => {
(rowRef as React.MutableRefObject<HTMLDivElement | null>).current = node; (rowRef as React.MutableRefObject<HTMLDivElement | null>).current = node;
@ -197,7 +213,14 @@ export const DocumentNode = React.memo(function DocumentNode({
); );
})()} })()}
<span className="flex-1 min-w-0 truncate">{doc.title}</span> <Tooltip delayDuration={600} open={titleTooltipOpen} onOpenChange={handleTitleTooltipOpenChange}>
<TooltipTrigger asChild>
<span ref={titleRef} className="flex-1 min-w-0 truncate">{doc.title}</span>
</TooltipTrigger>
<TooltipContent side="bottom" className="max-w-xs break-words">
{doc.title}
</TooltipContent>
</Tooltip>
{getDocumentTypeIcon( {getDocumentTypeIcon(
doc.document_type as DocumentTypeEnum, doc.document_type as DocumentTypeEnum,

View file

@ -163,21 +163,16 @@ export function ChatShareButton({ thread, onVisibilityChange, className }: ChatS
)} )}
<Popover open={open} onOpenChange={setOpen}> <Popover open={open} onOpenChange={setOpen}>
<Tooltip> <PopoverTrigger asChild>
<TooltipTrigger asChild> <Button
<PopoverTrigger asChild> variant="outline"
<Button size="icon"
variant="outline" className="h-8 w-8 md:w-auto md:px-3 md:gap-2 relative bg-muted hover:bg-muted/80 border-0 select-none"
size="icon" >
className="h-8 w-8 md:w-auto md:px-3 md:gap-2 relative bg-muted hover:bg-muted/80 border-0 select-none" <CurrentIcon className="h-4 w-4" />
> <span className="hidden md:inline text-sm">{buttonLabel}</span>
<CurrentIcon className="h-4 w-4" /> </Button>
<span className="hidden md:inline text-sm">{buttonLabel}</span> </PopoverTrigger>
</Button>
</PopoverTrigger>
</TooltipTrigger>
<TooltipContent>Share settings</TooltipContent>
</Tooltip>
<PopoverContent <PopoverContent
className="w-[280px] md:w-[320px] p-0 rounded-lg shadow-lg border-border/60 dark:bg-neutral-900 dark:border dark:border-white/5 select-none" className="w-[280px] md:w-[320px] p-0 rounded-lg shadow-lg border-border/60 dark:bg-neutral-900 dark:border dark:border-white/5 select-none"