AI 詠唱出來的第一版 UI, 如果是只有使用 desktop device only, 是沒問題, 只使用 hover 處理 switch 的功能在 desktop 上更實用, 但hover 在 mobile device 無法使用.
Changes:
- State-based Toggle: Replaced the CSS-only group-hover behavior with a React useState toggle. This ensures the dropdown opens and closes reliably on touch screens where hover states are inconsistent.
- Click-Away Support: Added a transparent backdrop that automatically closes the language menu when you click or tap anywhere else on the screen.
- Improved Mobile UX: The dropdown now responds immediately to taps, providing a much smoother experience for mobile users.
異動的程式碼:
const Header = ({ onHome, onSettings, onManagement, language, onLanguageChange, currentView }: {
onHome: () => void;
onSettings: () => void;
onManagement: () => void;
language: 'zh' | 'en';
onLanguageChange: (lang: 'zh' | 'en') => void;
currentView: View;
}) => {
const t = translations[language];
const [isLangOpen, setIsLangOpen] = useState(false);
說明: 增加 useState(false) 在 Header
- <div className="relative group">
- <button className="flex items-center space-x-1 hover:text-slate-900 transition-colors py-2">
+ <div className="relative">
+ <button
+ onClick={() => setIsLangOpen(!isLangOpen)}
+ className="flex items-center space-x-1 hover:text-slate-900 transition-colors py-2"
+ >
說明: button 增加 onClick={() => setIsLangOpen(!isLangOpen)} 的 event.
- <div className="absolute right-0 top-full mt-1 w-32 bg-white border border-slate-200 rounded-lg shadow-lg
opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all z-50">
- <button
- onClick={() => onLanguageChange('zh')}
- className={`w-full text-left px-4 py-2 text-sm hover:bg-slate-50 first:rounded-t-lg ${language === 'zh' ? 'text-slate-900 font-bold' : 'text-slate-600'}`}
- >
- {t.zh}
- </button>
- <button
- onClick={() => onLanguageChange('en')}
- className={`w-full text-left px-4 py-2 text-sm hover:bg-slate-50 last:rounded-b-lg ${language === 'en' ? 'text-slate-900 font-bold' : 'text-slate-600'}`}
- >
- {t.en}
- </button>
- </div>
+ {isLangOpen && (
+ <>
+ <div
+ className="fixed inset-0 z-40"
+ onClick={() => setIsLangOpen(false)}
+ />
+ <div className="absolute right-0 top-full mt-1 w-32 bg-white border border-slate-200 rounded-lg shadow-lg z-50 overflow-hidden">
+ <button
+ onClick={() => {
+ onLanguageChange('zh');
+ setIsLangOpen(false);
+ }}
+ />
+ <div className="absolute right-0 top-full mt-1 w-32 bg-white border border-slate-200 rounded-lg shadow-lg z-50 overflow-hidden">
+ <button
+ onClick={() => {
+ onLanguageChange('zh');
+ setIsLangOpen(false);
+ }}
+ className={`w-full text-left px-4 py-2 text-sm hover:bg-slate-50 ${language === 'zh' ? 'text-slate-900 font-bold bg-slate-50' : 'text-slate-600'}`}
+ >
+ {t.zh}
+ </button>
+ <button
+ onClick={() => {
+ onLanguageChange('en');
+ setIsLangOpen(false);
+ }}
+ className={`w-full text-left px-4 py-2 text-sm hover:bg-slate-50 ${language === 'en' ? 'text-slate-900 font-bold bg-slate-50' : 'text-slate-600'}`}
+ >
+ {t.en}
+ </button>
+ </div>
+ </>
+ )}
說明: button 增加判斷 isLangOpen 的 flag 來彈出語言切換的 popup menu.