From 78fc16a3ad6f5ad1f2b4a9b9d8860517d07909eb Mon Sep 17 00:00:00 2001 From: lukewalczak Date: Fri, 15 Apr 2022 23:20:18 +0200 Subject: [PATCH 1/2] refactor: correct elevation in components based on Surface --- src/components/Banner.tsx | 19 +++++++++++-------- src/components/Card/Card.tsx | 15 +++++++++------ src/components/Menu/Menu.tsx | 3 ++- src/components/Searchbar.tsx | 19 +++++++++++++++---- src/components/Snackbar.tsx | 15 ++++++++++++--- src/components/Surface.tsx | 4 +++- 6 files changed, 52 insertions(+), 23 deletions(-) diff --git a/src/components/Banner.tsx b/src/components/Banner.tsx index e9d62fda87..e881783e20 100644 --- a/src/components/Banner.tsx +++ b/src/components/Banner.tsx @@ -7,7 +7,6 @@ import Icon, { IconSource } from './Icon'; import { withTheme } from '../core/theming'; import type { $RemoveChildren, Theme } from '../types'; -const ELEVATION = 1; const DEFAULT_MAX_WIDTH = 960; type Props = $RemoveChildren & { @@ -42,6 +41,11 @@ type Props = $RemoveChildren & { * Use this prop to apply custom width for wide layouts. */ contentStyle?: StyleProp; + /** + * @supported Available in v3.x with theme version 3 + * Changes Banner shadow and background on iOS and Android. + */ + elevation?: 0 | 1 | 2 | 3 | 4 | 5 | Animated.Value; style?: StyleProp; ref?: React.RefObject; /** @@ -125,6 +129,7 @@ const Banner = ({ children, actions, contentStyle, + elevation = 1, style, theme, onShowAnimationFinished = () => {}, @@ -183,14 +188,9 @@ const Banner = ({ return ( @@ -285,6 +285,9 @@ const styles = StyleSheet.create({ button: { margin: 4, }, + elevation: { + elevation: 1, + }, }); export default withTheme(Banner); diff --git a/src/components/Card/Card.tsx b/src/components/Card/Card.tsx index 7019d8e7f2..bc0921b8d8 100644 --- a/src/components/Card/Card.tsx +++ b/src/components/Card/Card.tsx @@ -33,9 +33,9 @@ type HandlePressType = 'in' | 'out'; type Props = React.ComponentProps & { /** - * Resting elevation of the card which controls the drop shadow. + * Changes Card shadow and background on iOS and Android. */ - elevation?: never | number; + elevation?: 0 | 1 | 2 | 3 | 4 | 5 | Animated.Value; /** * Function to execute on long press. */ @@ -123,7 +123,7 @@ const Card = ({ const { current: elevationDarkAdaptive } = React.useRef( new Animated.Value(cardElevation) ); - const { animation, dark, mode, roundness } = theme; + const { animation, dark, mode, roundness, isV3 } = theme; const prevDarkRef = React.useRef(dark); React.useEffect(() => { @@ -158,13 +158,13 @@ const Card = ({ const isPressTypeIn = pressType === 'in'; if (dark && isAdaptiveMode) { Animated.timing(elevationDarkAdaptive, { - toValue: isPressTypeIn ? 8 : cardElevation, + toValue: isPressTypeIn ? (isV3 ? 2 : 8) : cardElevation, duration: animationDuration, useNativeDriver: false, }).start(); } else { Animated.timing(elevation, { - toValue: isPressTypeIn ? 8 : cardElevation, + toValue: isPressTypeIn ? (isV3 ? 2 : 8) : cardElevation, duration: animationDuration, useNativeDriver: false, }).start(); @@ -197,13 +197,16 @@ const Card = ({ style={[ { borderRadius: roundness, - elevation: computedElevation as unknown as number, borderColor, }, + !isV3 && { + elevation: computedElevation as unknown as number, + }, cardMode === 'outlined' ? styles.outlined : {}, style, ]} theme={theme} + {...(isV3 && { elevation: computedElevation })} {...rest} > { opacity: opacityAnimation, transform: scaleTransforms, borderRadius: theme.roundness, + ...(!theme.isV3 && { elevation: 8 }), ...(scrollableMenuHeight ? { height: scrollableMenuHeight } : {}), }; @@ -574,6 +575,7 @@ class Menu extends React.Component { contentStyle, ] as StyleProp } + {...(theme.isV3 && { elevation: 2 })} > {(scrollableMenuHeight && ( {children} @@ -595,7 +597,6 @@ const styles = StyleSheet.create({ shadowMenuContainer: { opacity: 0, paddingVertical: 8, - elevation: 8, }, }); diff --git a/src/components/Searchbar.tsx b/src/components/Searchbar.tsx index 7c8b906320..58b27375d8 100644 --- a/src/components/Searchbar.tsx +++ b/src/components/Searchbar.tsx @@ -8,6 +8,7 @@ import { TextInputProps, ViewStyle, TextStyle, + Animated, } from 'react-native'; import color from 'color'; @@ -47,12 +48,16 @@ type Props = React.ComponentPropsWithRef & { * Callback to execute if we want the left icon to act as button. */ onIconPress?: () => void; + /** + * @supported Available in v3.x with theme version 3 + * Changes Searchbar shadow and background on iOS and Android. + */ + elevation?: 0 | 1 | 2 | 3 | 4 | 5 | Animated.Value; /** * Set style of the TextInput component inside the searchbar */ inputStyle?: StyleProp; style?: StyleProp; - /** * @optional */ @@ -113,6 +118,7 @@ const Searchbar = React.forwardRef( onIconPress, placeholder, searchAccessibilityLabel = 'search', + elevation = 1, style, theme, value, @@ -153,8 +159,8 @@ const Searchbar = React.forwardRef( rest.onChangeText?.(''); }; - const { colors, roundness, dark, fonts } = theme; - const textColor = theme.isV3 ? theme.colors.onSurface : theme.colors.text; + const { colors, roundness, dark, fonts, isV3 } = theme; + const textColor = isV3 ? theme.colors.onSurface : theme.colors.text; const font = fonts.regular; const iconColor = customIconColor || @@ -164,10 +170,12 @@ const Searchbar = React.forwardRef( return ( & { /** * Style for the wrapper of the snackbar */ + /** + * @supported Available in v3.x with theme version 3 + * Changes Snackbar shadow and background on iOS and Android. + */ + elevation?: 0 | 1 | 2 | 3 | 4 | 5 | Animated.Value; wrapperStyle?: StyleProp; style?: StyleProp; ref?: React.RefObject; @@ -110,6 +115,7 @@ const Snackbar = ({ duration = DURATION_MEDIUM, onDismiss, children, + elevation = 2, wrapperStyle, style, theme, @@ -168,7 +174,7 @@ const Snackbar = ({ } }, [visible, duration, opacity, scale, onDismiss]); - const { colors, roundness } = theme; + const { colors, roundness, isV3 } = theme; if (hidden) return null; @@ -189,7 +195,7 @@ const Snackbar = ({ accessibilityLiveRegion="polite" style={ [ - !theme.isV3 && { elevation: 6 }, + !isV3 && styles.elevation, styles.container, { borderRadius: roundness, @@ -209,7 +215,7 @@ const Snackbar = ({ style, ] as StyleProp } - {...(theme.isV3 && { elevation: 2 })} + {...(isV3 && { elevation })} {...rest} > {children} From 2d742545ff3877cf90cd54e68139255568743621 Mon Sep 17 00:00:00 2001 From: lukewalczak Date: Sat, 16 Apr 2022 18:34:52 +0200 Subject: [PATCH 2/2] fix: correct shadow opacity --- src/components/Surface.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/Surface.tsx b/src/components/Surface.tsx index 1469202945..42a56bbc2b 100644 --- a/src/components/Surface.tsx +++ b/src/components/Surface.tsx @@ -196,7 +196,11 @@ const Surface = ({ const getStyleForAnimatedShadowLayer = (layer: 0 | 1) => { return { shadowColor, - shadowOpacity: iOSShadowOutputRanges[layer].shadowOpacity, + shadowOpacity: elevation.interpolate({ + inputRange: [0, 1], + outputRange: [0, iOSShadowOutputRanges[layer].shadowOpacity], + extrapolate: 'clamp', + }), shadowOffset: { width: 0, height: elevation.interpolate({ @@ -225,7 +229,7 @@ const Surface = ({ const getStyleForShadowLayer = (layer: 0 | 1) => { return { shadowColor, - shadowOpacity: iOSShadowOutputRanges[layer].shadowOpacity, + shadowOpacity: elevation ? iOSShadowOutputRanges[layer].shadowOpacity : 0, shadowOffset: { width: 0, height: iOSShadowOutputRanges[layer].height[elevation],