mirror of
https://github.com/notion-enhancer/notion-enhancer.git
synced 2025-04-11 15:59:03 +00:00
fix(panel): debounce peek trigger
e.g. do not show if mouse is moved quickly out of the window
This commit is contained in:
parent
c722c7f854
commit
493db7aa2e
@ -183,6 +183,7 @@ const insertPanel = async (api, db) => {
|
|||||||
appendToDom();
|
appendToDom();
|
||||||
|
|
||||||
useState(["panelOpen"], ([panelOpen]) => {
|
useState(["panelOpen"], ([panelOpen]) => {
|
||||||
|
console.log(panelOpen);
|
||||||
if (panelOpen) $panelTopbarBtn.setAttribute("data-active", true);
|
if (panelOpen) $panelTopbarBtn.setAttribute("data-active", true);
|
||||||
else $panelTopbarBtn.removeAttribute("data-active");
|
else $panelTopbarBtn.removeAttribute("data-active");
|
||||||
});
|
});
|
||||||
|
@ -136,7 +136,7 @@ function Panel({
|
|||||||
</aside>
|
</aside>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
let preDragWidth, dragStartX;
|
let preDragWidth, dragStartX, _animatedAt;
|
||||||
const getWidth = async (width) => {
|
const getWidth = async (width) => {
|
||||||
if (width && !isNaN(width)) {
|
if (width && !isNaN(width)) {
|
||||||
width = Math.max(width, minWidth);
|
width = Math.max(width, minWidth);
|
||||||
@ -150,6 +150,10 @@ function Panel({
|
|||||||
.querySelectorAll("[tabindex]")
|
.querySelectorAll("[tabindex]")
|
||||||
.forEach(($el) => ($el.tabIndex = interactive ? 1 : -1));
|
.forEach(($el) => ($el.tabIndex = interactive ? 1 : -1));
|
||||||
},
|
},
|
||||||
|
isAnimated = () => {
|
||||||
|
if (!_animatedAt) return false;
|
||||||
|
return Date.now() - _animatedAt <= transitionDuration;
|
||||||
|
},
|
||||||
isDragging = () => !isNaN(preDragWidth) && !isNaN(dragStartX),
|
isDragging = () => !isNaN(preDragWidth) && !isNaN(dragStartX),
|
||||||
isPinned = () => $panel.hasAttribute("data-pinned"),
|
isPinned = () => $panel.hasAttribute("data-pinned"),
|
||||||
isPeeked = () => $panel.hasAttribute("data-peeked"),
|
isPeeked = () => $panel.hasAttribute("data-peeked"),
|
||||||
@ -177,14 +181,14 @@ function Panel({
|
|||||||
boxShadow: "none",
|
boxShadow: "none",
|
||||||
};
|
};
|
||||||
|
|
||||||
const animationState = {},
|
const animationState = { ...closedWidth },
|
||||||
easing = "cubic-bezier(0.4, 0, 0.2, 1)",
|
easing = "cubic-bezier(0.4, 0, 0.2, 1)",
|
||||||
animate = ($target, keyframes) => {
|
animate = ($target, keyframes) => {
|
||||||
const opts = { fill: "forwards", duration: transitionDuration, easing };
|
const opts = { fill: "forwards", duration: transitionDuration, easing };
|
||||||
$target.animate(keyframes, opts);
|
$target.animate(keyframes, opts);
|
||||||
console.log($target, keyframes);
|
|
||||||
},
|
},
|
||||||
animatePanel = (to) => {
|
animatePanel = (to) => {
|
||||||
|
_animatedAt = Date.now();
|
||||||
animate($panel.lastElementChild, [animationState, to]);
|
animate($panel.lastElementChild, [animationState, to]);
|
||||||
Object.assign(animationState, to);
|
Object.assign(animationState, to);
|
||||||
};
|
};
|
||||||
@ -243,18 +247,22 @@ function Panel({
|
|||||||
|
|
||||||
// hovering over the peek trigger will temporarily
|
// hovering over the peek trigger will temporarily
|
||||||
// pop out an interactive preview of the panel
|
// pop out an interactive preview of the panel
|
||||||
|
let _peekDebounce;
|
||||||
const $peekTrigger = html`<div
|
const $peekTrigger = html`<div
|
||||||
class="absolute z-10 right-0 h-[calc(100vh-120px)] bottom-[60px] w-[64px]
|
class="absolute z-10 right-0 h-[calc(100vh-120px)] bottom-[60px] w-[96px]
|
||||||
group-&[data-peeked]/panel:(w-[calc(var(--panel--width,0)+8px)])
|
group-&[data-peeked]/panel:(w-[calc(var(--panel--width,0)+8px)])
|
||||||
group-&[data-pinned]/panel:(w-[calc(var(--panel--width,0)+8px)])"
|
group-&[data-pinned]/panel:(w-[calc(var(--panel--width,0)+8px)])"
|
||||||
></div>`;
|
></div>`;
|
||||||
$panel.prepend($peekTrigger);
|
$panel.prepend($peekTrigger);
|
||||||
$panel.addEventListener("mouseout", () => {
|
$panel.addEventListener("mouseout", () => {
|
||||||
if (isDragging() || isPinned()) return;
|
if (isDragging() || isAnimated() || isPinned()) return;
|
||||||
if (!$panel.matches(":hover")) $panel.close();
|
if (!$panel.matches(":hover")) $panel.close();
|
||||||
});
|
});
|
||||||
$panel.addEventListener("mouseover", () => {
|
$panel.addEventListener("mouseover", () => {
|
||||||
if (isClosed() && $panel.matches(":hover")) $panel.peek();
|
_peekDebounce ??= setTimeout(() => {
|
||||||
|
if (isClosed() && $panel.matches(":hover")) $panel.peek();
|
||||||
|
_peekDebounce = undefined;
|
||||||
|
}, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
// moves help button out of the way of open panel.
|
// moves help button out of the way of open panel.
|
||||||
|
@ -13,7 +13,7 @@ function TopbarButton({ icon, ...props }, ...children) {
|
|||||||
user-select-none h-[28px] w-[33px] duration-[20ms]
|
user-select-none h-[28px] w-[33px] duration-[20ms]
|
||||||
transition inline-flex items-center justify-center mr-[2px]
|
transition inline-flex items-center justify-center mr-[2px]
|
||||||
rounded-[3px] hover:bg-[color:var(--theme--bg-hover)]
|
rounded-[3px] hover:bg-[color:var(--theme--bg-hover)]
|
||||||
[data-active]:bg-[color:var(--theme--bg-hover)]`,
|
&[data-active]:bg-[color:var(--theme--bg-hover)]`,
|
||||||
});
|
});
|
||||||
return html`<button ...${props}>
|
return html`<button ...${props}>
|
||||||
<i
|
<i
|
||||||
|
Loading…
Reference in New Issue
Block a user