jutsu-react-native:react-native-styling

Use this skill when styling React Native components using StyleSheet API, Flexbox layout, and creating responsive, platform-aware designs.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "jutsu-react-native:react-native-styling" with this command: npx skills add thebushidocollective/han/thebushidocollective-han-jutsu-react-native-react-native-styling

React Native Styling

Use this skill when styling React Native components using StyleSheet API, Flexbox layout, and creating responsive, platform-aware designs.

Key Concepts

StyleSheet API

Create optimized styles with StyleSheet:

import { View, Text, StyleSheet } from 'react-native';

export default function Card() { return ( <View style={styles.container}> <Text style={styles.title}>Title</Text> <Text style={styles.body}>Body text</Text> </View> ); }

const styles = StyleSheet.create({ container: { padding: 16, backgroundColor: '#fff', borderRadius: 8, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 4, elevation: 3, // Android shadow }, title: { fontSize: 18, fontWeight: 'bold', color: '#333', marginBottom: 8, }, body: { fontSize: 14, color: '#666', lineHeight: 20, }, });

Flexbox Layout

React Native uses Flexbox by default:

import { View, StyleSheet } from 'react-native';

// Column layout (default) const styles = StyleSheet.create({ column: { flex: 1, flexDirection: 'column', // default justifyContent: 'flex-start', // default alignItems: 'stretch', // default }, });

// Row layout const rowStyles = StyleSheet.create({ row: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', padding: 16, }, });

// Centered content const centeredStyles = StyleSheet.create({ centered: { flex: 1, justifyContent: 'center', alignItems: 'center', }, });

Responsive Design

Use Dimensions for responsive layouts:

import { View, Dimensions, StyleSheet } from 'react-native';

const { width, height } = Dimensions.get('window');

const styles = StyleSheet.create({ container: { width: width * 0.9, // 90% of screen width height: height * 0.5, // 50% of screen height }, card: { width: width > 768 ? 400 : width * 0.9, // Tablet vs phone }, });

Platform-Specific Styles

Apply platform-specific styles:

import { Platform, StyleSheet } from 'react-native';

const styles = StyleSheet.create({ container: { paddingTop: Platform.OS === 'ios' ? 20 : 0, ...Platform.select({ ios: { shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.3, shadowRadius: 4, }, android: { elevation: 4, }, }), }, text: { fontFamily: Platform.select({ ios: 'System', android: 'Roboto', }), }, });

Best Practices

Use StyleSheet.create()

Always use StyleSheet for performance:

// Bad - Creates new object on every render <View style={{ padding: 16, backgroundColor: '#fff' }}> <Text>Content</Text> </View>

// Good - Optimized with StyleSheet const styles = StyleSheet.create({ container: { padding: 16, backgroundColor: '#fff', }, });

<View style={styles.container}> <Text>Content</Text> </View>

Combine Styles with Array

Compose styles using arrays:

import { View, Text, StyleSheet } from 'react-native';

function Button({ primary, disabled }: { primary?: boolean; disabled?: boolean }) { return ( <View style={[ styles.button, primary && styles.buttonPrimary, disabled && styles.buttonDisabled, ]}> <Text style={[ styles.buttonText, primary && styles.buttonTextPrimary, ]}> Press Me </Text> </View> ); }

const styles = StyleSheet.create({ button: { padding: 12, borderRadius: 8, backgroundColor: '#e0e0e0', }, buttonPrimary: { backgroundColor: '#007AFF', }, buttonDisabled: { opacity: 0.5, }, buttonText: { textAlign: 'center', color: '#333', fontWeight: '600', }, buttonTextPrimary: { color: '#fff', }, });

Design Tokens

Create reusable design tokens:

// theme.ts export const colors = { primary: '#007AFF', secondary: '#5856D6', success: '#34C759', error: '#FF3B30', warning: '#FF9500', background: '#FFFFFF', surface: '#F2F2F7', text: { primary: '#000000', secondary: '#3C3C43', tertiary: '#8E8E93', }, };

export const spacing = { xs: 4, sm: 8, md: 16, lg: 24, xl: 32, };

export const typography = { h1: { fontSize: 32, fontWeight: 'bold' as const, lineHeight: 40, }, h2: { fontSize: 24, fontWeight: 'bold' as const, lineHeight: 32, }, body: { fontSize: 16, lineHeight: 24, }, caption: { fontSize: 12, lineHeight: 16, }, };

export const shadows = { small: { shadowColor: '#000', shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.1, shadowRadius: 2, elevation: 2, }, medium: { shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.15, shadowRadius: 4, elevation: 4, }, large: { shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.2, shadowRadius: 8, elevation: 8, }, };

// Usage import { colors, spacing, typography, shadows } from './theme';

const styles = StyleSheet.create({ container: { padding: spacing.md, backgroundColor: colors.background, }, title: { ...typography.h1, color: colors.text.primary, }, card: { ...shadows.medium, borderRadius: 8, }, });

Theme Context

Implement theme switching:

import React, { createContext, useContext, useState } from 'react';

type Theme = { colors: { background: string; text: string; primary: string; }; };

const lightTheme: Theme = { colors: { background: '#FFFFFF', text: '#000000', primary: '#007AFF', }, };

const darkTheme: Theme = { colors: { background: '#000000', text: '#FFFFFF', primary: '#0A84FF', }, };

const ThemeContext = createContext<{ theme: Theme; toggleTheme: () => void; }>({ theme: lightTheme, toggleTheme: () => {}, });

export function ThemeProvider({ children }: { children: React.ReactNode }) { const [isDark, setIsDark] = useState(false);

const toggleTheme = () => setIsDark(!isDark);

return ( <ThemeContext.Provider value={{ theme: isDark ? darkTheme : lightTheme, toggleTheme, }} > {children} </ThemeContext.Provider> ); }

export const useTheme = () => useContext(ThemeContext);

// Usage function MyComponent() { const { theme } = useTheme();

return ( <View style={{ backgroundColor: theme.colors.background }}> <Text style={{ color: theme.colors.text }}>Themed Text</Text> </View> ); }

Common Patterns

Card Component with Variants

import React from 'react'; import { View, Text, StyleSheet, ViewStyle } from 'react-native';

interface CardProps { title: string; children: React.ReactNode; variant?: 'default' | 'outlined' | 'elevated'; }

export default function Card({ title, children, variant = 'default' }: CardProps) { const variantStyle = variant === 'outlined' ? styles.outlined : variant === 'elevated' ? styles.elevated : styles.default;

return ( <View style={[styles.card, variantStyle]}> <Text style={styles.title}>{title}</Text> <View style={styles.content}>{children}</View> </View> ); }

const styles = StyleSheet.create({ card: { borderRadius: 12, padding: 16, marginVertical: 8, }, default: { backgroundColor: '#F2F2F7', }, outlined: { backgroundColor: 'transparent', borderWidth: 1, borderColor: '#C6C6C8', }, elevated: { backgroundColor: '#fff', shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 8, elevation: 4, }, title: { fontSize: 18, fontWeight: 'bold', marginBottom: 12, }, content: { marginTop: 8, }, });

Responsive Grid

import React from 'react'; import { View, Dimensions, StyleSheet } from 'react-native';

const { width } = Dimensions.get('window'); const columns = width > 768 ? 3 : 2; const gap = 16; const itemWidth = (width - (columns + 1) * gap) / columns;

function Grid({ items }: { items: React.ReactNode[] }) { return ( <View style={styles.container}> {items.map((item, index) => ( <View key={index} style={styles.item}> {item} </View> ))} </View> ); }

const styles = StyleSheet.create({ container: { flexDirection: 'row', flexWrap: 'wrap', padding: gap, gap: gap, }, item: { width: itemWidth, }, });

Animated Button

import React from 'react'; import { Pressable, Text, StyleSheet, Animated, PressableStateCallbackType, } from 'react-native';

interface ButtonProps { title: string; onPress: () => void; }

export default function AnimatedButton({ title, onPress }: ButtonProps) { const scale = new Animated.Value(1);

const handlePressIn = () => { Animated.spring(scale, { toValue: 0.95, useNativeDriver: true, }).start(); };

const handlePressOut = () => { Animated.spring(scale, { toValue: 1, useNativeDriver: true, }).start(); };

return ( <Pressable onPress={onPress} onPressIn={handlePressIn} onPressOut={handlePressOut} > {({ pressed }) => ( <Animated.View style={[ styles.button, { transform: [{ scale }] }, pressed && styles.pressed, ]} > <Text style={styles.text}>{title}</Text> </Animated.View> )} </Pressable> ); }

const styles = StyleSheet.create({ button: { backgroundColor: '#007AFF', paddingVertical: 12, paddingHorizontal: 24, borderRadius: 8, alignItems: 'center', }, pressed: { backgroundColor: '#0051D5', }, text: { color: '#fff', fontSize: 16, fontWeight: '600', }, });

Anti-Patterns

Don't Use Percentages for Dimensions

// Bad - Percentages don't work as expected <View style={{ width: '50%' }}> <Text>Half width</Text> </View>

// Good - Use flex or specific dimensions <View style={{ flex: 1 }}> <Text>Full width</Text> </View>

Don't Forget Platform-Specific Shadows

// Bad - Only iOS shadow <View style={{ shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.3, shadowRadius: 4, }}> <Text>Card</Text> </View>

// Good - Both iOS and Android <View style={{ shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.3, shadowRadius: 4, elevation: 4, // Android }}> <Text>Card</Text> </View>

Don't Use Transform for Layout

// Bad - Transform doesn't affect layout <View style={{ transform: [{ translateX: 100 }] }}> <Text>Moved</Text> </View>

// Good - Use margin/padding for layout <View style={{ marginLeft: 100 }}> <Text>Moved</Text> </View>

Don't Hardcode Colors

// Bad - Hardcoded colors <View style={{ backgroundColor: '#007AFF' }}> <Text style={{ color: '#FFFFFF' }}>Text</Text> </View>

// Good - Use design tokens import { colors } from './theme';

<View style={{ backgroundColor: colors.primary }}> <Text style={{ color: colors.text.onPrimary }}>Text</Text> </View>

Related Skills

  • react-native-components: Styling core components

  • react-native-platform: Platform-specific styling considerations

  • react-native-performance: Optimizing style performance

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

android-jetpack-compose

No summary provided by upstream source.

Repository SourceNeeds Review
General

fastapi-async-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

storybook-story-writing

No summary provided by upstream source.

Repository SourceNeeds Review