Skip to content

refactor: remove mode from theme #4737

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion docs/docs/guides/02-theming.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ You can change the theme prop dynamically and all the components will automatica
A theme usually contains the following properties:

- `dark` (`boolean`): whether this is a dark theme or light theme.
- `mode` (`'adaptive' | 'exact'`): color mode for dark theme (See [Dark Theme](#dark-theme)).
- `roundness` (`number`): roundness of common elements, such as buttons.
- `colors` (`object`): various colors used throughout different elements.

Expand Down
4 changes: 0 additions & 4 deletions example/src/Examples/AppbarExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ const AppbarExample = ({ navigation }: Props) => {
header: () => (
<Appbar.Header
style={showCustomColor ? styles.customColor : null}
theme={{
mode: 'adaptive',
}}
mode={appbarMode}
elevated={showElevated}
>
Expand Down Expand Up @@ -171,7 +168,6 @@ const AppbarExample = ({ navigation }: Props) => {
},
]}
safeAreaInsets={{ bottom, left, right }}
theme={{ mode: 'adaptive' }}
>
<Appbar.Action icon="archive" onPress={() => {}} />
<Appbar.Action icon="email" onPress={() => {}} />
Expand Down
3 changes: 0 additions & 3 deletions src/components/Appbar/Appbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ export type Props = Omit<
* The top bar usually contains the screen title, controls such as navigation buttons, menu button etc.
* The bottom bar usually provides access to a drawer and up to four actions.
*
* By default Appbar uses primary color as a background, in dark theme with `adaptive` mode it will use surface colour instead.
* See [Dark Theme](https://callstack.github.io/react-native-paper/docs/guides/theming#dark-theme) for more informations
*
* ## Usage
* ### Top bar
* ```js
Expand Down
3 changes: 0 additions & 3 deletions src/components/BottomNavigation/BottomNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,6 @@ const SceneComponent = React.memo(({ component, ...rest }: any) =>
* BottomNavigation provides quick navigation between top-level views of an app with a bottom navigation bar.
* It is primarily designed for use on mobile. If you want to use the navigation bar only see [`BottomNavigation.Bar`](BottomNavigationBar).
*
* By default BottomNavigation uses primary color as a background, in dark theme with `adaptive` mode it will use surface colour instead.
* See [Dark Theme](https://callstack.github.io/react-native-paper/docs/guides/theming#dark-theme) for more information.
*
* ## Usage
* ```js
* import * as React from 'react';
Expand Down
71 changes: 15 additions & 56 deletions src/components/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ const Card = (
onLongPress,
onPressOut,
onPressIn,
mode: cardMode = 'elevated',
mode = 'elevated',
children,
style,
contentStyle,
Expand All @@ -158,11 +158,16 @@ const Card = (
ref: React.ForwardedRef<View>
) => {
const theme = useInternalTheme(themeOverrides);
const {
animation: { scale },
roundness,
} = theme;

const isMode = React.useCallback(
(modeToCompare: Mode) => {
return cardMode === modeToCompare;
return mode === modeToCompare;
},
[cardMode]
[mode]
);

const hasPassedTouchHandler = hasTouchHandler({
Expand All @@ -172,65 +177,21 @@ const Card = (
onPressOut,
});

// Default animated value
const { current: elevation } = React.useRef<Animated.Value>(
new Animated.Value(cardElevation)
);
// Dark adaptive animated value, used in case of toggling the theme,
// it prevents animating the background with native drivers inside Surface
const { current: elevationDarkAdaptive } = React.useRef<Animated.Value>(
new Animated.Value(cardElevation)
);
const { animation, dark, mode, roundness } = theme;

const prevDarkRef = React.useRef<boolean>(dark);
React.useEffect(() => {
prevDarkRef.current = dark;
});

const prevDark = prevDarkRef.current;
const isAdaptiveMode = mode === 'adaptive';
const animationDuration = 150 * animation.scale;

React.useEffect(() => {
/**
* Resets animations values if updating to dark adaptive mode,
* otherwise, any card that is in the middle of animation while
* toggling the theme will stay at that animated value until
* the next press-in
*/
if (dark && isAdaptiveMode && !prevDark) {
elevation.setValue(cardElevation);
elevationDarkAdaptive.setValue(cardElevation);
}
}, [
prevDark,
dark,
isAdaptiveMode,
cardElevation,
elevation,
elevationDarkAdaptive,
]);

const runElevationAnimation = (pressType: HandlePressType) => {
if (isMode('contained')) {
return;
}

const isPressTypeIn = pressType === 'in';
if (dark && isAdaptiveMode) {
Animated.timing(elevationDarkAdaptive, {
toValue: isPressTypeIn ? 2 : cardElevation,
duration: animationDuration,
useNativeDriver: false,
}).start();
} else {
Animated.timing(elevation, {
toValue: isPressTypeIn ? 2 : cardElevation,
duration: animationDuration,
useNativeDriver: false,
}).start();
}
Animated.timing(elevation, {
toValue: isPressTypeIn ? 2 : cardElevation,
duration: 150 * scale,
useNativeDriver: false,
}).start();
};

const handlePressIn = useLatestCallback((e: GestureResponderEvent) => {
Expand All @@ -249,12 +210,10 @@ const Card = (
? (child.type as any).displayName
: null
);
const computedElevation =
dark && isAdaptiveMode ? elevationDarkAdaptive : elevation;

const { backgroundColor, borderColor: themedBorderColor } = getCardColors({
theme,
mode: cardMode,
mode,
});

const flattenedStyles = (StyleSheet.flatten(style) || {}) as ViewStyle;
Expand Down Expand Up @@ -295,7 +254,7 @@ const Card = (
style,
]}
theme={theme}
elevation={isMode('elevated') ? computedElevation : 0}
elevation={isMode('elevated') ? elevation : 0}
testID={`${testID}-container`}
container
{...rest}
Expand Down
2 changes: 0 additions & 2 deletions src/components/Surface.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,6 @@ const SurfaceIOS = forwardRef<

/**
* Surface is a basic container that can give depth to an element with elevation shadow.
* On dark theme with `adaptive` mode, surface is constructed by also placing a semi-transparent white overlay over a component surface.
* See [Dark Theme](https://callstack.github.io/react-native-paper/docs/guides/theming#dark-theme) for more information.
* Overlay and shadow can be applied by specifying the `elevation` property both on Android and iOS.
*
* ## Usage
Expand Down
1 change: 0 additions & 1 deletion src/styles/themes/DarkTheme.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ const { palette, opacity } = tokens.md.ref;
export const DarkTheme: Theme = {
...LightTheme,
dark: true,
mode: 'adaptive',
colors: {
primary: palette.primary80,
primaryContainer: palette.primary30,
Expand Down
3 changes: 0 additions & 3 deletions src/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ export type Font = {
fontStyle?: 'normal' | 'italic' | undefined;
};

type Mode = 'adaptive' | 'exact';

export type Colors = {
primary: string;
primaryContainer: string;
Expand Down Expand Up @@ -61,7 +59,6 @@ export type ThemeProp = $DeepPartial<InternalTheme>;

export type ThemeBase = {
dark: boolean;
mode?: Mode;
roundness: number;
animation: {
scale: number;
Expand Down
Loading