expo-router 3.1.2 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/build/ExpoRoot.d.ts.map +1 -1
  2. package/build/ExpoRoot.js +57 -15
  3. package/build/ExpoRoot.js.map +1 -1
  4. package/build/LocationProvider.d.ts +3 -2
  5. package/build/LocationProvider.d.ts.map +1 -1
  6. package/build/LocationProvider.js +17 -5
  7. package/build/LocationProvider.js.map +1 -1
  8. package/build/Route.d.ts +1 -0
  9. package/build/Route.d.ts.map +1 -1
  10. package/build/Route.js +1 -1
  11. package/build/Route.js.map +1 -1
  12. package/build/fork/NavigationContainer.native.js +5 -3
  13. package/build/fork/NavigationContainer.native.js.map +1 -1
  14. package/build/fork/extractPathFromURL.d.ts.map +1 -1
  15. package/build/fork/extractPathFromURL.js +17 -16
  16. package/build/fork/extractPathFromURL.js.map +1 -1
  17. package/build/fork/getPathFromState.d.ts +1 -1
  18. package/build/fork/getPathFromState.d.ts.map +1 -1
  19. package/build/fork/getPathFromState.js +10 -35
  20. package/build/fork/getPathFromState.js.map +1 -1
  21. package/build/fork/getStateFromPath.d.ts +2 -2
  22. package/build/fork/getStateFromPath.d.ts.map +1 -1
  23. package/build/fork/getStateFromPath.js +59 -48
  24. package/build/fork/getStateFromPath.js.map +1 -1
  25. package/build/getDevServer/index.d.ts +0 -3
  26. package/build/getDevServer/index.d.ts.map +1 -1
  27. package/build/getDevServer/index.js +1 -28
  28. package/build/getDevServer/index.js.map +1 -1
  29. package/build/getReactNavigationConfig.d.ts.map +1 -1
  30. package/build/getReactNavigationConfig.js +3 -0
  31. package/build/getReactNavigationConfig.js.map +1 -1
  32. package/build/getRoutes.d.ts +1 -2
  33. package/build/getRoutes.d.ts.map +1 -1
  34. package/build/getRoutes.js +51 -49
  35. package/build/getRoutes.js.map +1 -1
  36. package/build/getServerManifest.d.ts +4 -0
  37. package/build/getServerManifest.d.ts.map +1 -1
  38. package/build/getServerManifest.js +6 -5
  39. package/build/getServerManifest.js.map +1 -1
  40. package/build/global-state/router-store.d.ts.map +1 -1
  41. package/build/global-state/router-store.js +28 -2
  42. package/build/global-state/router-store.js.map +1 -1
  43. package/build/global-state/routing.d.ts +0 -4
  44. package/build/global-state/routing.d.ts.map +1 -1
  45. package/build/global-state/routing.js +75 -95
  46. package/build/global-state/routing.js.map +1 -1
  47. package/build/head/ExpoHead.ios.js +4 -4
  48. package/build/head/ExpoHead.ios.js.map +1 -1
  49. package/build/head/ExpoHead.js +1 -1
  50. package/build/head/ExpoHead.js.map +1 -1
  51. package/build/head/url.d.ts.map +1 -1
  52. package/build/head/url.js +5 -6
  53. package/build/head/url.js.map +1 -1
  54. package/build/layouts/Tabs.js +2 -2
  55. package/build/layouts/Tabs.js.map +1 -1
  56. package/build/layouts/withLayoutContext.js +1 -1
  57. package/build/layouts/withLayoutContext.js.map +1 -1
  58. package/build/link/Link.d.ts +54 -1
  59. package/build/link/Link.d.ts.map +1 -1
  60. package/build/link/Link.js +54 -12
  61. package/build/link/Link.js.map +1 -1
  62. package/build/link/useLinkToPathProps.js +2 -2
  63. package/build/link/useLinkToPathProps.js.map +1 -1
  64. package/build/matchers.js +1 -1
  65. package/build/matchers.js.map +1 -1
  66. package/build/onboard/Tutorial.js +41 -34
  67. package/build/onboard/Tutorial.js.map +1 -1
  68. package/build/qualified-entry.js +3 -2
  69. package/build/qualified-entry.js.map +1 -1
  70. package/build/renderRootComponent.d.ts.map +1 -1
  71. package/build/renderRootComponent.js +28 -4
  72. package/build/renderRootComponent.js.map +1 -1
  73. package/build/routes-manifest.d.ts +1 -0
  74. package/build/routes-manifest.d.ts.map +1 -1
  75. package/build/routes-manifest.js.map +1 -1
  76. package/build/sortRoutes.d.ts.map +1 -1
  77. package/build/sortRoutes.js +21 -2
  78. package/build/sortRoutes.js.map +1 -1
  79. package/build/static/html.js +11 -9
  80. package/build/static/html.js.map +1 -1
  81. package/build/static/renderStaticContent.d.ts +39 -2
  82. package/build/static/renderStaticContent.d.ts.map +1 -1
  83. package/build/static/renderStaticContent.js +28 -6
  84. package/build/static/renderStaticContent.js.map +1 -1
  85. package/build/testing-library/index.js +2 -2
  86. package/build/testing-library/index.js.map +1 -1
  87. package/build/testing-library/mocks.d.ts +1 -3
  88. package/build/testing-library/mocks.d.ts.map +1 -1
  89. package/build/testing-library/mocks.js +7 -5
  90. package/build/testing-library/mocks.js.map +1 -1
  91. package/build/testing-library/require-context-ponyfill.js +3 -3
  92. package/build/testing-library/require-context-ponyfill.js.map +1 -1
  93. package/build/useScreens.js +19 -16
  94. package/build/useScreens.js.map +1 -1
  95. package/build/views/EmptyRoute.js +5 -2
  96. package/build/views/EmptyRoute.js.map +1 -1
  97. package/build/views/ErrorBoundary.js +43 -28
  98. package/build/views/ErrorBoundary.js.map +1 -1
  99. package/build/views/Navigator.js +16 -10
  100. package/build/views/Navigator.js.map +1 -1
  101. package/build/views/Sitemap.js +49 -35
  102. package/build/views/Sitemap.js.map +1 -1
  103. package/build/views/Splash.d.ts +1 -27
  104. package/build/views/Splash.d.ts.map +1 -1
  105. package/build/views/Splash.js +2 -112
  106. package/build/views/Splash.js.map +1 -1
  107. package/build/views/SuspenseFallback.js +3 -2
  108. package/build/views/SuspenseFallback.js.map +1 -1
  109. package/build/views/Toast.js +23 -18
  110. package/build/views/Toast.js.map +1 -1
  111. package/build/views/Try.js +1 -1
  112. package/build/views/Try.js.map +1 -1
  113. package/build/views/Unmatched.js +29 -17
  114. package/build/views/Unmatched.js.map +1 -1
  115. package/ios/ExpoHead.podspec +1 -1
  116. package/package.json +7 -18
  117. package/build/fork/react-native-web-container.d.ts +0 -8
  118. package/build/fork/react-native-web-container.d.ts.map +0 -1
  119. package/build/fork/react-native-web-container.js +0 -8
  120. package/build/fork/react-native-web-container.js.map +0 -1
  121. package/build/link/stateOperations.d.ts +0 -81
  122. package/build/link/stateOperations.d.ts.map +0 -1
  123. package/build/link/stateOperations.js +0 -105
  124. package/build/link/stateOperations.js.map +0 -1
  125. package/types/global.d.ts +0 -38
  126. package/types/metro-require.d.ts +0 -52
  127. package/types/react-native-web.d.ts +0 -295
