ubiquitous-invention/apps/web/components/sidebar/sidebar-header.tsx

175 lines
5.2 KiB
TypeScript
Raw Normal View History

"use client";
import {
ChevronsLeft,
ChevronsRight,
ChevronDown,
ClipboardList,
FileText,
List,
Presentation,
LayoutGrid,
Plus,
Search,
SlidersHorizontal,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { useSidebarStore } from "@/lib/stores/sidebar-store";
export interface SidebarHeaderProps {
collapsed: boolean;
onOpenSearch?: () => void;
onQuickAction?: (type: string) => void;
}
export function SidebarHeader({
collapsed,
onOpenSearch,
onQuickAction,
}: SidebarHeaderProps) {
const toggle = useSidebarStore((s) => s.toggle);
if (collapsed) {
return (
<div className="flex shrink-0 justify-center border-b border-sidebar-border px-1 py-2">
<Tooltip>
<TooltipTrigger asChild>
<Button
type="button"
variant="ghost"
size="icon"
className="size-7 shrink-0 text-muted-foreground hover:text-sidebar-foreground"
onClick={toggle}
aria-label="Expand sidebar"
>
<ChevronsRight className="size-4" />
</Button>
</TooltipTrigger>
<TooltipContent side="right">Expand</TooltipContent>
</Tooltip>
</div>
);
}
return (
<div className="flex shrink-0 items-center gap-1 border-b border-sidebar-border px-2 py-2">
<span className="min-w-0 flex-1 truncate text-base font-semibold text-sidebar-foreground">
Home
</span>
<div className="flex shrink-0 items-center gap-0.5">
<Tooltip>
<TooltipTrigger asChild>
<Button
type="button"
variant="ghost"
size="icon"
className="size-7 text-muted-foreground hover:text-sidebar-foreground"
aria-label="Search"
onClick={() => onOpenSearch?.()}
>
<Search className="size-4" />
</Button>
</TooltipTrigger>
<TooltipContent side="bottom">Search</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button
type="button"
variant="ghost"
size="icon"
className="size-7 text-muted-foreground hover:text-sidebar-foreground"
aria-label="Filter"
>
<SlidersHorizontal className="size-4" />
</Button>
</TooltipTrigger>
<TooltipContent side="bottom">Filter</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button
type="button"
variant="ghost"
size="icon"
className="size-7 text-muted-foreground hover:text-sidebar-foreground"
onClick={toggle}
aria-label="Collapse sidebar"
>
<ChevronsLeft className="size-4" />
</Button>
</TooltipTrigger>
<TooltipContent side="bottom">Collapse</TooltipContent>
</Tooltip>
<DropdownMenu>
<Tooltip>
<TooltipTrigger asChild>
<DropdownMenuTrigger asChild>
<Button
type="button"
variant="ghost"
size="sm"
className="h-7 gap-0.5 px-1.5 text-muted-foreground hover:text-sidebar-foreground"
aria-label="Create"
>
<Plus className="size-4" />
<ChevronDown className="size-3 opacity-70" />
</Button>
</DropdownMenuTrigger>
</TooltipTrigger>
<TooltipContent side="bottom">Create</TooltipContent>
</Tooltip>
<DropdownMenuContent align="end" className="w-52">
<DropdownMenuItem
className="gap-2"
onClick={() => onQuickAction?.("list")}
>
<List className="size-4" />
List
</DropdownMenuItem>
<DropdownMenuItem
className="gap-2"
onClick={() => onQuickAction?.("doc")}
>
<FileText className="size-4" />
Doc
</DropdownMenuItem>
<DropdownMenuItem
className="gap-2"
onClick={() => onQuickAction?.("whiteboard")}
>
<Presentation className="size-4" />
Whiteboard
</DropdownMenuItem>
<DropdownMenuItem
className="gap-2"
onClick={() => onQuickAction?.("form")}
>
<ClipboardList className="size-4" />
Form
</DropdownMenuItem>
<DropdownMenuItem
className="gap-2"
onClick={() => onQuickAction?.("space")}
>
<LayoutGrid className="size-4" />
Space
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</div>
);
}