expo-router 5.2.0-canary-20250630-547cd82 → 5.2.0-canary-20250709-136b77f
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.
- package/assets/modal.module.css +124 -0
- package/build/fork/useLinking.d.ts.map +1 -1
- package/build/fork/useLinking.js +7 -3
- package/build/fork/useLinking.js.map +1 -1
- package/build/layouts/DrawerClient.d.ts +2 -2
- package/build/layouts/Stack.web.d.ts +17 -0
- package/build/layouts/Stack.web.d.ts.map +1 -0
- package/build/layouts/Stack.web.js +17 -0
- package/build/layouts/Stack.web.js.map +1 -0
- package/build/layouts/StackClient.d.ts +41 -3
- package/build/layouts/StackClient.d.ts.map +1 -1
- package/build/layouts/StackClient.js +79 -2
- package/build/layouts/StackClient.js.map +1 -1
- package/build/layouts/TabsClient.d.ts +3 -3
- package/build/link/BaseExpoRouterLink.d.ts +2 -1
- package/build/link/BaseExpoRouterLink.d.ts.map +1 -1
- package/build/link/BaseExpoRouterLink.js +37 -1
- package/build/link/BaseExpoRouterLink.js.map +1 -1
- package/build/link/ExpoLink.d.ts +2 -1
- package/build/link/ExpoLink.d.ts.map +1 -1
- package/build/link/ExpoLink.js +44 -3
- package/build/link/ExpoLink.js.map +1 -1
- package/build/link/Link.d.ts +3 -3
- package/build/link/Link.d.ts.map +1 -1
- package/build/link/Link.js.map +1 -1
- package/build/link/LinkWithPreview.d.ts +19 -6
- package/build/link/LinkWithPreview.d.ts.map +1 -1
- package/build/link/LinkWithPreview.js +53 -18
- package/build/link/LinkWithPreview.js.map +1 -1
- package/build/link/preview/HrefPreview.d.ts.map +1 -1
- package/build/link/preview/HrefPreview.js +2 -2
- package/build/link/preview/HrefPreview.js.map +1 -1
- package/build/link/preview/native.d.ts +2 -0
- package/build/link/preview/native.d.ts.map +1 -1
- package/build/link/preview/native.js.map +1 -1
- package/build/modal/web/ModalStack.web.d.ts +25 -0
- package/build/modal/web/ModalStack.web.d.ts.map +1 -0
- package/build/modal/web/ModalStack.web.js +86 -0
- package/build/modal/web/ModalStack.web.js.map +1 -0
- package/build/modal/web/ModalStackRouteDrawer.web.d.ts +14 -0
- package/build/modal/web/ModalStackRouteDrawer.web.d.ts.map +1 -0
- package/build/modal/web/ModalStackRouteDrawer.web.js +161 -0
- package/build/modal/web/ModalStackRouteDrawer.web.js.map +1 -0
- package/build/modal/web/TransparentModalStackRouteDrawer.web.d.ts +10 -0
- package/build/modal/web/TransparentModalStackRouteDrawer.web.d.ts.map +1 -0
- package/build/modal/web/TransparentModalStackRouteDrawer.web.js +28 -0
- package/build/modal/web/TransparentModalStackRouteDrawer.web.js.map +1 -0
- package/build/modal/web/modalStyles.d.ts +3 -0
- package/build/modal/web/modalStyles.d.ts.map +1 -0
- package/build/modal/web/modalStyles.js +8 -0
- package/build/modal/web/modalStyles.js.map +1 -0
- package/build/modal/web/types.d.ts +14 -0
- package/build/modal/web/types.d.ts.map +1 -0
- package/build/modal/web/types.js +3 -0
- package/build/modal/web/types.js.map +1 -0
- package/build/modal/web/utils.d.ts +70 -0
- package/build/modal/web/utils.d.ts.map +1 -0
- package/build/modal/web/utils.js +117 -0
- package/build/modal/web/utils.js.map +1 -0
- package/ios/ExpoHead.podspec +1 -1
- package/ios/LinkPreview/LinkPreviewNativeActionView.swift +22 -0
- package/ios/LinkPreview/LinkPreviewNativeModule.swift +3 -0
- package/ios/LinkPreview/LinkPreviewNativeView.swift +30 -11
- package/package.json +9 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkWithPreview.js","sourceRoot":"","sources":["../../src/link/LinkWithPreview.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCb,0CAgHC;AAUD,wCAEC;AAKD,4BAOC;AAqBD,kCA2BC;AAED,kCAKC;AA9ND,+CASe;AAEf,oCAAqC;AACrC,6DAA0D;AAC1D,uDAAoD;AACpD,qEAAqE;AACrE,6CAK0B;AAC1B,+DAA4D;AAE5D,sCAAoD;AACpD,uEAA6D;AAC7D,qCAAkC;AAElC,MAAM,0BAA0B,GAAG,IAAA,qBAAa,EAE9C,SAAS,CAAC,CAAC;AAEb,SAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAa;IAC9D,MAAM,MAAM,GAAG,IAAA,iBAAS,GAAE,CAAC;IAC3B,MAAM,EAAE,gBAAgB,EAAE,GAAG,IAAA,0CAAqB,GAAE,CAAC;IACrD,MAAM,CAAC,oBAAoB,EAAE,sBAAsB,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;IAEvE,MAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,oBAAoB,GAAG,IAAA,cAAM,EAAC,gBAAgB,CAAC,CAAC;IAEtD,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,oBAAoB,EAAE,CAAC;YACzB,IAAI,oBAAoB,CAAC,OAAO,KAAK,gBAAgB,EAAE,CAAC;gBACtD,MAAM,IAAI,KAAK,CACb,iKAAiK,CAClK,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,CAAC;YACN,oBAAoB,CAAC,OAAO,GAAG,gBAAgB,CAAC;QAClD,CAAC;IACH,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEvB,MAAM,CAAC,YAAY,EAAE,kBAAkB,CAAC,GAAG,IAAA,iCAAe,GAAE,CAAC;IAE7D,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,IAAA,0BAAoB,EAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAC5C,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;gBAC1C,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;YAC/D,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;gBAC1C,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;YACvE,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;YACpE,CAAC;QACH,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAE9B,MAAM,cAAc,GAAG,eAAK,CAAC,OAAO,CAClC,GAAG,EAAE,CAAC,mBAAmB,CAAC,QAAQ,EAAE,WAAW,CAAC,EAChD,CAAC,QAAQ,CAAC,CACX,CAAC;IACF,MAAM,WAAW,GAAG,eAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC7F,MAAM,cAAc,GAAG,eAAK,CAAC,OAAO,CAClC,GAAG,EAAE,CAAC,mBAAmB,CAAC,QAAQ,EAAE,WAAW,CAAC,EAChD,CAAC,QAAQ,CAAC,CACX,CAAC;IAEF,IAAI,cAAc,IAAI,CAAC,cAAc,EAAE,CAAC;QACtC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CACb,sFAAsF,CACvF,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CACV,sFAAsF,CACvF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,eAAK,CAAC,OAAO,CAC3B,GAAG,EAAE,CAAC,cAAc,IAAI,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC,EAC7D,CAAC,cAAc,EAAE,QAAQ,CAAC,CAC3B,CAAC;IAEF,MAAM,eAAe,GAAG,eAAK,CAAC,OAAO,CACnC,GAAG,EAAE,CACH,+BAA+B,CAC7B,6BAA6B,CAAC,eAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CACnF,EACH,CAAC,WAAW,CAAC,CACd,CAAC;IACF,MAAM,OAAO,GAAG,eAAK,CAAC,OAAO,CAC3B,GAAG,EAAE,CAAC,cAAc,IAAI,CAAC,WAAW,CAAC,AAAD,EAAG,EACvC,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAC5B,CAAC;IAEF,IAAI,IAAA,0BAAoB,EAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QAC5D,OAAO,CAAC,uCAAkB,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,IAAI,CAAC,EAAG,CAAC;IAC9D,CAAC;IAED,OAAO,CACL,CAAC,0BAAiB,CAChB,YAAY,CAAC,CAAC,YAAY,CAAC,CAC3B,gBAAgB,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;YAC5C,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1B,CAAC,CAAC,CACF,iBAAiB,CAAC,CAAC,GAAG,EAAE;YACtB,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3B,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACvB,sBAAsB,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC,CAAC,CACF,gBAAgB,CAAC,CAAC,GAAG,EAAE;YACrB,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,CAAC,CAAC,CACF,iBAAiB,CAAC,CAAC,GAAG,EAAE;YACtB,gBAAgB,CAAC,KAAK,CAAC,CAAC;YACxB,sBAAsB,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC,CAAC,CACF,eAAe,CAAC,CAAC,GAAG,EAAE;YACpB,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,sBAAsB,EAAE,YAAY,EAAE,CAAC,CAAC;QACvE,CAAC,CAAC,CACF;MAAA,CAAC,0BAA0B,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CACtF;QAAA,CAAC,iCAAwB,CACvB;UAAA,CAAC,uCAAkB,CAAC,IAAI,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EACjE;QAAA,EAAE,iCAAwB,CAC1B;QAAA,CAAC,OAAO,CACR;QAAA,CAAC,WAAW,CACd;MAAA,EAAE,0BAA0B,CAC9B;IAAA,EAAE,0BAAiB,CAAC,CACrB,CAAC;AACJ,CAAC;AAUD,SAAgB,cAAc,CAAC,CAAiB;IAC9C,OAAO,IAAI,CAAC;AACd,CAAC;AAKD,SAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAiB;IAClD,IAAI,IAAA,kCAAY,GAAE,IAAI,CAAC,IAAA,WAAG,EAAC,0BAA0B,CAAC,EAAE,CAAC;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,6BAA6B,CAAC,eAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACpF,OAAO,CAAC,gCAAuB,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAG,CAAC;IACzF,CAAC,CAAC,CAAC;AACL,CAAC;AAqBD,SAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAoB;IACvE,MAAM,sBAAsB,GAAG,IAAA,WAAG,EAAC,0BAA0B,CAAC,CAAC;IAC/D,IAAI,IAAA,kCAAY,GAAE,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,sBAAsB,CAAC;IACnD,MAAM,WAAW,GAAG;QAClB,KAAK,EAAE,KAAK,IAAI,CAAC;QACjB,MAAM,EAAE,MAAM,IAAI,CAAC;KACpB,CAAC;IACF,IAAI,OAAwB,CAAC;IAC7B,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;IACxC,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,yBAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3D,CAAC;IAED,OAAO,CACL,CAAC,iCAAwB,CACvB,KAAK,CAAC,CAAC;YACL,6EAA6E;YAC7E,eAAe,EAAE,MAAM;SACxB,CAAC,CACF,oBAAoB,CAAC,CAAC,WAAW,CAAC,CAClC;MAAA,CAAC,OAAO,CACV;IAAA,EAAE,iCAAwB,CAAC,CAC5B,CAAC;AACJ,CAAC;AAED,SAAgB,WAAW,CAAC,KAAwB;IAClD,IAAI,eAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAA,sBAAc,EAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACpF,OAAO,KAAK,CAAC,QAAQ,CAAC;IACxB,CAAC;IACD,OAAO,CAAC,WAAI,CAAC,IAAI,KAAK,CAAC,EAAG,CAAC;AAC7B,CAAC;AAED,SAAS,mBAAmB,CAC1B,QAA6C,EAC7C,IAAgC;IAEhC,OAAO,eAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAC1C,CAAC,KAAK,EAAiC,EAAE,CAAC,IAAA,sBAAc,EAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,CACvF,CAAC;AACJ,CAAC;AAED,SAAS,+BAA+B,CACtC,KAAuE;IAEvE,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,CACzB,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QACd,GAAG,GAAG;QACN,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,OAAO;KACxB,CAAC,EACF,EAAgC,CACjC,CAAC;AACJ,CAAC;AAED,SAAS,6BAA6B,CAAC,QAAmD;IACxF,OAAO,QAAQ;SACZ,MAAM,CACL,CAAC,IAAI,EAAwC,EAAE,CAC7C,IAAA,sBAAc,EAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc,CACvD;SACA,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QACtB,EAAE,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,EAAE;QACnC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK;QACxB,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO;KAC7B,CAAC,CAAC,CAAC;AACR,CAAC","sourcesContent":["'use client';\n\nimport React, {\n createContext,\n isValidElement,\n use,\n useEffect,\n useRef,\n useState,\n type PropsWithChildren,\n type ReactElement,\n} from 'react';\n\nimport { useRouter } from '../hooks';\nimport { BaseExpoRouterLink } from './BaseExpoRouterLink';\nimport { HrefPreview } from './preview/HrefPreview';\nimport { useLinkPreviewContext } from './preview/LinkPreviewContext';\nimport {\n NativeLinkPreview,\n NativeLinkPreviewAction,\n NativeLinkPreviewContent,\n NativeLinkPreviewTrigger,\n} from './preview/native';\nimport { useNextScreenId } from './preview/useNextScreenId';\nimport { LinkProps } from './useLinkHooks';\nimport { shouldLinkExternally } from '../utils/url';\nimport { useIsPreview } from './preview/PreviewRouteContext';\nimport { Slot } from '../ui/Slot';\n\nconst InternalLinkPreviewContext = createContext<\n { isVisible: boolean; href: LinkProps['href'] } | undefined\n>(undefined);\n\nexport function LinkWithPreview({ children, ...rest }: LinkProps) {\n const router = useRouter();\n const { setIsPreviewOpen } = useLinkPreviewContext();\n const [isCurrentPreviewOpen, setIsCurrenPreviewOpen] = useState(false);\n\n const hrefWithoutQuery = String(rest.href).split('?')[0];\n const prevHrefWithoutQuery = useRef(hrefWithoutQuery);\n\n useEffect(() => {\n if (isCurrentPreviewOpen) {\n if (prevHrefWithoutQuery.current !== hrefWithoutQuery) {\n throw new Error(\n 'Link does not support changing the href prop after the preview has been opened. Please ensure that the href prop is stable and does not change between renders.'\n );\n }\n } else {\n prevHrefWithoutQuery.current = hrefWithoutQuery;\n }\n }, [hrefWithoutQuery]);\n\n const [nextScreenId, updateNextScreenId] = useNextScreenId();\n\n useEffect(() => {\n if (shouldLinkExternally(String(rest.href))) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('External links previews are not supported');\n } else {\n console.warn('External links previews are not supported');\n }\n }\n if (rest.replace) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('Using replace links with preview is not supported');\n } else {\n console.warn('Using replace links with preview is not supported');\n }\n }\n }, [rest.href, rest.replace]);\n\n const triggerElement = React.useMemo(\n () => getFirstChildOfType(children, LinkTrigger),\n [children]\n );\n const menuElement = React.useMemo(() => getFirstChildOfType(children, LinkMenu), [children]);\n const previewElement = React.useMemo(\n () => getFirstChildOfType(children, LinkPreview),\n [children]\n );\n\n if (previewElement && !triggerElement) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n 'When you use Link.Preview, you must use Link.Trigger to specify the trigger element.'\n );\n } else {\n console.warn(\n 'When you use Link.Preview, you must use Link.Trigger to specify the trigger element.'\n );\n }\n }\n\n const trigger = React.useMemo(\n () => triggerElement ?? <LinkTrigger>{children}</LinkTrigger>,\n [triggerElement, children]\n );\n\n const actionsHandlers = React.useMemo(\n () =>\n convertActionsToActionsHandlers(\n convertChildrenArrayToActions(React.Children.toArray(menuElement?.props.children))\n ),\n [menuElement]\n );\n const preview = React.useMemo(\n () => previewElement ?? <LinkPreview />,\n [previewElement, rest.href]\n );\n\n if (shouldLinkExternally(String(rest.href)) || rest.replace) {\n return <BaseExpoRouterLink children={children} {...rest} />;\n }\n\n return (\n <NativeLinkPreview\n nextScreenId={nextScreenId}\n onActionSelected={({ nativeEvent: { id } }) => {\n actionsHandlers[id]?.();\n }}\n onWillPreviewOpen={() => {\n router.prefetch(rest.href);\n setIsPreviewOpen(true);\n setIsCurrenPreviewOpen(true);\n }}\n onDidPreviewOpen={() => {\n updateNextScreenId(rest.href);\n }}\n onPreviewDidClose={() => {\n setIsPreviewOpen(false);\n setIsCurrenPreviewOpen(false);\n }}\n onPreviewTapped={() => {\n router.navigate(rest.href, { __internal__PreviewKey: nextScreenId });\n }}>\n <InternalLinkPreviewContext value={{ isVisible: isCurrentPreviewOpen, href: rest.href }}>\n <NativeLinkPreviewTrigger>\n <BaseExpoRouterLink {...rest} children={trigger} ref={rest.ref} />\n </NativeLinkPreviewTrigger>\n {preview}\n {menuElement}\n </InternalLinkPreviewContext>\n </NativeLinkPreview>\n );\n}\n\ninterface LinkMenuAction {\n /**\n * The title of the menu item.\n */\n title: string;\n onPress: () => void;\n}\n\nexport function LinkMenuAction(_: LinkMenuAction) {\n return null;\n}\ninterface LinkMenuProps {\n children: ReactElement<LinkMenuAction> | ReactElement<LinkMenuAction>[];\n}\n\nexport function LinkMenu({ children }: LinkMenuProps) {\n if (useIsPreview() || !use(InternalLinkPreviewContext)) {\n return null;\n }\n return convertChildrenArrayToActions(React.Children.toArray(children)).map((action) => {\n return <NativeLinkPreviewAction key={action.id} title={action.title} id={action.id} />;\n });\n}\n\ninterface LinkPreviewProps {\n /**\n * Sets the preferred width of the preview.\n * If not set, full width of the screen will be used.\n *\n * This is only **preferred** width, the actual width may be different\n */\n width?: number;\n\n /**\n * Sets the preferred height of the preview.\n * If not set, full height of the screen will be used.\n *\n * This is only **preferred** height, the actual height may be different\n */\n height?: number;\n children?: React.ReactNode;\n}\n\nexport function LinkPreview({ children, width, height }: LinkPreviewProps) {\n const internalPreviewContext = use(InternalLinkPreviewContext);\n if (useIsPreview() || !internalPreviewContext) {\n return null;\n }\n const { isVisible, href } = internalPreviewContext;\n const contentSize = {\n width: width ?? 0,\n height: height ?? 0,\n };\n let content: React.ReactNode;\n if (children) {\n content = isVisible ? children : null;\n } else {\n content = isVisible ? <HrefPreview href={href} /> : null;\n }\n\n return (\n <NativeLinkPreviewContent\n style={{\n /* Setting default background here, so that the preview is not transparent */\n backgroundColor: '#fff',\n }}\n preferredContentSize={contentSize}>\n {content}\n </NativeLinkPreviewContent>\n );\n}\n\nexport function LinkTrigger(props: PropsWithChildren) {\n if (React.Children.toArray(props.children).every((child) => !isValidElement(child))) {\n return props.children;\n }\n return <Slot {...props} />;\n}\n\nfunction getFirstChildOfType<PropsT>(\n children: React.ReactNode | React.ReactNode[],\n type: (props: PropsT) => unknown\n) {\n return React.Children.toArray(children).find(\n (child): child is ReactElement<PropsT> => isValidElement(child) && child.type === type\n );\n}\n\nfunction convertActionsToActionsHandlers(\n items: { id: string; title: string; onPress: () => void }[] | undefined\n) {\n return (items ?? []).reduce(\n (acc, item) => ({\n ...acc,\n [item.id]: item.onPress,\n }),\n {} as Record<string, () => void>\n );\n}\n\nfunction convertChildrenArrayToActions(children: ReturnType<typeof React.Children.toArray>) {\n return children\n .filter(\n (item): item is ReactElement<LinkMenuAction> =>\n isValidElement(item) && item.type === LinkMenuAction\n )\n .map((child, index) => ({\n id: `${child.props.title}-${index}`,\n title: child.props.title,\n onPress: child.props.onPress,\n }));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"LinkWithPreview.js","sourceRoot":"","sources":["../../src/link/LinkWithPreview.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCb,0CAgIC;AAcD,wCAEC;AAoDD,kCA2BC;AAED,kCAYC;AAhRD,+CAWe;AAGf,oCAAqC;AACrC,6DAA0D;AAC1D,uDAAoD;AACpD,qEAAqE;AACrE,6CAM0B;AAC1B,+DAA4D;AAE5D,sCAAoD;AACpD,uEAA6D;AAC7D,qCAAkC;AAElC,MAAM,0BAA0B,GAAG,IAAA,qBAAa,EAE9C,SAAS,CAAC,CAAC;AAEb,SAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAa;IAC9D,MAAM,MAAM,GAAG,IAAA,iBAAS,GAAE,CAAC;IAC3B,MAAM,EAAE,gBAAgB,EAAE,GAAG,IAAA,0CAAqB,GAAE,CAAC;IACrD,MAAM,CAAC,oBAAoB,EAAE,sBAAsB,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;IAEvE,MAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,oBAAoB,GAAG,IAAA,cAAM,EAAC,gBAAgB,CAAC,CAAC;IAEtD,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,oBAAoB,EAAE,CAAC;YACzB,IAAI,oBAAoB,CAAC,OAAO,KAAK,gBAAgB,EAAE,CAAC;gBACtD,MAAM,IAAI,KAAK,CACb,iKAAiK,CAClK,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,CAAC;YACN,oBAAoB,CAAC,OAAO,GAAG,gBAAgB,CAAC;QAClD,CAAC;IACH,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEvB,MAAM,CAAC,YAAY,EAAE,kBAAkB,CAAC,GAAG,IAAA,iCAAe,GAAE,CAAC;IAE7D,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,IAAA,0BAAoB,EAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAC5C,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;gBAC1C,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;YAC/D,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;gBAC1C,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;YACvE,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;YACpE,CAAC;QACH,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAE9B,MAAM,cAAc,GAAG,eAAK,CAAC,OAAO,CAClC,GAAG,EAAE,CAAC,mBAAmB,CAAC,QAAQ,EAAE,WAAW,CAAC,EAChD,CAAC,QAAQ,CAAC,CACX,CAAC;IACF,MAAM,WAAW,GAAG,eAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,mBAAmB,CAAC,QAAQ,EAAE,gBAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC7F,MAAM,cAAc,GAAG,eAAK,CAAC,OAAO,CAClC,GAAG,EAAE,CAAC,mBAAmB,CAAC,QAAQ,EAAE,WAAW,CAAC,EAChD,CAAC,QAAQ,CAAC,CACX,CAAC;IAEF,IAAI,cAAc,IAAI,CAAC,cAAc,EAAE,CAAC;QACtC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CACb,sFAAsF,CACvF,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CACV,sFAAsF,CACvF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,eAAK,CAAC,OAAO,CAC3B,GAAG,EAAE,CAAC,cAAc,IAAI,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC,EAC7D,CAAC,cAAc,EAAE,QAAQ,CAAC,CAC3B,CAAC;IAEF,MAAM,eAAe,GAAG,eAAK,CAAC,OAAO,CACnC,GAAG,EAAE,CACH,WAAW;QACT,CAAC,CAAC,+BAA+B,CAAC,6BAA6B,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;QAC/E,CAAC,CAAC,EAAE,EACR,CAAC,WAAW,CAAC,CACd,CAAC;IACF,MAAM,OAAO,GAAG,eAAK,CAAC,OAAO,CAC3B,GAAG,EAAE,CAAC,cAAc,IAAI,CAAC,WAAW,CAAC,AAAD,EAAG,EACvC,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAC5B,CAAC;IAEF,MAAM,eAAe,GAAG,IAAA,cAAM,EAAC,KAAK,CAAC,CAAC;IAEtC,IAAI,IAAA,0BAAoB,EAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QAC5D,OAAO,CAAC,uCAAkB,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,IAAI,CAAC,EAAG,CAAC;IAC9D,CAAC;IAED,OAAO,CACL,CAAC,0BAAiB,CAChB,YAAY,CAAC,CAAC,YAAY,CAAC,CAC3B,gBAAgB,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;YAC5C,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1B,CAAC,CAAC,CACF,iBAAiB,CAAC,CAAC,GAAG,EAAE;YACtB,eAAe,CAAC,OAAO,GAAG,KAAK,CAAC;YAChC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3B,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACvB,sBAAsB,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC,CAAC,CACF,gBAAgB,CAAC,CAAC,GAAG,EAAE;YACrB,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,CAAC,CAAC,CACF,kBAAkB,CAAC,CAAC,GAAG,EAAE;YACvB,iFAAiF;YACjF,mFAAmF;YACnF,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC;gBAC7B,sBAAsB,CAAC,KAAK,CAAC,CAAC;gBAC9B,gBAAgB,CAAC,KAAK,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC,CAAC,CACF,iBAAiB,CAAC,CAAC,GAAG,EAAE;YACtB,qEAAqE;YACrE,kDAAkD;YAClD,IAAI,eAAe,CAAC,OAAO,EAAE,CAAC;gBAC5B,sBAAsB,CAAC,KAAK,CAAC,CAAC;gBAC9B,gBAAgB,CAAC,KAAK,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC,CAAC,CACF,eAAe,CAAC,CAAC,GAAG,EAAE;YACpB,eAAe,CAAC,OAAO,GAAG,IAAI,CAAC;YAC/B,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,sBAAsB,EAAE,YAAY,EAAE,CAAC,CAAC;QACvE,CAAC,CAAC,CACF;MAAA,CAAC,0BAA0B,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CACtF;QAAA,CAAC,iCAAwB,CACvB;UAAA,CAAC,uCAAkB,CAAC,IAAI,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EACjE;QAAA,EAAE,iCAAwB,CAC1B;QAAA,CAAC,OAAO,CACR;QAAA,CAAC,WAAW,CACd;MAAA,EAAE,0BAA0B,CAC9B;IAAA,EAAE,0BAAiB,CAAC,CACrB,CAAC;AACJ,CAAC;AAcD,SAAgB,cAAc,CAAC,CAAsB;IACnD,OAAO,IAAI,CAAC;AACd,CAAC;AAcM,MAAM,QAAQ,GAAsB,CAAC,KAAK,EAAE,EAAE;IACnD,IAAI,IAAA,kCAAY,GAAE,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,KAAK,IAAI,CAAC,IAAA,WAAG,EAAC,0BAA0B,CAAC,EAAE,CAAC;QACxF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,8BAA8B,CACnC,6BAA6B,CAAC,CAAC,IAAA,qBAAa,EAAC,gBAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAChF,CAAC;AACJ,CAAC,CAAC;AAPW,QAAA,QAAQ,YAOnB;AAEF,SAAS,8BAA8B,CAAC,OAAgD;IACtF,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE,CAAC,CACtD,CAAC,gCAAuB,CACtB,IAAI,KAAK,CAAC,CACV,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CACd,QAAQ,CAAC,CAAC,8BAA8B,CAAC,QAAQ,CAAC,CAAC,EACnD,CACH,CAAC,CAAC;AACL,CAAC;AAqBD,SAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAoB;IACvE,MAAM,sBAAsB,GAAG,IAAA,WAAG,EAAC,0BAA0B,CAAC,CAAC;IAC/D,IAAI,IAAA,kCAAY,GAAE,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,KAAK,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAC/E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,sBAAsB,CAAC;IACnD,MAAM,WAAW,GAAG;QAClB,KAAK,EAAE,KAAK,IAAI,CAAC;QACjB,MAAM,EAAE,MAAM,IAAI,CAAC;KACpB,CAAC;IACF,IAAI,OAAwB,CAAC;IAC7B,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;IACxC,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,yBAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3D,CAAC;IAED,OAAO,CACL,CAAC,iCAAwB,CACvB,KAAK,CAAC,CAAC;YACL,6EAA6E;YAC7E,eAAe,EAAE,MAAM;SACxB,CAAC,CACF,oBAAoB,CAAC,CAAC,WAAW,CAAC,CAClC;MAAA,CAAC,OAAO,CACV;IAAA,EAAE,iCAAwB,CAAC,CAC5B,CAAC;AACJ,CAAC;AAED,SAAgB,WAAW,CAAC,KAAwB;IAClD,IAAI,eAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAA,sBAAc,EAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChF,6EAA6E;QAC7E,qGAAqG;QACrG,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;YAC7D,MAAM,IAAI,KAAK,CACb,gHAAgH,CACjH,CAAC;QACJ,CAAC;QACD,OAAO,KAAK,CAAC,QAAQ,CAAC;IACxB,CAAC;IACD,OAAO,CAAC,WAAI,CAAC,IAAI,KAAK,CAAC,EAAG,CAAC;AAC7B,CAAC;AAED,SAAS,mBAAmB,CAC1B,QAA6C,EAC7C,IAAgC;IAEhC,OAAO,eAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAC1C,CAAC,KAAK,EAAiC,EAAE,CAAC,IAAA,sBAAc,EAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,CACvF,CAAC;AACJ,CAAC;AAED,SAAS,+BAA+B,CACtC,KAA0D;IAE1D,OAAO,cAAc,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,CACvC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QACd,GAAG,GAAG;QACN,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,OAAO;KACxB,CAAC,EACF,EAAgC,CACjC,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CACrB,OAAgD;IAEhD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;QACpC,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,CAAC,GAAG,GAAG,EAAE,MAAM,CAAC,CAAC;IAC1B,CAAC,EAAE,EAA6C,CAAC,CAAC;AACpD,CAAC;AAOD,SAAS,6BAA6B,CACpC,QAAmD,EACnD,WAAmB,EAAE;IAErB,OAAO,QAAQ;SACZ,MAAM,CACL,CAAC,IAAI,EAA6D,EAAE,CAClE,IAAA,sBAAc,EAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,cAAc,IAAI,IAAI,CAAC,IAAI,KAAK,gBAAQ,CAAC,CACnF;SACA,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QACtB,EAAE,EAAE,GAAG,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,EAAE;QAC9C,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE;QAC9B,OAAO,EAAE,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,GAAE,CAAC;QAClE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI;QACtB,QAAQ,EACN,UAAU,IAAI,KAAK,CAAC,KAAK;YACvB,CAAC,CAAC,6BAA6B,CAC3B,eAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,EAC5C,GAAG,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,EAAE,CAC3C;YACH,CAAC,CAAC,EAAE;KACT,CAAC,CAAC,CAAC;AACR,CAAC","sourcesContent":["'use client';\n\nimport React, {\n createContext,\n createElement,\n isValidElement,\n use,\n useEffect,\n useRef,\n useState,\n type FC,\n type PropsWithChildren,\n type ReactElement,\n} from 'react';\nimport type { SFSymbol } from 'sf-symbols-typescript';\n\nimport { useRouter } from '../hooks';\nimport { BaseExpoRouterLink } from './BaseExpoRouterLink';\nimport { HrefPreview } from './preview/HrefPreview';\nimport { useLinkPreviewContext } from './preview/LinkPreviewContext';\nimport {\n NativeLinkPreview,\n NativeLinkPreviewAction,\n NativeLinkPreviewContent,\n NativeLinkPreviewTrigger,\n type NativeLinkPreviewActionProps,\n} from './preview/native';\nimport { useNextScreenId } from './preview/useNextScreenId';\nimport { LinkProps } from './useLinkHooks';\nimport { shouldLinkExternally } from '../utils/url';\nimport { useIsPreview } from './preview/PreviewRouteContext';\nimport { Slot } from '../ui/Slot';\n\nconst InternalLinkPreviewContext = createContext<\n { isVisible: boolean; href: LinkProps['href'] } | undefined\n>(undefined);\n\nexport function LinkWithPreview({ children, ...rest }: LinkProps) {\n const router = useRouter();\n const { setIsPreviewOpen } = useLinkPreviewContext();\n const [isCurrentPreviewOpen, setIsCurrenPreviewOpen] = useState(false);\n\n const hrefWithoutQuery = String(rest.href).split('?')[0];\n const prevHrefWithoutQuery = useRef(hrefWithoutQuery);\n\n useEffect(() => {\n if (isCurrentPreviewOpen) {\n if (prevHrefWithoutQuery.current !== hrefWithoutQuery) {\n throw new Error(\n 'Link does not support changing the href prop after the preview has been opened. Please ensure that the href prop is stable and does not change between renders.'\n );\n }\n } else {\n prevHrefWithoutQuery.current = hrefWithoutQuery;\n }\n }, [hrefWithoutQuery]);\n\n const [nextScreenId, updateNextScreenId] = useNextScreenId();\n\n useEffect(() => {\n if (shouldLinkExternally(String(rest.href))) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('External links previews are not supported');\n } else {\n console.warn('External links previews are not supported');\n }\n }\n if (rest.replace) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('Using replace links with preview is not supported');\n } else {\n console.warn('Using replace links with preview is not supported');\n }\n }\n }, [rest.href, rest.replace]);\n\n const triggerElement = React.useMemo(\n () => getFirstChildOfType(children, LinkTrigger),\n [children]\n );\n const menuElement = React.useMemo(() => getFirstChildOfType(children, LinkMenu), [children]);\n const previewElement = React.useMemo(\n () => getFirstChildOfType(children, LinkPreview),\n [children]\n );\n\n if (previewElement && !triggerElement) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n 'When you use Link.Preview, you must use Link.Trigger to specify the trigger element.'\n );\n } else {\n console.warn(\n 'When you use Link.Preview, you must use Link.Trigger to specify the trigger element.'\n );\n }\n }\n\n const trigger = React.useMemo(\n () => triggerElement ?? <LinkTrigger>{children}</LinkTrigger>,\n [triggerElement, children]\n );\n\n const actionsHandlers = React.useMemo(\n () =>\n menuElement\n ? convertActionsToActionsHandlers(convertChildrenArrayToActions([menuElement]))\n : {},\n [menuElement]\n );\n const preview = React.useMemo(\n () => previewElement ?? <LinkPreview />,\n [previewElement, rest.href]\n );\n\n const isPreviewTapped = useRef(false);\n\n if (shouldLinkExternally(String(rest.href)) || rest.replace) {\n return <BaseExpoRouterLink children={children} {...rest} />;\n }\n\n return (\n <NativeLinkPreview\n nextScreenId={nextScreenId}\n onActionSelected={({ nativeEvent: { id } }) => {\n actionsHandlers[id]?.();\n }}\n onWillPreviewOpen={() => {\n isPreviewTapped.current = false;\n router.prefetch(rest.href);\n setIsPreviewOpen(true);\n setIsCurrenPreviewOpen(true);\n }}\n onDidPreviewOpen={() => {\n updateNextScreenId(rest.href);\n }}\n onPreviewWillClose={() => {\n // When preview was not tapped, then we need to enable the screen stack animation\n // Otherwise a quick user could tap another link before onDidPreviewClose is called\n if (!isPreviewTapped.current) {\n setIsCurrenPreviewOpen(false);\n setIsPreviewOpen(false);\n }\n }}\n onPreviewDidClose={() => {\n // If preview was tapped we need to enable the screen stack animation\n // For other cases we did it in onPreviewWillClose\n if (isPreviewTapped.current) {\n setIsCurrenPreviewOpen(false);\n setIsPreviewOpen(false);\n }\n }}\n onPreviewTapped={() => {\n isPreviewTapped.current = true;\n router.navigate(rest.href, { __internal__PreviewKey: nextScreenId });\n }}>\n <InternalLinkPreviewContext value={{ isVisible: isCurrentPreviewOpen, href: rest.href }}>\n <NativeLinkPreviewTrigger>\n <BaseExpoRouterLink {...rest} children={trigger} ref={rest.ref} />\n </NativeLinkPreviewTrigger>\n {preview}\n {menuElement}\n </InternalLinkPreviewContext>\n </NativeLinkPreview>\n );\n}\n\ninterface LinkMenuActionProps {\n /**\n * The title of the menu item.\n */\n title: string;\n /**\n * Optional SF Symbol displayed alongside the menu item.\n */\n icon?: SFSymbol;\n onPress: () => void;\n}\n\nexport function LinkMenuAction(_: LinkMenuActionProps) {\n return null;\n}\n\nexport interface LinkMenuProps {\n /**\n * The title of the menu item\n */\n title?: string;\n /**\n * Optional SF Symbol displayed alongside the menu item.\n */\n icon?: string;\n children: ReactElement<LinkMenuActionProps> | ReactElement<LinkMenuActionProps>[];\n}\n\nexport const LinkMenu: FC<LinkMenuProps> = (props) => {\n if (useIsPreview() || process.env.EXPO_OS !== 'ios' || !use(InternalLinkPreviewContext)) {\n return null;\n }\n return convertActionsToNativeElements(\n convertChildrenArrayToActions([createElement(LinkMenu, props, props.children)])\n );\n};\n\nfunction convertActionsToNativeElements(actions: ConvertChildrenArrayToActionsReturnType) {\n return actions.map(({ children, onPress, ...props }) => (\n <NativeLinkPreviewAction\n {...props}\n key={props.id}\n children={convertActionsToNativeElements(children)}\n />\n ));\n}\n\ninterface LinkPreviewProps {\n /**\n * Sets the preferred width of the preview.\n * If not set, full width of the screen will be used.\n *\n * This is only **preferred** width, the actual width may be different\n */\n width?: number;\n\n /**\n * Sets the preferred height of the preview.\n * If not set, full height of the screen will be used.\n *\n * This is only **preferred** height, the actual height may be different\n */\n height?: number;\n children?: React.ReactNode;\n}\n\nexport function LinkPreview({ children, width, height }: LinkPreviewProps) {\n const internalPreviewContext = use(InternalLinkPreviewContext);\n if (useIsPreview() || process.env.EXPO_OS !== 'ios' || !internalPreviewContext) {\n return null;\n }\n const { isVisible, href } = internalPreviewContext;\n const contentSize = {\n width: width ?? 0,\n height: height ?? 0,\n };\n let content: React.ReactNode;\n if (children) {\n content = isVisible ? children : null;\n } else {\n content = isVisible ? <HrefPreview href={href} /> : null;\n }\n\n return (\n <NativeLinkPreviewContent\n style={{\n /* Setting default background here, so that the preview is not transparent */\n backgroundColor: '#fff',\n }}\n preferredContentSize={contentSize}>\n {content}\n </NativeLinkPreviewContent>\n );\n}\n\nexport function LinkTrigger(props: PropsWithChildren) {\n if (React.Children.count(props.children) > 1 || !isValidElement(props.children)) {\n // If onPress is passed, this means that Link passed props to this component.\n // We can assume that asChild is used, so we throw an error, because link will not work in this case.\n if (props && typeof props === 'object' && 'onPress' in props) {\n throw new Error(\n 'When using Link.Trigger in an asChild Link, you must pass a single child element that will emit onPress event.'\n );\n }\n return props.children;\n }\n return <Slot {...props} />;\n}\n\nfunction getFirstChildOfType<PropsT>(\n children: React.ReactNode | React.ReactNode[],\n type: (props: PropsT) => unknown\n) {\n return React.Children.toArray(children).find(\n (child): child is ReactElement<PropsT> => isValidElement(child) && child.type === type\n );\n}\n\nfunction convertActionsToActionsHandlers(\n items: ConvertChildrenArrayToActionsReturnType | undefined\n) {\n return flattenActions(items ?? []).reduce(\n (acc, item) => ({\n ...acc,\n [item.id]: item.onPress,\n }),\n {} as Record<string, () => void>\n );\n}\n\nfunction flattenActions(\n actions: ConvertChildrenArrayToActionsReturnType\n): ConvertChildrenArrayToActionsReturnType {\n return actions.reduce((acc, action) => {\n if (action.children.length > 0) {\n return [...acc, action, ...flattenActions(action.children)];\n }\n return [...acc, action];\n }, [] as ConvertChildrenArrayToActionsReturnType);\n}\n\ntype ConvertChildrenArrayToActionsReturnType = (Omit<NativeLinkPreviewActionProps, 'children'> & {\n onPress: () => void;\n children: ConvertChildrenArrayToActionsReturnType;\n})[];\n\nfunction convertChildrenArrayToActions(\n children: ReturnType<typeof React.Children.toArray>,\n parentId: string = ''\n): ConvertChildrenArrayToActionsReturnType {\n return children\n .filter(\n (item): item is ReactElement<LinkMenuActionProps | LinkMenuProps> =>\n isValidElement(item) && (item.type === LinkMenuAction || item.type === LinkMenu)\n )\n .map((child, index) => ({\n id: `${parentId}${child.props.title}-${index}`,\n title: child.props.title ?? '',\n onPress: 'onPress' in child.props ? child.props.onPress : () => {},\n icon: child.props.icon,\n children:\n 'children' in child.props\n ? convertChildrenArrayToActions(\n React.Children.toArray(child.props.children),\n `${parentId}${child.props.title}-${index}`\n )\n : [],\n }));\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HrefPreview.d.ts","sourceRoot":"","sources":["../../../src/link/preview/HrefPreview.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"HrefPreview.d.ts","sourceRoot":"","sources":["../../../src/link/preview/HrefPreview.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,IAAI,EAAuB,MAAM,aAAa,CAAC;AAKxD,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,sCA+BnD"}
|
|
@@ -5,11 +5,11 @@ exports.HrefPreview = HrefPreview;
|
|
|
5
5
|
const native_1 = require("@react-navigation/native");
|
|
6
6
|
const react_1 = require("react");
|
|
7
7
|
const PreviewRouteContext_1 = require("./PreviewRouteContext");
|
|
8
|
+
const constants_1 = require("../../constants");
|
|
8
9
|
const router_store_1 = require("../../global-state/router-store");
|
|
9
10
|
const useNavigation_1 = require("../../useNavigation");
|
|
10
11
|
const useScreens_1 = require("../../useScreens");
|
|
11
12
|
const linking_1 = require("../linking");
|
|
12
|
-
const constants_1 = require("../../constants");
|
|
13
13
|
function HrefPreview({ href }) {
|
|
14
14
|
const navigation = (0, useNavigation_1.useNavigation)();
|
|
15
15
|
const { routeNode, params, state } = getParamsAndNodeFromHref(href);
|
|
@@ -91,7 +91,7 @@ const navigationPropWithWarnings = {
|
|
|
91
91
|
index: 0,
|
|
92
92
|
routeNames: [],
|
|
93
93
|
routes: [],
|
|
94
|
-
type: '
|
|
94
|
+
type: '',
|
|
95
95
|
stale: false,
|
|
96
96
|
};
|
|
97
97
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HrefPreview.js","sourceRoot":"","sources":["../../../src/link/preview/HrefPreview.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AAkBb,kCA+BC;AA/CD,qDAIkC;AAClC,iCAAgC;AAEhC,+DAA4D;AAE5D,kEAAwD;AAExD,uDAAoD;AACpD,iDAA8D;AAC9D,wCAA8C;
|
|
1
|
+
{"version":3,"file":"HrefPreview.js","sourceRoot":"","sources":["../../../src/link/preview/HrefPreview.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport {\n NavigationContext,\n type NavigationProp,\n type ParamListBase,\n} from '@react-navigation/native';\nimport { useMemo } from 'react';\n\nimport { PreviewRouteContext } from './PreviewRouteContext';\nimport { RouteNode } from '../../Route';\nimport { INTERNAL_SLOT_NAME } from '../../constants';\nimport { store } from '../../global-state/router-store';\nimport { Href, UnknownOutputParams } from '../../types';\nimport { useNavigation } from '../../useNavigation';\nimport { getQualifiedRouteComponent } from '../../useScreens';\nimport { getPathFromState } from '../linking';\n\nexport function HrefPreview({ href }: { href: Href }) {\n const navigation = useNavigation();\n const { routeNode, params, state } = getParamsAndNodeFromHref(href);\n\n const path = state ? getPathFromState(state) : undefined;\n\n const value = useMemo(\n () => ({\n params,\n pathname: href.toString(),\n segments: path?.split('/').filter(Boolean) || [],\n }),\n [params, href]\n );\n\n // This can happen in a theoretical case where the state is not yet initialized or is incorrectly initialized.\n // It also check ensures TypeScript type safety.\n if (!routeNode) {\n return null;\n }\n\n const Component = getQualifiedRouteComponent(routeNode);\n\n return (\n <PreviewRouteContext value={value}>\n {/* Using NavigationContext to override useNavigation */}\n <NavigationContext value={navigationPropWithWarnings}>\n <Component navigation={navigation} />\n </NavigationContext>\n </PreviewRouteContext>\n );\n}\n\nfunction getParamsAndNodeFromHref(href: Href) {\n const hrefState = store.getStateForHref(href as any);\n if (hrefState?.routes[0] && hrefState.routes[0].name !== INTERNAL_SLOT_NAME) {\n const error = `Expo Router Error: Expected navigation state to begin with a ${INTERNAL_SLOT_NAME} route`;\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(error);\n } else {\n console.warn(error);\n }\n }\n // Assuming that root of the state is __root\n const initialState = hrefState?.routes[0]?.state;\n let state = initialState;\n let routeNode: RouteNode | undefined | null = store.routeNode;\n\n const params: UnknownOutputParams = {};\n\n while (state && routeNode) {\n const route = state.routes[state.index || state.routes.length - 1];\n Object.assign(params, route.params);\n state = route.state;\n routeNode = routeNode.children.find((child) => child.route === route.name);\n }\n\n return { params, routeNode, state: initialState };\n}\n\nconst displayWarningForProp = (prop: string) => {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n `navigation.${prop} should not be used in a previewed screen. To fix this issue, wrap navigation calls with 'if (!isPreview) { ... }'.`\n );\n }\n};\n\nconst createNOOPWithWarning = (prop: string) => () => displayWarningForProp(prop);\n\nconst navigationPropWithWarnings: NavigationProp<ParamListBase> = {\n setParams: createNOOPWithWarning('setParams'),\n setOptions: createNOOPWithWarning('setOptions'),\n addListener: (() => () => {}) as NavigationProp<ParamListBase>['addListener'],\n removeListener: () => {},\n isFocused: () => true,\n canGoBack: () => false,\n dispatch: createNOOPWithWarning('dispatch'),\n navigate: createNOOPWithWarning('navigate'),\n goBack: createNOOPWithWarning('goBack'),\n reset: createNOOPWithWarning('reset'),\n push: createNOOPWithWarning('push'),\n pop: createNOOPWithWarning('pop'),\n popToTop: createNOOPWithWarning('popToTop'),\n navigateDeprecated: createNOOPWithWarning('navigateDeprecated'),\n preload: createNOOPWithWarning('preload'),\n getId: () => {\n displayWarningForProp('getId');\n return '';\n },\n // @ts-expect-error\n getParent: createNOOPWithWarning('getParent'),\n getState: () => {\n displayWarningForProp('getState');\n return {\n key: '',\n index: 0,\n routeNames: [],\n routes: [],\n type: '',\n stale: false,\n };\n },\n};\n"]}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { type ViewProps } from 'react-native';
|
|
2
2
|
export interface NativeLinkPreviewActionProps {
|
|
3
3
|
title: string;
|
|
4
|
+
icon?: string;
|
|
4
5
|
id: string;
|
|
6
|
+
children?: React.ReactNode;
|
|
5
7
|
}
|
|
6
8
|
export declare function NativeLinkPreviewAction(props: NativeLinkPreviewActionProps): import("react").JSX.Element | null;
|
|
7
9
|
export type NativeLinkPreviewTriggerProps = ViewProps;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../../src/link/preview/native.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAGpE,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../../src/link/preview/native.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAGpE,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAKD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,4BAA4B,sCAK1E;AAID,MAAM,MAAM,6BAA6B,GAAG,SAAS,CAAC;AAKtD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,6BAA6B,sCAK5E;AAID,MAAM,WAAW,sBAAuB,SAAQ,SAAS;IACvD,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,WAAW,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,KAAK,IAAI,CAAC;IACpE,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAKD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,sCAK9D;AAID,MAAM,WAAW,6BAA8B,SAAQ,SAAS;IAC9D,oBAAoB,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1D;AAMD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,6BAA6B,sCAW5E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native.js","sourceRoot":"","sources":["../../../src/link/preview/native.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;
|
|
1
|
+
{"version":3,"file":"native.js","sourceRoot":"","sources":["../../../src/link/preview/native.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AAgBb,0DAKC;AASD,4DAKC;AAkBD,8CAKC;AAYD,4DAWC;AA/ED,+BAAyC;AACzC,+CAAoE;AASpE,MAAM,2BAA2B,GAC/B,uBAAQ,CAAC,EAAE,KAAK,KAAK;IACnB,CAAC,CAAC,IAAA,wBAAiB,EAAC,6BAA6B,EAAE,6BAA6B,CAAC;IACjF,CAAC,CAAC,IAAI,CAAC;AACX,SAAgB,uBAAuB,CAAC,KAAmC;IACzE,IAAI,CAAC,2BAA2B,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,CAAC,2BAA2B,CAAC,IAAI,KAAK,CAAC,EAAG,CAAC;AACpD,CAAC;AAKD,MAAM,4BAA4B,GAChC,uBAAQ,CAAC,EAAE,KAAK,KAAK;IACnB,CAAC,CAAC,IAAA,wBAAiB,EAAC,6BAA6B,EAAE,0BAA0B,CAAC;IAC9E,CAAC,CAAC,IAAI,CAAC;AACX,SAAgB,wBAAwB,CAAC,KAAoC;IAC3E,IAAI,CAAC,4BAA4B,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,CAAC,4BAA4B,CAAC,IAAI,KAAK,CAAC,EAAG,CAAC;AACrD,CAAC;AAcD,MAAM,qBAAqB,GACzB,uBAAQ,CAAC,EAAE,KAAK,KAAK;IACnB,CAAC,CAAC,IAAA,wBAAiB,EAAC,6BAA6B,EAAE,uBAAuB,CAAC;IAC3E,CAAC,CAAC,IAAI,CAAC;AACX,SAAgB,iBAAiB,CAAC,KAA6B;IAC7D,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,CAAC,qBAAqB,CAAC,IAAI,KAAK,CAAC,EAAG,CAAC;AAC9C,CAAC;AAOD,MAAM,4BAA4B,GAChC,uBAAQ,CAAC,EAAE,KAAK,KAAK;IACnB,CAAC,CAAC,IAAA,wBAAiB,EAAC,6BAA6B,EAAE,8BAA8B,CAAC;IAClF,CAAC,CAAC,IAAI,CAAC;AAEX,SAAgB,wBAAwB,CAAC,KAAoC;IAC3E,IAAI,CAAC,4BAA4B,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAG,yBAAU,CAAC,OAAO,CAAC;QAC/B,KAAK,CAAC,KAAK;QACX;YACE,QAAQ,EAAE,UAAU;SACZ;KACX,CAAC,CAAC;IACH,OAAO,CAAC,4BAA4B,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAG,CAAC;AACnE,CAAC;AACD,aAAa","sourcesContent":["'use client';\n\nimport { requireNativeView } from 'expo';\nimport { Platform, StyleSheet, type ViewProps } from 'react-native';\n\n// #region Action View\nexport interface NativeLinkPreviewActionProps {\n title: string;\n icon?: string;\n id: string;\n children?: React.ReactNode;\n}\nconst LinkPreviewNativeActionView: React.ComponentType<NativeLinkPreviewActionProps> | null =\n Platform.OS === 'ios'\n ? requireNativeView('ExpoRouterNativeLinkPreview', 'LinkPreviewNativeActionView')\n : null;\nexport function NativeLinkPreviewAction(props: NativeLinkPreviewActionProps) {\n if (!LinkPreviewNativeActionView) {\n return null;\n }\n return <LinkPreviewNativeActionView {...props} />;\n}\n// #endregion\n\n// #region Trigger View\nexport type NativeLinkPreviewTriggerProps = ViewProps;\nconst NativeLinkPreviewTriggerView: React.ComponentType<NativeLinkPreviewTriggerProps> | null =\n Platform.OS === 'ios'\n ? requireNativeView('ExpoRouterNativeLinkPreview', 'NativeLinkPreviewTrigger')\n : null;\nexport function NativeLinkPreviewTrigger(props: NativeLinkPreviewTriggerProps) {\n if (!NativeLinkPreviewTriggerView) {\n return null;\n }\n return <NativeLinkPreviewTriggerView {...props} />;\n}\n// #endregion\n\n// #region Preview View\nexport interface NativeLinkPreviewProps extends ViewProps {\n nextScreenId: string | undefined;\n onActionSelected?: (event: { nativeEvent: { id: string } }) => void;\n onWillPreviewOpen?: () => void;\n onDidPreviewOpen?: () => void;\n onPreviewWillClose?: () => void;\n onPreviewDidClose?: () => void;\n onPreviewTapped?: () => void;\n children: React.ReactNode;\n}\nconst NativeLinkPreviewView: React.ComponentType<NativeLinkPreviewProps> | null =\n Platform.OS === 'ios'\n ? requireNativeView('ExpoRouterNativeLinkPreview', 'NativeLinkPreviewView')\n : null;\nexport function NativeLinkPreview(props: NativeLinkPreviewProps) {\n if (!NativeLinkPreviewView) {\n return null;\n }\n return <NativeLinkPreviewView {...props} />;\n}\n// #endregion\n\n// #region Preview Content View\nexport interface NativeLinkPreviewContentProps extends ViewProps {\n preferredContentSize?: { width: number; height: number };\n}\nconst NativeLinkPreviewContentView: React.ComponentType<NativeLinkPreviewContentProps> | null =\n Platform.OS === 'ios'\n ? requireNativeView('ExpoRouterNativeLinkPreview', 'NativeLinkPreviewContentView')\n : null;\n\nexport function NativeLinkPreviewContent(props: NativeLinkPreviewContentProps) {\n if (!NativeLinkPreviewContentView) {\n return null;\n }\n const style = StyleSheet.flatten([\n props.style,\n {\n position: 'absolute',\n } as const,\n ]);\n return <NativeLinkPreviewContentView {...props} style={style} />;\n}\n// #endregion\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ParamListBase } from '@react-navigation/native';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
declare const RouterModal: React.ForwardRefExoticComponent<Omit<import("../..").PickPartial<any, "children">, "ref"> & React.RefAttributes<unknown>> & {
|
|
4
|
+
Screen: (props: import("../..").ScreenProps<object, Readonly<{
|
|
5
|
+
key: string;
|
|
6
|
+
index: number;
|
|
7
|
+
routeNames: string[];
|
|
8
|
+
history?: unknown[];
|
|
9
|
+
routes: import("@react-navigation/native").NavigationRoute<ParamListBase, string>[];
|
|
10
|
+
type: string;
|
|
11
|
+
stale: false;
|
|
12
|
+
}>, import("@react-navigation/native").EventMapBase>) => null;
|
|
13
|
+
Protected: typeof import("../../views/Protected").Protected;
|
|
14
|
+
};
|
|
15
|
+
declare const RouterModalScreen: (props: import("../..").ScreenProps<object, Readonly<{
|
|
16
|
+
key: string;
|
|
17
|
+
index: number;
|
|
18
|
+
routeNames: string[];
|
|
19
|
+
history?: unknown[];
|
|
20
|
+
routes: import("@react-navigation/native").NavigationRoute<ParamListBase, string>[];
|
|
21
|
+
type: string;
|
|
22
|
+
stale: false;
|
|
23
|
+
}>, import("@react-navigation/native").EventMapBase>) => null;
|
|
24
|
+
export { RouterModal, RouterModalScreen };
|
|
25
|
+
//# sourceMappingURL=ModalStack.web.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModalStack.web.d.ts","sourceRoot":"","sources":["../../../src/modal/web/ModalStack.web.tsx"],"names":[],"mappings":"AACA,OAAO,EAEL,aAAa,EAOd,MAAM,0BAA0B,CAAC;AAMlC,OAAO,KAAsB,MAAM,OAAO,CAAC;AAwG3C,QAAA,MAAM,WAAW;;;;;;;;;;;CAAkD,CAAC;AACpE,QAAA,MAAM,iBAAiB;;;;;;;;6DAAqB,CAAC;AAE7C,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.RouterModalScreen = exports.RouterModal = void 0;
|
|
38
|
+
const native_1 = require("@react-navigation/native");
|
|
39
|
+
const native_stack_1 = require("@react-navigation/native-stack");
|
|
40
|
+
const react_1 = __importStar(require("react"));
|
|
41
|
+
const ModalStackRouteDrawer_web_1 = require("./ModalStackRouteDrawer.web");
|
|
42
|
+
const TransparentModalStackRouteDrawer_web_1 = require("./TransparentModalStackRouteDrawer.web");
|
|
43
|
+
const utils_1 = require("./utils");
|
|
44
|
+
const withLayoutContext_1 = require("../../layouts/withLayoutContext");
|
|
45
|
+
function ModalStackNavigator({ initialRouteName, children, screenOptions, }) {
|
|
46
|
+
const { state, navigation, descriptors, NavigationContent, describe } = (0, native_1.useNavigationBuilder)(native_1.StackRouter, {
|
|
47
|
+
children,
|
|
48
|
+
screenOptions,
|
|
49
|
+
initialRouteName,
|
|
50
|
+
});
|
|
51
|
+
return (<NavigationContent>
|
|
52
|
+
<ModalStackView state={state} navigation={navigation} descriptors={descriptors} describe={describe}/>
|
|
53
|
+
</NavigationContent>);
|
|
54
|
+
}
|
|
55
|
+
const ModalStackView = ({ state, navigation, descriptors, describe }) => {
|
|
56
|
+
const isWeb = process.env.EXPO_OS === 'web';
|
|
57
|
+
const { colors } = (0, native_1.useTheme)();
|
|
58
|
+
const { routes: filteredRoutes, index: nonModalIndex } = (0, utils_1.convertStackStateToNonModalState)(state, descriptors, isWeb);
|
|
59
|
+
const newStackState = { ...state, routes: filteredRoutes, index: nonModalIndex };
|
|
60
|
+
const dismiss = (0, react_1.useCallback)(() => {
|
|
61
|
+
navigation.goBack();
|
|
62
|
+
}, [navigation]);
|
|
63
|
+
const overlayRoutes = react_1.default.useMemo(() => {
|
|
64
|
+
if (!isWeb)
|
|
65
|
+
return [];
|
|
66
|
+
const idx = (0, utils_1.findLastNonModalIndex)(state, descriptors);
|
|
67
|
+
return state.routes.slice(idx + 1);
|
|
68
|
+
}, [isWeb, state, descriptors]);
|
|
69
|
+
return (<div style={{ flex: 1, display: 'flex' }}>
|
|
70
|
+
<native_stack_1.NativeStackView state={newStackState} navigation={navigation} descriptors={descriptors} describe={describe}/>
|
|
71
|
+
{isWeb &&
|
|
72
|
+
overlayRoutes.map((route) => {
|
|
73
|
+
const isTransparentModal = (0, utils_1.isTransparentModalPresentation)(descriptors[route.key].options);
|
|
74
|
+
if (isTransparentModal) {
|
|
75
|
+
return (<TransparentModalStackRouteDrawer_web_1.TransparentModalStackRouteDrawer key={route.key} routeKey={route.key} options={descriptors[route.key].options} renderScreen={descriptors[route.key].render} onDismiss={dismiss}/>);
|
|
76
|
+
}
|
|
77
|
+
return (<ModalStackRouteDrawer_web_1.ModalStackRouteDrawer key={route.key} routeKey={route.key} options={descriptors[route.key].options} renderScreen={descriptors[route.key].render} onDismiss={dismiss} themeColors={colors}/>);
|
|
78
|
+
})}
|
|
79
|
+
</div>);
|
|
80
|
+
};
|
|
81
|
+
const createModalStack = (0, native_1.createNavigatorFactory)(ModalStackNavigator);
|
|
82
|
+
const RouterModal = (0, withLayoutContext_1.withLayoutContext)(createModalStack().Navigator);
|
|
83
|
+
exports.RouterModal = RouterModal;
|
|
84
|
+
const RouterModalScreen = RouterModal.Screen;
|
|
85
|
+
exports.RouterModalScreen = RouterModalScreen;
|
|
86
|
+
//# sourceMappingURL=ModalStack.web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModalStack.web.js","sourceRoot":"","sources":["../../../src/modal/web/ModalStack.web.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport {\n createNavigatorFactory,\n ParamListBase,\n StackActionHelpers,\n StackNavigationState,\n StackRouter,\n StackRouterOptions,\n useNavigationBuilder,\n useTheme,\n} from '@react-navigation/native';\nimport {\n NativeStackNavigationEventMap,\n NativeStackNavigationOptions,\n NativeStackView,\n} from '@react-navigation/native-stack';\nimport React, { useCallback } from 'react';\n\nimport { ModalStackRouteDrawer } from './ModalStackRouteDrawer.web';\nimport { TransparentModalStackRouteDrawer } from './TransparentModalStackRouteDrawer.web';\nimport { ModalStackNavigatorProps, ModalStackViewProps } from './types';\nimport {\n convertStackStateToNonModalState,\n findLastNonModalIndex,\n isTransparentModalPresentation,\n} from './utils';\nimport { ExtendedStackNavigationOptions } from '../../layouts/StackClient';\nimport { withLayoutContext } from '../../layouts/withLayoutContext';\n\nfunction ModalStackNavigator({\n initialRouteName,\n children,\n screenOptions,\n}: ModalStackNavigatorProps) {\n const { state, navigation, descriptors, NavigationContent, describe } = useNavigationBuilder<\n StackNavigationState<ParamListBase>,\n StackRouterOptions,\n StackActionHelpers<ParamListBase>,\n NativeStackNavigationOptions,\n NativeStackNavigationEventMap\n >(StackRouter, {\n children,\n screenOptions,\n initialRouteName,\n });\n\n return (\n <NavigationContent>\n <ModalStackView\n state={state}\n navigation={navigation}\n descriptors={descriptors}\n describe={describe}\n />\n </NavigationContent>\n );\n}\n\nconst ModalStackView = ({ state, navigation, descriptors, describe }: ModalStackViewProps) => {\n const isWeb = process.env.EXPO_OS === 'web';\n const { colors } = useTheme();\n\n const { routes: filteredRoutes, index: nonModalIndex } = convertStackStateToNonModalState(\n state,\n descriptors,\n isWeb\n );\n\n const newStackState = { ...state, routes: filteredRoutes, index: nonModalIndex };\n\n const dismiss = useCallback(() => {\n navigation.goBack();\n }, [navigation]);\n\n const overlayRoutes = React.useMemo(() => {\n if (!isWeb) return [];\n const idx = findLastNonModalIndex(state, descriptors);\n return state.routes.slice(idx + 1);\n }, [isWeb, state, descriptors]);\n\n return (\n <div style={{ flex: 1, display: 'flex' }}>\n <NativeStackView\n state={newStackState}\n navigation={navigation}\n descriptors={descriptors}\n describe={describe}\n />\n {isWeb &&\n overlayRoutes.map((route) => {\n const isTransparentModal = isTransparentModalPresentation(descriptors[route.key].options);\n\n if (isTransparentModal) {\n return (\n <TransparentModalStackRouteDrawer\n key={route.key}\n routeKey={route.key}\n options={descriptors[route.key].options as ExtendedStackNavigationOptions}\n renderScreen={descriptors[route.key].render}\n onDismiss={dismiss}\n />\n );\n }\n\n return (\n <ModalStackRouteDrawer\n key={route.key}\n routeKey={route.key}\n options={descriptors[route.key].options as ExtendedStackNavigationOptions}\n renderScreen={descriptors[route.key].render}\n onDismiss={dismiss}\n themeColors={colors}\n />\n );\n })}\n </div>\n );\n};\n\nconst createModalStack = createNavigatorFactory(ModalStackNavigator);\nconst RouterModal = withLayoutContext(createModalStack().Navigator);\nconst RouterModalScreen = RouterModal.Screen;\n\nexport { RouterModal, RouterModalScreen };\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ExtendedStackNavigationOptions } from '../../layouts/StackClient';
|
|
3
|
+
declare function ModalStackRouteDrawer({ routeKey, options, renderScreen, onDismiss, themeColors, }: {
|
|
4
|
+
routeKey: string;
|
|
5
|
+
options: ExtendedStackNavigationOptions;
|
|
6
|
+
renderScreen: () => React.ReactNode;
|
|
7
|
+
onDismiss: () => void;
|
|
8
|
+
themeColors: {
|
|
9
|
+
card: string;
|
|
10
|
+
background: string;
|
|
11
|
+
};
|
|
12
|
+
}): React.JSX.Element;
|
|
13
|
+
export { ModalStackRouteDrawer };
|
|
14
|
+
//# sourceMappingURL=ModalStackRouteDrawer.web.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModalStackRouteDrawer.web.d.ts","sourceRoot":"","sources":["../../../src/modal/web/ModalStackRouteDrawer.web.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,OAAO,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAE3E,iBAAS,qBAAqB,CAAC,EAC7B,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,SAAS,EACT,WAAW,GACZ,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,8BAA8B,CAAC;IACxC,YAAY,EAAE,MAAM,KAAK,CAAC,SAAS,CAAC;IACpC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CACnD,qBAkMA;AAED,OAAO,EAAE,qBAAqB,EAAE,CAAC"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.ModalStackRouteDrawer = ModalStackRouteDrawer;
|
|
8
|
+
const react_1 = __importDefault(require("react"));
|
|
9
|
+
const vaul_1 = require("vaul");
|
|
10
|
+
const modalStyles_1 = __importDefault(require("./modalStyles"));
|
|
11
|
+
const utils_1 = require("./utils");
|
|
12
|
+
function ModalStackRouteDrawer({ routeKey, options, renderScreen, onDismiss, themeColors, }) {
|
|
13
|
+
const [open, setOpen] = react_1.default.useState(true);
|
|
14
|
+
// Determine sheet vs. modal with an SSR-safe hook. The first render (during
|
|
15
|
+
// hydration) always assumes mobile/sheet to match the server markup; an
|
|
16
|
+
// effect then updates the state after mount if the viewport is desktop.
|
|
17
|
+
const isDesktop = (0, utils_1.useIsDesktop)();
|
|
18
|
+
const isSheet = !isDesktop;
|
|
19
|
+
// Resolve snap points logic.
|
|
20
|
+
const allowed = options.sheetAllowedDetents;
|
|
21
|
+
const isArrayDetents = Array.isArray(allowed);
|
|
22
|
+
const useCustomSnapPoints = isArrayDetents && !(allowed.length === 1 && allowed[0] === 1);
|
|
23
|
+
let snapPoints = useCustomSnapPoints
|
|
24
|
+
? allowed
|
|
25
|
+
: undefined;
|
|
26
|
+
if (!isSheet) {
|
|
27
|
+
snapPoints = [1];
|
|
28
|
+
}
|
|
29
|
+
const [snap, setSnap] = react_1.default.useState(useCustomSnapPoints && isArrayDetents ? allowed[0] : 1);
|
|
30
|
+
// Update the snap value when custom snap points change.
|
|
31
|
+
react_1.default.useEffect(() => {
|
|
32
|
+
if (isSheet) {
|
|
33
|
+
const next = useCustomSnapPoints && isArrayDetents ? allowed[0] : 1;
|
|
34
|
+
setSnap(next);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// Desktop modal always fixed snap at 1
|
|
38
|
+
setSnap(1);
|
|
39
|
+
}
|
|
40
|
+
}, [isSheet, useCustomSnapPoints, isArrayDetents, allowed]);
|
|
41
|
+
// Map react-native-screens ios sheet undimmed logic to Vaul's fadeFromIndex
|
|
42
|
+
const fadeFromIndex = isSheet
|
|
43
|
+
? options.sheetLargestUndimmedDetentIndex === 'last'
|
|
44
|
+
? (snapPoints?.length ?? 0)
|
|
45
|
+
: typeof options.sheetLargestUndimmedDetentIndex === 'number'
|
|
46
|
+
? options.sheetLargestUndimmedDetentIndex + 1
|
|
47
|
+
: 0
|
|
48
|
+
: 0;
|
|
49
|
+
// --- Styling -----------------------------------------------------------
|
|
50
|
+
// Using CSS variables so defaults live in CSS and can be overridden via props.
|
|
51
|
+
const modalStyleVars = {
|
|
52
|
+
backgroundColor: themeColors.background,
|
|
53
|
+
};
|
|
54
|
+
if (!isSheet) {
|
|
55
|
+
if (options.webModalStyle?.width) {
|
|
56
|
+
modalStyleVars['--expo-router-modal-width'] =
|
|
57
|
+
typeof options.webModalStyle.width === 'number'
|
|
58
|
+
? `${options.webModalStyle.width}px`
|
|
59
|
+
: options.webModalStyle.width;
|
|
60
|
+
modalStyleVars['--expo-router-modal-max-width'] =
|
|
61
|
+
typeof options.webModalStyle.width === 'number'
|
|
62
|
+
? `${options.webModalStyle.width}px`
|
|
63
|
+
: options.webModalStyle.width;
|
|
64
|
+
// Also set explicit width so browsers that ignore CSS vars in `width` prop still work.
|
|
65
|
+
modalStyleVars.width =
|
|
66
|
+
typeof options.webModalStyle.width === 'number'
|
|
67
|
+
? `${options.webModalStyle.width}px`
|
|
68
|
+
: options.webModalStyle.width;
|
|
69
|
+
}
|
|
70
|
+
// Min width override
|
|
71
|
+
if (options.webModalStyle?.minWidth) {
|
|
72
|
+
const mw = typeof options.webModalStyle.minWidth === 'number'
|
|
73
|
+
? `${options.webModalStyle.minWidth}px`
|
|
74
|
+
: options.webModalStyle.minWidth;
|
|
75
|
+
modalStyleVars['--expo-router-modal-min-width'] = mw;
|
|
76
|
+
modalStyleVars.minWidth = mw;
|
|
77
|
+
}
|
|
78
|
+
if (options.webModalStyle?.height) {
|
|
79
|
+
const h = typeof options.webModalStyle.height === 'number'
|
|
80
|
+
? `${options.webModalStyle.height}px`
|
|
81
|
+
: options.webModalStyle.height;
|
|
82
|
+
modalStyleVars['--expo-router-modal-height'] = h;
|
|
83
|
+
modalStyleVars.maxHeight = h;
|
|
84
|
+
modalStyleVars.height = h;
|
|
85
|
+
modalStyleVars.minHeight = h;
|
|
86
|
+
}
|
|
87
|
+
// Separate min-height override (takes precedence over modalHeight)
|
|
88
|
+
if (options.webModalStyle?.minHeight) {
|
|
89
|
+
const mh = typeof options.webModalStyle.minHeight === 'number'
|
|
90
|
+
? `${options.webModalStyle.minHeight}px`
|
|
91
|
+
: options.webModalStyle.minHeight;
|
|
92
|
+
modalStyleVars['--expo-router-modal-min-height'] = mh;
|
|
93
|
+
modalStyleVars.minHeight = mh;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const fitToContents = isSheet && options.sheetAllowedDetents === 'fitToContents';
|
|
97
|
+
if (fitToContents) {
|
|
98
|
+
modalStyleVars.height = 'auto';
|
|
99
|
+
modalStyleVars.minHeight = 'auto';
|
|
100
|
+
// Allow sheet to grow with content but never exceed viewport height
|
|
101
|
+
modalStyleVars.maxHeight = 'calc(100vh)';
|
|
102
|
+
}
|
|
103
|
+
// Apply corner radius (default 10px)
|
|
104
|
+
const radiusValue = options.sheetCornerRadius ?? 10;
|
|
105
|
+
const radiusCss = typeof radiusValue === 'number' ? `${radiusValue}px` : radiusValue;
|
|
106
|
+
if (options.webModalStyle?.border) {
|
|
107
|
+
modalStyleVars['--expo-router-modal-border'] = options.webModalStyle.border;
|
|
108
|
+
}
|
|
109
|
+
if (isSheet) {
|
|
110
|
+
// Only top corners for mobile sheet
|
|
111
|
+
modalStyleVars.borderTopLeftRadius = radiusCss;
|
|
112
|
+
modalStyleVars.borderTopRightRadius = radiusCss;
|
|
113
|
+
// Only apply CSS var override if a custom corner radius was provided
|
|
114
|
+
if (options.sheetCornerRadius) {
|
|
115
|
+
modalStyleVars['--expo-router-modal-border-radius'] = radiusCss;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// All corners for desktop modal
|
|
120
|
+
if (options.sheetCornerRadius) {
|
|
121
|
+
modalStyleVars.borderRadius = radiusCss;
|
|
122
|
+
modalStyleVars['--expo-router-modal-border-radius'] = radiusCss;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// --- End Styling -----------------------------------------------------------
|
|
126
|
+
const handleOpenChange = (open) => {
|
|
127
|
+
if (!open)
|
|
128
|
+
onDismiss();
|
|
129
|
+
};
|
|
130
|
+
// Props that only make sense for sheets
|
|
131
|
+
const sheetProps = isSheet
|
|
132
|
+
? {
|
|
133
|
+
snapPoints: snapPoints,
|
|
134
|
+
activeSnapPoint: snap,
|
|
135
|
+
setActiveSnapPoint: setSnap,
|
|
136
|
+
fadeFromIndex,
|
|
137
|
+
}
|
|
138
|
+
: {};
|
|
139
|
+
return (<vaul_1.Drawer.Root key={`${routeKey}-${isSheet ? 'sheet' : 'modal'}`} open={open} dismissible={options.gestureEnabled ?? true} onAnimationEnd={handleOpenChange} shouldScaleBackground onOpenChange={setOpen} {...sheetProps}>
|
|
140
|
+
<vaul_1.Drawer.Portal>
|
|
141
|
+
<vaul_1.Drawer.Overlay className={modalStyles_1.default.overlay} style={options.webModalStyle?.overlayBackground
|
|
142
|
+
? {
|
|
143
|
+
'--expo-router-modal-overlay-background': options.webModalStyle.overlayBackground,
|
|
144
|
+
}
|
|
145
|
+
: undefined}/>
|
|
146
|
+
<vaul_1.Drawer.Content aria-describedby="modal-description" className={modalStyles_1.default.drawerContent} style={{
|
|
147
|
+
pointerEvents: 'none',
|
|
148
|
+
...(fitToContents ? { height: 'auto' } : null),
|
|
149
|
+
}}>
|
|
150
|
+
<div className={modalStyles_1.default.modal} data-presentation={isSheet ? 'formSheet' : 'modal'} style={modalStyleVars}>
|
|
151
|
+
{/* TODO:(@Hirbod) Figure out how to add title and description to the modal for screen readers in a meaningful way */}
|
|
152
|
+
<vaul_1.Drawer.Title about="" aria-describedby="" className={modalStyles_1.default.srOnly}/>
|
|
153
|
+
<vaul_1.Drawer.Description about="" className={modalStyles_1.default.srOnly}/>
|
|
154
|
+
{/* Render the screen content */}
|
|
155
|
+
<div className={modalStyles_1.default.modalBody}>{renderScreen()}</div>
|
|
156
|
+
</div>
|
|
157
|
+
</vaul_1.Drawer.Content>
|
|
158
|
+
</vaul_1.Drawer.Portal>
|
|
159
|
+
</vaul_1.Drawer.Root>);
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=ModalStackRouteDrawer.web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModalStackRouteDrawer.web.js","sourceRoot":"","sources":["../../../src/modal/web/ModalStackRouteDrawer.web.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport React from 'react';\nimport { Drawer } from 'vaul';\n\nimport modalStyles from './modalStyles';\nimport { CSSWithVars } from './types';\nimport { useIsDesktop } from './utils';\nimport { ExtendedStackNavigationOptions } from '../../layouts/StackClient';\n\nfunction ModalStackRouteDrawer({\n routeKey,\n options,\n renderScreen,\n onDismiss,\n themeColors,\n}: {\n routeKey: string;\n options: ExtendedStackNavigationOptions;\n renderScreen: () => React.ReactNode;\n onDismiss: () => void;\n themeColors: { card: string; background: string };\n}) {\n const [open, setOpen] = React.useState(true);\n // Determine sheet vs. modal with an SSR-safe hook. The first render (during\n // hydration) always assumes mobile/sheet to match the server markup; an\n // effect then updates the state after mount if the viewport is desktop.\n const isDesktop = useIsDesktop();\n const isSheet = !isDesktop;\n\n // Resolve snap points logic.\n const allowed = options.sheetAllowedDetents;\n\n const isArrayDetents = Array.isArray(allowed);\n const useCustomSnapPoints = isArrayDetents && !(allowed.length === 1 && allowed[0] === 1);\n\n let snapPoints: (number | string)[] | undefined = useCustomSnapPoints\n ? (allowed as (number | string)[])\n : undefined;\n\n if (!isSheet) {\n snapPoints = [1];\n }\n\n const [snap, setSnap] = React.useState<number | string | null>(\n useCustomSnapPoints && isArrayDetents ? allowed[0] : 1\n );\n\n // Update the snap value when custom snap points change.\n React.useEffect(() => {\n if (isSheet) {\n const next = useCustomSnapPoints && isArrayDetents ? allowed[0] : 1;\n setSnap(next);\n } else {\n // Desktop modal always fixed snap at 1\n setSnap(1);\n }\n }, [isSheet, useCustomSnapPoints, isArrayDetents, allowed]);\n\n // Map react-native-screens ios sheet undimmed logic to Vaul's fadeFromIndex\n const fadeFromIndex = isSheet\n ? options.sheetLargestUndimmedDetentIndex === 'last'\n ? (snapPoints?.length ?? 0)\n : typeof options.sheetLargestUndimmedDetentIndex === 'number'\n ? options.sheetLargestUndimmedDetentIndex + 1\n : 0\n : 0;\n\n // --- Styling -----------------------------------------------------------\n\n // Using CSS variables so defaults live in CSS and can be overridden via props.\n const modalStyleVars: CSSWithVars = {\n backgroundColor: themeColors.background,\n };\n\n if (!isSheet) {\n if (options.webModalStyle?.width) {\n modalStyleVars['--expo-router-modal-width'] =\n typeof options.webModalStyle.width === 'number'\n ? `${options.webModalStyle.width}px`\n : options.webModalStyle.width;\n\n modalStyleVars['--expo-router-modal-max-width'] =\n typeof options.webModalStyle.width === 'number'\n ? `${options.webModalStyle.width}px`\n : options.webModalStyle.width;\n\n // Also set explicit width so browsers that ignore CSS vars in `width` prop still work.\n modalStyleVars.width =\n typeof options.webModalStyle.width === 'number'\n ? `${options.webModalStyle.width}px`\n : options.webModalStyle.width;\n }\n\n // Min width override\n if (options.webModalStyle?.minWidth) {\n const mw =\n typeof options.webModalStyle.minWidth === 'number'\n ? `${options.webModalStyle.minWidth}px`\n : options.webModalStyle.minWidth;\n modalStyleVars['--expo-router-modal-min-width'] = mw;\n modalStyleVars.minWidth = mw;\n }\n\n if (options.webModalStyle?.height) {\n const h =\n typeof options.webModalStyle.height === 'number'\n ? `${options.webModalStyle.height}px`\n : options.webModalStyle.height;\n modalStyleVars['--expo-router-modal-height'] = h;\n modalStyleVars.maxHeight = h;\n modalStyleVars.height = h;\n modalStyleVars.minHeight = h;\n }\n\n // Separate min-height override (takes precedence over modalHeight)\n if (options.webModalStyle?.minHeight) {\n const mh =\n typeof options.webModalStyle.minHeight === 'number'\n ? `${options.webModalStyle.minHeight}px`\n : options.webModalStyle.minHeight;\n modalStyleVars['--expo-router-modal-min-height'] = mh;\n modalStyleVars.minHeight = mh;\n }\n }\n\n const fitToContents = isSheet && options.sheetAllowedDetents === 'fitToContents';\n\n if (fitToContents) {\n modalStyleVars.height = 'auto';\n modalStyleVars.minHeight = 'auto';\n // Allow sheet to grow with content but never exceed viewport height\n modalStyleVars.maxHeight = 'calc(100vh)';\n }\n\n // Apply corner radius (default 10px)\n const radiusValue = options.sheetCornerRadius ?? 10;\n const radiusCss = typeof radiusValue === 'number' ? `${radiusValue}px` : radiusValue;\n\n if (options.webModalStyle?.border) {\n modalStyleVars['--expo-router-modal-border'] = options.webModalStyle.border;\n }\n\n if (isSheet) {\n // Only top corners for mobile sheet\n modalStyleVars.borderTopLeftRadius = radiusCss;\n modalStyleVars.borderTopRightRadius = radiusCss;\n\n // Only apply CSS var override if a custom corner radius was provided\n if (options.sheetCornerRadius) {\n modalStyleVars['--expo-router-modal-border-radius'] = radiusCss;\n }\n } else {\n // All corners for desktop modal\n if (options.sheetCornerRadius) {\n modalStyleVars.borderRadius = radiusCss;\n modalStyleVars['--expo-router-modal-border-radius'] = radiusCss;\n }\n }\n // --- End Styling -----------------------------------------------------------\n\n const handleOpenChange = (open: boolean) => {\n if (!open) onDismiss();\n };\n\n // Props that only make sense for sheets\n const sheetProps = isSheet\n ? {\n snapPoints: snapPoints as (number | string)[],\n activeSnapPoint: snap,\n setActiveSnapPoint: setSnap,\n fadeFromIndex,\n }\n : {};\n\n return (\n <Drawer.Root\n key={`${routeKey}-${isSheet ? 'sheet' : 'modal'}`}\n open={open}\n dismissible={options.gestureEnabled ?? true}\n onAnimationEnd={handleOpenChange}\n shouldScaleBackground\n onOpenChange={setOpen}\n {...sheetProps}>\n <Drawer.Portal>\n <Drawer.Overlay\n className={modalStyles.overlay}\n style={\n options.webModalStyle?.overlayBackground\n ? ({\n '--expo-router-modal-overlay-background': options.webModalStyle.overlayBackground,\n } as React.CSSProperties)\n : undefined\n }\n />\n <Drawer.Content\n aria-describedby=\"modal-description\"\n className={modalStyles.drawerContent}\n style={{\n pointerEvents: 'none',\n ...(fitToContents ? { height: 'auto' } : null),\n }}>\n <div\n className={modalStyles.modal}\n data-presentation={isSheet ? 'formSheet' : 'modal'}\n style={modalStyleVars}>\n {/* TODO:(@Hirbod) Figure out how to add title and description to the modal for screen readers in a meaningful way */}\n <Drawer.Title about=\"\" aria-describedby=\"\" className={modalStyles.srOnly} />\n <Drawer.Description about=\"\" className={modalStyles.srOnly} />\n {/* Render the screen content */}\n <div className={modalStyles.modalBody}>{renderScreen()}</div>\n </div>\n </Drawer.Content>\n </Drawer.Portal>\n </Drawer.Root>\n );\n}\n\nexport { ModalStackRouteDrawer };\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ExtendedStackNavigationOptions } from '../../layouts/StackClient';
|
|
3
|
+
declare function TransparentModalStackRouteDrawer({ routeKey, options, renderScreen, onDismiss, }: {
|
|
4
|
+
routeKey: string;
|
|
5
|
+
options: ExtendedStackNavigationOptions;
|
|
6
|
+
renderScreen: () => React.ReactNode;
|
|
7
|
+
onDismiss: () => void;
|
|
8
|
+
}): React.JSX.Element;
|
|
9
|
+
export { TransparentModalStackRouteDrawer };
|
|
10
|
+
//# sourceMappingURL=TransparentModalStackRouteDrawer.web.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TransparentModalStackRouteDrawer.web.d.ts","sourceRoot":"","sources":["../../../src/modal/web/TransparentModalStackRouteDrawer.web.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAE3E,iBAAS,gCAAgC,CAAC,EACxC,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,8BAA8B,CAAC;IACxC,YAAY,EAAE,MAAM,KAAK,CAAC,SAAS,CAAC;IACpC,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB,qBAsBA;AAED,OAAO,EAAE,gCAAgC,EAAE,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.TransparentModalStackRouteDrawer = TransparentModalStackRouteDrawer;
|
|
8
|
+
const react_1 = __importDefault(require("react"));
|
|
9
|
+
const vaul_1 = require("vaul");
|
|
10
|
+
const modalStyles_1 = __importDefault(require("./modalStyles"));
|
|
11
|
+
function TransparentModalStackRouteDrawer({ routeKey, options, renderScreen, onDismiss, }) {
|
|
12
|
+
const handleOpenChange = (open) => {
|
|
13
|
+
if (!open)
|
|
14
|
+
onDismiss();
|
|
15
|
+
};
|
|
16
|
+
return (<vaul_1.Drawer.Root defaultOpen key={`${routeKey}-transparent`} dismissible={options.gestureEnabled ?? false} onAnimationEnd={handleOpenChange}>
|
|
17
|
+
<vaul_1.Drawer.Portal>
|
|
18
|
+
<vaul_1.Drawer.Content className={modalStyles_1.default.transparentDrawerContent}>
|
|
19
|
+
{/* TODO:(@Hirbod) Figure out how to add title and description to the modal for screen readers in a meaningful way */}
|
|
20
|
+
<vaul_1.Drawer.Title about="" aria-describedby="" className={modalStyles_1.default.srOnly}/>
|
|
21
|
+
<vaul_1.Drawer.Description about="" className={modalStyles_1.default.srOnly}/>
|
|
22
|
+
{/* Render the screen content */}
|
|
23
|
+
<div className={modalStyles_1.default.modalBody}>{renderScreen()}</div>
|
|
24
|
+
</vaul_1.Drawer.Content>
|
|
25
|
+
</vaul_1.Drawer.Portal>
|
|
26
|
+
</vaul_1.Drawer.Root>);
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=TransparentModalStackRouteDrawer.web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TransparentModalStackRouteDrawer.web.js","sourceRoot":"","sources":["../../../src/modal/web/TransparentModalStackRouteDrawer.web.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;;AAyCJ,4EAAgC;AAxCzC,kDAA0B;AAC1B,+BAA8B;AAE9B,gEAAwC;AAGxC,SAAS,gCAAgC,CAAC,EACxC,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,SAAS,GAMV;IACC,MAAM,gBAAgB,GAAG,CAAC,IAAa,EAAE,EAAE;QACzC,IAAI,CAAC,IAAI;YAAE,SAAS,EAAE,CAAC;IACzB,CAAC,CAAC;IAEF,OAAO,CACL,CAAC,aAAM,CAAC,IAAI,CACV,WAAW,CACX,GAAG,CAAC,CAAC,GAAG,QAAQ,cAAc,CAAC,CAC/B,WAAW,CAAC,CAAC,OAAO,CAAC,cAAc,IAAI,KAAK,CAAC,CAC7C,cAAc,CAAC,CAAC,gBAAgB,CAAC,CACjC;MAAA,CAAC,aAAM,CAAC,MAAM,CACZ;QAAA,CAAC,aAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,qBAAW,CAAC,wBAAwB,CAAC,CAC9D;UAAA,CAAC,oHAAoH,CACrH;UAAA,CAAC,aAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,qBAAW,CAAC,MAAM,CAAC,EACzE;UAAA,CAAC,aAAM,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,qBAAW,CAAC,MAAM,CAAC,EAC3D;UAAA,CAAC,+BAA+B,CAChC;UAAA,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,qBAAW,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,EAAE,GAAG,CAC9D;QAAA,EAAE,aAAM,CAAC,OAAO,CAClB;MAAA,EAAE,aAAM,CAAC,MAAM,CACjB;IAAA,EAAE,aAAM,CAAC,IAAI,CAAC,CACf,CAAC;AACJ,CAAC","sourcesContent":["'use client';\nimport React from 'react';\nimport { Drawer } from 'vaul';\n\nimport modalStyles from './modalStyles';\nimport { ExtendedStackNavigationOptions } from '../../layouts/StackClient';\n\nfunction TransparentModalStackRouteDrawer({\n routeKey,\n options,\n renderScreen,\n onDismiss,\n}: {\n routeKey: string;\n options: ExtendedStackNavigationOptions;\n renderScreen: () => React.ReactNode;\n onDismiss: () => void;\n}) {\n const handleOpenChange = (open: boolean) => {\n if (!open) onDismiss();\n };\n\n return (\n <Drawer.Root\n defaultOpen\n key={`${routeKey}-transparent`}\n dismissible={options.gestureEnabled ?? false}\n onAnimationEnd={handleOpenChange}>\n <Drawer.Portal>\n <Drawer.Content className={modalStyles.transparentDrawerContent}>\n {/* TODO:(@Hirbod) Figure out how to add title and description to the modal for screen readers in a meaningful way */}\n <Drawer.Title about=\"\" aria-describedby=\"\" className={modalStyles.srOnly} />\n <Drawer.Description about=\"\" className={modalStyles.srOnly} />\n {/* Render the screen content */}\n <div className={modalStyles.modalBody}>{renderScreen()}</div>\n </Drawer.Content>\n </Drawer.Portal>\n </Drawer.Root>\n );\n}\n\nexport { TransparentModalStackRouteDrawer };\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modalStyles.d.ts","sourceRoot":"","sources":["../../../src/modal/web/modalStyles.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,kCAAkC,CAAC;AAEtD,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const modal_module_css_1 = __importDefault(require("../../../assets/modal.module.css"));
|
|
7
|
+
exports.default = modal_module_css_1.default;
|
|
8
|
+
//# sourceMappingURL=modalStyles.js.map
|