mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-25 08:46:22 +02:00
feat: introduce SidebarButton component for improved sidebar interactions
This commit is contained in:
parent
9a20db7fc4
commit
affc89dd5c
3 changed files with 126 additions and 74 deletions
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
import { CheckCircle2, CircleAlert } from "lucide-react";
|
||||
import { Spinner } from "@/components/ui/spinner";
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { NavItem } from "../../types/layout.types";
|
||||
import { SidebarButton } from "./SidebarButton";
|
||||
|
||||
interface NavSectionProps {
|
||||
items: NavItem[];
|
||||
|
|
@ -66,71 +66,48 @@ function StatusIcon({
|
|||
return <FallbackIcon className={cn("shrink-0", className)} />;
|
||||
}
|
||||
|
||||
function CollapsedOverlay({ item }: { item: NavItem }) {
|
||||
const indicator = item.statusIndicator;
|
||||
if (indicator && indicator !== "idle") {
|
||||
return <StatusBadge status={indicator} />;
|
||||
}
|
||||
if (item.badge) {
|
||||
return (
|
||||
<span className="absolute top-0.5 right-0.5 inline-flex items-center justify-center min-w-[14px] h-[14px] px-0.5 rounded-full bg-red-500 text-white text-[9px] font-medium">
|
||||
{item.badge}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function NavSection({ items, onItemClick, isCollapsed = false }: NavSectionProps) {
|
||||
return (
|
||||
<div className={cn("flex flex-col gap-0.5 py-2", isCollapsed && "items-center")}>
|
||||
{items.map((item) => {
|
||||
const Icon = item.icon;
|
||||
const indicator = item.statusIndicator;
|
||||
|
||||
const joyrideAttr =
|
||||
item.title === "Inbox" || item.title.toLowerCase().includes("inbox")
|
||||
? { "data-joyride": "inbox-sidebar" }
|
||||
? { "data-joyride": "inbox-sidebar" as const }
|
||||
: {};
|
||||
|
||||
if (isCollapsed) {
|
||||
return (
|
||||
<Tooltip key={item.url}>
|
||||
<TooltipTrigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onItemClick?.(item)}
|
||||
className={cn(
|
||||
"relative flex h-10 w-10 items-center justify-center rounded-md transition-colors",
|
||||
"hover:bg-accent hover:text-accent-foreground",
|
||||
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
||||
)}
|
||||
{...joyrideAttr}
|
||||
>
|
||||
<Icon className="h-4 w-4" />
|
||||
{indicator && indicator !== "idle" ? (
|
||||
<StatusBadge status={indicator} />
|
||||
) : item.badge ? (
|
||||
<span className="absolute top-0.5 right-0.5 inline-flex items-center justify-center min-w-[14px] h-[14px] px-0.5 rounded-full bg-red-500 text-white text-[9px] font-medium">
|
||||
{item.badge}
|
||||
</span>
|
||||
) : null}
|
||||
<span className="sr-only">{item.title}</span>
|
||||
</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="right">
|
||||
{item.title}
|
||||
{item.badge && ` (${item.badge})`}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
<SidebarButton
|
||||
key={item.url}
|
||||
type="button"
|
||||
icon={item.icon}
|
||||
label={item.title}
|
||||
onClick={() => onItemClick?.(item)}
|
||||
className={cn(
|
||||
"flex items-center gap-2 rounded-md mx-2 px-2 py-1.5 text-sm transition-colors text-left",
|
||||
"hover:bg-accent hover:text-accent-foreground",
|
||||
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
||||
)}
|
||||
{...joyrideAttr}
|
||||
>
|
||||
<StatusIcon status={indicator} FallbackIcon={Icon} className="h-4 w-4" />
|
||||
<span className="flex-1 truncate">{item.title}</span>
|
||||
{item.badge && (
|
||||
<span className="inline-flex items-center justify-center min-w-4 h-4 px-1 rounded-full bg-red-500 text-white text-[10px] font-medium">
|
||||
{item.badge}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
isCollapsed={isCollapsed}
|
||||
badge={item.badge}
|
||||
collapsedOverlay={<CollapsedOverlay item={item} />}
|
||||
expandedIconNode={
|
||||
<StatusIcon
|
||||
status={item.statusIndicator}
|
||||
FallbackIcon={item.icon}
|
||||
className="h-4 w-4"
|
||||
/>
|
||||
}
|
||||
buttonProps={joyrideAttr}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue