diff --git a/surfsense_web/components/layout/ui/sidebar/ChatListItem.tsx b/surfsense_web/components/layout/ui/sidebar/ChatListItem.tsx
index 4ef7b2965..ea4f946c2 100644
--- a/surfsense_web/components/layout/ui/sidebar/ChatListItem.tsx
+++ b/surfsense_web/components/layout/ui/sidebar/ChatListItem.tsx
@@ -56,19 +56,20 @@ export function ChatListItem({
return (
-
{animatedName}
-
+
{/* Actions dropdown - trigger hidden on mobile, long-press opens it instead */}
- {
setActiveFilter("all");
setFilterDrawerOpen(false);
}}
className={cn(
- "flex w-full items-center justify-between rounded-lg px-3 py-2.5 text-sm transition-colors",
+ "h-auto w-full justify-between rounded-lg px-3 py-2.5 text-sm transition-colors",
activeFilter === "all"
? "bg-primary/10 text-primary"
: "hover:bg-muted"
@@ -593,15 +594,16 @@ export function InboxSidebarContent({
{t("all") || "All"}
{activeFilter === "all" && }
-
-
+ {
setActiveFilter("unread");
setFilterDrawerOpen(false);
}}
className={cn(
- "flex w-full items-center justify-between rounded-lg px-3 py-2.5 text-sm transition-colors",
+ "h-auto w-full justify-between rounded-lg px-3 py-2.5 text-sm transition-colors",
activeFilter === "unread"
? "bg-primary/10 text-primary"
: "hover:bg-muted"
@@ -612,16 +614,17 @@ export function InboxSidebarContent({
{t("unread") || "Unread"}
{activeFilter === "unread" && }
-
+
{activeTab === "status" && (
- {
setActiveFilter("errors");
setFilterDrawerOpen(false);
}}
className={cn(
- "flex w-full items-center justify-between rounded-lg px-3 py-2.5 text-sm transition-colors",
+ "h-auto w-full justify-between rounded-lg px-3 py-2.5 text-sm transition-colors",
activeFilter === "errors"
? "bg-primary/10 text-primary"
: "hover:bg-muted"
@@ -632,7 +635,7 @@ export function InboxSidebarContent({
{t("errors_only") || "Errors only"}
{activeFilter === "errors" && }
-
+
)}
@@ -642,14 +645,15 @@ export function InboxSidebarContent({
{t("sources") || "Sources"}
- {
setSelectedSource(null);
setFilterDrawerOpen(false);
}}
className={cn(
- "flex w-full items-center justify-between rounded-lg px-3 py-2.5 text-sm transition-colors",
+ "h-auto w-full justify-between rounded-lg px-3 py-2.5 text-sm transition-colors",
selectedSource === null
? "bg-primary/10 text-primary"
: "hover:bg-muted"
@@ -660,17 +664,18 @@ export function InboxSidebarContent({
{t("all_sources") || "All sources"}
{selectedSource === null && }
-
+
{statusSourceOptions.map((source) => (
- {
setSelectedSource(source.key);
setFilterDrawerOpen(false);
}}
className={cn(
- "flex w-full items-center justify-between rounded-lg px-3 py-2.5 text-sm transition-colors",
+ "h-auto w-full justify-between rounded-lg px-3 py-2.5 text-sm transition-colors",
selectedSource === source.key
? "bg-primary/10 text-primary"
: "hover:bg-muted"
@@ -681,7 +686,7 @@ export function InboxSidebarContent({
{source.displayName}
{selectedSource === source.key && }
-
+
))}
@@ -922,11 +927,12 @@ export function InboxSidebarContent({
{activeTab === "status" ? (
diff --git a/surfsense_web/components/layout/ui/sidebar/Sidebar.tsx b/surfsense_web/components/layout/ui/sidebar/Sidebar.tsx
index 3a319347f..7cc65d2b8 100644
--- a/surfsense_web/components/layout/ui/sidebar/Sidebar.tsx
+++ b/surfsense_web/components/layout/ui/sidebar/Sidebar.tsx
@@ -6,6 +6,7 @@ import { useParams } from "next/navigation";
import { useTranslations } from "next-intl";
import { useMemo, useState } from "react";
import { Badge } from "@/components/ui/badge";
+import { Button } from "@/components/ui/button";
import { Progress } from "@/components/ui/progress";
import { Skeleton } from "@/components/ui/skeleton";
import { useIsAnonymous } from "@/contexts/anonymous-mode";
@@ -204,13 +205,14 @@ export function Sidebar({
alwaysShowAction={!disableTooltips && isSharedChatsPanelOpen}
action={
onViewAllSharedChats ? (
-
{!disableTooltips && isSharedChatsPanelOpen ? t("hide") : t("show_all")}
-
+
) : undefined
}
>
@@ -260,13 +262,14 @@ export function Sidebar({
alwaysShowAction={!disableTooltips && isPrivateChatsPanelOpen}
action={
onViewAllPrivateChats ? (
-
{!disableTooltips && isPrivateChatsPanelOpen ? t("hide") : t("show_all")}
-
+
) : undefined
}
>
diff --git a/surfsense_web/components/layout/ui/sidebar/SidebarButton.tsx b/surfsense_web/components/layout/ui/sidebar/SidebarButton.tsx
index 6702cea4a..83ece94ab 100644
--- a/surfsense_web/components/layout/ui/sidebar/SidebarButton.tsx
+++ b/surfsense_web/components/layout/ui/sidebar/SidebarButton.tsx
@@ -12,18 +12,12 @@ interface SidebarButtonProps {
isCollapsed?: boolean;
isActive?: boolean;
badge?: React.ReactNode;
- /** Overlay in the top-right corner of the collapsed icon (e.g. status badge) */
collapsedOverlay?: React.ReactNode;
- /** Custom icon node for collapsed mode — overrides the default
rendering */
collapsedIconNode?: React.ReactNode;
- /** Custom icon node for expanded mode — overrides the default rendering */
expandedIconNode?: React.ReactNode;
- /** Optional inline trailing content shown in expanded mode */
trailingContent?: React.ReactNode;
- /** Optional tooltip content that replaces the default label tooltip */
tooltipContent?: React.ReactNode;
className?: string;
- /** Extra attributes spread onto the inner (e.g. data-joyride) */
buttonProps?: React.ButtonHTMLAttributes;
}
diff --git a/surfsense_web/components/layout/ui/sidebar/SidebarUserProfile.tsx b/surfsense_web/components/layout/ui/sidebar/SidebarUserProfile.tsx
index 71966ae45..a8275829b 100644
--- a/surfsense_web/components/layout/ui/sidebar/SidebarUserProfile.tsx
+++ b/surfsense_web/components/layout/ui/sidebar/SidebarUserProfile.tsx
@@ -29,6 +29,7 @@ import {
DropdownMenuSubTrigger,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
+import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/spinner";
import { useLocaleContext } from "@/contexts/LocaleContext";
import { usePlatform } from "@/hooks/use-platform";
@@ -204,11 +205,12 @@ export function SidebarUserProfile({
-
{displayName}
-
+
@@ -367,10 +369,11 @@ export function SidebarUserProfile({
-
-
+
diff --git a/surfsense_web/components/layout/ui/tabs/TabBar.tsx b/surfsense_web/components/layout/ui/tabs/TabBar.tsx
index 6d170409f..3946fdc6d 100644
--- a/surfsense_web/components/layout/ui/tabs/TabBar.tsx
+++ b/surfsense_web/components/layout/ui/tabs/TabBar.tsx
@@ -10,6 +10,7 @@ import {
type Tab,
tabsAtom,
} from "@/atoms/tabs/tabs.atom";
+import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
interface TabBarProps {
@@ -189,22 +190,25 @@ export function TabBar({
)}
/>
) : null}
- handleTabClick(tab)}
- onMouseEnter={() => setHoveredTabIndex(index)}
- onMouseLeave={() => setHoveredTabIndex(null)}
- className={cn(
- "group relative flex h-full items-center px-3 w-[180px] min-h-0 overflow-hidden text-[13px] font-medium rounded-md transition-colors duration-150 shrink-0",
- isActive
- ? "bg-accent text-accent-foreground"
- : "bg-transparent text-muted-foreground hover:bg-accent hover:text-accent-foreground"
- )}
+ className="group relative h-full w-[180px] shrink-0"
>
-
- {tab.title}
-
+ handleTabClick(tab)}
+ onMouseEnter={() => setHoveredTabIndex(index)}
+ onMouseLeave={() => setHoveredTabIndex(null)}
+ className={cn(
+ "h-full w-full justify-start overflow-hidden px-3 text-left text-[13px] font-medium transition-colors duration-150",
+ isActive
+ ? "bg-accent text-accent-foreground"
+ : "bg-transparent text-muted-foreground hover:bg-accent hover:text-accent-foreground group-hover:bg-accent group-hover:text-accent-foreground group-focus-within:bg-accent group-focus-within:text-accent-foreground"
+ )}
+ >
+ {tab.title}
+
{/* Hover-only gradient + close overlay (sidebar pattern) — keeps pill width fixed and avoids ellipsis shift. */}
- {/* biome-ignore lint/a11y/useSemanticElements: cannot nest button inside button */}
- handleTabClose(e, tab.id)}
- onKeyDown={(e) => {
- if (e.key === "Enter" || e.key === " ") {
- e.preventDefault();
- handleTabClose(e as unknown as React.MouseEvent, tab.id);
- }
- }}
- className="pointer-events-auto rounded-full p-0.5 transition-colors hover:bg-accent hover:text-accent-foreground"
+ onMouseEnter={() => setHoveredTabIndex(index)}
+ onMouseLeave={() => setHoveredTabIndex(null)}
+ className="pointer-events-auto size-4 rounded-full p-0.5 hover:bg-accent hover:text-accent-foreground"
>
-
-
+
+
-
+
);
})}
@@ -243,14 +243,16 @@ export function TabBar({
"before:bg-gradient-to-r before:from-transparent before:to-panel"
)}
>
-
-
-
+
+
)}
diff --git a/surfsense_web/components/new-chat/chat-share-button.tsx b/surfsense_web/components/new-chat/chat-share-button.tsx
index 6e231707e..f8a9f55ff 100644
--- a/surfsense_web/components/new-chat/chat-share-button.tsx
+++ b/surfsense_web/components/new-chat/chat-share-button.tsx
@@ -143,18 +143,20 @@ export function ChatShareButton({ thread, onVisibilityChange, className }: ChatS
{hasPublicSnapshots && (