react-native-multiswitch-controller
Version:
Smooth animated multiswitch component with dynamic width
135 lines (134 loc) • 4.07 kB
JavaScript
"use strict";
import { useCallback, useMemo } from 'react';
import { StyleSheet, View } from 'react-native';
import Animated from 'react-native-reanimated';
import SwitchItem from "./SwitchItem.js";
import { commonColors } from "./constants.js";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
function SwitchList(props) {
const {
options,
activeOption,
onLayoutOptionItem,
onAnimationFinish,
animatedActiveOptionIndex,
animatedActiveOptionStyle,
scrollHandler,
controlListRef,
onPressItem,
variant,
// Style props
containerStyle,
inactiveOptionContainerStyle,
activeOptionContainerStyle,
inactiveTextStyle,
activeTextStyle,
containerHeight,
containerPadding,
optionGap,
optionHeight,
align
} = props;
const isSegmentedControlVariant = variant === 'segmentedControl';
const itemContainerStyle = useMemo(() => {
return {
height: optionHeight,
...inactiveOptionContainerStyle
};
}, [optionHeight, inactiveOptionContainerStyle]);
const renderItem = useCallback(({
item,
index
}) => /*#__PURE__*/_jsx(SwitchItem, {
variant: variant,
item: item,
isActive: activeOption === item.value,
index: index,
onLayout: onLayoutOptionItem,
onChange: () => {
onPressItem?.(item.value);
onAnimationFinish(item.value);
},
animatedActiveOptionIndex: animatedActiveOptionIndex,
itemContainerStyle: itemContainerStyle,
inactiveTextStyle: inactiveTextStyle,
activeTextStyle: activeTextStyle
}), [onLayoutOptionItem, activeOption, onAnimationFinish, animatedActiveOptionIndex, onPressItem, itemContainerStyle, activeTextStyle, inactiveTextStyle, variant]);
const containerStyles = useMemo(() => {
return {
height: containerHeight,
padding: containerPadding,
marginRight: align !== 'right' ? 'auto' : 0,
marginLeft: align !== 'left' ? 'auto' : 0
};
}, [containerHeight, containerPadding, align]);
const defaultActiveOptionStyles = useMemo(() => {
const styles = {
left: containerPadding
};
if (isSegmentedControlVariant) {
styles.height = optionHeight;
styles.top = containerPadding;
}
return styles;
}, [containerPadding, optionHeight, isSegmentedControlVariant]);
const ItemSeparatorComponent = useMemo(() => {
if (!optionGap) return null;
return /*#__PURE__*/_jsx(ItemSpace, {
gap: optionGap
});
}, [optionGap]);
if (!options.length) return null;
return /*#__PURE__*/_jsxs(View, {
style: [styles.container, isSegmentedControlVariant ? styles.containerSegmentedControl : styles.containerTabs, containerStyles, containerStyle],
children: [/*#__PURE__*/_jsx(Animated.View, {
style: [styles.activeOption, isSegmentedControlVariant ? styles.activeOptionSegmentedControl : styles.activeOptionTabs, defaultActiveOptionStyles, activeOptionContainerStyle, animatedActiveOptionStyle]
}), /*#__PURE__*/_jsx(Animated.FlatList, {
ref: controlListRef,
onScroll: scrollHandler,
scrollEventThrottle: 12,
accessibilityRole: "tablist",
data: options,
keyExtractor: item => String(item.value),
ItemSeparatorComponent: () => ItemSeparatorComponent,
renderItem: renderItem,
showsHorizontalScrollIndicator: false,
horizontal: true,
overScrollMode: "never",
bounces: false
})]
});
}
function ItemSpace({
gap
}) {
return /*#__PURE__*/_jsx(View, {
style: {
width: gap
}
});
}
const styles = StyleSheet.create({
container: {
overflow: 'hidden',
backgroundColor: commonColors.containerBackground
},
containerSegmentedControl: {
borderRadius: 999
},
containerTabs: {},
activeOption: {
position: 'absolute',
backgroundColor: commonColors.activeOptionBackground
},
activeOptionSegmentedControl: {
borderRadius: 999
},
activeOptionTabs: {
bottom: 0,
left: 0,
height: 2
}
});
export default SwitchList;
//# sourceMappingURL=SwitchList.js.map