diff --git a/src/components/Header.css b/src/components/Header.css index 9e7ac2e..c2c5530 100644 --- a/src/components/Header.css +++ b/src/components/Header.css @@ -85,3 +85,24 @@ padding: 0; margin: 0; } + +/* Transition Animation */ +.theme-transition { + transition: background-color 0.3s ease, color 0.3s ease; +} + +.theme-transition.transitioning { + transition: background-color 0.3s ease, color 0.3s ease; +} + +.transition-bg { + transition: background-color 0.3s ease; +} + +.transition-text { + transition: color 0.3s ease, opacity 0.3s ease; +} + +.transition-logo { + transition: opacity 0.3s ease; +} \ No newline at end of file diff --git a/src/components/Header.js b/src/components/Header.js index b1bad5f..9e2b6c1 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -1,9 +1,9 @@ -import { Navbar, Container } from "react-bootstrap"; -import "./Header.css"; -import { useContext, useState, useEffect, useRef } from "react"; -import logo from "./../logo.png"; -import logo_white from "./../logo-white.png"; +import { useContext, useEffect, useState } from "react"; +import { Container, Navbar } from "react-bootstrap"; import { useDebouncedCallback } from "use-debounce"; +import logo_white from "./../logo-white.png"; +import logo from "./../logo.png"; +import "./Header.css"; // Context import { ThemeContext } from "../Context/themeContext"; import Darkmode from "./Buttons/Darkmode"; @@ -11,18 +11,21 @@ import CustomSelect from "./Buttons/Language"; const Header = ({ language, setLanguage, setInputSearch }) => { const { theme, changeTheme } = useContext(ThemeContext); - const [input, setInput] = useState(""); // Mirrors inputSearch and setInputSearch + const [input, setInput] = useState(""); + const [isTransitioning, setIsTransitioning] = useState(false); - const debouncedInput = useDebouncedCallback( - (value) => { - setInputSearch(value); - }, - // delay in ms - 1000 - ); + const debouncedInput = useDebouncedCallback((value) => { + setInputSearch(value); + }, 1000); + + const handleThemeChange = () => { + setIsTransitioning(true); + changeTheme(); + setTimeout(() => setIsTransitioning(false), 300); // 匹配动画时长 + }; const handleInputSearch = (inputValue) => { - setInputExpanded(true); // Keep input expanded while typing + setInputExpanded(true); setInput(inputValue); debouncedInput(inputValue); }; @@ -31,46 +34,48 @@ const Header = ({ language, setLanguage, setInputSearch }) => { setInputSearch(input); }, [input, setInputSearch]); - const [inputExpanded, setInputExpanded] = useState(false); // Control input expansion state + const [inputExpanded, setInputExpanded] = useState(false); const handleSearchClick = () => { - setInputExpanded((prev) => !prev); // Expand input when clicked + setInputExpanded((prev) => !prev); }; return ( - - - - {theme.mode === "light" ? ( - Logo - ) : ( - Logo - )} + + + + Logo