Skip to content

Commit

Permalink
feat: dynamic tabbar
Browse files Browse the repository at this point in the history
  • Loading branch information
andreialecu committed Feb 5, 2021
1 parent eeb94cc commit f4ebdfe
Showing 1 changed file with 34 additions and 12 deletions.
46 changes: 34 additions & 12 deletions src/MaterialTabBar/TabBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,15 @@ const TabBar = <T extends TabName = any>({
const tabBarRef = useAnimatedRef<Animated.ScrollView>()
const windowWidth = useWindowDimensions().width
const isFirstRender = React.useRef(true)
const [nTabs] = React.useState(tabNames.length)
const itemsLayoutGathering = React.useRef<ItemLayout[]>([])
const [itemsLayoutGathering, setItemsLayoutGathering] = React.useState(
new Map<T, ItemLayout>()
)
const tabsOffset = useSharedValue(0)
const isScrolling = useSharedValue(false)

const nTabs = tabNames.length

console.log(tabNames)
const [itemsLayout, setItemsLayout] = React.useState<ItemLayout[]>(
scrollEnabled
? []
Expand All @@ -110,21 +114,34 @@ const TabBar = <T extends TabName = any>({
}, [scrollEnabled, nTabs, tabNames, windowWidth])

const onTabItemLayout = React.useCallback(
(event: LayoutChangeEvent) => {
if (scrollEnabled && itemsLayout.length < nTabs) {
(event: LayoutChangeEvent, name: T) => {
if (scrollEnabled) {
if (!event.nativeEvent?.layout) return
const { width, x } = event.nativeEvent.layout
itemsLayoutGathering.current.push({
width,
x,
setItemsLayoutGathering((itemsLayoutGathering) => {
const update = new Map(itemsLayoutGathering)
return update.set(name, {
width,
x,
})
})
if (itemsLayoutGathering.current.length === nTabs) {
setItemsLayout(itemsLayoutGathering.current.sort((a, b) => a.x - b.x))
}
}
},
[scrollEnabled, itemsLayout.length, nTabs]
[scrollEnabled]
)

React.useEffect(() => {
// pick out the layouts for the tabs we know about (in case they changed dynamically)
const layout = [...itemsLayoutGathering.entries()]
.filter(([tabName]) => tabNames.includes(tabName))
.map(([, layout]) => layout)
.sort((a, b) => a.x - b.x)

if (layout.length === tabNames.length) {
setItemsLayout(layout)
}
}, [itemsLayoutGathering, tabNames])

const cancelNextScrollSync = useSharedValue(index.value)

const onScroll = useAnimatedScrollHandler(
Expand Down Expand Up @@ -207,7 +224,11 @@ const TabBar = <T extends TabName = any>({
name={name}
label={tabProps.get(name)?.label || getLabelText(name)}
onPress={onTabPress}
onLayout={scrollEnabled ? onTabItemLayout : undefined}
onLayout={
scrollEnabled
? (event) => onTabItemLayout(event, name)
: undefined
}
scrollEnabled={scrollEnabled}
indexDecimal={indexDecimal}
labelStyle={labelStyle}
Expand Down Expand Up @@ -239,3 +260,4 @@ const styles = StyleSheet.create({
export { TabBar as MaterialTabBar }

export default TabBar

0 comments on commit f4ebdfe

Please sign in to comment.