Create Screen¶
Crée un nouvel écran React Native avec sa route Expo Router.
Arguments¶
name(requis) : Nom de l'écran en PascalCase (ex:WalletScreen)
Instructions¶
- Demander à l'utilisateur :
- L'écran est-il public ou authentifié ?
- L'écran fait-il partie des tabs ou est-ce une page modale/détail ?
-
Y a-t-il des paramètres de route (ex:
[id]) ? -
Créer la structure :
Structure de l'écran¶
src/screens/{featureName}/
├── {ScreenName}.tsx
├── components/
│ └── (composants spécifiques à l'écran)
└── hooks/
└── (hooks spécifiques à l'écran, optionnel)
Route Expo Router¶
src/app/(authenticated)/(tabs)/{routeName}.tsx
# ou
src/app/(authenticated)/{routeName}/index.tsx
# ou
src/app/(public)/{routeName}.tsx
Templates¶
Route : src/app/.../{routeName}.tsx¶
Route dynamique : src/app/.../[id].tsx¶
Screen : src/screens/{featureName}/{ScreenName}.tsx¶
import { Box } from "@bricks-common/uimmo/components/Box";
import { SafeAreaBox } from "@bricks-common/uimmo/components/SafeAreaBox";
import { Text } from "@bricks-common/uimmo/components/Text";
import { useTranslation } from "react-i18next";
export const {{ScreenName}} = () => {
const { t } = useTranslation();
return (
<SafeAreaBox edges={["top"]} fill bg="white">
<Box p="xl" fill>
<Text variant="heading/lg">{t("screenTitle.{{featureName}}")}</Text>
{/* TODO: Implement screen content */}
</Box>
</SafeAreaBox>
);
};
Screen avec paramètre : src/screens/{featureName}/{ScreenName}.tsx¶
import { Box } from "@bricks-common/uimmo/components/Box";
import { SafeAreaBox } from "@bricks-common/uimmo/components/SafeAreaBox";
import { Text } from "@bricks-common/uimmo/components/Text";
import { useLocalSearchParams } from "expo-router";
import { useTranslation } from "react-i18next";
export const {{ScreenName}} = () => {
const { t } = useTranslation();
const { id } = useLocalSearchParams<{ id: string }>();
return (
<SafeAreaBox edges={["top"]} fill bg="white">
<Box p="xl" fill>
<Text variant="heading/lg">{t("screenTitle.{{featureName}}")}</Text>
{/* TODO: Use id parameter */}
</Box>
</SafeAreaBox>
);
};
Screen avec données API¶
import { Box } from "@bricks-common/uimmo/components/Box";
import { SafeAreaBox } from "@bricks-common/uimmo/components/SafeAreaBox";
import { Text } from "@bricks-common/uimmo/components/Text";
import { useTranslation } from "react-i18next";
import { useProperty } from "@api/property/useProperty";
import { PropertySkeleton } from "./components/PropertySkeleton";
import { ErrorScreen } from "@components/ErrorScreen";
export const {{ScreenName}} = () => {
const { t } = useTranslation();
const { id } = useLocalSearchParams<{ id: string }>();
const { data, isLoading, isError, refetch } = useProperty(id);
if (isLoading) return <PropertySkeleton />;
if (isError || !data) return <ErrorScreen onRetry={refetch} />;
return (
<SafeAreaBox edges={["top"]} fill bg="white">
<Box p="xl" fill>
<Text variant="heading/lg">{data.name}</Text>
</Box>
</SafeAreaBox>
);
};
Ajouter la traduction¶
Dans src/i18n/locales/fr.json :
Checklist finale¶
- [ ] Screen créé dans
src/screens/{feature}/ - [ ] Route créée dans
src/app/ - [ ] Route exporte uniquement le screen (pas de logique)
- [ ] SafeAreaBox pour les zones sûres
- [ ] Traduction ajoutée pour le titre
- [ ] Early returns pour loading/error si données API
- [ ] Skeleton créé si nécessaire
Règles appliquées¶
- front-expo-routing.mdc
- front-api-data-fetching.mdc
- front-i18n.mdc
- front-cross-platform.mdc