From c78ad25f0de7c3bd2a3d59756e6bbe4ece7cee51 Mon Sep 17 00:00:00 2001 From: Kenneth Date: Fri, 13 Mar 2026 00:23:06 +0000 Subject: [PATCH] feat(client): add component library and simplify routing (#66) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(client): add component library and simplify routing Remove tab layout, explore page, modal, and unused template components. Replace with single-page layout and a dev component showcase with per-component detail pages. - Add Button with label prop, leading/trailing icon support - Add FeedCard, SerifText, SansSerifText, MonospaceText - Add colocated *.showcase.tsx files for each component - Use Stack navigator with themed headers Co-authored-by: Ona * fix(client): render showcase as JSX component Co-authored-by: Ona * chore(client): remove dead code chain Remove ThemedText, useThemeColor, useColorScheme hook, Colors, and Fonts — none referenced by current screens. Co-authored-by: Ona --------- Co-authored-by: Ona --- apps/aelis-client/src/app/(tabs)/_layout.tsx | 36 ------ apps/aelis-client/src/app/(tabs)/explore.tsx | 114 ------------------ apps/aelis-client/src/app/(tabs)/index.tsx | 96 --------------- apps/aelis-client/src/app/_layout.tsx | 46 +++++-- .../src/app/components/[name].tsx | 48 ++++++++ .../aelis-client/src/app/components/index.tsx | 37 ++++++ apps/aelis-client/src/app/index.tsx | 28 +++++ apps/aelis-client/src/app/modal.tsx | 29 ----- .../src/components/external-link.tsx | 25 ---- .../src/components/haptic-tab.tsx | 18 --- .../src/components/hello-wave.tsx | 20 --- .../src/components/parallax-scroll-view.tsx | 82 ------------- apps/aelis-client/src/components/showcase.tsx | 18 +++ .../src/components/themed-text.tsx | 60 --------- .../src/components/themed-view.tsx | 14 --- .../src/components/ui/button.showcase.tsx | 43 +++++++ .../aelis-client/src/components/ui/button.tsx | 30 +++++ .../src/components/ui/collapsible.tsx | 46 ------- .../src/components/ui/feed-card.showcase.tsx | 32 +++++ .../src/components/ui/feed-card.tsx | 6 + .../src/components/ui/icon-symbol.ios.tsx | 32 ----- .../src/components/ui/icon-symbol.tsx | 41 ------- .../components/ui/monospace-text.showcase.tsx | 31 +++++ .../src/components/ui/monospace-text.tsx | 10 ++ .../ui/sans-serif-text.showcase.tsx | 34 ++++++ .../src/components/ui/sans-serif-text.tsx | 10 ++ .../src/components/ui/serif-text.showcase.tsx | 25 ++++ .../src/components/ui/serif-text.tsx | 10 ++ apps/aelis-client/src/constants/theme.ts | 53 -------- .../src/hooks/use-color-scheme.ts | 1 - .../src/hooks/use-color-scheme.web.ts | 21 ---- .../aelis-client/src/hooks/use-theme-color.ts | 21 ---- 32 files changed, 396 insertions(+), 721 deletions(-) delete mode 100644 apps/aelis-client/src/app/(tabs)/_layout.tsx delete mode 100644 apps/aelis-client/src/app/(tabs)/explore.tsx delete mode 100644 apps/aelis-client/src/app/(tabs)/index.tsx create mode 100644 apps/aelis-client/src/app/components/[name].tsx create mode 100644 apps/aelis-client/src/app/components/index.tsx create mode 100644 apps/aelis-client/src/app/index.tsx delete mode 100644 apps/aelis-client/src/app/modal.tsx delete mode 100644 apps/aelis-client/src/components/external-link.tsx delete mode 100644 apps/aelis-client/src/components/haptic-tab.tsx delete mode 100644 apps/aelis-client/src/components/hello-wave.tsx delete mode 100644 apps/aelis-client/src/components/parallax-scroll-view.tsx create mode 100644 apps/aelis-client/src/components/showcase.tsx delete mode 100644 apps/aelis-client/src/components/themed-text.tsx delete mode 100644 apps/aelis-client/src/components/themed-view.tsx create mode 100644 apps/aelis-client/src/components/ui/button.showcase.tsx create mode 100644 apps/aelis-client/src/components/ui/button.tsx delete mode 100644 apps/aelis-client/src/components/ui/collapsible.tsx create mode 100644 apps/aelis-client/src/components/ui/feed-card.showcase.tsx create mode 100644 apps/aelis-client/src/components/ui/feed-card.tsx delete mode 100644 apps/aelis-client/src/components/ui/icon-symbol.ios.tsx delete mode 100644 apps/aelis-client/src/components/ui/icon-symbol.tsx create mode 100644 apps/aelis-client/src/components/ui/monospace-text.showcase.tsx create mode 100644 apps/aelis-client/src/components/ui/monospace-text.tsx create mode 100644 apps/aelis-client/src/components/ui/sans-serif-text.showcase.tsx create mode 100644 apps/aelis-client/src/components/ui/sans-serif-text.tsx create mode 100644 apps/aelis-client/src/components/ui/serif-text.showcase.tsx create mode 100644 apps/aelis-client/src/components/ui/serif-text.tsx delete mode 100644 apps/aelis-client/src/constants/theme.ts delete mode 100644 apps/aelis-client/src/hooks/use-color-scheme.ts delete mode 100644 apps/aelis-client/src/hooks/use-color-scheme.web.ts delete mode 100644 apps/aelis-client/src/hooks/use-theme-color.ts diff --git a/apps/aelis-client/src/app/(tabs)/_layout.tsx b/apps/aelis-client/src/app/(tabs)/_layout.tsx deleted file mode 100644 index aaa3ef1..0000000 --- a/apps/aelis-client/src/app/(tabs)/_layout.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { Tabs } from "expo-router" -import React from "react" - -import { HapticTab } from "@/components/haptic-tab" -import { IconSymbol } from "@/components/ui/icon-symbol" -import { Colors } from "@/constants/theme" -import { useColorScheme } from "@/hooks/use-color-scheme" - -export default function TabLayout() { - const colorScheme = useColorScheme() - - return ( - - , - }} - /> - , - }} - /> - - ) -} diff --git a/apps/aelis-client/src/app/(tabs)/explore.tsx b/apps/aelis-client/src/app/(tabs)/explore.tsx deleted file mode 100644 index 9112d61..0000000 --- a/apps/aelis-client/src/app/(tabs)/explore.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import { Image } from "expo-image" -import { Platform, StyleSheet } from "react-native" - -import { ExternalLink } from "@/components/external-link" -import ParallaxScrollView from "@/components/parallax-scroll-view" -import { ThemedText } from "@/components/themed-text" -import { ThemedView } from "@/components/themed-view" -import { Collapsible } from "@/components/ui/collapsible" -import { IconSymbol } from "@/components/ui/icon-symbol" -import { Fonts } from "@/constants/theme" - -export default function TabTwoScreen() { - return ( - - } - > - - - Explore - - - This app includes example code to help you get started. - - - This app has two screens:{" "} - app/(tabs)/index.tsx and{" "} - app/(tabs)/explore.tsx - - - The layout file in app/(tabs)/_layout.tsx{" "} - sets up the tab navigator. - - - Learn more - - - - - You can open this project on Android, iOS, and the web. To open the web version, press{" "} - w in the terminal running this project. - - - - - For static images, you can use the @2x and{" "} - @3x suffixes to provide files for - different screen densities - - - - Learn more - - - - - This template has light and dark mode support. The{" "} - useColorScheme() hook lets you inspect - what the user's current color scheme is, and so you can adjust UI colors accordingly. - - - Learn more - - - - - This template includes an example of an animated component. The{" "} - components/HelloWave.tsx component uses - the powerful{" "} - - react-native-reanimated - {" "} - library to create a waving hand animation. - - {Platform.select({ - ios: ( - - The components/ParallaxScrollView.tsx{" "} - component provides a parallax effect for the header image. - - ), - })} - - - ) -} - -const styles = StyleSheet.create({ - headerImage: { - color: "#808080", - bottom: -90, - left: -35, - position: "absolute", - }, - titleContainer: { - flexDirection: "row", - gap: 8, - }, -}) diff --git a/apps/aelis-client/src/app/(tabs)/index.tsx b/apps/aelis-client/src/app/(tabs)/index.tsx deleted file mode 100644 index 276a43b..0000000 --- a/apps/aelis-client/src/app/(tabs)/index.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { Image } from "expo-image" -import { Link } from "expo-router" -import { Platform, StyleSheet } from "react-native" - -import { HelloWave } from "@/components/hello-wave" -import ParallaxScrollView from "@/components/parallax-scroll-view" -import { ThemedText } from "@/components/themed-text" -import { ThemedView } from "@/components/themed-view" - -export default function HomeScreen() { - return ( - - } - > - - Welcome! - - - - Step 1: Try it - - Edit app/(tabs)/index.tsx to see changes. - Press{" "} - - {Platform.select({ - ios: "cmd + d", - android: "cmd + m", - web: "F12", - })} - {" "} - to open developer tools. - - - - - - Step 2: Explore - - - - alert("Action pressed")} /> - alert("Share pressed")} - /> - - alert("Delete pressed")} - /> - - - - - - {`Tap the Explore tab to learn more about what's included in this starter app.`} - - - - Step 3: Get a fresh start - - {`When you're ready, run `} - npm run reset-project to get a fresh{" "} - app directory. This will move the current{" "} - app to{" "} - app-example. - - - - ) -} - -const styles = StyleSheet.create({ - titleContainer: { - flexDirection: "row", - alignItems: "center", - gap: 8, - }, - stepContainer: { - gap: 8, - marginBottom: 8, - }, - reactLogo: { - height: 178, - width: 290, - bottom: 0, - left: 0, - position: "absolute", - }, -}) diff --git a/apps/aelis-client/src/app/_layout.tsx b/apps/aelis-client/src/app/_layout.tsx index 3478074..ce6036b 100644 --- a/apps/aelis-client/src/app/_layout.tsx +++ b/apps/aelis-client/src/app/_layout.tsx @@ -1,23 +1,45 @@ -import { DarkTheme, DefaultTheme, ThemeProvider } from "@react-navigation/native" +import "react-native-reanimated" import { Stack } from "expo-router" import { StatusBar } from "expo-status-bar" -import "react-native-reanimated" -import { useColorScheme } from "@/hooks/use-color-scheme" - -export const unstable_settings = { - anchor: "(tabs)", -} +import { useColorScheme } from "react-native" +import tw, { useDeviceContext } from "twrnc" export default function RootLayout() { + useDeviceContext(tw) const colorScheme = useColorScheme() + const headerBg = colorScheme === "dark" ? "#1c1917" : "#f5f5f4" + const headerTint = colorScheme === "dark" ? "#e7e5e4" : "#1c1917" return ( - - - - + <> + + + - + ) } diff --git a/apps/aelis-client/src/app/components/[name].tsx b/apps/aelis-client/src/app/components/[name].tsx new file mode 100644 index 0000000..86ece3b --- /dev/null +++ b/apps/aelis-client/src/app/components/[name].tsx @@ -0,0 +1,48 @@ +import { useLocalSearchParams, useNavigation } from "expo-router" +import { useEffect } from "react" +import { ScrollView, View } from "react-native" +import tw from "twrnc" + +import { buttonShowcase } from "@/components/ui/button.showcase" +import { feedCardShowcase } from "@/components/ui/feed-card.showcase" +import { monospaceTextShowcase } from "@/components/ui/monospace-text.showcase" +import { sansSerifTextShowcase } from "@/components/ui/sans-serif-text.showcase" +import { serifTextShowcase } from "@/components/ui/serif-text.showcase" +import { type Showcase } from "@/components/showcase" +import { SansSerifText } from "@/components/ui/sans-serif-text" + +const showcases: Record = { + button: buttonShowcase, + "feed-card": feedCardShowcase, + "serif-text": serifTextShowcase, + "sans-serif-text": sansSerifTextShowcase, + "monospace-text": monospaceTextShowcase, +} + +export default function ComponentDetailScreen() { + const { name } = useLocalSearchParams<{ name: string }>() + const navigation = useNavigation() + const showcase = showcases[name] + + useEffect(() => { + if (showcase) { + navigation.setOptions({ title: showcase.title }) + } + }, [navigation, showcase]) + + if (!showcase) { + return ( + + Component not found + + ) + } + + const ShowcaseComponent = showcase.component + + return ( + + + + ) +} diff --git a/apps/aelis-client/src/app/components/index.tsx b/apps/aelis-client/src/app/components/index.tsx new file mode 100644 index 0000000..d02ebbd --- /dev/null +++ b/apps/aelis-client/src/app/components/index.tsx @@ -0,0 +1,37 @@ +import { Link } from "expo-router" +import { FlatList, Pressable, View } from "react-native" +import tw from "twrnc" + +import { SansSerifText } from "@/components/ui/sans-serif-text" + +const components = [ + { name: "button", label: "Button" }, + { name: "feed-card", label: "FeedCard" }, + { name: "serif-text", label: "SerifText" }, + { name: "sans-serif-text", label: "SansSerifText" }, + { name: "monospace-text", label: "MonospaceText" }, +] as const + +export default function ComponentsScreen() { + return ( + + + item.name} + scrollEnabled={false} + ItemSeparatorComponent={() => ( + + )} + renderItem={({ item }) => ( + + + {item.label} + + + )} + /> + + + ) +} diff --git a/apps/aelis-client/src/app/index.tsx b/apps/aelis-client/src/app/index.tsx new file mode 100644 index 0000000..7e46df2 --- /dev/null +++ b/apps/aelis-client/src/app/index.tsx @@ -0,0 +1,28 @@ +import { Link } from "expo-router" +import { Pressable } from "react-native" +import { SafeAreaView } from "react-native-safe-area-context" +import tw from "twrnc" + +import { Button } from "@/components/ui/button" +import { FeedCard } from "@/components/ui/feed-card" +import { MonospaceText } from "@/components/ui/monospace-text" +import { SansSerifText } from "@/components/ui/sans-serif-text" +import { SerifText } from "@/components/ui/serif-text" + +export default function HomeScreen() { + return ( + + + Hello world asdsadsa + Hello world + asdjsakljdl +