react-native-safe-area-context#useSafeAreaFrame TypeScript Examples

The following examples show how to use react-native-safe-area-context#useSafeAreaFrame. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: CurvedTabBar.tsx    From curved-bottom-navigation-bar with MIT License 4 votes vote down vote up
CurvedTabBarComponent = (props: TabBarViewProps) => {
  // props
  const {
    routes,
    selectedIndex,
    barWidth,
    duration,
    dotColor,
    tabBarColor,
    titleShown,
    isRtl,
    navigationIndex,
    dotSize: SIZE_DOT,
    barHeight = TAB_BAR_HEIGHT,
  } = props;
  // state
  const {bottom} = useSafeAreaInsets();
  const {width} = useSafeAreaFrame();
  const actualBarWidth = useMemo<number>(
    () => barWidth || width,
    [barWidth, width],
  );
  const widthTab = useMemo(
    () => actualBarWidth / routes.length,
    [routes, actualBarWidth],
  );
  const inputRange = useMemo(
    () =>
      isRtl
        ? routes.map((_: any, index: number) => index).reverse()
        : routes.map((_: any, index: number) => index),
    [isRtl, routes],
  );

  const outputRange = useMemo(
    () =>
      routes.map(
        (_: any, index: number) => (index / routes.length) * actualBarWidth,
      ),
    [routes, actualBarWidth],
  );
  const actualBarHeight = useMemo<number>(
    () => barHeight + bottom,
    [barHeight, bottom],
  );
  const indexAnimated = useDerivedValue(() =>
    sharedTiming(selectedIndex.value, {duration}),
  );

  // func
  const renderButtonTab = useCallback(
    ({key, title, ...configs}: TabRoute, index: number) => {
      return (
        <ButtonTab
          focused={index === selectedIndex.value}
          width={actualBarWidth}
          key={key}
          title={title}
          titleShown={titleShown}
          indexAnimated={indexAnimated}
          countTab={routes.length}
          selectedIndex={selectedIndex}
          index={index}
          {...configs}
        />
      );
    },
    [indexAnimated, routes.length, selectedIndex, titleShown, actualBarWidth],
  );

  // reanimated

  const progress = withSharedTransition(sharedEq(selectedIndex, indexAnimated));

  const xPath = useInterpolate(indexAnimated, inputRange, outputRange);

  // path
  const pathProps = useAnimatedProps<PathProps>(() => {
    const centerHoleX = xPath.value + widthTab / 2;
    return {
      d: `M0,0 L${centerHoleX - SIZE_DOT},0
      C${centerHoleX - SIZE_DOT * 0.5},0 ${
        centerHoleX - SIZE_DOT * 0.75
      },${HEIGHT_HOLE} ${centerHoleX},${HEIGHT_HOLE} 
      C${centerHoleX + SIZE_DOT * 0.75},${HEIGHT_HOLE} ${
        centerHoleX + SIZE_DOT * 0.5
      },0 ${centerHoleX + SIZE_DOT} 0 
      L${actualBarWidth * 2},0 L ${
        actualBarWidth * 2
      },${actualBarHeight} L 0,${actualBarHeight} Z
      `,
    };
  }, [actualBarWidth, widthTab, SIZE_DOT, actualBarHeight]);

  // style
  const containerStyle = useMemo<StyleProp<ViewStyle>>(
    () => [
      {
        height: actualBarHeight,
        width: actualBarWidth,
      },
    ],
    [actualBarHeight, actualBarWidth],
  );
  const rowTab = useMemo<StyleProp<ViewStyle>>(
    () => [
      {
        width: actualBarWidth,
        height: actualBarHeight,
      },
    ],
    [actualBarHeight, actualBarWidth],
  );

  return (
    <>
      <RNShadow style={[styles.container, containerStyle]}>
        <Svg
          width={actualBarWidth}
          height={actualBarHeight}
          style={[styles.svg]}>
          <AnimatedPath
            animatedProps={pathProps}
            translateY={3}
            fill={tabBarColor}
            stroke={'transparent'}
            strokeWidth={0}
          />
        </Svg>
      </RNShadow>
      <View style={[styles.rowTab, rowTab]}>
        <Dot
          navigationIndex={navigationIndex}
          isRtl={isRtl}
          dotColor={dotColor}
          dotSize={SIZE_DOT}
          barHeight={actualBarHeight}
          width={actualBarWidth}
          selectedIndex={indexAnimated}
          routes={routes}
          progress={progress}
        />
        {routes.map(renderButtonTab)}
      </View>
    </>
  );
}
Example #2
Source File: CurvedTabBar.tsx    From curved-bottom-navigation-bar with MIT License 4 votes vote down vote up
CurvedTabBarComponent = (props: TabBarViewProps) => {
  // props
  const {
    routes,
    selectedIndex,
    barWidth,
    duration,
    dotColor,
    tabBarColor,
    titleShown,
    isRtl,
    navigationIndex,
    dotSize: SIZE_DOT,
    barHeight = TAB_BAR_HEIGHT,
  } = props;
  // state
  const { bottom } = useSafeAreaInsets();
  const { width } = useSafeAreaFrame();
  const actualBarWidth = useMemo<number>(
    () => barWidth || width,
    [barWidth, width]
  );
  const widthTab = useMemo(
    () => actualBarWidth / routes.length,
    [routes, actualBarWidth]
  );
  const inputRange = useMemo(
    () =>
      isRtl
        ? routes.map((_: any, index: number) => index).reverse()
        : routes.map((_: any, index: number) => index),
    [isRtl, routes]
  );

  const outputRange = useMemo(
    () =>
      routes.map(
        (_: any, index: number) => (index / routes.length) * actualBarWidth
      ),
    [routes, actualBarWidth]
  );
  const actualBarHeight = useMemo<number>(
    () => barHeight + bottom,
    [barHeight, bottom]
  );
  const indexAnimated = useDerivedValue(() =>
    sharedTiming(selectedIndex.value, { duration })
  );

  // func
  const renderButtonTab = useCallback(
    ({ key, title, ...configs }: TabRoute, index: number) => {
      return (
        <ButtonTab
          focused={index === selectedIndex.value}
          width={actualBarWidth}
          key={key}
          title={title}
          titleShown={titleShown}
          indexAnimated={indexAnimated}
          countTab={routes.length}
          selectedIndex={selectedIndex}
          index={index}
          {...configs}
        />
      );
    },
    [indexAnimated, routes.length, selectedIndex, titleShown, actualBarWidth]
  );

  // reanimated

  const progress = withSharedTransition(sharedEq(selectedIndex, indexAnimated));

  const xPath = useInterpolate(indexAnimated, inputRange, outputRange);

  // path
  const pathProps = useAnimatedProps<PathProps>(() => {
    const centerHoleX = xPath.value + widthTab / 2;
    return {
      d: `M0,0 L${centerHoleX - SIZE_DOT},0
      C${centerHoleX - SIZE_DOT * 0.5},0 ${
        centerHoleX - SIZE_DOT * 0.75
      },${HEIGHT_HOLE} ${centerHoleX},${HEIGHT_HOLE} 
      C${centerHoleX + SIZE_DOT * 0.75},${HEIGHT_HOLE} ${
        centerHoleX + SIZE_DOT * 0.5
      },0 ${centerHoleX + SIZE_DOT} 0 
      L${actualBarWidth * 2},0 L ${
        actualBarWidth * 2
      },${actualBarHeight} L 0,${actualBarHeight} Z
      `,
    };
  }, [actualBarWidth, widthTab, SIZE_DOT, actualBarHeight]);

  // style
  const containerStyle = useMemo<StyleProp<ViewStyle>>(
    () => [
      {
        height: actualBarHeight,
        width: actualBarWidth,
      },
    ],
    [actualBarHeight, actualBarWidth]
  );
  const rowTab = useMemo<StyleProp<ViewStyle>>(
    () => [
      {
        width: actualBarWidth,
        height: actualBarHeight,
      },
    ],
    [actualBarHeight, actualBarWidth]
  );

  return (
    <>
      <RNShadow style={[styles.container, containerStyle]}>
        <Svg
          width={actualBarWidth}
          height={actualBarHeight}
          style={[styles.svg]}
        >
          <AnimatedPath
            animatedProps={pathProps}
            translateY={3}
            fill={tabBarColor}
            stroke={'transparent'}
            strokeWidth={0}
          />
        </Svg>
      </RNShadow>
      <View style={[styles.rowTab, rowTab]}>
        <Dot
          navigationIndex={navigationIndex}
          isRtl={isRtl}
          dotColor={dotColor}
          dotSize={SIZE_DOT}
          barHeight={actualBarHeight}
          width={actualBarWidth}
          selectedIndex={indexAnimated}
          routes={routes}
          progress={progress}
        />
        {routes.map(renderButtonTab)}
      </View>
    </>
  );
}