diff --git a/example/.gitignore b/example/.gitignore index 05647d55c..0b37b6eb4 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -33,3 +33,9 @@ yarn-error.* # typescript *.tsbuildinfo + +# @generated expo-cli sync-2b81b286409207a5da26e14c78851eb30d8ccbdb +# The following patterns were generated by expo-cli + +expo-env.d.ts +# @end expo-cli \ No newline at end of file diff --git a/example/app.json b/example/app.json index a836acd2c..b3b544d04 100644 --- a/example/app.json +++ b/example/app.json @@ -4,27 +4,33 @@ "slug": "phosphor-react-native-example", "version": "1.0.0", "orientation": "portrait", - "icon": "./assets/icon.png", + "icon": "./assets/images/icon.png", + "scheme": "phosphor-react-native-example", "userInterfaceStyle": "light", "splash": { - "image": "./assets/splash.png", + "image": "./assets/images/splash.png", "resizeMode": "contain", "backgroundColor": "#ffffff" }, - "assetBundlePatterns": [ - "**/*" - ], "ios": { "supportsTablet": true }, "android": { "adaptiveIcon": { - "foregroundImage": "./assets/adaptive-icon.png", + "foregroundImage": "./assets/images/adaptive-icon.png", "backgroundColor": "#ffffff" } }, "web": { - "favicon": "./assets/favicon.png" + "bundler": "metro", + "output": "static", + "favicon": "./assets/images/favicon.png" + }, + "plugins": [ + "expo-router" + ], + "experiments": { + "typedRoutes": true } } } \ No newline at end of file diff --git a/example/app/(tabs)/_layout.tsx b/example/app/(tabs)/_layout.tsx new file mode 100644 index 000000000..83e6b4531 --- /dev/null +++ b/example/app/(tabs)/_layout.tsx @@ -0,0 +1,42 @@ +import { Tabs } from 'expo-router'; +import React from 'react'; + +import { TabBarIcon } from '@/components/navigation/TabBarIcon'; +import List from 'phosphor-react-native/src/icons/List'; +import { Colors } from '@/constants/Colors'; +import { useColorScheme } from '@/hooks/useColorScheme'; + +export default function TabLayout() { + const colorScheme = useColorScheme(); + + return ( + + ( + + ), + }} + /> + ( + + ), + }} + /> + + ); +} diff --git a/example/app/(tabs)/duotone.tsx b/example/app/(tabs)/duotone.tsx new file mode 100644 index 000000000..89e4b4a95 --- /dev/null +++ b/example/app/(tabs)/duotone.tsx @@ -0,0 +1,10 @@ +/* eslint-disable react-native/no-inline-styles */ +import { Text, View } from 'react-native'; + +export default function DuotoneScreen() { + return ( + + Explore + + ); +} diff --git a/example/app/(tabs)/index.tsx b/example/app/(tabs)/index.tsx new file mode 100644 index 000000000..e6dcd3096 --- /dev/null +++ b/example/app/(tabs)/index.tsx @@ -0,0 +1,165 @@ +/* eslint-disable react-native/no-inline-styles */ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +import * as React from 'react'; + +import { + StyleSheet, + View, + Text, + SafeAreaView, + FlatList, + StatusBar, + Image, + TouchableOpacity, +} from 'react-native'; +import * as IconPack from 'phosphor-react-native'; +import PhosphorLogo from '@/assets/images/phosphor-mark-tight-yellow.png'; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const { IconContext, ...Icons } = IconPack; + +const weights = ['thin', 'light', 'regular', 'bold', 'fill', 'duotone']; + +export default function App() { + const [weightIdx, setWeightIdx] = React.useState(2); + const [iconColor, setIconColor] = React.useState(undefined); + const [mirrorActive, setMirrorActive] = React.useState(false); + + const weight: IconPack.IconWeight = React.useMemo( + () => weights[weightIdx] as any, + [weightIdx] + ); + + const handleChangeWeight = React.useCallback(() => { + setWeightIdx((weightIdx + 1) % weights.length); + }, [weightIdx]); + + const handleChangeIconColor = React.useCallback(() => { + setIconColor(`#${Math.floor(Math.random() * 16777215).toString(16)}`); + }, []); + + const handleToggleMirror = React.useCallback(() => { + setMirrorActive(!mirrorActive); + }, [mirrorActive]); + + return ( + + + + + + + + Phosphor React Native + + {weight} + + + + + + + + + + + + + + !!Icon) as any[]} + keyExtractor={(item) => item[0]} + numColumns={3} + renderItem={({ item: [name, Icon] }) => ( + + + {name} + + )} + /> + + ); +} + +const styles = StyleSheet.create({ + rootView: { + flex: 1, + backgroundColor: '#FFF', + }, + headerContainer: { + backgroundColor: '#e76f51', + }, + header: { + backgroundColor: '#e76f51', + alignItems: 'center', + justifyContent: 'center', + flexDirection: 'row', + paddingBottom: 16, + paddingHorizontal: 16, + }, + logoImage: { + width: 40, + height: 40, + borderRadius: 20, + }, + headerText: { + color: '#FFF', + fontSize: 18, + fontWeight: 'bold', + flex: 1, + textAlign: 'center', + }, + weightSelect: { + width: 35, + }, + scrollView: { + flex: 1, + }, + main: { + backgroundColor: 'white', + paddingHorizontal: 8, + paddingBottom: 16, + }, + iconItem: { + width: '33%', + height: 100, + alignItems: 'center', + justifyContent: 'center', + padding: 8, + }, + iconName: { + textAlign: 'center', + opacity: 0.8, + marginTop: 4, + }, +}); diff --git a/example/app/+html.tsx b/example/app/+html.tsx new file mode 100644 index 000000000..849f2263f --- /dev/null +++ b/example/app/+html.tsx @@ -0,0 +1,42 @@ +import { ScrollViewStyleReset } from 'expo-router/html'; +import { type PropsWithChildren } from 'react'; + +/** + * This file is web-only and used to configure the root HTML for every web page during static rendering. + * The contents of this function only run in Node.js environments and do not have access to the DOM or browser APIs. + */ +export default function Root({ children }: PropsWithChildren) { + return ( + + + + + + + {/* + Disable body scrolling on web. This makes ScrollView components work closer to how they do on native. + However, body scrolling is often nice to have for mobile web. If you want to enable it, remove this line. + */} + + + {/* Using raw CSS styles as an escape-hatch to ensure the background color never flickers in dark-mode. */} +