fix: update styling and accessibility in various components

- Simplified text in DocumentsTableShell for clarity.
- Enhanced RightPanel styling for better visual consistency.
- Adjusted ChatListItem styles for improved interaction.
- Updated ReportPanelContent to include background styling and improved layout.
- Modified Drawer and FixedToolbar components for better UI integration.
This commit is contained in:
Anish Sarkar 2026-03-17 14:16:22 +05:30
parent 440f5aec72
commit 9321d27021
7 changed files with 49 additions and 22 deletions

View file

@ -817,7 +817,7 @@ export function DocumentsTableShell({
{hasDeletableSelection && (
<div className="flex items-center justify-between px-3 py-2 bg-muted/50 border-b border-border/50 sticky top-0 z-10">
<span className="text-xs text-muted-foreground">
{deletableSelectedIds.length} deletable selected
{deletableSelectedIds.length} selected
</span>
<Button
variant="destructive"

View file

@ -103,7 +103,7 @@ export function RightPanel({ documentsPanel }: RightPanelProps) {
return (
<aside
style={{ width: targetWidth }}
className="flex h-full shrink-0 flex-col rounded-xl border bg-background overflow-hidden transition-[width] duration-200 ease-out"
className="flex h-full shrink-0 flex-col rounded-xl border bg-sidebar text-sidebar-foreground overflow-hidden transition-[width] duration-200 ease-out"
>
<div className="relative flex-1 min-h-0 overflow-hidden">
{effectiveTab === "sources" && documentsOpen && documentsPanel && (
@ -117,9 +117,9 @@ export function RightPanel({ documentsPanel }: RightPanelProps) {
</div>
)}
{effectiveTab === "report" && reportOpen && (
<div className="h-full">
<div className="h-full flex flex-col">
<ReportPanelContent
reportId={reportState.reportId!}
reportId={reportState.reportId as number}
title={reportState.title || "Report"}
onClose={closeReport}
shareToken={reportState.shareToken}

View file

@ -61,7 +61,7 @@ export function ChatListItem({
onClick={handleClick}
{...(isMobile ? longPressHandlers : {})}
className={cn(
"flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-sm text-left transition-colors",
"flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-sm text-left",
"group-hover/item:bg-accent group-hover/item:text-accent-foreground",
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
isActive && "bg-accent text-accent-foreground"
@ -73,7 +73,7 @@ export function ChatListItem({
{/* Actions dropdown - trigger hidden on mobile, long-press opens it instead */}
<div
className={cn(
"pointer-events-none absolute right-0 top-0 bottom-0 flex items-center pr-1 pl-6 rounded-r-md transition-opacity",
"pointer-events-none absolute right-0 top-0 bottom-0 flex items-center pr-1 pl-6 rounded-r-md",
isActive
? "bg-gradient-to-l from-accent from-60% to-transparent"
: "bg-gradient-to-l from-sidebar from-60% to-transparent group-hover/item:from-accent",

View file

@ -307,7 +307,7 @@ export function ReportPanelContent({
size="sm"
onClick={handleCopy}
disabled={isLoading || !reportContent?.content}
className="h-8 min-w-[80px] px-3.5 py-4 text-[15px]"
className="h-8 min-w-[80px] px-3.5 py-4 text-[15px] bg-sidebar select-none"
>
{copied ? "Copied" : "Copy"}
</Button>
@ -319,7 +319,7 @@ export function ReportPanelContent({
variant="outline"
size="sm"
disabled={isLoading || !reportContent?.content}
className="h-8 px-3.5 py-4 text-[15px] gap-1.5"
className="h-8 px-3.5 py-4 text-[15px] gap-1.5 bg-sidebar select-none"
>
Export
<ChevronDownIcon className="size-3" />
@ -327,7 +327,7 @@ export function ReportPanelContent({
</DropdownMenuTrigger>
<DropdownMenuContent
align="start"
className={`min-w-[200px] dark:bg-neutral-900 dark:border dark:border-white/5${insideDrawer ? " z-[100]" : ""}`}
className={`min-w-[200px] select-none${insideDrawer ? " z-[100]" : ""}`}
>
{!shareToken && (
<>
@ -398,14 +398,18 @@ export function ReportPanelContent({
{versions.length > 1 && (
<DropdownMenu modal={insideDrawer ? false : undefined}>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="sm" className="h-8 px-3.5 py-4 text-[15px] gap-1.5">
<Button
variant="outline"
size="sm"
className="h-8 px-3.5 py-4 text-[15px] gap-1.5 bg-sidebar select-none"
>
v{activeVersionIndex + 1}
<ChevronDownIcon className="size-3" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent
align="start"
className={`min-w-[120px] dark:bg-neutral-900 dark:border dark:border-white/5${insideDrawer ? " z-[100]" : ""}`}
className={`min-w-[120px] select-none${insideDrawer ? " z-[100]" : ""}`}
>
{versions.map((v, i) => (
<DropdownMenuItem
@ -455,6 +459,7 @@ export function ReportPanelContent({
onSave={handleSave}
hasUnsavedChanges={editedMarkdown !== null}
isSaving={saving}
className="[&_[role=toolbar]]:!bg-sidebar"
/>
)
) : (
@ -491,7 +496,7 @@ function DesktopReportPanel() {
return (
<div
ref={panelRef}
className="flex w-[50%] max-w-[700px] min-w-[380px] flex-col border-l bg-background animate-in slide-in-from-right-4 duration-300 ease-out"
className="flex w-[50%] max-w-[700px] min-w-[380px] flex-col border-l bg-sidebar text-sidebar-foreground animate-in slide-in-from-right-4 duration-300 ease-out"
>
<ReportPanelContent
reportId={panelState.reportId}
@ -521,7 +526,7 @@ function MobileReportDrawer() {
shouldScaleBackground={false}
>
<DrawerContent
className="h-[90vh] max-h-[90vh] z-80 !rounded-none border-none"
className="h-[95vh] max-h-[95vh] z-80 bg-sidebar overflow-hidden"
overlayClassName="z-80"
>
<DrawerHandle />

View file

@ -4,10 +4,11 @@ import { makeAssistantToolUI } from "@assistant-ui/react";
import { useAtomValue, useSetAtom } from "jotai";
import { Dot, FileTextIcon } from "lucide-react";
import { useParams, usePathname } from "next/navigation";
import { useEffect, useState } from "react";
import { useEffect, useRef, useState } from "react";
import { z } from "zod";
import { openReportPanelAtom, reportPanelAtom } from "@/atoms/chat/report-panel.atom";
import { TextShimmerLoader } from "@/components/prompt-kit/loader";
import { useMediaQuery } from "@/hooks/use-media-query";
import { baseApiService } from "@/lib/apis/base-api.service";
/**
@ -110,15 +111,20 @@ function ReportCard({
title,
wordCount,
shareToken,
autoOpen = false,
}: {
reportId: number;
title: string;
wordCount?: number;
/** When set, uses public endpoint for fetching report data */
shareToken?: string | null;
/** When true, auto-opens the report panel on desktop after metadata loads */
autoOpen?: boolean;
}) {
const openPanel = useSetAtom(openReportPanelAtom);
const panelState = useAtomValue(reportPanelAtom);
const isDesktop = useMediaQuery("(min-width: 768px)");
const autoOpenedRef = useRef(false);
const [metadata, setMetadata] = useState<{
title: string;
wordCount: number | null;
@ -154,11 +160,19 @@ function ReportCard({
versionLabel = `version ${idx + 1}`;
}
}
setMetadata({
title: parsed.data.title || title,
wordCount: parsed.data.report_metadata?.word_count ?? wordCount ?? null,
versionLabel,
});
const resolvedTitle = parsed.data.title || title;
const resolvedWordCount = parsed.data.report_metadata?.word_count ?? wordCount ?? null;
setMetadata({ title: resolvedTitle, wordCount: resolvedWordCount, versionLabel });
if (autoOpen && isDesktop && !autoOpenedRef.current) {
autoOpenedRef.current = true;
openPanel({
reportId,
title: resolvedTitle,
wordCount: resolvedWordCount ?? undefined,
shareToken,
});
}
}
}
} catch {
@ -171,7 +185,7 @@ function ReportCard({
return () => {
cancelled = true;
};
}, [reportId, title, wordCount, shareToken]);
}, [reportId, title, wordCount, shareToken, autoOpen, isDesktop, openPanel]);
// Show non-clickable error card for any error (failed status, not found, etc.)
if (!isLoading && error) {
@ -243,6 +257,13 @@ export const GenerateReportToolUI = makeAssistantToolUI<GenerateReportArgs, Gene
const topic = args.topic || "Report";
// Track whether we witnessed the generation (running state).
// If we mount directly with a result, this stays false → it's a revisit.
const sawRunningRef = useRef(false);
if (status.type === "running" || status.type === "requires-action") {
sawRunningRef.current = true;
}
// Loading state - tool is still running (LLM generating report)
if (status.type === "running" || status.type === "requires-action") {
return <ReportGeneratingState topic={topic} />;
@ -293,6 +314,7 @@ export const GenerateReportToolUI = makeAssistantToolUI<GenerateReportArgs, Gene
title={result.title || topic}
wordCount={result.word_count ?? undefined}
shareToken={shareToken}
autoOpen={sawRunningRef.current}
/>
);
}

View file

@ -45,7 +45,7 @@ function DrawerContent({
<DrawerOverlay className={overlayClassName} />
<DrawerPrimitive.Content
className={cn(
"fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background",
"fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-3xl bg-main-panel",
className
)}
{...props}

View file

@ -14,7 +14,7 @@ export function FixedToolbar({
return (
<Toolbar
className={cn(
"scrollbar-hide sticky top-0 left-0 z-10 w-full justify-between overflow-x-auto rounded-t-lg border-b bg-background/95 p-1 backdrop-blur supports-backdrop-filter:bg-background/60",
"scrollbar-hide sticky top-0 left-0 z-10 w-full justify-between overflow-x-auto border-b bg-background/95 p-1 backdrop-blur supports-backdrop-filter:bg-background/60",
className
)}
{...props}