rn-bottom-menu
Version:
React Native custom bottom menu
185 lines (184 loc) • 8.72 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.BottomMenuBar = exports.defaultSpringConfig = void 0;
var react_1 = __importStar(require("react"));
var react_native_1 = require("react-native");
var react_native_reanimated_1 = __importStar(require("react-native-reanimated"));
var react_native_safe_area_context_1 = require("react-native-safe-area-context");
var react_native_svg_1 = require("react-native-svg");
var BottomMenu_styles_1 = require("./BottomMenu.styles");
var BottomMenu_bar_button_1 = __importStar(require("./BottomMenu.bar.button"));
var BottomMenu_shape_1 = require("./BottomMenu.shape");
var ReanimatedSvg = react_native_reanimated_1.default.createAnimatedComponent(react_native_svg_1.Svg);
var tabWidth = 110;
exports.defaultSpringConfig = {
damping: 30,
mass: 0.7,
stiffness: 250,
};
var BottomMenuBar = function (_a) {
var state = _a.state, descriptors = _a.descriptors, navigation = _a.navigation, springConfig = _a.springConfig, bottomBarContainerStyle = _a.bottomBarContainerStyle, focusedButtonStyle = _a.focusedButtonStyle, _b = _a.mode, mode = _b === void 0 ? 'default' : _b, _c = _a.isRtl, isRtl = _c === void 0 ? false : _c;
var currentDescriptor = descriptors[state.routes[state.index].key];
var _d = (0, react_1.useState)({
width: react_native_1.Dimensions.get('window').width,
height: react_native_1.Dimensions.get('window').height,
}), _e = _d[0], width = _e.width, height = _e.height, setDimensions = _d[1];
var bottom = (0, react_native_safe_area_context_1.useSafeAreaInsets)().bottom;
var d = (0, BottomMenu_shape_1.getBottomMenuShape)(width, height, tabWidth, BottomMenu_styles_1.TAB_BAR_HEIGHT - 21.5);
var tabsWidthValue = react_1.default.useMemo(function () { return width / state.routes.length; }, [width, state.routes]);
var tabsRealWidth = width / state.routes.length;
var initialPosition = isRtl
? -width + tabsWidthValue * (state.routes.length - 1 - state.index)
: -width + tabsWidthValue * state.index;
var animatedValueLength = (0, react_native_reanimated_1.useSharedValue)(initialPosition);
var offset = tabsRealWidth < tabWidth
? tabWidth - tabsRealWidth
: (tabsRealWidth - tabWidth) * -1;
(0, react_1.useEffect)(function () {
animatedValueLength.value = initialPosition;
}, [isRtl]);
var animatedStyles = (0, react_native_reanimated_1.useAnimatedStyle)(function () {
return {
transform: [{ translateX: animatedValueLength.value }],
};
});
(0, react_1.useEffect)(function () {
animatedValueLength.value = (0, react_native_reanimated_1.withSpring)(initialPosition - offset / 2,
// @ts-ignore
springConfig || exports.defaultSpringConfig);
}, [
width,
height,
state,
tabsWidthValue,
offset,
animatedValueLength,
springConfig,
initialPosition,
]);
var animationValueThreshold = (0, react_native_reanimated_1.useSharedValue)(0);
(0, react_1.useEffect)(function () {
animationValueThreshold.value = (0, react_native_reanimated_1.withSpring)(state.index,
// @ts-ignore
springConfig || exports.defaultSpringConfig);
}, [animationValueThreshold, state.index, springConfig]);
// @ts-ignore
return (<react_native_1.View onLayout={function (_a) {
var _b = _a.nativeEvent.layout, lHeight = _b.height, lWidth = _b.width;
setDimensions({ width: lWidth, height: lHeight });
}} style={[
BottomMenu_styles_1.style.container,
{
marginBottom: bottom,
height: BottomMenu_styles_1.TAB_BAR_HEIGHT,
flexDirection: isRtl ? 'row-reverse' : 'row',
},
bottomBarContainerStyle,
currentDescriptor.options.tabBarStyle,
]}>
{bottom > 0 && (<react_native_1.View style={[
{
height: bottom,
backgroundColor: Object.values(descriptors)[state.index].options
.tabBarActiveBackgroundColor,
bottom: bottom * -1,
},
BottomMenu_styles_1.style.bottomFill,
]}/>)}
<react_native_1.View style={[
BottomMenu_styles_1.style.fabButtonsContainer,
{
flexDirection: isRtl ? 'row-reverse' : 'row',
},
]}>
{state.routes.map(function (route, index) {
var options = descriptors[route.key].options;
var isFocused = state.index === index;
var onPress = function () {
var event = navigation.emit({
type: 'tabPress',
target: route.key,
canPreventDefault: true,
});
if (!isFocused && !event.defaultPrevented) {
navigation.navigate(route.name);
}
};
var onLongPress = function () {
navigation.emit({
type: 'tabLongPress',
target: route.key,
});
};
return (<BottomMenu_bar_button_1.default mode={mode} key={route.key} options={options} onPress={onPress} onLongPress={onLongPress} focusedButtonStyle={focusedButtonStyle} index={index} isFocused={isFocused} activeTintColor={options.tabBarActiveTintColor} inactiveTintColor={options.tabBarInactiveTintColor}/>);
})}
</react_native_1.View>
<react_native_1.View style={[react_native_1.StyleSheet.absoluteFill, BottomMenu_styles_1.style.barShapeWrapper]}>
<ReanimatedSvg width={width * 2.5} height={height + bottom} style={[
{
width: '100%',
backgroundColor: 'transparent',
},
animatedStyles,
]}>
<react_native_svg_1.Path d={d} fill={Object.values(descriptors)[state.index].options
.tabBarActiveBackgroundColor || '#fff'}/>
</ReanimatedSvg>
</react_native_1.View>
{state.routes.map(function (route, index) {
var options = descriptors[route.key].options;
var isFocused = state.index === index;
var onPress = function () {
var event = navigation.emit({
type: 'tabPress',
target: route.key,
canPreventDefault: true,
});
if (!isFocused && !event.defaultPrevented) {
navigation.navigate(route.name);
}
};
var onLongPress = function () {
navigation.emit({
type: 'tabLongPress',
target: route.key,
});
};
return (<BottomMenu_bar_button_1.BottomBarButton mode={mode} focusedButtonStyle={focusedButtonStyle} key={route.key} options={options} onPress={onPress} onLongPress={onLongPress} index={index} isFocused={isFocused} activeTintColor={options.tabBarActiveTintColor} inactiveTintColor={options.tabBarInactiveTintColor}/>);
})}
</react_native_1.View>);
};
exports.BottomMenuBar = BottomMenuBar;