Rn components
Skill almasumdev/awesome-react-native-agent-skills/.github/skills/ui/rn-components
Curated agent skills, conventions, and workflows for building React Native apps with AI coding agents.
npx -y skills add almasumdev/awesome-react-native-agent-skills --skill rn-componentsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Expert guidance on building composable React Native components with StyleSheet, Unistyles, or NativeWind, and using FlashList for performant lists. Use when asked about components, styling, or list rendering.
SKILL.md
4.4 KB, as published. Nobody here has run it
React Native Components & Styling
Instructions
Write function components only. Keep them small, pure, and presentational. Push state and effects into hooks.
1. Component Shape
// src/shared/ui/Button.tsx
import { memo } from 'react';
import { Pressable, Text, StyleSheet } from 'react-native';
import type { PressableProps } from 'react-native';
type Variant = 'primary' | 'secondary';
type ButtonProps = Omit<PressableProps, 'children'> & {
label: string;
variant?: Variant;
};
export const Button = memo(function Button({
label,
variant = 'primary',
disabled,
...rest
}: ButtonProps) {
return (
<Pressable
accessibilityRole="button"
accessibilityState={{ disabled: !!disabled }}
disabled={disabled}
style={({ pressed }) => [
styles.base,
styles[variant],
pressed && styles.pressed,
disabled && styles.disabled,
]}
{...rest}
>
<Text style={[styles.label, variant === 'secondary' && styles.labelSecondary]}>
{label}
</Text>
</Pressable>
);
});
const styles = StyleSheet.create({
base: { paddingHorizontal: 16, paddingVertical: 12, borderRadius: 12, alignItems: 'center' },
primary: { backgroundColor: '#1f6feb' },
secondary: { backgroundColor: 'transparent', borderWidth: 1, borderColor: '#1f6feb' },
pressed: { opacity: 0.85 },
disabled: { opacity: 0.4 },
label: { color: '#ffffff', fontWeight: '600', fontSize: 16 },
labelSecondary: { color: '#1f6feb' },
});
Rules:
- Use
memoonly when props are stable and the component is rendered many times. - Accept a
styleprop viaStyleProp<ViewStyle>to keep components composable. - Keep every styling decision in
StyleSheet.createor a theme-aware wrapper. No inline object literals in JSX.
2. Theming with Unistyles
// src/shared/ui/theme/unistyles.ts
import { UnistylesRegistry } from 'react-native-unistyles';
const light = { colors: { bg: '#ffffff', text: '#0b1220', accent: '#1f6feb' } } as const;
const dark = { colors: { bg: '#0b1220', text: '#e6edf3', accent: '#58a6ff' } } as const;
type AppThemes = { light: typeof light; dark: typeof dark };
type AppBreakpoints = { sm: 0; md: 600; lg: 900 };
declare module 'react-native-unistyles' {
export interface UnistylesThemes extends AppThemes {}
export interface UnistylesBreakpoints extends AppBreakpoints {}
}
UnistylesRegistry.addThemes({ light, dark })
.addBreakpoints({ sm: 0, md: 600, lg: 900 })
.addConfig({ adaptiveThemes: true });
3. NativeWind (Tailwind) Alternative
Use only when the team already writes Tailwind. Configure tailwind.config.js, add the babel plugin, and style via className:
import { View, Text } from 'react-native';
export function Card({ title }: { title: string }) {
return (
<View className="rounded-2xl bg-white p-4 shadow">
<Text className="text-base font-semibold text-slate-900">{title}</Text>
</View>
);
}
4. Lists with FlashList
Always prefer @shopify/flash-list over FlatList for lists longer than one screen.
import { FlashList } from '@shopify/flash-list';
import { ArticleRow } from './ArticleRow';
import type { Article } from '@domain/articles';
export function ArticleList({ data }: { data: readonly Article[] }) {
return (
<FlashList
data={data}
keyExtractor={(a) => a.id}
estimatedItemSize={96}
renderItem={({ item }) => <ArticleRow article={item} />}
getItemType={(a) => (a.body.length > 400 ? 'long' : 'short')}
drawDistance={250}
/>
);
}
Guidance:
- Provide
estimatedItemSizebased on the measured row height. - Use
getItemTypeto let FlashList recycle cells of different layouts. - Memoise row components (
memo+ stable callbacks withuseCallback).
Checklist
- No class components anywhere in the codebase.
- No inline style objects in JSX; all styles come from
StyleSheet.createor theme hooks. - Lists longer than one screen use
FlashListwithestimatedItemSizeand stablekeyExtractor. - Interactive components expose
accessibilityRoleandaccessibilityState. - Row components are memoised and callbacks are wrapped in
useCallback.