Patterns mobile natif et cross-platform : Android (Kotlin/Compose), iOS (SwiftUI/UIKit), Flutter, React Native/Expo. Se charge quand le code touche du mobile.
From codebloomnpx claudepluginhub vendeesign/codebloom --plugin codebloomThis skill uses the workspace's default tool permissions.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
Se charge automatiquement quand du code touche Android, iOS, Flutter ou React Native.
contentDescription Android, accessibilityLabel iOS/RN)prefers-reduced-motion / accessibilityReduceMotiontransform et opacity — jamais layout (width, height, margin, padding)pointer: coarse (mobile)Avant la logique métier : ./gradlew assembleDebug doit réussir.
!! (crash). Utiliser user?.name ?: "Unknown"Result au ViewModel : runCatching { }.onSuccess { }.onFailure { }nullable (String?) — le backend peut omettre des champs optionnels| Opération | Thread | Raison |
|---|---|---|
| Mutations UI/State | Dispatchers.Main | Obligatoire main thread |
| Network/File I/O | Dispatchers.IO | Ne pas bloquer le main |
| Compute intensif | Dispatchers.Default | JSON parsing, crypto, tri |
@Composable uniquement dans @Composable — LaunchedEffect(Unit) pour suspendremember { mutableStateOf(...) }remember { derivedStateOf { ... } } (évite calculs redondants)StateFlow<UiState> (persiste les config changes)viewModel() ou rememberconst constructors sur les widgets statiquesbackground, icon, view, button) → préfixer : app_background, ic_homedev, prod avec buildConfigField() pour API URLsapp/src/dev/, app/src/prod/.ignoresSafeArea() réservé aux backgroundsUIKit : preferredFont(forTextStyle:) + adjustsFontForContentSizeCategory = true
SwiftUI : styles sémantiques (.headline, .body, .caption) + Font.custom(_:size:relativeTo:)
Reflow aux tailles d'accessibilité sans troncature.
.systemBackground, .label, .primary, .secondary| Pattern | Composant |
|---|---|
| Tab-based (3-5 sections) | UITabBarController / TabView |
| Hiérarchique | UINavigationController / NavigationStack + NavigationPath |
| Modal / tâche focused | Sheet avec dismiss path explicite |
List avec .insetGrouped, .searchableShareLinkProgressView(value:total:) (connu) ou ProgressView() (indéterminé)@Environment(\.scenePhase), @Environment(\.dynamicTypeSize), @Environment(\.accessibilityReduceMotion)@SceneStorage pour persistence entre les tabs| Tâche | Composant |
|---|---|
| Listes | UICollectionView + DiffableDataSource |
| Grilles | UICollectionViewCompositionalLayout |
| Layouts linéaires | UIStackView |
| Boutons modernes | UIButton.Configuration |
| Feedback haptique | UIImpactFeedbackGenerator |
const constructors sur tous les widgets statiquesValueKey pour primitifs, ObjectKey pour objetsConsumerWidget plutôt que StatefulWidget avec providersbuild()Riverpod (recommandé) :
StateProvider + ConsumerWidget pour état simpleNotifierProvider / AsyncNotifierProvider pour complexeref.watch(provider.select(...)) pour rebuilds ciblésBloc/Cubit : pour workflows event-driven avec logique métier complexe
RepaintBoundary pour isoler les animations complexescompute() pour les tâches lourdes (isolates)| Au lieu de... | Utiliser... | Pourquoi |
|---|---|---|
FlatList (> 20 items) | FlashList + memo | View recycling, perf |
Image (RN natif) | expo-image | WebP + cache intégré |
TouchableOpacity | Pressable | API moderne |
expo-av | expo-audio / expo-video | Deprecation |
Animated (RN natif) | Reanimated 3 | GPU optimisé |
PanResponder | Gesture Handler | Gestes propres |
Platform.OS (Expo) | process.env.EXPO_OS | Détection Expo-specific |
useContext (React 18+) | React.use() | Hook moderne |
contentInsetAdjustmentBehavior='automatic' sur tous les scrollables — gère les safe areas sans <SafeAreaView>headerLargeTitle + headerBackButtonDisplayMode pour le feel natif iOS| Besoin | Solution |
|---|---|
| UI locale | useState / useReducer |
| État partagé | Zustand (selectors) ou Jotai (atoms) |
| Données serveur | React Query |
| Formulaires | React Hook Form + Zod |
index.ts qui re-exporte tout)source-map-explorer avant de ship pour identifier le bloat{count && <Text />} rend le string "0" → utiliser {count > 0 && <Text />}app/npx expo start (Expo Go) d'abord — custom builds uniquement si modules natifs locauxCoverage par écran : happy path + error state + empty state + loading state + edge cases (offline, slow network, expired session)