Skip to content

Commit f5c1752

Browse files
committed
style: use shadcn button
1 parent 709532f commit f5c1752

File tree

2 files changed

+58
-24
lines changed

2 files changed

+58
-24
lines changed

apps/saru/app/api/history/route.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { NextResponse } from 'next/server';
2-
import { auth } from "@/lib/auth"; // Import Better Auth
3-
import { headers } from 'next/headers'; // Import headers
4-
import { getDocumentsById, getChatsByUserId } from '@/lib/db/queries'; // Import Drizzle queries
2+
import { auth } from "@/lib/auth";
3+
import { headers } from 'next/headers';
4+
import { getDocumentsById, getChatsByUserId } from '@/lib/db/queries';
55

66
export async function GET() {
77
// --- Authentication ---

apps/saru/components/sidebar/sidebar-documents.tsx

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { toast } from 'sonner';
99
import useSWR from 'swr';
1010
import { cn, fetcher } from '@/lib/utils';
1111
import {
12-
FileIcon,
1312
MoreHorizontalIcon,
1413
PlusIcon,
1514
TrashIcon,
@@ -24,12 +23,6 @@ import {
2423
AlertDialogHeader,
2524
AlertDialogTitle,
2625
} from '@/components/ui/alert-dialog';
27-
import {
28-
DropdownMenu,
29-
DropdownMenuContent,
30-
DropdownMenuItem,
31-
DropdownMenuTrigger,
32-
} from '@/components/ui/dropdown-menu';
3326
import {
3427
SidebarGroup,
3528
SidebarGroupContent,
@@ -45,7 +38,6 @@ import { Input } from '@/components/ui/input';
4538
import { Button } from '@/components/ui/button';
4639
import { Checkbox } from '@/components/ui/checkbox';
4740
import useSWRInfinite from 'swr/infinite';
48-
import { motion } from 'framer-motion';
4941

5042
type GroupedDocuments = {
5143
today: Document[];
@@ -105,7 +97,17 @@ const PureDocumentItem = ({
10597

10698
const router = useRouter();
10799
const buttonRef = useRef<HTMLButtonElement>(null);
100+
const menuRef = useRef<HTMLDivElement>(null);
101+
const closeTimerRef = useRef<number | null>(null);
108102
const [showCustomMenu, setShowCustomMenu] = useState(false);
103+
104+
useEffect(() => {
105+
return () => {
106+
if (closeTimerRef.current) {
107+
clearTimeout(closeTimerRef.current);
108+
}
109+
};
110+
}, []);
109111

110112
return (
111113
<SidebarMenuItem className="relative">
@@ -138,33 +140,65 @@ const PureDocumentItem = ({
138140
ref={buttonRef}
139141
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground mr-0.5"
140142
showOnHover={!isActive}
141-
onBlur={() => setTimeout(() => setShowCustomMenu(false), 100)}
142-
onClick={() => setShowCustomMenu(!showCustomMenu)}
143+
data-state={showCustomMenu ? 'open' : 'closed'}
144+
aria-haspopup="menu"
145+
aria-expanded={showCustomMenu}
146+
aria-controls={`doc-menu-${document.id}`}
147+
onBlur={(e) => {
148+
if (closeTimerRef.current) {
149+
clearTimeout(closeTimerRef.current);
150+
closeTimerRef.current = null;
151+
}
152+
const next = e.relatedTarget as Node | null;
153+
if (menuRef.current && next && menuRef.current.contains(next)) return;
154+
closeTimerRef.current = window.setTimeout(() => setShowCustomMenu(false), 100);
155+
}}
156+
onClick={() => setShowCustomMenu((v) => !v)}
157+
onKeyDown={(e) => {
158+
if (e.key === 'Escape') {
159+
e.stopPropagation();
160+
setShowCustomMenu(false);
161+
}
162+
if (e.key === 'Enter' || e.key === ' ') {
163+
e.preventDefault();
164+
setShowCustomMenu((v) => !v);
165+
}
166+
}}
143167
>
144168
<MoreHorizontalIcon />
145169
<span className="sr-only">More</span>
146170
</SidebarMenuAction>
147171
)}
148172

149-
{/* Dropdown positioned just below the three dots */}
150173
{!isSelectionMode && showCustomMenu && (
151174
<div
152-
className="absolute right-0 top-full z-[9999] min-w-[8rem] overflow-visible rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md"
175+
ref={menuRef}
176+
id={`doc-menu-${document.id}`}
177+
role="menu"
178+
aria-labelledby={`doc-menu-${document.id}`}
179+
className="absolute right-0 top-full z-50 min-w-[8rem] overflow-visible rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md"
153180
style={{
154-
marginTop: '2px' // Small gap below the button
181+
marginTop: '2px'
155182
}}
156183
onMouseDown={(e) => e.preventDefault()}
157-
>
158-
<div
159-
className="cursor-pointer text-destructive hover:bg-destructive/15 hover:text-destructive relative flex select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors"
160-
onClick={() => {
184+
onKeyDown={(e) => {
185+
if (e.key === 'Escape') {
186+
e.stopPropagation();
161187
setShowCustomMenu(false);
162-
onDelete(document.id);
163-
}}
188+
buttonRef.current?.focus();
189+
}
190+
}}
164191
>
192+
<Button
193+
variant="destructive"
194+
size="sm"
195+
role="menuitem"
196+
className="h-7 text-sm w-full"
197+
onClick={() => { setShowCustomMenu(false); onDelete(document.id); }}
198+
>
199+
Delete
165200
<TrashIcon />
166-
<span>Delete</span>
167-
</div>
201+
</Button>
168202
</div>
169203
)}
170204
</SidebarMenuItem>

0 commit comments

Comments
 (0)