UNPKG

rn-segmented-tabs

Version:

A customizable and animated select component for React Native

141 lines (140 loc) 6.57 kB
"use strict"; 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; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Tabs; //@ts-nocheck const react_1 = __importStar(require("react")); const react_native_1 = require("react-native"); const react_native_linear_gradient_1 = __importDefault(require("react-native-linear-gradient")); const react_native_reanimated_1 = __importStar(require("react-native-reanimated")); function Tab({ option, selectedValue, onChange, tabStyle, labelStyle, activeTabLabelColor, tabLabelColor, }) { const isActiveTab = (0, react_native_reanimated_1.useSharedValue)(0); (0, react_1.useEffect)(() => { isActiveTab.value = (0, react_native_reanimated_1.withTiming)(selectedValue === option.value ? 1 : 0); }, [selectedValue, option, isActiveTab]); const animatedTabTextStyle = (0, react_native_reanimated_1.useAnimatedStyle)(() => { const color = (0, react_native_reanimated_1.interpolateColor)(isActiveTab.value, [0, 1], [tabLabelColor, activeTabLabelColor]); return { color, }; }); return (<react_native_1.TouchableOpacity style={[styles.tab, tabStyle]} onPress={() => { onChange && onChange(option); }}> <react_native_reanimated_1.default.Text style={[styles.label, labelStyle, animatedTabTextStyle]}> {option.label} </react_native_reanimated_1.default.Text> </react_native_1.TouchableOpacity>); } const DEFAULT_INNER_PADDING = 8; function Tabs({ options, selectedValue, onChange, innerPadding = DEFAULT_INNER_PADDING, containerStyle, labelStyle, activeTabLabelColor = "#000", tabLabelColor = "#000", indicatorStyle, tabStyle, gradientColors = ["#333", "#999"], useGradients = false, gradientStart = { x: 0, y: 0 }, gradientEnd = { x: 1, y: 0 }, animationConfig, }) { const offset = (0, react_native_reanimated_1.useSharedValue)(0); const [containerDimensions, setContainerDimensions] = (0, react_1.useState)({ height: 0, width: 0, }); (0, react_1.useEffect)(() => { var _a; offset.value = (0, react_native_reanimated_1.withTiming)((_a = options === null || options === void 0 ? void 0 : options.indexOf(selectedValue)) !== null && _a !== void 0 ? _a : 0, animationConfig); }, [selectedValue, offset, options, animationConfig]); const itemWidth = (0, react_1.useMemo)(() => { if (!containerDimensions.width) { return 0; } return (containerDimensions.width - innerPadding * 2) / (options === null || options === void 0 ? void 0 : options.length); }, [containerDimensions.width, innerPadding, options === null || options === void 0 ? void 0 : options.length]); const animatedIndicatorStyle = (0, react_native_reanimated_1.useAnimatedStyle)(() => { const translationX = offset.value * itemWidth; return { transform: [ { translateX: translationX, }, ], }; }); const combinedIndicatorStyle = [ styles.indicator, animatedIndicatorStyle, { width: `${100 / (options === null || options === void 0 ? void 0 : options.length)}%`, height: containerDimensions.height - innerPadding * 2, }, indicatorStyle, { top: innerPadding, left: innerPadding }, ]; return (<react_native_1.View style={[styles.container, containerStyle, { padding: innerPadding }]} onLayout={(event) => { setContainerDimensions({ height: event.nativeEvent.layout.height, width: event.nativeEvent.layout.width, }); }}> {useGradients ? (<react_native_reanimated_1.default.View style={[combinedIndicatorStyle, { backgroundColor: "transparent" }]}> <react_native_linear_gradient_1.default key={JSON.stringify(containerDimensions)} style={[ { width: "100%", height: containerDimensions.height - innerPadding * 2, }, indicatorStyle, ]} colors={gradientColors} start={gradientStart} end={gradientEnd}/> </react_native_reanimated_1.default.View>) : (<react_native_reanimated_1.default.View style={combinedIndicatorStyle}/>)} {options === null || options === void 0 ? void 0 : options.map((option) => (<Tab key={option.value} labelStyle={labelStyle} tabLabelColor={tabLabelColor} onChange={onChange} tabStyle={tabStyle} selectedValue={selectedValue.value} option={option} activeTabLabelColor={activeTabLabelColor}/>))} </react_native_1.View>); } const styles = react_native_1.StyleSheet.create({ container: { backgroundColor: "#e4e4e4", borderRadius: 8, flexDirection: "row", }, tab: { minHeight: 50, flex: 1, justifyContent: "center", alignItems: "center", borderRadius: 8, }, indicator: { backgroundColor: "#fff", position: "absolute", borderRadius: 8, }, label: { fontWeight: "bold", }, });