BottomNavBar.tsx (4065B)
1 import React, { useState, useEffect } from 'react'; 2 import { Timer, Heart } from 'lucide-react'; 3 4 type Tab = 'timer' | 'history' | 'bond'; 5 6 interface BottomNavBarProps { 7 activeTab: Tab; 8 setActiveTab: (tab: Tab) => void; 9 } 10 11 const BottomNavBar: React.FC<BottomNavBarProps> = ({ activeTab, setActiveTab }) => { 12 const [isDesktop, setIsDesktop] = useState(false); 13 14 useEffect(() => { 15 const handleResize = () => { 16 setIsDesktop(window.innerWidth >= 1000); 17 }; 18 handleResize(); 19 window.addEventListener('resize', handleResize); 20 return () => window.removeEventListener('resize', handleResize); 21 }, []); 22 23 return ( 24 <div className="fixed bottom-0 left-0 right-0 z-40 flex border-t border-muted/10 bg-background"> 25 {isDesktop ? ( 26 /* ========================================== 27 PC用レイアウト: 2タブ構成 28 ========================================== */ 29 <> 30 <button 31 onClick={() => setActiveTab('timer')} 32 className={`btn-nav relative flex flex-col items-center justify-center ${ 33 activeTab === 'timer' || activeTab === 'history' ? 'active' : '' 34 }`} 35 > 36 <div className="relative flex flex-col items-center"> 37 <Timer size={30} /> 38 <div className={`btn-nav-bar absolute rounded-full ${ 39 activeTab === 'timer' || activeTab === 'history' ? 'active' : '' 40 }`}/> 41 </div> 42 </button> 43 44 <button 45 onClick={() => setActiveTab('bond')} 46 className={`btn-nav relative flex flex-col items-center justify-center ${ 47 activeTab === 'bond' ? 'active' : '' 48 }`} 49 > 50 <div className="relative flex flex-col items-center"> 51 <Heart size={30} /> 52 <div className={`btn-nav-bar absolute rounded-full ${ 53 activeTab === 'bond' ? 'active' : '' 54 }`}/> 55 </div> 56 </button> 57 </> 58 ) : ( 59 /* ========================================== 60 スマホ用レイアウト: 3タブ構成 61 ========================================== */ 62 <> 63 <button 64 onClick={() => setActiveTab('timer')} 65 className={`btn-nav relative flex flex-col items-center justify-center ${activeTab === 'timer' ? 'active' : ''}`} 66 > 67 <div className="relative flex flex-col items-center"> 68 <Timer size={30} /> 69 <div className={`btn-nav-bar absolute rounded-full ${activeTab === 'timer' ? 'active' : ''}`}/> 70 </div> 71 </button> 72 73 <button 74 onClick={() => setActiveTab('history')} 75 className={`btn-nav relative flex flex-col items-center justify-center ${activeTab === 'history' ? 'active' : ''}`} 76 > 77 <div className="relative flex flex-col items-center"> 78 <svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"> 79 <rect width="18" height="18" x="3" y="4" rx="2" ry="2"/> 80 <line x1="16" x2="16" y1="2" y2="6"/> 81 <line x1="8" x2="8" y1="2" y2="6"/> 82 <line x1="3" x2="21" y1="10" y2="10"/> 83 </svg> 84 <div className={`btn-nav-bar absolute rounded-full ${activeTab === 'history' ? 'active' : ''}`}/> 85 </div> 86 </button> 87 88 <button 89 onClick={() => setActiveTab('bond')} 90 className={`btn-nav relative flex flex-col items-center justify-center ${activeTab === 'bond' ? 'active' : ''}`} 91 > 92 <div className="relative flex flex-col items-center"> 93 <Heart size={30} /> 94 <div className={`btn-nav-bar absolute rounded-full ${activeTab === 'bond' ? 'active' : ''}`}/> 95 </div> 96 </button> 97 </> 98 )} 99 </div> 100 ); 101 }; 102 103 export default BottomNavBar;