expo-router 0.0.20 → 0.0.22

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 (54) hide show
  1. package/build/ContextNavigationContainer.d.ts +7 -12
  2. package/build/ContextNavigationContainer.d.ts.map +1 -1
  3. package/build/ContextNavigationContainer.js +11 -10
  4. package/build/ContextNavigationContainer.js.map +1 -1
  5. package/build/getLinkingConfig.js +1 -1
  6. package/build/getLinkingConfig.js.map +1 -1
  7. package/build/index.d.ts +3 -3
  8. package/build/index.d.ts.map +1 -1
  9. package/build/index.js +3 -3
  10. package/build/index.js.map +1 -1
  11. package/build/link/Link.d.ts +26 -0
  12. package/build/link/Link.d.ts.map +1 -0
  13. package/build/link/Link.js +40 -0
  14. package/build/link/Link.js.map +1 -0
  15. package/build/link/href.d.ts +9 -0
  16. package/build/link/href.d.ts.map +1 -0
  17. package/build/link/href.js +34 -0
  18. package/build/link/href.js.map +1 -0
  19. package/build/{linking.d.ts → link/linking.d.ts} +2 -2
  20. package/build/link/linking.d.ts.map +1 -0
  21. package/build/{linking.js → link/linking.js} +2 -2
  22. package/build/link/linking.js.map +1 -0
  23. package/build/{useLink.d.ts → link/useLink.d.ts} +1 -1
  24. package/build/link/useLink.d.ts.map +1 -0
  25. package/build/{useLink.js → link/useLink.js} +2 -2
  26. package/build/link/useLink.js.map +1 -0
  27. package/build/{fork → link}/useLinkToPath.d.ts +0 -0
  28. package/build/link/useLinkToPath.d.ts.map +1 -0
  29. package/build/{fork → link}/useLinkToPath.js +0 -0
  30. package/build/{fork → link}/useLinkToPath.js.map +1 -1
  31. package/build/link/useLinkToPathProps.d.ts +11 -0
  32. package/build/link/useLinkToPathProps.d.ts.map +1 -0
  33. package/build/link/useLinkToPathProps.js +31 -0
  34. package/build/link/useLinkToPathProps.js.map +1 -0
  35. package/build/views/Directory.js +1 -1
  36. package/build/views/Directory.js.map +1 -1
  37. package/build/views/ErrorBoundary.js +1 -1
  38. package/build/views/ErrorBoundary.js.map +1 -1
  39. package/build/views/Layout.d.ts +6 -0
  40. package/build/views/Layout.d.ts.map +1 -1
  41. package/build/views/Layout.js +52 -3
  42. package/build/views/Layout.js.map +1 -1
  43. package/build/views/Unmatched.js +1 -1
  44. package/build/views/Unmatched.js.map +1 -1
  45. package/package.json +1 -1
  46. package/build/fork/useLinkToPath.d.ts.map +0 -1
  47. package/build/linking.d.ts.map +0 -1
  48. package/build/linking.js.map +0 -1
  49. package/build/useLink.d.ts.map +0 -1
  50. package/build/useLink.js.map +0 -1
  51. package/build/views/Link.d.ts +0 -36
  52. package/build/views/Link.d.ts.map +0 -1
  53. package/build/views/Link.js +0 -87
  54. package/build/views/Link.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { NavigationContainer, NavigationContainerRef } from "@react-navigation/native";
1
+ import { NavigationContainer } from "@react-navigation/native";
2
2
  import React from "react";
3
3
  declare type NavigationContainerProps = React.ComponentProps<typeof NavigationContainer>;
