Mobile ui

This commit is contained in:
2026-02-14 22:22:05 -08:00
parent a5650e8a1b
commit d6c832dac3

View File

@@ -1,5 +1,5 @@
import { useEffect, useMemo, useRef, useState } from "preact/hooks";
import { Check, ChevronDown, Globe2, LogOut, MessageSquare, Plus, Search, SendHorizontal, Trash2 } from "lucide-preact";
import { Check, ChevronDown, Globe2, Menu, MessageSquare, Plus, Search, SendHorizontal, Trash2 } from "lucide-preact";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { Separator } from "@/components/ui/separator";
@@ -301,6 +301,7 @@ export default function App() {
const searchRunAbortRef = useRef<AbortController | null>(null);
const searchRunCounterRef = useRef(0);
const [contextMenu, setContextMenu] = useState<ContextMenuState | null>(null);
const [isMobileSidebarOpen, setIsMobileSidebarOpen] = useState(false);
useEffect(() => {
if (typeof document === "undefined") return;
@@ -549,6 +550,7 @@ export default function App() {
setSelectedItem(null);
setSelectedChat(null);
setSelectedSearch(null);
setIsMobileSidebarOpen(false);
};
const handleCreateSearch = () => {
@@ -558,6 +560,7 @@ export default function App() {
setSelectedItem(null);
setSelectedChat(null);
setSelectedSearch(null);
setIsMobileSidebarOpen(false);
};
const openContextMenu = (event: MouseEvent, item: SidebarSelection) => {
@@ -956,7 +959,21 @@ export default function App() {
return (
<div className="h-full">
<div className="flex h-full w-full overflow-hidden bg-background">
<aside className="flex w-80 shrink-0 flex-col border-r bg-[hsl(272_34%_14%)]">
{isMobileSidebarOpen ? (
<button
type="button"
className="fixed inset-0 z-30 bg-black/45 md:hidden"
onClick={() => setIsMobileSidebarOpen(false)}
aria-label="Close sidebar"
/>
) : null}
<aside
className={cn(
"fixed inset-y-0 left-0 z-40 flex w-[85vw] max-w-80 shrink-0 flex-col border-r bg-[hsl(272_34%_14%)] transition-transform md:static md:z-auto md:w-80 md:max-w-none",
isMobileSidebarOpen ? "translate-x-0" : "-translate-x-full md:translate-x-0"
)}
>
<div className="grid grid-cols-2 gap-2 p-3">
<Button className="justify-start gap-2" onClick={handleCreateChat}>
<Plus className="h-4 w-4" />
@@ -992,6 +1009,7 @@ export default function App() {
setContextMenu(null);
setDraftKind(null);
setSelectedItem({ kind: item.kind, id: item.id });
setIsMobileSidebarOpen(false);
}}
onContextMenu={(event) => openContextMenu(event, { kind: item.kind, id: item.id })}
type="button"
@@ -1014,12 +1032,25 @@ export default function App() {
<main className="flex min-w-0 flex-1 flex-col">
<header className="flex flex-wrap items-center justify-between gap-3 border-b px-4 py-3">
<div>
<div className="flex items-start gap-2">
<Button
type="button"
size="icon"
variant="ghost"
className="-ml-1 h-8 w-8 md:hidden"
onClick={() => setIsMobileSidebarOpen(true)}
aria-label="Open sidebar"
>
<Menu className="h-4 w-4" />
</Button>
<div>
<h1 className="text-sm font-semibold md:text-base">{selectedTitle}</h1>
<p className="text-xs text-muted-foreground">
Sybil Web{authMode ? ` (${authMode === "open" ? "open mode" : "token mode"})` : ""}
{isSearchMode ? " • Exa Search" : ""}
</p>
</div>
</div>
<div className="flex w-full max-w-xl items-center gap-2 md:w-auto">
{!isSearchMode ? (