From 4c34b978ce6560eb569f7f82838651e62b1ac9c1 Mon Sep 17 00:00:00 2001
From: Pinapelz <yukais@pinapelz.com>
Date: Mon, 19 May 2025 17:13:11 -0700
Subject: frontend: adjust mobile dropdown menu position styling

---
 site/src/components/TitleBar.tsx | 69 ++++++++++++++++++++++++++++++++++------
 1 file changed, 60 insertions(+), 9 deletions(-)

(limited to 'site/src/components/TitleBar.tsx')

diff --git a/site/src/components/TitleBar.tsx b/site/src/components/TitleBar.tsx
index 8016a77..651b402 100644
--- a/site/src/components/TitleBar.tsx
+++ b/site/src/components/TitleBar.tsx
@@ -15,11 +15,16 @@ const TitleBar: React.FC = () => {
   const [otherDropdownOpen, setOtherDropdownOpen] = useState(false);
   const dropdownRef = useRef<HTMLDivElement>(null);
   const otherDropdownRef = useRef<HTMLDivElement>(null);
+  const rhythmGamesBtnRef = useRef<HTMLButtonElement>(null);
+  const otherGamesBtnRef = useRef<HTMLButtonElement>(null);
   const [searchParams] = useSearchParams();
   const navigate = useNavigate();
   const location = useLocation();
   const isMoe = searchParams.has("moe");
 
+  const [rhythmDropdownStyle, setRhythmDropdownStyle] = useState<React.CSSProperties>({});
+  const [otherDropdownStyle, setOtherDropdownStyle] = useState<React.CSSProperties>({});
+
   const toggleTheme = () => {
     const params = new URLSearchParams(searchParams);
 
@@ -106,6 +111,48 @@ const TitleBar: React.FC = () => {
     },
   ];
 
+  const calculateDropdownPosition = (buttonRef: React.RefObject<HTMLElement>) => {
+    if (!buttonRef.current) return {};
+
+    const rect = buttonRef.current.getBoundingClientRect();
+    const dropdownWidth = 320; // sm:w-80 equivalent in px
+    const spaceOnRight = window.innerWidth - rect.right;
+    if (spaceOnRight < dropdownWidth) {
+      return { right: 'auto', left: '0' };
+    }
+    return { right: '0', left: 'auto' };
+  };
+  const toggleRhythmDropdown = () => {
+    const newState = !dropdownOpen;
+    if (newState) {
+      setRhythmDropdownStyle(calculateDropdownPosition(rhythmGamesBtnRef));
+    }
+    setDropdownOpen(newState);
+  };
+
+  const toggleOtherDropdown = () => {
+    const newState = !otherDropdownOpen;
+    if (newState) {
+      setOtherDropdownStyle(calculateDropdownPosition(otherGamesBtnRef));
+    }
+    setOtherDropdownOpen(newState);
+  };
+
+  // Handle window resize
+  useEffect(() => {
+    const handleResize = () => {
+      if (dropdownOpen) {
+        setRhythmDropdownStyle(calculateDropdownPosition(rhythmGamesBtnRef));
+      }
+      if (otherDropdownOpen) {
+        setOtherDropdownStyle(calculateDropdownPosition(otherGamesBtnRef));
+      }
+    };
+
+    window.addEventListener('resize', handleResize);
+    return () => window.removeEventListener('resize', handleResize);
+  }, [dropdownOpen, otherDropdownOpen]);
+
   useEffect(() => {
     const handleClickOutside = (event: MouseEvent) => {
       if (
@@ -158,18 +205,19 @@ const TitleBar: React.FC = () => {
             </Link>
           </div>
 
-          <div className="flex items-center space-x-4">
+          <div className="flex items-center space-x-2 sm:space-x-4">
             <Link
               to={`/${isMoe ? "?moe" : ""}`}
-              className={`${isMoe ? "text-pink-800 hover:text-pink-600" : "text-gray-300 hover:text-white"} font-medium`}
+              className={`${isMoe ? "text-pink-800 hover:text-pink-600" : "text-gray-300 hover:text-white"} font-medium text-sm sm:text-base`}
             >
               All Games
             </Link>
 
             <div className="relative" ref={dropdownRef}>
               <button
-                className={`${isMoe ? "text-pink-800 hover:text-pink-600" : "text-gray-300 hover:text-white"} font-medium flex items-center`}
-                onClick={() => setDropdownOpen(!dropdownOpen)}
+                ref={rhythmGamesBtnRef}
+                className={`${isMoe ? "text-pink-800 hover:text-pink-600" : "text-gray-300 hover:text-white"} font-medium flex items-center text-sm sm:text-base`}
+                onClick={toggleRhythmDropdown}
               >
                 Rhythm Games
                 <svg
@@ -189,7 +237,8 @@ const TitleBar: React.FC = () => {
 
               {dropdownOpen && (
                 <div
-                  className={`absolute mt-2 w-64 sm:w-80 ${isMoe ? "bg-pink-100 border-pink-300" : "bg-gray-800 border-gray-700"} border rounded-md shadow-lg z-10 right-0`}
+                  className={`absolute mt-2 w-64 sm:w-80 ${isMoe ? "bg-pink-100 border-pink-300" : "bg-gray-800 border-gray-700"} border rounded-md shadow-lg z-10`}
+                  style={rhythmDropdownStyle}
                 >
                   <div className="py-1 max-h-[70vh] overflow-y-auto scroll-py-2">
                     {gameCategories.map((category, index) => (
@@ -222,8 +271,9 @@ const TitleBar: React.FC = () => {
 
             <div className="relative" ref={otherDropdownRef}>
               <button
-                className={`${isMoe ? "text-pink-800 hover:text-pink-600" : "text-gray-300 hover:text-white"} font-medium flex items-center`}
-                onClick={() => setOtherDropdownOpen(!otherDropdownOpen)}
+                ref={otherGamesBtnRef}
+                className={`${isMoe ? "text-pink-800 hover:text-pink-600" : "text-gray-300 hover:text-white"} font-medium flex items-center text-sm sm:text-base`}
+                onClick={toggleOtherDropdown}
               >
                 Other Games
                 <svg
@@ -243,7 +293,8 @@ const TitleBar: React.FC = () => {
 
               {otherDropdownOpen && (
                 <div
-                  className={`absolute mt-2 w-64 sm:w-80 ${isMoe ? "bg-pink-100 border-pink-300" : "bg-gray-800 border-gray-700"} border rounded-md shadow-lg z-10 right-0`}
+                  className={`absolute mt-2 w-64 sm:w-80 ${isMoe ? "bg-pink-100 border-pink-300" : "bg-gray-800 border-gray-700"} border rounded-md shadow-lg z-10`}
+                  style={otherDropdownStyle}
                 >
                   <div className="py-1 max-h-[70vh] overflow-y-auto scroll-py-2">
                     {otherGames.map((category, index) => (
@@ -280,4 +331,4 @@ const TitleBar: React.FC = () => {
   );
 };
 
-export default TitleBar;
+export default TitleBar
-- 
cgit v1.2.3

