Skip to main content

Styled Components

Styled Components provide a powerful way to create reusable, theme-aware components that automatically handle styling through props. This guide shows you how to create and use styled components effectively.

🎨 Styled Components

Styled components allow you to create reusable, theme-aware components that automatically handle styling through props.

Creating Styled Components

Basic Styled Component Creation

The simplest way to create a styled component is using the styled() function:

import { View, Text, Pressable } from 'react-native';
import { styled } from '@mapples/style';

// Create styled components
const StyledView = styled(View);
const StyledText = styled(Text);
const StyledPressable = styled(Pressable);

Using Styled Components

🚀 Usage

Once created, you can use these components with styled props:

import React from 'react';
import { StyledView, StyledText, StyledPressable } from './components';

const MyComponent = () => {
return (
<StyledView
styled={{
style: {
backgroundColor: 'theme.colors.background',
padding: 'sizing.lg',
borderRadius: 'sizing.md',
},
'&:mobile': {
padding: 'sizing.md',
},
}}
>
<StyledText
styled={{
style: {
color: 'theme.colors.text',
fontSize: 'sizing.lg',
fontWeight: 'bold',
},
}}
>
Welcome to Styled Components
</StyledText>

<StyledPressable
styled={{
style: {
backgroundColor: 'theme.colors.primary',
padding: 'sizing.md',
borderRadius: 'sizing.sm',
alignItems: 'center',
justifyContent: 'center',
},
'&:hover': {
backgroundColor: 'theme.colors.primary',
opacity: 0.8,
},
}}
onPress={() => console.log('Pressed!')}
>
<StyledText
styled={{
style: {
color: 'theme.colors.background',
fontWeight: 'bold',
},
}}
>
Click me
</StyledText>
</StyledPressable>
</StyledView>
);
};

Advanced Styled Component Patterns

Pre-configured Styled Components

Create components with default styling that can be overridden:

import { View, Text } from 'react-native';
import { styled, Styler } from '@mapples/style';

// Create a card component with default styles
const StyledCard = styled(View);

// Create a title component with default styles
const StyledTitle = styled(Text);

// Usage with default styles and overrides
const ProductCard = ({ product }) => {
return (
<StyledCard
styled={{
style: {
backgroundColor: 'theme.colors.surface',
borderRadius: 'sizing.md',
padding: 'sizing.lg',
margin: 'sizing.sm',
shadowColor: 'theme.colors.text',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
'&:mobile': {
margin: 'sizing.xs',
padding: 'sizing.md',
},
}}
>
<StyledTitle
styled={{
style: {
fontSize: 'sizing.lg',
fontWeight: 'bold',
color: 'theme.colors.text',
marginBottom: 'sizing.sm',
},
}}
>
{product.name}
</StyledTitle>

<StyledText
styled={{
style: {
color: 'theme.colors.textSecondary',
fontSize: 'sizing.md',
},
}}
>
{product.description}
</StyledText>
</StyledCard>
);
};

Styled Components with Variants

🎯 Variant Components

Create components that support different visual variants:

import { View, Text } from 'react-native';
import { styled } from '@mapples/style';

const StyledButton = styled(Pressable);
const StyledButtonText = styled(Text);

const Button = ({ variant = 'primary', size = 'md', children, styled, ...props }) => {
const getVariantStyles = () => {
switch (variant) {
case 'primary':
return {
backgroundColor: 'theme.colors.primary',
color: 'theme.colors.background',
};
case 'secondary':
return {
backgroundColor: 'theme.colors.surface',
color: 'theme.colors.primary',
borderWidth: 1,
borderColor: 'theme.colors.primary',
};
case 'ghost':
return {
backgroundColor: 'transparent',
color: 'theme.colors.primary',
};
default:
return {};
}
};

const getSizeStyles = () => {
switch (size) {
case 'sm':
return {
paddingVertical: 'sizing.sm',
paddingHorizontal: 'sizing.md',
};
case 'lg':
return {
paddingVertical: 'sizing.lg',
paddingHorizontal: 'sizing.xl',
};
default:
return {
paddingVertical: 'sizing.md',
paddingHorizontal: 'sizing.lg',
};
}
};

return (
<StyledButton
styled={{
style: {
borderRadius: 'sizing.sm',
alignItems: 'center',
justifyContent: 'center',
...getVariantStyles(),
...getSizeStyles(),
},
'&:hover': {
opacity: 0.8,
},
'&:active': {
transform: [{ scale: 0.95 }],
},
}}
{...props}
>
<StyledButtonText
styled={{
style: {
fontWeight: 'bold',
textAlign: 'center',
color: variant === 'primary' ? 'theme.colors.background' : 'theme.colors.primary',
},
}}
>
{children}
</StyledButtonText>
</StyledButton>
);
};

// Usage
<Button variant="primary" size="lg" styled={{ style: { margin: 'sizing.md' } }}>
Primary Button
</Button>

<Button variant="secondary" size="sm" styled={{ style: { margin: 'sizing.sm' } }}>
Secondary Button
</Button>

Responsive Styled Components

📱 Responsive Design

Create components that adapt to different screen sizes:

import { View, Text } from 'react-native';
import { styled } from '@mapples/style';

const StyledContainer = styled(View);
const StyledGrid = styled(View);
const StyledGridItem = styled(View);

const ResponsiveGrid = ({ children, columns = 1, styled }) => {
return (
<StyledContainer
styled={{
style: {
flex: 1,
padding: 'sizing.md',
'&:mobile': {
padding: 'sizing.sm',
},
},
}}
>
<StyledGrid
styled={{
style: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-between',
'&:mobile': {
flexDirection: 'column',
},
},
}}
>
{children}
</StyledGrid>
</StyledContainer>
);
};

