Implement custom tab bar and introduce core styling utilities#1
Conversation
This commit establishes the main navigation structure with a custom-designed bottom tab bar, enhancing the user interface and providing a consistent look and feel. * Introduces `app/(tabs)/_layout.tsx` for a custom tab bar implementation using `expo-router`'s `Tabs` component, complete with bespoke styling and icon handling. * Adds `constants/theme.ts` and `constants/data.ts` to centralize color schemes, spacing, component dimensions, and tab configuration. * Integrates `clsx` for dynamic class name generation within the tab bar. * Moves `subscriptions/[id]` outside the `(tabs)` directory, allowing it to function as a standalone detail screen rather than a primary tab. * Updates existing tab screens (`index`, `insights`, `settings`, `subscriptions`) to use `SafeAreaView` and aligns them with the new theming approach. * Adds a comprehensive set of font, icon, and image assets to support the new UI. * Includes `image.d.ts` and `type.d.ts` for improved TypeScript support for assets and global interfaces.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThis PR replaces the tab root with a custom ChangesTab Bar and Theme Infrastructure
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant TabsLayout
participant tabsData as tabs (constants/data.ts)
participant TabIcon
participant Tabs as expo-router Tabs
TabsLayout->>tabsData: map tabs array
TabsLayout->>Tabs: render Tabs.Screen per tab
Tabs->>TabIcon: tabBarIcon(focused, icon)
TabIcon-->>Tabs: styled icon view
Tabs-->>TabsLayout: rendered tab bar
Related Issues: None found in provided context. Related PRs: None found in provided context. Suggested labels: enhancement, ui Suggested reviewers: devcedrick Poem: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Pull request overview
This PR establishes a custom bottom tab navigation UI (via expo-router Tabs) and introduces centralized styling utilities (theme constants + tab configuration), while moving the subscription details screen to a standalone route outside the tab group.
Changes:
- Added a custom-styled tab bar in
app/(tabs)/_layout.tsx, driven by centralized tab config (constants/data.ts) and theme tokens (constants/theme.ts). - Introduced shared constants and asset typing support (
constants/*,image.d.ts,type.d.ts) and addedclsxfor conditional tab icon styling. - Moved
subscriptions/[id]toapp/subscriptions/[id].tsxand updated the Home tab link to use the dynamic route.
Reviewed changes
Copilot reviewed 10 out of 58 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| type.d.ts | Adds global typing for tab icon props used by the custom tab bar. |
| package.json | Adds clsx dependency for conditional class name composition. |
| package-lock.json | Locks clsx dependency. |
| image.d.ts | Adds TypeScript module declarations for image imports. |
| constants/theme.ts | Centralizes colors, spacing scale, and tab bar sizing tokens. |
| constants/icons.ts | Centralizes icon imports/exports for use across the app. |
| constants/data.ts | Defines the tab configuration (name/title/icon) used to generate tab screens. |
| assets/expo.icon/icon.json | Adds/updates Expo icon asset metadata. |
| assets/expo.icon/Assets/expo-symbol 2.svg | Adds an SVG asset used by the Expo icon set. |
| app/subscriptions/[id].tsx | Introduces a standalone subscription details screen using a dynamic route. |
| app/(tabs)/subscriptions.tsx | Updates tab screen wrapper to use SafeAreaView. |
| app/(tabs)/settings.tsx | Updates tab screen wrapper to use SafeAreaView. |
| app/(tabs)/insights.tsx | Updates tab screen wrapper to use SafeAreaView. |
| app/(tabs)/index.tsx | Updates Home tab layout to use SafeAreaView and links to the dynamic subscription details route. |
| app/(tabs)/_layout.tsx | Implements custom tab bar styling and icon rendering based on centralized config/theme. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export { | ||
| activity, | ||
| add, | ||
| adobe, | ||
| back, | ||
| canva, | ||
| claude, | ||
| dropbox, | ||
| figma, | ||
| github, | ||
| home, | ||
| logo, | ||
| medium, | ||
| menu, | ||
| netflix, | ||
| notion, | ||
| openai, | ||
| plus, | ||
| setting, | ||
| spotify, | ||
| wallet | ||
| }; |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/`(tabs)/_layout.tsx:
- Around line 62-67: The Tabs.Screen registration for subscriptions/[id] in the
_layout component no longer matches a child route under app/(tabs)/, so it
should be moved to the parent navigator that owns the subscriptions/[id] route,
or the route file should be kept under (tabs) if it is meant to remain a tab
child. Update the navigator setup in _layout so the screen is registered where
the actual route lives, and remove the mismatched tab-level registration.
- Around line 14-22: `TabIcon` is defined inside `TabsLayout`, which creates a
new component type on every render and can remount the icon tree unnecessarily.
Move `TabIcon` out of the `TabsLayout` function body into module scope, keep
using the existing `TabIconProps`, and pass `focused` and `icon` into it from
`TabsLayout` so the component identity stays stable across re-renders.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 0b1484d1-39a8-45d0-a20f-940c3a3c3c31
⛔ Files ignored due to path filters (45)
assets/expo.icon/Assets/expo-symbol 2.svgis excluded by!**/*.svgassets/expo.icon/Assets/grid.pngis excluded by!**/*.pngassets/fonts/PlusJakartaSans-Bold.ttfis excluded by!**/*.ttfassets/fonts/PlusJakartaSans-ExtraBold.ttfis excluded by!**/*.ttfassets/fonts/PlusJakartaSans-Light.ttfis excluded by!**/*.ttfassets/fonts/PlusJakartaSans-Medium.ttfis excluded by!**/*.ttfassets/fonts/PlusJakartaSans-Regular.ttfis excluded by!**/*.ttfassets/fonts/PlusJakartaSans-SemiBold.ttfis excluded by!**/*.ttfassets/icons/activity.pngis excluded by!**/*.pngassets/icons/add.pngis excluded by!**/*.pngassets/icons/adobe.pngis excluded by!**/*.pngassets/icons/back.pngis excluded by!**/*.pngassets/icons/canva.pngis excluded by!**/*.pngassets/icons/claude.pngis excluded by!**/*.pngassets/icons/dropbox.pngis excluded by!**/*.pngassets/icons/figma.pngis excluded by!**/*.pngassets/icons/github.pngis excluded by!**/*.pngassets/icons/home.pngis excluded by!**/*.pngassets/icons/logo.pngis excluded by!**/*.pngassets/icons/medium.pngis excluded by!**/*.pngassets/icons/menu.pngis excluded by!**/*.pngassets/icons/netflix.pngis excluded by!**/*.pngassets/icons/notion.pngis excluded by!**/*.pngassets/icons/openai.pngis excluded by!**/*.pngassets/icons/plus.pngis excluded by!**/*.pngassets/icons/setting.pngis excluded by!**/*.pngassets/icons/spotify.pngis excluded by!**/*.pngassets/icons/wallet.pngis excluded by!**/*.pngassets/images/avatar.pngis excluded by!**/*.pngassets/images/expo-badge-white.pngis excluded by!**/*.pngassets/images/expo-badge.pngis excluded by!**/*.pngassets/images/expo-logo.pngis excluded by!**/*.pngassets/images/icon.pngis excluded by!**/*.pngassets/images/logo-glow.pngis excluded by!**/*.pngassets/images/partial-react-logo.pngis excluded by!**/*.pngassets/images/splash-icon.pngis excluded by!**/*.pngassets/images/splash-pattern.pngis excluded by!**/*.pngassets/images/tabIcons/explore.pngis excluded by!**/*.pngassets/images/tabIcons/explore@2x.pngis excluded by!**/*.pngassets/images/tabIcons/explore@3x.pngis excluded by!**/*.pngassets/images/tabIcons/home.pngis excluded by!**/*.pngassets/images/tabIcons/home@2x.pngis excluded by!**/*.pngassets/images/tabIcons/home@3x.pngis excluded by!**/*.pngassets/images/tutorial-web.pngis excluded by!**/*.pngpackage-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (13)
app/(tabs)/_layout.tsxapp/(tabs)/index.tsxapp/(tabs)/insights.tsxapp/(tabs)/settings.tsxapp/(tabs)/subscriptions.tsxapp/subscriptions/[id].tsxassets/expo.icon/icon.jsonconstants/data.tsconstants/icons.tsconstants/theme.tsimage.d.tspackage.jsontype.d.ts
Moves the `TabIcon` component out of the `TabsLayout` function. This refactors the component for better organization and prevents its re-declaration on every render of the layout component, improving stability and performance.
This commit establishes the main navigation structure with a custom-designed bottom tab bar, enhancing the user interface and providing a consistent look and feel.
app/(tabs)/_layout.tsxfor a custom tab bar implementation usingexpo-router'sTabscomponent, complete with bespoke styling and icon handling.constants/theme.tsandconstants/data.tsto centralize color schemes, spacing, component dimensions, and tab configuration.clsxfor dynamic class name generation within the tab bar.subscriptions/[id]outside the(tabs)directory, allowing it to function as a standalone detail screen rather than a primary tab.index,insights,settings,subscriptions) to useSafeAreaViewand aligns them with the new theming approach.image.d.tsandtype.d.tsfor improved TypeScript support for assets and global interfaces.Summary by CodeRabbit