feat(ui): add mouse wheel cycling for select dropdowns, range sliders, and number inputs
Build Windows Installer / build (push) Successful in 10m49s

This commit is contained in:
m4xx1m committed 2026-11-12 20:26:31 +03:00
1 parent 478dbff654
commit 375cff78cb
4 files changed
+208 -1

No files matched your search

+39
View File
@@ -0,0 +1,39 @@
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { WheelStepper, nextEnabledOptionIndex, stepNumericValue } from './wheel.ts';
describe('wheel helpers', () => {
it('triggers immediately on mouse wheel notch and accumulates touchpad micro-deltas', () => {
const stepper = new WheelStepper(40, 250);
assert.equal(stepper.feed({ deltaY: 100, nowMs: 1000 }), 1);
assert.equal(stepper.feed({ deltaY: -100, nowMs: 1050 }), -1);
// Touchpad micro-events accumulate until threshold
assert.equal(stepper.feed({ deltaY: 15, nowMs: 1100 }), 0);
assert.equal(stepper.feed({ deltaY: 15, nowMs: 1120 }), 0);
assert.equal(stepper.feed({ deltaY: 15, nowMs: 1140 }), 1);
// Reversing direction clears prior partial delta
assert.equal(stepper.feed({ deltaY: 20, nowMs: 1200 }), 0);
assert.equal(stepper.feed({ deltaY: -25, nowMs: 1220 }), 0);
assert.equal(stepper.feed({ deltaY: -20, nowMs: 1240 }), -1);
// Idle reset discards stale delta
assert.equal(stepper.feed({ deltaY: 30, nowMs: 1300 }), 0);
assert.equal(stepper.feed({ deltaY: 20, nowMs: 1700 }), 0);
});
it('skips disabled options and clamps at bounds', () => {
const flags = [false, true, false, false];
assert.equal(nextEnabledOptionIndex(0, flags, 1), 2);
assert.equal(nextEnabledOptionIndex(2, flags, -1), 0);
assert.equal(nextEnabledOptionIndex(0, flags, -1), 0);
assert.equal(nextEnabledOptionIndex(3, flags, 1), 3);
});
it('steps numeric values cleanly without float drift', () => {
assert.equal(stepNumericValue(1.1, 0.05, 0.25, 8, 1), 1.15);
assert.equal(stepNumericValue(0.25, 0.05, 0.25, 8, -1), 0.25);
assert.equal(stepNumericValue(51, 1, 0, 51, 1), 51);
});
});