test(realtime-table): шаг прокрутки колесом — чистые функции

Чистые функции getWheelScrollDelta и canScrollBy для шага прокрутки
колесом мыши в таблице форм (AURORA-1944), с тестами node:test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andrey Epifancev 2026-10-29 18:26:04 +04:00
parent 2a287480b6
commit ef83a6c361
2 changed files with 66 additions and 0 deletions

View File

@ -0,0 +1,22 @@
// Шаг прокрутки колесом мыши в таблице форм (AURORA-1944).
// Браузер прокручивает ~100 px за щелчок, строки 34–48 px: за щелчок уезжает 2–3 строки.
export const WHEEL_SCROLL_MULTIPLIER = 2;
const DOM_DELTA_PIXEL = 0;
const DOM_DELTA_LINE = 1;
// Щелчок колеса мыши в Chrome/Edge — от ~50 px; тачпад шлёт мелкие шаги, их не трогаем.
const MIN_MOUSE_WHEEL_DELTA_PX = 50;
// Firefox шлёт строки (deltaMode = 1, обычно 3 строки за щелчок).
const LINE_HEIGHT_PX = 33;
// На сколько px прокрутить по вертикали вместо браузера, или null — отдать событие браузеру.
export const getWheelScrollDelta = ({ deltaX, deltaY, deltaMode, ctrlKey, shiftKey }) => {
if (ctrlKey || shiftKey || deltaY === 0 || Math.abs(deltaX) > Math.abs(deltaY)) return null;
if (deltaMode === DOM_DELTA_LINE) return deltaY * LINE_HEIGHT_PX * WHEEL_SCROLL_MULTIPLIER;
if (deltaMode !== DOM_DELTA_PIXEL || Math.abs(deltaY) < MIN_MOUSE_WHEEL_DELTA_PX) return null;
return deltaY * WHEEL_SCROLL_MULTIPLIER;
};
// Можно ли прокрутить элемент на delta по вертикали (иначе отдаём событие браузеру — прокрутка страницы).
export const canScrollBy = ({ scrollTop, scrollHeight, clientHeight }, delta) =>
delta < 0 ? scrollTop > 0 : scrollTop + clientHeight < scrollHeight;

View File

@ -0,0 +1,44 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { canScrollBy, getWheelScrollDelta } from './wheelScroll.js';
const wheel = (overrides) => ({ deltaX: 0, deltaY: 0, deltaMode: 0, ctrlKey: false, shiftKey: false, ...overrides });
test('щелчок колеса мыши удваивает шаг', () => {
assert.equal(getWheelScrollDelta(wheel({ deltaY: 100 })), 200);
assert.equal(getWheelScrollDelta(wheel({ deltaY: -100 })), -200);
assert.equal(getWheelScrollDelta(wheel({ deltaY: 120 })), 240);
});
test('тачпад (мелкие px-шаги) не трогаем', () => {
assert.equal(getWheelScrollDelta(wheel({ deltaY: 10 })), null);
assert.equal(getWheelScrollDelta(wheel({ deltaY: 49 })), null);
});
test('Firefox (строки) считает в строках ×2', () => {
assert.equal(getWheelScrollDelta(wheel({ deltaMode: 1, deltaY: 3 })), 198);
});
test('прокрутка страницами (deltaMode 2) не трогаем', () => {
assert.equal(getWheelScrollDelta(wheel({ deltaMode: 2, deltaY: 1 })), null);
});
test('Ctrl и Shift не трогаем', () => {
assert.equal(getWheelScrollDelta(wheel({ deltaY: 100, ctrlKey: true })), null);
assert.equal(getWheelScrollDelta(wheel({ deltaY: 100, shiftKey: true })), null);
});
test('горизонтальная прокрутка и нулевая дельта не трогаем', () => {
assert.equal(getWheelScrollDelta(wheel({ deltaX: 100, deltaY: 20 })), null);
assert.equal(getWheelScrollDelta(wheel({ deltaY: 0 })), null);
});
test('canScrollBy: у верха вверх и у низа вниз — нельзя, в середине — можно', () => {
const top = { scrollTop: 0, scrollHeight: 1000, clientHeight: 400 };
const bottom = { scrollTop: 600, scrollHeight: 1000, clientHeight: 400 };
const middle = { scrollTop: 300, scrollHeight: 1000, clientHeight: 400 };
assert.equal(canScrollBy(top, -200), false);
assert.equal(canScrollBy(bottom, 200), false);
assert.equal(canScrollBy(middle, 200), true);
assert.equal(canScrollBy(middle, -200), true);
});