mirror of
https://github.com/responsively-org/responsively-app
synced 2024-11-10 14:54:12 +00:00
Added Scroll to top feature
This commit is contained in:
parent
1bf5835037
commit
a0e242e57c
2 changed files with 67 additions and 0 deletions
|
@ -138,6 +138,15 @@ const Toolbar = ({
|
||||||
onRotate(!rotated);
|
onRotate(!rotated);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const scrollToTop = () => {
|
||||||
|
if (webview) {
|
||||||
|
webview.executeJavaScript(
|
||||||
|
'window.scrollTo({ top: 0, behavior: "smooth" })',
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-between gap-1">
|
<div className="flex items-center justify-between gap-1">
|
||||||
<div className="my-1 inline-flex max-w-[75%] items-center gap-1 overflow-x-auto">
|
<div className="my-1 inline-flex max-w-[75%] items-center gap-1 overflow-x-auto">
|
||||||
|
@ -190,6 +199,9 @@ const Toolbar = ({
|
||||||
<Button onClick={toggleRulers} title="Show rulers">
|
<Button onClick={toggleRulers} title="Show rulers">
|
||||||
<Icon icon="tdesign:measurement-1" />
|
<Icon icon="tdesign:measurement-1" />
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button onClick={scrollToTop} title="Scroll to Top">
|
||||||
|
<Icon icon="ic:baseline-arrow-upward" />
|
||||||
|
</Button>
|
||||||
<ColorBlindnessTools webview={webview} />
|
<ColorBlindnessTools webview={webview} />
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
|
|
|
@ -495,6 +495,61 @@ const Device = ({ isPrimary, device, setIndividualDevice }: Props) => {
|
||||||
const scaledHeight = height * zoomfactor;
|
const scaledHeight = height * zoomfactor;
|
||||||
const scaledWidth = width * zoomfactor;
|
const scaledWidth = width * zoomfactor;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const webview = ref.current;
|
||||||
|
if (!webview) return;
|
||||||
|
|
||||||
|
const injectScrollToTopButton = () => {
|
||||||
|
webview
|
||||||
|
.executeJavaScript(`document.readyState`, false)
|
||||||
|
.then((readyState) => {
|
||||||
|
if (readyState !== 'complete') {
|
||||||
|
throw new Error('Document not ready for injection.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const buttonHTML = `
|
||||||
|
<button id="scrollToTopButton" style="position: fixed; right: 20px; bottom: 20px; z-index: 1000; padding: 10px 15px; font-size: 16px; border: none; background-color: #007BFF; color: white; border-radius: 5px; cursor: pointer; opacity: 0; transition: opacity 0.5s;">
|
||||||
|
↑
|
||||||
|
</button>
|
||||||
|
`;
|
||||||
|
const script = `
|
||||||
|
document.body.insertAdjacentHTML('beforeend', '${buttonHTML.replace(
|
||||||
|
/\n/g,
|
||||||
|
''
|
||||||
|
)}');
|
||||||
|
const scrollToTopButton = document.getElementById('scrollToTopButton');
|
||||||
|
scrollToTopButton.onclick = function() {
|
||||||
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('scroll', function() {
|
||||||
|
if (window.scrollY > 100) {
|
||||||
|
scrollToTopButton.style.opacity = 1;
|
||||||
|
} else {
|
||||||
|
scrollToTopButton.style.opacity = 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`;
|
||||||
|
|
||||||
|
return webview.executeJavaScript(script, false);
|
||||||
|
})
|
||||||
|
.then(() => null)
|
||||||
|
.catch((err) => {
|
||||||
|
console.error('Error executing script or loading document:', err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
webview.addEventListener('dom-ready', injectScrollToTopButton);
|
||||||
|
|
||||||
|
// eslint-disable-next-line consistent-return
|
||||||
|
return () => {
|
||||||
|
if (webview) {
|
||||||
|
webview.removeEventListener('dom-ready', injectScrollToTopButton);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
}, [ref]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cx('h-fit flex-shrink-0', {
|
className={cx('h-fit flex-shrink-0', {
|
||||||
|
|
Loading…
Reference in a new issue