@@ -1 +1 @@
1
- {"version":3,"file":"withLayoutContext.js","sourceRoot":"","sources":["../../src/layouts/withLayoutContext.tsx"],"names":[],"mappings":"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","sourcesContent":["import { EventMapBase, NavigationState } from '@react-navigation/native';\nimport React from 'react';\n\nimport { useContextKey } from '../Route';\nimport { PickPartial } from '../types';\nimport { useSortedScreens, ScreenProps } from '../useScreens';\nimport { Screen } from '../views/Screen';\n\nexport function useFilterScreenChildren(\n children: React.ReactNode,\n {\n isCustomNavigator,\n contextKey,\n }: {\n isCustomNavigator?: boolean;\n /** Used for sending developer hints */\n contextKey?: string;\n } = {}\n) {\n return React.useMemo(() => {\n const customChildren: any[] = [];\n const screens = React.Children.map(children, (child) => {\n if (React.isValidElement(child) && child && child.type === Screen) {\n if (!child.props.name) {\n throw new Error(\n `<Screen /> component in \\`default export\\` at \\`app${contextKey}/_layout\\` must have a \\`name\\` prop when used as a child of a Layout Route.`\n );\n }\n if (process.env.NODE_ENV !== 'production') {\n if (['children', 'component', 'getComponent'].some((key) => key in child.props)) {\n throw new Error(\n `<Screen /> component in \\`default export\\` at \\`app${contextKey}/_layout\\` must not have a \\`children\\`, \\`component\\`, or \\`getComponent\\` prop when used as a child of a Layout Route`\n );\n }\n }\n return child.props;\n } else {\n if (isCustomNavigator) {\n customChildren.push(child);\n } else {\n console.warn(\n `Layout children must be of type Screen, all other children are ignored. To use custom children, create a custom <Layout />. Update Layout Route at: \"app${contextKey}/_layout\"`\n );\n }\n }\n });\n\n // Add an assertion for development\n if (process.env.NODE_ENV !== 'production') {\n // Assert if names are not unique\n const names = screens?.map((screen) => screen.name);\n if (names && new Set(names).size !== names.length) {\n throw new Error('Screen names must be unique: ' + names);\n }\n }\n\n return {\n screens,\n children: customChildren,\n };\n }, [children]);\n}\n\n/** Return a navigator that automatically injects matched routes and renders nothing when there are no children. Return type with children prop optional */\nexport function withLayoutContext<\n TOptions extends object,\n T extends React.ComponentType<any>,\n State extends NavigationState,\n EventMap extends EventMapBase,\n>(\n Nav: T,\n processor?: (\n options: ScreenProps<TOptions, State, EventMap>[]\n ) => ScreenProps<TOptions, State, EventMap>[]\n): React.ForwardRefExoticComponent<\n React.PropsWithoutRef<PickPartial<React.ComponentProps<T>, 'children'>> &\n React.RefAttributes<unknown>\n> & {\n Screen: (props: ScreenProps<TOptions, State, EventMap>) => null;\n} {\n const Navigator = React.forwardRef(\n (\n { children: userDefinedChildren, ...props }: PickPartial<React.ComponentProps<T>, 'children'>,\n ref\n ) => {\n const contextKey = useContextKey();\n\n const { screens } = useFilterScreenChildren(userDefinedChildren, {\n contextKey,\n });\n\n const processed = processor ? processor(screens ?? []) : screens;\n\n const sorted = useSortedScreens(processed ?? []);\n\n // Prevent throwing an error when there are no screens.\n if (!sorted.length) {\n return null;\n }\n\n return (\n // @ts-expect-error\n <Nav {...props} id={contextKey} ref={ref} children={sorted} />\n );\n }\n );\n\n // @ts-expect-error\n Navigator.Screen = Screen;\n // @ts-expect-error\n return Navigator;\n}\n"]}
1
+ {"version":3,"file":"withLayoutContext.js","sourceRoot":"","sources":["../../src/layouts/withLayoutContext.tsx"],"names":[],"mappings":"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","sourcesContent":["import { EventMapBase, NavigationState } from '@react-navigation/native';\nimport React from 'react';\n\nimport { useContextKey } from '../Route';\nimport { PickPartial } from '../types';\nimport { useSortedScreens, ScreenProps } from '../useScreens';\nimport { Screen } from '../views/Screen';\n\nexport function useFilterScreenChildren(\n children: React.ReactNode,\n {\n isCustomNavigator,\n contextKey,\n }: {\n isCustomNavigator?: boolean;\n /** Used for sending developer hints */\n contextKey?: string;\n } = {}\n) {\n return React.useMemo(() => {\n const customChildren: any[] = [];\n const screens = React.Children.map(children, (child) => {\n if (React.isValidElement(child) && child && child.type === Screen) {\n if (!child.props.name) {\n throw new Error(\n `<Screen /> component in \\`default export\\` at \\`app${contextKey}/_layout\\` must have a \\`name\\` prop when used as a child of a Layout Route.`\n );\n }\n if (process.env.NODE_ENV !== 'production') {\n if (['children', 'component', 'getComponent'].some((key) => key in child.props)) {\n throw new Error(\n `<Screen /> component in \\`default export\\` at \\`app${contextKey}/_layout\\` must not have a \\`children\\`, \\`component\\`, or \\`getComponent\\` prop when used as a child of a Layout Route`\n );\n }\n }\n return child.props;\n } else {\n if (isCustomNavigator) {\n customChildren.push(child);\n } else {\n console.warn(\n `Layout children must be of type Screen, all other children are ignored. To use custom children, create a custom <Layout />. Update Layout Route at: \"app${contextKey}/_layout\"`\n );\n }\n }\n });\n\n // Add an assertion for development\n if (process.env.NODE_ENV !== 'production') {\n // Assert if names are not unique\n const names = screens?.map((screen) => screen.name);\n if (names && new Set(names).size !== names.length) {\n throw new Error('Screen names must be unique: ' + names);\n }\n }\n\n return {\n screens,\n children: customChildren,\n };\n }, [children]);\n}\n\n/** Return a navigator that automatically injects matched routes and renders nothing when there are no children. Return type with children prop optional */\nexport function withLayoutContext<\n TOptions extends object,\n T extends React.ComponentType<any>,\n State extends NavigationState,\n EventMap extends EventMapBase,\n>(\n Nav: T,\n processor?: (\n options: ScreenProps<TOptions, State, EventMap>[]\n ) => ScreenProps<TOptions, State, EventMap>[]\n): React.ForwardRefExoticComponent<\n React.PropsWithoutRef<PickPartial<React.ComponentProps<T>, 'children'>> &\n React.RefAttributes<unknown>\n> & {\n Screen: (props: ScreenProps<TOptions, State, EventMap>) => null;\n} {\n const Navigator = React.forwardRef(\n (\n { children: userDefinedChildren, ...props }: PickPartial<React.ComponentProps<T>, 'children'>,\n ref\n ) => {\n const contextKey = useContextKey();\n\n const { screens } = useFilterScreenChildren(userDefinedChildren, {\n contextKey,\n });\n\n const processed = processor ? processor(screens ?? []) : screens;\n\n const sorted = useSortedScreens(processed ?? []);\n\n // Prevent throwing an error when there are no screens.\n if (!sorted.length) {\n return null;\n }\n\n return (\n // @ts-expect-error\n <Nav {...props} id={contextKey} ref={ref} children={sorted} />\n );\n }\n );\n\n // @ts-expect-error\n Navigator.Screen = Screen;\n // @ts-expect-error\n return Navigator;\n}\n"]}
@@ -1,13 +1,64 @@
1
1
  import * as React from 'react';
2
2
  import { TextProps, GestureResponderEvent } from 'react-native';
3
3
  import { Href, resolveHref } from './href';
