Card
The Card component is a versatile container for displaying content in a structured manner. It can include headers, bodies, footers, and supports various visual styles like shadows, radii, and blur effects.
Installation
$ cbui-cli install card
cbui-cli
globally and authenticated your account. This will ensure you can access all the necessary features.Import
1import { Card, CardHeader, CardBody, CardFooter, CardContext, useCardContext } from '@/crossbuildui/card';
2// Ensure 'expo-blur' is installed and configured.
3// import { View, Text, Image } from 'react-native'; // For content
4// import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; // For icons
CardHeader
, CardBody
, CardFooter
) can utilize expo-blur
for blur effects. If you plan to use the isBlurred
or isFooterBlurred
props, ensure expo-blur
is installed and properly configured in your Expo project.Basic Usage
Compose a card using CardHeader
, CardBody
, and CardFooter
as children of the main Card
component.
1<Card>
2 <CardHeader>
3 <Text style={{ fontSize: 18, fontWeight: 'bold' }}>Card Title</Text>
4 </CardHeader>
5 <CardBody>
6 <Text>This is the main content of the card. It can contain text, images, or any other components.</Text>
7 </CardBody>
8 <CardFooter>
9 <Button size="sm">Learn More</Button>
10 </CardFooter>
11</Card>
Shadows & Radius
Control the card's elevation and corner rounding with the shadow
and radius
props.
1<View style={{ flexDirection: 'row', justifyContent: 'space-around', flexWrap: 'wrap' }}>
2 <Card shadow="sm" radius="sm" style={{ width: 150, margin: 10 }}>
3 <CardBody><Text>Small Shadow, Small Radius</Text></CardBody>
4 </Card>
5 <Card shadow="md" radius="md" style={{ width: 150, margin: 10 }}>
6 <CardBody><Text>Medium Shadow (Default), Medium Radius (Default)</Text></CardBody>
7 </Card>
8 <Card shadow="lg" radius="lg" style={{ width: 150, margin: 10 }}>
9 <CardBody><Text>Large Shadow, Large Radius</Text></CardBody>
10 </Card>
11 <Card shadow="none" radius="none" style={{ width: 150, margin: 10 }}>
12 <CardBody><Text>No Shadow, No Radius</Text></CardBody>
13 </Card>
14</View>
Pressable Card
Make the card interactive by setting isPressable
to true. You can handle press events with onPress
and control background changes with changeBgOnPress
.
1const [count, setCount] = useState(0);
2
3<Card
4 isPressable
5 onPress={() => setCount(count + 1)}
6 style={{ alignItems: 'center', padding: 20 }}
7>
8 <Text>Press me!</Text>
9 <Text>Pressed: {count} times</Text>
10</Card>
11
12// Without background change on press
13<Card isPressable changeBgOnPress={false} onPress={() => console.log('Pressed!')}>
14 <CardBody><Text>Pressable, no BG change</Text></CardBody>
15</Card>
Blurred Card
Apply a blur effect to the entire card using isBlurred
and adjust its intensity with blurIntensity
. You can also specifically blur the footer using isFooterBlurred
on the Card
component.
1// Whole card blurred
2<Card isBlurred blurIntensity={20} style={{ width: 200 }}>
3 <CardHeader><Text style={{color: 'white', fontWeight: 'bold'}}>Blurred Card</Text></CardHeader>
4 <CardBody><Text style={{color: 'white'}}>Content inside a blurred card.</Text></CardBody>
5</Card>
6
7// Card with blurred footer (controlled by Card prop)
8<Card isFooterBlurred blurIntensity={30} style={{ width: 200, marginTop: 10 }}>
9 <CardHeader><Text>Normal Header</Text></CardHeader>
10 <CardBody><Text>Normal Body</Text></CardBody>
11 <CardFooter>
12 <Text style={{color: 'white'}}>Blurred Footer Content</Text>
13 </CardFooter>
14</Card>
Blurred Sections
Apply blur effects to individual sections (CardHeader
, CardBody
, CardFooter
) by setting the isBlurred
prop directly on them. Note: If the entire Card
has isBlurred=
, the footer will also blur unless isBlurred=
is explicitly set on the CardFooter
itself.
1// Card with only header blurred
2<Card style={{ width: 250, marginVertical: 10 }}>
3 <CardHeader isBlurred blurIntensity={25}>
4 <Text style={{ fontWeight: 'bold', color: 'white' }}>Blurred Header</Text>
5 </CardHeader>
6 <CardBody>
7 <Text>This body is not blurred.</Text>
8 </CardBody>
9</Card>
10
11// Card with only body blurred
12<Card style={{ width: 250, marginVertical: 10 }}>
13 <CardHeader>
14 <Text style={{ fontWeight: 'bold' }}>Normal Header</Text>
15 </CardHeader>
16 <CardBody isBlurred blurIntensity={25}>
17 <Text style={{ color: 'white' }}>This body is blurred.</Text>
18 <Text style={{ color: 'white', marginTop: 5 }}>More blurred content.</Text>
19 </CardBody>
20 <CardFooter>
21 <Text>Normal Footer</Text>
22 </CardFooter>
23</Card>
24
25// Card with only footer blurred (controlled by CardFooter prop)
26<Card style={{ width: 250, marginVertical: 10 }}>
27 <CardHeader><Text style={{ fontWeight: 'bold' }}>Normal Header</Text></CardHeader>
28 <CardBody><Text>Normal Body</Text></CardBody>
29 <CardFooter isBlurred blurIntensity={25}>
30 <Text style={{ color: 'white' }}>This footer is blurred.</Text>
31 </CardFooter>
32</Card>
Full Width
Make the card span the full width of its parent container by setting fullWidth=
.
1<Card fullWidth>
2 <CardHeader><Text style={{fontWeight: 'bold'}}>Full Width Card</Text></CardHeader>
3 <CardBody><Text>This card spans the entire width of its parent.</Text></CardBody>
4</Card>
Disabled State
Disable the card, affecting its appearance and interactivity if pressable, using the disabled
prop.
1<Card isPressable disabled onPress={() => console.log('Should not log')}>
2 <CardHeader><Text>Disabled Pressable Card</Text></CardHeader>
3 <CardBody><Text>This card looks and acts disabled.</Text></CardBody>
4</Card>
5
6<Card disabled style={{marginTop: 10}}>
7 <CardHeader><Text>Disabled Non-Pressable Card</Text></CardHeader>
8 <CardBody><Text>Content is visually dimmed.</Text></CardBody>
9</Card>
Complex Layout Example
Cards can be used to build more complex UI elements by combining them with other components and custom styling.
1<Card shadow="lg" radius="lg" style={{ marginVertical: 10 }}>
2 <CardHeader style={{ flexDirection: 'row', alignItems: 'center', borderBottomWidth: 1, borderBottomColor: '#eee' }}>
3 <Image source={{ uri: 'https://i.pravatar.cc/40?u=a042581f4e29026024d' }} style={{ width: 40, height: 40, borderRadius: 20, marginRight: 10 }} />
4 <View>
5 <Text style={{ fontWeight: 'bold' }}>User Name</Text>
6 <Text style={{ fontSize: 12, color: 'gray' }}>Posted 2 hours ago</Text>
7 </View>
8 </CardHeader>
9 <CardBody>
10 <Image source={{ uri: 'https://picsum.photos/seed/picsum/400/200' }} style={{ width: '100%', height: 150, borderRadius: 8, marginBottom: 10 }} resizeMode="cover" />
11 <Text>This is a more complex card layout with an image and structured content.</Text>
12 </CardBody>
13 <CardFooter style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
14 <View style={{ flexDirection: 'row', alignItems: 'center' }}>
15 {/* <Icon name="heart-outline" size={20} color="red" /> */}
16 <Text style={{ marginLeft: 4 }}>12 Likes</Text>
17 </View>
18 <Button size="sm" variant="flat">Comment</Button>
19 </CardFooter>
20</Card>
Using Card Context
For advanced use cases or creating deeply integrated custom child components, you can access the Card's properties using the useCardContext
hook. This hook consumes CardContext
and provides access to props like shadow
, radius
, isPressable
, isBlurred
, fullWidth
, disabled
, and more, directly from within any descendant of the Card
component.
This is useful if you are building custom components that need to react to the Card's state or configuration without explicit prop drilling.
1import { Card, CardBody, useCardContext } from '@/crossbuildui/card';
2import { Text, View } from 'react-native';
3
4const CardInfoDisplay = () => {
5 const context = useCardContext();
6
7 if (!context) {
8 return <Text>This component must be used within a Card.</Text>;
9 }
10
11 const { shadow, radius, isPressable, isBlurred, fullWidth } = context;
12
13 return (
14 <View style={{ marginTop: 8, padding: 8, backgroundColor: '#f0f0f0', borderRadius: 4 }}>
15 <Text>Card Context Info:</Text>
16 <Text>- Shadow: {shadow}, Radius: {radius}</Text>
17 <Text>- Pressable: {isPressable ? 'Yes' : 'No'}, Blurred: {isBlurred ? 'Yes' : 'No'}</Text>
18 <Text>- Full Width: {fullWidth ? 'Yes' : 'No'}</Text>
19 </View>
20 );
21};
22
23<Card shadow="sm" radius="lg" isPressable><CardBody><Text>Card Content</Text><CardInfoDisplay /></CardBody></Card>
Props Overview
Card Props
PROP | TYPE | DEFAULT | DESCRIPTION |
---|---|---|---|
children | ReactNode | - | Content, typically CardHeader , CardBody , CardFooter . |
shadow | 'none' | 'sm' | 'md' | 'lg' | 'md' | Shadow depth. |
radius | 'none' | 'sm' | 'md' | 'lg' | 'md' | Border radius. |
fullWidth | boolean | false | If true, card takes full parent width. |
isPressable | boolean | false | Makes the card pressable. |
changeBgOnPress | boolean | true | Change background on press if pressable. |
isBlurred | boolean | false | Apply blur effect to the entire card. |
blurIntensity | number | 10 | Blur intensity (1-100). |
isFooterBlurred | boolean | false | Apply blur effect specifically to the footer. |
disabled | boolean | false | Disable the card. |
disableAnimation | boolean | false | Disable press animations. |
disableRipple | boolean | false | Disable Android ripple effect. |
allowTextSelectionOnPress | boolean | false | Allow text selection during press. |
styles | CardSlotsStyles | - | Custom styles for card slots (base, header, body, footer, blurredView, footerBlurredView). |
style | StyleProp<ViewStyle> | - | Style for the card's outermost container. |
onPress | (event) => void | - | Callback for press events if isPressable . |
...PressableProps | various | - | Other props from React Native's Pressable. |
CardHeader Props
PROP | TYPE | DEFAULT | DESCRIPTION |
---|---|---|---|
children | ReactNode | - | Content of the header. |
style | StyleProp<ViewStyle> | - | Style for the header container. |
isBlurred | boolean | false | Apply blur effect to the header. |
blurIntensity | number | 50 | Blur intensity (1-100). |
CardBody Props
PROP | TYPE | DEFAULT | DESCRIPTION |
---|---|---|---|
children | ReactNode | - | Content of the body. |
style | StyleProp<ViewStyle> | - | Style for the body container. |
isBlurred | boolean | false | Apply blur effect to the body. |
blurIntensity | number | 50 | Blur intensity (1-100). |
CardFooter Props
PROP | TYPE | DEFAULT | DESCRIPTION |
---|---|---|---|
children | ReactNode | - | Content of the footer. |
style | StyleProp<ViewStyle> | - | Style for the footer container. |
isBlurred | boolean | false | Apply blur effect to the footer (behavior also influenced by Card's isBlurred and isFooterBlurred props). |
blurIntensity | number | 50 | Blur intensity (1-100). |
Styling
Customize the appearance of the Card and its sections:
- Card Component:
style
: Applied to the outermost container of the Card (which could be aView
,Pressable
, orBlurView
). Use for margins, width, etc.styles
(slot styles): An object to style specific internal parts of the Card:base
: Styles the direct content holder view within the Card (the one that gets the main background color and border radius if not blurred, or the content wrapper inside BlurView).header
: (Not directly used by Card, but defined in types. Styling for header is via CardHeader's own style prop or by targeting it through children).body
: (Similar to header).footer
: (Similar to header).blurredView
: Styles applied to theBlurView
component whenisBlurred
is true on theCard
.footerBlurredView
: (Not directly used by Card, footer blur is handled by cloning CardFooter with blur props).
- CardHeader, CardBody, CardFooter Components:
style
: Applied to the root container of each sub-component. Use for padding, background color (if not blurred), borders, etc.
The Card
component intelligently handles background colors. If you provide a backgroundColor
in the Card
's main style
prop, it will be used as the card's background. If the card is isBlurred
, this background color will be applied to the content *inside* the blur, allowing the blur effect to tint it.
1// Styling the Card container and its slots
2// Card.styles.base is applied to the inner content holder.
3// Card.styles.blurredView is applied to the BlurView if Card isBlurred.
4// Note: Card.styles.header, .body, .footer are defined in types but not directly applied by Card to its children.
5// Style CardHeader, CardBody, CardFooter via their own 'style' prop.
6<Card
7 isBlurred // Example to show blurredView styling
8 blurIntensity={5}
9 style={{ marginVertical: 10 }} // Styles the outermost Card container (BlurView in this case)
10 styles={{
11 base: { backgroundColor: 'rgba(255, 255, 0, 0.3)' }, // Content holder inside BlurView
12 blurredView: { borderColor: 'purple', borderWidth: 1 } // Styles the BlurView itself
13 }}
14 radius="none"
15>
16 <CardHeader>
17 <Text style={{color: 'black'}}>Styled Header (text color for contrast)</Text>
18 </CardHeader>
19 <CardBody>
20 <Text style={{color: 'black'}}>Content with custom slot styling.</Text>
21 </CardBody>
22 <CardFooter>
23 <Text style={{color: 'black'}}>Styled Footer</Text>
24 </CardFooter>
25</Card>
Accessibility
The Card component itself is a container. Accessibility largely depends on its content and usage:
- If the card is
isPressable
, it behaves like aPressable
and will haveaccessibilityRole="button"
by default. Ensure meaningful content or anaccessibilityLabel
is provided for screen readers. - Content within
CardHeader
,CardBody
, andCardFooter
should follow standard accessibility practices for text, images, and interactive elements. - For complex cards, consider using semantic headers (e.g., larger text for titles) to aid navigation.