@ramses-superapp/ramses-ui
Version:
Skinless UI primitives for Ramses Built Apps
99 lines (95 loc) • 2.95 kB
JavaScript
"use strict";
import { useEffect, useRef, useState } from 'react';
import { View, TouchableOpacity, Animated, StyleSheet } from 'react-native';
import { useTheme } from "../hooks/ThemeProvider.js";
import RsText from "./RsText.js";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const CONTAINER_PADDING = 2;
function RsToggleButton({
choices,
value,
onChange,
style
}) {
const theme = useTheme();
const styles = generateStyles(theme);
// State to store the container width
const [containerWidth, setContainerWidth] = useState(0);
// Calculate pill width based on container width and number of choices
const pillWidth = containerWidth / choices.length - CONTAINER_PADDING * 2;
const selectedIndex = choices.findIndex(c => c.value === value);
// Animated value for translateX
const translateX = useRef(new Animated.Value(selectedIndex * pillWidth)).current;
useEffect(() => {
Animated.timing(translateX, {
toValue: selectedIndex * pillWidth,
duration: 300,
useNativeDriver: true
}).start();
}, [selectedIndex, pillWidth, translateX]);
const animatedStyle = {
width: pillWidth,
transform: [{
translateX
}]
};
return /*#__PURE__*/_jsxs(View, {
style: [styles.container, style],
onLayout: e => setContainerWidth(e.nativeEvent.layout.width),
children: [containerWidth > 0 && /*#__PURE__*/_jsx(Animated.View, {
style: [styles.pill, animatedStyle]
}), choices.map((c, _idx) => {
const selected = value === c.value;
return /*#__PURE__*/_jsx(TouchableOpacity, {
style: styles.touchable,
onPress: () => {
if (!selected) onChange(c.value);
},
activeOpacity: 0.8,
children: /*#__PURE__*/_jsx(RsText, {
text: c.label,
fontSize: 16,
color: selected ? theme.Text.primaryButtonText : theme.Text.secondaryButtonText,
fontWeight: selected ? 'Bold' : 'Regular'
})
}, String(c.value));
})]
});
}
export default RsToggleButton;
function generateStyles(theme) {
return StyleSheet.create({
container: {
flexDirection: 'row',
backgroundColor: theme.Background.input,
borderRadius: 10,
borderWidth: 1,
borderColor: theme.Borders.input,
overflow: 'hidden',
alignSelf: 'center',
width: '100%',
// Make it take full width of parent
height: 52,
padding: CONTAINER_PADDING,
direction: 'ltr'
},
pill: {
position: 'absolute',
top: CONTAINER_PADDING,
left: CONTAINER_PADDING,
height: '100%',
backgroundColor: theme.Background.primaryButton,
borderRadius: 8,
borderWidth: 1,
borderColor: theme.Borders.primaryButton,
zIndex: 0
},
touchable: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
zIndex: 1
}
});
}
//# sourceMappingURL=RsToggleButton.js.map