feat(kanban): sidebar edge zone now toggles (open + close)
The 32px left drag zone now also closes the sidebar when it is open. Symmetric behaviour: dwell ≥400ms while dragging closes if open / opens if closed. To prevent a drag that starts with the pointer already inside the sidebar (e.g. dragging a sidebar card itself) from immediately auto- closing, the close action requires the pointer to have left the strip at least once after the drag started. So: - closed + drag-to-edge -> opens (unchanged). - open + drag a card out, then move the card back to the edge -> closes. - open + drag a sidebar card directly to the board -> nothing happens. After a successful toggle the dwell flag resets, so the user must leave the strip and re-enter to trigger another action. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+24
-8
@@ -193,6 +193,12 @@ export function App() {
|
||||
}
|
||||
let timer: number | null = null;
|
||||
let inside = false;
|
||||
// Para evitar que un drag iniciado dentro del sidebar abierto dispare un
|
||||
// cierre inmediato, exigimos que el puntero haya salido de la franja al
|
||||
// menos una vez tras empezar el drag. Asi: abrir = entrar a la franja
|
||||
// tras empezar fuera (que ya pasaba); cerrar = salir de la franja y
|
||||
// volver a entrar.
|
||||
let hasLeftStrip = false;
|
||||
const clear = () => {
|
||||
if (timer !== null) {
|
||||
window.clearTimeout(timer);
|
||||
@@ -203,16 +209,26 @@ export function App() {
|
||||
const nowInside = ev.clientX <= DRAG_EDGE_WIDTH;
|
||||
if (nowInside === inside) return;
|
||||
inside = nowInside;
|
||||
setEdgeArmed(nowInside);
|
||||
if (nowInside) {
|
||||
if (navOpenRef.current) return; // already open, nothing to do
|
||||
clear();
|
||||
timer = window.setTimeout(() => {
|
||||
setNavOpen(true);
|
||||
}, DRAG_EDGE_HOVER_MS);
|
||||
} else {
|
||||
// El brillo visible solo cuando "armable": fuera-y-luego-dentro (open
|
||||
// siempre) o dentro con sidebar cerrado (open trigger).
|
||||
const armable = nowInside && (!navOpenRef.current || hasLeftStrip);
|
||||
setEdgeArmed(armable);
|
||||
if (!nowInside) {
|
||||
hasLeftStrip = true;
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
// nowInside = true
|
||||
if (!armable) return;
|
||||
clear();
|
||||
const willOpen = !navOpenRef.current;
|
||||
timer = window.setTimeout(() => {
|
||||
setNavOpen(willOpen);
|
||||
// Tras toggle, resetea el flag para no encadenar otra accion sin
|
||||
// que el usuario salga + vuelva.
|
||||
hasLeftStrip = false;
|
||||
setEdgeArmed(false);
|
||||
}, DRAG_EDGE_HOVER_MS);
|
||||
};
|
||||
document.addEventListener("mousemove", onMove);
|
||||
return () => {
|
||||
|
||||
Reference in New Issue
Block a user