improve ux overflow with sidebar (#79)
This commit is contained in:
4
src/atoms/uiAtoms.ts
Normal file
4
src/atoms/uiAtoms.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import { atom } from "jotai";
|
||||||
|
|
||||||
|
// Atom to track if any dropdown is currently open in the UI
|
||||||
|
export const dropdownOpenAtom = atom<boolean>(false);
|
||||||
@@ -6,6 +6,7 @@ import { PlusCircle, MoreVertical, Trash2 } from "lucide-react";
|
|||||||
import { useAtom } from "jotai";
|
import { useAtom } from "jotai";
|
||||||
import { selectedChatIdAtom } from "@/atoms/chatAtoms";
|
import { selectedChatIdAtom } from "@/atoms/chatAtoms";
|
||||||
import { selectedAppIdAtom } from "@/atoms/appAtoms";
|
import { selectedAppIdAtom } from "@/atoms/appAtoms";
|
||||||
|
import { dropdownOpenAtom } from "@/atoms/uiAtoms";
|
||||||
import { IpcClient } from "@/ipc/ipc_client";
|
import { IpcClient } from "@/ipc/ipc_client";
|
||||||
import { showError, showSuccess } from "@/lib/toast";
|
import { showError, showSuccess } from "@/lib/toast";
|
||||||
import {
|
import {
|
||||||
@@ -28,6 +29,7 @@ export function ChatList({ show }: { show?: boolean }) {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [selectedChatId, setSelectedChatId] = useAtom(selectedChatIdAtom);
|
const [selectedChatId, setSelectedChatId] = useAtom(selectedChatIdAtom);
|
||||||
const [selectedAppId, setSelectedAppId] = useAtom(selectedAppIdAtom);
|
const [selectedAppId, setSelectedAppId] = useAtom(selectedAppIdAtom);
|
||||||
|
const [isDropdownOpen, setIsDropdownOpen] = useAtom(dropdownOpenAtom);
|
||||||
const { chats, loading, refreshChats } = useChats(selectedAppId);
|
const { chats, loading, refreshChats } = useChats(selectedAppId);
|
||||||
const routerState = useRouterState();
|
const routerState = useRouterState();
|
||||||
const isChatRoute = routerState.location.pathname === "/chat";
|
const isChatRoute = routerState.location.pathname === "/chat";
|
||||||
@@ -136,7 +138,7 @@ export function ChatList({ show }: { show?: boolean }) {
|
|||||||
<SidebarMenu className="space-y-1">
|
<SidebarMenu className="space-y-1">
|
||||||
{chats.map((chat) => (
|
{chats.map((chat) => (
|
||||||
<SidebarMenuItem key={chat.id} className="mb-1">
|
<SidebarMenuItem key={chat.id} className="mb-1">
|
||||||
<div className="flex w-[185px] items-center">
|
<div className="flex w-[175px] items-center">
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
@@ -161,7 +163,9 @@ export function ChatList({ show }: { show?: boolean }) {
|
|||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
{selectedChatId === chat.id && (
|
{selectedChatId === chat.id && (
|
||||||
<DropdownMenu>
|
<DropdownMenu
|
||||||
|
onOpenChange={(open) => setIsDropdownOpen(open)}
|
||||||
|
>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import { Home, Inbox, Settings, HelpCircle } from "lucide-react";
|
|||||||
import { Link, useRouterState } from "@tanstack/react-router";
|
import { Link, useRouterState } from "@tanstack/react-router";
|
||||||
import { useSidebar } from "@/components/ui/sidebar"; // import useSidebar hook
|
import { useSidebar } from "@/components/ui/sidebar"; // import useSidebar hook
|
||||||
import { useEffect, useState, useRef } from "react";
|
import { useEffect, useState, useRef } from "react";
|
||||||
|
import { useAtom } from "jotai";
|
||||||
|
import { dropdownOpenAtom } from "@/atoms/uiAtoms";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Sidebar,
|
Sidebar,
|
||||||
@@ -50,6 +52,7 @@ export function AppSidebar() {
|
|||||||
const [hoverState, setHoverState] = useState<HoverState>("no-hover");
|
const [hoverState, setHoverState] = useState<HoverState>("no-hover");
|
||||||
const expandedByHover = useRef(false);
|
const expandedByHover = useRef(false);
|
||||||
const [isHelpDialogOpen, setIsHelpDialogOpen] = useState(false); // State for dialog
|
const [isHelpDialogOpen, setIsHelpDialogOpen] = useState(false); // State for dialog
|
||||||
|
const [isDropdownOpen] = useAtom(dropdownOpenAtom);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
@@ -62,13 +65,14 @@ export function AppSidebar() {
|
|||||||
if (
|
if (
|
||||||
hoverState === "clear-hover" &&
|
hoverState === "clear-hover" &&
|
||||||
state === "expanded" &&
|
state === "expanded" &&
|
||||||
expandedByHover.current
|
expandedByHover.current &&
|
||||||
|
!isDropdownOpen
|
||||||
) {
|
) {
|
||||||
toggleSidebar();
|
toggleSidebar();
|
||||||
expandedByHover.current = false;
|
expandedByHover.current = false;
|
||||||
setHoverState("no-hover");
|
setHoverState("no-hover");
|
||||||
}
|
}
|
||||||
}, [hoverState, toggleSidebar, state, setHoverState]);
|
}, [hoverState, toggleSidebar, state, setHoverState, isDropdownOpen]);
|
||||||
|
|
||||||
const routerState = useRouterState();
|
const routerState = useRouterState();
|
||||||
const isAppRoute =
|
const isAppRoute =
|
||||||
@@ -93,7 +97,9 @@ export function AppSidebar() {
|
|||||||
<Sidebar
|
<Sidebar
|
||||||
collapsible="icon"
|
collapsible="icon"
|
||||||
onMouseLeave={() => {
|
onMouseLeave={() => {
|
||||||
setHoverState("clear-hover");
|
if (!isDropdownOpen) {
|
||||||
|
setHoverState("clear-hover");
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SidebarContent className="overflow-hidden">
|
<SidebarContent className="overflow-hidden">
|
||||||
|
|||||||
Reference in New Issue
Block a user