├── hooks ├── useColorScheme.ts ├── useColorScheme.web.ts └── useThemeColor.ts ├── assets ├── images │ ├── icon.png │ ├── favicon.png │ ├── splash.png │ ├── react-logo.png │ ├── adaptive-icon.png │ ├── react-logo@2x.png │ ├── react-logo@3x.png │ └── partial-react-logo.png └── fonts │ └── SpaceMono-Regular.ttf ├── ios ├── Podfile.properties.json ├── expowidgetexample │ ├── Images.xcassets │ │ ├── Contents.json │ │ ├── SplashScreen.imageset │ │ │ ├── image.png │ │ │ └── Contents.json │ │ ├── SplashScreenBackground.imageset │ │ │ ├── image.png │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── App-Icon-1024x1024@1x.png │ │ │ └── Contents.json │ ├── noop-file.swift │ ├── expowidgetexample-Bridging-Header.h │ ├── AppDelegate.h │ ├── expowidgetexample.entitlements │ ├── main.m │ ├── Supporting │ │ └── Expo.plist │ ├── Info.plist │ ├── AppDelegate.mm │ └── SplashScreen.storyboard ├── expowidgetexample.xcworkspace │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── contents.xcworkspacedata ├── .gitignore ├── .xcode.env ├── Podfile ├── expowidgetexample.xcodeproj │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── expowidgetexample.xcscheme │ └── project.pbxproj └── Podfile.lock ├── expo-env.d.ts ├── babel.config.js ├── targets └── widget │ ├── Assets.xcassets │ ├── myImage.imageset │ │ ├── 1x.png │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ ├── App-Icon-20x20@1x.png │ │ ├── App-Icon-20x20@2x.png │ │ ├── App-Icon-20x20@3x.png │ │ ├── App-Icon-29x29@1x.png │ │ ├── App-Icon-29x29@2x.png │ │ ├── App-Icon-29x29@3x.png │ │ ├── App-Icon-40x40@1x.png │ │ ├── App-Icon-40x40@2x.png │ │ ├── App-Icon-40x40@3x.png │ │ ├── App-Icon-60x60@2x.png │ │ ├── App-Icon-60x60@3x.png │ │ ├── App-Icon-76x76@1x.png │ │ ├── App-Icon-76x76@2x.png │ │ ├── ItunesArtwork@2x.png │ │ ├── App-Icon-83.5x83.5@2x.png │ │ └── Contents.json │ ├── $accent.colorset │ │ └── Contents.json │ ├── $widgetBackground.colorset │ │ └── Contents.json │ └── slate.colorset │ │ └── Contents.json │ ├── index.swift │ ├── generated.entitlements │ ├── Info.plist │ ├── expo-target.config.js │ ├── PrivacyInfo.xcprivacy │ └── widgets.swift ├── .gitignore ├── tsconfig.json ├── components ├── __tests__ │ ├── ThemedText-test.tsx │ └── __snapshots__ │ │ └── ThemedText-test.tsx.snap ├── navigation │ └── TabBarIcon.tsx ├── ThemedView.tsx ├── ExternalLink.tsx ├── HelloWave.tsx ├── Collapsible.tsx ├── ThemedText.tsx └── ParallaxScrollView.tsx ├── constants └── Colors.ts ├── app ├── +not-found.tsx ├── (tabs) │ ├── _layout.tsx │ ├── index.tsx │ └── explore.tsx ├── _layout.tsx └── +html.tsx ├── app.json ├── package.json ├── README.md └── scripts └── reset-project.js /hooks/useColorScheme.ts: -------------------------------------------------------------------------------- 1 | export { useColorScheme } from 'react-native'; 2 | -------------------------------------------------------------------------------- /assets/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/assets/images/icon.png -------------------------------------------------------------------------------- /assets/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/assets/images/favicon.png -------------------------------------------------------------------------------- /assets/images/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/assets/images/splash.png -------------------------------------------------------------------------------- /ios/Podfile.properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo.jsEngine": "hermes", 3 | "EX_DEV_CLIENT_NETWORK_INSPECTOR": "true" 4 | } 5 | -------------------------------------------------------------------------------- /assets/images/react-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/assets/images/react-logo.png -------------------------------------------------------------------------------- /assets/images/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/assets/images/adaptive-icon.png -------------------------------------------------------------------------------- /assets/images/react-logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/assets/images/react-logo@2x.png -------------------------------------------------------------------------------- /assets/images/react-logo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/assets/images/react-logo@3x.png -------------------------------------------------------------------------------- /expo-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | // NOTE: This file should not be edited and should be in your git ignore -------------------------------------------------------------------------------- /ios/expowidgetexample/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "expo" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /assets/fonts/SpaceMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/assets/fonts/SpaceMono-Regular.ttf -------------------------------------------------------------------------------- /assets/images/partial-react-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/assets/images/partial-react-logo.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function (api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /ios/expowidgetexample/noop-file.swift: -------------------------------------------------------------------------------- 1 | // 2 | // @generated 3 | // A blank Swift file must be created for native modules with Swift files to work correctly. 4 | // 5 | -------------------------------------------------------------------------------- /ios/expowidgetexample/expowidgetexample-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | -------------------------------------------------------------------------------- /targets/widget/Assets.xcassets/myImage.imageset/1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/targets/widget/Assets.xcassets/myImage.imageset/1x.png -------------------------------------------------------------------------------- /ios/expowidgetexample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | 5 | @interface AppDelegate : EXAppDelegateWrapper 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .expo/ 3 | dist/ 4 | npm-debug.* 5 | *.jks 6 | *.p8 7 | *.p12 8 | *.key 9 | *.mobileprovision 10 | *.orig.* 11 | web-build/ 12 | 13 | # macOS 14 | .DS_Store 15 | -------------------------------------------------------------------------------- /ios/expowidgetexample/Images.xcassets/SplashScreen.imageset/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/ios/expowidgetexample/Images.xcassets/SplashScreen.imageset/image.png -------------------------------------------------------------------------------- /targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@1x.png -------------------------------------------------------------------------------- /targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@2x.png -------------------------------------------------------------------------------- /targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@3x.png -------------------------------------------------------------------------------- /targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@1x.png -------------------------------------------------------------------------------- /targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@2x.png -------------------------------------------------------------------------------- /targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@3x.png -------------------------------------------------------------------------------- /targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@1x.png -------------------------------------------------------------------------------- /targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@2x.png -------------------------------------------------------------------------------- /targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@3x.png -------------------------------------------------------------------------------- /targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-60x60@2x.png -------------------------------------------------------------------------------- /targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-60x60@3x.png -------------------------------------------------------------------------------- /targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-76x76@1x.png -------------------------------------------------------------------------------- /targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-76x76@2x.png -------------------------------------------------------------------------------- /targets/widget/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/targets/widget/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png -------------------------------------------------------------------------------- /targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/expowidgetexample/Images.xcassets/SplashScreenBackground.imageset/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/ios/expowidgetexample/Images.xcassets/SplashScreenBackground.imageset/image.png -------------------------------------------------------------------------------- /targets/widget/index.swift: -------------------------------------------------------------------------------- 1 | import WidgetKit 2 | import SwiftUI 3 | 4 | @main 5 | struct exportWidgets: WidgetBundle { 6 | var body: some Widget { 7 | // Export widgets here 8 | widgets() 9 | } 10 | } -------------------------------------------------------------------------------- /ios/expowidgetexample/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-apple-widget-example/HEAD/ios/expowidgetexample/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/expowidgetexample/expowidgetexample.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ios/expowidgetexample/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char * argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /ios/expowidgetexample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "expo/tsconfig.base", 3 | "compilerOptions": { 4 | "strict": true, 5 | "paths": { 6 | "@/*": [ 7 | "./*" 8 | ] 9 | } 10 | }, 11 | "include": [ 12 | "**/*.ts", 13 | "**/*.tsx", 14 | ".expo/types/**/*.ts", 15 | "expo-env.d.ts" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /ios/expowidgetexample.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/expowidgetexample/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "filename": "App-Icon-1024x1024@1x.png", 5 | "idiom": "universal", 6 | "platform": "ios", 7 | "size": "1024x1024" 8 | } 9 | ], 10 | "info": { 11 | "version": 1, 12 | "author": "expo" 13 | } 14 | } -------------------------------------------------------------------------------- /components/__tests__/ThemedText-test.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import renderer from 'react-test-renderer'; 3 | 4 | import { ThemedText } from '../ThemedText'; 5 | 6 | it(`renders correctly`, () => { 7 | const tree = renderer.create(Snapshot test!).toJSON(); 8 | 9 | expect(tree).toMatchSnapshot(); 10 | }); 11 | -------------------------------------------------------------------------------- /targets/widget/generated.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.bacon.data 8 | 9 | 10 | -------------------------------------------------------------------------------- /targets/widget/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSExtension 6 | 7 | NSExtensionPointIdentifier 8 | com.apple.widgetkit-extension 9 | 10 | 11 | -------------------------------------------------------------------------------- /targets/widget/Assets.xcassets/myImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "idiom": "universal", 5 | "scale": "1x", 6 | "filename": "1x.png" 7 | }, 8 | { 9 | "idiom": "universal", 10 | "scale": "2x" 11 | }, 12 | { 13 | "idiom": "universal", 14 | "scale": "3x" 15 | } 16 | ], 17 | "info": { 18 | "version": 1, 19 | "author": "expo" 20 | } 21 | } -------------------------------------------------------------------------------- /ios/expowidgetexample/Supporting/Expo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | EXUpdatesCheckOnLaunch 6 | ALWAYS 7 | EXUpdatesEnabled 8 | 9 | EXUpdatesLaunchWaitMs 10 | 0 11 | 12 | -------------------------------------------------------------------------------- /ios/expowidgetexample/Images.xcassets/SplashScreen.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "idiom": "universal", 5 | "filename": "image.png", 6 | "scale": "1x" 7 | }, 8 | { 9 | "idiom": "universal", 10 | "scale": "2x" 11 | }, 12 | { 13 | "idiom": "universal", 14 | "scale": "3x" 15 | } 16 | ], 17 | "info": { 18 | "version": 1, 19 | "author": "expo" 20 | } 21 | } -------------------------------------------------------------------------------- /ios/expowidgetexample/Images.xcassets/SplashScreenBackground.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "idiom": "universal", 5 | "filename": "image.png", 6 | "scale": "1x" 7 | }, 8 | { 9 | "idiom": "universal", 10 | "scale": "2x" 11 | }, 12 | { 13 | "idiom": "universal", 14 | "scale": "3x" 15 | } 16 | ], 17 | "info": { 18 | "version": 1, 19 | "author": "expo" 20 | } 21 | } -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | .xcode.env.local 25 | 26 | # Bundle artifacts 27 | *.jsbundle 28 | 29 | # CocoaPods 30 | /Pods/ 31 | -------------------------------------------------------------------------------- /targets/widget/Assets.xcassets/$accent.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": [ 3 | { 4 | "color": { 5 | "color-space": "display-p3", 6 | "components": { 7 | "red": 0.9411764705882353, 8 | "green": 0.5803921568627451, 9 | "blue": 0.34509803921568627, 10 | "alpha": 1 11 | } 12 | }, 13 | "idiom": "universal" 14 | } 15 | ], 16 | "info": { 17 | "version": 1, 18 | "author": "expo" 19 | } 20 | } -------------------------------------------------------------------------------- /components/__tests__/__snapshots__/ThemedText-test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`renders correctly 1`] = ` 4 | 22 | Snapshot test! 23 | 24 | `; 25 | -------------------------------------------------------------------------------- /targets/widget/Assets.xcassets/$widgetBackground.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": [ 3 | { 4 | "color": { 5 | "color-space": "display-p3", 6 | "components": { 7 | "red": 0.8588235294117647, 8 | "green": 0.45098039215686275, 9 | "blue": 0.611764705882353, 10 | "alpha": 1 11 | } 12 | }, 13 | "idiom": "universal" 14 | } 15 | ], 16 | "info": { 17 | "version": 1, 18 | "author": "expo" 19 | } 20 | } -------------------------------------------------------------------------------- /components/navigation/TabBarIcon.tsx: -------------------------------------------------------------------------------- 1 | // You can explore the built-in icon families and icons on the web at https://icons.expo.fyi/ 2 | 3 | import Ionicons from '@expo/vector-icons/Ionicons'; 4 | import { type IconProps } from '@expo/vector-icons/build/createIconSet'; 5 | import { type ComponentProps } from 'react'; 6 | 7 | export function TabBarIcon({ style, ...rest }: IconProps['name']>) { 8 | return ; 9 | } 10 | -------------------------------------------------------------------------------- /hooks/useColorScheme.web.ts: -------------------------------------------------------------------------------- 1 | // NOTE: The default React Native styling doesn't support server rendering. 2 | // Server rendered styles should not change between the first render of the HTML 3 | // and the first render on the client. Typically, web developers will use CSS media queries 4 | // to render different styles on the client and server, these aren't directly supported in React Native 5 | // but can be achieved using a styling library like Nativewind. 6 | export function useColorScheme() { 7 | return 'light'; 8 | } 9 | -------------------------------------------------------------------------------- /ios/.xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /components/ThemedView.tsx: -------------------------------------------------------------------------------- 1 | import { View, type ViewProps } from 'react-native'; 2 | 3 | import { useThemeColor } from '@/hooks/useThemeColor'; 4 | 5 | export type ThemedViewProps = ViewProps & { 6 | lightColor?: string; 7 | darkColor?: string; 8 | }; 9 | 10 | export function ThemedView({ style, lightColor, darkColor, ...otherProps }: ThemedViewProps) { 11 | const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background'); 12 | 13 | return ; 14 | } 15 | -------------------------------------------------------------------------------- /targets/widget/expo-target.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@bacons/apple-targets').Config} */ 2 | module.exports = { 3 | type: "widget", 4 | icon: "../../assets/images/icon.png", 5 | colors: { 6 | slate: { 7 | light: "#F0F0F0", 8 | dark: "#3E72A0", 9 | }, 10 | $accent: "#F09458", 11 | $widgetBackground: "#DB739C", 12 | }, 13 | entitlements: { 14 | "com.apple.security.application-groups": ["group.bacon.data"], 15 | }, 16 | images: { 17 | myImage: "../../assets/images/react-logo.png", 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /hooks/useThemeColor.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Learn more about light and dark modes: 3 | * https://docs.expo.dev/guides/color-schemes/ 4 | */ 5 | 6 | import { useColorScheme } from 'react-native'; 7 | 8 | import { Colors } from '@/constants/Colors'; 9 | 10 | export function useThemeColor( 11 | props: { light?: string; dark?: string }, 12 | colorName: keyof typeof Colors.light & keyof typeof Colors.dark 13 | ) { 14 | const theme = useColorScheme() ?? 'light'; 15 | const colorFromProps = props[theme]; 16 | 17 | if (colorFromProps) { 18 | return colorFromProps; 19 | } else { 20 | return Colors[theme][colorName]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /components/ExternalLink.tsx: -------------------------------------------------------------------------------- 1 | import { Link } from 'expo-router'; 2 | import { openBrowserAsync } from 'expo-web-browser'; 3 | import { type ComponentProps } from 'react'; 4 | import { Platform } from 'react-native'; 5 | 6 | type Props = Omit, 'href'> & { href: string }; 7 | 8 | export function ExternalLink({ href, ...rest }: Props) { 9 | return ( 10 | { 15 | if (Platform.OS !== 'web') { 16 | // Prevent the default behavior of linking to the default browser on native. 17 | event.preventDefault(); 18 | // Open the link in an in-app browser. 19 | await openBrowserAsync(href); 20 | } 21 | }} 22 | /> 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /constants/Colors.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Below are the colors that are used in the app. The colors are defined in the light and dark mode. 3 | * There are many other ways to style your app. For example, [Nativewind](https://www.nativewind.dev/), [Tamagui](https://tamagui.dev/), [unistyles](https://reactnativeunistyles.vercel.app), etc. 4 | */ 5 | 6 | const tintColorLight = '#0a7ea4'; 7 | const tintColorDark = '#fff'; 8 | 9 | export const Colors = { 10 | light: { 11 | text: '#11181C', 12 | background: '#fff', 13 | tint: tintColorLight, 14 | icon: '#687076', 15 | tabIconDefault: '#687076', 16 | tabIconSelected: tintColorLight, 17 | }, 18 | dark: { 19 | text: '#ECEDEE', 20 | background: '#151718', 21 | tint: tintColorDark, 22 | icon: '#9BA1A6', 23 | tabIconDefault: '#9BA1A6', 24 | tabIconSelected: tintColorDark, 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /app/+not-found.tsx: -------------------------------------------------------------------------------- 1 | import { Link, Stack } from 'expo-router'; 2 | import { StyleSheet } from 'react-native'; 3 | 4 | import { ThemedText } from '@/components/ThemedText'; 5 | import { ThemedView } from '@/components/ThemedView'; 6 | 7 | export default function NotFoundScreen() { 8 | return ( 9 | <> 10 | 11 | 12 | This screen doesn't exist. 13 | 14 | Go to home screen! 15 | 16 | 17 | 18 | ); 19 | } 20 | 21 | const styles = StyleSheet.create({ 22 | container: { 23 | flex: 1, 24 | alignItems: 'center', 25 | justifyContent: 'center', 26 | padding: 20, 27 | }, 28 | link: { 29 | marginTop: 15, 30 | paddingVertical: 15, 31 | }, 32 | }); 33 | -------------------------------------------------------------------------------- /targets/widget/Assets.xcassets/slate.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": [ 3 | { 4 | "color": { 5 | "color-space": "display-p3", 6 | "components": { 7 | "red": 0.9411764705882353, 8 | "green": 0.9411764705882353, 9 | "blue": 0.9411764705882353, 10 | "alpha": 1 11 | } 12 | }, 13 | "idiom": "universal" 14 | }, 15 | { 16 | "appearances": [ 17 | { 18 | "appearance": "luminosity", 19 | "value": "dark" 20 | } 21 | ], 22 | "color": { 23 | "color-space": "display-p3", 24 | "components": { 25 | "red": 0.24313725490196078, 26 | "green": 0.4470588235294118, 27 | "blue": 0.6274509803921569, 28 | "alpha": 1 29 | } 30 | }, 31 | "idiom": "universal" 32 | } 33 | ], 34 | "info": { 35 | "version": 1, 36 | "author": "expo" 37 | } 38 | } -------------------------------------------------------------------------------- /components/HelloWave.tsx: -------------------------------------------------------------------------------- 1 | import { StyleSheet } from 'react-native'; 2 | import Animated, { 3 | useSharedValue, 4 | useAnimatedStyle, 5 | withTiming, 6 | withRepeat, 7 | withSequence, 8 | } from 'react-native-reanimated'; 9 | 10 | import { ThemedText } from '@/components/ThemedText'; 11 | 12 | export function HelloWave() { 13 | const rotationAnimation = useSharedValue(0); 14 | 15 | rotationAnimation.value = withRepeat( 16 | withSequence(withTiming(25, { duration: 150 }), withTiming(0, { duration: 150 })), 17 | 4 // Run the animation 4 times 18 | ); 19 | 20 | const animatedStyle = useAnimatedStyle(() => ({ 21 | transform: [{ rotate: `${rotationAnimation.value}deg` }], 22 | })); 23 | 24 | return ( 25 | 26 | 👋 27 | 28 | ); 29 | } 30 | 31 | const styles = StyleSheet.create({ 32 | text: { 33 | fontSize: 28, 34 | lineHeight: 32, 35 | marginTop: -6, 36 | }, 37 | }); 38 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "expo-widget-example", 3 | "slug": "expo-widget-example", 4 | "version": "1.0.0", 5 | "orientation": "portrait", 6 | "icon": "./assets/images/icon.png", 7 | "scheme": "myapp", 8 | "userInterfaceStyle": "automatic", 9 | "splash": { 10 | "image": "./assets/images/splash.png", 11 | "resizeMode": "contain", 12 | "backgroundColor": "#ffffff" 13 | }, 14 | "ios": { 15 | "supportsTablet": true, 16 | "bundleIdentifier": "com.bacon.expo-widget-example" 17 | }, 18 | "android": { 19 | "adaptiveIcon": { 20 | "foregroundImage": "./assets/images/adaptive-icon.png", 21 | "backgroundColor": "#ffffff" 22 | } 23 | }, 24 | "web": { 25 | "bundler": "metro", 26 | "output": "static", 27 | "favicon": "./assets/images/favicon.png" 28 | }, 29 | "plugins": [ 30 | "expo-router", 31 | [ 32 | "@bacons/apple-targets", 33 | { 34 | "appleTeamId": "XXXXXXXXXX" 35 | } 36 | ] 37 | ], 38 | "experiments": { 39 | "typedRoutes": true 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/(tabs)/_layout.tsx: -------------------------------------------------------------------------------- 1 | import { Tabs } from 'expo-router'; 2 | import React from 'react'; 3 | 4 | import { TabBarIcon } from '@/components/navigation/TabBarIcon'; 5 | import { Colors } from '@/constants/Colors'; 6 | import { useColorScheme } from '@/hooks/useColorScheme'; 7 | 8 | export default function TabLayout() { 9 | const colorScheme = useColorScheme(); 10 | 11 | return ( 12 | 17 | ( 22 | 23 | ), 24 | }} 25 | /> 26 | ( 31 | 32 | ), 33 | }} 34 | /> 35 | 36 | ); 37 | } 38 | -------------------------------------------------------------------------------- /app/_layout.tsx: -------------------------------------------------------------------------------- 1 | import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native'; 2 | import { useFonts } from 'expo-font'; 3 | import { Stack } from 'expo-router'; 4 | import * as SplashScreen from 'expo-splash-screen'; 5 | import { useEffect } from 'react'; 6 | import 'react-native-reanimated'; 7 | 8 | import { useColorScheme } from '@/hooks/useColorScheme'; 9 | 10 | // Prevent the splash screen from auto-hiding before asset loading is complete. 11 | SplashScreen.preventAutoHideAsync(); 12 | 13 | export default function RootLayout() { 14 | const colorScheme = useColorScheme(); 15 | const [loaded] = useFonts({ 16 | SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'), 17 | }); 18 | 19 | useEffect(() => { 20 | if (loaded) { 21 | SplashScreen.hideAsync(); 22 | } 23 | }, [loaded]); 24 | 25 | if (!loaded) { 26 | return null; 27 | } 28 | 29 | return ( 30 | 31 | 32 | 33 | 34 | 35 | 36 | ); 37 | } 38 | -------------------------------------------------------------------------------- /components/Collapsible.tsx: -------------------------------------------------------------------------------- 1 | import Ionicons from '@expo/vector-icons/Ionicons'; 2 | import { PropsWithChildren, useState } from 'react'; 3 | import { StyleSheet, TouchableOpacity, useColorScheme } from 'react-native'; 4 | 5 | import { ThemedText } from '@/components/ThemedText'; 6 | import { ThemedView } from '@/components/ThemedView'; 7 | import { Colors } from '@/constants/Colors'; 8 | 9 | export function Collapsible({ children, title }: PropsWithChildren & { title: string }) { 10 | const [isOpen, setIsOpen] = useState(false); 11 | const theme = useColorScheme() ?? 'light'; 12 | 13 | return ( 14 | 15 | setIsOpen((value) => !value)} 18 | activeOpacity={0.8}> 19 | 24 | {title} 25 | 26 | {isOpen && {children}} 27 | 28 | ); 29 | } 30 | 31 | const styles = StyleSheet.create({ 32 | heading: { 33 | flexDirection: 'row', 34 | alignItems: 'center', 35 | gap: 6, 36 | }, 37 | content: { 38 | marginTop: 6, 39 | marginLeft: 24, 40 | }, 41 | }); 42 | -------------------------------------------------------------------------------- /targets/widget/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyAccessedAPITypes 6 | 7 | 8 | NSPrivacyAccessedAPIType 9 | NSPrivacyAccessedAPICategoryUserDefaults 10 | NSPrivacyAccessedAPITypeReasons 11 | 12 | CA92.1 13 | 14 | 15 | 16 | NSPrivacyAccessedAPIType 17 | NSPrivacyAccessedAPICategoryFileTimestamp 18 | NSPrivacyAccessedAPITypeReasons 19 | 20 | 0A2A.1 21 | 3B52.1 22 | C617.1 23 | 24 | 25 | 26 | NSPrivacyAccessedAPIType 27 | NSPrivacyAccessedAPICategoryDiskSpace 28 | NSPrivacyAccessedAPITypeReasons 29 | 30 | E174.1 31 | 85F4.1 32 | 33 | 34 | 35 | NSPrivacyAccessedAPIType 36 | NSPrivacyAccessedAPICategorySystemBootTime 37 | NSPrivacyAccessedAPITypeReasons 38 | 39 | 35F9.1 40 | 41 | 42 | 43 | NSPrivacyCollectedDataTypes 44 | 45 | NSPrivacyTracking 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /components/ThemedText.tsx: -------------------------------------------------------------------------------- 1 | import { Text, type TextProps, StyleSheet } from 'react-native'; 2 | 3 | import { useThemeColor } from '@/hooks/useThemeColor'; 4 | 5 | export type ThemedTextProps = TextProps & { 6 | lightColor?: string; 7 | darkColor?: string; 8 | type?: 'default' | 'title' | 'defaultSemiBold' | 'subtitle' | 'link'; 9 | }; 10 | 11 | export function ThemedText({ 12 | style, 13 | lightColor, 14 | darkColor, 15 | type = 'default', 16 | ...rest 17 | }: ThemedTextProps) { 18 | const color = useThemeColor({ light: lightColor, dark: darkColor }, 'text'); 19 | 20 | return ( 21 | 33 | ); 34 | } 35 | 36 | const styles = StyleSheet.create({ 37 | default: { 38 | fontSize: 16, 39 | lineHeight: 24, 40 | }, 41 | defaultSemiBold: { 42 | fontSize: 16, 43 | lineHeight: 24, 44 | fontWeight: '600', 45 | }, 46 | title: { 47 | fontSize: 32, 48 | fontWeight: 'bold', 49 | lineHeight: 32, 50 | }, 51 | subtitle: { 52 | fontSize: 20, 53 | fontWeight: 'bold', 54 | }, 55 | link: { 56 | lineHeight: 30, 57 | fontSize: 16, 58 | color: '#0a7ea4', 59 | }, 60 | }); 61 | -------------------------------------------------------------------------------- /app/+html.tsx: -------------------------------------------------------------------------------- 1 | import { ScrollViewStyleReset } from 'expo-router/html'; 2 | import { type PropsWithChildren } from 'react'; 3 | 4 | /** 5 | * This file is web-only and used to configure the root HTML for every web page during static rendering. 6 | * The contents of this function only run in Node.js environments and do not have access to the DOM or browser APIs. 7 | */ 8 | export default function Root({ children }: PropsWithChildren) { 9 | return ( 10 | 11 | 12 | 13 | 14 | 15 | 16 | {/* 17 | Disable body scrolling on web. This makes ScrollView components work closer to how they do on native. 18 | However, body scrolling is often nice to have for mobile web. If you want to enable it, remove this line. 19 | */} 20 | 21 | 22 | {/* Using raw CSS styles as an escape-hatch to ensure the background color never flickers in dark-mode. */} 23 |