UNPKG

@tanstack/solid-router

Version:

Modern and scalable routing for Solid applications

145 lines (144 loc) 4.36 kB
const require_runtime = require("./_virtual/_rolldown/runtime.cjs"); const require_useRouter = require("./useRouter.cjs"); let solid_js_web = require("solid-js/web"); let solid_js = require("solid-js"); solid_js = require_runtime.__toESM(solid_js); //#region src/useBlocker.tsx function _resolveBlockerOpts(opts, condition) { if (opts === void 0) return { shouldBlockFn: () => true, withResolver: false }; if ("shouldBlockFn" in opts) return opts; if (typeof opts === "function") { const shouldBlock = Boolean(condition ?? true); const _customBlockerFn = async () => { if (shouldBlock) return await opts(); return false; }; return { shouldBlockFn: _customBlockerFn, enableBeforeUnload: shouldBlock, withResolver: false }; } const shouldBlock = solid_js.createMemo(() => Boolean(opts.condition ?? true)); const _customBlockerFn = async () => { if (shouldBlock() && opts.blockerFn !== void 0) return await opts.blockerFn(); return shouldBlock(); }; return { get shouldBlockFn() { return _customBlockerFn; }, get enableBeforeUnload() { return shouldBlock(); }, get withResolver() { return opts.blockerFn === void 0; } }; } function useBlocker(opts, condition) { const props = solid_js.mergeProps({ enableBeforeUnload: true, disabled: false, withResolver: false }, _resolveBlockerOpts(opts, condition)); const router = require_useRouter.useRouter(); const [resolver, setResolver] = solid_js.createSignal({ status: "idle", current: void 0, next: void 0, action: void 0, proceed: void 0, reset: void 0 }); solid_js.createEffect(() => { const blockerFnComposed = async (blockerFnArgs) => { function getLocation(location) { const parsedLocation = router.parseLocation(location); const matchedRoutes = router.getMatchedRoutes(parsedLocation.pathname); if (matchedRoutes.foundRoute === void 0) return { routeId: "__notFound__", fullPath: parsedLocation.pathname, pathname: parsedLocation.pathname, params: matchedRoutes.routeParams, search: parsedLocation.search }; return { routeId: matchedRoutes.foundRoute.id, fullPath: matchedRoutes.foundRoute.fullPath, pathname: parsedLocation.pathname, params: matchedRoutes.routeParams, search: parsedLocation.search }; } const current = getLocation(blockerFnArgs.currentLocation); const next = getLocation(blockerFnArgs.nextLocation); if (current.routeId === "__notFound__" && next.routeId !== "__notFound__") return false; const shouldBlock = await props.shouldBlockFn({ action: blockerFnArgs.action, current, next }); if (!props.withResolver) return shouldBlock; if (!shouldBlock) return false; const canNavigateAsync = await new Promise((resolve) => { setResolver({ status: "blocked", current, next, action: blockerFnArgs.action, proceed: () => resolve(false), reset: () => resolve(true) }); }); setResolver({ status: "idle", current: void 0, next: void 0, action: void 0, proceed: void 0, reset: void 0 }); return canNavigateAsync; }; const disposeBlock = props.disabled ? void 0 : router.history.block({ blockerFn: blockerFnComposed, enableBeforeUnload: props.enableBeforeUnload }); solid_js.onCleanup(() => disposeBlock?.()); }); return resolver; } var _resolvePromptBlockerArgs = (props) => { if ("shouldBlockFn" in props) return props; const shouldBlock = solid_js.createMemo(() => Boolean(props.condition ?? true)); const _customBlockerFn = async () => { if (shouldBlock() && props.blockerFn !== void 0) return await props.blockerFn(); return shouldBlock; }; return { shouldBlockFn: _customBlockerFn, get enableBeforeUnload() { return shouldBlock(); }, get withResolver() { return props.blockerFn === void 0; } }; }; var Block = function Block(opts) { const [propsWithChildren, rest] = solid_js.splitProps(opts, ["children"]); const resolver = useBlocker(_resolvePromptBlockerArgs(rest)); return (0, solid_js_web.memo)(solid_js.createMemo(() => { const child = propsWithChildren.children; if (resolver && typeof child === "function") return child(resolver()); return child; })); }; //#endregion exports.Block = Block; exports.useBlocker = useBlocker; //# sourceMappingURL=useBlocker.cjs.map