원클릭으로
create-screen
Add a new screen or tab to the app with routing and i18n
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Add a new screen or tab to the app with routing and i18n
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Transform the base template into a specific application
Add or update i18n keys in both English and Arabic locale files
Scaffold a UI component with unistyles variants pattern
Scaffold a complete feature module with types, service, hooks, schema, and constants
Generate a validated form with Zod schema, react-hook-form, and i18n
Review changed code against project conventions and rules
| name | create-screen |
| description | Add a new screen or tab to the app with routing and i18n |
| auto-invocable | true |
| triggers | ["add a screen","create a page","add a tab","new screen","new tab","create a route"] |
Add a new screen or tab following expo-router conventions and project patterns.
Ask the user for:
app/(main)/(tabs)/<name>.tsxapp/(main)/<name>.tsxapp/(auth)/<name>.tsx/create-feature firstScreen files use lowercase with hyphens and default exports.
// app/(main)/(tabs)/<name>.tsx OR app/(main)/<name>.tsx
import { useTranslation } from 'react-i18next';
import { StyleSheet } from 'react-native-unistyles';
import { ScreenContainer } from '@/common/components/ScreenContainer';
import { Text } from '@/common/components/Text';
import { ErrorBoundary } from '@/common/components/ErrorBoundary';
export default function <Name>Screen() {
const { t } = useTranslation();
return (
<ScreenContainer scrollable padded>
<ErrorBoundary>
<Text variant="h1">{t('<name>.title')}</Text>
</ErrorBoundary>
</ScreenContainer>
);
}
const styles = StyleSheet.create((theme) => ({
// Add styles as needed
}));
If protected (requires auth):
import { useProtectedRoute } from '@/hooks/useProtectedRoute';
export default function <Name>Screen() {
useProtectedRoute(); // Redirects to /(auth)/login if not authenticated
const { t } = useTranslation();
// ... rest of screen
}
Edit app/(main)/(tabs)/_layout.tsx to add the new tab:
<Tabs.Screen
name="<name>"
options={{
title: t('tabs.<name>'),
tabBarIcon: ({ color, size }) => (
<Icon name="<icon-name>-outline" color={color} size={size} />
),
}}
/>
The Icon component uses Ionicons names. Choose an appropriate icon from the Ionicons set.
Current tab layout reference (app/(main)/(tabs)/_layout.tsx):
TabBar component: tabBar={(props) => <TabBar {...props} />}headerShown: false in screenOptionsIcon from @/common/components/Icon if adding tabBarIconUpdate BOTH src/i18n/locales/en.json and src/i18n/locales/ar.json:
// For the screen content
{
"<name>": {
"title": "<Screen Title>",
"subtitle": "<Optional subtitle>"
}
}
// If it's a tab, also add under "tabs":
{
"tabs": {
"<name>": "<Tab Label>"
}
}
Provide Arabic translations for both. Mark uncertain ones with TODO in commit.
If the screen is navigated to from another screen, add the navigation call:
import { router } from 'expo-router';
// Navigate to the screen
router.push('/(main)/<name>');
// Or with params
router.push({ pathname: '/(main)/<name>', params: { id: '123' } });
Run npm run validate to ensure no TypeScript or lint errors.
import { FlatList } from 'react-native';
import { Loading } from '@/common/components/Loading';
import { EmptyState } from '@/common/components/EmptyState';
import { use<Entities> } from '@/features/<name>/hooks/use<Name>';
export default function <Name>Screen() {
const { t } = useTranslation();
const { data, isLoading } = use<Entities>();
if (isLoading) return <Loading fullScreen />;
return (
<ScreenContainer>
<FlatList
data={data}
keyExtractor={(item) => item.id}
renderItem={({ item }) => <ItemCard item={item} />}
ListEmptyComponent={<EmptyState title={t('<name>.empty')} />}
/>
</ScreenContainer>
);
}
import { useLocalSearchParams } from 'expo-router';
import { use<Entity> } from '@/features/<name>/hooks/use<Name>';
export default function <Name>DetailScreen() {
const { id } = useLocalSearchParams<{ id: string }>();
const { data, isLoading } = use<Entity>(id);
// ...
}
export default (expo-router requirement)order-details.tsx, NOT OrderDetails.tsxStyleSheet from react-native-unistyles, NOT react-nativeText from @/common/components/Text, NOT react-nativeuseTranslation()ScreenContainerErrorBoundary for data-driven screens