Mindinventory / react-native-tabbar-interaction

Tabbar Component For React-Native
https://www.mindinventory.com/react-native-app-development.php
MIT License
818 stars 171 forks source link

Change active tab #39

Closed RedirexStudio closed 2 years ago

RedirexStudio commented 2 years ago

Hello! Thank you a lot for your job! I have one question: How i can change active tab by default? Now default active slide is first, but i want change it on therty

akashmi commented 2 years ago

@redirexStudio current version is not supporting to mark any tab as the default selected tab. we will include your suggestion in our next version. Thanks for using this lib.

akashmi commented 2 years ago

@redirexStudio please try the latest version 2.2.2 for your request. we have added the option to set the default active tab.

RedirexStudio commented 2 years ago

Ooh, Thank you a lot! It's really helped me! You a very responsive team and it's great and i'll suggest your lib to all my friends!

RedirexStudio commented 2 years ago

By the way, if you interesting... I was try to hardcode it :D I had try to change index active tab in this case ))) TabBar.tsx `import as React from "react"; import { SafeAreaView, StyleSheet, Dimensions, View, Animated, Text, TextStyle, } from "react-native"; import as shape from "d3-shape"; import Svg, { Path } from "react-native-svg"; import StaticTabbar from "./StaticTabbar";

const AnimatedSvg = Animated.createAnimatedComponent(Svg); let { width } = Dimensions.get("window");

const height = 65;

const getPath = (tabWidth: number, width: number) => { const left = shape .line() .x((d) => d.x) .y((d) => d.y)([ { x: 0, y: 0 }, { x: width + tabWidth / 2, y: 0 }, ]); const tab = shape .line() .x((d) => d.x) .y((d) => d.y) .curve(shape.curveBasis)([ { x: width + width / 2 - 100, y: 0 }, { x: width + width / 2 - 65 + -35, y: 0 }, { x: width + width / 2 - 50 + 10, y: -6 }, { x: width + width / 2 - 50 + 15, y: height - 14 }, { x: width + width / 2 + 50 - 15, y: height - 14 }, { x: width + width / 2 + 50 - 10, y: -6 }, { x: width + width / 2 + 65 - -35, y: 0 }, { x: width + width / 2 + 100, y: 0 }, ]); const right = shape .line() .x((d) => d.x) .y((d) => d.y)([ { x: width, y: 0 }, { x: width 2, y: 0 }, { x: width 2, y: height }, { x: 0, y: height }, { x: 0, y: 0 }, ]);

return ` ${tab} `; };

export interface TabsType { name: string; title: string; activeIcon: JSX.Element; inactiveIcon: JSX.Element; }

interface Props { tabs: Array; containerTopRightRadius?: number; tabBarBackground: string; tabBarContainerBackground: string; containerBottomSpace?: number; containerWidth?: number; containerTopLeftRadius?: number; containerBottomLeftRadius?: number; containerBottomRightRadius?: number; activeTabBackground?: string; labelStyle?: TextStyle; onTabChange?: (tab: TabsType) => void; }

export default class Tabbar extends React.PureComponent { value = new Animated.Value(2);

render() { const { tabs, containerTopRightRadius, tabBarBackground, tabBarContainerBackground, containerBottomSpace, containerWidth, containerTopLeftRadius, containerBottomLeftRadius, containerBottomRightRadius, } = this.props; let CustomWidth = containerWidth ? containerWidth : width; const { value } = this; const translateX = value.interpolate({ inputRange: [0, CustomWidth], outputRange: [-CustomWidth, 0], }); let tabBarBackgroundColor = tabBarBackground ? tabBarBackground : "transparent"; const tabWidth: number | void | string = tabs.length > 0 // ? CustomWidth / tabs.length ? CustomWidth : console.error("please add tab data"); let d; if (typeof tabWidth == "number") { d = getPath(tabWidth, CustomWidth); }

let borderTopRightRadius = containerTopRightRadius
  ? containerTopRightRadius
  : 0;
let borderTopLeftRadius = containerTopLeftRadius
  ? containerTopLeftRadius
  : 0;
let borderBottomLeftRadius = containerBottomLeftRadius
  ? containerBottomLeftRadius
  : 0;
let borderBottomRightRadius = containerBottomRightRadius
  ? containerBottomRightRadius
  : 0;
if (tabs.length > 0) {
  return (
    <>
      <View
        style={{
          backgroundColor: tabBarContainerBackground
            ? tabBarContainerBackground
            : "#fff",
          position: "absolute",
          bottom: containerBottomSpace ? containerBottomSpace : 0,
          alignSelf: "center",
          borderTopRightRadius,
          borderTopLeftRadius,
          borderBottomLeftRadius,
          borderBottomRightRadius,
        }}
      >
        <View
          {...{
            height,
            width: CustomWidth,
            backgroundColor: tabBarContainerBackground
              ? tabBarContainerBackground
              : "#fff",
            alignSelf: "center",
            borderTopRightRadius,
            borderTopLeftRadius,
            borderBottomLeftRadius,
            borderBottomRightRadius,
          }}
        >
          <AnimatedSvg
            width={CustomWidth * 2}
            {...{ height }}
            style={{
              transform: [{ translateX }],
              justifyContent: "center",
              alignItems: "center",
            }}
          >
            <Path fill={tabBarBackgroundColor} {...{ d }} />
          </AnimatedSvg>
          <View style={StyleSheet.absoluteFill}>
            <StaticTabbar {...this.props} {...{ tabs, value }} />
          </View>
        </View>
        <SafeAreaView
          style={{
            alignSelf: "center",
            borderBottomLeftRadius,
            borderBottomRightRadius,
          }}
        />
      </View>
    </>
  );
} else {
  return (
    <View style={styles.emptyContainer}>
      <Text>Please add tab data</Text>
    </View>
  );
}

} }

const styles = StyleSheet.create({ container: { width: width, }, emptyContainer: { flex: 1, justifyContent: "center", alignItems: "center" }, }); `

