@@ -112,9 +112,11 @@ watch(
112112 { immediate: true },
113113)
114114
115- // Suppress per-card enter animation when the entire result set is replaced (new search).
116- // Cards loaded incrementally via scroll should still animate in with the stagger effect.
117- const suppressAnimation = shallowRef (false )
115+ // Tracks how many items came from the last new-search batch.
116+ // Items at index < newSearchBatchSize are from the new search → no animation.
117+ // Items at index >= newSearchBatchSize were loaded via scroll → animate with stagger.
118+ // Using an index threshold avoids any timing dependency on nextTick / virtual list paint.
119+ const newSearchBatchSize = shallowRef (Infinity )
118120
119121// Reset scroll state when results change significantly (new search)
120122watch (
@@ -127,10 +129,7 @@ watch(
127129 (oldResults .length > 0 && newResults [0 ]?.package .name !== oldResults [0 ]?.package .name )
128130 ) {
129131 hasScrolledToInitial .value = false
130- suppressAnimation .value = true
131- nextTick (() => {
132- suppressAnimation .value = false
133- })
132+ newSearchBatchSize .value = newResults .length
134133 }
135134 },
136135)
@@ -181,10 +180,13 @@ defineExpose({
181180 :index =" index"
182181 :search-query =" searchQuery"
183182 :class ="
184- !suppressAnimation && 'motion-safe:animate-fade-in motion-safe:animate-fill-both'
183+ index >= newSearchBatchSize &&
184+ 'motion-safe:animate-fade-in motion-safe:animate-fill-both'
185185 "
186186 :style ="
187- !suppressAnimation ? { animationDelay: `${Math.min(index * 0.02, 0.3)}s` } : {}
187+ index >= newSearchBatchSize
188+ ? { animationDelay: `${Math.min((index - newSearchBatchSize) * 0.02, 0.3)}s` }
189+ : {}
188190 "
189191 :filters =" filters"
190192 @click-keyword =" emit('clickKeyword', $event)"
@@ -237,9 +239,14 @@ defineExpose({
237239 :index =" index"
238240 :search-query =" searchQuery"
239241 :class ="
240- !suppressAnimation && 'motion-safe:animate-fade-in motion-safe:animate-fill-both'
242+ index >= newSearchBatchSize &&
243+ 'motion-safe:animate-fade-in motion-safe:animate-fill-both'
244+ "
245+ :style ="
246+ index >= newSearchBatchSize
247+ ? { animationDelay: `${Math.min((index - newSearchBatchSize) * 0.02, 0.3)}s` }
248+ : {}
241249 "
242- :style =" !suppressAnimation ? { animationDelay: `${Math.min(index * 0.02, 0.3)}s` } : {}"
243250 :filters =" filters"
244251 @click-keyword =" emit('clickKeyword', $event)"
245252 />
0 commit comments