const GridItem = ({ children, span = 1, styled }) => {
return (
<StyledGridItem
styled={{
style: {
flex: span,
margin: 'sizing.sm',
'&:mobile': {
flex: '100%',
margin: 'sizing.xs',
},
'&:tablet': {
flex: span <= 2 ? '50%' : '100%',
},
},
}}
>
{children}
</StyledGridItem>
);
};

// Usage
<ResponsiveGrid>
<GridItem span={1}>
<StyledText styled={{ style: { color: 'theme.colors.text' } }}>
Item 1
</StyledText>
</GridItem>
<GridItem span={2}>
<StyledText styled={{ style: { color: 'theme.colors.text' } }}>
Item 2 (spans 2 columns)
</StyledText>
</GridItem>
</ResponsiveGrid>

Styled Props Patterns

Theme-based Styling

Use theme values in your styled props:

const ThemedCard = ({ children, styled }) => {
return (
<StyledView
styled={{
style: {
backgroundColor: 'theme.colors.surface',
borderColor: 'theme.colors.primary',
borderWidth: 1,
borderRadius: 'sizing.md',
padding: 'sizing.lg',
shadowColor: 'theme.colors.text',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
}}
>
{children}
</StyledView>
);
};

Conditional Styling

🎯 Conditional Logic

Apply styles conditionally based on props or state:

const ConditionalCard = ({ isActive, isSelected, children, styled }) => {
return (
<StyledView
styled={{
style: {
backgroundColor: isActive ? 'theme.colors.primary' : 'theme.colors.surface',
borderColor: isSelected ? 'theme.colors.success' : 'theme.colors.border',
borderWidth: isSelected ? 2 : 1,
borderRadius: 'sizing.md',
padding: 'sizing.md',
opacity: isActive ? 1 : 0.7,
},
'&:hover': {
backgroundColor: isActive ? 'theme.colors.primary' : 'theme.colors.background',
},
}}
>
{children}
</StyledView>
);
};

Style Composition

🎨 Style Composition

Combine multiple style sources:

const ComposedCard = ({ variant, children, styled }) => {
const baseStyles = {
borderRadius: 'sizing.md',
padding: 'sizing.lg',
margin: 'sizing.sm',
};

const variantStyles = {
primary: {
backgroundColor: 'theme.colors.primary',
color: 'theme.colors.background',
},
secondary: {
backgroundColor: 'theme.colors.surface',
color: 'theme.colors.primary',
},
};

return (
<StyledView
styled={{
style: {
...baseStyles,
...variantStyles[variant],
},
}}
>
{children}
</StyledView>
);
};

Best Practices

1. Component Organization

Organize your styled components for better maintainability:

// ✅ Good: Organized styled components
const StyledComponents = {
View: styled(View),
Text: styled(Text),
Pressable: styled(Pressable),
ScrollView: styled(ScrollView),
};

// Usage
<StyledComponents.View styled={{ style: { padding: 'sizing.md' } }}>
<StyledComponents.Text styled={{ style: { color: 'theme.colors.text' } }}>
Content
</StyledComponents.Text>
</StyledComponents.View>

2. Performance Optimization

⚡ Performance

Memoize expensive styled components for better performance:

import { memo } from 'react';

// Memoize expensive styled components
const ExpensiveStyledComponent = memo(({ data, styled }) => {
return (
<StyledView styled={styled}>
{data.map((item, index) => (
<StyledText key={index} styled={{ style: { color: 'theme.colors.text' } }}>
{item.name}
</StyledText>
))}
</StyledView>
);
});

3. TypeScript Support

🔧 TypeScript

Use TypeScript for better development experience:

import { StyledProps } from '@mapples/style';

interface CardProps {
title: string;
content: string;
styled?: StyledProps<CardProps>;
}

const Card = ({ title, content, styled }: CardProps) => {
return (
<StyledView styled={styled}>
<StyledText styled={{ style: { fontWeight: 'bold' } }}>
{title}
</StyledText>
<StyledText styled={{ style: { color: 'theme.colors.textSecondary' } }}>
{content}
</StyledText>
</StyledView>
);
};

What's Next?

🔤 Typography

Learn how to use the Typography component and configure typography settings.

Typography →

🍳 Cookbook

Explore advanced examples and patterns for custom components and styling.

Advanced Examples →

📚 Usage Guide

Learn the basics of setting up and using Styler in your projects.

Basic Setup →