4
- export interface LinkProps extends Omit<TextProps, 'href' | 'hoverStyle'> {
4
+ interface WebAnchorProps {
5
+ /**
6
+ * **Web only:** Specifies where to open the `href`.
7
+ *
8
+ * - **_self**: the current tab.
9
+ * - **_blank**: opens in a new tab or window.
10
+ * - **_parent**: opens in the parent browsing context. If no parent, defaults to **_self**.
11
+ * - **_top**: opens in the highest browsing context ancestor. If no ancestors, defaults to **_self**.
12
+ *
13
+ * This property is passed to the underlying anchor (`<a>`) tag.
14
+ *
15
+ * @default '_self'
16
+ *
17
+ * @example
18
+ * <Link href="https://expo.dev" target="_blank">Go to Expo in new tab</Link>
19
+ */
20
+ target?: '_self' | '_blank' | '_parent' | '_top' | (string & object);
21
+ /**
22
+ * **Web only:** Specifies the relationship between the `href` and the current route.
23
+ *
24
+ * Common values:
25
+ * - **nofollow**: Indicates to search engines that they should not follow the `href`. This is often used for user-generated content or links that should not influence search engine rankings.
26
+ * - **noopener**: Suggests that the `href` should not have access to the opening window's `window.opener` object, which is a security measure to prevent potentially harmful behavior in cases of links that open new tabs or windows.
27
+ * - **noreferrer**: Requests that the browser not send the `Referer` HTTP header when navigating to the `href`. This can enhance user privacy.
28
+ *
29
+ * The `rel` property is primarily used for informational and instructive purposes, helping browsers and web
30
+ * crawlers make better decisions about how to handle and interpret the links on a web page. It is important
31
+ * to use appropriate `rel` values to ensure that links behave as intended and adhere to best practices for web
32
+ * development and SEO (Search Engine Optimization).
33
+ *
34
+ * This property is passed to the underlying anchor (`<a>`) tag.
35
+ *
36
+ * @example
37
+ * <Link href="https://expo.dev" rel="nofollow">Go to Expo</Link>
38
+ */
39
+ rel?: string;
40
+ /**
41
+ * **Web only:** Specifies that the `href` should be downloaded when the user clicks on the link,
42
+ * instead of navigating to it. It is typically used for links that point to files that the user should download,
43
+ * such as PDFs, images, documents, etc.
44
+ *
45
+ * The value of the `download` property, which represents the filename for the downloaded file.
46
+ * This property is passed to the underlying anchor (`<a>`) tag.
47
+ *
48
+ * @example
49
+ * <Link href="/image.jpg" download="my-image.jpg">Download image</Link>
50
+ */
51
+ download?: string;
52
+ }
53
+ export interface LinkProps extends Omit<TextProps, 'href'>, WebAnchorProps {
5
54
  /** Path to route to. */
6
55
  href: Href;
7
56
  /** Forward props to child component. Useful for custom buttons. */
8
57
  asChild?: boolean;
9
58
  /** Should replace the current route without adding to the history. */
10
59
  replace?: boolean;
60
+ /** On web, this sets the HTML `class` directly. On native, this can be used with CSS interop tools like Nativewind. */
61
+ className?: string;
11
62
  onPress?: (e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent) => void;
12
63
  }
13
64
  /** Redirects to the href as soon as the component is mounted. */
@@ -27,6 +78,8 @@ export interface LinkComponent {
27
78
  * @param props.replace Should replace the current route without adding to the history.
28
79
  * @param props.asChild Forward props to child component. Useful for custom buttons.
29
80
  * @param props.children Child elements to render the content.
81
+ * @param props.className On web, this sets the HTML `class` directly. On native, this can be used with CSS interop tools like Nativewind.
30
82
  */
31
83
  export declare const Link: LinkComponent;
84
+ export {};
32
85
  //# sourceMappingURL=Link.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../src/link/Link.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAQ,SAAS,EAAE,qBAAqB,EAAY,MAAM,cAAc,CAAC;AAEhF,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAK3C,MAAM,WAAW,SAAU,SAAQ,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,CAAC;IACvE,wBAAwB;IACxB,IAAI,EAAE,IAAI,CAAC;IAGX,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,sEAAsE;IACtE,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,EAAE,UAAU,CAAC,GAAG,qBAAqB,KAAK,IAAI,CAAC;CAChG;AAED,iEAAiE;AACjE,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,QAUhD;AAED,MAAM,WAAW,aAAa;IAC5B,CAAC,KAAK,EAAE,KAAK,CAAC,iBAAiB,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC;IACzD,6DAA6D;IAC7D,WAAW,EAAE,OAAO,WAAW,CAAC;CACjC;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,IAAI,eAA+D,CAAC"}
1
+ {"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../src/link/Link.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAQ,SAAS,EAAE,qBAAqB,EAAY,MAAM,cAAc,CAAC;AAEhF,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAK3C,UAAU,cAAc;IACtB;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IAErE;;;;;;;;;;;;;;;;;OAiBG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAU,SAAQ,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,cAAc;IACxE,wBAAwB;IACxB,IAAI,EAAE,IAAI,CAAC;IAGX,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,sEAAsE;IACtE,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,uHAAuH;IACvH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,EAAE,UAAU,CAAC,GAAG,qBAAqB,KAAK,IAAI,CAAC;CAChG;AAED,iEAAiE;AACjE,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,QAUhD;AAED,MAAM,WAAW,aAAa;IAC5B,CAAC,KAAK,EAAE,KAAK,CAAC,iBAAiB,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC;IACzD,6DAA6D;IAC7D,WAAW,EAAE,OAAO,WAAW,CAAC;CACjC;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,IAAI,eAA+D,CAAC"}
@@ -58,12 +58,57 @@ exports.Redirect = Redirect;
58
58
  * @param props.replace Should replace the current route without adding to the history.
59
59
  * @param props.asChild Forward props to child component. Useful for custom buttons.
60
60
  * @param props.children Child elements to render the content.
61
+ * @param props.className On web, this sets the HTML `class` directly. On native, this can be used with CSS interop tools like Nativewind.
61
62
  */
62
63
  exports.Link = React.forwardRef(ExpoRouterLink);
63
64
  exports.Link.resolveHref = href_1.resolveHref;
65
+ // Mutate the style prop to add the className on web.
66
+ function useInteropClassName(props) {
67
+ if (react_native_1.Platform.OS !== 'web') {
68
+ return props.style;
69
+ }
70
+ // eslint-disable-next-line react-hooks/rules-of-hooks
71
+ return React.useMemo(() => {
72
+ if (props.className == null) {
73
+ return props.style;
74
+ }
75
+ const cssStyle = {
76
+ $$css: true,
77
+ __routerLinkClassName: props.className,
78
+ };
79
+ if (Array.isArray(props.style)) {
80
+ return [...props.style, cssStyle];
81
+ }
82
+ return [props.style, cssStyle];
83
+ }, [props.style, props.className]);
84
+ }
85
+ const useHrefAttrs = react_native_1.Platform.select({
86
+ web: function useHrefAttrs({ asChild, rel, target, download }) {
87
+ return React.useMemo(() => {
88
+ const hrefAttrs = {
89
+ rel,
90
+ target,
91
+ download,
92
+ };
93
+ if (asChild) {
94
+ return hrefAttrs;
95
+ }
96
+ return {
97
+ hrefAttrs,
98
+ };
99
+ }, [asChild, rel, target, download]);
100
+ },
101
+ default: function useHrefAttrs() {
102
+ return {};
103
+ },
104
+ });
64
105
  function ExpoRouterLink({ href, replace,
65
106
  // TODO: This does not prevent default on the anchor tag.
66
- asChild, ...rest }, ref) {
107
+ asChild, rel, target, download, ...rest }, ref) {
108
+ // Mutate the style prop to add the className on web.
109
+ const style = useInteropClassName(rest);
110
+ // If not passing asChild, we need to forward the props to the anchor tag using React Native Web's `hrefAttrs`.
111
+ const hrefAttrs = useHrefAttrs({ asChild, rel, target, download });
67
112
  const resolvedHref = React.useMemo(() => {
68
113
  if (href == null) {
69
114
  throw new Error('Link: href is required');
@@ -77,16 +122,13 @@ asChild, ...rest }, ref) {
77
122
  }
78
123
  props.onPress(e);
79
124
  };
80
- return React.createElement(
81
- // @ts-expect-error: slot is not type-safe
82
- asChild ? react_slot_1.Slot : react_native_1.Text, {
83
- ref,
84
- ...props,
85
- ...rest,
86
- ...react_native_1.Platform.select({
87
- web: { onClick: onPress },
88
- default: { onPress },
89
- }),
90
- });
125
+ const Element = asChild ? react_slot_1.Slot : react_native_1.Text;
126
+ // Avoid using createElement directly, favoring JSX, to allow tools like Nativewind to perform custom JSX handling on native.
127
+ return (<Element ref={ref} {...props} {...hrefAttrs} {...rest} style={style} {...react_native_1.Platform.select({
128
+ web: {
129
+ onClick: onPress,
130
+ },
131
+ default: { onPress },
132
+ })}/>);
91
133
  }
92
134
  //# sourceMappingURL=Link.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Link.js","sourceRoot":"","sources":["../../src/link/Link.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wFAAwF;AACxF,mCAAmC;AACnC,qDAA4C;AAC5C,6CAA+B;AAC/B,+CAAgF;AAEhF,iCAA2C;AAC3C,8EAAsD;AACtD,oCAAqC;AACrC,sDAAmD;AAgBnD,iEAAiE;AACjE,SAAgB,QAAQ,CAAC,EAAE,IAAI,EAAkB;IAC/C,MAAM,MAAM,GAAG,IAAA,iBAAS,GAAE,CAAC;IAC3B,IAAA,+BAAc,EAAC,GAAG,EAAE;QAClB,IAAI;YACF,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;SACtB;QAAC,OAAO,KAAK,EAAE;YACd,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;SACtB;IACH,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC;AACd,CAAC;AAVD,4BAUC;AAQD;;;;;;;;GAQG;AACU,QAAA,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,cAAc,CAA6B,CAAC;AAEjF,YAAI,CAAC,WAAW,GAAG,kBAAW,CAAC;AAE/B,SAAS,cAAc,CACrB,EACE,IAAI,EACJ,OAAO;AACP,yDAAyD;AACzD,OAAO,EACP,GAAG,IAAI,EACG,EACZ,GAA6B;IAE7B,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACtC,IAAI,IAAI,IAAI,IAAI,EAAE;YAChB,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;SAC3C;QACD,OAAO,IAAA,kBAAW,EAAC,IAAI,CAAC,CAAC;IAC3B,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,MAAM,KAAK,GAAG,IAAA,4BAAkB,EAAC,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC;IAElE,MAAM,OAAO,GAAG,CAAC,CAA0E,EAAE,EAAE;QAC7F,IAAI,SAAS,IAAI,IAAI,EAAE;YACrB,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;SACnB;QACD,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC,CAAC;IAEF,OAAO,KAAK,CAAC,aAAa;IACxB,0CAA0C;IAC1C,OAAO,CAAC,CAAC,CAAC,iBAAI,CAAC,CAAC,CAAC,mBAAI,EACrB;QACE,GAAG;QACH,GAAG,KAAK;QACR,GAAG,IAAI;QACP,GAAG,uBAAQ,CAAC,MAAM,CAAC;YACjB,GAAG,EAAE,EAAE,OAAO,EAAE,OAAO,EAAS;YAChC,OAAO,EAAE,EAAE,OAAO,EAAE;SACrB,CAAC;KACH,CACF,CAAC;AACJ,CAAC","sourcesContent":["// Fork of @react-navigation/native Link.tsx with `href` and `replace` support added and\n// `to` / `action` support removed.\nimport { Slot } from '@radix-ui/react-slot';\nimport * as React from 'react';\nimport { Text, TextProps, GestureResponderEvent, Platform } from 'react-native';\n\nimport { Href, resolveHref } from './href';\nimport useLinkToPathProps from './useLinkToPathProps';\nimport { useRouter } from '../hooks';\nimport { useFocusEffect } from '../useFocusEffect';\n\nexport interface LinkProps extends Omit<TextProps, 'href' | 'hoverStyle'> {\n /** Path to route to. */\n href: Href;\n\n // TODO(EvanBacon): This may need to be extracted for React Native style support.\n /** Forward props to child component. Useful for custom buttons. */\n asChild?: boolean;\n\n /** Should replace the current route without adding to the history. */\n replace?: boolean;\n\n onPress?: (e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent) => void;\n}\n\n/** Redirects to the href as soon as the component is mounted. */\nexport function Redirect({ href }: { href: Href }) {\n const router = useRouter();\n useFocusEffect(() => {\n try {\n router.replace(href);\n } catch (error) {\n console.error(error);\n }\n });\n return null;\n}\n\nexport interface LinkComponent {\n (props: React.PropsWithChildren<LinkProps>): JSX.Element;\n /** Helper method to resolve an Href object into a string. */\n resolveHref: typeof resolveHref;\n}\n\n/**\n * Component to render link to another route using a path.\n * Uses an anchor tag on the web.\n *\n * @param props.href Absolute path to route (e.g. `/feeds/hot`).\n * @param props.replace Should replace the current route without adding to the history.\n * @param props.asChild Forward props to child component. Useful for custom buttons.\n * @param props.children Child elements to render the content.\n */\nexport const Link = React.forwardRef(ExpoRouterLink) as unknown as LinkComponent;\n\nLink.resolveHref = resolveHref;\n\nfunction ExpoRouterLink(\n {\n href,\n replace,\n // TODO: This does not prevent default on the anchor tag.\n asChild,\n ...rest\n }: LinkProps,\n ref: React.ForwardedRef<Text>\n) {\n const resolvedHref = React.useMemo(() => {\n if (href == null) {\n throw new Error('Link: href is required');\n }\n return resolveHref(href);\n }, [href]);\n\n const props = useLinkToPathProps({ href: resolvedHref, replace });\n\n const onPress = (e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent) => {\n if ('onPress' in rest) {\n rest.onPress?.(e);\n }\n props.onPress(e);\n };\n\n return React.createElement(\n // @ts-expect-error: slot is not type-safe\n asChild ? Slot : Text,\n {\n ref,\n ...props,\n ...rest,\n ...Platform.select({\n web: { onClick: onPress } as any,\n default: { onPress },\n }),\n }\n );\n}\n"]}
1
+ {"version":3,"file":"Link.js","sourceRoot":"","sources":["../../src/link/Link.tsx"],"names":[],"mappings":"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","sourcesContent":["// Fork of @react-navigation/native Link.tsx with `href` and `replace` support added and\n// `to` / `action` support removed.\nimport { Slot } from '@radix-ui/react-slot';\nimport * as React from 'react';\nimport { Text, TextProps, GestureResponderEvent, Platform } from 'react-native';\n\nimport { Href, resolveHref } from './href';\nimport useLinkToPathProps from './useLinkToPathProps';\nimport { useRouter } from '../hooks';\nimport { useFocusEffect } from '../useFocusEffect';\n\ninterface WebAnchorProps {\n /**\n * **Web only:** Specifies where to open the `href`.\n *\n * - **_self**: the current tab.\n * - **_blank**: opens in a new tab or window.\n * - **_parent**: opens in the parent browsing context. If no parent, defaults to **_self**.\n * - **_top**: opens in the highest browsing context ancestor. If no ancestors, defaults to **_self**.\n *\n * This property is passed to the underlying anchor (`<a>`) tag.\n *\n * @default '_self'\n *\n * @example\n * <Link href=\"https://expo.dev\" target=\"_blank\">Go to Expo in new tab</Link>\n */\n target?: '_self' | '_blank' | '_parent' | '_top' | (string & object);\n\n /**\n * **Web only:** Specifies the relationship between the `href` and the current route.\n *\n * Common values:\n * - **nofollow**: Indicates to search engines that they should not follow the `href`. This is often used for user-generated content or links that should not influence search engine rankings.\n * - **noopener**: Suggests that the `href` should not have access to the opening window's `window.opener` object, which is a security measure to prevent potentially harmful behavior in cases of links that open new tabs or windows.\n * - **noreferrer**: Requests that the browser not send the `Referer` HTTP header when navigating to the `href`. This can enhance user privacy.\n *\n * The `rel` property is primarily used for informational and instructive purposes, helping browsers and web\n * crawlers make better decisions about how to handle and interpret the links on a web page. It is important\n * to use appropriate `rel` values to ensure that links behave as intended and adhere to best practices for web\n * development and SEO (Search Engine Optimization).\n *\n * This property is passed to the underlying anchor (`<a>`) tag.\n *\n * @example\n * <Link href=\"https://expo.dev\" rel=\"nofollow\">Go to Expo</Link>\n */\n rel?: string;\n\n /**\n * **Web only:** Specifies that the `href` should be downloaded when the user clicks on the link,\n * instead of navigating to it. It is typically used for links that point to files that the user should download,\n * such as PDFs, images, documents, etc.\n *\n * The value of the `download` property, which represents the filename for the downloaded file.\n * This property is passed to the underlying anchor (`<a>`) tag.\n *\n * @example\n * <Link href=\"/image.jpg\" download=\"my-image.jpg\">Download image</Link>\n */\n download?: string;\n}\n\nexport interface LinkProps extends Omit<TextProps, 'href'>, WebAnchorProps {\n /** Path to route to. */\n href: Href;\n\n // TODO(EvanBacon): This may need to be extracted for React Native style support.\n /** Forward props to child component. Useful for custom buttons. */\n asChild?: boolean;\n\n /** Should replace the current route without adding to the history. */\n replace?: boolean;\n\n /** On web, this sets the HTML `class` directly. On native, this can be used with CSS interop tools like Nativewind. */\n className?: string;\n\n onPress?: (e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent) => void;\n}\n\n/** Redirects to the href as soon as the component is mounted. */\nexport function Redirect({ href }: { href: Href }) {\n const router = useRouter();\n useFocusEffect(() => {\n try {\n router.replace(href);\n } catch (error) {\n console.error(error);\n }\n });\n return null;\n}\n\nexport interface LinkComponent {\n (props: React.PropsWithChildren<LinkProps>): JSX.Element;\n /** Helper method to resolve an Href object into a string. */\n resolveHref: typeof resolveHref;\n}\n\n/**\n * Component to render link to another route using a path.\n * Uses an anchor tag on the web.\n *\n * @param props.href Absolute path to route (e.g. `/feeds/hot`).\n * @param props.replace Should replace the current route without adding to the history.\n * @param props.asChild Forward props to child component. Useful for custom buttons.\n * @param props.children Child elements to render the content.\n * @param props.className On web, this sets the HTML `class` directly. On native, this can be used with CSS interop tools like Nativewind.\n */\nexport const Link = React.forwardRef(ExpoRouterLink) as unknown as LinkComponent;\n\nLink.resolveHref = resolveHref;\n\n// Mutate the style prop to add the className on web.\nfunction useInteropClassName(props: { style?: TextProps['style']; className?: string }) {\n if (Platform.OS !== 'web') {\n return props.style;\n }\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return React.useMemo(() => {\n if (props.className == null) {\n return props.style;\n }\n const cssStyle = {\n $$css: true,\n __routerLinkClassName: props.className,\n };\n\n if (Array.isArray(props.style)) {\n return [...props.style, cssStyle];\n }\n return [props.style, cssStyle];\n }, [props.style, props.className]);\n}\n\nconst useHrefAttrs = Platform.select<\n (props: Partial<LinkProps>) => { hrefAttrs?: any } & Partial<LinkProps>\n>({\n web: function useHrefAttrs({ asChild, rel, target, download }: Partial<LinkProps>) {\n return React.useMemo(() => {\n const hrefAttrs = {\n rel,\n target,\n download,\n };\n if (asChild) {\n return hrefAttrs;\n }\n return {\n hrefAttrs,\n };\n }, [asChild, rel, target, download]);\n },\n default: function useHrefAttrs() {\n return {};\n },\n});\n\nfunction ExpoRouterLink(\n {\n href,\n replace,\n // TODO: This does not prevent default on the anchor tag.\n asChild,\n rel,\n target,\n download,\n ...rest\n }: LinkProps,\n ref: React.ForwardedRef<Text>\n) {\n // Mutate the style prop to add the className on web.\n const style = useInteropClassName(rest);\n\n // If not passing asChild, we need to forward the props to the anchor tag using React Native Web's `hrefAttrs`.\n const hrefAttrs = useHrefAttrs({ asChild, rel, target, download });\n\n const resolvedHref = React.useMemo(() => {\n if (href == null) {\n throw new Error('Link: href is required');\n }\n return resolveHref(href);\n }, [href]);\n\n const props = useLinkToPathProps({ href: resolvedHref, replace });\n\n const onPress = (e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent) => {\n if ('onPress' in rest) {\n rest.onPress?.(e);\n }\n props.onPress(e);\n };\n\n const Element = asChild ? Slot : Text;\n\n // Avoid using createElement directly, favoring JSX, to allow tools like Nativewind to perform custom JSX handling on native.\n return (\n <Element\n ref={ref}\n {...props}\n {...hrefAttrs}\n {...rest}\n style={style}\n {...Platform.select({\n web: {\n onClick: onPress,\n } as any,\n default: { onPress },\n })}\n />\n );\n}\n"]}
@@ -39,8 +39,8 @@ function useLinkToPathProps(props) {
39
39
  }
40
40
  };