4
4
  export declare function useNavigationContainerContext(): [Partial<import("@react-navigation/native").NavigationContainerProps & {
@@ -8,7 +8,7 @@ export declare function useNavigationContainerContext(): [Partial<import("@react
8
8
  documentTitle?: import("@react-navigation/native").DocumentTitleOptions | undefined;
9
9
  onReady?: (() => void) | undefined;
10
10
  } & {
11
- ref?: React.Ref<NavigationContainerRef<{}>> | undefined;
11
+ ref?: React.Ref<import("@react-navigation/native").NavigationContainerRef<{}>> | undefined;
12
12
  }>, (props: Partial<import("@react-navigation/native").NavigationContainerProps & {
13
13
  theme?: import("@react-navigation/native").Theme | undefined;
14
14
  linking?: import("@react-navigation/native").LinkingOptions<{}> | undefined;
@@ -16,18 +16,13 @@ export declare function useNavigationContainerContext(): [Partial<import("@react
16
16
  documentTitle?: import("@react-navigation/native").DocumentTitleOptions | undefined;
17
17
  onReady?: (() => void) | undefined;
18
18
  } & {
19
- ref?: React.Ref<NavigationContainerRef<{}>> | undefined;
19
+ ref?: React.Ref<import("@react-navigation/native").NavigationContainerRef<{}>> | undefined;
20
20
  }>) => void];
21
21
  /** react-navigation `NavigationContainer` with automatic `linking` prop generated from the routes context. */
22
- export declare const ContextNavigationContainer: React.ForwardRefExoticComponent<Pick<import("@react-navigation/native").NavigationContainerProps & {
23
- theme?: import("@react-navigation/native").Theme | undefined;
24
- linking?: import("@react-navigation/native").LinkingOptions<{}> | undefined;
25
- fallback?: React.ReactNode;
26
- documentTitle?: import("@react-navigation/native").DocumentTitleOptions | undefined;
27
- onReady?: (() => void) | undefined;
28
- } & {
29
- ref?: React.Ref<NavigationContainerRef<{}>> | undefined;
30
- }, keyof import("@react-navigation/native").NavigationContainerProps | "theme" | "linking" | "fallback" | "documentTitle" | "onReady"> & React.RefAttributes<NavigationContainerRef<{}>>>;
22
+ export declare function ContextNavigationContainer(props: NavigationContainerProps): JSX.Element;
31
23
  export declare function RootContainer({ documentTitle, fallback, onReady, initialState, onStateChange, onUnhandledAction, theme, }: Omit<NavigationContainerProps, "independent" | "ref" | "children" | "linking">): null;
24
+ export declare namespace RootContainer {
25
+ var getRef: () => import("@react-navigation/native").NavigationContainerRefWithCurrent<ReactNavigation.RootParamList>;
26
+ }
32
27
  export {};
33
28
  //# sourceMappingURL=ContextNavigationContainer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ContextNavigationContainer.d.ts","sourceRoot":"","sources":["../src/ContextNavigationContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,mBAAmB,EACnB,sBAAsB,EAEvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAsB,MAAM,OAAO,CAAC;AAM3C,aAAK,wBAAwB,GAAG,KAAK,CAAC,cAAc,CAClD,OAAO,mBAAmB,CAC3B,CAAC;AASF,wBAAgB,6BAA6B;;;;;;;;;;;;;;;;aAQ5C;AAED,8GAA8G;AAC9G,eAAO,MAAM,0BAA0B;;;;;;;;yLAwBtC,CAAC;AA6DF,wBAAgB,aAAa,CAAC,EAC5B,aAAa,EACb,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,KAAK,GACN,EAAE,IAAI,CACL,wBAAwB,EACxB,aAAa,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,CAC/C,QAwBA"}
1
+ {"version":3,"file":"ContextNavigationContainer.d.ts","sourceRoot":"","sources":["../src/ContextNavigationContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,mBAAmB,EACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAsB,MAAM,OAAO,CAAC;AAQ3C,aAAK,wBAAwB,GAAG,KAAK,CAAC,cAAc,CAClD,OAAO,mBAAmB,CAC3B,CAAC;AASF,wBAAgB,6BAA6B;;;;;;;;;;;;;;;;aAQ5C;AAED,8GAA8G;AAC9G,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,wBAAwB,eAsBzE;AAoDD,wBAAgB,aAAa,CAAC,EAC5B,aAAa,EACb,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,KAAK,GACN,EAAE,IAAI,CACL,wBAAwB,EACxB,aAAa,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,CAC/C,QAwBA;yBAnCe,aAAa"}
@@ -1,8 +1,9 @@
1
- import { findFocusedRoute, NavigationContainer, } from "@react-navigation/native";
1
+ import { createNavigationContainerRef, findFocusedRoute, NavigationContainer, } from "@react-navigation/native";
2
2
  import React, { useCallback } from "react";
3
3
  import { useLinkingConfig } from "./getLinkingConfig";
4
4
  import SplashModule from "./splash";
5
5
  import { VirtualRouteContext } from "./useCurrentRoute";
6
+ const navigationRef = createNavigationContainerRef();
6
7
  const NavigationContainerContext = React.createContext([{}, function () { }]);
7
8
  export function useNavigationContainerContext() {
8
9
  const context = React.useContext(NavigationContainerContext);
@@ -12,7 +13,7 @@ export function useNavigationContainerContext() {
12
13
  return context;
13
14
  }
14
15
  /** react-navigation `NavigationContainer` with automatic `linking` prop generated from the routes context. */
15
- export const ContextNavigationContainer = React.forwardRef((props, ref) => {
16
+ export function ContextNavigationContainer(props) {
16
17
  const [state, setState] = React.useState({});
17
18
  const linking = useLinkingConfig();
18
19
  console.log("linking", linking);
@@ -24,8 +25,8 @@ export const ContextNavigationContainer = React.forwardRef((props, ref) => {
24
25
  },
25
26
  setState,
26
27
  ] },
27
- React.createElement(InternalContextNavigationContainer, { ref: ref })));
28
- });
28
+ React.createElement(InternalContextNavigationContainer, null)));
29
+ }
29
30
  function trimQuery(pathname) {
30
31
  const queryIndex = pathname.indexOf("?");
31
32
  if (queryIndex !== -1) {
@@ -33,7 +34,7 @@ function trimQuery(pathname) {
33
34
  }
34
35
  return pathname;
35
36
  }
36
- const InternalContextNavigationContainer = React.forwardRef((props, ref) => {
37
+ function InternalContextNavigationContainer(props) {
37
38
  const [contextProps] = useNavigationContainerContext();
38
39
  const [state, setState] = React.useState({ pathname: null, query: {} });
39
40
  const onStateChange = useCallback((state) => {
@@ -45,10 +46,6 @@ const InternalContextNavigationContainer = React.forwardRef((props, ref) => {
45
46
  });
46
47
  }
47
48
  }, [setState]);
48
- const navigationRef = React.useRef(null);
49
- React.useImperativeHandle(ref, () => navigationRef.current, [
50
- navigationRef,
51
- ]);
52
49
  return (React.createElement(VirtualRouteContext.Provider, { value: state },
53
50
  React.createElement(NavigationContainer, { ...props, ...contextProps, ref: navigationRef, onReady: () => {
54
51
  contextProps.onReady?.();
@@ -59,7 +56,7 @@ const InternalContextNavigationContainer = React.forwardRef((props, ref) => {
59
56
  contextProps.onStateChange?.(state);
60
57
  onStateChange(state);
61
58
  } })));
62
- });
59
+ }
63
60
  export function RootContainer({ documentTitle, fallback, onReady, initialState, onStateChange, onUnhandledAction, theme, }) {
64
61
  const [, setProps] = useNavigationContainerContext();
65
62
  React.useEffect(() => {
@@ -83,4 +80,8 @@ export function RootContainer({ documentTitle, fallback, onReady, initialState,
83
80
  ]);
84
81
  return null;
85
82
  }
83
+ /** Get the root navigation container ref. */
84
+ RootContainer.getRef = () => {
85
+ return navigationRef;
86
+ };
86
87
  //# sourceMappingURL=ContextNavigationContainer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ContextNavigationContainer.js","sourceRoot":"","sources":["../src/ContextNavigationContainer.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n findFocusedRoute,\n NavigationContainer,\n NavigationContainerRef,\n ParamListBase,\n} from \"@react-navigation/native\";\nimport React, { useCallback } from \"react\";\n\nimport { useLinkingConfig } from \"./getLinkingConfig\";\nimport SplashModule from \"./splash\";\nimport { VirtualRouteContext } from \"./useCurrentRoute\";\n\ntype NavigationContainerProps = React.ComponentProps<\n typeof NavigationContainer\n>;\n\nconst NavigationContainerContext = React.createContext<\n [\n Partial<NavigationContainerProps>,\n (props: Partial<NavigationContainerProps>) => void\n ]\n>([{}, function () {}]);\n\nexport function useNavigationContainerContext() {\n const context = React.useContext(NavigationContainerContext);\n if (!context) {\n throw new Error(\n \"useNavigationContainerContext must be used within a NavigationContainerContext\"\n );\n }\n return context;\n}\n\n/** react-navigation `NavigationContainer` with automatic `linking` prop generated from the routes context. */\nexport const ContextNavigationContainer = React.forwardRef(\n (props: NavigationContainerProps, ref: NavigationContainerProps[\"ref\"]) => {\n const [state, setState] = React.useState<Partial<NavigationContainerProps>>(\n {}\n );\n\n const linking = useLinkingConfig();\n console.log(\"linking\", linking);\n\n return (\n <NavigationContainerContext.Provider\n value={[\n {\n ...props,\n linking,\n ...state,\n },\n setState,\n ]}\n >\n <InternalContextNavigationContainer ref={ref} />\n </NavigationContainerContext.Provider>\n );\n }\n);\n\nfunction trimQuery(pathname: string): string {\n const queryIndex = pathname.indexOf(\"?\");\n if (queryIndex !== -1) {\n return pathname.substring(0, queryIndex);\n }\n return pathname;\n}\n\nconst InternalContextNavigationContainer = React.forwardRef(\n (props: object, ref: NavigationContainerProps[\"ref\"]) => {\n const [contextProps] = useNavigationContainerContext();\n const [state, setState] = React.useState<{\n pathname: string | null;\n query: Record<string, any>;\n }>({ pathname: null, query: {} });\n\n const onStateChange = useCallback(\n (state) => {\n if (state) {\n const currentRoute = findFocusedRoute(state);\n setState({\n pathname: trimQuery(currentRoute?.path ?? \"/\"),\n query: currentRoute?.params ?? {},\n });\n }\n },\n [setState]\n );\n\n const navigationRef =\n React.useRef<NavigationContainerRef<ParamListBase>>(null);\n\n React.useImperativeHandle(ref, () => navigationRef.current!, [\n navigationRef,\n ]);\n\n return (\n <VirtualRouteContext.Provider value={state}>\n {/* @ts-expect-error: children are required */}\n <NavigationContainer\n {...props}\n {...contextProps}\n ref={navigationRef}\n onReady={() => {\n contextProps.onReady?.();\n SplashModule?.hideAsync();\n const initialState = navigationRef.current?.getRootState();\n onStateChange(initialState);\n }}\n onStateChange={(state) => {\n contextProps.onStateChange?.(state);\n onStateChange(state);\n }}\n />\n </VirtualRouteContext.Provider>\n );\n }\n);\n\nexport function RootContainer({\n documentTitle,\n fallback,\n onReady,\n initialState,\n onStateChange,\n onUnhandledAction,\n theme,\n}: Omit<\n NavigationContainerProps,\n \"independent\" | \"ref\" | \"children\" | \"linking\"\n>) {\n const [, setProps] = useNavigationContainerContext();\n\n React.useEffect(() => {\n setProps({\n documentTitle,\n fallback,\n onReady,\n initialState,\n onStateChange,\n onUnhandledAction,\n theme,\n });\n }, [\n documentTitle,\n fallback,\n onReady,\n initialState,\n onStateChange,\n onUnhandledAction,\n theme,\n ]);\n\n return null;\n}\n"]}
1
+ {"version":3,"file":"ContextNavigationContainer.js","sourceRoot":"","sources":["../src/ContextNavigationContainer.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n createNavigationContainerRef,\n findFocusedRoute,\n NavigationContainer,\n} from \"@react-navigation/native\";\nimport React, { useCallback } from \"react\";\n\nimport { useLinkingConfig } from \"./getLinkingConfig\";\nimport SplashModule from \"./splash\";\nimport { VirtualRouteContext } from \"./useCurrentRoute\";\n\nconst navigationRef = createNavigationContainerRef();\n\ntype NavigationContainerProps = React.ComponentProps<\n typeof NavigationContainer\n>;\n\nconst NavigationContainerContext = React.createContext<\n [\n Partial<NavigationContainerProps>,\n (props: Partial<NavigationContainerProps>) => void\n ]\n>([{}, function () {}]);\n\nexport function useNavigationContainerContext() {\n const context = React.useContext(NavigationContainerContext);\n if (!context) {\n throw new Error(\n \"useNavigationContainerContext must be used within a NavigationContainerContext\"\n );\n }\n return context;\n}\n\n/** react-navigation `NavigationContainer` with automatic `linking` prop generated from the routes context. */\nexport function ContextNavigationContainer(props: NavigationContainerProps) {\n const [state, setState] = React.useState<Partial<NavigationContainerProps>>(\n {}\n );\n\n const linking = useLinkingConfig();\n console.log(\"linking\", linking);\n\n return (\n <NavigationContainerContext.Provider\n value={[\n {\n ...props,\n linking,\n ...state,\n },\n setState,\n ]}\n >\n <InternalContextNavigationContainer />\n </NavigationContainerContext.Provider>\n );\n}\n\nfunction trimQuery(pathname: string): string {\n const queryIndex = pathname.indexOf(\"?\");\n if (queryIndex !== -1) {\n return pathname.substring(0, queryIndex);\n }\n return pathname;\n}\n\nfunction InternalContextNavigationContainer(props: object) {\n const [contextProps] = useNavigationContainerContext();\n const [state, setState] = React.useState<{\n pathname: string | null;\n query: Record<string, any>;\n }>({ pathname: null, query: {} });\n\n const onStateChange = useCallback(\n (state) => {\n if (state) {\n const currentRoute = findFocusedRoute(state);\n setState({\n pathname: trimQuery(currentRoute?.path ?? \"/\"),\n query: currentRoute?.params ?? {},\n });\n }\n },\n [setState]\n );\n\n return (\n <VirtualRouteContext.Provider value={state}>\n {/* @ts-expect-error: children are required */}\n <NavigationContainer\n {...props}\n {...contextProps}\n ref={navigationRef}\n onReady={() => {\n contextProps.onReady?.();\n SplashModule?.hideAsync();\n const initialState = navigationRef.current?.getRootState();\n onStateChange(initialState);\n }}\n onStateChange={(state) => {\n contextProps.onStateChange?.(state);\n onStateChange(state);\n }}\n />\n </VirtualRouteContext.Provider>\n );\n}\n\nexport function RootContainer({\n documentTitle,\n fallback,\n onReady,\n initialState,\n onStateChange,\n onUnhandledAction,\n theme,\n}: Omit<\n NavigationContainerProps,\n \"independent\" | \"ref\" | \"children\" | \"linking\"\n>) {\n const [, setProps] = useNavigationContainerContext();\n\n React.useEffect(() => {\n setProps({\n documentTitle,\n fallback,\n onReady,\n initialState,\n onStateChange,\n onUnhandledAction,\n theme,\n });\n }, [\n documentTitle,\n fallback,\n onReady,\n initialState,\n onStateChange,\n onUnhandledAction,\n theme,\n ]);\n\n return null;\n}\n\n/** Get the root navigation container ref. */\nRootContainer.getRef = () => {\n return navigationRef;\n};\n"]}
@@ -1,7 +1,7 @@
1
1
  import { useMemo } from "react";
2
2
  import { getAllWebRedirects } from "./aasa";
3
3
  import { useRoutesContext } from "./context";
4
- import { addEventListener, getInitialURL, getRootURL, getPathFromState, getStateFromPath, } from "./linking";
4
+ import { addEventListener, getInitialURL, getRootURL, getPathFromState, getStateFromPath, } from "./link/linking";
5
5
  import { matchDeepDynamicRouteName, matchDynamicName, matchFragmentName, } from "./matchers";
6
6
  // `[page]` -> `:page`
7
7
  // `page` -> `page`
@@ -1 +1 @@
1
- {"version":3,"file":"getLinkingConfig.js","sourceRoot":"","sources":["../src/getLinkingConfig.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAGhC,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,sBAAsB;AACtB,mBAAmB;AACnB,SAAS,oCAAoC,CAAC,IAAY;IACxD,IAAI,yBAAyB,CAAC,IAAI,CAAC,EAAE;QACnC,OAAO,GAAG,CAAC;KACZ;IACD,MAAM,WAAW,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAE3C,IAAI,WAAW,EAAE;QACf,OAAO,IAAI,WAAW,EAAE,CAAC;KAC1B;IAED,IAAI,IAAI,KAAK,OAAO,IAAI,iBAAiB,CAAC,IAAI,CAAC,EAAE;QAC/C,OAAO,EAAE,CAAC;KACX;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,kCAAkC,CAChD,KAAkB,EAClB,UAAoB,EAAE;IAEtB,kEAAkE;IAClE,yFAAyF;IACzF,MAAM,SAAS,GAAG,KAAK;SACpB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,MAAM,IAAI,GAAG,oCAAoC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAE9D,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;YACzB,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;SAC3B;QAED,MAAM,OAAO,GAAG,kCAAkC,CAAC,IAAI,CAAC,QAAQ,EAAE;YAChE,GAAG,OAAO;YACV,IAAI;SACL,CAAC,CAAC;QAEH,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAU,CAAC;IAClD,CAAC,CAAC;SACD,MAAM,CAAwB,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,EAAE;QACvD,GAAG,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC;QACrB,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,EAAE,CAAC,CAAC;IAET,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAmB;IAClD,OAAO;QACL,QAAQ,EAAE;YACR,2BAA2B;YAC3B,UAAU,EAAE;YAEZ,4FAA4F;YAC5F,0BAA0B;YAC1B,GAAG,kBAAkB,EAAE;SACxB;QACD,MAAM,EAAE;YACN,OAAO,EAAE,kCAAkC,CAAC,MAAM,CAAC;SACpD;QACD,8EAA8E;QAC9E,wEAAwE;QACxE,+EAA+E;QAC/E,8GAA8G;QAC9G,8EAA8E;QAC9E,aAAa;QACb,SAAS,EAAE,gBAAgB;QAC3B,gBAAgB;QAChB,gBAAgB;KACjB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3D,CAAC","sourcesContent":["import { LinkingOptions, PathConfigMap } from \"@react-navigation/native\";\nimport { useMemo } from \"react\";\n\nimport { RouteNode } from \"./Route\";\nimport { getAllWebRedirects } from \"./aasa\";\nimport { useRoutesContext } from \"./context\";\nimport {\n addEventListener,\n getInitialURL,\n getRootURL,\n getPathFromState,\n getStateFromPath,\n} from \"./linking\";\nimport {\n matchDeepDynamicRouteName,\n matchDynamicName,\n matchFragmentName,\n} from \"./matchers\";\n\n// `[page]` -> `:page`\n// `page` -> `page`\nfunction convertDynamicRouteToReactNavigation(name: string) {\n if (matchDeepDynamicRouteName(name)) {\n return \"*\";\n }\n const dynamicName = matchDynamicName(name);\n\n if (dynamicName) {\n return `:${dynamicName}`;\n }\n\n if (name === \"index\" || matchFragmentName(name)) {\n return \"\";\n }\n\n return name;\n}\n\nexport function treeToReactNavigationLinkingRoutes(\n nodes: RouteNode[],\n parents: string[] = []\n): PathConfigMap<object> {\n // TODO: Intercept errors, strip invalid routes, and warn instead.\n // Our warnings can be more helpful than upstream since we know the associated file name.\n const firstPass = nodes\n .map((node) => {\n const path = convertDynamicRouteToReactNavigation(node.route);\n\n if (!node.children.length) {\n return [node.route, path];\n }\n\n const screens = treeToReactNavigationLinkingRoutes(node.children, [\n ...parents,\n path,\n ]);\n\n return [node.route, { path, screens }] as const;\n })\n .reduce<PathConfigMap<object>>((acc, [route, current]) => {\n acc[route] = current;\n return acc;\n }, {});\n\n return firstPass;\n}\n\nexport function getLinkingConfig(routes: RouteNode[]): LinkingOptions<object> {\n return {\n prefixes: [\n /* your linking prefixes */\n getRootURL(),\n\n // This ensures that we can redirect correctly when the user comes from an associated domain\n // i.e. iOS Safari banner.\n ...getAllWebRedirects(),\n ],\n config: {\n screens: treeToReactNavigationLinkingRoutes(routes),\n },\n // A custom getInitialURL is used on native to ensure the app always starts at\n // the root path if it's launched from something other than a deep link.\n // This helps keep the native functionality working like the web functionality.\n // For example, if you had a root navigator where the first screen was `/settings` and the second was `/index`\n // then `/index` would be used on web and `/settings` would be used on native.\n getInitialURL,\n subscribe: addEventListener,\n getStateFromPath,\n getPathFromState,\n };\n}\n\nexport function useLinkingConfig(): LinkingOptions<object> {\n const routes = useRoutesContext();\n return useMemo(() => getLinkingConfig(routes), [routes]);\n}\n"]}
1
+ {"version":3,"file":"getLinkingConfig.js","sourceRoot":"","sources":["../src/getLinkingConfig.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAGhC,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,sBAAsB;AACtB,mBAAmB;AACnB,SAAS,oCAAoC,CAAC,IAAY;IACxD,IAAI,yBAAyB,CAAC,IAAI,CAAC,EAAE;QACnC,OAAO,GAAG,CAAC;KACZ;IACD,MAAM,WAAW,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAE3C,IAAI,WAAW,EAAE;QACf,OAAO,IAAI,WAAW,EAAE,CAAC;KAC1B;IAED,IAAI,IAAI,KAAK,OAAO,IAAI,iBAAiB,CAAC,IAAI,CAAC,EAAE;QAC/C,OAAO,EAAE,CAAC;KACX;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,kCAAkC,CAChD,KAAkB,EAClB,UAAoB,EAAE;IAEtB,kEAAkE;IAClE,yFAAyF;IACzF,MAAM,SAAS,GAAG,KAAK;SACpB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,MAAM,IAAI,GAAG,oCAAoC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAE9D,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;YACzB,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;SAC3B;QAED,MAAM,OAAO,GAAG,kCAAkC,CAAC,IAAI,CAAC,QAAQ,EAAE;YAChE,GAAG,OAAO;YACV,IAAI;SACL,CAAC,CAAC;QAEH,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAU,CAAC;IAClD,CAAC,CAAC;SACD,MAAM,CAAwB,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,EAAE;QACvD,GAAG,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC;QACrB,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,EAAE,CAAC,CAAC;IAET,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAmB;IAClD,OAAO;QACL,QAAQ,EAAE;YACR,2BAA2B;YAC3B,UAAU,EAAE;YAEZ,4FAA4F;YAC5F,0BAA0B;YAC1B,GAAG,kBAAkB,EAAE;SACxB;QACD,MAAM,EAAE;YACN,OAAO,EAAE,kCAAkC,CAAC,MAAM,CAAC;SACpD;QACD,8EAA8E;QAC9E,wEAAwE;QACxE,+EAA+E;QAC/E,8GAA8G;QAC9G,8EAA8E;QAC9E,aAAa;QACb,SAAS,EAAE,gBAAgB;QAC3B,gBAAgB;QAChB,gBAAgB;KACjB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3D,CAAC","sourcesContent":["import { LinkingOptions, PathConfigMap } from \"@react-navigation/native\";\nimport { useMemo } from \"react\";\n\nimport { RouteNode } from \"./Route\";\nimport { getAllWebRedirects } from \"./aasa\";\nimport { useRoutesContext } from \"./context\";\nimport {\n addEventListener,\n getInitialURL,\n getRootURL,\n getPathFromState,\n getStateFromPath,\n} from \"./link/linking\";\nimport {\n matchDeepDynamicRouteName,\n matchDynamicName,\n matchFragmentName,\n} from \"./matchers\";\n\n// `[page]` -> `:page`\n// `page` -> `page`\nfunction convertDynamicRouteToReactNavigation(name: string) {\n if (matchDeepDynamicRouteName(name)) {\n return \"*\";\n }\n const dynamicName = matchDynamicName(name);\n\n if (dynamicName) {\n return `:${dynamicName}`;\n }\n\n if (name === \"index\" || matchFragmentName(name)) {\n return \"\";\n }\n\n return name;\n}\n\nexport function treeToReactNavigationLinkingRoutes(\n nodes: RouteNode[],\n parents: string[] = []\n): PathConfigMap<object> {\n // TODO: Intercept errors, strip invalid routes, and warn instead.\n // Our warnings can be more helpful than upstream since we know the associated file name.\n const firstPass = nodes\n .map((node) => {\n const path = convertDynamicRouteToReactNavigation(node.route);\n\n if (!node.children.length) {\n return [node.route, path];\n }\n\n const screens = treeToReactNavigationLinkingRoutes(node.children, [\n ...parents,\n path,\n ]);\n\n return [node.route, { path, screens }] as const;\n })\n .reduce<PathConfigMap<object>>((acc, [route, current]) => {\n acc[route] = current;\n return acc;\n }, {});\n\n return firstPass;\n}\n\nexport function getLinkingConfig(routes: RouteNode[]): LinkingOptions<object> {\n return {\n prefixes: [\n /* your linking prefixes */\n getRootURL(),\n\n // This ensures that we can redirect correctly when the user comes from an associated domain\n // i.e. iOS Safari banner.\n ...getAllWebRedirects(),\n ],\n config: {\n screens: treeToReactNavigationLinkingRoutes(routes),\n },\n // A custom getInitialURL is used on native to ensure the app always starts at\n // the root path if it's launched from something other than a deep link.\n // This helps keep the native functionality working like the web functionality.\n // For example, if you had a root navigator where the first screen was `/settings` and the second was `/index`\n // then `/index` would be used on web and `/settings` would be used on native.\n getInitialURL,\n subscribe: addEventListener,\n getStateFromPath,\n getPathFromState,\n };\n}\n\nexport function useLinkingConfig(): LinkingOptions<object> {\n const routes = useRoutesContext();\n return useMemo(() => getLinkingConfig(routes), [routes]);\n}\n"]}
package/build/index.d.ts CHANGED
@@ -8,8 +8,8 @@ export { ExpoRoot } from "./views/Root";
8
8
  export { Unmatched } from "./views/Unmatched";
9
9
  export { ErrorBoundary } from "./views/ErrorBoundary";
10
10
  export { Layout, Children } from "./views/Layout";
11
- export { Link } from "./views/Link";
12
- export { useLink } from "./useLink";
11
+ export { Link } from "./link/Link";
12
+ export { useLink } from "./link/useLink";
13
13
  export { RootContainer } from "./ContextNavigationContainer";
14
- export * as Linking from "./linking";
14
+ export * as Linking from "./link/linking";
15
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAG7D,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC"}
package/build/index.js CHANGED
@@ -9,9 +9,9 @@ export { ExpoRoot } from "./views/Root";
9
9
  export { Unmatched } from "./views/Unmatched";
10
10
  export { ErrorBoundary } from "./views/ErrorBoundary";
11
11
  export { Layout, Children } from "./views/Layout";
12
- export { Link } from "./views/Link";
13
- export { useLink } from "./useLink";
12
+ export { Link } from "./link/Link";
13
+ export { useLink } from "./link/useLink";
14
14
  export { RootContainer } from "./ContextNavigationContainer";
15
- import * as Linking_1 from "./linking";
15
+ import * as Linking_1 from "./link/linking";
16
16
  export { Linking_1 as Linking };
17
17
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,6CAA6C;AAI7C,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;2BAGpC,WAAW;sBAAxB,OAAO","sourcesContent":["// export { useRoutes } from \"./Route\";\n// export { useScreens } from \"./useScreens\";\n\nexport { ErrorBoundaryProps } from \"./views/Try\";\n\nexport { Stack } from \"./layouts/Stack\";\nexport { NativeStack } from \"./layouts/NativeStack\";\nexport { Tabs } from \"./layouts/Tabs\";\nexport { Drawer } from \"./layouts/Drawer\";\nexport { withLayoutContext } from \"./layouts/withLayoutContext\";\n\nexport { ExpoRoot } from \"./views/Root\";\nexport { Unmatched } from \"./views/Unmatched\";\nexport { ErrorBoundary } from \"./views/ErrorBoundary\";\n\nexport { Layout, Children } from \"./views/Layout\";\nexport { Link } from \"./views/Link\";\nexport { useLink } from \"./useLink\";\nexport { RootContainer } from \"./ContextNavigationContainer\";\n// export { useCurrentRoute } from \"./useCurrentRoute\";\n\nexport * as Linking from \"./linking\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,6CAA6C;AAI7C,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;2BAEpC,gBAAgB;sBAA7B,OAAO","sourcesContent":["// export { useRoutes } from \"./Route\";\n// export { useScreens } from \"./useScreens\";\n\nexport { ErrorBoundaryProps } from \"./views/Try\";\n\nexport { Stack } from \"./layouts/Stack\";\nexport { NativeStack } from \"./layouts/NativeStack\";\nexport { Tabs } from \"./layouts/Tabs\";\nexport { Drawer } from \"./layouts/Drawer\";\nexport { withLayoutContext } from \"./layouts/withLayoutContext\";\n\nexport { ExpoRoot } from \"./views/Root\";\nexport { Unmatched } from \"./views/Unmatched\";\nexport { ErrorBoundary } from \"./views/ErrorBoundary\";\n\nexport { Layout, Children } from \"./views/Layout\";\nexport { Link } from \"./link/Link\";\nexport { useLink } from \"./link/useLink\";\nexport { RootContainer } from \"./ContextNavigationContainer\";\n\nexport * as Linking from \"./link/linking\";\n"]}
@@ -0,0 +1,26 @@
1
+ import { TextProps } from "@bacons/react-views";
2
+ import * as React from "react";
3
+ import { GestureResponderEvent } from "react-native";
4
+ import { Href } from "./href";
5
+ declare type Props = {
6
+ /** Add a property which is familiar to */
7
+ href: Href;
8
+ /** Forward props to child component. Useful for custom buttons. */
9
+ asChild?: boolean;
10
+ /** Should replace the current screen without adding to the history. */
11
+ replace?: boolean;
12
+ onPress?: (e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent) => void;
13
+ } & (TextProps & {
14
+ children: React.ReactNode;
15
+ });
16
+ /**
17
+ * Component to render link to another screen using a path.
18
+ * Uses an anchor tag on the web.
19
+ *
20
+ * @param props.href Absolute path to screen (e.g. `/feeds/hot`).
21
+ * @param props.asChild Forward props to child component. Useful for custom buttons.
22
+ * @param props.children Child elements to render the content.
23
+ */
24
+ export declare const Link: React.ForwardRefExoticComponent<Pick<Props, "children" | "replace" | "key" | "allowFontScaling" | "ellipsizeMode" | "lineBreakMode" | "numberOfLines" | "onLayout" | "onTextLayout" | "onPress" | "onPressIn" | "onPressOut" | "onLongPress" | "testID" | "nativeID" | "maxFontSizeMultiplier" | "adjustsFontSizeToFit" | "minimumFontScale" | "suppressHighlighting" | "selectable" | "selectionColor" | "textBreakStrategy" | "dataDetectorType" | "android_hyphenationFrequency" | "accessible" | "accessibilityActions" | "accessibilityLabel" | "accessibilityState" | "accessibilityHint" | "accessibilityValue" | "onAccessibilityAction" | "accessibilityLiveRegion" | "importantForAccessibility" | "accessibilityElementsHidden" | "accessibilityViewIsModal" | "onAccessibilityEscape" | "onAccessibilityTap" | "onMagicTap" | "accessibilityIgnoresInvertColors" | "asChild" | keyof import("@bacons/react-views/build/Text").WebTextProps> & React.RefAttributes<Text>>;
25
+ export {};
26
+ //# sourceMappingURL=Link.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../src/link/Link.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAQ,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,qBAAqB,EAAY,MAAM,cAAc,CAAC;AAE/D,OAAO,EAAE,IAAI,EAAe,MAAM,QAAQ,CAAC;AAG3C,aAAK,KAAK,GAAG;IACX,2CAA2C;IAC3C,IAAI,EAAE,IAAI,CAAC;IAGX,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,OAAO,CAAC,EAAE,CACR,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,EAAE,UAAU,CAAC,GAAG,qBAAqB,KACvE,IAAI,CAAC;CACX,GAAG,CAAC,SAAS,GAAG;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,CAAC,CAAC;AAEhD;;;;;;;GAOG;AACH,eAAO,MAAM,IAAI,s7BAAmC,CAAC"}
@@ -0,0 +1,40 @@
1
+ // Fork of @react-navigation/native Link.tsx with `href` and `replace` support added and
2
+ // `to` / `action` support removed.
3
+ import { Text } from "@bacons/react-views";
4
+ import { Slot } from "@radix-ui/react-slot";
5
+ import * as React from "react";
6
+ import { Platform } from "react-native";
7
+ import { resolveHref } from "./href";
8
+ import useLinkToPathProps from "./useLinkToPathProps";
9
+ /**
10
+ * Component to render link to another screen using a path.
11
+ * Uses an anchor tag on the web.
12
+ *
13
+ * @param props.href Absolute path to screen (e.g. `/feeds/hot`).
14
+ * @param props.asChild Forward props to child component. Useful for custom buttons.
15
+ * @param props.children Child elements to render the content.
16
+ */
17
+ export const Link = React.forwardRef(ExpoRouterLink);
18
+ function ExpoRouterLink({ href, replace, asChild, ...rest }, ref) {
19
+ // TODO: Auto use router's client-side event.
20
+ const resolvedHref = React.useMemo(() => resolveHref(href), [href]);
21
+ const props = useLinkToPathProps({ href: resolvedHref, replace });
22
+ const onPress = (e) => {
23
+ if ("onPress" in rest) {
24
+ rest.onPress?.(e);
25
+ }
26
+ props.onPress(e);
27
+ };
28
+ return React.createElement(
29
+ // @ts-expect-error: slot is not type-safe
30
+ asChild ? Slot : Text, {
31
+ ref,
32
+ ...props,
33
+ ...rest,
34
+ ...Platform.select({
35
+ web: { onClick: onPress },
36
+ default: { onPress },
37
+ }),
38
+ });
39
+ }
40
+ //# sourceMappingURL=Link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Link.js","sourceRoot":"","sources":["../../src/link/Link.tsx"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,mCAAmC;AACnC,OAAO,EAAE,IAAI,EAAa,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAyB,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE/D,OAAO,EAAQ,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AAkBtD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AAErD,SAAS,cAAc,CACrB,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,EAAS,EAC1C,GAA6B;IAE7B,6CAA6C;IAC7C,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEpE,MAAM,KAAK,GAAG,kBAAkB,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC;IAElE,MAAM,OAAO,GAAG,CACd,CAA0E,EAC1E,EAAE;QACF,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,IAAI,CAAC,CAAC,CAAC,IAAI,EACrB;QACE,GAAG;QACH,GAAG,KAAK;QACR,GAAG,IAAI;QACP,GAAG,QAAQ,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 { Text, TextProps } from \"@bacons/react-views\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { GestureResponderEvent, Platform } from \"react-native\";\n\nimport { Href, resolveHref } from \"./href\";\nimport useLinkToPathProps from \"./useLinkToPathProps\";\n\ntype Props = {\n /** Add a property which is familiar 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 screen without adding to the history. */\n replace?: boolean;\n\n onPress?: (\n e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent\n ) => void;\n} & (TextProps & { children: React.ReactNode });\n\n/**\n * Component to render link to another screen using a path.\n * Uses an anchor tag on the web.\n *\n * @param props.href Absolute path to screen (e.g. `/feeds/hot`).\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);\n\nfunction ExpoRouterLink(\n { href, replace, asChild, ...rest }: Props,\n ref: React.ForwardedRef<Text>\n) {\n // TODO: Auto use router's client-side event.\n const resolvedHref = React.useMemo(() => resolveHref(href), [href]);\n\n const props = useLinkToPathProps({ href: resolvedHref, replace });\n\n const onPress = (\n e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent\n ) => {\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"]}
@@ -0,0 +1,9 @@
1
+ export declare type Href = string | {
2
+ pathname?: string;
3
+ query?: Record<string, any>;
4
+ };
5
+ export declare const resolveHref: (href: {
6
+ pathname?: string;
7
+ query?: Record<string, any>;
8
+ } | string) => string;
9
+ //# sourceMappingURL=href.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"href.d.ts","sourceRoot":"","sources":["../../src/link/href.ts"],"names":[],"mappings":"AAAA,oBAAY,IAAI,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,CAAC;AAE/E,eAAO,MAAM,WAAW,SAChB;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GAAG,MAAM,KAChE,MAUF,CAAC"}
@@ -0,0 +1,34 @@
1
+ export const resolveHref = (href) => {
2
+ if (typeof href === "string") {
3
+ return href ?? "";
4
+ }
5
+ const path = href.pathname ?? "";
6
+ if (!href?.query) {
7
+ return path;
8
+ }
9
+ const { pathname, query } = createQualifiedPathname(path, { ...href.query });
10
+ return pathname + (Object.keys(query).length ? `?${createQuery(query)}` : "");
11
+ };
12
+ function createQualifiedPathname(pathname, query) {
13
+ for (const [key, value = ""] of Object.entries(query)) {
14
+ const dynamicKey = `[${key}]`;
15
+ const deepDynamicKey = `[...${key}]`;
16
+ if (pathname.includes(dynamicKey)) {
17
+ pathname = pathname.replace(dynamicKey, Array.isArray(value) ? value.join("/") : value);
18
+ }
19
+ else if (pathname.includes(deepDynamicKey)) {
20
+ pathname = pathname.replace(deepDynamicKey, Array.isArray(value) ? value.join("/") : value);
21
+ }
22
+ else {
23
+ continue;
24
+ }
25
+ delete query[key];
26
+ }
27
+ return { pathname, query };
28
+ }
29
+ function createQuery(query) {
30
+ return Object.keys(query)
31
+ .map((key) => `${key}=${query[key]}`)
32
+ .join("&");
33
+ }
34
+ //# sourceMappingURL=href.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"href.js","sourceRoot":"","sources":["../../src/link/href.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,IAAiE,EACzD,EAAE;IACV,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;QAC5B,OAAO,IAAI,IAAI,EAAE,CAAC;KACnB;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;IACjC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;QAChB,OAAO,IAAI,CAAC;KACb;IACD,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,uBAAuB,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IAC7E,OAAO,QAAQ,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAChF,CAAC,CAAC;AAEF,SAAS,uBAAuB,CAAC,QAAgB,EAAE,KAA0B;IAC3E,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,GAAG,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QACrD,MAAM,UAAU,GAAG,IAAI,GAAG,GAAG,CAAC;QAC9B,MAAM,cAAc,GAAG,OAAO,GAAG,GAAG,CAAC;QACrC,IAAI,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE;YACjC,QAAQ,GAAG,QAAQ,CAAC,OAAO,CACzB,UAAU,EACV,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAC/C,CAAC;SACH;aAAM,IAAI,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE;YAC5C,QAAQ,GAAG,QAAQ,CAAC,OAAO,CACzB,cAAc,EACd,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAC/C,CAAC;SACH;aAAM;YACL,SAAS;SACV;QAED,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC;KACnB;IACD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC7B,CAAC;AAED,SAAS,WAAW,CAAC,KAA0B;IAC7C,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;SACtB,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;SACpC,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC","sourcesContent":["export type Href = string | { pathname?: string; query?: Record<string, any> };\n\nexport const resolveHref = (\n href: { pathname?: string; query?: Record<string, any> } | string\n): string => {\n if (typeof href === \"string\") {\n return href ?? \"\";\n }\n const path = href.pathname ?? \"\";\n if (!href?.query) {\n return path;\n }\n const { pathname, query } = createQualifiedPathname(path, { ...href.query });\n return pathname + (Object.keys(query).length ? `?${createQuery(query)}` : \"\");\n};\n\nfunction createQualifiedPathname(pathname: string, query: Record<string, any>) {\n for (const [key, value = \"\"] of Object.entries(query)) {\n const dynamicKey = `[${key}]`;\n const deepDynamicKey = `[...${key}]`;\n if (pathname.includes(dynamicKey)) {\n pathname = pathname.replace(\n dynamicKey,\n Array.isArray(value) ? value.join(\"/\") : value\n );\n } else if (pathname.includes(deepDynamicKey)) {\n pathname = pathname.replace(\n deepDynamicKey,\n Array.isArray(value) ? value.join(\"/\") : value\n );\n } else {\n continue;\n }\n\n delete query[key];\n }\n return { pathname, query };\n}\n\nfunction createQuery(query: Record<string, any>) {\n return Object.keys(query)\n .map((key) => `${key}=${query[key]}`)\n .join(\"&\");\n}\n"]}
@@ -1,5 +1,5 @@
1
- import getPathFromState from "./fork/getPathFromState";
2
- import getStateFromPath from "./fork/getStateFromPath";
1
+ import getPathFromState from "../fork/getPathFromState";
2
+ import getStateFromPath from "../fork/getStateFromPath";
3
3
  export declare function getInitialURL(): Promise<string>;
4
4
  export declare function getRootURL(): string;
5
5
  export declare function addEventListener(listener: (url: string) => void): () => void;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linking.d.ts","sourceRoot":"","sources":["../../src/link/linking.ts"],"names":[],"mappings":"AAGA,OAAO,gBAAgB,MAAM,0BAA0B,CAAC;AACxD,OAAO,gBAAgB,MAAM,0BAA0B,CAAC;AAOxD,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CA+BrD;AAID,wBAAgB,UAAU,WAKzB;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,cAiC/D;AAED,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import Constants, { ExecutionEnvironment } from "expo-constants";
2
2
  import * as Linking from "expo-linking";
3
- import getPathFromState from "./fork/getPathFromState";
4
- import getStateFromPath from "./fork/getStateFromPath";
3
+ import getPathFromState from "../fork/getPathFromState";
4
+ import getStateFromPath from "../fork/getStateFromPath";
5
5
  // A custom getInitialURL is used on native to ensure the app always starts at
6
6
  // the root path if it's launched from something other than a deep link.
7
7
  // This helps keep the native functionality working like the web functionality.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linking.js","sourceRoot":"","sources":["../../src/link/linking.ts"],"names":[],"mappings":"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","sourcesContent":["import Constants, { ExecutionEnvironment } from \"expo-constants\";\nimport * as Linking from \"expo-linking\";\n\nimport getPathFromState from \"../fork/getPathFromState\";\nimport getStateFromPath from \"../fork/getStateFromPath\";\n\n// A custom getInitialURL is used on native to ensure the app always starts at\n// the root path if it's launched from something other than a deep link.\n// This helps keep the native functionality working like the web functionality.\n// For example, if you had a root navigator where the first screen was `/settings` and the second was `/index`\n// then `/index` would be used on web and `/settings` would be used on native.\nexport async function getInitialURL(): Promise<string> {\n const url = await Promise.race<string>([\n (async () => {\n const url = await Linking.getInitialURL();\n\n // NOTE(EvanBacon): This could probably be wrapped with the development boundary\n // since Expo Go is mostly just used in development.\n\n // Expo Go is weird and requires the root path to be `/--/`\n if (\n url &&\n Constants.executionEnvironment === ExecutionEnvironment.StoreClient\n ) {\n const parsed = Linking.parse(url);\n // If the URL is defined (default in Expo Go dev apps) and the URL has no path:\n // `exp://192.168.87.39:19000/` then use the default `exp://192.168.87.39:19000/--/`\n if (parsed.path === null || [\"\", \"/\"].includes(parsed.path)) {\n return getRootURL();\n }\n }\n // The path will be nullish in bare apps when the app is launched from the home screen.\n // TODO(EvanBacon): define some policy around notifications.\n return url ?? getRootURL();\n })(),\n new Promise<string>((resolve) =>\n // Timeout in 150ms if `getInitialState` doesn't resolve\n // Workaround for https://github.com/facebook/react-native/issues/25675\n setTimeout(() => resolve(getRootURL()), 150)\n ),\n ]);\n return url;\n}\n\nlet _rootURL: string | undefined;\n\nexport function getRootURL() {\n if (_rootURL === undefined) {\n _rootURL = Linking.createURL(\"/\");\n }\n return _rootURL;\n}\n\nexport function addEventListener(listener: (url: string) => void) {\n let callback: (({ url }: { url: string }) => void) | undefined = undefined;\n\n if (Constants.executionEnvironment === ExecutionEnvironment.StoreClient) {\n // This extra work is only done in the Expo Go app.\n callback = ({ url }: { url: string }) => {\n const parsed = Linking.parse(url);\n // If the URL is defined (default in Expo Go dev apps) and the URL has no path:\n // `exp://192.168.87.39:19000/` then use the default `exp://192.168.87.39:19000/--/`\n if (parsed.path === null || [\"\", \"/\"].includes(parsed.path)) {\n listener(getRootURL());\n } else {\n listener(url);\n }\n };\n } else {\n callback = ({ url }: { url: string }) => listener(url);\n }\n const subscription = Linking.addEventListener(\"url\", callback) as\n | { remove(): void }\n | undefined;\n\n // Storing this in a local variable stops Jest from complaining about import after teardown\n const removeEventListener = Linking.removeEventListener?.bind(Linking);\n\n return () => {\n // https://github.com/facebook/react-native/commit/6d1aca806cee86ad76de771ed3a1cc62982ebcd7\n if (subscription?.remove) {\n subscription.remove();\n } else {\n removeEventListener?.(\"url\", callback);\n }\n };\n}\n\nexport { getStateFromPath, getPathFromState };\n"]}
@@ -1,4 +1,4 @@
1
- import { Href, resolveHref } from "./views/Link";
1
+ import { Href, resolveHref } from "./href";
2
2
  export declare function useLink(): {
3
3
  push: (href: Href) => void;
4
4
  replace: (href: Href) => void;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLink.d.ts","sourceRoot":"","sources":["../../src/link/useLink.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAI3C,wBAAgB,OAAO,IAAI;IACzB,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC3B,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC9B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,OAAO,WAAW,CAAC;CAC3B,CAqBA"}
@@ -1,7 +1,7 @@
1
1
  import { useNavigation } from "@react-navigation/native";
2
2
  import { useMemo } from "react";
3
- import { useLinkToPath } from "./fork/useLinkToPath";
4
- import { resolveHref } from "./views/Link";
3
+ import { resolveHref } from "./href";
4
+ import { useLinkToPath } from "./useLinkToPath";
5
5
  // Wraps useLinkTo to provide an API which is similar to the Link component.
6
6
  export function useLink() {
7
7
  const linkTo = useLinkToPath();
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLink.js","sourceRoot":"","sources":["../../src/link/useLink.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,EAAQ,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,4EAA4E;AAC5E,MAAM,UAAU,OAAO;IAMrB,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,OAAO,OAAO,CACZ,GAAG,EAAE,CAAC,CAAC;QACL,IAAI,EAAE,CAAC,GAAS,EAAE,EAAE;YAClB,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;YAC9B,MAAM,CAAC,IAAI,CAAC,CAAC;QACf,CAAC;QACD,OAAO,EAAE,CAAC,GAAS,EAAE,EAAE;YACrB,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;YAC9B,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC1B,CAAC;QACD,IAAI,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE;QAChC,KAAK,EAAE,WAAW;QAClB,2DAA2D;QAC3D,sEAAsE;KACvE,CAAC,EACF,CAAC,UAAU,EAAE,MAAM,CAAC,CACrB,CAAC;AACJ,CAAC","sourcesContent":["import { useNavigation } from \"@react-navigation/native\";\nimport { useMemo } from \"react\";\n\nimport { Href, resolveHref } from \"./href\";\nimport { useLinkToPath } from \"./useLinkToPath\";\n\n// Wraps useLinkTo to provide an API which is similar to the Link component.\nexport function useLink(): {\n push: (href: Href) => void;\n replace: (href: Href) => void;\n back: () => void;\n parse: typeof resolveHref;\n} {\n const linkTo = useLinkToPath();\n const navigation = useNavigation();\n\n return useMemo(\n () => ({\n push: (url: Href) => {\n const href = resolveHref(url);\n linkTo(href);\n },\n replace: (url: Href) => {\n const href = resolveHref(url);\n linkTo(href, \"REPLACE\");\n },\n back: () => navigation?.goBack(),\n parse: resolveHref,\n // TODO(EvanBacon): add `pathname`, `query`, maybe `reload`\n // TODO(EvanBacon): add `canGoBack` but maybe more like a `hasContext`\n }),\n [navigation, linkTo]\n );\n}\n"]}
File without changes
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLinkToPath.d.ts","sourceRoot":"","sources":["../../src/link/useLinkToPath.ts"],"names":[],"mappings":"AASA,wBAAgB,aAAa,SAKpB,MAAM,UAAU,MAAM,UA6C9B"}
File without changes
@@ -1 +1 @@
1
- {"version":3,"file":"useLinkToPath.js","sourceRoot":"","sources":["../../src/fork/useLinkToPath.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,6BAA6B,GAC9B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,UAAU,aAAa;IAC3B,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,6BAA6B,CAAC,CAAC;IACnE,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;IAEjD,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,CAC9B,CAAC,EAAU,EAAE,KAAc,EAAE,EAAE;QAC7B,IAAI,UAAU,KAAK,SAAS,EAAE;YAC5B,MAAM,IAAI,KAAK,CACb,kFAAkF,CACnF,CAAC;SACH;QAED,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;YACvB,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;gBACpB,qBAAqB;gBACrB,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACpB,OAAO;aACR;iBAAM;gBACL,MAAM,IAAI,KAAK,CACb,iCAAiC,EAAE,gCAAgC,CACpE,CAAC;aACH;SACF;QAED,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QAE5B,MAAM,KAAK,GAAG,OAAO,EAAE,gBAAgB;YACrC,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC;YAC9C,CAAC,CAAC,gBAAgB,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAE1C,IAAI,KAAK,EAAE;YACT,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;YAE1D,IAAI,MAAM,KAAK,SAAS,EAAE;gBACxB,IAAI,KAAK,EAAE;oBACT,aAAa;oBACb,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC;iBACrB;gBACD,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;aAC7B;iBAAM;gBACL,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;aACzB;SACF;aAAM;YACL,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;SACpE;IACH,CAAC,EACD,CAAC,OAAO,EAAE,UAAU,CAAC,CACtB,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import {\n getActionFromState,\n getStateFromPath,\n NavigationContainerRefContext,\n} from \"@react-navigation/core\";\nimport { LinkingContext } from \"@react-navigation/native\";\nimport * as React from \"react\";\nimport { Linking } from \"react-native\";\n\nexport function useLinkToPath() {\n const navigation = React.useContext(NavigationContainerRefContext);\n const linking = React.useContext(LinkingContext);\n\n const linkTo = React.useCallback(\n (to: string, event?: string) => {\n if (navigation === undefined) {\n throw new Error(\n \"Couldn't find a navigation object. Is your component inside NavigationContainer?\"\n );\n }\n\n if (!to.startsWith(\"/\")) {\n if (/:\\/\\//.test(to)) {\n // Open external link\n Linking.openURL(to);\n return;\n } else {\n throw new Error(\n `The href must start with '/' (${to}) or be a fully qualified URL.`\n );\n }\n }\n\n const { options } = linking;\n\n const state = options?.getStateFromPath\n ? options.getStateFromPath(to, options.config)\n : getStateFromPath(to, options?.config);\n\n if (state) {\n const action = getActionFromState(state, options?.config);\n\n if (action !== undefined) {\n if (event) {\n // @ts-ignore\n action.type = event;\n }\n navigation.dispatch(action);\n } else {\n navigation.reset(state);\n }\n } else {\n throw new Error(\"Failed to parse the path to a navigation state.\");\n }\n },\n [linking, navigation]\n );\n\n return linkTo;\n}\n"]}
1
+ {"version":3,"file":"useLinkToPath.js","sourceRoot":"","sources":["../../src/link/useLinkToPath.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,6BAA6B,GAC9B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,UAAU,aAAa;IAC3B,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,6BAA6B,CAAC,CAAC;IACnE,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;IAEjD,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,CAC9B,CAAC,EAAU,EAAE,KAAc,EAAE,EAAE;QAC7B,IAAI,UAAU,KAAK,SAAS,EAAE;YAC5B,MAAM,IAAI,KAAK,CACb,kFAAkF,CACnF,CAAC;SACH;QAED,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;YACvB,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;gBACpB,qBAAqB;gBACrB,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACpB,OAAO;aACR;iBAAM;gBACL,MAAM,IAAI,KAAK,CACb,iCAAiC,EAAE,gCAAgC,CACpE,CAAC;aACH;SACF;QAED,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QAE5B,MAAM,KAAK,GAAG,OAAO,EAAE,gBAAgB;YACrC,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC;YAC9C,CAAC,CAAC,gBAAgB,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAE1C,IAAI,KAAK,EAAE;YACT,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;YAE1D,IAAI,MAAM,KAAK,SAAS,EAAE;gBACxB,IAAI,KAAK,EAAE;oBACT,aAAa;oBACb,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC;iBACrB;gBACD,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;aAC7B;iBAAM;gBACL,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;aACzB;SACF;aAAM;YACL,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;SACpE;IACH,CAAC,EACD,CAAC,OAAO,EAAE,UAAU,CAAC,CACtB,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import {\n getActionFromState,\n getStateFromPath,\n NavigationContainerRefContext,\n} from \"@react-navigation/core\";\nimport { LinkingContext } from \"@react-navigation/native\";\nimport * as React from \"react\";\nimport { Linking } from \"react-native\";\n\nexport function useLinkToPath() {\n const navigation = React.useContext(NavigationContainerRefContext);\n const linking = React.useContext(LinkingContext);\n\n const linkTo = React.useCallback(\n (to: string, event?: string) => {\n if (navigation === undefined) {\n throw new Error(\n \"Couldn't find a navigation object. Is your component inside NavigationContainer?\"\n );\n }\n\n if (!to.startsWith(\"/\")) {\n if (/:\\/\\//.test(to)) {\n // Open external link\n Linking.openURL(to);\n return;\n } else {\n throw new Error(\n `The href must start with '/' (${to}) or be a fully qualified URL.`\n );\n }\n }\n\n const { options } = linking;\n\n const state = options?.getStateFromPath\n ? options.getStateFromPath(to, options.config)\n : getStateFromPath(to, options?.config);\n\n if (state) {\n const action = getActionFromState(state, options?.config);\n\n if (action !== undefined) {\n if (event) {\n // @ts-ignore\n action.type = event;\n }\n navigation.dispatch(action);\n } else {\n navigation.reset(state);\n }\n } else {\n throw new Error(\"Failed to parse the path to a navigation state.\");\n }\n },\n [linking, navigation]\n );\n\n return linkTo;\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import * as React from "react";
2
+ import { GestureResponderEvent } from "react-native";
3
+ export default function useLinkToPathProps(props: {
4
+ href: string;
5
+ replace?: boolean;
6
+ }): {
7
+ href: string;
8
+ accessibilityRole: "link";
9
+ onPress: (e?: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent) => void;
10
+ };
11
+ //# sourceMappingURL=useLinkToPathProps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLinkToPathProps.d.ts","sourceRoot":"","sources":["../../src/link/useLinkToPathProps.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,qBAAqB,EAAY,MAAM,cAAc,CAAC;AAI/D,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,KAAK,EAAE;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;;;kBAIO,gBAAgB,CAAC,iBAAiB,EAAE,UAAU,CAAC,GAAG,qBAAqB;EA6B9E"}
@@ -0,0 +1,31 @@
1
+ import { Platform } from "react-native";
2
+ import { useLinkToPath } from "./useLinkToPath";
3
+ export default function useLinkToPathProps(props) {
4
+ const linkTo = useLinkToPath();
5
+ const onPress = (e) => {
6
+ let shouldHandle = false;
7
+ if (Platform.OS !== "web" || !e) {
8
+ shouldHandle = e ? !e.defaultPrevented : true;
9
+ }
10
+ else if (!e.defaultPrevented && // onPress prevented default
11
+ // @ts-expect-error: these properties exist on web, but not in React Native
12
+ !(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) && // ignore clicks with modifier keys
13
+ // @ts-expect-error: these properties exist on web, but not in React Native
14
+ (e.button == null || e.button === 0) && // ignore everything but left clicks
15
+ // @ts-expect-error: these properties exist on web, but not in React Native
16
+ [undefined, null, "", "self"].includes(e.currentTarget?.target) // let browser handle "target=_blank" etc.
17
+ ) {
18
+ e.preventDefault();
19
+ shouldHandle = true;
20
+ }
21
+ if (shouldHandle) {
22
+ linkTo(props.href, props.replace ? "REPLACE" : undefined);
23
+ }
24
+ };
25
+ return {
26
+ href: props.href,
27
+ accessibilityRole: "link",
28
+ onPress,
29
+ };
30
+ }
31
+ //# sourceMappingURL=useLinkToPathProps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLinkToPathProps.js","sourceRoot":"","sources":["../../src/link/useLinkToPathProps.tsx"],"names":[],"mappings":"AACA,OAAO,EAAyB,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE/D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,KAG1C;IACC,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAE/B,MAAM,OAAO,GAAG,CACd,CAA2E,EAC3E,EAAE;QACF,IAAI,YAAY,GAAG,KAAK,CAAC;QAEzB,IAAI,QAAQ,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,IACL,CAAC,CAAC,CAAC,gBAAgB,IAAI,4BAA4B;YACnD,2EAA2E;YAC3E,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,mCAAmC;YAC1F,2EAA2E;YAC3E,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,oCAAoC;YAC5E,2EAA2E;YAC3E,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,0CAA0C;UAC1G;YACA,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,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,iBAAiB,EAAE,MAAe;QAClC,OAAO;KACR,CAAC;AACJ,CAAC","sourcesContent":["import * as React from \"react\";\nimport { GestureResponderEvent, Platform } from \"react-native\";\n\nimport { useLinkToPath } from \"./useLinkToPath\";\n\nexport default function useLinkToPathProps(props: {\n href: string;\n replace?: boolean;\n}) {\n const linkTo = useLinkToPath();\n\n const onPress = (\n e?: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent\n ) => {\n let shouldHandle = false;\n\n if (Platform.OS !== \"web\" || !e) {\n shouldHandle = e ? !e.defaultPrevented : true;\n } else if (\n !e.defaultPrevented && // onPress prevented default\n // @ts-expect-error: these properties exist on web, but not in React Native\n !(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) && // ignore clicks with modifier keys\n // @ts-expect-error: these properties exist on web, but not in React Native\n (e.button == null || e.button === 0) && // ignore everything but left clicks\n // @ts-expect-error: these properties exist on web, but not in React Native\n [undefined, null, \"\", \"self\"].includes(e.currentTarget?.target) // let browser handle \"target=_blank\" etc.\n ) {\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 href: props.href,\n accessibilityRole: \"link\" as const,\n onPress,\n };\n}\n"]}
@@ -4,8 +4,8 @@ import React from "react";
4
4
  import { ScrollView, Platform, StatusBar, useWindowDimensions, } from "react-native";
5
5
  import { useSafeAreaInsets } from "react-native-safe-area-context";
6
6
  import { useRoutesContext } from "../context";
7
+ import { Link } from "../link/Link";
7
8
  import { matchDeepDynamicRouteName, matchFragmentName } from "../matchers";
8
- import { Link } from "./Link";
9
9
  const INDENT = 18;
10
10
  function useSortedRoutes() {
11
11
  const ctx = useRoutesContext();
@@ -1 +1 @@
1
- {"version":3,"file":"Directory.js","sourceRoot":"","sources":["../../src/views/Directory.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Image, Pressable, StyleSheet, Text, View } from \"@bacons/react-views\";\nimport { useNavigation } from \"@react-navigation/native\";\nimport { NativeStackNavigationOptions } from \"@react-navigation/native-stack\";\nimport React from \"react\";\nimport {\n ScrollView,\n Platform,\n StatusBar,\n useWindowDimensions,\n} from \"react-native\";\nimport { useSafeAreaInsets } from \"react-native-safe-area-context\";\n\nimport { RouteNode } from \"../Route\";\nimport { useRoutesContext } from \"../context\";\nimport { matchDeepDynamicRouteName, matchFragmentName } from \"../matchers\";\nimport { Link } from \"./Link\";\n\nconst INDENT = 18;\n\nfunction useSortedRoutes() {\n const ctx = useRoutesContext();\n\n const routes = React.useMemo(\n () =>\n ctx\n .filter((route) => !route.internal)\n .sort((a, b) => {\n // Emulate vscode's sorting\n if (a.route < b.route) {\n return -1;\n }\n if (a.route > b.route) {\n return 1;\n }\n return 0;\n }),\n [ctx]\n );\n return routes;\n}\n\nconst styles = StyleSheet.create({\n container: {\n backgroundColor: \"black\",\n flex: 1,\n alignItems: \"stretch\",\n },\n main: {\n marginHorizontal: \"auto\",\n flex: 1,\n\n alignItems: \"stretch\",\n },\n scroll: {\n padding: 12,\n flex: 1,\n // paddingTop: top + 12,\n alignItems: \"stretch\",\n },\n itemContainer: {\n borderWidth: 1,\n borderColor: \"#323232\",\n borderRadius: 19,\n marginBottom: 12,\n overflow: \"hidden\",\n },\n itemPressable: {\n paddingHorizontal: INDENT,\n paddingVertical: 16,\n flexDirection: \"row\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n transitionDuration: \"100ms\",\n },\n filename: { color: \"white\", fontSize: 20, marginLeft: 12 },\n virtual: { textAlign: \"right\", color: \"white\" },\n image: { width: 24, height: 24, resizeMode: \"contain\" },\n});\n\nexport function getNavOptions(): NativeStackNavigationOptions {\n return {\n title: \"Index\",\n headerShown: true,\n presentation: \"modal\",\n animation: \"default\",\n headerLargeTitle: true,\n headerTitleStyle: {\n color: \"white\",\n },\n\n headerTintColor: \"white\",\n headerLargeTitleStyle: {\n color: \"white\",\n },\n headerStyle: {\n backgroundColor: \"black\",\n // @ts-expect-error: mistyped\n borderBottomColor: \"#323232\",\n },\n };\n}\n\nexport function Directory() {\n const routes = useSortedRoutes();\n const { bottom } = useSafeAreaInsets();\n const { width } = useWindowDimensions();\n return (\n <View style={styles.container}>\n <StatusBar barStyle=\"light-content\" />\n <View\n style={[\n styles.main,\n {\n minWidth: Math.min(960, width * 0.9),\n },\n ]}\n >\n <ScrollView\n contentInsetAdjustmentBehavior=\"automatic\"\n contentContainerStyle={[\n styles.scroll,\n {\n paddingBottom: bottom + 12,\n },\n ]}\n style={{ flex: 1 }}\n >\n {routes.map((child) => (\n <View key={child.contextKey} style={styles.itemContainer}>\n <FileItem route={child} />\n </View>\n ))}\n </ScrollView>\n </View>\n </View>\n );\n}\n\nfunction FileItem({\n route,\n level = 0,\n parents = [],\n}: {\n route: RouteNode;\n level?: number;\n parents?: string[];\n}) {\n const disabled = route.children.length > 0;\n\n const navigation = useNavigation();\n const href = React.useMemo(() => {\n return (\n \"/\" +\n [...parents, route.route]\n .map((v) => {\n // add an extra layer of entropy to the url for deep dynamic routes\n if (matchDeepDynamicRouteName(v)) {\n return v + \"/\" + Date.now();\n }\n // groups and index must be erased\n return !!matchFragmentName(v) || v === \"index\" ? \"\" : v;\n })\n .filter(Boolean)\n .join(\"/\")\n );\n }, [parents, route.route]);\n\n return (\n <>\n <Link\n href={href}\n onPress={() => {\n if (Platform.OS !== \"web\") {\n // Ensure the modal pops\n navigation.goBack();\n }\n }}\n // @ts-expect-error: disabled not on type\n disabled={disabled}\n asChild\n >\n <Pressable>\n {({ pressed, hovered }) => (\n <View\n style={[\n styles.itemPressable,\n {\n paddingLeft: INDENT + level * INDENT,\n backgroundColor: hovered\n ? \"rgba(255,255,255,0.1)\"\n : \"transparent\",\n },\n pressed && { backgroundColor: \"#323232\" },\n disabled && { opacity: 0.4 },\n ]}\n >\n <View style={{ flexDirection: \"row\", alignItems: \"center\" }}>\n {route.children.length ? <PkgIcon /> : <FileIcon />}\n <Text style={styles.filename}>{route.contextKey}</Text>\n </View>\n\n {!disabled && <ForwardIcon />}\n {route.generated && <Text style={styles.virtual}>Virtual</Text>}\n </View>\n )}\n </Pressable>\n </Link>\n {route.children.map((child, index) => (\n <FileItem\n key={child.contextKey}\n route={child}\n parents={[...parents, route.route]}\n level={level + 1}\n />\n ))}\n </>\n );\n}\n\nfunction FileIcon() {\n return (\n <Image\n style={styles.image}\n source={require(\"expo-router/assets/file.png\")}\n />\n );\n}\n\nfunction PkgIcon() {\n return (\n <Image\n style={styles.image}\n source={require(\"expo-router/assets/pkg.png\")}\n />\n );\n}\n\nfunction ForwardIcon() {\n return (\n <Image\n style={styles.image}\n source={require(\"expo-router/assets/forward.png\")}\n />\n );\n}\n"]}
1
+ {"version":3,"file":"Directory.js","sourceRoot":"","sources":["../../src/views/Directory.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Image, Pressable, StyleSheet, Text, View } from \"@bacons/react-views\";\nimport { useNavigation } from \"@react-navigation/native\";\nimport { NativeStackNavigationOptions } from \"@react-navigation/native-stack\";\nimport React from \"react\";\nimport {\n ScrollView,\n Platform,\n StatusBar,\n useWindowDimensions,\n} from \"react-native\";\nimport { useSafeAreaInsets } from \"react-native-safe-area-context\";\n\nimport { RouteNode } from \"../Route\";\nimport { useRoutesContext } from \"../context\";\nimport { Link } from \"../link/Link\";\nimport { matchDeepDynamicRouteName, matchFragmentName } from \"../matchers\";\n\nconst INDENT = 18;\n\nfunction useSortedRoutes() {\n const ctx = useRoutesContext();\n\n const routes = React.useMemo(\n () =>\n ctx\n .filter((route) => !route.internal)\n .sort((a, b) => {\n // Emulate vscode's sorting\n if (a.route < b.route) {\n return -1;\n }\n if (a.route > b.route) {\n return 1;\n }\n return 0;\n }),\n [ctx]\n );\n return routes;\n}\n\nconst styles = StyleSheet.create({\n container: {\n backgroundColor: \"black\",\n flex: 1,\n alignItems: \"stretch\",\n },\n main: {\n marginHorizontal: \"auto\",\n flex: 1,\n\n alignItems: \"stretch\",\n },\n scroll: {\n padding: 12,\n flex: 1,\n // paddingTop: top + 12,\n alignItems: \"stretch\",\n },\n itemContainer: {\n borderWidth: 1,\n borderColor: \"#323232\",\n borderRadius: 19,\n marginBottom: 12,\n overflow: \"hidden\",\n },\n itemPressable: {\n paddingHorizontal: INDENT,\n paddingVertical: 16,\n flexDirection: \"row\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n transitionDuration: \"100ms\",\n },\n filename: { color: \"white\", fontSize: 20, marginLeft: 12 },\n virtual: { textAlign: \"right\", color: \"white\" },\n image: { width: 24, height: 24, resizeMode: \"contain\" },\n});\n\nexport function getNavOptions(): NativeStackNavigationOptions {\n return {\n title: \"Index\",\n headerShown: true,\n presentation: \"modal\",\n animation: \"default\",\n headerLargeTitle: true,\n headerTitleStyle: {\n color: \"white\",\n },\n\n headerTintColor: \"white\",\n headerLargeTitleStyle: {\n color: \"white\",\n },\n headerStyle: {\n backgroundColor: \"black\",\n // @ts-expect-error: mistyped\n borderBottomColor: \"#323232\",\n },\n };\n}\n\nexport function Directory() {\n const routes = useSortedRoutes();\n const { bottom } = useSafeAreaInsets();\n const { width } = useWindowDimensions();\n return (\n <View style={styles.container}>\n <StatusBar barStyle=\"light-content\" />\n <View\n style={[\n styles.main,\n {\n minWidth: Math.min(960, width * 0.9),\n },\n ]}\n >\n <ScrollView\n contentInsetAdjustmentBehavior=\"automatic\"\n contentContainerStyle={[\n styles.scroll,\n {\n paddingBottom: bottom + 12,\n },\n ]}\n style={{ flex: 1 }}\n >\n {routes.map((child) => (\n <View key={child.contextKey} style={styles.itemContainer}>\n <FileItem route={child} />\n </View>\n ))}\n </ScrollView>\n </View>\n </View>\n );\n}\n\nfunction FileItem({\n route,\n level = 0,\n parents = [],\n}: {\n route: RouteNode;\n level?: number;\n parents?: string[];\n}) {\n const disabled = route.children.length > 0;\n\n const navigation = useNavigation();\n const href = React.useMemo(() => {\n return (\n \"/\" +\n [...parents, route.route]\n .map((v) => {\n // add an extra layer of entropy to the url for deep dynamic routes\n if (matchDeepDynamicRouteName(v)) {\n return v + \"/\" + Date.now();\n }\n // groups and index must be erased\n return !!matchFragmentName(v) || v === \"index\" ? \"\" : v;\n })\n .filter(Boolean)\n .join(\"/\")\n );\n }, [parents, route.route]);\n\n return (\n <>\n <Link\n href={href}\n onPress={() => {\n if (Platform.OS !== \"web\") {\n // Ensure the modal pops\n navigation.goBack();\n }\n }}\n // @ts-expect-error: disabled not on type\n disabled={disabled}\n asChild\n >\n <Pressable>\n {({ pressed, hovered }) => (\n <View\n style={[\n styles.itemPressable,\n {\n paddingLeft: INDENT + level * INDENT,\n backgroundColor: hovered\n ? \"rgba(255,255,255,0.1)\"\n : \"transparent\",\n },\n pressed && { backgroundColor: \"#323232\" },\n disabled && { opacity: 0.4 },\n ]}\n >\n <View style={{ flexDirection: \"row\", alignItems: \"center\" }}>\n {route.children.length ? <PkgIcon /> : <FileIcon />}\n <Text style={styles.filename}>{route.contextKey}</Text>\n </View>\n\n {!disabled && <ForwardIcon />}\n {route.generated && <Text style={styles.virtual}>Virtual</Text>}\n </View>\n )}\n </Pressable>\n </Link>\n {route.children.map((child, index) => (\n <FileItem\n key={child.contextKey}\n route={child}\n parents={[...parents, route.route]}\n level={level + 1}\n />\n ))}\n </>\n );\n}\n\nfunction FileIcon() {\n return (\n <Image\n style={styles.image}\n source={require(\"expo-router/assets/file.png\")}\n />\n );\n}\n\nfunction PkgIcon() {\n return (\n <Image\n style={styles.image}\n source={require(\"expo-router/assets/pkg.png\")}\n />\n );\n}\n\nfunction ForwardIcon() {\n return (\n <Image\n style={styles.image}\n source={require(\"expo-router/assets/forward.png\")}\n />\n );\n}\n"]}
@@ -2,7 +2,7 @@ import { Pressable, StyleSheet, Text, View } from "@bacons/react-views";
2
2
  import React from "react";
3
3
  import { Platform, ScrollView, TouchableOpacity } from "react-native";
4
4
  import { SafeAreaView } from "react-native-safe-area-context";
5
- import { Link } from "./Link";
5
+ import { Link } from "../link/Link";
6
6
  export function ErrorBoundary({ error, retry }) {
7
7
  return (React.createElement(View, { accessibilityRole: "main", style: [styles.container] },
8
8
  React.createElement(SafeAreaView, { style: { flex: 1, maxWidth: 720, marginHorizontal: "auto" } },
@@ -1 +1 @@
1
- {"version":3,"file":"ErrorBoundary.js","sourceRoot":"","sources":["../../src/views/ErrorBoundary.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Pressable, StyleSheet, Text, View } from \"@bacons/react-views\";\nimport React from \"react\";\nimport { Platform, ScrollView, TouchableOpacity } from \"react-native\";\nimport { SafeAreaView } from \"react-native-safe-area-context\";\n\nimport { Link } from \"./Link\";\nimport { ErrorBoundaryProps } from \"./Try\";\n\nexport function ErrorBoundary({ error, retry }: ErrorBoundaryProps) {\n return (\n <View accessibilityRole=\"main\" style={[styles.container]}>\n <SafeAreaView\n style={{ flex: 1, maxWidth: 720, marginHorizontal: \"auto\" }}\n >\n <View\n style={{\n marginBottom: 12,\n flexDirection: \"row\",\n flexWrap: \"wrap\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n }}\n >\n <Text\n accessibilityRole=\"header\"\n accessibilityLevel={1}\n style={styles.title}\n >\n Something went wrong\n </Text>\n <View style={{ flexDirection: \"row\", alignItems: \"center\" }}>\n <Pressable>\n {({ hovered }) => (\n <TouchableOpacity onPress={retry}>\n <View\n style={[\n {\n transitionDuration: \"100ms\",\n paddingVertical: 12,\n paddingHorizontal: 24,\n borderColor: \"white\",\n borderWidth: 2,\n marginLeft: 8,\n },\n hovered && { backgroundColor: \"white\" },\n ]}\n >\n <Text\n style={[\n styles.buttonText,\n {\n transitionDuration: \"100ms\",\n color: hovered ? \"black\" : \"white\",\n },\n ]}\n >\n Retry\n </Text>\n </View>\n </TouchableOpacity>\n )}\n </Pressable>\n </View>\n </View>\n\n <StackTrace error={error} />\n {process.env.NODE_ENV === \"development\" && (\n <Link href=\"/__index\" style={styles.link}>\n Sitemap\n </Link>\n )}\n </SafeAreaView>\n </View>\n );\n}\n\nfunction StackTrace({ error }: { error: Error }) {\n return (\n <ScrollView\n style={{\n marginVertical: 8,\n borderColor: \"rgba(255,255,255,0.5)\",\n borderWidth: 1,\n padding: 12,\n }}\n >\n <Text style={[styles.code, { color: \"white\" }]}>{error.stack}</Text>\n </ScrollView>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n backgroundColor: \"black\",\n padding: 24,\n alignItems: \"stretch\",\n justifyContent: \"center\",\n },\n title: {\n color: \"white\",\n fontSize: 36,\n\n // textAlign: \"center\",\n fontWeight: \"bold\",\n },\n buttonText: {\n fontSize: 18,\n fontWeight: \"bold\",\n color: \"black\",\n },\n code: {\n fontFamily: Platform.select({\n default: \"Courier\",\n ios: \"Courier New\",\n android: \"monospace\",\n }),\n fontWeight: \"500\",\n },\n subtitle: {\n color: \"white\",\n fontSize: 14,\n marginBottom: 12,\n // textAlign: \"center\",\n },\n link: {\n color: \"rgba(255,255,255,0.4)\",\n textDecorationStyle: \"solid\",\n textDecorationLine: \"underline\",\n fontSize: 14,\n textAlign: \"center\",\n },\n});\n"]}
1
+ {"version":3,"file":"ErrorBoundary.js","sourceRoot":"","sources":["../../src/views/ErrorBoundary.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Pressable, StyleSheet, Text, View } from \"@bacons/react-views\";\nimport React from \"react\";\nimport { Platform, ScrollView, TouchableOpacity } from \"react-native\";\nimport { SafeAreaView } from \"react-native-safe-area-context\";\n\nimport { Link } from \"../link/Link\";\nimport { ErrorBoundaryProps } from \"./Try\";\n\nexport function ErrorBoundary({ error, retry }: ErrorBoundaryProps) {\n return (\n <View accessibilityRole=\"main\" style={[styles.container]}>\n <SafeAreaView\n style={{ flex: 1, maxWidth: 720, marginHorizontal: \"auto\" }}\n >\n <View\n style={{\n marginBottom: 12,\n flexDirection: \"row\",\n flexWrap: \"wrap\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n }}\n >\n <Text\n accessibilityRole=\"header\"\n accessibilityLevel={1}\n style={styles.title}\n >\n Something went wrong\n </Text>\n <View style={{ flexDirection: \"row\", alignItems: \"center\" }}>\n <Pressable>\n {({ hovered }) => (\n <TouchableOpacity onPress={retry}>\n <View\n style={[\n {\n transitionDuration: \"100ms\",\n paddingVertical: 12,\n paddingHorizontal: 24,\n borderColor: \"white\",\n borderWidth: 2,\n marginLeft: 8,\n },\n hovered && { backgroundColor: \"white\" },\n ]}\n >\n <Text\n style={[\n styles.buttonText,\n {\n transitionDuration: \"100ms\",\n color: hovered ? \"black\" : \"white\",\n },\n ]}\n >\n Retry\n </Text>\n </View>\n </TouchableOpacity>\n )}\n </Pressable>\n </View>\n </View>\n\n <StackTrace error={error} />\n {process.env.NODE_ENV === \"development\" && (\n <Link href=\"/__index\" style={styles.link}>\n Sitemap\n </Link>\n )}\n </SafeAreaView>\n </View>\n );\n}\n\nfunction StackTrace({ error }: { error: Error }) {\n return (\n <ScrollView\n style={{\n marginVertical: 8,\n borderColor: \"rgba(255,255,255,0.5)\",\n borderWidth: 1,\n padding: 12,\n }}\n >\n <Text style={[styles.code, { color: \"white\" }]}>{error.stack}</Text>\n </ScrollView>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n backgroundColor: \"black\",\n padding: 24,\n alignItems: \"stretch\",\n justifyContent: \"center\",\n },\n title: {\n color: \"white\",\n fontSize: 36,\n\n // textAlign: \"center\",\n fontWeight: \"bold\",\n },\n buttonText: {\n fontSize: 18,\n fontWeight: \"bold\",\n color: \"black\",\n },\n code: {\n fontFamily: Platform.select({\n default: \"Courier\",\n ios: \"Courier New\",\n android: \"monospace\",\n }),\n fontWeight: \"500\",\n },\n subtitle: {\n color: \"white\",\n fontSize: 14,\n marginBottom: 12,\n // textAlign: \"center\",\n },\n link: {\n color: \"rgba(255,255,255,0.4)\",\n textDecorationStyle: \"solid\",\n textDecorationLine: \"underline\",\n fontSize: 14,\n textAlign: \"center\",\n },\n});\n"]}
@@ -2,7 +2,10 @@ import { RouterFactory, useNavigationBuilder } from "@react-navigation/native";
2
2
  import * as React from "react";
3
3
  export declare const LayoutContext: React.Context<{
4
4
  contextKey: string;
5
+ /** Normalized path representing the selected route `/[id]?id=normal` -> `/normal` */
5
6
  pathname: string;
7
+ /** Normalized string representing the selected state `/(group)/any/[id]` */
8
+ statePath: string;
6
9
  state: any;
7
10
  navigation: any;
8
11
  descriptors: any;
@@ -22,7 +25,10 @@ export declare namespace Layout {
22
25
  }
23
26
  export declare function useLayoutContext(): {
24
27
  contextKey: string;
28
+ /** Normalized path representing the selected route `/[id]?id=normal` -> `/normal` */
25
29
  pathname: string;
30
+ /** Normalized string representing the selected state `/(group)/any/[id]` */
31
+ statePath: string;
26
32
  state: any;
27
33
  navigation: any;
28
34
  descriptors: any;
@@ -1 +1 @@
1
- {"version":3,"file":"Layout.d.ts","sourceRoot":"","sources":["../../src/views/Layout.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAEb,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,eAAO,MAAM,aAAa;gBACZ,MAAM;cACR,MAAM;WACT,GAAG;gBACE,GAAG;iBACF,GAAG;YACR,cAAc,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;SACvB,CAAC;AAMhB,oBAAY,WAAW,GAAG;IACxB,gBAAgB,CAAC,EAAE,UAAU,CAC3B,OAAO,oBAAoB,CAC5B,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;IACzB,aAAa,CAAC,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;IAC5E,QAAQ,CAAC,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAClE,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC;CACrD,CAAC;AAEF,+DAA+D;AAC/D,wBAAgB,MAAM,CAAC,EACrB,gBAAgB,EAChB,aAAa,EACb,QAAQ,EACR,MAAoB,GACrB,EAAE,WAAW,eA2Bb;yBAhCe,MAAM;;;;AAkCtB,wBAAgB,gBAAgB;;;;;;;EAM/B;AAED,wBAAgB,QAAQ,QAcvB;AAED,8CAA8C;AAC9C,wBAAgB,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,eAc5D;AAED,wBAAgB,eAAe,QAE9B;AAED,wBAAgB,aAAa,gBAM5B"}
1
+ {"version":3,"file":"Layout.d.ts","sourceRoot":"","sources":["../../src/views/Layout.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,aAAa,EAEb,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,eAAO,MAAM,aAAa;gBACZ,MAAM;IAClB,qFAAqF;cAC3E,MAAM;IAChB,4EAA4E;eACjE,MAAM;WACV,GAAG;gBACE,GAAG;iBACF,GAAG;YACR,cAAc,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;SACvB,CAAC;AAMhB,oBAAY,WAAW,GAAG;IACxB,gBAAgB,CAAC,EAAE,UAAU,CAC3B,OAAO,oBAAoB,CAC5B,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;IACzB,aAAa,CAAC,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;IAC5E,QAAQ,CAAC,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAClE,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC;CACrD,CAAC;AAEF,+DAA+D;AAC/D,wBAAgB,MAAM,CAAC,EACrB,gBAAgB,EAChB,aAAa,EACb,QAAQ,EACR,MAAoB,GACrB,EAAE,WAAW,eA+Bb;yBApCe,MAAM;;;;AAwFtB,wBAAgB,gBAAgB;;IAhH9B,qFAAqF;;IAErF,4EAA4E;;;;;;EAoH7E;AAED,wBAAgB,QAAQ,QAcvB;AAED,8CAA8C;AAC9C,wBAAgB,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,eAc5D;AAED,wBAAgB,eAAe,QAE9B;AAED,wBAAgB,aAAa,gBAM5B"}
@@ -1,6 +1,9 @@
1
- import { StackRouter, useNavigationBuilder, } from "@react-navigation/native";
1
+ import { LinkingContext, StackRouter, useNavigationBuilder, } from "@react-navigation/native";
2
2
  import * as React from "react";
3
3
  import { useContextKey } from "../Route";
4
+ import getPathFromState from "../fork/getPathFromState";
5
+ import { resolveHref } from "../link/href";
6
+ import { matchFragmentName } from "../matchers";
4
7
  import { useScreens } from "../useScreens";
5
8
  // TODO: This might already exist upstream, maybe something like `useCurrentRender` ?
6
9
  export const LayoutContext = React.createContext(null);
@@ -11,14 +14,18 @@ if (process.env.NODE_ENV !== "production") {
11
14
  export function Layout({ initialRouteName, screenOptions, children, router = StackRouter, }) {
12
15
  const contextKey = useContextKey();
13
16
  const screens = useScreens();
17
+ const linking = React.useContext(LinkingContext);
14
18
  const { state, navigation, descriptors, NavigationContent } = useNavigationBuilder(router, {
15
19
  children: screens,
16
20
  screenOptions,
17
21
  initialRouteName,
18
22
  });
19
- const selected = state?.routes[state.index]?.name;
23
+ const statePath = linking.options?.getPathFromState
24
+ ? linking.options.getPathFromState(state)
25
+ : getPathFromState(state);
20
26
  return (React.createElement(LayoutContext.Provider, { value: {
21
- pathname: selected ?? "",
27
+ pathname: pathnameFromStatePath(statePath),
28
+ statePath: getNormalizedStatePath(statePath),
22
29
  contextKey,
23
30
  state,
24
31
  navigation,
@@ -27,6 +34,48 @@ export function Layout({ initialRouteName, screenOptions, children, router = Sta
27
34
  } },
28
35
  React.createElement(NavigationContent, null, children)));
29
36
  }
37
+ function getNormalizedStatePath(statePath) {
38
+ const pathname = "/" +
39
+ (statePath
40
+ .split("/")
41
+ .map((value) => decodeURIComponent(value))
42
+ .filter(Boolean)
43
+ .join("/") || "");
44
+ return pathname.split("?")[0];
45
+ }
46
+ function pathnameFromStatePath(statePath) {
47
+ const pathname = "/" +
48
+ (statePath
49
+ .split("/")
50
+ .map((value) => {
51
+ const segment = decodeURIComponent(value);
52
+ if (matchFragmentName(segment) != null || segment === "index") {
53
+ return null;
54
+ }
55
+ return segment;
56
+ })
57
+ .filter(Boolean)
58
+ .join("/") || "");
59
+ const components = pathname.split("?");
60
+ return resolveHref({
61
+ pathname: components[0],
62
+ // TODO: This is not efficient, we should generate based on the state instead
63
+ // of converting to string then back to object
64
+ query: parseQueryString(components[1] ?? ""),
65
+ });
66
+ }
67
+ function parseQueryString(val) {
68
+ if (!val) {
69
+ return {};
70
+ }
71
+ const query = {};
72
+ const a = val.split("&");
73
+ for (let i = 0; i < a.length; i++) {
74
+ const b = a[i].split("=");
75
+ query[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || "");
76
+ }
77
+ return query;
78
+ }
30
79
  export function useLayoutContext() {
31
80
  const context = React.useContext(LayoutContext);
32
81
  if (!context) {
@@ -1 +1 @@
1
- {"version":3,"file":"Layout.js","sourceRoot":"","sources":["../../src/views/Layout.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n RouterFactory,\n StackRouter,\n useNavigationBuilder,\n} from \"@react-navigation/native\";\nimport * as React from \"react\";\n\nimport { useContextKey } from \"../Route\";\nimport { useScreens } from \"../useScreens\";\n\n// TODO: This might already exist upstream, maybe something like `useCurrentRender` ?\nexport const LayoutContext = React.createContext<{\n contextKey: string;\n pathname: string;\n state: any;\n navigation: any;\n descriptors: any;\n router: RouterFactory<any, any, any>;\n} | null>(null);\n\nif (process.env.NODE_ENV !== \"production\") {\n LayoutContext.displayName = \"LayoutContext\";\n}\n\nexport type LayoutProps = {\n initialRouteName?: Parameters<\n typeof useNavigationBuilder\n >[1][\"initialRouteName\"];\n screenOptions?: Parameters<typeof useNavigationBuilder>[1][\"screenOptions\"];\n children?: Parameters<typeof useNavigationBuilder>[1][\"children\"];\n router?: Parameters<typeof useNavigationBuilder>[0];\n};\n\n/** An unstyled custom navigator. Good for basic web layouts */\nexport function Layout({\n initialRouteName,\n screenOptions,\n children,\n router = StackRouter,\n}: LayoutProps) {\n const contextKey = useContextKey();\n const screens = useScreens();\n\n const { state, navigation, descriptors, NavigationContent } =\n useNavigationBuilder(router, {\n children: screens,\n screenOptions,\n initialRouteName,\n });\n\n const selected = state?.routes[state.index]?.name;\n\n return (\n <LayoutContext.Provider\n value={{\n pathname: selected ?? \"\",\n contextKey,\n state,\n navigation,\n descriptors,\n router,\n }}\n >\n <NavigationContent>{children}</NavigationContent>\n </LayoutContext.Provider>\n );\n}\n\nexport function useLayoutContext() {\n const context = React.useContext(LayoutContext);\n if (!context) {\n throw new Error(\"useLayoutContext must be used within a <Layout />\");\n }\n return context;\n}\n\nexport function useChild() {\n const context = useLayoutContext();\n\n const { state, descriptors } = context;\n\n const current = state.routes.find((route, i) => {\n return state.index === i;\n });\n\n if (!current) {\n return null;\n }\n\n return descriptors[current.key]?.render() ?? null;\n}\n\n/** Renders the currently selected content. */\nexport function Children(props: Omit<LayoutProps, \"children\">) {\n const contextKey = useContextKey();\n const context = React.useContext(LayoutContext);\n // Ensure the context is for the current contextKey\n if (context?.contextKey !== contextKey) {\n // Qualify the content and re-export.\n return (\n <Layout {...props}>\n <TrustedChildren />\n </Layout>\n );\n }\n\n return <TrustedChildren />;\n}\n\nexport function TrustedChildren() {\n return useChild();\n}\n\nexport function DefaultLayout() {\n return (\n <Layout>\n <TrustedChildren />\n </Layout>\n );\n}\n\nLayout.Children = Children;\nLayout.useContext = useLayoutContext;\n"]}
1
+ {"version":3,"file":"Layout.js","sourceRoot":"","sources":["../../src/views/Layout.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n LinkingContext,\n RouterFactory,\n StackRouter,\n useNavigationBuilder,\n} from \"@react-navigation/native\";\nimport * as React from \"react\";\n\nimport { useContextKey } from \"../Route\";\nimport getPathFromState from \"../fork/getPathFromState\";\nimport { resolveHref } from \"../link/href\";\nimport { matchFragmentName } from \"../matchers\";\nimport { useScreens } from \"../useScreens\";\n\n// TODO: This might already exist upstream, maybe something like `useCurrentRender` ?\nexport const LayoutContext = React.createContext<{\n contextKey: string;\n /** Normalized path representing the selected route `/[id]?id=normal` -> `/normal` */\n pathname: string;\n /** Normalized string representing the selected state `/(group)/any/[id]` */\n statePath: string;\n state: any;\n navigation: any;\n descriptors: any;\n router: RouterFactory<any, any, any>;\n} | null>(null);\n\nif (process.env.NODE_ENV !== \"production\") {\n LayoutContext.displayName = \"LayoutContext\";\n}\n\nexport type LayoutProps = {\n initialRouteName?: Parameters<\n typeof useNavigationBuilder\n >[1][\"initialRouteName\"];\n screenOptions?: Parameters<typeof useNavigationBuilder>[1][\"screenOptions\"];\n children?: Parameters<typeof useNavigationBuilder>[1][\"children\"];\n router?: Parameters<typeof useNavigationBuilder>[0];\n};\n\n/** An unstyled custom navigator. Good for basic web layouts */\nexport function Layout({\n initialRouteName,\n screenOptions,\n children,\n router = StackRouter,\n}: LayoutProps) {\n const contextKey = useContextKey();\n const screens = useScreens();\n const linking = React.useContext(LinkingContext);\n\n const { state, navigation, descriptors, NavigationContent } =\n useNavigationBuilder(router, {\n children: screens,\n screenOptions,\n initialRouteName,\n });\n\n const statePath = linking.options?.getPathFromState\n ? linking.options.getPathFromState(state)\n : getPathFromState(state);\n\n return (\n <LayoutContext.Provider\n value={{\n pathname: pathnameFromStatePath(statePath),\n statePath: getNormalizedStatePath(statePath),\n contextKey,\n state,\n navigation,\n descriptors,\n router,\n }}\n >\n <NavigationContent>{children}</NavigationContent>\n </LayoutContext.Provider>\n );\n}\n\nfunction getNormalizedStatePath(statePath: string) {\n const pathname =\n \"/\" +\n (statePath\n .split(\"/\")\n .map((value) => decodeURIComponent(value))\n .filter(Boolean)\n .join(\"/\") || \"\");\n\n return pathname.split(\"?\")![0];\n}\n\nfunction pathnameFromStatePath(statePath: string) {\n const pathname =\n \"/\" +\n (statePath\n .split(\"/\")\n .map((value) => {\n const segment = decodeURIComponent(value);\n if (matchFragmentName(segment) != null || segment === \"index\") {\n return null;\n }\n return segment;\n })\n .filter(Boolean)\n .join(\"/\") || \"\");\n\n const components = pathname.split(\"?\");\n\n return resolveHref({\n pathname: components[0],\n // TODO: This is not efficient, we should generate based on the state instead\n // of converting to string then back to object\n query: parseQueryString(components[1] ?? \"\"),\n });\n}\n\nfunction parseQueryString(val: string) {\n if (!val) {\n return {};\n }\n const query = {};\n const a = val.split(\"&\");\n for (let i = 0; i < a.length; i++) {\n const b = a[i].split(\"=\");\n query[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || \"\");\n }\n return query;\n}\n\nexport function useLayoutContext() {\n const context = React.useContext(LayoutContext);\n if (!context) {\n throw new Error(\"useLayoutContext must be used within a <Layout />\");\n }\n return context;\n}\n\nexport function useChild() {\n const context = useLayoutContext();\n\n const { state, descriptors } = context;\n\n const current = state.routes.find((route, i) => {\n return state.index === i;\n });\n\n if (!current) {\n return null;\n }\n\n return descriptors[current.key]?.render() ?? null;\n}\n\n/** Renders the currently selected content. */\nexport function Children(props: Omit<LayoutProps, \"children\">) {\n const contextKey = useContextKey();\n const context = React.useContext(LayoutContext);\n // Ensure the context is for the current contextKey\n if (context?.contextKey !== contextKey) {\n // Qualify the content and re-export.\n return (\n <Layout {...props}>\n <TrustedChildren />\n </Layout>\n );\n }\n\n return <TrustedChildren />;\n}\n\nexport function TrustedChildren() {\n return useChild();\n}\n\nexport function DefaultLayout() {\n return (\n <Layout>\n <TrustedChildren />\n </Layout>\n );\n}\n\nLayout.Children = Children;\nLayout.useContext = useLayoutContext;\n"]}
@@ -1,7 +1,7 @@
1
1
  import { StyleSheet, Text, View } from "@bacons/react-views";
2
2
  import { createURL } from "expo-linking";
3
3
  import React, { forwardRef } from "react";
4
- import { Link } from "./Link";
4
+ import { Link } from "../link/Link";
5
5
  /** Default screen for unmatched routes. */
6
6
  export const Unmatched = forwardRef((props, ref) => {
7
7
  const url = createURL("");
@@ -1 +1 @@
1
- {"version":3,"file":"Unmatched.js","sourceRoot":"","sources":["../../src/views/Unmatched.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9B,2CAA2C;AAC3C,MAAM,CAAC,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACjD,MAAM,GAAG,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;IAC1B,OAAO;IACL,aAAa;IACb,oBAAC,IAAI,IAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,SAAS;QACrC,oBAAC,IAAI,IACH,iBAAiB,EAAC,QAAQ,EAC1B,kBAAkB,EAAE,CAAC,EACrB,KAAK,EAAE,MAAM,CAAC,KAAK,sBAGd;QACP,oBAAC,IAAI,IACH,iBAAiB,EAAC,QAAQ,EAC1B,kBAAkB,EAAE,CAAC,EACrB,KAAK,EAAE,MAAM,CAAC,QAAQ;;YAEG,GAAG;YAC5B,oBAAC,IAAI,IAAC,IAAI,EAAC,GAAG,EAAC,KAAK,EAAE,MAAM,CAAC,IAAI,eAE1B,CACF;QAEP,oBAAC,IAAI,IAAC,IAAI,EAAC,GAAG,EAAC,KAAK,EAAE,MAAM,CAAC,IAAI,IAC9B,GAAG,CACC;QAEN,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,IAAI,CACzC,oBAAC,IAAI,IAAC,IAAI,EAAC,UAAU,EAAC,KAAK,EAAE,MAAM,CAAC,IAAI,cAEjC,CACR,CACI,CACR,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IAC/B,SAAS,EAAE;QACT,IAAI,EAAE,CAAC;QACP,eAAe,EAAE,OAAO;QACxB,OAAO,EAAE,EAAE;QACX,UAAU,EAAE,QAAQ;QACpB,cAAc,EAAE,QAAQ;KACzB;IACD,KAAK,EAAE;QACL,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,EAAE;QACZ,aAAa,EAAE,EAAE;QACjB,YAAY,EAAE,EAAE;QAChB,iBAAiB,EAAE,SAAS;QAC5B,iBAAiB,EAAE,CAAC;QACpB,SAAS,EAAE,QAAQ;QACnB,UAAU,EAAE,MAAM;KACnB;IACD,QAAQ,EAAE;QACR,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,EAAE;QACZ,YAAY,EAAE,EAAE;QAChB,SAAS,EAAE,QAAQ;KACpB;IACD,IAAI,EAAE,EAAE,KAAK,EAAE,uBAAuB,EAAE,SAAS,EAAE,QAAQ,EAAE;CAC9D,CAAC,CAAC","sourcesContent":["import { StyleSheet, Text, View } from \"@bacons/react-views\";\nimport { createURL } from \"expo-linking\";\nimport React, { forwardRef } from \"react\";\n\nimport { Link } from \"./Link\";\n\n/** Default screen for unmatched routes. */\nexport const Unmatched = forwardRef((props, ref) => {\n const url = createURL(\"\");\n return (\n // @ts-ignore\n <View ref={ref} style={styles.container}>\n <Text\n accessibilityRole=\"header\"\n accessibilityLevel={1}\n style={styles.title}\n >\n Unmatched Route\n </Text>\n <Text\n accessibilityRole=\"header\"\n accessibilityLevel={2}\n style={styles.subtitle}\n >\n Page could not be found.{\" \"}\n <Link href=\"/\" style={styles.link}>\n Go back.\n </Link>\n </Text>\n\n <Link href=\"/\" style={styles.link}>\n {url}\n </Link>\n\n {process.env.NODE_ENV === \"development\" && (\n <Link href=\"/__index\" style={styles.link}>\n Sitemap\n </Link>\n )}\n </View>\n );\n});\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n backgroundColor: \"black\",\n padding: 24,\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n title: {\n color: \"white\",\n fontSize: 36,\n paddingBottom: 12,\n marginBottom: 12,\n borderBottomColor: \"#323232\",\n borderBottomWidth: 1,\n textAlign: \"center\",\n fontWeight: \"bold\",\n },\n subtitle: {\n color: \"white\",\n fontSize: 18,\n marginBottom: 12,\n textAlign: \"center\",\n },\n link: { color: \"rgba(255,255,255,0.4)\", textAlign: \"center\" },\n});\n"]}
1
+ {"version":3,"file":"Unmatched.js","sourceRoot":"","sources":["../../src/views/Unmatched.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC,2CAA2C;AAC3C,MAAM,CAAC,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACjD,MAAM,GAAG,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;IAC1B,OAAO;IACL,aAAa;IACb,oBAAC,IAAI,IAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,SAAS;QACrC,oBAAC,IAAI,IACH,iBAAiB,EAAC,QAAQ,EAC1B,kBAAkB,EAAE,CAAC,EACrB,KAAK,EAAE,MAAM,CAAC,KAAK,sBAGd;QACP,oBAAC,IAAI,IACH,iBAAiB,EAAC,QAAQ,EAC1B,kBAAkB,EAAE,CAAC,EACrB,KAAK,EAAE,MAAM,CAAC,QAAQ;;YAEG,GAAG;YAC5B,oBAAC,IAAI,IAAC,IAAI,EAAC,GAAG,EAAC,KAAK,EAAE,MAAM,CAAC,IAAI,eAE1B,CACF;QAEP,oBAAC,IAAI,IAAC,IAAI,EAAC,GAAG,EAAC,KAAK,EAAE,MAAM,CAAC,IAAI,IAC9B,GAAG,CACC;QAEN,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,IAAI,CACzC,oBAAC,IAAI,IAAC,IAAI,EAAC,UAAU,EAAC,KAAK,EAAE,MAAM,CAAC,IAAI,cAEjC,CACR,CACI,CACR,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IAC/B,SAAS,EAAE;QACT,IAAI,EAAE,CAAC;QACP,eAAe,EAAE,OAAO;QACxB,OAAO,EAAE,EAAE;QACX,UAAU,EAAE,QAAQ;QACpB,cAAc,EAAE,QAAQ;KACzB;IACD,KAAK,EAAE;QACL,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,EAAE;QACZ,aAAa,EAAE,EAAE;QACjB,YAAY,EAAE,EAAE;QAChB,iBAAiB,EAAE,SAAS;QAC5B,iBAAiB,EAAE,CAAC;QACpB,SAAS,EAAE,QAAQ;QACnB,UAAU,EAAE,MAAM;KACnB;IACD,QAAQ,EAAE;QACR,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,EAAE;QACZ,YAAY,EAAE,EAAE;QAChB,SAAS,EAAE,QAAQ;KACpB;IACD,IAAI,EAAE,EAAE,KAAK,EAAE,uBAAuB,EAAE,SAAS,EAAE,QAAQ,EAAE;CAC9D,CAAC,CAAC","sourcesContent":["import { StyleSheet, Text, View } from \"@bacons/react-views\";\nimport { createURL } from \"expo-linking\";\nimport React, { forwardRef } from \"react\";\n\nimport { Link } from \"../link/Link\";\n\n/** Default screen for unmatched routes. */\nexport const Unmatched = forwardRef((props, ref) => {\n const url = createURL(\"\");\n return (\n // @ts-ignore\n <View ref={ref} style={styles.container}>\n <Text\n accessibilityRole=\"header\"\n accessibilityLevel={1}\n style={styles.title}\n >\n Unmatched Route\n </Text>\n <Text\n accessibilityRole=\"header\"\n accessibilityLevel={2}\n style={styles.subtitle}\n >\n Page could not be found.{\" \"}\n <Link href=\"/\" style={styles.link}>\n Go back.\n </Link>\n </Text>\n\n <Link href=\"/\" style={styles.link}>\n {url}\n </Link>\n\n {process.env.NODE_ENV === \"development\" && (\n <Link href=\"/__index\" style={styles.link}>\n Sitemap\n </Link>\n )}\n </View>\n );\n});\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n backgroundColor: \"black\",\n padding: 24,\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n title: {\n color: \"white\",\n fontSize: 36,\n paddingBottom: 12,\n marginBottom: 12,\n borderBottomColor: \"#323232\",\n borderBottomWidth: 1,\n textAlign: \"center\",\n fontWeight: \"bold\",\n },\n subtitle: {\n color: \"white\",\n fontSize: 18,\n marginBottom: 12,\n textAlign: \"center\",\n },\n link: { color: \"rgba(255,255,255,0.4)\", textAlign: \"center\" },\n});\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-router",
3
- "version": "0.0.20",
3
+ "version": "0.0.22",
4
4
  "main": "build/index.js",
5
5
  "files": [
6
6
  "entry.js",
@@ -1 +0,0 @@
1
- {"version":3,"file":"useLinkToPath.d.ts","sourceRoot":"","sources":["../../src/fork/useLinkToPath.ts"],"names":[],"mappings":"AASA,wBAAgB,aAAa,SAKpB,MAAM,UAAU,MAAM,UA6C9B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"linking.d.ts","sourceRoot":"","sources":["../src/linking.ts"],"names":[],"mappings":"AAGA,OAAO,gBAAgB,MAAM,yBAAyB,CAAC;AACvD,OAAO,gBAAgB,MAAM,yBAAyB,CAAC;AAOvD,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CA+BrD;AAID,wBAAgB,UAAU,WAKzB;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,cAiC/D;AAED,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"linking.js","sourceRoot":"","sources":["../src/linking.ts"],"names":[],"mappings":"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","sourcesContent":["import Constants, { ExecutionEnvironment } from \"expo-constants\";\nimport * as Linking from \"expo-linking\";\n\nimport getPathFromState from \"./fork/getPathFromState\";\nimport getStateFromPath from \"./fork/getStateFromPath\";\n\n// A custom getInitialURL is used on native to ensure the app always starts at\n// the root path if it's launched from something other than a deep link.\n// This helps keep the native functionality working like the web functionality.\n// For example, if you had a root navigator where the first screen was `/settings` and the second was `/index`\n// then `/index` would be used on web and `/settings` would be used on native.\nexport async function getInitialURL(): Promise<string> {\n const url = await Promise.race<string>([\n (async () => {\n const url = await Linking.getInitialURL();\n\n // NOTE(EvanBacon): This could probably be wrapped with the development boundary\n // since Expo Go is mostly just used in development.\n\n // Expo Go is weird and requires the root path to be `/--/`\n if (\n url &&\n Constants.executionEnvironment === ExecutionEnvironment.StoreClient\n ) {\n const parsed = Linking.parse(url);\n // If the URL is defined (default in Expo Go dev apps) and the URL has no path:\n // `exp://192.168.87.39:19000/` then use the default `exp://192.168.87.39:19000/--/`\n if (parsed.path === null || [\"\", \"/\"].includes(parsed.path)) {\n return getRootURL();\n }\n }\n // The path will be nullish in bare apps when the app is launched from the home screen.\n // TODO(EvanBacon): define some policy around notifications.\n return url ?? getRootURL();\n })(),\n new Promise<string>((resolve) =>\n // Timeout in 150ms if `getInitialState` doesn't resolve\n // Workaround for https://github.com/facebook/react-native/issues/25675\n setTimeout(() => resolve(getRootURL()), 150)\n ),\n ]);\n return url;\n}\n\nlet _rootURL: string | undefined;\n\nexport function getRootURL() {\n if (_rootURL === undefined) {\n _rootURL = Linking.createURL(\"/\");\n }\n return _rootURL;\n}\n\nexport function addEventListener(listener: (url: string) => void) {\n let callback: (({ url }: { url: string }) => void) | undefined = undefined;\n\n if (Constants.executionEnvironment === ExecutionEnvironment.StoreClient) {\n // This extra work is only done in the Expo Go app.\n callback = ({ url }: { url: string }) => {\n const parsed = Linking.parse(url);\n // If the URL is defined (default in Expo Go dev apps) and the URL has no path:\n // `exp://192.168.87.39:19000/` then use the default `exp://192.168.87.39:19000/--/`\n if (parsed.path === null || [\"\", \"/\"].includes(parsed.path)) {\n listener(getRootURL());\n } else {\n listener(url);\n }\n };\n } else {\n callback = ({ url }: { url: string }) => listener(url);\n }\n const subscription = Linking.addEventListener(\"url\", callback) as\n | { remove(): void }\n | undefined;\n\n // Storing this in a local variable stops Jest from complaining about import after teardown\n const removeEventListener = Linking.removeEventListener?.bind(Linking);\n\n return () => {\n // https://github.com/facebook/react-native/commit/6d1aca806cee86ad76de771ed3a1cc62982ebcd7\n if (subscription?.remove) {\n subscription.remove();\n } else {\n removeEventListener?.(\"url\", callback);\n }\n };\n}\n\nexport { getStateFromPath, getPathFromState };\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"useLink.d.ts","sourceRoot":"","sources":["../src/useLink.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGjD,wBAAgB,OAAO,IAAI;IACzB,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC3B,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC9B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,OAAO,WAAW,CAAC;CAC3B,CAqBA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"useLink.js","sourceRoot":"","sources":["../src/useLink.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAQ,WAAW,EAAE,MAAM,cAAc,CAAC;AAEjD,4EAA4E;AAC5E,MAAM,UAAU,OAAO;IAMrB,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,OAAO,OAAO,CACZ,GAAG,EAAE,CAAC,CAAC;QACL,IAAI,EAAE,CAAC,GAAS,EAAE,EAAE;YAClB,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;YAC9B,MAAM,CAAC,IAAI,CAAC,CAAC;QACf,CAAC;QACD,OAAO,EAAE,CAAC,GAAS,EAAE,EAAE;YACrB,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;YAC9B,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC1B,CAAC;QACD,IAAI,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE;QAChC,KAAK,EAAE,WAAW;QAClB,2DAA2D;QAC3D,sEAAsE;KACvE,CAAC,EACF,CAAC,UAAU,EAAE,MAAM,CAAC,CACrB,CAAC;AACJ,CAAC","sourcesContent":["import { useNavigation } from \"@react-navigation/native\";\nimport { useMemo } from \"react\";\n\nimport { useLinkToPath } from \"./fork/useLinkToPath\";\nimport { Href, resolveHref } from \"./views/Link\";\n\n// Wraps useLinkTo to provide an API which is similar to the Link component.\nexport function useLink(): {\n push: (href: Href) => void;\n replace: (href: Href) => void;\n back: () => void;\n parse: typeof resolveHref;\n} {\n const linkTo = useLinkToPath();\n const navigation = useNavigation();\n\n return useMemo(\n () => ({\n push: (url: Href) => {\n const href = resolveHref(url);\n linkTo(href);\n },\n replace: (url: Href) => {\n const href = resolveHref(url);\n linkTo(href, \"REPLACE\");\n },\n back: () => navigation?.goBack(),\n parse: resolveHref,\n // TODO(EvanBacon): add `pathname`, `query`, maybe `reload`\n // TODO(EvanBacon): add `canGoBack` but maybe more like a `hasContext`\n }),\n [navigation, linkTo]\n );\n}\n"]}
@@ -1,36 +0,0 @@
1
- import { TextProps } from "@bacons/react-views";
2
- import type { NavigationAction } from "@react-navigation/core";
3
- import type { To } from "@react-navigation/native/src/useLinkTo";
4
- import * as React from "react";
5
- import { GestureResponderEvent } from "react-native";
6
- export declare type Href = string | {
7
- pathname?: string;
8
- query?: Record<string, any>;
9
- };
10
- declare type Props<ParamList extends ReactNavigation.RootParamList> = {
11
- /** Add a property which is familiar to */
12
- href?: Href;
13
- /** Forward props to child component. Useful for custom buttons. */
14
- asChild?: boolean;
15
- to?: To<ParamList>;
16
- action?: NavigationAction;
17
- target?: string;
18
- onPress?: (e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent) => void;
19
- } & (TextProps & {
20
- children: React.ReactNode;
21
- });
22
- /**
23
- * Component to render link to another screen using a path.
24
- * Uses an anchor tag on the web.
25
- *
26
- * @param props.href Absolute path to screen (e.g. `/feeds/hot`).
27
- * @param props.action Optional action to use for in-page navigation. By default, the path is parsed to an action based on linking config.
28
- * @param props.children Child elements to render the content.
29
- */
30
- export declare const Link: React.ForwardRefExoticComponent<Pick<Props<ReactNavigation.RootParamList>, "children" | "key" | "allowFontScaling" | "ellipsizeMode" | "lineBreakMode" | "numberOfLines" | "onLayout" | "onTextLayout" | "onPress" | "onPressIn" | "onPressOut" | "onLongPress" | "testID" | "nativeID" | "maxFontSizeMultiplier" | "adjustsFontSizeToFit" | "minimumFontScale" | "suppressHighlighting" | "selectable" | "selectionColor" | "textBreakStrategy" | "dataDetectorType" | "android_hyphenationFrequency" | "accessible" | "accessibilityActions" | "accessibilityLabel" | "accessibilityState" | "accessibilityHint" | "accessibilityValue" | "onAccessibilityAction" | "accessibilityLiveRegion" | "importantForAccessibility" | "accessibilityElementsHidden" | "accessibilityViewIsModal" | "onAccessibilityEscape" | "onAccessibilityTap" | "onMagicTap" | "accessibilityIgnoresInvertColors" | "asChild" | "to" | "action" | keyof import("@bacons/react-views/build/Text").WebTextProps> & React.RefAttributes<Text>>;
31
- export declare const resolveHref: (href: {
32
- pathname?: string;
33
- query?: Record<string, any>;
34
- } | string) => string;
35
- export {};
36
- //# sourceMappingURL=Link.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../src/views/Link.tsx"],"names":[],"mappings":"AACA,OAAO,EAAQ,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,wCAAwC,CAAC;AACjE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,qBAAqB,EAAY,MAAM,cAAc,CAAC;AAE/D,oBAAY,IAAI,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,CAAC;AAE/E,aAAK,KAAK,CAAC,SAAS,SAAS,eAAe,CAAC,aAAa,IAAI;IAC5D,2CAA2C;IAC3C,IAAI,CAAC,EAAE,IAAI,CAAC;IAEZ,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,EAAE,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC;IACnB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,CACR,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,EAAE,UAAU,CAAC,GAAG,qBAAqB,KACvE,IAAI,CAAC;CACX,GAAG,CAAC,SAAS,GAAG;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,CAAC,CAAC;AAEhD;;;;;;;GAOG;AACH,eAAO,MAAM,IAAI,29BAA6B,CAAC;AAE/C,eAAO,MAAM,WAAW,SAChB;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GAAG,MAAM,KAChE,MAUF,CAAC"}
@@ -1,87 +0,0 @@
1
- // Fork of @react-navigation/native Link.tsx
2
- import { Text } from "@bacons/react-views";
3
- import { Slot } from "@radix-ui/react-slot";
4
- import { useLinkProps } from "@react-navigation/native";
5
- import * as React from "react";
6
- import { Platform } from "react-native";
7
- /**
8
- * Component to render link to another screen using a path.
9
- * Uses an anchor tag on the web.
10
- *
11
- * @param props.href Absolute path to screen (e.g. `/feeds/hot`).
12
- * @param props.action Optional action to use for in-page navigation. By default, the path is parsed to an action based on linking config.
13
- * @param props.children Child elements to render the content.
14
- */
15
- export const Link = React.forwardRef(BaseLink);
16
- export const resolveHref = (href) => {
17
- if (typeof href === "string") {
18
- return href ?? "";
19
- }
20
- const path = href.pathname ?? "";
21
- if (!href?.query) {
22
- return path;
23
- }
24
- const { pathname, query } = createQualifiedPathname(path, { ...href.query });
25
- return pathname + (Object.keys(query).length ? `?${createQuery(query)}` : "");
26
- };
27
- function createQualifiedPathname(pathname, query) {
28
- for (const [key, value = ""] of Object.entries(query)) {
29
- const dynamicKey = `[${key}]`;
30
- const deepDynamicKey = `[...${key}]`;
31
- if (pathname.includes(dynamicKey)) {
32
- pathname = pathname.replace(dynamicKey, Array.isArray(value) ? value.join("/") : value);
33
- }
34
- else if (pathname.includes(deepDynamicKey)) {
35
- pathname = pathname.replace(deepDynamicKey, Array.isArray(value) ? value.join("/") : value);
36
- }
37
- else {
38
- continue;
39
- }
40
- delete query[key];
41
- }
42
- return { pathname, query };
43
- }
44
- function createQuery(query) {
45
- return Object.keys(query)
46
- .map((key) => `${key}=${query[key]}`)
47
- .join("&");
48
- }
49
- function useResolvedHref({ href, to, }) {
50
- // TODO: Auto use router's client-side event.
51
- return React.useMemo(() => {
52
- if (href) {
53
- return resolveHref(href);
54
- }
55
- if (to == null) {
56
- throw new Error(`You must specify either 'href' or 'to' prop in a <Link />.`);
57
- }
58
- if (typeof to === "string" && !to.startsWith("/")) {
59
- // TODO: Auto delegate out external links
60
- return "/";
61
- }
62
- return to;
63
- }, [href, to]);
64
- }
65
- function BaseLink({ to, href, action, asChild, ...rest }, ref) {
66
- // TODO: Auto use router's client-side event.
67
- const resolvedTo = useResolvedHref({ href, to });
68
- const props = useLinkProps({ to: resolvedTo, action });
69
- const onPress = (e) => {
70
- if ("onPress" in rest) {
71
- rest.onPress?.(e);
72
- }
73
- props.onPress(e);
74
- };
75
- return React.createElement(
76
- // @ts-expect-error: slot is not type-safe
77
- asChild ? Slot : Text, {
78
- ref,
79
- ...props,
80
- ...rest,
81
- ...Platform.select({
82
- web: { onClick: onPress },
83
- default: { onPress },
84
- }),
85
- });
86
- }
87
- //# sourceMappingURL=Link.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Link.js","sourceRoot":"","sources":["../../src/views/Link.tsx"],"names":[],"mappings":"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","sourcesContent":["// Fork of @react-navigation/native Link.tsx\nimport { Text, TextProps } from \"@bacons/react-views\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport type { NavigationAction } from \"@react-navigation/core\";\nimport { useLinkProps } from \"@react-navigation/native\";\nimport type { To } from \"@react-navigation/native/src/useLinkTo\";\nimport * as React from \"react\";\nimport { GestureResponderEvent, Platform } from \"react-native\";\n\nexport type Href = string | { pathname?: string; query?: Record<string, any> };\n\ntype Props<ParamList extends ReactNavigation.RootParamList> = {\n /** Add a property which is familiar to */\n href?: Href;\n\n /** Forward props to child component. Useful for custom buttons. */\n asChild?: boolean;\n\n to?: To<ParamList>;\n action?: NavigationAction;\n target?: string;\n onPress?: (\n e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent\n ) => void;\n} & (TextProps & { children: React.ReactNode });\n\n/**\n * Component to render link to another screen using a path.\n * Uses an anchor tag on the web.\n *\n * @param props.href Absolute path to screen (e.g. `/feeds/hot`).\n * @param props.action Optional action to use for in-page navigation. By default, the path is parsed to an action based on linking config.\n * @param props.children Child elements to render the content.\n */\nexport const Link = React.forwardRef(BaseLink);\n\nexport const resolveHref = (\n href: { pathname?: string; query?: Record<string, any> } | string\n): string => {\n if (typeof href === \"string\") {\n return href ?? \"\";\n }\n const path = href.pathname ?? \"\";\n if (!href?.query) {\n return path;\n }\n const { pathname, query } = createQualifiedPathname(path, { ...href.query });\n return pathname + (Object.keys(query).length ? `?${createQuery(query)}` : \"\");\n};\n\nfunction createQualifiedPathname(pathname: string, query: Record<string, any>) {\n for (const [key, value = \"\"] of Object.entries(query)) {\n const dynamicKey = `[${key}]`;\n const deepDynamicKey = `[...${key}]`;\n if (pathname.includes(dynamicKey)) {\n pathname = pathname.replace(\n dynamicKey,\n Array.isArray(value) ? value.join(\"/\") : value\n );\n } else if (pathname.includes(deepDynamicKey)) {\n pathname = pathname.replace(\n deepDynamicKey,\n Array.isArray(value) ? value.join(\"/\") : value\n );\n } else {\n continue;\n }\n\n delete query[key];\n }\n return { pathname, query };\n}\n\nfunction createQuery(query: Record<string, any>) {\n return Object.keys(query)\n .map((key) => `${key}=${query[key]}`)\n .join(\"&\");\n}\n\nfunction useResolvedHref<ParamList extends ReactNavigation.RootParamList>({\n href,\n to,\n}: Pick<Props<ParamList>, \"href\" | \"to\">) {\n // TODO: Auto use router's client-side event.\n return React.useMemo(() => {\n if (href) {\n return resolveHref(href);\n }\n\n if (to == null) {\n throw new Error(\n `You must specify either 'href' or 'to' prop in a <Link />.`\n );\n }\n if (typeof to === \"string\" && !to.startsWith(\"/\")) {\n // TODO: Auto delegate out external links\n return \"/\";\n }\n return to;\n }, [href, to]);\n}\n\nfunction BaseLink<ParamList extends ReactNavigation.RootParamList>(\n { to, href, action, asChild, ...rest }: Props<ParamList>,\n ref: React.ForwardedRef<Text>\n) {\n // TODO: Auto use router's client-side event.\n const resolvedTo = useResolvedHref({ href, to });\n\n const props = useLinkProps<ParamList>({ to: resolvedTo, action });\n\n const onPress = (\n e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent\n ) => {\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"]}