From e4aa00e1405aa28d173d21d7c19e22a1a519e404 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Sun, 1 Dec 2024 18:53:44 +0000 Subject: [PATCH] Divide free space proportionally --- src/view/com/pager/TabBar.tsx | 37 +++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/view/com/pager/TabBar.tsx b/src/view/com/pager/TabBar.tsx index 171a0c2217..b0f8744627 100644 --- a/src/view/com/pager/TabBar.tsx +++ b/src/view/com/pager/TabBar.tsx @@ -59,14 +59,43 @@ export function TabBar({ [scrollElRef], ) + const indexToOffset = useCallback( + (index: number) => { + 'worklet' + const layout = layouts.get()[index] + const availableSize = containerSize.get() - 2 * CONTENT_PADDING + if (!layout) { + const offsetPerPage = contentSize.get() - availableSize + return (index / (itemsLength - 1)) * offsetPerPage + } + const freeSpace = availableSize - layout.width + const accumulatingOffset = interpolate( + index, + // Gradually shift every next item to the left so that the first item + // is positioned like "left: 0" but the last item is like "right: 0". + [0, itemsLength - 1], + [0, freeSpace], + 'clamp', + ) + return layout.x - accumulatingOffset + }, + [itemsLength, contentSize, containerSize, layouts], + ) + const progressToOffset = useCallback( (progress: number) => { 'worklet' - const offsetPerPage = - contentSize.get() + 2 * CONTENT_PADDING - containerSize.get() - return (progress / (itemsLength - 1)) * offsetPerPage + return interpolate( + progress, + [Math.floor(progress), Math.ceil(progress)], + [ + indexToOffset(Math.floor(progress)), + indexToOffset(Math.ceil(progress)), + ], + 'clamp', + ) }, - [itemsLength, contentSize, containerSize], + [indexToOffset], ) // When we know the entire layout for the first time, scroll selection into view.