Skip to content

Commit

Permalink
New Switch look (#994)
Browse files Browse the repository at this point in the history
* new Switch look

* refactor: merge SwitchSetting to SwitchItem

* fix: remove margin
  • Loading branch information
nyagami authored Mar 10, 2024
1 parent 202feb1 commit 0d5d7ad
Show file tree
Hide file tree
Showing 12 changed files with 213 additions and 128 deletions.
171 changes: 109 additions & 62 deletions src/components/Switch/Switch.tsx
Original file line number Diff line number Diff line change
@@ -1,77 +1,124 @@
import React from 'react';
import { Pressable, StyleSheet, View, Text } from 'react-native';
import { Switch, List } from 'react-native-paper';
import {
StyleProp,
StyleSheet,
TouchableWithoutFeedback,
ViewStyle,
} from 'react-native';
import React, { useEffect } from 'react';
import Animated, {
interpolateColor,
useSharedValue,
useAnimatedStyle,
withSpring,
withTiming,
useDerivedValue,
} from 'react-native-reanimated';
import { ThemeColors } from '@theme/types';

interface SwitchProps {
label: string;
description?: string;
onPress: () => void;
theme: ThemeColors;
icon?: string;
value: boolean;
onValueChange: () => void;
size?: number;
style?: StyleProp<ViewStyle>;
}

const SwitchSetting: React.FC<SwitchProps> = ({
label,
description,
onPress,
const Switch = ({
theme,
icon,
value,
}) => {
const styles = StyleSheet.create({
container: {
paddingHorizontal: 16,
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: description ? 16 : 12,
},
row: {
flexDirection: 'row',
flex: 1,
},
icon: {
margin: 0,
},
textContainer: {
marginLeft: icon && 16,
},
text: {
fontSize: 16,
flex: 1,
textAlignVertical: 'center',
},
switch: { marginLeft: 8 },
size = 22,
onValueChange,
style,
}: SwitchProps) => {
// value for Switch Animation
const switchTranslate = useSharedValue(value ? size : size / 6);
// state for activate Switch
// Progress Value
const progress = useDerivedValue(() => {
return withTiming(value ? size : 0);
});

// useEffect for change the switchTranslate Value
useEffect(() => {
if (value) {
switchTranslate.value = size;
} else {
switchTranslate.value = size / 6;
}
}, [value, switchTranslate, size]);

// Circle Animation
const customSpringStyles = useAnimatedStyle(() => {
return {
transform: [
{
translateX: withSpring(switchTranslate.value, {
mass: 1,
damping: 15,
stiffness: 120,
overshootClamping: false,
restSpeedThreshold: 0.001,
restDisplacementThreshold: 0.001,
}),
},
],
};
});

// Background Color Animation
const backgroundColorStyle = useAnimatedStyle(() => {
const backgroundColor = interpolateColor(
progress.value,
[0, size],
[theme.outline, theme.primary],
);
return {
backgroundColor,
};
});

return (
<Pressable
android_ripple={{
color: theme.rippleColor,
}}
style={styles.container}
onPress={onPress}
>
<View style={styles.row}>
{icon && (
<List.Icon color={theme.primary} icon={icon} style={styles.icon} />
)}
<View style={styles.textContainer}>
<Text style={[styles.text, { color: theme.onSurface }]}>{label}</Text>
{description && (
<Text style={{ color: theme.onSurfaceVariant }}>{description}</Text>
)}
</View>
</View>
<Switch
value={value}
onValueChange={onPress}
color={theme.primary}
style={styles.switch}
/>
</Pressable>
<TouchableWithoutFeedback onPress={onValueChange}>
<Animated.View
style={[
styles.container,
style,
{
width: size * 2 + size / 6,
height: size + size / 3,
borderRadius: size,
},
backgroundColorStyle,
]}
>
<Animated.View
style={[
styles.circle,
customSpringStyles,
{ height: size, width: size, borderRadius: size },
]}
/>
</Animated.View>
</TouchableWithoutFeedback>
);
};

export default SwitchSetting;
export default Switch;

const styles = StyleSheet.create({
container: {
justifyContent: 'center',
backgroundColor: '#F2F5F7',
},
circle: {
backgroundColor: 'white',
shadowColor: 'black',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.2,
shadowRadius: 2.5,
elevation: 4,
},
});
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import React from 'react';
import { Pressable, StyleSheet, View, Text } from 'react-native';

import { Switch } from 'react-native-paper';
import {
Pressable,
StyleSheet,
View,
Text,
ViewStyle,
StyleProp,
} from 'react-native';
import Switch from './Switch';
import { ThemeColors } from '../../theme/types';

interface SwitchItemProps {
Expand All @@ -10,6 +16,8 @@ interface SwitchItemProps {
description?: string;
onPress: () => void;
theme: ThemeColors;
size?: number;
style?: StyleProp<ViewStyle>;
}

const SwitchItem: React.FC<SwitchItemProps> = ({
Expand All @@ -18,10 +26,12 @@ const SwitchItem: React.FC<SwitchItemProps> = ({
onPress,
theme,
value,
size,
style,
}) => (
<Pressable
android_ripple={{ color: theme.rippleColor }}
style={[styles.container]}
style={[styles.container, style]}
onPress={onPress}
>
<View style={styles.labelContainer}>
Expand All @@ -33,8 +43,9 @@ const SwitchItem: React.FC<SwitchItemProps> = ({
<Switch
value={value}
onValueChange={onPress}
color={theme.primary}
theme={theme}
style={styles.switch}
size={size}
/>
</Pressable>
);
Expand All @@ -45,8 +56,8 @@ const styles = StyleSheet.create({
container: {
flexDirection: 'row',
justifyContent: 'space-between',
paddingHorizontal: 16,
paddingVertical: 12,
alignItems: 'center',
},
labelContainer: {
flex: 1,
Expand Down
2 changes: 1 addition & 1 deletion src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export { default as EmptyView } from './EmptyView/EmptyView';
export { default as Chip } from './Chip/Chip';
export { default as Button } from './Button/Button';
export { default as Appbar } from './Appbar/Appbar';
export { default as SwitchItem } from './SwitchItem/SwitchItem';
export { default as SwitchItem } from './Switch/SwitchItem';
export { default as List } from './List/List';
export { default as ColorPreferenceItem } from './ColorPreferenceItem/ColorPreferenceItem';
export { default as LoadingMoreIndicator } from './LoadingMoreIndicator/LoadingMoreIndicator';
Expand Down
6 changes: 6 additions & 0 deletions src/screens/browse/BrowseSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const BrowseSettings = ({ navigation }: BrowseSettingsScreenProp) => {
value={showAniList}
onPress={() => setBrowseSettings({ showAniList: !showAniList })}
theme={theme}
style={styles.item}
/>
<SwitchItem
label={`${getString('common.show')} MyAnimeList`}
Expand All @@ -51,6 +52,7 @@ const BrowseSettings = ({ navigation }: BrowseSettingsScreenProp) => {
setBrowseSettings({ showMyAnimeList: !showMyAnimeList })
}
theme={theme}
style={styles.item}
/>
<List.Divider theme={theme} />
<List.SubHeader theme={theme}>
Expand All @@ -66,6 +68,7 @@ const BrowseSettings = ({ navigation }: BrowseSettingsScreenProp) => {
value={languagesFilter.includes(item)}
onPress={() => toggleLanguageFilter(item)}
theme={theme}
style={styles.item}
/>
)}
/>
Expand All @@ -79,4 +82,7 @@ const styles = StyleSheet.create({
container: {
paddingBottom: 40,
},
item: {
paddingHorizontal: 16,
},
});
12 changes: 7 additions & 5 deletions src/screens/more/MoreScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import {
Text,
ScrollView,
} from 'react-native';
import { Switch } from 'react-native-paper';
import { getString } from '@strings/translations';

import { List } from '@components';

import { MoreHeader } from './components/MoreHeader';
import { useDownload, useLibrarySettings, useTheme } from '@hooks/persisted';
import { MoreStackScreenProps } from '@navigators/types';
import Switch from '@components/Switch/Switch';

const MoreScreen = ({ navigation }: MoreStackScreenProps) => {
const theme = useTheme();
Expand Down Expand Up @@ -44,6 +44,7 @@ const MoreScreen = ({ navigation }: MoreStackScreenProps) => {
paddingVertical: 14,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
}}
onPress={enableDownloadedOnlyMode}
>
Expand All @@ -64,10 +65,10 @@ const MoreScreen = ({ navigation }: MoreStackScreenProps) => {
</View>
</View>
<Switch
theme={theme}
value={downloadedOnlyMode}
onValueChange={enableDownloadedOnlyMode}
color={theme.primary}
style={{ marginRight: 8 }}
size={24}
/>
</Pressable>
<Pressable
Expand All @@ -77,6 +78,7 @@ const MoreScreen = ({ navigation }: MoreStackScreenProps) => {
paddingVertical: 14,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
}}
onPress={enableIncognitoMode}
>
Expand All @@ -97,10 +99,10 @@ const MoreScreen = ({ navigation }: MoreStackScreenProps) => {
</View>
</View>
<Switch
theme={theme}
value={incognitoMode}
onValueChange={enableIncognitoMode}
color={theme.primary}
style={{ marginRight: 8 }}
size={24}
/>
</Pressable>
<List.Divider theme={theme} />
Expand Down
Loading

0 comments on commit 0d5d7ad

Please sign in to comment.