[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6ETX0SMZDFGS58J09BKNRMB":3,"skill-same:01M6ETX0SMZDFGS58J09BKNRMB":121},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":44,"commitSha":45,"skillDirectory":46,"forksCount":47,"repositoryHtmlUrl":48,"repositoryHomepageUrl":49,"ownerHtmlUrl":50,"ownerBlogUrl":6,"ownerDescription":51,"updatedAt":52,"install":53,"resources":66},"01M6ETX0SMZDFGS58J09BKNRMB","building-native-ui",null,"Complete guide for building beautiful apps with Expo Router. Covers fundamentals, styling, components, navigation, animations, patterns, and native tabs.","ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fexpo\u002Fbuilding-native-ui\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000032","设计师","PROFESSION","适用职业",[24,25,26,27,28,29,30,31,32,33,34,35,36,37],"building native ui","ui","native","components","guide","router","styling","navigation","expo","patterns","apps","complete","expo router","with","2026-11-10 10:12:30",false,"---\nname: building-native-ui\ndescription: Complete guide for building beautiful apps with Expo Router. Covers fundamentals, styling, components, navigation, animations, patterns, and native tabs.\nversion: 1.0.0\nlicense: MIT\n---\n\n# Expo UI Guidelines\n\n## References\n\nConsult these resources as needed:\n\n- .\u002Freferences\u002Froute-structure.md -- Route file conventions, dynamic routes, query parameters, groups, and folder organization\n- .\u002Freferences\u002Ftabs.md -- Native tab bar with NativeTabs, migration from JS tabs, iOS 26 features\n- .\u002Freferences\u002Ficons.md -- SF Symbols with expo-symbols, common icon names, animations, and weights\n- .\u002Freferences\u002Fcontrols.md -- Native iOS controls: Switch, Slider, SegmentedControl, DateTimePicker, Picker\n- .\u002Freferences\u002Fvisual-effects.md -- Blur effects with expo-blur and liquid glass with expo-glass-effect\n- .\u002Freferences\u002Fanimations.md -- Reanimated animations: entering, exiting, layout, scroll-driven, and gestures\n- .\u002Freferences\u002Fsearch.md -- Search bar integration with headers, useSearch hook, and filtering patterns\n- .\u002Freferences\u002Fgradients.md -- CSS gradients using experimental_backgroundImage (New Architecture only)\n- .\u002Freferences\u002Fmedia.md -- Media handling for Expo Router including camera, audio, video, and file saving\n- .\u002Freferences\u002Fstorage.md -- Data storage patterns including SQLite, AsyncStorage, and SecureStore\n- .\u002Freferences\u002Fwebgpu-three.md -- 3D graphics, games, and GPU-powered visualizations with WebGPU and Three.js\n\n## Running the App\n\n**CRITICAL: Always try Expo Go first before creating custom builds.**\n\nMost Expo apps work in Expo Go without any custom native code. Before running `npx expo run:ios` or `npx expo run:android`:\n\n1. **Start with Expo Go**: Run `npx expo start` and scan the QR code with Expo Go\n2. **Check if features work**: Test your app thoroughly in Expo Go\n3. **Only create custom builds when required** - see below\n\n### When Custom Builds Are Required\n\nYou need `npx expo run:ios\u002Fandroid` or `eas build` ONLY when using:\n\n- **Local Expo modules** (custom native code in `modules\u002F`)\n- **Apple targets** (widgets, app clips, extensions via `@bacons\u002Fapple-targets`)\n- **Third-party native modules** not included in Expo Go\n- **Custom native configuration** that can't be expressed in `app.json`\n\n### When Expo Go Works\n\nExpo Go supports a huge range of features out of the box:\n\n- All `expo-*` packages (camera, location, notifications, etc.)\n- Expo Router navigation\n- Most UI libraries (reanimated, gesture handler, etc.)\n- Push notifications, deep links, and more\n\n**If you're unsure, try Expo Go first.** Creating custom builds adds complexity, slower iteration, and requires Xcode\u002FAndroid Studio setup.\n\n## Code Style\n\n- Be cautious of unterminated strings. Ensure nested backticks are escaped; never forget to escape quotes correctly.\n- Always use import statements at the top of the file.\n- Always use kebab-case for file names, e.g. `comment-card.tsx`\n- Always remove old route files when moving or restructuring navigation\n- Never use special characters in file names\n- Configure tsconfig.json with path aliases, and prefer aliases over relative imports for refactors.\n\n## Routes\n\nSee `.\u002Freferences\u002Froute-structure.md` for detailed route conventions.\n\n- Routes belong in the `app` directory.\n- Never co-locate components, types, or utilities in the app directory. This is an anti-pattern.\n- Ensure the app always has a route that matches \"\u002F\", it may be inside a group route.\n\n## Library Preferences\n\n- Never use modules removed from React Native such as Picker, WebView, SafeAreaView, or AsyncStorage\n- Never use legacy expo-permissions\n- `expo-audio` not `expo-av`\n- `expo-video` not `expo-av`\n- `expo-symbols` not `@expo\u002Fvector-icons`\n- `react-native-safe-area-context` not react-native SafeAreaView\n- `process.env.EXPO_OS` not `Platform.OS`\n- `React.use` not `React.useContext`\n- `expo-image` Image component instead of intrinsic element `img`\n- `expo-glass-effect` for liquid glass backdrops\n\n## Responsiveness\n\n- Always wrap root component in a scroll view for responsiveness\n- Use `\u003CScrollView contentInsetAdjustmentBehavior=\"automatic\" \u002F>` instead of `\u003CSafeAreaView>` for smarter safe area insets\n- `contentInsetAdjustmentBehavior=\"automatic\"` should be applied to FlatList and SectionList as well\n- Use flexbox instead of Dimensions API\n- ALWAYS prefer `useWindowDimensions` over `Dimensions.get()` to measure screen size\n\n## Behavior\n\n- Use expo-haptics conditionally on iOS to make more delightful experiences\n- Use views with built-in haptics like `\u003CSwitch \u002F>` from React Native and `@react-native-community\u002Fdatetimepicker`\n- When a route belongs to a Stack, its first child should almost always be a ScrollView with `contentInsetAdjustmentBehavior=\"automatic\"` set\n- Prefer `headerSearchBarOptions` in Stack.Screen options to add a search bar\n- Use the `\u003CText selectable \u002F>` prop on text containing data that could be copied\n- Consider formatting large numbers like 1.4M or 38k\n- Never use intrinsic elements like 'img' or 'div' unless in a webview or Expo DOM component\n\n# Styling\n\nFollow Apple Human Interface Guidelines.\n\n## General Styling Rules\n\n- Prefer flex gap over margin and padding styles\n- Prefer padding over margin where possible\n- Always account for safe area, either with stack headers, tabs, or ScrollView\u002FFlatList `contentInsetAdjustmentBehavior=\"automatic\"`\n- Ensure both top and bottom safe area insets are accounted for\n- Inline styles not StyleSheet.create unless reusing styles is faster\n- Add entering and exiting animations for state changes\n- Use `{ borderCurve: 'continuous' }` for rounded corners unless creating a capsule shape\n- ALWAYS use a navigation stack title instead of a custom text element on the page\n- When padding a ScrollView, use `contentContainerStyle` padding and gap instead of padding on the ScrollView itself (reduces clipping)\n- CSS and Tailwind are not supported - use inline styles\n\n## Text Styling\n\n- Add the `selectable` prop to every `\u003CText\u002F>` element displaying important data or error messages\n- Counters should use `{ fontVariant: 'tabular-nums' }` for alignment\n\n## Shadows\n\nUse CSS `boxShadow` style prop. NEVER use legacy React Native shadow or elevation styles.\n\n```tsx\n\u003CView style={{ boxShadow: \"0 1px 2px rgba(0, 0, 0, 0.05)\" }} \u002F>\n```\n\n'inset' shadows are supported.\n\n# Navigation\n\n## Link\n\nUse `\u003CLink href=\"\u002Fpath\" \u002F>` from 'expo-router' for navigation between routes.\n\n```tsx\nimport { Link } from 'expo-router';\n\n\u002F\u002F Basic link\n\u003CLink href=\"\u002Fpath\" \u002F>\n\n\u002F\u002F Wrapping custom components\n\u003CLink href=\"\u002Fpath\" asChild>\n  \u003CPressable>...\u003C\u002FPressable>\n\u003C\u002FLink>\n```\n\nWhenever possible, include a `\u003CLink.Preview>` to follow iOS conventions. Add context menus and previews frequently to enhance navigation.\n\n## Stack\n\n- ALWAYS use `_layout.tsx` files to define stacks\n- Use Stack from 'expo-router\u002Fstack' for native navigation stacks\n\n### Page Title\n\nSet the page title in Stack.Screen options:\n\n```tsx\n\u003CStack.Screen options={{ title: \"Home\" }} \u002F>\n```\n\n## Context Menus\n\nAdd long press context menus to Link components:\n\n```tsx\nimport { Link } from \"expo-router\";\n\n\u003CLink href=\"\u002Fsettings\" asChild>\n  \u003CLink.Trigger>\n    \u003CPressable>\n      \u003CCard \u002F>\n    \u003C\u002FPressable>\n  \u003C\u002FLink.Trigger>\n  \u003CLink.Menu>\n    \u003CLink.MenuAction\n      title=\"Share\"\n      icon=\"square.and.arrow.up\"\n      onPress={handleSharePress}\n    \u002F>\n    \u003CLink.MenuAction\n      title=\"Block\"\n      icon=\"nosign\"\n      destructive\n      onPress={handleBlockPress}\n    \u002F>\n    \u003CLink.Menu title=\"More\" icon=\"ellipsis\">\n      \u003CLink.MenuAction title=\"Copy\" icon=\"doc.on.doc\" onPress={() => {}} \u002F>\n      \u003CLink.MenuAction\n        title=\"Delete\"\n        icon=\"trash\"\n        destructive\n        onPress={() => {}}\n      \u002F>\n    \u003C\u002FLink.Menu>\n  \u003C\u002FLink.Menu>\n\u003C\u002FLink>;\n```\n\n## Link Previews\n\nUse link previews frequently to enhance navigation:\n\n```tsx\n\u003CLink href=\"\u002Fsettings\">\n  \u003CLink.Trigger>\n    \u003CPressable>\n      \u003CCard \u002F>\n    \u003C\u002FPressable>\n  \u003C\u002FLink.Trigger>\n  \u003CLink.Preview \u002F>\n\u003C\u002FLink>\n```\n\nLink preview can be used with context menus.\n\n## Modal\n\nPresent a screen as a modal:\n\n```tsx\n\u003CStack.Screen name=\"modal\" options={{ presentation: \"modal\" }} \u002F>\n```\n\nPrefer this to building a custom modal component.\n\n## Sheet\n\nPresent a screen as a dynamic form sheet:\n\n```tsx\n\u003CStack.Screen\n  name=\"sheet\"\n  options={{\n    presentation: \"formSheet\",\n    sheetGrabberVisible: true,\n    sheetAllowedDetents: [0.5, 1.0],\n    contentStyle: { backgroundColor: \"transparent\" },\n  }}\n\u002F>\n```\n\n- Using `contentStyle: { backgroundColor: \"transparent\" }` makes the background liquid glass on iOS 26+.\n\n## Common route structure\n\nA standard app layout with tabs and stacks inside each tab:\n\n```\napp\u002F\n  _layout.tsx — \u003CNativeTabs \u002F>\n  (index,search)\u002F\n    _layout.tsx — \u003CStack \u002F>\n    index.tsx — Main list\n    search.tsx — Search view\n```\n\n```tsx\n\u002F\u002F app\u002F_layout.tsx\nimport { NativeTabs, Icon, Label } from \"expo-router\u002Funstable-native-tabs\";\nimport { Theme } from \"..\u002Fcomponents\u002Ftheme\";\n\nexport default function Layout() {\n  return (\n    \u003CTheme>\n      \u003CNativeTabs>\n        \u003CNativeTabs.Trigger name=\"(index)\">\n          \u003CIcon sf=\"list.dash\" \u002F>\n          \u003CLabel>Items\u003C\u002FLabel>\n        \u003C\u002FNativeTabs.Trigger>\n        \u003CNativeTabs.Trigger name=\"(search)\" role=\"search\" \u002F>\n      \u003C\u002FNativeTabs>\n    \u003C\u002FTheme>\n  );\n}\n```\n\nCreate a shared group route so both tabs can push common screens:\n\n```tsx\n\u002F\u002F app\u002F(index,search)\u002F_layout.tsx\nimport { Stack } from \"expo-router\u002Fstack\";\nimport { PlatformColor } from \"react-native\";\n\nexport default function Layout({ segment }) {\n  const screen = segment.match(\u002F\\((.*)\\)\u002F)?.[1]!;\n  const titles: Record\u003Cstring, string> = { index: \"Items\", search: \"Search\" };\n\n  return (\n    \u003CStack\n      screenOptions={{\n        headerTransparent: true,\n        headerShadowVisible: false,\n        headerLargeTitleShadowVisible: false,\n        headerLargeStyle: { backgroundColor: \"transparent\" },\n        headerTitleStyle: { color: PlatformColor(\"label\") },\n        headerLargeTitle: true,\n        headerBlurEffect: \"none\",\n        headerBackButtonDisplayMode: \"minimal\",\n      }}\n    >\n      \u003CStack.Screen name={screen} options={{ title: titles[screen] }} \u002F>\n      \u003CStack.Screen name=\"i\u002F[id]\" options={{ headerLargeTitle: false }} \u002F>\n    \u003C\u002FStack>\n  );\n}\n```\n","# Expo UI Guidelines\n\n## References\n\nConsult these resources as needed:\n\n- .\u002Freferences\u002Froute-structure.md -- Route file conventions, dynamic routes, query parameters, groups, and folder organization\n- .\u002Freferences\u002Ftabs.md -- Native tab bar with NativeTabs, migration from JS tabs, iOS 26 features\n- .\u002Freferences\u002Ficons.md -- SF Symbols with expo-symbols, common icon names, animations, and weights\n- .\u002Freferences\u002Fcontrols.md -- Native iOS controls: Switch, Slider, SegmentedControl, DateTimePicker, Picker\n- .\u002Freferences\u002Fvisual-effects.md -- Blur effects with expo-blur and liquid glass with expo-glass-effect\n- .\u002Freferences\u002Fanimations.md -- Reanimated animations: entering, exiting, layout, scroll-driven, and gestures\n- .\u002Freferences\u002Fsearch.md -- Search bar integration with headers, useSearch hook, and filtering patterns\n- .\u002Freferences\u002Fgradients.md -- CSS gradients using experimental_backgroundImage (New Architecture only)\n- .\u002Freferences\u002Fmedia.md -- Media handling for Expo Router including camera, audio, video, and file saving\n- .\u002Freferences\u002Fstorage.md -- Data storage patterns including SQLite, AsyncStorage, and SecureStore\n- .\u002Freferences\u002Fwebgpu-three.md -- 3D graphics, games, and GPU-powered visualizations with WebGPU and Three.js\n\n## Running the App\n\n**CRITICAL: Always try Expo Go first before creating custom builds.**\n\nMost Expo apps work in Expo Go without any custom native code. Before running `npx expo run:ios` or `npx expo run:android`:\n\n1. **Start with Expo Go**: Run `npx expo start` and scan the QR code with Expo Go\n2. **Check if features work**: Test your app thoroughly in Expo Go\n3. **Only create custom builds when required** - see below\n\n### When Custom Builds Are Required\n\nYou need `npx expo run:ios\u002Fandroid` or `eas build` ONLY when using:\n\n- **Local Expo modules** (custom native code in `modules\u002F`)\n- **Apple targets** (widgets, app clips, extensions via `@bacons\u002Fapple-targets`)\n- **Third-party native modules** not included in Expo Go\n- **Custom native configuration** that can't be expressed in `app.json`\n\n### When Expo Go Works\n\nExpo Go supports a huge range of features out of the box:\n\n- All `expo-*` packages (camera, location, notifications, etc.)\n- Expo Router navigation\n- Most UI libraries (reanimated, gesture handler, etc.)\n- Push notifications, deep links, and more\n\n**If you're unsure, try Expo Go first.** Creating custom builds adds complexity, slower iteration, and requires Xcode\u002FAndroid Studio setup.\n\n## Code Style\n\n- Be cautious of unterminated strings. Ensure nested backticks are escaped; never forget to escape quotes correctly.\n- Always use import statements at the top of the file.\n- Always use kebab-case for file names, e.g. `comment-card.tsx`\n- Always remove old route files when moving or restructuring navigation\n- Never use special characters in file names\n- Configure tsconfig.json with path aliases, and prefer aliases over relative imports for refactors.\n\n## Routes\n\nSee `.\u002Freferences\u002Froute-structure.md` for detailed route conventions.\n\n- Routes belong in the `app` directory.\n- Never co-locate components, types, or utilities in the app directory. This is an anti-pattern.\n- Ensure the app always has a route that matches \"\u002F\", it may be inside a group route.\n\n## Library Preferences\n\n- Never use modules removed from React Native such as Picker, WebView, SafeAreaView, or AsyncStorage\n- Never use legacy expo-permissions\n- `expo-audio` not `expo-av`\n- `expo-video` not `expo-av`\n- `expo-symbols` not `@expo\u002Fvector-icons`\n- `react-native-safe-area-context` not react-native SafeAreaView\n- `process.env.EXPO_OS` not `Platform.OS`\n- `React.use` not `React.useContext`\n- `expo-image` Image component instead of intrinsic element `img`\n- `expo-glass-effect` for liquid glass backdrops\n\n## Responsiveness\n\n- Always wrap root component in a scroll view for responsiveness\n- Use `\u003CScrollView contentInsetAdjustmentBehavior=\"automatic\" \u002F>` instead of `\u003CSafeAreaView>` for smarter safe area insets\n- `contentInsetAdjustmentBehavior=\"automatic\"` should be applied to FlatList and SectionList as well\n- Use flexbox instead of Dimensions API\n- ALWAYS prefer `useWindowDimensions` over `Dimensions.get()` to measure screen size\n\n## Behavior\n\n- Use expo-haptics conditionally on iOS to make more delightful experiences\n- Use views with built-in haptics like `\u003CSwitch \u002F>` from React Native and `@react-native-community\u002Fdatetimepicker`\n- When a route belongs to a Stack, its first child should almost always be a ScrollView with `contentInsetAdjustmentBehavior=\"automatic\"` set\n- Prefer `headerSearchBarOptions` in Stack.Screen options to add a search bar\n- Use the `\u003CText selectable \u002F>` prop on text containing data that could be copied\n- Consider formatting large numbers like 1.4M or 38k\n- Never use intrinsic elements like 'img' or 'div' unless in a webview or Expo DOM component\n\n# Styling\n\nFollow Apple Human Interface Guidelines.\n\n## General Styling Rules\n\n- Prefer flex gap over margin and padding styles\n- Prefer padding over margin where possible\n- Always account for safe area, either with stack headers, tabs, or ScrollView\u002FFlatList `contentInsetAdjustmentBehavior=\"automatic\"`\n- Ensure both top and bottom safe area insets are accounted for\n- Inline styles not StyleSheet.create unless reusing styles is faster\n- Add entering and exiting animations for state changes\n- Use `{ borderCurve: 'continuous' }` for rounded corners unless creating a capsule shape\n- ALWAYS use a navigation stack title instead of a custom text element on the page\n- When padding a ScrollView, use `contentContainerStyle` padding and gap instead of padding on the ScrollView itself (reduces clipping)\n- CSS and Tailwind are not supported - use inline styles\n\n## Text Styling\n\n- Add the `selectable` prop to every `\u003CText\u002F>` element displaying important data or error messages\n- Counters should use `{ fontVariant: 'tabular-nums' }` for alignment\n\n## Shadows\n\nUse CSS `boxShadow` style prop. NEVER use legacy React Native shadow or elevation styles.\n\n```tsx\n\u003CView style={{ boxShadow: \"0 1px 2px rgba(0, 0, 0, 0.05)\" }} \u002F>\n```\n\n'inset' shadows are supported.\n\n# Navigation\n\n## Link\n\nUse `\u003CLink href=\"\u002Fpath\" \u002F>` from 'expo-router' for navigation between routes.\n\n```tsx\nimport { Link } from 'expo-router';\n\n\u002F\u002F Basic link\n\u003CLink href=\"\u002Fpath\" \u002F>\n\n\u002F\u002F Wrapping custom components\n\u003CLink href=\"\u002Fpath\" asChild>\n  \u003CPressable>...\u003C\u002FPressable>\n\u003C\u002FLink>\n```\n\nWhenever possible, include a `\u003CLink.Preview>` to follow iOS conventions. Add context menus and previews frequently to enhance navigation.\n\n## Stack\n\n- ALWAYS use `_layout.tsx` files to define stacks\n- Use Stack from 'expo-router\u002Fstack' for native navigation stacks\n\n### Page Title\n\nSet the page title in Stack.Screen options:\n\n```tsx\n\u003CStack.Screen options={{ title: \"Home\" }} \u002F>\n```\n\n## Context Menus\n\nAdd long press context menus to Link components:\n\n```tsx\nimport { Link } from \"expo-router\";\n\n\u003CLink href=\"\u002Fsettings\" asChild>\n  \u003CLink.Trigger>\n    \u003CPressable>\n      \u003CCard \u002F>\n    \u003C\u002FPressable>\n  \u003C\u002FLink.Trigger>\n  \u003CLink.Menu>\n    \u003CLink.MenuAction\n      title=\"Share\"\n      icon=\"square.and.arrow.up\"\n      onPress={handleSharePress}\n    \u002F>\n    \u003CLink.MenuAction\n      title=\"Block\"\n      icon=\"nosign\"\n      destructive\n      onPress={handleBlockPress}\n    \u002F>\n    \u003CLink.Menu title=\"More\" icon=\"ellipsis\">\n      \u003CLink.MenuAction title=\"Copy\" icon=\"doc.on.doc\" onPress={() => {}} \u002F>\n      \u003CLink.MenuAction\n        title=\"Delete\"\n        icon=\"trash\"\n        destructive\n        onPress={() => {}}\n      \u002F>\n    \u003C\u002FLink.Menu>\n  \u003C\u002FLink.Menu>\n\u003C\u002FLink>;\n```\n\n## Link Previews\n\nUse link previews frequently to enhance navigation:\n\n```tsx\n\u003CLink href=\"\u002Fsettings\">\n  \u003CLink.Trigger>\n    \u003CPressable>\n      \u003CCard \u002F>\n    \u003C\u002FPressable>\n  \u003C\u002FLink.Trigger>\n  \u003CLink.Preview \u002F>\n\u003C\u002FLink>\n```\n\nLink preview can be used with context menus.\n\n## Modal\n\nPresent a screen as a modal:\n\n```tsx\n\u003CStack.Screen name=\"modal\" options={{ presentation: \"modal\" }} \u002F>\n```\n\nPrefer this to building a custom modal component.\n\n## Sheet\n\nPresent a screen as a dynamic form sheet:\n\n```tsx\n\u003CStack.Screen\n  name=\"sheet\"\n  options={{\n    presentation: \"formSheet\",\n    sheetGrabberVisible: true,\n    sheetAllowedDetents: [0.5, 1.0],\n    contentStyle: { backgroundColor: \"transparent\" },\n  }}\n\u002F>\n```\n\n- Using `contentStyle: { backgroundColor: \"transparent\" }` makes the background liquid glass on iOS 26+.\n\n## Common route structure\n\nA standard app layout with tabs and stacks inside each tab:\n\n```\napp\u002F\n  _layout.tsx — \u003CNativeTabs \u002F>\n  (index,search)\u002F\n    _layout.tsx — \u003CStack \u002F>\n    index.tsx — Main list\n    search.tsx — Search view\n```\n\n```tsx\n\u002F\u002F app\u002F_layout.tsx\nimport { NativeTabs, Icon, Label } from \"expo-router\u002Funstable-native-tabs\";\nimport { Theme } from \"..\u002Fcomponents\u002Ftheme\";\n\nexport default function Layout() {\n  return (\n    \u003CTheme>\n      \u003CNativeTabs>\n        \u003CNativeTabs.Trigger name=\"(index)\">\n          \u003CIcon sf=\"list.dash\" \u002F>\n          \u003CLabel>Items\u003C\u002FLabel>\n        \u003C\u002FNativeTabs.Trigger>\n        \u003CNativeTabs.Trigger name=\"(search)\" role=\"search\" \u002F>\n      \u003C\u002FNativeTabs>\n    \u003C\u002FTheme>\n  );\n}\n```\n\nCreate a shared group route so both tabs can push common screens:\n\n```tsx\n\u002F\u002F app\u002F(index,search)\u002F_layout.tsx\nimport { Stack } from \"expo-router\u002Fstack\";\nimport { PlatformColor } from \"react-native\";\n\nexport default function Layout({ segment }) {\n  const screen = segment.match(\u002F\\((.*)\\)\u002F)?.[1]!;\n  const titles: Record\u003Cstring, string> = { index: \"Items\", search: \"Search\" };\n\n  return (\n    \u003CStack\n      screenOptions={{\n        headerTransparent: true,\n        headerShadowVisible: false,\n        headerLargeTitleShadowVisible: false,\n        headerLargeStyle: { backgroundColor: \"transparent\" },\n        headerTitleStyle: { color: PlatformColor(\"label\") },\n        headerLargeTitle: true,\n        headerBlurEffect: \"none\",\n        headerBackButtonDisplayMode: \"minimal\",\n      }}\n    >\n      \u003CStack.Screen name={screen} options={{ title: titles[screen] }} \u002F>\n      \u003CStack.Screen name=\"i\u002F[id]\" options={{ headerLargeTitle: false }} \u002F>\n    \u003C\u002FStack>\n  );\n}\n```\n",{"name":5,"license":15,"version":43,"description":7},"1.0.0","main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Faiskillstore\u002Fmarketplace\u002Fexpo\u002Fbuilding-native-ui",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":8,"skillName":5,"commands":54,"prompt":64,"zipAvailable":65},[55,58,61],{"tool":56,"command":57},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill building-native-ui",{"tool":59,"command":60},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill building-native-ui",{"tool":62,"command":63},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill building-native-ui","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fexpo\u002Fbuilding-native-ui\u002FSKILL.md",true,[67,73,77,81,85,89,93,97,101,105,109,113,117],{"path":68,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":71,"sourceHtmlUrl":72},"references\u002Fanimations.md","REFERENCE","参考文档",4747,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fexpo\u002Fbuilding-native-ui\u002Freferences\u002Fanimations.md",{"path":74,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":75,"sourceHtmlUrl":76},"references\u002Fcontrols.md",5055,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fexpo\u002Fbuilding-native-ui\u002Freferences\u002Fcontrols.md",{"path":78,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":79,"sourceHtmlUrl":80},"references\u002Fform-sheet.md",5573,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fexpo\u002Fbuilding-native-ui\u002Freferences\u002Fform-sheet.md",{"path":82,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":83,"sourceHtmlUrl":84},"references\u002Fgradients.md",2717,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fexpo\u002Fbuilding-native-ui\u002Freferences\u002Fgradients.md",{"path":86,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":87,"sourceHtmlUrl":88},"references\u002Ficons.md",4771,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fexpo\u002Fbuilding-native-ui\u002Freferences\u002Ficons.md",{"path":90,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":91,"sourceHtmlUrl":92},"references\u002Fmedia.md",6196,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fexpo\u002Fbuilding-native-ui\u002Freferences\u002Fmedia.md",{"path":94,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":95,"sourceHtmlUrl":96},"references\u002Froute-structure.md",5106,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fexpo\u002Fbuilding-native-ui\u002Freferences\u002Froute-structure.md",{"path":98,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":99,"sourceHtmlUrl":100},"references\u002Fsearch.md",5193,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fexpo\u002Fbuilding-native-ui\u002Freferences\u002Fsearch.md",{"path":102,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":103,"sourceHtmlUrl":104},"references\u002Fstorage.md",2935,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fexpo\u002Fbuilding-native-ui\u002Freferences\u002Fstorage.md",{"path":106,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":107,"sourceHtmlUrl":108},"references\u002Ftabs.md",7981,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fexpo\u002Fbuilding-native-ui\u002Freferences\u002Ftabs.md",{"path":110,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":111,"sourceHtmlUrl":112},"references\u002Fvisual-effects.md",4335,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fexpo\u002Fbuilding-native-ui\u002Freferences\u002Fvisual-effects.md",{"path":114,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":115,"sourceHtmlUrl":116},"references\u002Fwebgpu-three.md",14466,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fexpo\u002Fbuilding-native-ui\u002Freferences\u002Fwebgpu-three.md",{"path":118,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":119,"sourceHtmlUrl":120},"skill-report.json",18663,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fexpo\u002Fbuilding-native-ui\u002Fskill-report.json",[122,136,146,154,160,167],{"skillNo":123,"name":124,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":125,"categories":126,"keywords":132,"publishedAt":38},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[127],{"categoryNo":128,"categoryName":129,"taxonomyType":130,"taxonomyTypeDesc":131},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[133,134,135],"model","model hierarchy","model hierarchy skill",{"skillNo":137,"name":138,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":139,"categories":140,"keywords":142,"publishedAt":38},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[141],{"categoryNo":128,"categoryName":129,"taxonomyType":130,"taxonomyTypeDesc":131},[143,144,145],"MCP","zoom","zoom mcp",{"skillNo":147,"name":148,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":149,"categories":150,"keywords":151,"publishedAt":38},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[152,153,34,144],"sdk","zoom apps sdk",{"skillNo":155,"name":156,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":157,"categories":158,"keywords":159,"publishedAt":38},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[156],{"skillNo":161,"name":162,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":163,"categories":164,"keywords":166,"publishedAt":38},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[165],{"categoryNo":128,"categoryName":129,"taxonomyType":130,"taxonomyTypeDesc":131},[162],{"skillNo":168,"name":169,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":170,"categories":171,"keywords":172,"publishedAt":38},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[169]]