Teal theme and landing page - #106
Merged
Merged
Conversation
https://reactnativereusables.com - shadcn/ui for React Native, on top of NativeWind, which compiles Tailwind classes into React Native styles. The components are checked into src/components/ui/ rather than installed, so they are ours to edit, and `cli add` writes more of them there. Fifteen to start with: alert, avatar, badge, button, card, checkbox, icon, input, label, progress, separator, skeleton, switch, text and textarea. The rest of the catalogue is one `add` away, which is the point of the library, so there was no reason to pull all thirty in up front. Setup notes: - babel.config.js is new. babel-preset-expo's defaults were enough until now. The React Compiler is unaffected: it comes from the Metro caller, and `expo export` still reports it enabled. - metro.config.js sets inlineRem to 16. NativeWind defaults to 14 and the components are sized against 16. - src/global.css keeps the web font variables it already had and gains the design tokens. src/lib/theme.ts mirrors them for native props that want a colour string rather than a class, and the root layout takes its navigation theme from there so nav chrome and `bg-background` agree. - The CSS import moved from src/constants/theme.ts to the root layout, which is where both Expo and NativeWind want it. The exported web CSS still carries --font-display. - Two jest additions, or nothing under src/components/ui/ can be rendered in a test: @rn-primitives ships JSX and lucide-react-native ships ESM, so both need babel run over them, and react-native-reanimated needs the worklets mock its own Jest guide recommends. Existing screens are untouched beyond the layout - ThemedText, ThemedView and src/constants/theme.ts still drive them. Restyling is a separate job. Verified with the CLI's own `doctor`, plus lint, typecheck, 24 passing tests and iOS, Android and web bundles. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The app opened on the Expo starter screen - "Welcome to Expo", the Expo wordmark, a "Try editing src/app/index.tsx" hint - and had no palette of its own. Both replaced. The theme, defined once in src/global.css and derived from there by src/lib/theme.ts and src/constants/theme.ts, so the tab bar and the screens still on StyleSheet follow it rather than drifting. On the teal. The brand colour is rgb(35, 170, 172), hsl(181 66% 41%), and it is the primary in dark mode where it carries dark text at 6.4:1. In light mode the primary is the same hue and saturation at 29% lightness. White on the brand teal is 2.8:1 against the 4.5:1 WCAG AA asks for at this text size, and it misses the 3:1 for icons and focus rings too; deepened it reaches 5.2:1 for a white label and 5.1:1 as ink on the background, so one teal covers buttons, links, icons and rings instead of needing a shade for each. Every pair in both schemes clears AA, which matters more than usual for people reading this tired, on a phone, in bad light. Also fills in --destructive-foreground, which tailwind.config.js has always referenced and global.css never defined, and retints ThemedText's hardcoded #3c87f7 link blue - itself only 3.3:1 on white - to the theme primary. The landing page says what the app is for in plain words, gives three reassurances, and offers a way in and a way to look around. It promises only what the app does: no claim that entries are private, because the API behind them does not guarantee that yet, and a line saying it is not medical advice. "Start your journal" goes to /tasks, the placeholder resource the README describes. Icons are imported one at a time rather than off the lucide barrel. Metro does not tree-shake, and three icons off the barrel cost 1.8MB - the iOS bundle went 5.6MB, then 3.8MB once the imports were narrowed. Same fix applied to the generated checkbox. Verified with lint, typecheck, 28 passing tests and iOS, Android and web bundles. Every class the landing page uses was checked against the compiled stylesheet, and both teal primaries appear in the shipped CSS. Still Expo's: the launch logo and app icon, since splash-icon.png is a byte-identical copy of expo-logo.png and there is no brand art in the tree. The splash and adaptive-icon background colours are now the theme's. AnimatedIcon in src/components/animated-icon.tsx is unused now that nothing renders the Expo wordmark; AnimatedSplashOverlay beside it is still the launch animation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Setting the splash backgroundColor in app.json to the brand teal left the JS overlay that continues it still on Expo's #208AEF, so launch went teal, flashed blue, then showed the app. Same colour in both places now. The overlay also loads splash-icon.png rather than expo-logo.png. They are the same file today, but app.json's splash already points at splash-icon.png, so real brand art dropped in at that one path will pick up in both places instead of one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Web does not get the native tab bar. app-tabs.web.tsx draws a floating header instead, absolutely positioned, and no screen left room for it: it is 78px tall and the three screens padded 32, 16 and 64. Measured in a headless browser at 390x844, the landing page had 46px of its 64px logo behind the header and the Tasks title was 44px under it. The header now states its own height, from a WebHeaderInset constant the screens pad by - the mirror of BottomTabInset, which already solves this for the tab bar at the bottom on native. Zero on native, where there is no top header. Clearances afterwards: landing +32px, tasks +16px, explore +64px. Dark mode on web never worked. tailwind.config.js sets darkMode: 'class', so every dark style hangs off a `dark` class on <html>; NativeWind resolves that against Appearance on native, but on web the class is only added by an explicit colorScheme.set() call, and nothing called it. Both schemes rendered the light palette. A +html.tsx now sets the class from prefers-color-scheme before the bundle loads - early enough for NativeWind to start on the right scheme and to avoid a flash - and follows changes while the page is open. Verified in the browser: light gives #FCFDFD with the #19797B primary, dark gives #0E171B with #24ABAE, which is the palette as written. Plus lint, typecheck, 28 tests, and iOS, Android and web bundles. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Measured at 390x844 in a headless browser. The header could not fit: the brand name, three tabs and the Docs link need about 510px and none of them shrink, so the bar ran from -60 to 450 on a 390px screen with "Along With You" 28px past the left edge. Below 600px it now drops the brand name and tightens its padding, which brings the bar to 24..366 with no horizontal overflow. The landing page says the name directly underneath anyway. The bar also sat 8px wider than the content below it, at 16px inset against the screens' px-6. Both are 24 now, so the bar and the text line up. The landing page hero is centred rather than left aligned, and the rhythm is tighter: the mark 64 to 56, gaps 8/5/3 to 6/4/2, the card's inner gap 6 to 5, and the lead trimmed by a sentence rather than by font size - text size is the last thing to shrink on an app for people reading it tired. Type sizes are unchanged. That moves the primary call to action from 866 to 750, above the 844 fold on a 390x844 phone and above it at 430, 768 and 1280 too. The mark's centre matches the viewport centre at every one of those widths. Verified: lint, typecheck, 28 tests, iOS, Android and web bundles, all three screens still clearing the header, and both colour schemes still resolving to the palette. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Both were sitting untracked in the working tree, one commit away from being committed by accident. The note at the top of this file is right that .DS_Store belongs in a global ignore, but the same reasoning as the *:Zone.Identifier line above applies: the repo gets mounted into a container from a Mac, and the file then shows up in `git status` for whoever is working inside the container, where their global ignore is not. mobile/.gitignore already had it; the root did not. ui-review/ is where screenshots of the phone app land when looking over a UI change - useful, but large binaries that go stale immediately. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
main took the React Native Reusables branch as a squash (#105), so its content arrived under a new commit while this branch still carried the original. Git saw both sides creating lib/theme.ts and checkbox.tsx and both editing README.md, global.css and constants/theme.ts, and could not tell they were the same change. Resolved by keeping this branch's copies. main's version of all five files is byte-identical to the commit this branch already contains, so ours is that plus the teal theme work and nothing was dropped: the merged tree matches the branch's tree before the merge exactly. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.