- because of making the root's child div styles as override: auto it won't be a ref for the sticky category logic
71 lines
2.3 KiB
TypeScript
71 lines
2.3 KiB
TypeScript
import { Button } from "antd";
|
|
import TopIcon from "components/Icons/TopIcon";
|
|
import { useScrollHandler } from "contexts/ScrollHandlerContext";
|
|
import useBreakPoint from "hooks/useBreakPoint";
|
|
import { useCallback } from "react";
|
|
import { useAppSelector } from "redux/hooks";
|
|
import { colors } from "ThemeConstants";
|
|
import styles from "./FloatingButton.module.css";
|
|
|
|
export function FloatingButton() {
|
|
const { isRTL } = useAppSelector((state) => state.locale);
|
|
const { themeName } = useAppSelector((state) => state.theme);
|
|
const { isMobile, isTablet } = useBreakPoint();
|
|
|
|
const { showScrollTop } = useScrollHandler();
|
|
|
|
const scrollToTop = useCallback(() => {
|
|
// Use a more stable approach to find the scroll container
|
|
const findScrollContainer = () => {
|
|
const antApp = document.querySelector('.ant-app') as HTMLElement;
|
|
if (antApp && antApp.scrollHeight > antApp.clientHeight) {
|
|
return antApp;
|
|
}
|
|
|
|
const appContainer = document.querySelector('[class*="App"]') as HTMLElement;
|
|
if (appContainer && appContainer.scrollHeight > appContainer.clientHeight) {
|
|
return appContainer;
|
|
}
|
|
|
|
return document.documentElement;
|
|
};
|
|
|
|
const scrollContainer = findScrollContainer();
|
|
if (scrollContainer) {
|
|
scrollContainer.scrollTo({
|
|
top: 0,
|
|
behavior: "smooth",
|
|
});
|
|
}
|
|
}, []);
|
|
|
|
return (
|
|
<>
|
|
{/* Floating Scroll to Top Button */}
|
|
{showScrollTop && (
|
|
<Button
|
|
type="primary"
|
|
shape="circle"
|
|
size={isMobile ? "large" : "large"}
|
|
icon={<TopIcon />}
|
|
onClick={scrollToTop}
|
|
className={`${styles.scrollToTopButton}`}
|
|
style={{
|
|
position: "fixed",
|
|
bottom: isMobile ? "100px" : isTablet ? "120px" : "25px",
|
|
right: isRTL ? "auto" : isMobile ? "20px" : "32px",
|
|
left: isRTL ? (isMobile ? "20px" : "32px") : "auto",
|
|
zIndex: 1000,
|
|
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
|
|
backgroundColor:
|
|
themeName === "dark" ? colors.primary : colors.primary,
|
|
borderColor: themeName === "dark" ? colors.primary : colors.primary,
|
|
width: isMobile ? 48 : 56,
|
|
height: isMobile ? 48 : 56,
|
|
}}
|
|
/>
|
|
)}
|
|
</>
|
|
);
|
|
}
|