Skip to content

Commit

Permalink
Merge pull request #3 from UofA-Blueprint/ASC-67-feature/implement-so…
Browse files Browse the repository at this point in the history
…rt-dropdown-list

Implement sort dropdown list
  • Loading branch information
TienDucHo authored Feb 10, 2024
2 parents f1e9d93 + 0be9b40 commit b6bc532
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 4 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.21.4",
"@types/jest": "^29.5.0",
"@types/react": "^18.0.27",
"@types/react": "^18.2.51",
"@types/react-dom": "^18.0.10",
"@types/react-test-renderer": "^18.0.0",
"@vitejs/plugin-react": "^3.1.0",
Expand Down
11 changes: 8 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import {
createBrowserRouter,
RouterProvider,
} from "react-router-dom";

// routes
import Test from "./routes/Test";
import DropdownItem from "./components/DropdownItem";
import SortDropdownListTestRoute from "./routes/SortDropdownListTestRoute";
import NavigaionTest from "./routes/NavigationTest";
import Test from "@/routes/Test";

const router = createBrowserRouter([
{
Expand All @@ -16,10 +16,15 @@ const router = createBrowserRouter([
path: "/test",
element: <Test />,
},
{
path: "/SortDropdownListTestRoute",
element: <SortDropdownListTestRoute />,
},
{
path: "/nav-test",
element: <NavigaionTest />,
},

]);

function App() {
Expand Down
18 changes: 18 additions & 0 deletions src/components/DropdownItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// As shown in TestSquareProps
export interface DropdownItemProps {
text: string;
isSelected: boolean;
onSelect: () => void;
}

function DropdownItem({ text, isSelected, onSelect }:DropdownItemProps) {
return (
<li
className={`py-1 pr-4 pl-2 rounded-lg h-8 hover:bg-neutrals-light-500 cursor-pointer ${isSelected ? 'font-bold' : 'font-normal'}`} onClick={onSelect}>

<a className=" text-neutrals-dark-500 font-display">{text}</a>
</li>
);
}

export default DropdownItem;
82 changes: 82 additions & 0 deletions src/components/SortDropdownList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { useEffect, useRef, useState } from "react";
import DropdownItem from "./DropdownItem";
import { CaretDown } from "@phosphor-icons/react";

function SortDropdownList() {
// Options that can be later add in
const items = [
"Newest to Oldest",
"Oldest to Newest",
"Most-Least Storage",
"Recently Updated",
];

// State to keep track of the currently selected option
const [selectedItem, setSelectedItem] = useState<string | null>(
null
); // useState expect either string or null var

// State to keep track of the menu is being open or not
const [open, setOpen] = useState(false);

// Check if user click outside of the menu to close it
let menuRef = useRef<HTMLInputElement>(null); // Typescript like this

useEffect(() => {
let handler = (e: any) => {
if (menuRef.current && !menuRef.current.contains(e.target)) {
// Check menuRef.current is not null before calling .contains
setOpen(false);
}
};

document.addEventListener("mousedown", handler);

return () => {
// Clean up to prevent memory leaks and avoid running outdated event handlers
document.removeEventListener("mousedown", handler);
};
}, []);

return (
<div className="relative w-full" ref={menuRef}>
{/* For the menu trigger */}
<div
className={`w-full cursor-pointer font-body h-10 bg-status-blue-light flex justify-between items-center px-4 py-2 ${
open ? "rounded-t-lg mb-2" : "rounded-lg"
} `}
onClick={() => setOpen(!open)}
>
Sort
{/* The arrow symbol */}
<CaretDown size={24} />
</div>

{/* For the dropdown options */}
<div
className={`bg-status-blue-light p-4 rounded-b-lg z-10 absolute w-full ${
open ? "visible opacity-1" : "invisible opacity-0"
}`}
>
<div className={`flex flex-col gap-2`}>
<ul>
{items.map((item, index) => (
<DropdownItem
key={index}
text={item}
isSelected={selectedItem === item} // Check if matched with the selected option
onSelect={() => setSelectedItem(item)} // set the selectedItem to that option and when it re-render it will be check by the line above
/>
))}
</ul>
{/* for fun */}
<button className="text-white border bg-primary-main">
Reset
</button>
</div>
</div>
</div>
);
}

export default SortDropdownList;
19 changes: 19 additions & 0 deletions src/routes/SortDropdownListTestRoute.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import DropdownItem from "../components/DropdownItem";
import SortDropdownList from "../components/SortDropdownList";

function SortDropdownListTestRoute() {
return (
<div className="flex flex-col items-center justify-center min-h-screen">
<div className="text-h2">Hello</div>
<div className="text-body-reg">
Is this the sort dropdown list that you looking for?😩
</div>
<div className="w-1/4">
<SortDropdownList />
</div>
<div>What happen If I do this?</div>
</div>
);
}

export default SortDropdownListTestRoute;

0 comments on commit b6bc532

Please sign in to comment.