UNPKG

next-sanity

Version:
115 lines (114 loc) 4.61 kB
import { jsx } from "react/jsx-runtime"; import { VisualEditing as VisualEditing$1 } from "@sanity/visual-editing/react"; import { useRouter, usePathname, useSearchParams } from "next/navigation.js"; import { revalidateRootLayout } from "next-sanity/visual-editing/server-actions"; import { useRef, useState, useEffect, useMemo, useCallback } from "react"; function pathHasPrefix(path, prefix) { if (typeof path != "string") return !1; const { pathname } = parsePath(path); return pathname === prefix || pathname.startsWith(`${prefix}/`); } function parsePath(path) { const hashIndex = path.indexOf("#"), queryIndex = path.indexOf("?"), hasQuery = queryIndex > -1 && (hashIndex < 0 || queryIndex < hashIndex); return hasQuery || hashIndex > -1 ? { pathname: path.substring(0, hasQuery ? queryIndex : hashIndex), query: hasQuery ? path.substring(queryIndex, hashIndex > -1 ? hashIndex : void 0) : "", hash: hashIndex > -1 ? path.slice(hashIndex) : "" } : { pathname: path, query: "", hash: "" }; } function addPathPrefix(path, prefix) { if (!path.startsWith("/") || !prefix) return path; if (path === "/" && prefix) return prefix; const { pathname, query, hash } = parsePath(path); return `${prefix}${pathname}${query}${hash}`; } function removePathPrefix(path, prefix) { if (!pathHasPrefix(path, prefix)) return path; const withoutPrefix = path.slice(prefix.length); return withoutPrefix.startsWith("/") ? withoutPrefix : `/${withoutPrefix}`; } const normalizePathTrailingSlash = (path, trailingSlash) => { const { pathname, query, hash } = parsePath(path); return trailingSlash ? pathname.endsWith("/") ? `${pathname}${query}${hash}` : `${pathname}/${query}${hash}` : `${removeTrailingSlash(pathname)}${query}${hash}`; }; function removeTrailingSlash(route) { return route.replace(/\/$/, "") || "/"; } function VisualEditing(props) { const { basePath = "", plugins, components, refresh, trailingSlash = !1, zIndex } = props, router = useRouter(), routerRef = useRef(router), [navigate, setNavigate] = useState(); useEffect(() => { routerRef.current = router; }, [router]); const history = useMemo( () => ({ subscribe: (_navigate) => (setNavigate(() => _navigate), () => setNavigate(void 0)), update: (update) => { switch (update.type) { case "push": return routerRef.current.push(removePathPrefix(update.url, basePath)); case "pop": return routerRef.current.back(); case "replace": return routerRef.current.replace(removePathPrefix(update.url, basePath)); default: throw new Error(`Unknown update type: ${update.type}`); } } }), [basePath] ), pathname = usePathname(), searchParams = useSearchParams(); useEffect(() => { navigate && navigate({ type: "push", url: normalizePathTrailingSlash( addPathPrefix(`${pathname}${searchParams?.size ? `?${searchParams}` : ""}`, basePath), trailingSlash ) }); }, [basePath, navigate, pathname, searchParams, trailingSlash]); const handleRefresh = useCallback( (payload) => { if (refresh) return refresh(payload); const manualFastRefresh = () => (console.debug( "Live preview is setup, calling router.refresh() to refresh the server components without refetching cached data" ), routerRef.current.refresh(), Promise.resolve()), manualFallbackRefresh = () => (console.debug( "No loaders in live mode detected, or preview kit setup, revalidating root layout" ), revalidateRootLayout()), mutationFallbackRefresh = () => (console.debug( "No loaders in live mode detected, or preview kit setup, revalidating root layout" ), revalidateRootLayout()); switch (payload.source) { case "manual": return payload.livePreviewEnabled ? manualFastRefresh() : manualFallbackRefresh(); case "mutation": return payload.livePreviewEnabled ? mutationFastRefresh() : mutationFallbackRefresh(); default: throw new Error("Unknown refresh source", { cause: payload }); } }, [refresh] ); return /* @__PURE__ */ jsx( VisualEditing$1, { plugins, components, history, portal: !0, refresh: handleRefresh, zIndex } ); } function mutationFastRefresh() { return console.debug( "Live preview is setup, mutation is skipped assuming its handled by the live preview" ), !1; } export { VisualEditing as default }; //# sourceMappingURL=VisualEditing.js.map