diff --git a/example/src/Examples/CardExample.tsx b/example/src/Examples/CardExample.tsx index f82fb78a0b..74e9559eeb 100644 --- a/example/src/Examples/CardExample.tsx +++ b/example/src/Examples/CardExample.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Alert, ScrollView, StyleSheet } from 'react-native'; +import { Alert, ScrollView, StyleSheet, View } from 'react-native'; import { Avatar, Paragraph, @@ -7,98 +7,120 @@ import { Button, IconButton, useTheme, + Text, + Switch, } from 'react-native-paper'; const CardExample = () => { const { colors: { background }, } = useTheme(); + const [isOutlined, setIsOutlined] = React.useState(false); + const mode = isOutlined ? 'outlined' : 'elevated'; return ( - - - - - - - The Abandoned Ship is a wrecked ship located on Route 108 in Hoenn, - originally being a ship named the S.S. Cactus. The second part of - the ship can only be accessed by using Dive and contains the - Scanner. - - - - - - - - - - - - } - right={(props: any) => ( - {}} /> - )} + + + Outlined + + setIsOutlined((prevIsOutlined) => !prevIsOutlined) + } /> - - - Dotted around the Hoenn region, you will find loamy soil, many of - which are housing berries. Once you have picked the berries, then - you have the ability to use that loamy soil to grow your own - berries. These can be any berry and will require attention to get - the best crop. - - - - - - ( - {}} /> - )} - /> - - { - Alert.alert('The Chameleon is Pressed'); - }} - > - - - - - This is a pressable chameleon. If you press me, I will alert. - - - - { - Alert.alert('The City is Long Pressed'); - }} + + - - } - /> - - - This is a long press only city. If you long press me, I will alert. - - - - + + + + + + The Abandoned Ship is a wrecked ship located on Route 108 in + Hoenn, originally being a ship named the S.S. Cactus. The second + part of the ship can only be accessed by using Dive and contains + the Scanner. + + + + + + + + + + + + } + right={(props: any) => ( + {}} /> + )} + /> + + + Dotted around the Hoenn region, you will find loamy soil, many of + which are housing berries. Once you have picked the berries, then + you have the ability to use that loamy soil to grow your own + berries. These can be any berry and will require attention to get + the best crop. + + + + + + ( + {}} /> + )} + /> + + { + Alert.alert('The Chameleon is Pressed'); + }} + mode={mode} + > + + + + + This is a pressable chameleon. If you press me, I will alert. + + + + { + Alert.alert('The City is Long Pressed'); + }} + mode={mode} + > + + } + /> + + + This is a long press only city. If you long press me, I will + alert. + + + + + ); }; @@ -114,6 +136,12 @@ const styles = StyleSheet.create({ card: { margin: 4, }, + preference: { + alignItems: 'center', + flexDirection: 'row', + justifyContent: 'flex-end', + paddingVertical: 12, + }, }); export default CardExample; diff --git a/package.json b/package.json index 7bbb19ec74..a033247517 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "registry": "https://registry.npmjs.org/" }, "dependencies": { - "@callstack/react-theme-provider": "^3.0.5", + "@callstack/react-theme-provider": "^3.0.6", "color": "^3.1.2", "react-native-iphone-x-helper": "^1.3.1" }, diff --git a/src/components/Card/Card.tsx b/src/components/Card/Card.tsx index 496a86247d..99ffb78bd5 100644 --- a/src/components/Card/Card.tsx +++ b/src/components/Card/Card.tsx @@ -7,6 +7,8 @@ import { View, ViewStyle, } from 'react-native'; +import color from 'color'; +import { white, black } from '../../styles/colors'; import CardContent from './CardContent'; import CardActions from './CardActions'; // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -16,11 +18,21 @@ import CardTitle, { CardTitle as _CardTitle } from './CardTitle'; import Surface from '../Surface'; import { withTheme } from '../../core/theming'; +type OutlinedCardProps = { + mode: 'outlined'; + elevation?: never; +}; + +type ElevatedCardProps = { + mode?: 'elevated'; + elevation?: number; +}; + type Props = React.ComponentProps & { /** * Resting elevation of the card which controls the drop shadow. */ - elevation?: number; + elevation?: never | number; /** * Function to execute on long press. */ @@ -29,6 +41,12 @@ type Props = React.ComponentProps & { * Function to execute on press. */ onPress?: () => void; + /** + * Mode of the Card. + * - `elevated` - Card with elevation. + * - `outlined` - Card with an outline. + */ + mode?: 'elevated' | 'outlined'; /** * Content of the `Card`. */ @@ -85,16 +103,18 @@ const Card = ({ elevation: cardElevation = 1, onLongPress, onPress, + mode: cardMode = 'elevated', children, style, theme, testID, accessible, ...rest -}: Props) => { +}: (OutlinedCardProps | ElevatedCardProps) & Props) => { const { current: elevation } = React.useRef( new Animated.Value(cardElevation) ); + const { animation, dark, mode, roundness } = theme; const handlePressIn = () => { const { @@ -110,27 +130,33 @@ const Card = ({ }; const handlePressOut = () => { - const { - dark, - mode, - animation: { scale }, - } = theme; Animated.timing(elevation, { toValue: cardElevation, - duration: 150 * scale, + duration: 150 * animation.scale, useNativeDriver: !dark || mode === 'exact', }).start(); }; - const { roundness } = theme; const total = React.Children.count(children); const siblings = React.Children.map(children, (child) => React.isValidElement(child) && child.type ? (child.type as any).displayName : null ); + const borderColor = color(theme.dark ? white : black) + .alpha(0.12) + .rgb() + .string(); + return ( - + { + it('renders an outlined card', () => { + const tree = renderer.create().toJSON(); + + expect(tree).toMatchSnapshot(); + }); +}); diff --git a/src/components/__tests__/Card/__snapshots__/Card.test.js.snap b/src/components/__tests__/Card/__snapshots__/Card.test.js.snap new file mode 100644 index 0000000000..999596f3fb --- /dev/null +++ b/src/components/__tests__/Card/__snapshots__/Card.test.js.snap @@ -0,0 +1,33 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Card renders an outlined card 1`] = ` + + + +`; diff --git a/yarn.lock b/yarn.lock index 14a2ce4294..bd41595f30 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1806,10 +1806,10 @@ eslint-restricted-globals "^0.2.0" prettier "^1.19.1" -"@callstack/react-theme-provider@^3.0.5": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@callstack/react-theme-provider/-/react-theme-provider-3.0.5.tgz#a173e455e9603c9c45357a3b6ace1273086527ca" - integrity sha512-Iec+ybWN0FvNj87sD3oWo/49edGUP0UOSdMnzCJEFJIDYr992ECIuOV89burAAh2/ibPCxgLiK6dmgv2mO/8Tg== +"@callstack/react-theme-provider@^3.0.6": + version "3.0.6" + resolved "https://registry.yarnpkg.com/@callstack/react-theme-provider/-/react-theme-provider-3.0.6.tgz#7dac483037e27e28676bdf1431ba87b88f21118f" + integrity sha512-wwKMXfmklfogpalNZT0W+jh76BIquiYUiQHOaPmt/PCyCEP/E6rP+e7Uie6mBZrfkea9WJYJ+mus6r+45JAEhg== dependencies: deepmerge "^3.2.0" hoist-non-react-statics "^3.3.0"