StaticTabbar.tsx `import * as React from "react"; import { View, StyleSheet, TouchableWithoutFeedback, Animated, Dimensions, Text, TextStyle, } from "react-native";

import { TabsType } from "./TabBar"; let { width } = Dimensions.get("window"); var prevIndex = -1;

interface Props { value?: Animated.AnimatedValue; tabs: Array; onTabChange?: (tab: TabsType) => void; labelStyle?: TextStyle; activeTabBackground?: string; Hvalue?: number; containerWidth?: number; }

export default class StaticTabbar extends React.PureComponent { values: Array; constructor(props: Props) { super(props); const { tabs } = this.props; this.values = tabs?.map( (tab, index) => new Animated.Value(index === 2 ? 2 : 0) ); }

onPress = (index: number) => { if (prevIndex !== index) { const { value, tabs, containerWidth } = this.props; let customWidth = containerWidth ? containerWidth : width; const tabWidth = customWidth / tabs.length; Animated.sequence([ Animated.parallel( this.values.map( (v: Animated.AnimatedValue | Animated.AnimatedValueXY) => Animated.timing(v, { toValue: 0, duration: 50, useNativeDriver: true, }) ) ), Animated.timing(value, { toValue: tabWidth * (index-2), useNativeDriver: true, }), Animated.timing(this.values[index], { toValue: 1, useNativeDriver: true, duration: 750, }), ]).start(); prevIndex = index; } };

render() { const { onPress } = this; const { tabs, value, activeTabBackground, labelStyle, onTabChange, containerWidth, } = this.props; let customWidth = containerWidth ? containerWidth : width; let mergeLabelStyle = { ...styles.labelStyle, ...labelStyle }; let newActiveIcon = [ styles.activeIcon, { backgroundColor: activeTabBackground ? activeTabBackground : "#fff" }, ]; return (

{tabs.map((tab, key) => { const tabWidth = customWidth / tabs.length; const cursor = tabWidth * (key-2); const opacity = value.interpolate({ inputRange: [cursor - tabWidth, cursor, cursor + tabWidth], outputRange: [1, 0, 1], extrapolate: "clamp", }); const opacity1 = this.values[key].interpolate({ inputRange: [0, 1], outputRange: [0, 1], extrapolate: "clamp", }); return ( { onPress(key); onTabChange && onTabChange(tab); }} > {tab.inactiveIcon} {tab.title} {tab.activeIcon} ); })}
);

} }

const styles = StyleSheet.create({ container: { flexDirection: "row", }, tab: { flex: 1, justifyContent: "center", alignItems: "center", height: 64, }, activeIcon: { width: 60, height: 60, borderRadius: 50, marginBottom: 30, justifyContent: "center", alignItems: "center", }, labelStyle: { fontSize: 11, fontWeight: "600", // marginTop: 3, color: "#000", }, }); `