41
41
  return {
42
- // Ensure there's always a value for href. Manually append the basePath to the href prop that shows in the static HTML.
43
- href: (0, getPathFromState_1.appendBasePath)((0, matchers_1.stripGroupSegmentsFromPath)(props.href) || '/'),
42
+ // Ensure there's always a value for href. Manually append the baseUrl to the href prop that shows in the static HTML.
43
+ href: (0, getPathFromState_1.appendBaseUrl)((0, matchers_1.stripGroupSegmentsFromPath)(props.href) || '/'),
44
44
  role: 'link',
45
45
  onPress,
46
46
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useLinkToPathProps.js","sourceRoot":"","sources":["../../src/link/useLinkToPathProps.tsx"],"names":[],"mappings":";;AACA,+CAA+D;AAE/D,+DAA0D;AAC1D,+DAA6D;AAC7D,0CAAyD;AAEzD,SAAS,yBAAyB,CAChC,CAA0E;IAE1E,IAAI,CAAC,EAAE,gBAAgB,EAAE;QACvB,OAAO,KAAK,CAAC;KACd;IAED;IACE,yBAAyB;IACzB,QAAQ,IAAI,CAAC;QACb,mCAAmC;QACnC,CAAC,CAAC,CAAC,OAAO;QACV,CAAC,CAAC,CAAC,MAAM;QACT,CAAC,CAAC,CAAC,OAAO;QACV,CAAC,CAAC,CAAC,QAAQ;QACX,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,0BAA0B;QAClE,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,0CAA0C;MACzG;QACA,OAAO,IAAI,CAAC;KACb;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAwB,kBAAkB,CAAC,KAA0C;IACnF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,4BAAa,GAAE,CAAC;IAEnC,MAAM,OAAO,GAAG,CAAC,CAA2E,EAAE,EAAE;QAC9F,IAAI,YAAY,GAAG,KAAK,CAAC;QAEzB,IAAI,uBAAQ,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC,CAAC,EAAE;YAC/B,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC;SAC/C;aAAM,IAAI,yBAAyB,CAAC,CAAC,CAAC,EAAE;YACvC,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,YAAY,GAAG,IAAI,CAAC;SACrB;QAED,IAAI,YAAY,EAAE;YAChB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;SAC3D;IACH,CAAC,CAAC;IAEF,OAAO;QACL,uHAAuH;QACvH,IAAI,EAAE,IAAA,iCAAc,EAAC,IAAA,qCAA0B,EAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;QACnE,IAAI,EAAE,MAAe;QACrB,OAAO;KACR,CAAC;AACJ,CAAC;AAxBD,qCAwBC","sourcesContent":["import * as React from 'react';\nimport { GestureResponderEvent, Platform } from 'react-native';\n\nimport { appendBasePath } from '../fork/getPathFromState';\nimport { useExpoRouter } from '../global-state/router-store';\nimport { stripGroupSegmentsFromPath } from '../matchers';\n\nfunction eventShouldPreventDefault(\n e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent\n): boolean {\n if (e?.defaultPrevented) {\n return false;\n }\n\n if (\n // Only check MouseEvents\n 'button' in e &&\n // ignore clicks with modifier keys\n !e.metaKey &&\n !e.altKey &&\n !e.ctrlKey &&\n !e.shiftKey &&\n (e.button == null || e.button === 0) && // Only accept left clicks\n [undefined, null, '', 'self'].includes(e.currentTarget.target) // let browser handle \"target=_blank\" etc.\n ) {\n return true;\n }\n\n return false;\n}\n\nexport default function useLinkToPathProps(props: { href: string; replace?: boolean }) {\n const { linkTo } = useExpoRouter();\n\n const onPress = (e?: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent) => {\n let shouldHandle = false;\n\n if (Platform.OS !== 'web' || !e) {\n shouldHandle = e ? !e.defaultPrevented : true;\n } else if (eventShouldPreventDefault(e)) {\n e.preventDefault();\n shouldHandle = true;\n }\n\n if (shouldHandle) {\n linkTo(props.href, props.replace ? 'REPLACE' : undefined);\n }\n };\n\n return {\n // Ensure there's always a value for href. Manually append the basePath to the href prop that shows in the static HTML.\n href: appendBasePath(stripGroupSegmentsFromPath(props.href) || '/'),\n role: 'link' as const,\n onPress,\n };\n}\n"]}
1
+ {"version":3,"file":"useLinkToPathProps.js","sourceRoot":"","sources":["../../src/link/useLinkToPathProps.tsx"],"names":[],"mappings":";;AACA,+CAA+D;AAE/D,+DAAyD;AACzD,+DAA6D;AAC7D,0CAAyD;AAEzD,SAAS,yBAAyB,CAChC,CAA0E;IAE1E,IAAI,CAAC,EAAE,gBAAgB,EAAE;QACvB,OAAO,KAAK,CAAC;KACd;IAED;IACE,yBAAyB;IACzB,QAAQ,IAAI,CAAC;QACb,mCAAmC;QACnC,CAAC,CAAC,CAAC,OAAO;QACV,CAAC,CAAC,CAAC,MAAM;QACT,CAAC,CAAC,CAAC,OAAO;QACV,CAAC,CAAC,CAAC,QAAQ;QACX,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,0BAA0B;QAClE,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,0CAA0C;MACzG;QACA,OAAO,IAAI,CAAC;KACb;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAwB,kBAAkB,CAAC,KAA0C;IACnF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,4BAAa,GAAE,CAAC;IAEnC,MAAM,OAAO,GAAG,CAAC,CAA2E,EAAE,EAAE;QAC9F,IAAI,YAAY,GAAG,KAAK,CAAC;QAEzB,IAAI,uBAAQ,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC,CAAC,EAAE;YAC/B,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC;SAC/C;aAAM,IAAI,yBAAyB,CAAC,CAAC,CAAC,EAAE;YACvC,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,YAAY,GAAG,IAAI,CAAC;SACrB;QAED,IAAI,YAAY,EAAE;YAChB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;SAC3D;IACH,CAAC,CAAC;IAEF,OAAO;QACL,sHAAsH;QACtH,IAAI,EAAE,IAAA,gCAAa,EAAC,IAAA,qCAA0B,EAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;QAClE,IAAI,EAAE,MAAe;QACrB,OAAO;KACR,CAAC;AACJ,CAAC;AAxBD,qCAwBC","sourcesContent":["import * as React from 'react';\nimport { GestureResponderEvent, Platform } from 'react-native';\n\nimport { appendBaseUrl } from '../fork/getPathFromState';\nimport { useExpoRouter } from '../global-state/router-store';\nimport { stripGroupSegmentsFromPath } from '../matchers';\n\nfunction eventShouldPreventDefault(\n e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent\n): boolean {\n if (e?.defaultPrevented) {\n return false;\n }\n\n if (\n // Only check MouseEvents\n 'button' in e &&\n // ignore clicks with modifier keys\n !e.metaKey &&\n !e.altKey &&\n !e.ctrlKey &&\n !e.shiftKey &&\n (e.button == null || e.button === 0) && // Only accept left clicks\n [undefined, null, '', 'self'].includes(e.currentTarget.target) // let browser handle \"target=_blank\" etc.\n ) {\n return true;\n }\n\n return false;\n}\n\nexport default function useLinkToPathProps(props: { href: string; replace?: boolean }) {\n const { linkTo } = useExpoRouter();\n\n const onPress = (e?: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent) => {\n let shouldHandle = false;\n\n if (Platform.OS !== 'web' || !e) {\n shouldHandle = e ? !e.defaultPrevented : true;\n } else if (eventShouldPreventDefault(e)) {\n e.preventDefault();\n shouldHandle = true;\n }\n\n if (shouldHandle) {\n linkTo(props.href, props.replace ? 'REPLACE' : undefined);\n }\n };\n\n return {\n // Ensure there's always a value for href. Manually append the baseUrl to the href prop that shows in the static HTML.\n href: appendBaseUrl(stripGroupSegmentsFromPath(props.href) || '/'),\n role: 'link' as const,\n onPress,\n };\n}\n"]}
package/build/matchers.js CHANGED
@@ -15,7 +15,7 @@ function matchDeepDynamicRouteName(name) {
15
15
  exports.matchDeepDynamicRouteName = matchDeepDynamicRouteName;
16
16
  /** Match `(page)` -> `page` */
17
17
  function matchGroupName(name) {
18
- return name.match(/^\(([^/]+?)\)$/)?.[1];
18
+ return name.match(/^(?:[^\\(\\)])*?\(([^\\/]+)\).*?$/)?.[1];
19
19
  }
20
20
  exports.matchGroupName = matchGroupName;
21
21
  function getNameFromFilePath(name) {
@@ -1 +1 @@
1
- {"version":3,"file":"matchers.js","sourceRoot":"","sources":["../src/matchers.tsx"],"names":[],"mappings":";;;AAAA,+BAA+B;AAC/B,SAAgB,gBAAgB,CAAC,IAAY;IAC3C,sDAAsD;IACtD,6CAA6C;IAC7C,OAAO,IAAI,CAAC,KAAK,CAAC,4BAA4B,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACvD,CAAC;AAJD,4CAIC;AAED,kCAAkC;AAClC,SAAgB,yBAAyB,CAAC,IAAY;IACpD,OAAO,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC;AAFD,8DAEC;AAED,+BAA+B;AAC/B,SAAgB,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC3C,CAAC;AAFD,wCAEC;AAED,SAAgB,mBAAmB,CAAC,IAAY;IAC9C,OAAO,yBAAyB,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/D,CAAC;AAFD,kDAEC;AAED,SAAgB,aAAa,CAAC,IAAY;IACxC,qEAAqE;IACrE,uBAAuB;IACvB,MAAM,MAAM,GAAG,GAAG,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAC/C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;QAC/B,OAAO,MAAM,CAAC;KACf;IACD,OAAO,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC;AARD,sCAQC;AAED,0CAA0C;AAC1C,SAAgB,yBAAyB,CAAC,IAAY;IACpD,OAAO,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;AACjD,CAAC;AAFD,8DAEC;AAED,mEAAmE;AACnE,SAAgB,oBAAoB,CAAC,QAAgB;IACnD,OAAO,QAAQ,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;AAChD,CAAC;AAFD,oDAEC;AAED,SAAgB,0BAA0B,CAAC,IAAY;IACrD,OAAO,IAAI;SACR,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;QACjB,IAAI,cAAc,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE;YAC7B,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;SACb;QACD,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,EAAc,CAAC;SACjB,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAVD,gEAUC;AAED,SAAgB,8BAA8B,CAAC,IAAY;IACzD,OAAO,0BAA0B,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AACnE,CAAC;AAFD,wEAEC","sourcesContent":["/** Match `[page]` -> `page` */\nexport function matchDynamicName(name: string): string | undefined {\n // Don't match `...` or `[` or `]` inside the brackets\n // eslint-disable-next-line no-useless-escape\n return name.match(/^\\[([^[\\](?:\\.\\.\\.)]+?)\\]$/)?.[1];\n}\n\n/** Match `[...page]` -> `page` */\nexport function matchDeepDynamicRouteName(name: string): string | undefined {\n return name.match(/^\\[\\.\\.\\.([^/]+?)\\]$/)?.[1];\n}\n\n/** Match `(page)` -> `page` */\nexport function matchGroupName(name: string): string | undefined {\n return name.match(/^\\(([^/]+?)\\)$/)?.[1];\n}\n\nexport function getNameFromFilePath(name: string): string {\n return removeSupportedExtensions(removeFileSystemDots(name));\n}\n\nexport function getContextKey(name: string): string {\n // The root path is `` (empty string) so always prepend `/` to ensure\n // there is some value.\n const normal = '/' + getNameFromFilePath(name);\n if (!normal.endsWith('_layout')) {\n return normal;\n }\n return normal.replace(/\\/?_layout$/, '');\n}\n\n/** Remove `.js`, `.ts`, `.jsx`, `.tsx` */\nexport function removeSupportedExtensions(name: string): string {\n return name.replace(/(\\+api)?\\.[jt]sx?$/g, '');\n}\n\n// Remove any amount of `./` and `../` from the start of the string\nexport function removeFileSystemDots(filePath: string): string {\n return filePath.replace(/^(?:\\.\\.?\\/)+/g, '');\n}\n\nexport function stripGroupSegmentsFromPath(path: string): string {\n return path\n .split('/')\n .reduce((acc, v) => {\n if (matchGroupName(v) == null) {\n acc.push(v);\n }\n return acc;\n }, [] as string[])\n .join('/');\n}\n\nexport function stripInvisibleSegmentsFromPath(path: string): string {\n return stripGroupSegmentsFromPath(path).replace(/\\/?index$/, '');\n}\n"]}
1
+ {"version":3,"file":"matchers.js","sourceRoot":"","sources":["../src/matchers.tsx"],"names":[],"mappings":";;;AAAA,+BAA+B;AAC/B,SAAgB,gBAAgB,CAAC,IAAY;IAC3C,sDAAsD;IACtD,6CAA6C;IAC7C,OAAO,IAAI,CAAC,KAAK,CAAC,4BAA4B,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACvD,CAAC;AAJD,4CAIC;AAED,kCAAkC;AAClC,SAAgB,yBAAyB,CAAC,IAAY;IACpD,OAAO,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC;AAFD,8DAEC;AAED,+BAA+B;AAC/B,SAAgB,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,KAAK,CAAC,mCAAmC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC;AAFD,wCAEC;AAED,SAAgB,mBAAmB,CAAC,IAAY;IAC9C,OAAO,yBAAyB,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/D,CAAC;AAFD,kDAEC;AAED,SAAgB,aAAa,CAAC,IAAY;IACxC,qEAAqE;IACrE,uBAAuB;IACvB,MAAM,MAAM,GAAG,GAAG,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAC/C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;QAC/B,OAAO,MAAM,CAAC;KACf;IACD,OAAO,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC;AARD,sCAQC;AAED,0CAA0C;AAC1C,SAAgB,yBAAyB,CAAC,IAAY;IACpD,OAAO,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;AACjD,CAAC;AAFD,8DAEC;AAED,mEAAmE;AACnE,SAAgB,oBAAoB,CAAC,QAAgB;IACnD,OAAO,QAAQ,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;AAChD,CAAC;AAFD,oDAEC;AAED,SAAgB,0BAA0B,CAAC,IAAY;IACrD,OAAO,IAAI;SACR,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;QACjB,IAAI,cAAc,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE;YAC7B,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;SACb;QACD,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,EAAc,CAAC;SACjB,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAVD,gEAUC;AAED,SAAgB,8BAA8B,CAAC,IAAY;IACzD,OAAO,0BAA0B,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AACnE,CAAC;AAFD,wEAEC","sourcesContent":["/** Match `[page]` -> `page` */\nexport function matchDynamicName(name: string): string | undefined {\n // Don't match `...` or `[` or `]` inside the brackets\n // eslint-disable-next-line no-useless-escape\n return name.match(/^\\[([^[\\](?:\\.\\.\\.)]+?)\\]$/)?.[1];\n}\n\n/** Match `[...page]` -> `page` */\nexport function matchDeepDynamicRouteName(name: string): string | undefined {\n return name.match(/^\\[\\.\\.\\.([^/]+?)\\]$/)?.[1];\n}\n\n/** Match `(page)` -> `page` */\nexport function matchGroupName(name: string): string | undefined {\n return name.match(/^(?:[^\\\\(\\\\)])*?\\(([^\\\\/]+)\\).*?$/)?.[1];\n}\n\nexport function getNameFromFilePath(name: string): string {\n return removeSupportedExtensions(removeFileSystemDots(name));\n}\n\nexport function getContextKey(name: string): string {\n // The root path is `` (empty string) so always prepend `/` to ensure\n // there is some value.\n const normal = '/' + getNameFromFilePath(name);\n if (!normal.endsWith('_layout')) {\n return normal;\n }\n return normal.replace(/\\/?_layout$/, '');\n}\n\n/** Remove `.js`, `.ts`, `.jsx`, `.tsx` */\nexport function removeSupportedExtensions(name: string): string {\n return name.replace(/(\\+api)?\\.[jt]sx?$/g, '');\n}\n\n// Remove any amount of `./` and `../` from the start of the string\nexport function removeFileSystemDots(filePath: string): string {\n return filePath.replace(/^(?:\\.\\.?\\/)+/g, '');\n}\n\nexport function stripGroupSegmentsFromPath(path: string): string {\n return path\n .split('/')\n .reduce((acc, v) => {\n if (matchGroupName(v) == null) {\n acc.push(v);\n }\n return acc;\n }, [] as string[])\n .join('/');\n}\n\nexport function stripInvisibleSegmentsFromPath(path: string): string {\n return stripGroupSegmentsFromPath(path).replace(/\\/?index$/, '');\n}\n"]}
@@ -12,15 +12,19 @@ const exports_1 = require("../exports");
12
12
  const Pressable_1 = require("../views/Pressable");
13
13
  // TODO: Use openLinkFromBrowser thing
14
14
  function Header() {
15
- return (react_1.default.createElement(Pressable_1.Pressable, null, ({ hovered }) => (react_1.default.createElement(react_native_1.Text, { role: "heading", "aria-level": 1, style: [styles.title, react_native_1.Platform.OS !== 'web' && { textAlign: 'left' }] },
16
- "Welcome to",
17
- ' ',
18
- react_1.default.createElement(exports_1.Link, { href: "https://github.com/expo/expo-router/", style: [
15
+ return (<Pressable_1.Pressable>
16
+ {({ hovered }) => (<react_native_1.Text role="heading" aria-level={1} style={[styles.title, react_native_1.Platform.OS !== 'web' && { textAlign: 'left' }]}>
17
+ Welcome to{' '}
18
+ <exports_1.Link href="https://github.com/expo/expo-router/" style={[
19
19
  hovered && {
20
20
  textDecorationColor: 'white',
21
21
  textDecorationLine: 'underline',
22
22
  },
23
- ] }, "Expo")))));
23
+ ]}>
24
+ Expo
25
+ </exports_1.Link>
26
+ </react_native_1.Text>)}
27
+ </Pressable_1.Pressable>);
24
28
  }
25
29
  const canAutoTouchFile = process.env.EXPO_ROUTER_APP_ROOT != null;
26
30
  function Tutorial() {
@@ -39,19 +43,20 @@ function Tutorial() {
39
43
  }
40
44
  }
41
45
  }, []);
42
- return (react_1.default.createElement(react_native_1.View, { style: styles.background },
43
- react_1.default.createElement(react_native_1.StatusBar, { barStyle: "light-content" }),
44
- react_1.default.createElement(react_native_safe_area_context_1.SafeAreaView, { style: styles.safeArea },
45
- react_1.default.createElement(react_native_1.View, { style: styles.container },
46
- react_1.default.createElement(Header, null),
47
- react_1.default.createElement(react_native_1.Text, { role: "heading", "aria-level": 2, style: styles.subtitle },
48
- "Start by creating a file",
49
- '\n',
50
- "in the",
51
- ' ',
52
- react_1.default.createElement(react_native_1.Text, { style: { fontWeight: 'bold' } }, getRootDir()),
53
- " directory."),
54
- canAutoTouchFile && react_1.default.createElement(Button, null)))));
46
+ return (<react_native_1.View style={styles.background}>
47
+ <react_native_1.StatusBar barStyle="light-content"/>
48
+
49
+ <react_native_safe_area_context_1.SafeAreaView style={styles.safeArea}>
50
+ <react_native_1.View style={styles.container}>
51
+ <Header />
52
+ <react_native_1.Text role="heading" aria-level={2} style={styles.subtitle}>
53
+ Start by creating a file{'\n'}in the{' '}
54
+ <react_native_1.Text style={{ fontWeight: 'bold' }}>{getRootDir()}</react_native_1.Text> directory.
55
+ </react_native_1.Text>
56
+ {canAutoTouchFile && <Button />}
57
+ </react_native_1.View>
58
+ </react_native_safe_area_context_1.SafeAreaView>
59
+ </react_native_1.View>);
55
60
  }
56
61
  exports.Tutorial = Tutorial;
57
62
  function getRootDir() {
@@ -65,9 +70,9 @@ function getRootDir() {
65
70
  return dir.split('/').pop() ?? dir;
66
71
  }
67
72
  function Button() {
68
- return (react_1.default.createElement(Pressable_1.Pressable, { onPress: () => {
73
+ return (<Pressable_1.Pressable onPress={() => {
69
74
  (0, createEntryFile_1.createEntryFileAsync)();
70
- }, style: {
75
+ }} style={{
71
76
  ...react_native_1.Platform.select({
72
77
  web: {
73
78
  // subtle white shadow
@@ -81,20 +86,22 @@ function Button() {
81
86
  overflow: 'hidden',
82
87
  },
83
88
  }),
84
- } }, ({ pressed, hovered }) => (react_1.default.createElement(react_native_1.View, { style: [
85
- styles.buttonContainer,
86
- hovered && {
87
- backgroundColor: 'white',
88
- },
89
- pressed && {
90
- backgroundColor: 'rgba(255,255,255,0.7)',
91
- },
92
- ] },
93
- react_1.default.createElement(react_native_1.Text, { style: [styles.code, hovered && { color: 'black' }] },
94
- react_1.default.createElement(react_native_1.Text, { style: { color: '#BCC3CD' } }, "$"),
95
- " touch ",
96
- getRootDir(),
97
- "/index.js")))));
89
+ }}>
90
+ {({ pressed, hovered }) => (<react_native_1.View style={[
91
+ styles.buttonContainer,
92
+ hovered && {
93
+ backgroundColor: 'white',
94
+ },
95
+ pressed && {
96
+ backgroundColor: 'rgba(255,255,255,0.7)',
97
+ },
98
+ ]}>
99
+ <react_native_1.Text style={[styles.code, hovered && { color: 'black' }]}>
100
+ <react_native_1.Text style={{ color: '#BCC3CD' }}>$</react_native_1.Text> touch {getRootDir()}
101
+ /index.js
102
+ </react_native_1.Text>
103
+ </react_native_1.View>)}
104
+ </Pressable_1.Pressable>);
98
105
  }
99
106
  const styles = react_native_1.StyleSheet.create({
100
107
  background: {
@@ -1 +1 @@
1
- {"version":3,"file":"Tutorial.js","sourceRoot":"","sources":["../../src/onboard/Tutorial.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { Platform, StatusBar, StyleSheet, Text, View } from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\n\nimport { createEntryFileAsync } from './createEntryFile';\nimport { Link } from '../exports';\nimport { Pressable } from '../views/Pressable';\n\n// TODO: Use openLinkFromBrowser thing\nfunction Header() {\n return (\n <Pressable>\n {({ hovered }) => (\n <Text\n role=\"heading\"\n aria-level={1}\n style={[styles.title, Platform.OS !== 'web' && { textAlign: 'left' }]}>\n Welcome to{' '}\n <Link\n href=\"https://github.com/expo/expo-router/\"\n style={[\n hovered && {\n textDecorationColor: 'white',\n textDecorationLine: 'underline',\n },\n ]}>\n Expo\n </Link>\n </Text>\n )}\n </Pressable>\n );\n}\n\nconst canAutoTouchFile = process.env.EXPO_ROUTER_APP_ROOT != null;\n\nexport function Tutorial() {\n React.useEffect(() => {\n if (Platform.OS === 'web') {\n // Reset the route on web so the initial route isn't a 404 after\n // the user has created the entry file.\n // This is useful for cases where you are testing the tutorial.\n // To test: touch the new file, then navigate to a missing route `/foobar`, then delete the app folder.\n // you should see the tutorial again and be able to create the entry file once more.\n if (typeof location !== 'undefined' && location.pathname !== '/') {\n location.replace('/');\n }\n if (typeof window !== 'undefined' && typeof window.document !== 'undefined') {\n window.document.title = 'npx expo start';\n }\n }\n }, []);\n\n return (\n <View style={styles.background}>\n <StatusBar barStyle=\"light-content\" />\n\n <SafeAreaView style={styles.safeArea}>\n <View style={styles.container}>\n <Header />\n <Text role=\"heading\" aria-level={2} style={styles.subtitle}>\n Start by creating a file{'\\n'}in the{' '}\n <Text style={{ fontWeight: 'bold' }}>{getRootDir()}</Text> directory.\n </Text>\n {canAutoTouchFile && <Button />}\n </View>\n </SafeAreaView>\n </View>\n );\n}\n\nfunction getRootDir() {\n const dir = process.env.EXPO_ROUTER_ABS_APP_ROOT!;\n if (dir.match(/\\/src\\/app$/)) {\n return 'src/app';\n } else if (dir.match(/\\/app$/)) {\n return 'app';\n }\n return dir.split('/').pop() ?? dir;\n}\n\nfunction Button() {\n return (\n <Pressable\n onPress={() => {\n createEntryFileAsync();\n }}\n style={{\n ...Platform.select({\n web: {\n // subtle white shadow\n boxShadow: 'rgba(255, 255, 255, 0.15) 0px 0px 20px 5px',\n },\n native: {\n position: 'absolute',\n bottom: 24,\n left: 24,\n right: 24,\n overflow: 'hidden',\n },\n }),\n }}>\n {({ pressed, hovered }) => (\n <View\n style={[\n styles.buttonContainer,\n hovered && {\n backgroundColor: 'white',\n },\n pressed && {\n backgroundColor: 'rgba(255,255,255,0.7)',\n },\n ]}>\n <Text style={[styles.code, hovered && { color: 'black' }]}>\n <Text style={{ color: '#BCC3CD' }}>$</Text> touch {getRootDir()}\n /index.js\n </Text>\n </View>\n )}\n </Pressable>\n );\n}\n\nconst styles = StyleSheet.create({\n background: {\n ...Platform.select({\n web: {\n backgroundImage:\n 'radial-gradient(circle at 1px 1px, rgba(255,255,255,0.15) 1px, transparent 0)',\n backgroundPositionX: -3,\n backgroundPositionY: -3,\n backgroundSize: '40px 40px',\n },\n }),\n backgroundColor: 'black',\n flex: 1,\n },\n safeArea: {\n flex: 1,\n maxWidth: 960,\n marginHorizontal: 'auto',\n alignItems: 'stretch',\n },\n container: {\n flex: 1,\n padding: 24,\n alignItems: 'flex-start',\n justifyContent: 'center',\n },\n title: {\n color: 'white',\n fontSize: 64,\n paddingBottom: 24,\n fontWeight: 'bold',\n },\n buttonContainer: {\n ...Platform.select({\n web: {\n transitionDuration: '200ms',\n backgroundColor: 'transparent',\n },\n default: {\n backgroundColor: 'white',\n },\n }),\n\n borderColor: 'white',\n borderWidth: 2,\n paddingVertical: 12,\n paddingHorizontal: 24,\n },\n buttonText: {\n color: 'black',\n },\n code: {\n ...Platform.select({\n web: {\n transitionDuration: '200ms',\n color: 'white',\n fontFamily: 'Courier',\n },\n default: {\n color: 'black',\n fontFamily: Platform.select({\n ios: 'Courier New',\n android: 'monospace',\n }),\n },\n }),\n\n userSelect: 'none',\n fontSize: 18,\n fontWeight: 'bold',\n },\n subtitle: {\n color: '#BCC3CD',\n fontSize: 36,\n fontWeight: '100',\n paddingBottom: 36,\n maxWidth: 960,\n },\n});\n"]}
1
+ {"version":3,"file":"Tutorial.js","sourceRoot":"","sources":["../../src/onboard/Tutorial.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { Platform, StatusBar, StyleSheet, Text, View } from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\n\nimport { createEntryFileAsync } from './createEntryFile';\nimport { Link } from '../exports';\nimport { Pressable } from '../views/Pressable';\n\n// TODO: Use openLinkFromBrowser thing\nfunction Header() {\n return (\n <Pressable>\n {({ hovered }) => (\n <Text\n role=\"heading\"\n aria-level={1}\n style={[styles.title, Platform.OS !== 'web' && { textAlign: 'left' }]}>\n Welcome to{' '}\n <Link\n href=\"https://github.com/expo/expo-router/\"\n style={[\n hovered && {\n textDecorationColor: 'white',\n textDecorationLine: 'underline',\n },\n ]}>\n Expo\n </Link>\n </Text>\n )}\n </Pressable>\n );\n}\n\nconst canAutoTouchFile = process.env.EXPO_ROUTER_APP_ROOT != null;\n\nexport function Tutorial() {\n React.useEffect(() => {\n if (Platform.OS === 'web') {\n // Reset the route on web so the initial route isn't a 404 after\n // the user has created the entry file.\n // This is useful for cases where you are testing the tutorial.\n // To test: touch the new file, then navigate to a missing route `/foobar`, then delete the app folder.\n // you should see the tutorial again and be able to create the entry file once more.\n if (typeof location !== 'undefined' && location.pathname !== '/') {\n location.replace('/');\n }\n if (typeof window !== 'undefined' && typeof window.document !== 'undefined') {\n window.document.title = 'npx expo start';\n }\n }\n }, []);\n\n return (\n <View style={styles.background}>\n <StatusBar barStyle=\"light-content\" />\n\n <SafeAreaView style={styles.safeArea}>\n <View style={styles.container}>\n <Header />\n <Text role=\"heading\" aria-level={2} style={styles.subtitle}>\n Start by creating a file{'\\n'}in the{' '}\n <Text style={{ fontWeight: 'bold' }}>{getRootDir()}</Text> directory.\n </Text>\n {canAutoTouchFile && <Button />}\n </View>\n </SafeAreaView>\n </View>\n );\n}\n\nfunction getRootDir() {\n const dir = process.env.EXPO_ROUTER_ABS_APP_ROOT!;\n if (dir.match(/\\/src\\/app$/)) {\n return 'src/app';\n } else if (dir.match(/\\/app$/)) {\n return 'app';\n }\n return dir.split('/').pop() ?? dir;\n}\n\nfunction Button() {\n return (\n <Pressable\n onPress={() => {\n createEntryFileAsync();\n }}\n style={{\n ...Platform.select({\n web: {\n // subtle white shadow\n boxShadow: 'rgba(255, 255, 255, 0.15) 0px 0px 20px 5px',\n },\n native: {\n position: 'absolute',\n bottom: 24,\n left: 24,\n right: 24,\n overflow: 'hidden',\n },\n }),\n }}>\n {({ pressed, hovered }) => (\n <View\n style={[\n styles.buttonContainer,\n hovered && {\n backgroundColor: 'white',\n },\n pressed && {\n backgroundColor: 'rgba(255,255,255,0.7)',\n },\n ]}>\n <Text style={[styles.code, hovered && { color: 'black' }]}>\n <Text style={{ color: '#BCC3CD' }}>$</Text> touch {getRootDir()}\n /index.js\n </Text>\n </View>\n )}\n </Pressable>\n );\n}\n\nconst styles = StyleSheet.create({\n background: {\n ...Platform.select({\n web: {\n backgroundImage:\n 'radial-gradient(circle at 1px 1px, rgba(255,255,255,0.15) 1px, transparent 0)',\n backgroundPositionX: -3,\n backgroundPositionY: -3,\n backgroundSize: '40px 40px',\n },\n }),\n backgroundColor: 'black',\n flex: 1,\n },\n safeArea: {\n flex: 1,\n maxWidth: 960,\n marginHorizontal: 'auto',\n alignItems: 'stretch',\n },\n container: {\n flex: 1,\n padding: 24,\n alignItems: 'flex-start',\n justifyContent: 'center',\n },\n title: {\n color: 'white',\n fontSize: 64,\n paddingBottom: 24,\n fontWeight: 'bold',\n },\n buttonContainer: {\n ...Platform.select({\n web: {\n transitionDuration: '200ms',\n backgroundColor: 'transparent',\n },\n default: {\n backgroundColor: 'white',\n },\n }),\n\n borderColor: 'white',\n borderWidth: 2,\n paddingVertical: 12,\n paddingHorizontal: 24,\n },\n buttonText: {\n color: 'black',\n },\n code: {\n ...Platform.select({\n web: {\n transitionDuration: '200ms',\n color: 'white',\n fontFamily: 'Courier',\n },\n default: {\n color: 'black',\n fontFamily: Platform.select({\n ios: 'Courier New',\n android: 'monospace',\n }),\n },\n }),\n\n userSelect: 'none',\n fontSize: 18,\n fontWeight: 'bold',\n },\n subtitle: {\n color: '#BCC3CD',\n fontSize: 36,\n fontWeight: '100',\n paddingBottom: 36,\n maxWidth: 960,\n },\n});\n"]}
@@ -14,8 +14,9 @@ const head_1 = require("./head");
14
14
  const _ctx_1 = require("../_ctx");
15
15
  // Must be exported or Fast Refresh won't update the context
16
16
  function App() {
17
- return (react_1.default.createElement(head_1.Head.Provider, null,
18
- react_1.default.createElement(ExpoRoot_1.ExpoRoot, { context: _ctx_1.ctx })));
17
+ return (<head_1.Head.Provider>
18
+ <ExpoRoot_1.ExpoRoot context={_ctx_1.ctx}/>
19
+ </head_1.Head.Provider>);
19
20
  }
20
21
  exports.App = App;
21
22
  //# sourceMappingURL=qualified-entry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"qualified-entry.js","sourceRoot":"","sources":["../src/qualified-entry.tsx"],"names":[],"mappings":";;;;;;AAAA,wFAAwF;AACxF,yFAAyF;AACzF,6FAA6F;AAC7F,2FAA2F;AAC3F,kDAA0B;AAE1B,yCAAsC;AACtC,iCAA8B;AAC9B,kCAA8B;AAE9B,4DAA4D;AAC5D,SAAgB,GAAG;IACjB,OAAO,CACL,8BAAC,WAAI,CAAC,QAAQ;QACZ,8BAAC,mBAAQ,IAAC,OAAO,EAAE,UAAG,GAAI,CACZ,CACjB,CAAC;AACJ,CAAC;AAND,kBAMC","sourcesContent":["// The entry component (one that uses context modules) cannot be in the same file as the\n// entry side-effects, otherwise they'll be updated when files are added/removed from the\n// app directory. This will cause a lot of unfortunate errors regarding HMR and Fast Refresh.\n// This is because Fast Refresh is sending the entire file containing an updated component.\nimport React from 'react';\n\nimport { ExpoRoot } from './ExpoRoot';\nimport { Head } from './head';\nimport { ctx } from '../_ctx';\n\n// Must be exported or Fast Refresh won't update the context\nexport function App() {\n return (\n <Head.Provider>\n <ExpoRoot context={ctx} />\n </Head.Provider>\n );\n}\n"]}
1
+ {"version":3,"file":"qualified-entry.js","sourceRoot":"","sources":["../src/qualified-entry.tsx"],"names":[],"mappings":";;;;;;AAAA,wFAAwF;AACxF,yFAAyF;AACzF,6FAA6F;AAC7F,2FAA2F;AAC3F,kDAA0B;AAE1B,yCAAsC;AACtC,iCAA8B;AAC9B,kCAA8B;AAE9B,4DAA4D;AAC5D,SAAgB,GAAG;IACjB,OAAO,CACL,CAAC,WAAI,CAAC,QAAQ,CACZ;MAAA,CAAC,mBAAQ,CAAC,OAAO,CAAC,CAAC,UAAG,CAAC,EACzB;IAAA,EAAE,WAAI,CAAC,QAAQ,CAAC,CACjB,CAAC;AACJ,CAAC;AAND,kBAMC","sourcesContent":["// The entry component (one that uses context modules) cannot be in the same file as the\n// entry side-effects, otherwise they'll be updated when files are added/removed from the\n// app directory. This will cause a lot of unfortunate errors regarding HMR and Fast Refresh.\n// This is because Fast Refresh is sending the entire file containing an updated component.\nimport React from 'react';\n\nimport { ExpoRoot } from './ExpoRoot';\nimport { Head } from './head';\nimport { ctx } from '../_ctx';\n\n// Must be exported or Fast Refresh won't update the context\nexport function App() {\n return (\n <Head.Provider>\n <ExpoRoot context={ctx} />\n </Head.Provider>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"renderRootComponent.d.ts","sourceRoot":"","sources":["../src/renderRootComponent.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AA+C1B;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,QAsCtE"}
1
+ {"version":3,"file":"renderRootComponent.d.ts","sourceRoot":"","sources":["../src/renderRootComponent.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AA6C1B;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,QAuCtE"}
@@ -1,13 +1,36 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
5
28
  Object.defineProperty(exports, "__esModule", { value: true });
6
29
  exports.renderRootComponent = void 0;
7
30
  const expo_1 = require("expo");
31
+ const SplashScreen = __importStar(require("expo-splash-screen"));
8
32
  const react_1 = __importDefault(require("react"));
9
33
  const react_native_1 = require("react-native");
10
- const Splash_1 = require("./views/Splash");
11
34
  function isBaseObject(obj) {
12
35
  if (Object.prototype.toString.call(obj) !== '[object Object]') {
13
36
  return false;
@@ -50,7 +73,8 @@ function renderRootComponent(Component) {
50
73
  try {
51
74
  // This must be delayed so the user has a chance to call it first.
52
75
  setTimeout(() => {
53
- (0, Splash_1._internal_preventAutoHideAsync)();
76
+ // @ts-expect-error: This function is native-only and for internal-use only.
77
+ SplashScreen._internal_preventAutoHideAsync?.();
54
78
  });
55
79
  if (process.env.NODE_ENV !== 'production') {
56
80
  const { withErrorOverlay } = require('@expo/metro-runtime/error-overlay');
@@ -62,13 +86,13 @@ function renderRootComponent(Component) {
62
86
  }
63
87
  catch (e) {
64
88
  // Hide the splash screen if there was an error so the user can see it.
65
- Splash_1.SplashScreen.hideAsync();
89
+ SplashScreen.hideAsync();
66
90
  const error = convertError(e);
67
91
  // Prevent the app from throwing confusing:
68
92
  // ERROR Invariant Violation: "main" has not been registered. This can happen if:
69
93
  // * Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
70
94
  // * A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called.
71
- (0, expo_1.registerRootComponent)(() => react_1.default.createElement(react_native_1.View, null));
95
+ (0, expo_1.registerRootComponent)(() => <react_native_1.View />);
72
96
  // Console is pretty useless on native, on web you get interactive stack traces.
73
97
  if (react_native_1.Platform.OS === 'web') {
74
98
  console.error(error);
@@ -1 +1 @@
1
- {"version":3,"file":"renderRootComponent.js","sourceRoot":"","sources":["../src/renderRootComponent.tsx"],"names":[],"mappings":";;;;;;AAAA,+BAA6C;AAC7C,kDAA0B;AAC1B,+CAA8C;AAE9C,2CAA8E;AAE9E,SAAS,YAAY,CAAC,GAAQ;IAC5B,IAAI,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,iBAAiB,EAAE;QAC7D,OAAO,KAAK,CAAC;KACd;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,KAAK,KAAK,IAAI,EAAE;QAClB,OAAO,IAAI,CAAC;KACb;IACD,OAAO,KAAK,KAAK,MAAM,CAAC,SAAS,CAAC;AACpC,CAAC;AAED,SAAS,aAAa,CAAC,KAAU;IAC/B,OAAO,CACL,KAAK;QACL,OAAO,KAAK,KAAK,QAAQ;QACzB,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC9B,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAClC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CAAC,KAAU;IAC9B,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE;QACxB,OAAO,KAAK,CAAC;KACd;IAED,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE;QAC1C,IAAI,KAAK,IAAI,IAAI,EAAE;YACjB,OAAO,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;SACxD;KACF;IAED,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE;QACvB,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;KACzC;IAED,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,SAAgB,mBAAmB,CAAC,SAAmC;IACrE,IAAI;QACF,kEAAkE;QAClE,UAAU,CAAC,GAAG,EAAE;YACd,IAAA,uCAA8B,GAAE,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE;YACzC,MAAM,EAAE,gBAAgB,EAAE,GACxB,OAAO,CAAC,mCAAmC,CAAuD,CAAC;YACrG,IAAA,4BAAqB,EAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC;SACpD;aAAM;YACL,IAAA,4BAAqB,EAAC,SAAS,CAAC,CAAC;SAClC;KACF;IAAC,OAAO,CAAC,EAAE;QACV,uEAAuE;QACvE,qBAAY,CAAC,SAAS,EAAE,CAAC;QAEzB,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9B,2CAA2C;QAC3C,mFAAmF;QACnF,yIAAyI;QACzI,+FAA+F;QAC/F,IAAA,4BAAqB,EAAC,GAAG,EAAE,CAAC,8BAAC,mBAAI,OAAG,CAAC,CAAC;QAEtC,gFAAgF;QAChF,IAAI,uBAAQ,CAAC,EAAE,KAAK,KAAK,EAAE;YACzB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACrB,OAAO,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;SACnF;QAED,+CAA+C;QAC/C,UAAU,CAAC,GAAG,EAAE;YACd,MAAM,KAAK,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,+CAA+C;KAChD;AACH,CAAC;AAtCD,kDAsCC","sourcesContent":["import { registerRootComponent } from 'expo';\nimport React from 'react';\nimport { Platform, View } from 'react-native';\n\nimport { SplashScreen, _internal_preventAutoHideAsync } from './views/Splash';\n\nfunction isBaseObject(obj: any) {\n if (Object.prototype.toString.call(obj) !== '[object Object]') {\n return false;\n }\n const proto = Object.getPrototypeOf(obj);\n if (proto === null) {\n return true;\n }\n return proto === Object.prototype;\n}\n\nfunction isErrorShaped(error: any): error is Error {\n return (\n error &&\n typeof error === 'object' &&\n typeof error.name === 'string' &&\n typeof error.message === 'string'\n );\n}\n\n/**\n * After we throw this error, any number of tools could handle it.\n * This check ensures the error is always in a reason state before surfacing it to the runtime.\n */\nfunction convertError(error: any) {\n if (isErrorShaped(error)) {\n return error;\n }\n\n if (process.env.NODE_ENV === 'development') {\n if (error == null) {\n return new Error('A null/undefined error was thrown.');\n }\n }\n\n if (isBaseObject(error)) {\n return new Error(JSON.stringify(error));\n }\n\n return new Error(String(error));\n}\n\n/**\n * Register and mount the root component using the predefined rendering\n * method. This function ensures the Splash Screen and errors are handled correctly.\n */\nexport function renderRootComponent(Component: React.ComponentType<any>) {\n try {\n // This must be delayed so the user has a chance to call it first.\n setTimeout(() => {\n _internal_preventAutoHideAsync();\n });\n\n if (process.env.NODE_ENV !== 'production') {\n const { withErrorOverlay } =\n require('@expo/metro-runtime/error-overlay') as typeof import('@expo/metro-runtime/error-overlay');\n registerRootComponent(withErrorOverlay(Component));\n } else {\n registerRootComponent(Component);\n }\n } catch (e) {\n // Hide the splash screen if there was an error so the user can see it.\n SplashScreen.hideAsync();\n\n const error = convertError(e);\n // Prevent the app from throwing confusing:\n // ERROR Invariant Violation: \"main\" has not been registered. This can happen if:\n // * Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.\n // * A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called.\n registerRootComponent(() => <View />);\n\n // Console is pretty useless on native, on web you get interactive stack traces.\n if (Platform.OS === 'web') {\n console.error(error);\n console.error(`A runtime error has occurred while rendering the root component.`);\n }\n\n // Give React a tick to render before throwing.\n setTimeout(() => {\n throw error;\n });\n\n // TODO: Render a production-only error screen.\n }\n}\n"]}
1
+ {"version":3,"file":"renderRootComponent.js","sourceRoot":"","sources":["../src/renderRootComponent.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+BAA6C;AAC7C,iEAAmD;AACnD,kDAA0B;AAC1B,+CAA8C;AAE9C,SAAS,YAAY,CAAC,GAAQ;IAC5B,IAAI,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,iBAAiB,EAAE;QAC7D,OAAO,KAAK,CAAC;KACd;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,KAAK,KAAK,IAAI,EAAE;QAClB,OAAO,IAAI,CAAC;KACb;IACD,OAAO,KAAK,KAAK,MAAM,CAAC,SAAS,CAAC;AACpC,CAAC;AAED,SAAS,aAAa,CAAC,KAAU;IAC/B,OAAO,CACL,KAAK;QACL,OAAO,KAAK,KAAK,QAAQ;QACzB,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC9B,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAClC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CAAC,KAAU;IAC9B,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE;QACxB,OAAO,KAAK,CAAC;KACd;IAED,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE;QAC1C,IAAI,KAAK,IAAI,IAAI,EAAE;YACjB,OAAO,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;SACxD;KACF;IAED,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE;QACvB,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;KACzC;IAED,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,SAAgB,mBAAmB,CAAC,SAAmC;IACrE,IAAI;QACF,kEAAkE;QAClE,UAAU,CAAC,GAAG,EAAE;YACd,4EAA4E;YAC5E,YAAY,CAAC,8BAA8B,EAAE,EAAE,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE;YACzC,MAAM,EAAE,gBAAgB,EAAE,GACxB,OAAO,CAAC,mCAAmC,CAAuD,CAAC;YACrG,IAAA,4BAAqB,EAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC;SACpD;aAAM;YACL,IAAA,4BAAqB,EAAC,SAAS,CAAC,CAAC;SAClC;KACF;IAAC,OAAO,CAAC,EAAE;QACV,uEAAuE;QACvE,YAAY,CAAC,SAAS,EAAE,CAAC;QAEzB,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9B,2CAA2C;QAC3C,mFAAmF;QACnF,yIAAyI;QACzI,+FAA+F;QAC/F,IAAA,4BAAqB,EAAC,GAAG,EAAE,CAAC,CAAC,mBAAI,CAAC,AAAD,EAAG,CAAC,CAAC;QAEtC,gFAAgF;QAChF,IAAI,uBAAQ,CAAC,EAAE,KAAK,KAAK,EAAE;YACzB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACrB,OAAO,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;SACnF;QAED,+CAA+C;QAC/C,UAAU,CAAC,GAAG,EAAE;YACd,MAAM,KAAK,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,+CAA+C;KAChD;AACH,CAAC;AAvCD,kDAuCC","sourcesContent":["import { registerRootComponent } from 'expo';\nimport * as SplashScreen from 'expo-splash-screen';\nimport React from 'react';\nimport { Platform, View } from 'react-native';\n\nfunction isBaseObject(obj: any) {\n if (Object.prototype.toString.call(obj) !== '[object Object]') {\n return false;\n }\n const proto = Object.getPrototypeOf(obj);\n if (proto === null) {\n return true;\n }\n return proto === Object.prototype;\n}\n\nfunction isErrorShaped(error: any): error is Error {\n return (\n error &&\n typeof error === 'object' &&\n typeof error.name === 'string' &&\n typeof error.message === 'string'\n );\n}\n\n/**\n * After we throw this error, any number of tools could handle it.\n * This check ensures the error is always in a reason state before surfacing it to the runtime.\n */\nfunction convertError(error: any) {\n if (isErrorShaped(error)) {\n return error;\n }\n\n if (process.env.NODE_ENV === 'development') {\n if (error == null) {\n return new Error('A null/undefined error was thrown.');\n }\n }\n\n if (isBaseObject(error)) {\n return new Error(JSON.stringify(error));\n }\n\n return new Error(String(error));\n}\n\n/**\n * Register and mount the root component using the predefined rendering\n * method. This function ensures the Splash Screen and errors are handled correctly.\n */\nexport function renderRootComponent(Component: React.ComponentType<any>) {\n try {\n // This must be delayed so the user has a chance to call it first.\n setTimeout(() => {\n // @ts-expect-error: This function is native-only and for internal-use only.\n SplashScreen._internal_preventAutoHideAsync?.();\n });\n\n if (process.env.NODE_ENV !== 'production') {\n const { withErrorOverlay } =\n require('@expo/metro-runtime/error-overlay') as typeof import('@expo/metro-runtime/error-overlay');\n registerRootComponent(withErrorOverlay(Component));\n } else {\n registerRootComponent(Component);\n }\n } catch (e) {\n // Hide the splash screen if there was an error so the user can see it.\n SplashScreen.hideAsync();\n\n const error = convertError(e);\n // Prevent the app from throwing confusing:\n // ERROR Invariant Violation: \"main\" has not been registered. This can happen if:\n // * Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.\n // * A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called.\n registerRootComponent(() => <View />);\n\n // Console is pretty useless on native, on web you get interactive stack traces.\n if (Platform.OS === 'web') {\n console.error(error);\n console.error(`A runtime error has occurred while rendering the root component.`);\n }\n\n // Give React a tick to render before throwing.\n setTimeout(() => {\n throw error;\n });\n\n // TODO: Render a production-only error screen.\n }\n}\n"]}
@@ -1,4 +1,5 @@
1
1
  export type RouteInfo<TRegex = string> = {
2
+ file: string;
2
3
  page: string;
3
4
  namedRegex: TRegex;
4
5
  routeKeys: {
@@ -1 +1 @@
1
- {"version":3,"file":"routes-manifest.d.ts","sourceRoot":"","sources":["../src/routes-manifest.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,SAAS,CAAC,MAAM,GAAG,MAAM,IAAI;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE;QAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,oBAAoB,CAAC,MAAM,GAAG,MAAM,IAAI;IAClD,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;IAC/B,UAAU,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;IAChC,cAAc,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;CACrC,CAAC;AAYF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,oBAAoB,GAAG,IAAI,CAWjF"}
1
+ {"version":3,"file":"routes-manifest.d.ts","sourceRoot":"","sources":["../src/routes-manifest.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,SAAS,CAAC,MAAM,GAAG,MAAM,IAAI;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE;QAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,oBAAoB,CAAC,MAAM,GAAG,MAAM,IAAI;IAClD,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;IAC/B,UAAU,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;IAChC,cAAc,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;CACrC,CAAC;AAYF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,oBAAoB,GAAG,IAAI,CAWjF"}