Skip to content

Commit

Permalink
refactor: add card title and subtitle variants, adjust example
Browse files Browse the repository at this point in the history
  • Loading branch information
lukewalczak committed May 30, 2022
1 parent 71a7b35 commit 5e6cd99
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 58 deletions.
105 changes: 54 additions & 51 deletions example/src/Examples/CardExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,77 +7,82 @@ import {
Button,
IconButton,
useTheme,
Text,
Switch,
Chip,
Text,
} from 'react-native-paper';
import { PreferencesContext } from '..';
import ScreenWrapper from '../ScreenWrapper';

type Mode = 'elevated' | 'outlined' | 'filled';

const CardExample = () => {
const { colors, isV3 } = useTheme();
const [isOutlined, setIsOutlined] = React.useState(false);
const isV2mode = isOutlined ? 'outlined' : 'elevated';
const [isV3mode, setIsV3Mode] = React.useState('elevated') as any;
const [selectedMode, setSelectedMode] = React.useState('elevated' as Mode);
const preferences = React.useContext(PreferencesContext);
const mode = isV3 ? isV3mode : isV2mode;

const modes = isV3
? ['elevated', 'outlined', 'filled']
: ['elevated', 'outlined'];

const TextComponent = isV3 ? Text : Paragraph;

return (
<ScreenWrapper contentContainerStyle={styles.content}>
<View style={styles.preference}>
{isV3 ? (
<>
{['elevated', 'outlined', 'filled'].map((mode) => (
<Chip
key={mode}
icon="heart"
selected={isV3mode === mode}
mode="outlined"
onPress={() => setIsV3Mode(mode)}
style={styles.chip}
>
{mode}
</Chip>
))}
</>
) : (
<>
<Text>Outlined</Text>
<Switch
value={isOutlined}
onValueChange={() =>
setIsOutlined((prevIsOutlined) => !prevIsOutlined)
}
/>
</>
)}
{(modes as Mode[]).map((mode) => (
<Chip
key={mode}
selected={selectedMode === mode}
mode="outlined"
onPress={() => setSelectedMode(mode)}
style={styles.chip}
>
{mode}
</Chip>
))}
</View>
<ScrollView
style={[styles.container, { backgroundColor: colors?.background }]}
contentContainerStyle={styles.content}
>
<Card style={styles.card} mode={mode}>
<Card style={styles.card} mode={selectedMode}>
<Card.Cover
source={require('../../assets/images/wrecked-ship.jpg')}
/>
<Card.Title title="Abandoned Ship" />
<Card.Content>
<Paragraph>
<TextComponent variant="bodyMedium">
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.
</Paragraph>
</TextComponent>
</Card.Content>
</Card>
<Card style={styles.card} mode={mode}>
{isV3 && (
<Card style={styles.card} mode={selectedMode}>
<Card.Cover source={require('../../assets/images/bridge.jpg')} />
<Card.Title
title="Title variant"
subtitle="Subtitle variant"
titleVariant="headlineMedium"
subtitleVariant="bodyLarge"
/>
<Card.Content>
<TextComponent variant="bodyMedium">
This is a card using title and subtitle with specified variants.
</TextComponent>
</Card.Content>
</Card>
)}
<Card style={styles.card} mode={selectedMode}>
<Card.Cover source={require('../../assets/images/forest.jpg')} />
<Card.Actions>
<Button onPress={() => {}}>Share</Button>
<Button onPress={() => {}}>Explore</Button>
</Card.Actions>
</Card>
<Card style={styles.card} mode={mode}>
<Card style={styles.card} mode={selectedMode}>
<Card.Title
title="Berries that are trimmed at the end"
subtitle="Omega Ruby"
Expand All @@ -87,16 +92,16 @@ const CardExample = () => {
)}
/>
<Card.Content>
<Paragraph>
<TextComponent variant="bodyMedium">
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.
</Paragraph>
</TextComponent>
</Card.Content>
</Card>
<Card style={styles.card} mode={mode}>
<Card style={styles.card} mode={selectedMode}>
<Card.Cover
source={require('../../assets/images/strawberries.jpg')}
/>
Expand All @@ -113,50 +118,50 @@ const CardExample = () => {
onPress={() => {
Alert.alert('The Chameleon is Pressed');
}}
mode={mode}
mode={selectedMode}
>
<Card.Cover source={require('../../assets/images/chameleon.jpg')} />
<Card.Title title="Pressable Chameleon" />
<Card.Content>
<Paragraph>
<TextComponent variant="bodyMedium">
This is a pressable chameleon. If you press me, I will alert.
</Paragraph>
</TextComponent>
</Card.Content>
</Card>
<Card
style={styles.card}
onLongPress={() => {
Alert.alert('The City is Long Pressed');
}}
mode={mode}
mode={selectedMode}
>
<Card.Cover source={require('../../assets/images/city.jpg')} />
<Card.Title
title="Long Pressable City"
left={(props) => <Avatar.Icon {...props} icon="city" />}
/>
<Card.Content>
<Paragraph>
<TextComponent variant="bodyMedium">
This is a long press only city. If you long press me, I will
alert.
</Paragraph>
</TextComponent>
</Card.Content>
</Card>
<Card
style={styles.card}
onPress={() => {
preferences.toggleTheme();
}}
mode={mode}
mode={selectedMode}
>
<Card.Title
title="Pressable Theme Change"
left={(props) => <Avatar.Icon {...props} icon="format-paint" />}
/>
<Card.Content>
<Paragraph>
<TextComponent variant="bodyMedium">
This is pressable card. If you press me, I will switch the theme.
</Paragraph>
</TextComponent>
</Card.Content>
</Card>
</ScrollView>
Expand All @@ -178,12 +183,10 @@ const styles = StyleSheet.create({
},
chip: {
margin: 4,
width: 100,
},
preference: {
alignItems: 'center',
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 12,
paddingHorizontal: 8,
},
Expand Down
4 changes: 2 additions & 2 deletions src/components/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,13 @@ const Card = ({
const isPressTypeIn = pressType === 'in';
if (dark && isAdaptiveMode) {
Animated.timing(elevationDarkAdaptive, {
toValue: isPressTypeIn ? (isV3 ? 1 : 8) : cardElevation,
toValue: isPressTypeIn ? (isV3 ? 2 : 8) : cardElevation,
duration: animationDuration,
useNativeDriver: false,
}).start();
} else {
Animated.timing(elevation, {
toValue: isPressTypeIn ? (isV3 ? 1 : 8) : cardElevation,
toValue: isPressTypeIn ? (isV3 ? 2 : 8) : cardElevation,
duration: animationDuration,
useNativeDriver: false,
}).start();
Expand Down
3 changes: 1 addition & 2 deletions src/components/Card/CardActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const CardActions = (props: Props) => {
{React.Children.map(props.children, (child, i) => {
return React.isValidElement(child)
? React.cloneElement(child, {
compact: child.props.compact !== false,
compact: !isV3 && child.props.compact !== false,
mode: isV3 && (i === 0 ? 'outlined' : 'contained'),
style: isV3 && styles.button,
})
Expand All @@ -67,7 +67,6 @@ const styles = StyleSheet.create({
padding: 8,
},
button: {
paddingHorizontal: 24,
marginLeft: 8,
},
});
Expand Down
42 changes: 39 additions & 3 deletions src/components/Card/CardTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from 'react-native';

import { withTheme } from '../../core/theming';
import type { Theme } from '../../types';
import type { MD3TypescaleKey, Theme } from '../../types';
import Caption from '../Typography/v2/Caption';
import Title from '../Typography/v2/Title';
import Text from '../Typography/Text';
Expand All @@ -26,6 +26,23 @@ type Props = React.ComponentPropsWithRef<typeof View> & {
* Number of lines for the title.
*/
titleNumberOfLines?: number;
/**
* @supported Available in v3.x with theme version 3
*
* Title text variant defines appropriate text styles for type role and its size.
* Available variants:
*
* Display: `displayLarge`, `displayMedium`, `displaySmall`
*
* Headline: `headlineLarge`, `headlineMedium`, `headlineSmall`
*
* Title: `titleLarge`, `titleMedium`, `titleSmall`
*
* Label: `labelLarge`, `labelMedium`, `labelSmall`
*
* Body: `bodyLarge`, `bodyMedium`, `bodySmall`
*/
titleVariant?: keyof typeof MD3TypescaleKey;
/**
* Text for the subtitle. Note that this will only accept a string or `<Text>`-based node.
*/
Expand All @@ -38,6 +55,23 @@ type Props = React.ComponentPropsWithRef<typeof View> & {
* Number of lines for the subtitle.
*/
subtitleNumberOfLines?: number;
/**
* @supported Available in v3.x with theme version 3
*
* Subtitle text variant defines appropriate text styles for type role and its size.
* Available variants:
*
* Display: `displayLarge`, `displayMedium`, `displaySmall`
*
* Headline: `headlineLarge`, `headlineMedium`, `headlineSmall`
*
* Title: `titleLarge`, `titleMedium`, `titleSmall`
*
* Label: `labelLarge`, `labelMedium`, `labelSmall`
*
* Body: `bodyLarge`, `bodyMedium`, `bodySmall`
*/
subtitleVariant?: keyof typeof MD3TypescaleKey;
/**
* Callback which returns a React element to display on the left side.
*/
Expand Down Expand Up @@ -99,9 +133,11 @@ const CardTitle = ({
title,
titleStyle,
titleNumberOfLines = 1,
titleVariant = 'bodyLarge',
subtitle,
subtitleStyle,
subtitleNumberOfLines = 1,
subtitleVariant = 'bodyMedium',
left,
leftStyle,
right,
Expand Down Expand Up @@ -144,7 +180,7 @@ const CardTitle = ({
titleStyle,
]}
numberOfLines={titleNumberOfLines}
variant="bodyLarge"
variant={titleVariant}
>
{title}
</TextComponent>
Expand All @@ -154,7 +190,7 @@ const CardTitle = ({
component={subtitleComponent}
style={[styles.subtitle, subtitleStyle]}
numberOfLines={subtitleNumberOfLines}
variant="bodyMedium"
variant={subtitleVariant}
>
{subtitle}
</TextComponent>
Expand Down

0 comments on commit 5e6cd99

Please sign in to comment.