@@ -61,7 +61,7 @@ func TestFilter_CoalescesSameDirection(t *testing.T) {
6161 require.Equal(t, float64(3), msg.DeltaY, "should accumulate 3 down events")
6262}
6363
64−func TestFilter_DirectionChangeResetsAccumulator(t *testing.T) {
64+func TestFilter_DirectionChangeWithinWindowAccumulatesNewDirection(t *testing.T) {
6565 t.Parallel()
6666 f, now := newTestFilter(t)
6767
@@ -81,6 +81,31 @@ func TestFilter_DirectionChangeResetsAccumulator(t *testing.T) {
8181 require.Equal(t, float64(-2), msg.DeltaY, "should have 2 accumulated up events")
8282}
8383
84+func TestFilter_DirectionChangeDropsStaleAccumulator(t *testing.T) {
85+ t.Parallel()
86+ f, now := newTestFilter(t)
87+
88+ // Scroll up
89+ f.Filter(nil, wheelUp())
90+
91+ // Scroll up again
92+ *now = now.Add(5 * time.Millisecond)
93+ result := f.Filter(nil, wheelUp())
94+ require.Nil(t, result)
95+
96+ // Scroll down (accumulation should reset)
97+ *now = now.Add(5 * time.Millisecond)
98+ result = f.Filter(nil, wheelDown())
99+ require.Nil(t, result)
100+
101+ // And scroll down again
102+ *now = now.Add(20 * time.Millisecond)
103+ result = f.Filter(nil, wheelDown())
104+ msg, ok := result.(common.CoalescedWheelMsg)
105+ require.True(t, ok)
106+ require.Equal(t, float64(2), msg.DeltaY, "should drop stale opposite-direction events")
107+}
108+
84109func TestFilter_WindowExpiryEmitsAccumulated(t *testing.T) {
85110 t.Parallel()
86111 f, now := newTestFilter(t)