next-sanity
Version:
Sanity.io toolkit for Next.js
115 lines (114 loc) • 4.61 kB
JavaScript
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