Fix form keyboard issues and sticky footers in agent screens
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
import React, { memo, useEffect } from 'react';
|
||||
import {
|
||||
Pressable,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import Animated, {
|
||||
interpolateColor,
|
||||
useAnimatedStyle,
|
||||
useSharedValue,
|
||||
withTiming,
|
||||
} from 'react-native-reanimated';
|
||||
|
||||
import { useTheme } from '../../../theme';
|
||||
|
||||
interface ToggleSwitchProps {
|
||||
label: string;
|
||||
description?: string;
|
||||
value: boolean;
|
||||
onValueChange: (value: boolean) => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
const ToggleSwitchComponent = ({
|
||||
label,
|
||||
description,
|
||||
value,
|
||||
onValueChange,
|
||||
disabled = false,
|
||||
}: ToggleSwitchProps) => {
|
||||
const theme = useTheme();
|
||||
const progress = useSharedValue(value ? 1 : 0);
|
||||
|
||||
useEffect(() => {
|
||||
progress.value = withTiming(value ? 1 : 0, { duration: 180 });
|
||||
}, [progress, value]);
|
||||
|
||||
const trackStyle = useAnimatedStyle(() => ({
|
||||
backgroundColor: interpolateColor(
|
||||
progress.value,
|
||||
[0, 1],
|
||||
[theme.colors.surfaceMuted, theme.colors.primary],
|
||||
),
|
||||
}));
|
||||
|
||||
const thumbStyle = useAnimatedStyle(() => ({
|
||||
transform: [{ translateX: withTiming(progress.value * 22, { duration: 180 }) }],
|
||||
}));
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
disabled={disabled}
|
||||
onPress={() => onValueChange(!value)}
|
||||
style={[
|
||||
styles.row,
|
||||
disabled && styles.rowDisabled,
|
||||
{
|
||||
borderBottomColor: theme.colors.cardBorder,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<View style={styles.copy}>
|
||||
<Text style={[styles.label, { color: theme.colors.textPrimary }]}>{label}</Text>
|
||||
{description ? (
|
||||
<Text style={[styles.description, { color: theme.colors.textSecondary }]}>
|
||||
{description}
|
||||
</Text>
|
||||
) : null}
|
||||
</View>
|
||||
<Animated.View
|
||||
style={[
|
||||
styles.track,
|
||||
trackStyle,
|
||||
{ borderRadius: theme.radius.pill },
|
||||
]}
|
||||
>
|
||||
<Animated.View
|
||||
style={[
|
||||
styles.thumb,
|
||||
thumbStyle,
|
||||
{ backgroundColor: theme.colors.white },
|
||||
]}
|
||||
/>
|
||||
</Animated.View>
|
||||
</Pressable>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
paddingVertical: 16,
|
||||
borderBottomWidth: StyleSheet.hairlineWidth,
|
||||
gap: 16,
|
||||
},
|
||||
rowDisabled: {
|
||||
opacity: 0.55,
|
||||
},
|
||||
copy: {
|
||||
flex: 1,
|
||||
gap: 4,
|
||||
},
|
||||
label: {
|
||||
fontSize: 15,
|
||||
fontWeight: '700',
|
||||
},
|
||||
description: {
|
||||
fontSize: 12,
|
||||
lineHeight: 18,
|
||||
},
|
||||
track: {
|
||||
width: 52,
|
||||
height: 30,
|
||||
justifyContent: 'center',
|
||||
paddingHorizontal: 4,
|
||||
},
|
||||
thumb: {
|
||||
width: 18,
|
||||
height: 18,
|
||||
borderRadius: 9,
|
||||
},
|
||||
});
|
||||
|
||||
export const ToggleSwitch = memo(ToggleSwitchComponent);
|
||||
Reference in New Issue
Block a user