style: sidebar ui improvement (#1816)

* style: sidebar ui improvement

* style: sidebar menu spacing

* style: sidebar consistent spacing

* style: notification improvement

* style: remove from favorite filled icon added

* chore: settings option added in sidebar context menu

* chore: update delete project option visibility for sidebar

* style: sidebar project list display border top on scroll
This commit is contained in:
Anmol Singh Bhatia 2023-08-11 15:53:10 +05:30 committed by GitHub
parent 5c964d144a
commit dbb53a663e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 166 additions and 84 deletions

View file

@ -1,4 +1,4 @@
import React, { useState, FC } from "react";
import React, { useState, FC, useRef, useEffect } from "react";
import { useRouter } from "next/router";
import { mutate } from "swr";
@ -6,7 +6,7 @@ import { mutate } from "swr";
// react-beautiful-dnd
import { DragDropContext, Draggable, DropResult, Droppable } from "react-beautiful-dnd";
// headless ui
import { Disclosure } from "@headlessui/react";
import { Disclosure, Transition } from "@headlessui/react";
// hooks
import useToast from "hooks/use-toast";
import useTheme from "hooks/use-theme";
@ -36,6 +36,10 @@ export const ProjectSidebarList: FC = () => {
const [projectToDelete, setProjectToDelete] = useState<IProject | null>(null);
// router
const [isScrolled, setIsScrolled] = useState(false);
const containerRef = useRef<HTMLDivElement | null>(null);
const router = useRouter();
const { workspaceSlug, projectId } = router.query;
@ -126,6 +130,27 @@ export const ProjectSidebarList: FC = () => {
});
};
const handleScroll = () => {
if (containerRef.current) {
const scrollTop = containerRef.current.scrollTop;
setIsScrolled(scrollTop > 0);
}
};
useEffect(() => {
const currentContainerRef = containerRef.current;
if (currentContainerRef) {
currentContainerRef.addEventListener("scroll", handleScroll);
}
return () => {
if (currentContainerRef) {
currentContainerRef.removeEventListener("scroll", handleScroll);
}
};
}, []);
return (
<>
<DeleteProjectModal
@ -134,7 +159,12 @@ export const ProjectSidebarList: FC = () => {
data={projectToDelete}
user={user}
/>
<div className="h-full overflow-y-auto px-4 space-y-3 pt-3 border-t border-custom-sidebar-border-300">
<div
ref={containerRef}
className={`h-full overflow-y-auto px-4 space-y-3 pt-3 ${
isScrolled ? "border-t border-custom-sidebar-border-300" : ""
}`}
>
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId="favorite-projects">
{(provided) => (
@ -147,7 +177,7 @@ export const ProjectSidebarList: FC = () => {
<Disclosure.Button
as="button"
type="button"
className="group flex items-center gap-1 px-1.5 text-xs font-semibold text-custom-sidebar-text-200 text-left hover:bg-custom-sidebar-background-80 rounded w-min whitespace-nowrap"
className="group flex items-center gap-1 px-1.5 text-xs font-semibold text-custom-sidebar-text-400 text-left hover:bg-custom-sidebar-background-80 rounded w-full whitespace-nowrap"
>
Favorites
<Icon
@ -199,37 +229,57 @@ export const ProjectSidebarList: FC = () => {
{({ open }) => (
<>
{!store?.theme?.sidebarCollapsed && (
<Disclosure.Button
as="button"
type="button"
className="group flex items-center gap-1 px-1.5 text-xs font-semibold text-custom-sidebar-text-200 text-left hover:bg-custom-sidebar-background-80 rounded w-min whitespace-nowrap"
>
Projects
<Icon
iconName={open ? "arrow_drop_down" : "arrow_right"}
className="group-hover:opacity-100 opacity-0 !text-lg"
/>
</Disclosure.Button>
<div className="group flex justify-between items-center text-xs px-1.5 rounded text-custom-sidebar-text-400 hover:bg-custom-sidebar-background-80 w-full">
<Disclosure.Button
as="button"
type="button"
className="flex items-center gap-1 font-semibold text-left whitespace-nowrap"
>
Projects
<Icon
iconName={open ? "arrow_drop_down" : "arrow_right"}
className="group-hover:opacity-100 opacity-0 !text-lg"
/>
</Disclosure.Button>
<button
className="group-hover:opacity-100 opacity-0"
onClick={() => {
const e = new KeyboardEvent("keydown", { key: "p" });
document.dispatchEvent(e);
}}
>
<Icon iconName="add" />
</button>
</div>
)}
<Disclosure.Panel as="div" className="space-y-2">
{orderedJoinedProjects.map((project, index) => (
<Draggable key={project.id} draggableId={project.id} index={index}>
{(provided, snapshot) => (
<div ref={provided.innerRef} {...provided.draggableProps}>
<SingleSidebarProject
key={project.id}
project={project}
sidebarCollapse={store?.theme?.sidebarCollapsed}
provided={provided}
snapshot={snapshot}
handleDeleteProject={() => handleDeleteProject(project)}
handleCopyText={() => handleCopyText(project.id)}
/>
</div>
)}
</Draggable>
))}
</Disclosure.Panel>
<Transition
enter="transition duration-100 ease-out"
enterFrom="transform scale-95 opacity-0"
enterTo="transform scale-100 opacity-100"
leave="transition duration-75 ease-out"
leaveFrom="transform scale-100 opacity-100"
leaveTo="transform scale-95 opacity-0"
>
<Disclosure.Panel as="div" className="space-y-2">
{orderedJoinedProjects.map((project, index) => (
<Draggable key={project.id} draggableId={project.id} index={index}>
{(provided, snapshot) => (
<div ref={provided.innerRef} {...provided.draggableProps}>
<SingleSidebarProject
key={project.id}
project={project}
sidebarCollapse={store?.theme?.sidebarCollapsed}
provided={provided}
snapshot={snapshot}
handleDeleteProject={() => handleDeleteProject(project)}
handleCopyText={() => handleCopyText(project.id)}
/>
</div>
)}
</Draggable>
))}
</Disclosure.Panel>
</Transition>
{provided.placeholder}
</>
)}
@ -239,43 +289,7 @@ export const ProjectSidebarList: FC = () => {
)}
</Droppable>
</DragDropContext>
{otherProjects && otherProjects.length > 0 && (
<Disclosure
as="div"
className="flex flex-col space-y-2"
defaultOpen={projectId && otherProjects.find((p) => p.id === projectId) ? true : false}
>
{({ open }) => (
<>
{!store?.theme?.sidebarCollapsed && (
<Disclosure.Button
as="button"
type="button"
className="group flex items-center gap-1 px-1.5 text-xs font-semibold text-custom-sidebar-text-200 text-left hover:bg-custom-sidebar-background-80 rounded w-min whitespace-nowrap"
>
Other Projects
<Icon
iconName={open ? "arrow_drop_down" : "arrow_right"}
className="group-hover:opacity-100 opacity-0 !text-lg"
/>
</Disclosure.Button>
)}
<Disclosure.Panel as="div" className="space-y-2">
{otherProjects?.map((project, index) => (
<SingleSidebarProject
key={project.id}
project={project}
sidebarCollapse={store?.theme?.sidebarCollapsed}
handleDeleteProject={() => handleDeleteProject(project)}
handleCopyText={() => handleCopyText(project.id)}
shortContextMenu
/>
))}
</Disclosure.Panel>
</>
)}
</Disclosure>
)}
{allProjects && allProjects.length === 0 && (
<button
type="button"