UNPKG

hydrogen-sanity

Version:
129 lines (125 loc) 4.04 kB
import { isMaybePresentation } from '@sanity/presentation-comlink'; import { enableVisualEditing } from '@sanity/visual-editing'; import { useRef, useState, useEffect, useMemo } from 'react'; import { useNavigate, useLocation, useSubmit, useRevalidator } from 'react-router'; import { useEffectEvent } from 'use-effect-event'; import { isServer, sanitizePerspective } from './utils.js'; import { useRefresh } from './refresh.js'; import { useHasActiveLoaders } from './registry.js'; function useHistory() { const navigateRemix = useNavigate(); const navigateRemixRef = useRef(navigateRemix); const [navigate, setNavigate] = useState(); const location = useLocation(); const isProgrammaticNavRef = useRef(false); useEffect(() => { navigateRemixRef.current = navigateRemix; }, [navigateRemix]); useEffect(() => { if (navigate && !isProgrammaticNavRef.current) { navigate({ type: "push", url: `${location.pathname}${location.search}${location.hash}` }); } isProgrammaticNavRef.current = false; }, [location.hash, location.pathname, location.search, navigate]); const historyAdapter = useMemo( () => ({ subscribe(_navigate) { setNavigate(() => _navigate); return () => setNavigate(void 0); }, update(update) { isProgrammaticNavRef.current = true; if (update.type === "push" || update.type === "replace") { navigateRemixRef.current(update.url, { replace: update.type === "replace" }); } else if (update.type === "pop") { navigateRemixRef.current(-1); } } }), [] ); return historyAdapter; } if (isServer()) { throw new Error( "Overlays should only run client-side. Please check that this file is not being imported into a worker or server bundle." ); } function OverlaysClient(props) { const { components, zIndex, refresh, action = "/api/preview" } = props; const submit = useSubmit(); const revalidator = useRevalidator(); const { refreshHandler } = useRefresh(); const refreshFn = refreshHandler(refresh); const historyAdapter = useHistory(); const hasActiveLoaders = useHasActiveLoaders(); const [inStudioContext] = useState(() => { if (isServer()) { return null; } return isMaybePresentation(); }); const handlePerspectiveChange = useEffectEvent((perspective) => { const cleanPerspective = sanitizePerspective(perspective); const formData = new FormData(); formData.set( "perspective", Array.isArray(cleanPerspective) ? cleanPerspective.join(",") : cleanPerspective ); submit(formData, { method: "PUT", action, navigate: false, preventScrollReset: true }); refreshFn({ source: "manual", livePreviewEnabled: false // Force server revalidation for perspective changes }); }); const handleRefresh = useEffectEvent((payload) => { if (refresh) { return refresh(payload, () => refreshFn(payload), revalidator); } switch (payload.source) { case "manual": return refreshFn(payload); default: if (hasActiveLoaders) { return false; } return refreshFn(payload); } }); useEffect(() => { if (isServer() || !inStudioContext) return void 0; const handleMessage = (event) => { const { type, data } = event.data || {}; if (type === "presentation/perspective") { handlePerspectiveChange(data.perspective); } }; window.addEventListener("message", handleMessage); return () => { window.removeEventListener("message", handleMessage); }; }, [inStudioContext]); useEffect(() => { const disable = enableVisualEditing({ components, zIndex, refresh: handleRefresh, history: historyAdapter }); return () => disable(); }, [components, zIndex, historyAdapter]); return null; } export { OverlaysClient as default }; //# sourceMappingURL=Overlays.client.js.map