Added simplebar support

This commit is contained in:
Tom Butcher 2025-11-16 13:29:04 +00:00
parent 040d7133f6
commit 9561887e4b
6 changed files with 630 additions and 1651 deletions

View File

@ -29,6 +29,7 @@
"react-scroll": "^1.9.3",
"react-turnstile": "^1.1.4",
"sass": "^1.86.3",
"simplebar-react": "^3.3.2",
"vite": "^6.2.5",
"vite-plugin-svgo": "^2.0.0",
"vite-plugin-svgr": "^4.5.0",

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@ import {
useSettingsContext,
} from "./contexts/SettingsContext";
const apiUrl = import.meta.env.VITE_API_URL;
import "./global.css";
// Component that handles image loading after API data is fetched
const AppContent = ({ pages, properties, images }) => {

View File

@ -1,6 +1,5 @@
import { useEffect, useRef, useState } from "react";
import { useEffect, useRef, useState, useCallback } from "react";
import PropTypes from "prop-types";
import { Layout } from "antd";
import ContentRenderer from "./ContentRenderer";
import HeaderLogo from "./HeaderLogo";
import ScrollIcon from "../icons/ScrollIcon";
@ -9,8 +8,8 @@ import ImageCarousel from "./ImageCarousel";
import CloseButton from "./CloseButton";
import MenuButton from "./MenuButton";
import { useSettingsContext } from "../contexts/SettingsContext";
const { Content } = Layout;
import Simplebar from "simplebar-react";
import "simplebar-react/dist/simplebar.min.css";
const Page = ({
pageData,
@ -29,10 +28,11 @@ const Page = ({
!pageData.showProperties &&
!pageData.showContactForm &&
!pageData.hideMobileImage;
const contentRef = useRef(null);
const scrollRef = useRef(null);
const [isImageShrunk, setIsImageShrunk] = useState(false);
const [safariBlurToggle, setSafariBlurToggle] = useState(false);
const shrinkDistance = 1;
const [hasVerticalScrollbar, setHasVerticalScrollbar] = useState(false);
const settings = useSettingsContext();
const themes = settings?.themes || [];
@ -43,8 +43,9 @@ const Page = ({
// Reset scroll position and image state when visible becomes false
useEffect(() => {
if (!visible && contentRef.current) {
contentRef.current.scrollTop = 0;
if (!visible && scrollRef.current) {
const el = scrollRef.current.getScrollElement();
el.scrollTop = 0;
setIsImageShrunk(false);
}
}, [visible]);
@ -83,14 +84,50 @@ const Page = ({
};
}, [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(() => {
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 = () => {
// Don't shrink image if page is not visible
if (!visible) return;
const el = contentRef.current;
const el = scrollRef.current.getScrollElement();
const scrollTop = el.scrollTop;
const scrollHeight = el.scrollHeight;
const clientHeight = el.clientHeight;
@ -118,7 +155,7 @@ const Page = ({
}
};
const el = contentRef.current;
const el = scrollRef.current.getScrollElement();
el.addEventListener("scroll", handleScroll);
return () => {
@ -172,22 +209,34 @@ const Page = ({
<ImageCarousel page={pageData} className="th-mobile-image" />
</div>
)}
<Content
<div
className={`th-page-content${
visible == false ? " th-page-content-hidden" : ""
}${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
className={`th-content-container ${
mobileImage ? " th-content-container-mobile-image" : ""
className={`th-content-container-wrapper${
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>
</Content>
</Simplebar>
</div>
{pageData?.showScroll == true && <ScrollIcon visible={visible} />}
</div>
);

View File

@ -8,7 +8,7 @@ export default defineConfig({
plugins: [react(), svgo(), svgr()],
server: {
host: "0.0.0.0",
allowedHosts: ["thehideout.tombutcher.work"],
allowedHosts: ["dev.tombutcher.work"],
},
base: "/",
});

935
yarn.lock

File diff suppressed because it is too large Load Diff