diff --git a/src/components/Actionbar/Actionbar.tsx b/src/components/Actionbar/Actionbar.tsx index 5086004e..7b138471 100644 --- a/src/components/Actionbar/Actionbar.tsx +++ b/src/components/Actionbar/Actionbar.tsx @@ -73,10 +73,8 @@ export const Actionbar: React.FC = ({ const styles = StyleSheet.create({ actionbarContainer: { alignItems: 'center', - borderTopLeftRadius: 16, - borderTopRightRadius: 16, bottom: 0, - elevation: 1, + elevation: 0, flexDirection: 'row', justifyContent: 'space-around', position: 'absolute', diff --git a/src/components/BottomSheet/BottomSheet.tsx b/src/components/BottomSheet/BottomSheet.tsx index afcf38a6..41cdf7ed 100644 --- a/src/components/BottomSheet/BottomSheet.tsx +++ b/src/components/BottomSheet/BottomSheet.tsx @@ -9,7 +9,8 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { useBackHandler } from '@hooks/index'; import { BottomSheetModalMethods } from '@gorhom/bottom-sheet/lib/typescript/types'; import BottomSheetBackdrop from './BottomSheetBackdrop'; -import { useWindowDimensions } from 'react-native'; +import { StyleSheet, useWindowDimensions, View } from 'react-native'; +import { useTheme } from '@hooks/persisted'; interface BottomSheetProps extends Omit { @@ -18,6 +19,33 @@ interface BottomSheetProps snapPoints?: number[]; } +// const MD3DragHandle = () => { +// const theme = useTheme(); +// return ( +// +// +// +// ); +// }; + +// const handleStyles = StyleSheet.create({ +// container: { +// alignItems: 'center', +// paddingVertical: 12, +// }, +// handle: { +// width: 32, +// height: 4, +// borderRadius: 2, +// opacity: 0.4, +// }, +// }); + const BottomSheet: React.FC = ({ bottomSheetRef, children, @@ -29,6 +57,7 @@ const BottomSheet: React.FC = ({ const indexRef = useRef(null); const { bottom, top } = useSafeAreaInsets(); const { height } = useWindowDimensions(); + const theme = useTheme(); const renderBackdrop = useCallback( (backdropProps: BottomSheetBackdropProps) => ( @@ -61,6 +90,11 @@ const BottomSheet: React.FC = ({ ref={bottomSheetRef} backdropComponent={renderBackdrop} handleComponent={null} + backgroundStyle={{ + borderTopLeftRadius: 28, + borderTopRightRadius: 28, + backgroundColor: theme.surface, + }} containerStyle={[{ paddingBottom: bottom }, containerStyle]} onChange={index => { onChange?.(index); diff --git a/src/components/BottomTabBar/index.tsx b/src/components/BottomTabBar/index.tsx index 7003075c..1cea1978 100644 --- a/src/components/BottomTabBar/index.tsx +++ b/src/components/BottomTabBar/index.tsx @@ -100,7 +100,7 @@ function CustomBottomTabBar({ transitionDuration: 250, transitionTimingFunction: 'ease-in-out', marginBottom: showLabel ? 4 : 20, - width: isFocused ? 52 : 32, + width: isFocused ? 64 : 32, backgroundColor: isFocused ? theme.primaryContainer : 'transparent', @@ -116,8 +116,8 @@ function CustomBottomTabBar({ style={[ styles.label, { - color: theme.onSurfaceVariant, - fontWeight: '700', + color: isFocused ? theme.onSurface : theme.onSurfaceVariant, + fontWeight: '500', }, ]} numberOfLines={1} @@ -138,7 +138,8 @@ export type { CustomBottomTabBarProps }; const styles = StyleSheet.create({ container: { flexDirection: 'row', - paddingVertical: 4, + paddingTop: 12, + paddingBottom: 16, paddingHorizontal: 0, minHeight: 80, }, @@ -154,8 +155,8 @@ const styles = StyleSheet.create({ display: 'flex', justifyContent: 'center', alignItems: 'center', - padding: 2, - borderRadius: 24, + height: 32, + borderRadius: 16, }, label: { height: 16, diff --git a/src/components/Chip/Chip.tsx b/src/components/Chip/Chip.tsx index e412d530..d0c8c614 100644 --- a/src/components/Chip/Chip.tsx +++ b/src/components/Chip/Chip.tsx @@ -2,7 +2,6 @@ import React from 'react'; import { Pressable, StyleSheet, Text, View } from 'react-native'; import { ThemeColors } from '../../theme/types'; -import { overlay } from 'react-native-paper'; interface ChipProps { label: string; @@ -14,9 +13,7 @@ const Chip: React.FC = ({ label, theme }) => ( style={[ styles.chipContainer, { - backgroundColor: theme.isDark - ? overlay(1, theme.surface) - : theme.secondaryContainer, + backgroundColor: theme.secondaryContainer, }, ]} > @@ -28,7 +25,7 @@ const Chip: React.FC = ({ label, theme }) => ( style={[ styles.label, { - color: theme.isDark ? theme.onSurface : theme.onSecondaryContainer, + color: theme.onSecondaryContainer, }, ]} > @@ -48,7 +45,7 @@ const styles = StyleSheet.create({ overflow: 'hidden', }, label: { - fontSize: 12, + fontSize: 14, }, pressable: { alignItems: 'center', diff --git a/src/components/ConfirmationDialog/ConfirmationDialog.tsx b/src/components/ConfirmationDialog/ConfirmationDialog.tsx index a9e29955..03e1baf7 100644 --- a/src/components/ConfirmationDialog/ConfirmationDialog.tsx +++ b/src/components/ConfirmationDialog/ConfirmationDialog.tsx @@ -65,7 +65,7 @@ const styles = StyleSheet.create({ shadowColor: 'transparent', }, content: { - fontSize: 16, + fontSize: 14, letterSpacing: 0, }, }); diff --git a/src/components/IconButtonV2/IconButtonV2.tsx b/src/components/IconButtonV2/IconButtonV2.tsx index 593cae0c..bab1822f 100644 --- a/src/components/IconButtonV2/IconButtonV2.tsx +++ b/src/components/IconButtonV2/IconButtonV2.tsx @@ -41,7 +41,11 @@ const IconButton: React.FC = ({ diff --git a/src/components/List/List.tsx b/src/components/List/List.tsx index 160bcea8..03dd63ab 100644 --- a/src/components/List/List.tsx +++ b/src/components/List/List.tsx @@ -33,7 +33,7 @@ const SubHeader = ({ children: ReactNode; theme: ThemeColors; }) => ( - + {children} ); @@ -51,13 +51,13 @@ const Item: React.FC = ({ if (icon) { return ( ); } - }, [icon, theme.primary]); + }, [icon, theme.onSurfaceVariant]); const rightIcon = useCallback(() => { if (right) { return ( @@ -68,7 +68,7 @@ const Item: React.FC = ({ /> ); } - }, [right, theme.primary]); + }, [right, theme.onSurfaceVariant]); return ( = ({ }; const Divider = ({ theme }: { theme: ThemeColors }) => ( - + ); const InfoItem = ({ @@ -119,7 +121,11 @@ const InfoItem = ({ ); const Icon = ({ icon, theme }: { icon: string; theme: ThemeColors }) => ( - + ); interface ColorItemProps { @@ -174,12 +180,11 @@ const styles = StyleSheet.create({ marginEnd: 16, }, description: { - fontSize: 12, + fontSize: 14, lineHeight: 20, }, divider: { height: 1, - opacity: 0.5, }, iconCtn: { paddingStart: 16, diff --git a/src/components/Menu/index.tsx b/src/components/Menu/index.tsx index a2d82c34..342f79d0 100644 --- a/src/components/Menu/index.tsx +++ b/src/components/Menu/index.tsx @@ -173,7 +173,7 @@ const Menu: React.FC & { Item: React.FC } = ({ key={menuLayout ? 'ready' : 'measuring'} style={[ styles.menuContainer, - { backgroundColor: theme.surface }, + { backgroundColor: theme.surface2 || theme.surface }, contentStyle, menuPosition, ]} @@ -220,14 +220,14 @@ Menu.Item = MenuItem; const styles = StyleSheet.create({ menuContainer: { - borderRadius: 8, - elevation: 8, + borderRadius: 4, + elevation: 2, shadowOffset: { width: 0, - height: 2, + height: 1, }, - shadowOpacity: 0.25, - shadowRadius: 6, + shadowOpacity: 0.2, + shadowRadius: 3, overflow: 'hidden', position: 'absolute', zIndex: 1001, @@ -246,7 +246,7 @@ const styles = StyleSheet.create({ backgroundColor: 'rgba(0, 0, 0, 0.1)', }, menuItem: { - paddingHorizontal: 16, + paddingHorizontal: 12, paddingVertical: 12, minHeight: 48, justifyContent: 'center', diff --git a/src/components/SearchbarV2/SearchbarV2.tsx b/src/components/SearchbarV2/SearchbarV2.tsx index 1e3e2c6a..b46dd40b 100644 --- a/src/components/SearchbarV2/SearchbarV2.tsx +++ b/src/components/SearchbarV2/SearchbarV2.tsx @@ -82,7 +82,7 @@ const Searchbar: React.FC = ({ ref={searchbarRef} style={[styles.textInput, { color: theme.onSurface }]} placeholder={placeholder} - placeholderTextColor={theme.onSurface} + placeholderTextColor={theme.onSurfaceVariant} onChangeText={onChangeText} onSubmitEditing={onSubmitEditing} defaultValue={searchText} @@ -160,7 +160,7 @@ const styles = StyleSheet.create({ paddingHorizontal: 8, }, searchbarContainer: { - borderRadius: 50, + borderRadius: 28, marginBottom: 12, marginHorizontal: 16, minHeight: 56, diff --git a/src/components/SegmentedControl/SegmentedControl.tsx b/src/components/SegmentedControl/SegmentedControl.tsx index bc5acbaa..b743356b 100644 --- a/src/components/SegmentedControl/SegmentedControl.tsx +++ b/src/components/SegmentedControl/SegmentedControl.tsx @@ -88,7 +88,7 @@ export function SegmentedControl({ const styles = StyleSheet.create({ container: { flexDirection: 'row', - height: 48, + height: 40, }, segment: { flex: 1, @@ -99,16 +99,16 @@ const styles = StyleSheet.create({ segmentFirst: { borderLeftWidth: 1, borderRightWidth: 1, - borderTopLeftRadius: 24, - borderBottomLeftRadius: 24, + borderTopLeftRadius: 20, + borderBottomLeftRadius: 20, }, segmentMiddle: { borderRightWidth: 1, }, segmentLast: { borderRightWidth: 1, - borderTopRightRadius: 24, - borderBottomRightRadius: 24, + borderTopRightRadius: 20, + borderBottomRightRadius: 20, }, segmentPressable: { flex: 1, diff --git a/src/components/Switch/Switch.tsx b/src/components/Switch/Switch.tsx index c2805d5d..0485736a 100644 --- a/src/components/Switch/Switch.tsx +++ b/src/components/Switch/Switch.tsx @@ -10,73 +10,118 @@ import Animated, { } from 'react-native-reanimated'; import { useTheme } from '@hooks/persisted'; +// MD3 Switch dimensions +const TRACK_WIDTH = 52; +const TRACK_HEIGHT = 32; +const TRACK_RADIUS = TRACK_HEIGHT / 2; +const THUMB_SIZE_OFF = 16; +const THUMB_SIZE_ON = 24; +const TRACK_BORDER_WIDTH = 2; + +// Thumb positions: centered vertically, padded from edges +const THUMB_OFFSET_OFF = (TRACK_HEIGHT - THUMB_SIZE_OFF) / 2; +const THUMB_OFFSET_ON = + TRACK_WIDTH - THUMB_SIZE_ON - (TRACK_HEIGHT - THUMB_SIZE_ON) / 2; + interface SwitchProps { value: boolean; onValueChange?: () => void; - size?: number; style?: StyleProp; } -const Switch = ({ value, size = 22, onValueChange, style }: SwitchProps) => { +const Switch = ({ value, onValueChange, style }: SwitchProps) => { const theme = useTheme(); - // Value for Switch Animation - // const switchTranslate = useSharedValue(value ? size : size / 6); - // Background color animation progress - const progress = useSharedValue(value ? size : 0); + const progress = useSharedValue(value ? 1 : 0); - // Animate switch movement - const customSpringStyles = useAnimatedStyle(() => ({ + useEffect(() => { + progress.value = withTiming(value ? 1 : 0, { duration: 200 }); + }, [progress, value]); + + // Animate thumb position + const thumbPositionStyle = useAnimatedStyle(() => ({ transform: [ { - translateX: withSpring(value ? size : size / 6, { - mass: 1, - damping: 15, - stiffness: 120, - overshootClamping: false, - }), + translateX: withSpring( + value ? THUMB_OFFSET_ON : THUMB_OFFSET_OFF, + { + mass: 1, + damping: 15, + stiffness: 120, + overshootClamping: false, + }, + ), }, ], })); - // Precompute background color animation - const backgroundColor = useDerivedValue( + // Animate thumb size + const thumbSizeStyle = useAnimatedStyle(() => { + const size = withSpring(value ? THUMB_SIZE_ON : THUMB_SIZE_OFF, { + mass: 1, + damping: 15, + stiffness: 120, + overshootClamping: false, + }); + return { + width: size, + height: size, + borderRadius: size, + }; + }); + + // Animate track background color + const trackBgColor = useDerivedValue( () => interpolateColor( progress.value, - [0, size], - [theme.outline, theme.primary], + [0, 1], + [theme.surfaceVariant, theme.primary], ), - [value], + [theme.surfaceVariant, theme.primary], ); - const backgroundColorStyle = useAnimatedStyle(() => ({ - backgroundColor: backgroundColor.value, + const trackColorStyle = useAnimatedStyle(() => ({ + backgroundColor: trackBgColor.value, })); - useEffect(() => { - progress.value = withTiming(value ? size : 0); - }, [progress, size, value]); + // Animate track border + const trackBorderStyle = useAnimatedStyle(() => ({ + borderWidth: withTiming(value ? 0 : TRACK_BORDER_WIDTH, { duration: 200 }), + borderColor: theme.outline, + })); + + // Animate thumb color + const thumbBgColor = useDerivedValue( + () => + interpolateColor( + progress.value, + [0, 1], + [theme.outline, theme.onPrimary], + ), + [theme.outline, theme.onPrimary], + ); + + const thumbColorStyle = useAnimatedStyle(() => ({ + backgroundColor: thumbBgColor.value, + })); return ( @@ -87,18 +132,20 @@ const Switch = ({ value, size = 22, onValueChange, style }: SwitchProps) => { export default React.memo(Switch); const styles = StyleSheet.create({ - circle: { - backgroundColor: 'white', - elevation: 4, + thumb: { + elevation: 1, shadowColor: 'black', shadowOffset: { width: 0, - height: 2, + height: 1, }, - shadowOpacity: 0.2, - shadowRadius: 2.5, + shadowOpacity: 0.15, + shadowRadius: 1, }, - container: { + track: { + width: TRACK_WIDTH, + height: TRACK_HEIGHT, + borderRadius: TRACK_RADIUS, justifyContent: 'center', }, }); diff --git a/src/components/Switch/SwitchItem.tsx b/src/components/Switch/SwitchItem.tsx index da63d180..d619387f 100644 --- a/src/components/Switch/SwitchItem.tsx +++ b/src/components/Switch/SwitchItem.tsx @@ -16,7 +16,6 @@ interface SwitchItemProps { description?: string; onPress: () => void; theme: ThemeColors; - size?: number; style?: StyleProp; } @@ -26,7 +25,6 @@ const SwitchItem: React.FC = ({ onPress, theme, value, - size, style, }) => ( = ({ value={value} onValueChange={onPress} style={styles.switch} - size={size} /> ); @@ -58,10 +55,11 @@ const styles = StyleSheet.create({ alignItems: 'center', flexDirection: 'row', justifyContent: 'space-between', + paddingHorizontal: 16, paddingVertical: 12, }, description: { - fontSize: 12, + fontSize: 14, lineHeight: 20, }, label: { diff --git a/src/screens/more/MoreScreen.tsx b/src/screens/more/MoreScreen.tsx index c429b732..2411670b 100644 --- a/src/screens/more/MoreScreen.tsx +++ b/src/screens/more/MoreScreen.tsx @@ -86,7 +86,6 @@ const MoreScreen = ({ navigation }: MoreStackScreenProps) => { { diff --git a/src/screens/novel/components/JumpToChapterModal.tsx b/src/screens/novel/components/JumpToChapterModal.tsx index 2eaf92eb..41cefe6c 100644 --- a/src/screens/novel/components/JumpToChapterModal.tsx +++ b/src/screens/novel/components/JumpToChapterModal.tsx @@ -227,14 +227,12 @@ const JumpToChapterModal = ({ value={openChapter} theme={theme} onPress={() => setOpenChapter(!openChapter)} - size={20} /> setMode(!mode)} - size={20} /> {result.length ? ( diff --git a/src/screens/reader/components/ReaderBottomSheet/ReaderSheetPreferenceItem.tsx b/src/screens/reader/components/ReaderBottomSheet/ReaderSheetPreferenceItem.tsx index 0971c160..300a7673 100644 --- a/src/screens/reader/components/ReaderBottomSheet/ReaderSheetPreferenceItem.tsx +++ b/src/screens/reader/components/ReaderBottomSheet/ReaderSheetPreferenceItem.tsx @@ -16,7 +16,6 @@ const ReaderSheetPreferenceItem: React.FC = ({ onPress, theme, }) => { - const size = 20; return ( = ({ fallback={ } > - + );