@@ -162,130 +162,114 @@ describe("`useChatKeyboard` — Android non-inverted + always", () => {
162162} ) ;
163163
164164describe ( "`useChatKeyboard` — Android inverted + always" , ( ) => {
165- it ( "should set containerTranslateY in onMove" , ( ) => {
165+ it ( "should set padding in onStart and call scrollTo in onMove" , ( ) => {
166166 const { result } = render ( {
167167 inverted : true ,
168168 keyboardLiftBehavior : "always" ,
169169 } ) ;
170170
171171 handlers . onStart ( { height : KEYBOARD } ) ;
172- handlers . onMove ( { height : 200 } ) ;
172+ expect ( result . current . padding . value ) . toBe ( KEYBOARD ) ;
173173
174- expect ( result . current . containerTranslateY . value ) . toBe ( - 200 ) ;
174+ handlers . onMove ( { height : 200 } ) ;
175+ // target = offsetBeforeScroll(0) + padding(300) - effective(200) = 100
176+ expect ( mockScrollTo ) . toHaveBeenCalledWith ( expect . anything ( ) , 0 , 100 , false ) ;
175177 } ) ;
176178
177- it ( "should update containerTranslateY per-frame" , ( ) => {
178- const { result } = render ( {
179- inverted : true ,
180- keyboardLiftBehavior : "always" ,
181- } ) ;
179+ it ( "should call scrollTo per-frame with correct targets" , ( ) => {
180+ render ( { inverted : true , keyboardLiftBehavior : "always" } ) ;
182181
183182 handlers . onStart ( { height : KEYBOARD } ) ;
184183
185184 handlers . onMove ( { height : 100 } ) ;
186- expect ( result . current . containerTranslateY . value ) . toBe ( - 100 ) ;
185+ // target = 0 + 300 - 100 = 200
186+ expect ( mockScrollTo ) . toHaveBeenLastCalledWith (
187+ expect . anything ( ) ,
188+ 0 ,
189+ 200 ,
190+ false ,
191+ ) ;
187192
188193 handlers . onMove ( { height : 250 } ) ;
189- expect ( result . current . containerTranslateY . value ) . toBe ( - 250 ) ;
190- } ) ;
191-
192- it ( "should NOT call scrollTo for inverted lists" , ( ) => {
193- render ( { inverted : true , keyboardLiftBehavior : "always" } ) ;
194-
195- handlers . onStart ( { height : KEYBOARD } ) ;
196- handlers . onMove ( { height : 200 } ) ;
197-
198- expect ( mockScrollTo ) . not . toHaveBeenCalled ( ) ;
194+ // target = 0 + 300 - 250 = 50
195+ expect ( mockScrollTo ) . toHaveBeenLastCalledWith (
196+ expect . anything ( ) ,
197+ 0 ,
198+ 50 ,
199+ false ,
200+ ) ;
199201 } ) ;
200202
201- it ( "should reset containerTranslateY on keyboard close " , ( ) => {
203+ it ( "should return undefined for contentOffsetY " , ( ) => {
202204 const { result } = render ( {
203205 inverted : true ,
204206 keyboardLiftBehavior : "always" ,
205207 } ) ;
206208
207- handlers . onStart ( { height : KEYBOARD } ) ;
208- handlers . onMove ( { height : KEYBOARD } ) ;
209- handlers . onEnd ( { height : 0 } ) ;
210-
211- expect ( result . current . containerTranslateY . value ) . toBe ( 0 ) ;
212- expect ( result . current . padding . value ) . toBe ( 0 ) ;
213- } ) ;
214- } ) ;
215-
216- describe ( "`useChatKeyboard` — Android behaviors" , ( ) => {
217- it ( "persistent inverted: should NOT reset translateY on close" , ( ) => {
218- const { result } = render ( {
219- inverted : true ,
220- keyboardLiftBehavior : "persistent" ,
221- } ) ;
222-
223- handlers . onStart ( { height : KEYBOARD } ) ;
224- handlers . onMove ( { height : KEYBOARD } ) ;
225- handlers . onEnd ( { height : 0 } ) ;
226-
227- expect ( result . current . containerTranslateY . value ) . toBe ( - KEYBOARD ) ;
209+ expect ( result . current . contentOffsetY ) . toBeUndefined ( ) ;
228210 } ) ;
229211
230- it ( "persistent inverted: should not shrink translateY" , ( ) => {
231- const { result } = render ( {
232- inverted : true ,
233- keyboardLiftBehavior : "persistent" ,
234- } ) ;
212+ it ( "should scroll back on keyboard close" , ( ) => {
213+ render ( { inverted : true , keyboardLiftBehavior : "always" } ) ;
235214
236215 handlers . onStart ( { height : KEYBOARD } ) ;
237216 handlers . onMove ( { height : KEYBOARD } ) ;
238- handlers . onMove ( { height : 200 } ) ;
239-
240- expect ( result . current . containerTranslateY . value ) . toBe ( - KEYBOARD ) ;
241- } ) ;
217+ mockScrollTo . mockClear ( ) ;
242218
243- it ( "never: should not scroll or translate" , ( ) => {
244- mockOffset . value = 100 ;
245- const { result } = render ( {
246- inverted : false ,
247- keyboardLiftBehavior : "never" ,
248- } ) ;
219+ // keyboard closes: offsetBeforeScroll = scroll.value = 0
220+ handlers . onStart ( { height : 0 } ) ;
249221
250- handlers . onStart ( { height : KEYBOARD } ) ;
251- handlers . onMove ( { height : 200 } ) ;
222+ handlers . onMove ( { height : 150 } ) ;
223+ // target = 0 + 300 - 150 = 150
224+ expect ( mockScrollTo ) . toHaveBeenLastCalledWith (
225+ expect . anything ( ) ,
226+ 0 ,
227+ 150 ,
228+ false ,
229+ ) ;
252230
253- expect ( mockScrollTo ) . not . toHaveBeenCalled ( ) ;
254- expect ( result . current . containerTranslateY . value ) . toBe ( 0 ) ;
231+ handlers . onMove ( { height : 0 } ) ;
232+ // target = 0 + 300 - 0 = 300
233+ expect ( mockScrollTo ) . toHaveBeenLastCalledWith (
234+ expect . anything ( ) ,
235+ 0 ,
236+ 300 ,
237+ false ,
238+ ) ;
255239 } ) ;
256240
257- it ( "whenAtEnd: should scroll when at end" , ( ) => {
258- mockOffset . value = 1180 ;
259- render ( { inverted : false , keyboardLiftBehavior : "whenAtEnd" } ) ;
241+ it ( "should preserve user scroll position on close" , ( ) => {
242+ render ( { inverted : true , keyboardLiftBehavior : "always" } ) ;
260243
261244 handlers . onStart ( { height : KEYBOARD } ) ;
262- handlers . onMove ( { height : 200 } ) ;
263-
264- expect ( mockScrollTo ) . toHaveBeenCalled ( ) ;
265- } ) ;
266-
267- it ( "whenAtEnd: should NOT scroll when NOT at end" , ( ) => {
268- mockOffset . value = 100 ;
269- render ( { inverted : false , keyboardLiftBehavior : "whenAtEnd" } ) ;
245+ handlers . onMove ( { height : KEYBOARD } ) ;
246+ mockScrollTo . mockClear ( ) ;
270247
271- handlers . onStart ( { height : KEYBOARD } ) ;
272- handlers . onMove ( { height : 200 } ) ;
248+ // user scrolled to 50 while keyboard open
249+ mockOffset . value = 50 ;
250+ handlers . onStart ( { height : 0 } ) ;
273251
274- expect ( mockScrollTo ) . not . toHaveBeenCalled ( ) ;
252+ handlers . onMove ( { height : 150 } ) ;
253+ // target = 50 + 300 - 150 = 200
254+ expect ( mockScrollTo ) . toHaveBeenLastCalledWith (
255+ expect . anything ( ) ,
256+ 0 ,
257+ 200 ,
258+ false ,
259+ ) ;
275260 } ) ;
276261
277- it ( "persistent non-inverted: should not scroll back on shrink" , ( ) => {
278- mockOffset . value = 100 ;
279- render ( { inverted : false , keyboardLiftBehavior : "persistent" } ) ;
262+ it ( "should finalize padding in onEnd" , ( ) => {
263+ const { result } = render ( {
264+ inverted : true ,
265+ keyboardLiftBehavior : "always" ,
266+ } ) ;
280267
281268 handlers . onStart ( { height : KEYBOARD } ) ;
282- handlers . onMove ( { height : 200 } ) ;
283- expect ( mockScrollTo ) . toHaveBeenCalled ( ) ;
284- mockScrollTo . mockClear ( ) ;
285-
286- mockOffset . value = 300 ;
287- handlers . onMove ( { height : 100 } ) ;
269+ handlers . onEnd ( { height : KEYBOARD } ) ;
270+ expect ( result . current . padding . value ) . toBe ( KEYBOARD ) ;
288271
289- expect ( mockScrollTo ) . not . toHaveBeenCalled ( ) ;
272+ handlers . onEnd ( { height : 0 } ) ;
273+ expect ( result . current . padding . value ) . toBe ( 0 ) ;
290274 } ) ;
291275} ) ;
0 commit comments