ExpoStartup

Card

A versatile card component for displaying content with images, text, and interactive elements.

Card

The Card component is a flexible container for displaying content such as products, articles, or features. It supports different visual styles, interactive behaviors, and can include images, titles, descriptions, prices, ratings, and action buttons.

Features

  • Multiple Variants: Classic, overlay, compact, and minimal styles
  • Interactive: Optional press handlers and link navigation
  • Rich Content: Support for images, text, prices, ratings, and badges
  • Customizable: Control for rounded corners, dimensions, and styling
  • Image Overlay: Optional gradient overlay for better text visibility
  • Action Button: Optional button with custom handler
  • Dark Mode Support: Automatic light/dark mode styles

Import

import Card from '@/components/Card';

Props

Core Props

PropTypeDefaultDescription
titlestringRequiredThe title displayed in the card
descriptionstringOptional description text
imagestringRequiredURI of the image to display
onPress() => voidFunction called when the card is pressed
hrefstringIf provided, card acts as a navigation link
childrenReact.ReactNodeAdditional content to render in the card

Styling Props

PropTypeDefaultDescription
variant'classic' | 'overlay' | 'compact' | 'minimal''classic'The visual style of the card
classNamestring'w-full'Additional Tailwind classes for the container
styleViewStyleReact Native style object for the container
rounded'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full''lg'The border radius of the card
widthnumber | string200Width of the card
imageHeightnumber200Height of the image in pixels

Content Props

PropTypeDefaultDescription
pricestringPrice text to display
ratingnumberRating value (displays with a star icon)
badgestringText for a badge overlay on the image
badgeColorstring'#FF3B30'Background color for the badge
showOverlaybooleantrueWhether to show a gradient overlay (for overlay variant)
overlayGradient[string, string]['transparent', 'rgba(0,0,0,0.3)']Gradient colors for the overlay
buttonstringText for an action button
onButtonPress() => voidFunction called when the button is pressed

Variants

Classic

The default variant with image on top and content below:

<Card
  title="Product Title"
  description="Product description here"
  image="https://example.com/image.jpg"
  variant="classic"
/>

Overlay

Text displays on top of the image with a gradient overlay:

<Card
  title="Featured Article"
  description="Read more about this topic"
  image="https://example.com/image.jpg"
  variant="overlay"
/>

Compact

A more condensed version of the classic card:

<Card
  title="Compact Item"
  image="https://example.com/image.jpg"
  variant="compact"
/>

Minimal

The most simplified version with minimal styling:

<Card
  title="Simple Card"
  image="https://example.com/image.jpg"
  variant="minimal"
/>

Usage Examples

Basic Card

<Card
  title="Mountain Retreat"
  description="A peaceful cabin in the mountains"
  image="https://example.com/cabin.jpg"
/>

Product Card with Price and Rating

<Card
  title="Wireless Headphones"
  description="Premium noise-cancelling headphones"
  image="https://example.com/headphones.jpg"
  price="$249.99"
  rating={4.8}
/>

Card with Badge

<Card
  title="Summer Collection"
  image="https://example.com/summer.jpg"
  badge="NEW"
  badgeColor="#4CAF50"
/>

Card with Action Button

<Card
  title="Premium Subscription"
  description="Unlock all features and content"
  image="https://example.com/premium.jpg"
  button="Subscribe Now"
  onButtonPress={() => handleSubscribe()}
/>
<Card
  title="Travel Guide"
  description="Explore amazing destinations"
  image="https://example.com/travel.jpg"
  href="/guides/travel"
/>

Custom Styling

<Card
  title="Custom Design"
  image="https://example.com/design.jpg"
  rounded="2xl"
  className="shadow-lg"
  width={300}
  imageHeight={250}
/>
<Card
  title="Mountain Sunset"
  image="https://example.com/sunset.jpg"
  variant="overlay"
  overlayGradient={['transparent', 'rgba(0,0,0,0.7)']}
/>

Grid Layout Example

Use with a FlatList or ScrollView for a grid layout:

<FlatList
  data={products}
  numColumns={2}
  renderItem={({ item }) => (
    <Card
      title={item.title}
      description={item.description}
      image={item.image}
      price={item.price}
      rating={item.rating}
      className="m-2"
      width={(windowWidth / 2) - 16}
    />
  )}
/>

Best Practices

Consistent Card Design

Use the same card variant for similar content types:

  • Use classic for product listings with detailed information
  • Use overlay for featured content or media gallery items
  • Use compact for dense grid layouts or side-scrolling lists
  • Use minimal for simple content previews

Image Quality

Ensure images are properly sized and optimized:

<Card
  title="High Quality Image"
  image={imageUrl}
  // Set proper dimensions to avoid layout shifts
  imageHeight={200}
  // Use proper rounded corners for the image
  rounded="md"
/>

Interactive Feedback

Provide clear feedback for interactive cards:

// For cards that navigate
<Card
  title="Learn More"
  image={imageUrl}
  href="/details"
  // The card uses TouchableOpacity with activeOpacity={0.8}
/>
 
// For cards with custom actions
<Card
  title="Custom Action"
  image={imageUrl}
  onPress={() => {
    // Show feedback to user
    Toast.show('Card pressed!');
    // Perform action
    handleCardAction();
  }}
/>

Implementation Details

The Card component uses React Native's TouchableOpacity, View, Text, and Image components for rendering. When the href prop is provided, it uses Expo Router's navigation system.

For the overlay variant, it uses ImageBackground with a LinearGradient to create a visually appealing overlay effect that improves text readability on the image.

The component supports both light and dark mode through the useThemeColors hook and the ThemedText component.

Notes

  • The image prop requires a valid URI string
  • When both href and onPress are provided, href takes precedence
  • For the overlay variant, the text is displayed directly on the image with a gradient background
  • The rating prop automatically adds a star icon next to the numeric value
  • The badge is positioned in the top-right corner of the image
  • The default width is 200 pixels, but can be customized with the width prop