Skip to content
This repository has been archived by the owner on Nov 27, 2022. It is now read-only.

Commit

Permalink
fix: fix scrollable tabs before layout if no tab width was provided
Browse files Browse the repository at this point in the history
If a `width` wasn't provided for tabs and `scrollEnabled` was set to `true`, we needed to wait for layout to render them.
This commit makes sure we render the tabs properly before layout fires.

Closes #805
  • Loading branch information
satya164 committed Jul 5, 2019
1 parent 97649c6 commit afbd348
Show file tree
Hide file tree
Showing 5 changed files with 13 additions and 26 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,8 @@ Opacity for pressed tab (iOS and Android < 5.0 only).

Boolean indicating whether to enable scrollable tabs.

If you set `scrollEnabled` to `true`, you should also specify a `width` in `tabStyle` to improve the initial render.

##### `bounces`

Boolean indicating whether the tab bar bounces when scrolling.
Expand Down
2 changes: 1 addition & 1 deletion example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export default class ExampleList extends React.Component<any, State> {

if (
Number.isFinite(savedIndex) &&
savedIndex > 0 &&
savedIndex >= 0 &&
savedIndex < EXAMPLE_COMPONENTS.length
) {
this.setState({
Expand Down
11 changes: 5 additions & 6 deletions src/TabBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,8 @@ export default class TabBar<T extends Route> extends React.Component<
pointerEvents="none"
style={[
styles.indicatorContainer,
scrollEnabled
? { width: tabBarWidth, transform: [{ translateX }] as any }
: null,
scrollEnabled ? { transform: [{ translateX }] as any } : null,
tabBarWidth ? { width: tabBarWidth } : null,
]}
>
{this.props.renderIndicator({
Expand All @@ -272,7 +271,9 @@ export default class TabBar<T extends Route> extends React.Component<
overScrollMode="never"
contentContainerStyle={[
styles.tabContent,
scrollEnabled ? null : styles.container,
scrollEnabled
? { width: tabBarWidth || `${routes.length * 40}%` }
: styles.container,
contentContainerStyle,
]}
scrollEventThrottle={16}
Expand All @@ -296,9 +297,7 @@ export default class TabBar<T extends Route> extends React.Component<
key={route.key}
position={position}
route={route}
tabWidth={tabWidth}
navigationState={navigationState}
scrollEnabled={scrollEnabled}
getAccessibilityLabel={getAccessibilityLabel}
getAccessible={getAccessible}
getLabelText={getLabelText}
Expand Down
4 changes: 2 additions & 2 deletions src/TabBarIndicator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default class TabBarIndicator<T extends Route> extends React.Component<
);

render() {
const { width, position, navigationState, style } = this.props;
const { layout, width, position, navigationState, style } = this.props;
const { routes } = navigationState;

const translateX = this.getTranslateX(position, routes, width);
Expand All @@ -37,7 +37,7 @@ export default class TabBarIndicator<T extends Route> extends React.Component<
{ width: `${100 / routes.length}%` },
// If layout is not available, use `left` property for positioning the indicator
// This avoids rendering delay until we are able to calculate translateX
width
layout.width
? { transform: [{ translateX }] as any }
: { left: `${(100 / routes.length) * navigationState.index}%` },
style,
Expand Down
20 changes: 3 additions & 17 deletions src/TabBarItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ type Props<T extends Route> = {
position: Animated.Node<number>;
route: T;
navigationState: NavigationState<T>;
scrollEnabled?: boolean;
activeColor?: string;
inactiveColor?: string;
pressColor?: string;
Expand All @@ -37,7 +36,6 @@ type Props<T extends Route> = {
renderBadge?: (scene: Scene<T>) => React.ReactNode;
onPress: () => void;
onLongPress: () => void;
tabWidth: number;
labelStyle?: StyleProp<TextStyle>;
style: StyleProp<ViewStyle>;
};
Expand Down Expand Up @@ -81,7 +79,6 @@ export default class TabBarItem<T extends Route> extends React.Component<
route,
position,
navigationState,
scrollEnabled,
renderLabel: renderLabelPassed,
renderIcon,
renderBadge,
Expand All @@ -95,7 +92,6 @@ export default class TabBarItem<T extends Route> extends React.Component<
pressOpacity,
labelStyle,
style,
tabWidth,
onPress,
onLongPress,
} = this.props;
Expand Down Expand Up @@ -197,18 +193,8 @@ export default class TabBarItem<T extends Route> extends React.Component<
}

const tabStyle = StyleSheet.flatten(style);
const isWidthSet =
(tabStyle && typeof tabStyle.width !== 'undefined') ||
scrollEnabled === true;

const tabContainerStyle: ViewStyle = {};
const itemStyle = isWidthSet ? { width: tabWidth } : null;

if (tabStyle && typeof tabStyle.flex === 'number') {
tabContainerStyle.flex = tabStyle.flex;
} else if (!isWidthSet) {
tabContainerStyle.flex = 1;
}
const isWidthSet = tabStyle && tabStyle.width !== undefined;
const tabContainerStyle: ViewStyle | null = isWidthSet ? null : { flex: 1 };

const scene = { route };

Expand Down Expand Up @@ -238,7 +224,7 @@ export default class TabBarItem<T extends Route> extends React.Component<
onLongPress={onLongPress}
style={tabContainerStyle}
>
<View pointerEvents="none" style={[styles.item, itemStyle, tabStyle]}>
<View pointerEvents="none" style={[styles.item, tabStyle]}>
{icon}
{label}
{badge != null ? <View style={styles.badge}>{badge}</View> : null}
Expand Down

0 comments on commit afbd348

Please sign in to comment.