mirror of
https://github.com/notion-enhancer/notion-enhancer.git
synced 2025-04-08 06:29:03 +00:00
feat: conditional display of scroll to top btn
This commit is contained in:
parent
42b2fedacf
commit
d420b2de4e
56
src/core/islands/FloatingButton.mjs
Normal file
56
src/core/islands/FloatingButton.mjs
Normal file
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* notion-enhancer
|
||||
* (c) 2024 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
let __$wrapper;
|
||||
const setupWrapper = () => {
|
||||
const notionHelp = ".notion-help-button",
|
||||
{ html, addMutationListener } = globalThis.__enhancerApi,
|
||||
{ removeMutationListener } = globalThis.__enhancerApi;
|
||||
return (__$wrapper ??= new Promise((res, rej) => {
|
||||
const addToDom = () => {
|
||||
const $help = document.querySelector(notionHelp);
|
||||
if (!$help) return;
|
||||
const $wrapper = html`<div
|
||||
class="notion-enhancer--floating-buttons z-50
|
||||
absolute right-0 bottom-[calc(26px+env(safe-area-inset-bottom))]
|
||||
flex gap-[12px] !(&>.notion-help-button:static)"
|
||||
></div>`;
|
||||
removeMutationListener(addToDom);
|
||||
$help.replaceWith($wrapper);
|
||||
$wrapper.append($help);
|
||||
res($wrapper);
|
||||
};
|
||||
addMutationListener(notionHelp, addToDom);
|
||||
addToDom();
|
||||
}));
|
||||
},
|
||||
addFloatingButton = async ($btn) => {
|
||||
if (document.contains($btn)) return;
|
||||
(await setupWrapper()).prepend($btn);
|
||||
},
|
||||
removeFloatingButton = ($btn) => $btn.remove();
|
||||
|
||||
function FloatingButton({ icon, ...props }, ...children) {
|
||||
const { html, extendProps } = globalThis.__enhancerApi;
|
||||
extendProps(props, {
|
||||
tabindex: 0,
|
||||
class: `notion-enhancer--floating-button
|
||||
size-[36px] flex items-center justify-center rounded-full
|
||||
text-([20px] [color:var(--theme--fg-primary)]) select-none cursor-pointer
|
||||
bg-[color:var(--theme--bg-secondary)] hover:bg-[color:var(--theme--bg-hover)]
|
||||
shadow-[rgba(15,15,15,0.2)_0px_0px_0px_1px,rgba(15,15,15,0.2)_0px_2px_4px]`,
|
||||
});
|
||||
return html`<button ...${props}>${children}</button>`;
|
||||
}
|
||||
|
||||
Object.assign((globalThis.__enhancerApi ??= {}), {
|
||||
addFloatingButton,
|
||||
removeFloatingButton,
|
||||
});
|
||||
|
||||
export { addFloatingButton, FloatingButton };
|
@ -7,45 +7,37 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
import { FloatingButton } from "../../core/islands/FloatingButton.mjs";
|
||||
|
||||
export default async (api, db) => {
|
||||
const { html } = api,
|
||||
const { html, addFloatingButton, removeFloatingButton } = api,
|
||||
{ addMutationListener, removeMutationListener } = api,
|
||||
distanceUntilShown = await db.get("distanceScrolledUntilShown"),
|
||||
scrollUnits = await db.get("scrollDistanceUnits"),
|
||||
behavior = (await db.get("smoothScrolling")) ? "smooth" : "auto",
|
||||
scroller = ".notion-frame > .notion-scroller";
|
||||
|
||||
const $btn = html`<button
|
||||
let $scroller;
|
||||
const $btn = html`<${FloatingButton}
|
||||
onclick=${() => $scroller?.scroll({ top: 0, left: 0, behavior })}
|
||||
aria-label="Scroll to top"
|
||||
class="z-50 flex items-center justify-center absolute rounded-full
|
||||
text-([20px] [color:var(--theme--fg-primary)]) select-none cursor-pointer
|
||||
bg-[color:var(--theme--bg-secondary)] hover:bg-[color:var(--theme--bg-hover)]
|
||||
bottom-[calc(26px+env(safe-area-inset-bottom))] right-[74px] w-[36px] h-[36px]"
|
||||
style="box-shadow: rgba(15, 15, 15, 0.2) 0px 0px 0px 1px, rgba(15, 15, 15, 0.2) 0px 2px 4px;"
|
||||
onclick=${() => {
|
||||
const $scroller = document.querySelector(scroller);
|
||||
$scroller.scroll({ top: 0, left: 0, behavior });
|
||||
}}
|
||||
>
|
||||
<i class="i-chevrons-up" />
|
||||
</button>`;
|
||||
document.body.append($btn);
|
||||
|
||||
// const topDistancePx = +(await db.get(["top_distance_px"])),
|
||||
// topDistancePercent = 0.01 * (await db.get(["top_distance_percent"])),
|
||||
// adjustButtonVisibility = async () => {
|
||||
// if (!$scroller) return;
|
||||
// $scrollButton.classList.add("hidden");
|
||||
// const scrolledDistance =
|
||||
// $scroller.scrollTop >= topDistancePx ||
|
||||
// $scroller.scrollTop >=
|
||||
// ($scroller.scrollHeight - $scroller.clientHeight) *
|
||||
// topDistancePercent;
|
||||
// if (scrolledDistance) $scrollButton.classList.remove("hidden");
|
||||
// };
|
||||
// web.addDocumentObserver(() => {
|
||||
// $scroller = document.querySelector(".notion-frame > .notion-scroller");
|
||||
// $scroller.removeEventListener("scroll", adjustButtonVisibility);
|
||||
// $scroller.addEventListener("scroll", adjustButtonVisibility);
|
||||
// }, [".notion-frame > .notion-scroller"]);
|
||||
// adjustButtonVisibility();
|
||||
// if (topDistancePx && topDistancePercent)
|
||||
// $scrollButton.classList.add("hidden");
|
||||
><i class="i-chevrons-up" />
|
||||
<//>`,
|
||||
onScroll = () => {
|
||||
if (!$scroller) return;
|
||||
const { scrollTop, scrollHeight, clientHeight } = $scroller,
|
||||
scrollPercent = (scrollTop / (scrollHeight - clientHeight)) * 100,
|
||||
scrollDist = scrollUnits === "Percent" ? scrollPercent : scrollTop;
|
||||
if (distanceUntilShown <= scrollDist) addFloatingButton($btn);
|
||||
else removeFloatingButton($btn);
|
||||
},
|
||||
setup = () => {
|
||||
if (document.contains($scroller)) return;
|
||||
$scroller = document.querySelector(scroller);
|
||||
$scroller?.removeEventListener("scroll", onScroll);
|
||||
$scroller?.addEventListener("scroll", onScroll);
|
||||
onScroll();
|
||||
};
|
||||
addMutationListener(scroller, setup, true);
|
||||
setup();
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user