Added simplebar support
This commit is contained in:
parent
040d7133f6
commit
9561887e4b
@ -29,6 +29,7 @@
|
|||||||
"react-scroll": "^1.9.3",
|
"react-scroll": "^1.9.3",
|
||||||
"react-turnstile": "^1.1.4",
|
"react-turnstile": "^1.1.4",
|
||||||
"sass": "^1.86.3",
|
"sass": "^1.86.3",
|
||||||
|
"simplebar-react": "^3.3.2",
|
||||||
"vite": "^6.2.5",
|
"vite": "^6.2.5",
|
||||||
"vite-plugin-svgo": "^2.0.0",
|
"vite-plugin-svgo": "^2.0.0",
|
||||||
"vite-plugin-svgr": "^4.5.0",
|
"vite-plugin-svgr": "^4.5.0",
|
||||||
|
|||||||
1257
public/global.css
1257
public/global.css
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,7 @@ import {
|
|||||||
useSettingsContext,
|
useSettingsContext,
|
||||||
} from "./contexts/SettingsContext";
|
} from "./contexts/SettingsContext";
|
||||||
const apiUrl = import.meta.env.VITE_API_URL;
|
const apiUrl = import.meta.env.VITE_API_URL;
|
||||||
|
import "./global.css";
|
||||||
|
|
||||||
// Component that handles image loading after API data is fetched
|
// Component that handles image loading after API data is fetched
|
||||||
const AppContent = ({ pages, properties, images }) => {
|
const AppContent = ({ pages, properties, images }) => {
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState, useCallback } from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import { Layout } from "antd";
|
|
||||||
import ContentRenderer from "./ContentRenderer";
|
import ContentRenderer from "./ContentRenderer";
|
||||||
import HeaderLogo from "./HeaderLogo";
|
import HeaderLogo from "./HeaderLogo";
|
||||||
import ScrollIcon from "../icons/ScrollIcon";
|
import ScrollIcon from "../icons/ScrollIcon";
|
||||||
@ -9,8 +8,8 @@ import ImageCarousel from "./ImageCarousel";
|
|||||||
import CloseButton from "./CloseButton";
|
import CloseButton from "./CloseButton";
|
||||||
import MenuButton from "./MenuButton";
|
import MenuButton from "./MenuButton";
|
||||||
import { useSettingsContext } from "../contexts/SettingsContext";
|
import { useSettingsContext } from "../contexts/SettingsContext";
|
||||||
|
import Simplebar from "simplebar-react";
|
||||||
const { Content } = Layout;
|
import "simplebar-react/dist/simplebar.min.css";
|
||||||
|
|
||||||
const Page = ({
|
const Page = ({
|
||||||
pageData,
|
pageData,
|
||||||
@ -29,10 +28,11 @@ const Page = ({
|
|||||||
!pageData.showProperties &&
|
!pageData.showProperties &&
|
||||||
!pageData.showContactForm &&
|
!pageData.showContactForm &&
|
||||||
!pageData.hideMobileImage;
|
!pageData.hideMobileImage;
|
||||||
const contentRef = useRef(null);
|
const scrollRef = useRef(null);
|
||||||
const [isImageShrunk, setIsImageShrunk] = useState(false);
|
const [isImageShrunk, setIsImageShrunk] = useState(false);
|
||||||
const [safariBlurToggle, setSafariBlurToggle] = useState(false);
|
const [safariBlurToggle, setSafariBlurToggle] = useState(false);
|
||||||
const shrinkDistance = 1;
|
const shrinkDistance = 1;
|
||||||
|
const [hasVerticalScrollbar, setHasVerticalScrollbar] = useState(false);
|
||||||
|
|
||||||
const settings = useSettingsContext();
|
const settings = useSettingsContext();
|
||||||
const themes = settings?.themes || [];
|
const themes = settings?.themes || [];
|
||||||
@ -43,8 +43,9 @@ const Page = ({
|
|||||||
|
|
||||||
// Reset scroll position and image state when visible becomes false
|
// Reset scroll position and image state when visible becomes false
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!visible && contentRef.current) {
|
if (!visible && scrollRef.current) {
|
||||||
contentRef.current.scrollTop = 0;
|
const el = scrollRef.current.getScrollElement();
|
||||||
|
el.scrollTop = 0;
|
||||||
setIsImageShrunk(false);
|
setIsImageShrunk(false);
|
||||||
}
|
}
|
||||||
}, [visible]);
|
}, [visible]);
|
||||||
@ -83,14 +84,50 @@ const Page = ({
|
|||||||
};
|
};
|
||||||
}, [isImageShrunk, mobileImage]);
|
}, [isImageShrunk, mobileImage]);
|
||||||
|
|
||||||
|
const checkOverflow = useCallback(() => {
|
||||||
|
if (!scrollRef.current) return;
|
||||||
|
const el = scrollRef.current.getScrollElement();
|
||||||
|
if (!el) return;
|
||||||
|
const canScroll = el.scrollHeight > el.clientHeight;
|
||||||
|
setHasVerticalScrollbar(canScroll);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Recalculate overflow on mount, when layout/content changes, and on resize
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!contentRef.current || !mobileImage) return;
|
checkOverflow();
|
||||||
|
}, [
|
||||||
|
checkOverflow,
|
||||||
|
pageData?.content,
|
||||||
|
visible,
|
||||||
|
isLargeMobile,
|
||||||
|
isMobile,
|
||||||
|
mobileImage,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Observe size changes of the scroll container
|
||||||
|
useEffect(() => {
|
||||||
|
if (!scrollRef.current) return;
|
||||||
|
const el = scrollRef.current.getScrollElement();
|
||||||
|
if (!el) return;
|
||||||
|
const resizeObserver = new ResizeObserver(() => {
|
||||||
|
checkOverflow();
|
||||||
|
});
|
||||||
|
resizeObserver.observe(el);
|
||||||
|
window.addEventListener("resize", checkOverflow);
|
||||||
|
return () => {
|
||||||
|
resizeObserver.disconnect();
|
||||||
|
window.removeEventListener("resize", checkOverflow);
|
||||||
|
};
|
||||||
|
}, [checkOverflow]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!scrollRef.current || !mobileImage) return;
|
||||||
|
|
||||||
const handleScroll = () => {
|
const handleScroll = () => {
|
||||||
// Don't shrink image if page is not visible
|
// Don't shrink image if page is not visible
|
||||||
if (!visible) return;
|
if (!visible) return;
|
||||||
|
|
||||||
const el = contentRef.current;
|
const el = scrollRef.current.getScrollElement();
|
||||||
const scrollTop = el.scrollTop;
|
const scrollTop = el.scrollTop;
|
||||||
const scrollHeight = el.scrollHeight;
|
const scrollHeight = el.scrollHeight;
|
||||||
const clientHeight = el.clientHeight;
|
const clientHeight = el.clientHeight;
|
||||||
@ -118,7 +155,7 @@ const Page = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const el = contentRef.current;
|
const el = scrollRef.current.getScrollElement();
|
||||||
el.addEventListener("scroll", handleScroll);
|
el.addEventListener("scroll", handleScroll);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
@ -172,22 +209,34 @@ const Page = ({
|
|||||||
<ImageCarousel page={pageData} className="th-mobile-image" />
|
<ImageCarousel page={pageData} className="th-mobile-image" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<Content
|
|
||||||
|
<div
|
||||||
className={`th-page-content${
|
className={`th-page-content${
|
||||||
visible == false ? " th-page-content-hidden" : ""
|
visible == false ? " th-page-content-hidden" : ""
|
||||||
}${isLargeMobile ? " th-page-content-mobile" : ""}`}
|
}${isLargeMobile ? " th-page-content-mobile" : ""}`}
|
||||||
ref={contentRef}
|
|
||||||
>
|
>
|
||||||
<div className="th-content-container-wrapper">
|
<Simplebar
|
||||||
|
className="th-content-scroll"
|
||||||
|
ref={scrollRef}
|
||||||
|
forceVisible="y"
|
||||||
|
autoHide={false}
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
className={`th-content-container ${
|
className={`th-content-container-wrapper${
|
||||||
mobileImage ? " th-content-container-mobile-image" : ""
|
hasVerticalScrollbar ? " th-content-container-wrapper-scroll" : ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<ContentRenderer content={pageData?.content} />
|
<div
|
||||||
|
className={`th-content-container ${
|
||||||
|
mobileImage ? " th-content-container-mobile-image" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<ContentRenderer content={pageData?.content} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Simplebar>
|
||||||
</Content>
|
</div>
|
||||||
|
|
||||||
{pageData?.showScroll == true && <ScrollIcon visible={visible} />}
|
{pageData?.showScroll == true && <ScrollIcon visible={visible} />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -8,7 +8,7 @@ export default defineConfig({
|
|||||||
plugins: [react(), svgo(), svgr()],
|
plugins: [react(), svgo(), svgr()],
|
||||||
server: {
|
server: {
|
||||||
host: "0.0.0.0",
|
host: "0.0.0.0",
|
||||||
allowedHosts: ["thehideout.tombutcher.work"],
|
allowedHosts: ["dev.tombutcher.work"],
|
||||||
},
|
},
|
||||||
base: "/",
|
base: "/",
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user