Skip to content

Commit

Permalink
Merge pull request #68 from Saifullah-dev/65-breadcrumb-handle-overflow
Browse files Browse the repository at this point in the history
65 breadcrumb handle overflow
  • Loading branch information
Saifullah-dev authored Sep 14, 2024
2 parents d9185cb + c522dd3 commit bc2d68a
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 56 deletions.
132 changes: 106 additions & 26 deletions frontend/src/FileManager/BreadCrumb/BreadCrumb.jsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,121 @@
import { useEffect, useState } from "react";
import { MdHome, MdOutlineNavigateNext } from "react-icons/md";
import "./BreadCrumb.scss";
import { useEffect, useRef, useState } from "react";
import { MdHome, MdMoreHoriz, MdOutlineNavigateNext } from "react-icons/md";
import { useFileNavigation } from "../../contexts/FileNavigationContext";
import { useDetectOutsideClick } from "../../hooks/useDetectOutsideClick";
import "./BreadCrumb.scss";

const BreadCrumb = () => {
const [folders, setFolders] = useState([]);
const [hiddenFolders, setHiddenFolders] = useState([]);
const [hiddenFoldersWidth, setHiddenFoldersWidth] = useState([]);
const [showHiddenFolders, setShowHiddenFolders] = useState(false);

const { currentPath, setCurrentPath } = useFileNavigation();
const breadCrumbRef = useRef(null);
const foldersRef = useRef([]);
const moreBtnRef = useRef(null);
const popoverRef = useDetectOutsideClick(() => {
setShowHiddenFolders(false);
});

useEffect(() => {
setFolders(currentPath?.split("/"));
setFolders(() => {
let path = "";
return currentPath?.split("/").map((item) => {
return {
name: item || "Home",
path: item === "" ? item : (path += `/${item}`),
};
});
});
setHiddenFolders([]);
setHiddenFoldersWidth([]);
}, [currentPath]);

const switchPath = (index) => {
if (index < folders.length - 1) {
setCurrentPath(() => {
const toSlice = folders.length - (index + 1);
const switchFolders = folders.slice(0, -toSlice);
return switchFolders.join("/");
});
}
const switchPath = (path) => {
setCurrentPath(path);
};

const getBreadCrumbWidth = () => {
const containerWidth = breadCrumbRef.current.clientWidth;
const containerStyles = getComputedStyle(breadCrumbRef.current);
const paddingLeft = parseFloat(containerStyles.paddingLeft);
const moreBtnGap = hiddenFolders.length > 0 ? 1 : 0;
const flexGap = parseFloat(containerStyles.gap) * (folders.length + moreBtnGap);
return containerWidth - (paddingLeft + flexGap);
};

const checkAvailableSpace = () => {
const availableSpace = getBreadCrumbWidth();
const remainingFoldersWidth = foldersRef.current.reduce((prev, curr) => {
if (!curr) return prev;
return prev + curr.clientWidth;
}, 0);
const moreBtnWidth = moreBtnRef.current?.clientWidth || 0;
return availableSpace - (remainingFoldersWidth + moreBtnWidth);
};

const isBreadCrumbOverflowing = () => {
return breadCrumbRef.current.scrollWidth > breadCrumbRef.current.clientWidth;
};

useEffect(() => {
if (isBreadCrumbOverflowing()) {
const hiddenFolder = folders[1];
const hiddenFolderWidth = foldersRef.current[1]?.clientWidth;
setHiddenFoldersWidth((prev) => [...prev, hiddenFolderWidth]);
setHiddenFolders((prev) => [...prev, hiddenFolder]);
setFolders((prev) => prev.filter((_, index) => index !== 1));
} else if (hiddenFolders.length > 0 && checkAvailableSpace() > hiddenFoldersWidth.at(-1)) {
const newFolders = [folders[0], hiddenFolders.at(-1), ...folders.slice(1)];
setFolders(newFolders);
setHiddenFolders((prev) => prev.slice(0, -1));
setHiddenFoldersWidth((prev) => prev.slice(0, -1));
}
}, [isBreadCrumbOverflowing]);

return (
<div className="breadcrumb">
{folders.map((folder, index) => (
<span key={index} className="folder-name" onClick={() => switchPath(index)}>
{index === 0 ? (
<>
<MdHome /> Home
</>
) : (
<>
<MdOutlineNavigateNext /> {folder}
</>
)}
</span>
))}
<div className="bread-crumb-container">
<div className="breadcrumb" ref={breadCrumbRef}>
{folders.map((folder, index) => (
<div key={index} style={{ display: "contents" }}>
<span
className="folder-name"
onClick={() => switchPath(folder.path)}
ref={(el) => (foldersRef.current[index] = el)}
>
{index === 0 ? <MdHome /> : <MdOutlineNavigateNext />}
{folder.name}
</span>
{hiddenFolders?.length > 0 && index === 0 && (
<button
className="folder-name folder-name-btn"
onClick={() => setShowHiddenFolders(true)}
ref={moreBtnRef}
title="Show more folders"
>
<MdMoreHoriz size={22} className="hidden-folders" />
</button>
)}
</div>
))}
</div>

{showHiddenFolders && (
<ul ref={popoverRef.ref} className="hidden-folders-container">
{hiddenFolders.map((folder, index) => (
<li
key={index}
onClick={() => {
switchPath(folder.path);
setShowHiddenFolders(false);
}}
>
{folder.name}
</li>
))}
</ul>
)}
</div>
);
};
Expand Down
85 changes: 73 additions & 12 deletions frontend/src/FileManager/BreadCrumb/BreadCrumb.scss
Original file line number Diff line number Diff line change
@@ -1,18 +1,79 @@
@import "../../styles/variables";

.breadcrumb {
height: calc(5.8% - 21px);
display: flex;
gap: 0.5rem;
border-bottom: 1px solid #dddddd;
padding: 10px 15px;
overflow-x: scroll;
.bread-crumb-container {
position: relative;

&::-webkit-scrollbar {
height: 3px;
}
.breadcrumb {
height: calc(5.8% - 21px);
display: flex;
gap: 0.5rem;
border-bottom: 1px solid #dddddd;
padding: 10px 0 10PX 15px;
overflow-x: hidden;

&::-webkit-scrollbar {
height: 3px;
}

&::-webkit-scrollbar-thumb {
background: $primary-color !important;
}

.folder-name {
display: flex;
align-items: center;
gap: 0.25rem;
font-weight: 500;
min-width: fit-content;

&:hover {
cursor: pointer;
color: $secondary-color;
}
}

.hidden-folders {
padding: 0 4px;
}

.folder-name-btn {
background-color: transparent;
border: none;
padding: 0;

&:hover,
&:focus {
cursor: pointer;
color: $primary-color;
background-color: #dddcdc;
border-radius: 5px;
}
}

&::-webkit-scrollbar-thumb {
background: $primary-color !important;
}
}

.hidden-folders-container {
position: absolute;
margin: 0;
z-index: 2;
background-color: rgb(99, 99, 99);
color: white;
padding: 4px;
border-radius: 5px;
font-size: .9em;
left: 3rem;
display: flex;
flex-direction: column;
gap: 5px;

li {
padding: 5px 10px;
border-radius: 4px;

&:hover {
cursor: pointer;
background-color: rgb(117, 117, 117);
}
}
}
2 changes: 1 addition & 1 deletion frontend/src/FileManager/FileList/FileItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ const FileItem = ({
const handleFileAccess = () => {
setVisible(false);
if (file.isDirectory) {
setCurrentPath((prev) => prev + "/" + file.name);
setCurrentPath(file.path);
setSelectedFileIndex(null);
setSelectedFile(null);
} else {
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/FileManager/FileManager.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ const FileManager = ({
);
};

FileManager.displayName = "FileManager";

FileManager.propTypes = {
files: PropTypes.arrayOf(
PropTypes.shape({
Expand Down
13 changes: 0 additions & 13 deletions frontend/src/FileManager/FileManager.scss
Original file line number Diff line number Diff line change
Expand Up @@ -89,19 +89,6 @@ svg {
padding-left: 0px;
border-bottom-right-radius: 8px;
}

.folder-name {
display: flex;
align-items: center;
gap: 0.25rem;
font-weight: 500;
min-width: fit-content;

&:hover {
cursor: pointer;
color: $secondary-color;
}
}
}
}

Expand Down
10 changes: 6 additions & 4 deletions frontend/src/FileManager/Toolbar/Toolbar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
display: flex;
justify-content: space-between;

> div {
>div {
display: flex;
}

Expand Down Expand Up @@ -39,7 +39,7 @@
display: flex;
justify-content: space-between;

> div {
>div {
display: flex;
position: relative;
}
Expand All @@ -57,6 +57,7 @@
margin: 0;
border: 1px solid #c4c4c4;
border-radius: 5px;

ul {
list-style: none;
padding-left: 0;
Expand Down Expand Up @@ -113,10 +114,11 @@
}

.icon-only {
padding: 8px !important;
padding: 0 8px !important;

&:focus {
background-color: rgb(0 0 0 / 12%);
border-radius: 3px;
}
}

Expand All @@ -126,4 +128,4 @@
width: 1px;
margin: 0 5px;
}
}
}

0 comments on commit bc2d68a

Please sign in to comment.