react-native-curved-bottom-bar
Version:
A high performance, beautiful and fully customizable curved bottom navigation bar for React Native.
201 lines • 9.07 kB
JavaScript
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
/* eslint-disable @typescript-eslint/no-shadow */
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import React, { useCallback, useEffect, useImperativeHandle, useMemo, useState } from 'react';
import { Dimensions, I18nManager, Text, TouchableOpacity, View } from 'react-native';
import { scale } from 'react-native-size-scaling';
import { useDeviceOrientation } from '../../../useDeviceOrientation';
import { getPathDown } from '../../utils/pathDown';
import { getPathUp } from '../../utils/pathUp';
import { CurvedViewComponent } from '../CurvedView/curvedView';
import { styles } from './styles';
const {
width: maxW
} = Dimensions.get('window');
const Tab = createBottomTabNavigator();
const BottomBarComponent = /*#__PURE__*/React.forwardRef((props, ref) => {
const {
type = 'DOWN',
circlePosition = 'CENTER',
style,
width = null,
height = 65,
circleWidth = 50,
bgColor = 'gray',
initialRouteName,
tabBar,
renderCircle,
borderTopLeftRight = false,
shadowStyle,
borderColor = 'gray',
borderWidth = 0
} = props;
const [itemLeft, setItemLeft] = useState([]);
const [itemRight, setItemRight] = useState([]);
const [maxWidth, setMaxWidth] = useState(width || maxW);
const [isShow, setIsShow] = useState(true);
const children = props === null || props === void 0 ? void 0 : props.children;
const orientation = useDeviceOrientation();
useImperativeHandle(ref, () => {
return {
setVisible
};
});
const setVisible = visible => {
setIsShow(visible);
};
useEffect(() => {
const {
width: w
} = Dimensions.get('window');
if (!width) {
setMaxWidth(w);
}
}, [orientation, width]);
const _renderButtonCenter = useCallback((focusedTab, navigate) => {
var _children$filter$, _children$filter$$pro;
const getTab = (_children$filter$ = children.filter(e => {
var _e$props, _e$props2;
return (e === null || e === void 0 ? void 0 : (_e$props = e.props) === null || _e$props === void 0 ? void 0 : _e$props.position) === 'CIRCLE' || (e === null || e === void 0 ? void 0 : (_e$props2 = e.props) === null || _e$props2 === void 0 ? void 0 : _e$props2.position) === 'CENTER';
})[0]) === null || _children$filter$ === void 0 ? void 0 : (_children$filter$$pro = _children$filter$.props) === null || _children$filter$$pro === void 0 ? void 0 : _children$filter$$pro.name;
return renderCircle({
routeName: getTab,
selectedTab: focusedTab,
navigate: selectTab => {
if (selectTab) {
navigate(selectTab);
}
}
});
}, [children, renderCircle]);
useEffect(() => {
const arrLeft = children.filter(item => {
var _item$props;
return (item === null || item === void 0 ? void 0 : (_item$props = item.props) === null || _item$props === void 0 ? void 0 : _item$props.position) === 'LEFT';
});
const arrRight = children.filter(item => {
var _item$props2;
return (item === null || item === void 0 ? void 0 : (_item$props2 = item.props) === null || _item$props2 === void 0 ? void 0 : _item$props2.position) === 'RIGHT';
});
setItemLeft(arrLeft);
setItemRight(arrRight);
}, [children, initialRouteName]);
const getCircleWidth = useMemo(() => {
return circleWidth < 50 ? 50 : circleWidth > 60 ? 60 : circleWidth;
}, [circleWidth]);
const getTabbarHeight = useMemo(() => {
return height < 50 ? 50 : height > 90 ? 90 : height;
}, [height]);
const d = useMemo(() => {
return type === 'DOWN' ? getPathDown(maxWidth, getTabbarHeight, getCircleWidth, borderTopLeftRight, !I18nManager.isRTL ? circlePosition : circlePosition === 'LEFT' ? 'RIGHT' : circlePosition === 'RIGHT' ? 'LEFT' : 'CENTER') : getPathUp(maxWidth, getTabbarHeight + 30, getCircleWidth, borderTopLeftRight, !I18nManager.isRTL ? circlePosition : circlePosition === 'LEFT' ? 'RIGHT' : circlePosition === 'RIGHT' ? 'LEFT' : 'CENTER');
}, [borderTopLeftRight, circlePosition, getCircleWidth, getTabbarHeight, maxWidth, type]);
const renderItem = _ref => {
let {
color,
routeName,
navigate
} = _ref;
return /*#__PURE__*/React.createElement(TouchableOpacity, {
key: routeName,
style: styles.itemTab,
onPress: () => navigate(routeName)
}, /*#__PURE__*/React.createElement(Text, {
style: {
color: color
}
}, routeName));
};
const _renderTabIcon = useCallback((arr, focusedTab, navigation) => {
return /*#__PURE__*/React.createElement(View, {
style: [styles.rowLeft, {
height: scale(getTabbarHeight)
}]
}, arr.map((item, index) => {
var _item$props3;
const routeName = item === null || item === void 0 ? void 0 : (_item$props3 = item.props) === null || _item$props3 === void 0 ? void 0 : _item$props3.name;
if (tabBar === undefined) {
return renderItem({
routeName,
color: focusedTab === routeName ? 'blue' : 'gray',
navigate: navigation.navigate
});
}
return /*#__PURE__*/React.createElement(View, {
style: styles.flex1,
key: index.toString()
}, tabBar({
routeName,
selectedTab: focusedTab,
navigate: selectTab => {
if (selectTab !== focusedTab) {
navigation.navigate({
name: routeName,
merge: true
});
}
}
}));
}));
}, [getTabbarHeight, tabBar]);
const renderPosition = useCallback(props => {
const {
state,
navigation
} = props;
const focusedTab = state === null || state === void 0 ? void 0 : state.routes[state.index].name;
if (circlePosition === 'LEFT') {
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(View, {
style: {
marginLeft: scale(getCircleWidth) / 2
}
}, _renderButtonCenter(focusedTab, navigation.navigate)), _renderTabIcon([...itemLeft, ...itemRight], focusedTab, navigation));
}
if (circlePosition === 'RIGHT') {
return /*#__PURE__*/React.createElement(React.Fragment, null, _renderTabIcon([...itemLeft, ...itemRight], focusedTab, navigation), /*#__PURE__*/React.createElement(View, {
style: {
marginRight: scale(getCircleWidth) / 2
}
}, _renderButtonCenter(focusedTab, navigation.navigate)));
}
return /*#__PURE__*/React.createElement(React.Fragment, null, _renderTabIcon(itemLeft, focusedTab, navigation), _renderButtonCenter(focusedTab, navigation.navigate), _renderTabIcon(itemRight, focusedTab, navigation));
}, [_renderButtonCenter, _renderTabIcon, circlePosition, getCircleWidth, itemLeft, itemRight]);
const _renderTabContainer = useCallback(props => {
return /*#__PURE__*/React.createElement(View, {
style: [styles.main, {
width: maxWidth
}, type === 'UP' && styles.top30]
}, renderPosition(props));
}, [maxWidth, renderPosition, type]);
const MyTabBar = useCallback(props => {
if (!isShow) {
return null;
}
return /*#__PURE__*/React.createElement(View, {
style: [styles.container, style]
}, /*#__PURE__*/React.createElement(CurvedViewComponent, {
style: shadowStyle,
width: maxWidth,
height: scale(getTabbarHeight) + (type === 'DOWN' ? 0 : scale(30)),
bgColor: bgColor,
path: d,
borderColor: borderColor,
borderWidth: borderWidth
}), _renderTabContainer(props));
}, [_renderTabContainer, bgColor, d, getTabbarHeight, isShow, maxWidth, shadowStyle, style, type, borderColor, borderWidth]);
const main = useMemo(() => {
return /*#__PURE__*/React.createElement(Tab.Navigator, _extends({}, props, {
tabBar: MyTabBar
}), children === null || children === void 0 ? void 0 : children.map(e => {
var _e$props3, _e$props4, _e$props5, _e$props6;
const Component = e === null || e === void 0 ? void 0 : (_e$props3 = e.props) === null || _e$props3 === void 0 ? void 0 : _e$props3.component;
return /*#__PURE__*/React.createElement(Tab.Screen, {
options: e === null || e === void 0 ? void 0 : (_e$props4 = e.props) === null || _e$props4 === void 0 ? void 0 : _e$props4.options,
key: e === null || e === void 0 ? void 0 : (_e$props5 = e.props) === null || _e$props5 === void 0 ? void 0 : _e$props5.name,
name: e === null || e === void 0 ? void 0 : (_e$props6 = e.props) === null || _e$props6 === void 0 ? void 0 : _e$props6.name
}, props => /*#__PURE__*/React.createElement(Component, props));
}));
}, [MyTabBar, children, props]);
return main;
});
export default BottomBarComponent;
//# sourceMappingURL=index.js.map