sanity
Version:
Sanity is a real-time content infrastructure with a scalable, hosted backend featuring a Graph Oriented Query Language (GROQ), asset pipelines and fast edge caches
628 lines (626 loc) • 28.5 kB
JavaScript
import { c } from "react-compiler-runtime";
import { useContext, useEffect, useState, createElement, useLayoutEffect, lazy, Suspense } from "react";
import { PresentationSharedStateContext, PresentationContext, PresentationDocumentContext, PresentationNavigateContext, PresentationParamsContext } from "sanity/_singletons";
import { jsxs, Fragment, jsx } from "react/jsx-runtime";
import { useDocumentStore, usePerspective, isRecord, isReference, getDraftId, defineLocaleResourceBundle, useTranslation, defineDocumentFieldAction, useWorkspace, pathToString, getPublishedId, definePlugin, getVersionFromId, isDocumentSchemaType } from "sanity";
import { ComposeIcon, ErrorOutlineIcon, WarningOutlineIcon, InfoOutlineIcon, ChevronRightIcon, DesktopIcon, MasterDetailIcon } from "@sanity/icons";
import { apiVersion } from "@sanity/preview-url-secret/constants";
import { Card, Flex, Box, Spinner, Text, Stack, rem } from "@sanity/ui";
import { styled } from "styled-components";
import get from "lodash/get.js";
import { Observable, switchMap, from, of, isObservable, map, combineLatest, mergeAll, scan } from "rxjs";
import { useIntentLink, useRouter, encodeJsonParams, route } from "sanity/router";
import { useEffectEvent } from "use-effect-event";
import { uuid } from "@sanity/uuid";
import { parse, object, fallback, boolean, picklist } from "valibot";
const useSharedState = (key, value) => {
const $ = c(5), context = useContext(PresentationSharedStateContext);
if (!context)
throw new Error("Preview Snapshots context is missing");
const {
setValue
} = context;
let t0, t1;
$[0] !== key || $[1] !== setValue || $[2] !== value ? (t0 = () => {
setValue(key, value);
}, t1 = [key, value, setValue], $[0] = key, $[1] = setValue, $[2] = value, $[3] = t0, $[4] = t1) : (t0 = $[3], t1 = $[4]), useEffect(t0, t1);
}, DEFAULT_TOOL_ICON = ComposeIcon, DEFAULT_TOOL_NAME = "presentation", DEFAULT_TOOL_TITLE = "Presentation", EDIT_INTENT_MODE = "presentation", MAX_TIME_TO_OVERLAYS_CONNECTION = 3e3, API_VERSION = apiVersion, MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL = 1e3, LOADER_QUERY_GC_INTERVAL = 3e4, POPUP_CHECK_INTERVAL = 1e3;
function keysOf(value) {
return Object.keys(value);
}
function setKey(source, key, value) {
return {
...source,
[key]: value
};
}
function props(options = {}) {
return (source) => new Observable((observer) => source.subscribe(observer)).pipe(switchMap((object2) => {
const keyObservables = keysOf(object2).map((key) => {
const value = object2[key];
return isObservable(value) ? from(value).pipe(map((val) => [key, val])) : of([key, value]);
});
return options.wait ? combineLatest(keyObservables).pipe(map((pairs) => pairs.reduce((acc, [key, value]) => setKey(acc, key, value), {}))) : from(keyObservables).pipe(mergeAll(), scan((acc, [key, value]) => setKey(acc, key, value), {}));
}));
}
const INITIAL_STATE = {
locations: []
};
function getDocumentId(value) {
return isReference(value) ? value._ref : "_id" in value ? value._id : void 0;
}
function cleanPreviewable(id, previewable) {
const clean = id ? {
...previewable,
_id: id
} : {
...previewable
};
return clean._type === "reference" && (delete clean._type, delete clean._ref, delete clean._weak, delete clean._dataset, delete clean._projectId, delete clean._strengthenOnPublish), clean;
}
function listen(id, fields, store) {
const query = {
fetch: `*[_id==$id][0]{${fields.join(", ")}}`,
// TODO: is it more performant to use `||` instead of `in`?
listen: "*[_id in [$id,$draftId]]"
}, params = {
id,
draftId: getDraftId(id)
};
return store.listenQuery(query, params, {
perspective: "drafts",
tag: "drafts"
});
}
function observeDocument(value, paths, store) {
if (!value || typeof value != "object")
return of(value);
const id = getDocumentId(value), currentValue = cleanPreviewable(id, value), headlessPaths = paths.filter((path) => !(path[0] in currentValue));
if (id && headlessPaths.length) {
const fields = [...new Set(headlessPaths.map((path) => path[0]))];
return listen(id, fields, store).pipe(switchMap((snapshot) => snapshot ? observeDocument(snapshot, paths, store) : of(null)));
}
const leads = {};
paths.forEach((path) => {
const [head, ...tail] = path;
leads[head] || (leads[head] = []), leads[head].push(tail);
});
const next = Object.keys(leads).reduce((res, head) => {
const tails = leads[head].filter((tail) => tail.length > 0);
return tails.length === 0 ? res[head] = isRecord(value) ? value[head] : void 0 : res[head] = observeDocument(value[head], tails, store), res;
}, currentValue);
return of(next).pipe(props({
wait: !0
}));
}
function observeForLocations(documentId, resolver, documentStore) {
const {
select
} = resolver, paths = Object.values(select).map((value) => String(value).split(".")) || [];
return observeDocument({
_type: "reference",
_ref: documentId
}, paths, documentStore).pipe(map((doc2) => Object.keys(select).reduce((acc, key) => (acc[key] = get(doc2, select[key]), acc), {})), map(resolver.resolve));
}
function useDocumentLocations(props2) {
const $ = c(19), {
id,
resolvers,
type,
version
} = props2, documentStore = useDocumentStore(), {
perspectiveStack
} = usePerspective(), [locationsState, setLocationsState] = useState(INITIAL_STATE), resolver = resolvers && (typeof resolvers == "function" ? resolvers : resolvers[type]), [locationsStatus, setLocationsStatus] = useState(resolver ? "resolving" : "empty");
let t0;
bb0: {
if (!resolver) {
t0 = void 0;
break bb0;
}
if (typeof resolver == "function") {
let t13;
if ($[0] !== documentStore || $[1] !== id || $[2] !== perspectiveStack || $[3] !== resolver || $[4] !== type || $[5] !== version) {
const _result = resolver({
id,
type,
version,
perspectiveStack
}, {
documentStore
});
t13 = isObservable(_result) ? _result : of(_result), $[0] = documentStore, $[1] = id, $[2] = perspectiveStack, $[3] = resolver, $[4] = type, $[5] = version, $[6] = t13;
} else
t13 = $[6];
t0 = t13;
break bb0;
}
if ("select" in resolver && "resolve" in resolver) {
let t13;
$[7] !== documentStore || $[8] !== id || $[9] !== resolver ? (t13 = observeForLocations(id, resolver, documentStore), $[7] = documentStore, $[8] = id, $[9] = resolver, $[10] = t13) : t13 = $[10], t0 = t13;
break bb0;
}
let t12;
$[11] !== resolver ? (t12 = of(resolver), $[11] = resolver, $[12] = t12) : t12 = $[12], t0 = t12;
}
const result = t0;
let t1, t2;
$[13] !== result ? (t1 = () => {
const sub = result?.subscribe((state) => {
setLocationsState(state || INITIAL_STATE), setLocationsStatus(state ? "resolved" : "empty");
});
return () => sub?.unsubscribe();
}, t2 = [result], $[13] = result, $[14] = t1, $[15] = t2) : (t1 = $[14], t2 = $[15]), useEffect(t1, t2);
let t3;
return $[16] !== locationsState || $[17] !== locationsStatus ? (t3 = {
state: locationsState,
status: locationsStatus
}, $[16] = locationsState, $[17] = locationsStatus, $[18] = t3) : t3 = $[18], t3;
}
const presentationLocaleNamespace = "presentation", presentationUsEnglishLocaleBundle = defineLocaleResourceBundle({
locale: "en-US",
namespace: presentationLocaleNamespace,
resources: () => import("./resources6.mjs")
});
function usePresentationTool(t0) {
const throwOnMissingContext = t0 === void 0 ? !0 : t0, presentation = useContext(PresentationContext);
if (throwOnMissingContext && !presentation)
throw new Error("Presentation context is missing");
return presentation;
}
function useCurrentPresentationToolName() {
return usePresentationTool(!1)?.name ?? void 0;
}
const TONE_ICONS = {
positive: InfoOutlineIcon,
caution: WarningOutlineIcon,
critical: ErrorOutlineIcon
};
function LocationsBanner(props2) {
const $ = c(34), {
documentId,
isResolving,
options,
schemaType,
showPresentationTitle
} = props2, {
locations,
message,
tone
} = props2.state, len = locations?.length || 0, {
t
} = useTranslation(presentationLocaleNamespace), presentation = useContext(PresentationContext), presentationName = presentation?.name, [expanded, setExpanded] = useState(!1);
let t0;
$[0] !== len ? (t0 = () => {
len && setExpanded(_temp$1);
}, $[0] = len, $[1] = t0) : t0 = $[1];
const toggle = t0;
let t1;
$[2] !== isResolving || $[3] !== len || $[4] !== message || $[5] !== t ? (t1 = isResolving ? t("locations-banner.resolving.text") : message || t("locations-banner.locations-count", {
count: len
}), $[2] = isResolving, $[3] = len, $[4] = message, $[5] = t, $[6] = t1) : t1 = $[6];
const title = t1, ToneIcon = tone ? TONE_ICONS[tone] : void 0;
let t2;
$[7] === Symbol.for("react.memo_cache_sentinel") ? (t2 = {
margin: -1
}, $[7] = t2) : t2 = $[7];
let t3;
$[8] !== ToneIcon || $[9] !== locations || $[10] !== options || $[11] !== showPresentationTitle || $[12] !== title || $[13] !== tone ? (t3 = !locations && /* @__PURE__ */ jsxs(Flex, { align: "flex-start", gap: 3, padding: 3, children: [
tone && ToneIcon && /* @__PURE__ */ jsx(Box, { flex: "none", children: /* @__PURE__ */ jsx(Text, { size: 1, children: /* @__PURE__ */ jsx(ToneIcon, {}) }) }),
/* @__PURE__ */ jsx(Box, { flex: 1, children: /* @__PURE__ */ jsxs(Text, { size: 1, weight: "medium", children: [
showPresentationTitle && /* @__PURE__ */ jsxs(Fragment, { children: [
options.title || DEFAULT_TOOL_TITLE,
" \xB7 "
] }),
title
] }) })
] }), $[8] = ToneIcon, $[9] = locations, $[10] = options, $[11] = showPresentationTitle, $[12] = title, $[13] = tone, $[14] = t3) : t3 = $[14];
let t4;
$[15] !== documentId || $[16] !== expanded || $[17] !== isResolving || $[18] !== len || $[19] !== locations || $[20] !== options || $[21] !== presentation?.params || $[22] !== presentationName || $[23] !== schemaType || $[24] !== showPresentationTitle || $[25] !== title || $[26] !== toggle ? (t4 = locations && /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx(Card, { as: len ? "button" : void 0, onClick: toggle, padding: 3, radius: 1, tone: "inherit", children: /* @__PURE__ */ jsxs(Flex, { gap: 3, children: [
/* @__PURE__ */ jsx(Box, { flex: "none", children: isResolving ? /* @__PURE__ */ jsx(Spinner, { size: 1 }) : /* @__PURE__ */ jsx(Text, { size: 1, children: len === 0 ? /* @__PURE__ */ jsx(InfoOutlineIcon, {}) : /* @__PURE__ */ jsx(ChevronRightIcon, { style: {
transform: `rotate(${expanded ? "90deg" : 0})`,
transition: "transform 100ms ease-in-out"
} }) }) }),
/* @__PURE__ */ jsx(Box, { flex: 1, children: /* @__PURE__ */ jsxs(Text, { size: 1, weight: "medium", children: [
showPresentationTitle && /* @__PURE__ */ jsxs(Fragment, { children: [
options.title || DEFAULT_TOOL_TITLE,
" \xB7 "
] }),
title
] }) })
] }) }),
/* @__PURE__ */ jsx(Stack, { hidden: !expanded, marginTop: 1, space: 1, children: locations.map((l, index) => /* @__PURE__ */ jsx(LocationItem, { active: (options.name || DEFAULT_TOOL_NAME) === presentationName && l.href === presentation?.params.preview, documentId, documentType: schemaType.name, node: l, toolName: options.name || DEFAULT_TOOL_NAME }, index)) })
] }), $[15] = documentId, $[16] = expanded, $[17] = isResolving, $[18] = len, $[19] = locations, $[20] = options, $[21] = presentation?.params, $[22] = presentationName, $[23] = schemaType, $[24] = showPresentationTitle, $[25] = title, $[26] = toggle, $[27] = t4) : t4 = $[27];
let t5;
$[28] !== t3 || $[29] !== t4 ? (t5 = /* @__PURE__ */ jsxs("div", { style: t2, children: [
t3,
t4
] }), $[28] = t3, $[29] = t4, $[30] = t5) : t5 = $[30];
let t6;
return $[31] !== t5 || $[32] !== tone ? (t6 = /* @__PURE__ */ jsx(Card, { padding: 1, radius: 2, border: !0, tone, children: t5 }), $[31] = t5, $[32] = tone, $[33] = t6) : t6 = $[33], t6;
}
function _temp$1(v) {
return !v;
}
function LocationItem(props2) {
const $ = c(26), {
documentId,
documentType,
node,
active,
toolName
} = props2, presentation = useContext(PresentationContext), currentPresentationToolName = useCurrentPresentationToolName(), isCurrentTool = toolName === currentPresentationToolName, navigate = presentation?.navigate, t0 = presentation?.structureParams;
let t1;
$[0] !== documentId || $[1] !== documentType || $[2] !== node.href || $[3] !== t0 || $[4] !== toolName ? (t1 = {
intent: "edit",
params: {
id: documentId,
type: documentType,
mode: "presentation",
presentation: toolName,
...t0,
preview: node.href
}
}, $[0] = documentId, $[1] = documentType, $[2] = node.href, $[3] = t0, $[4] = toolName, $[5] = t1) : t1 = $[5];
const presentationLinkProps = useIntentLink(t1);
let t2;
$[6] !== navigate || $[7] !== node.href ? (t2 = () => {
navigate?.({}, {
preview: node.href
});
}, $[6] = navigate, $[7] = node.href, $[8] = t2) : t2 = $[8];
const handleCurrentToolClick = t2;
let t3;
$[9] !== isCurrentTool || $[10] !== presentationLinkProps ? (t3 = isCurrentTool ? {} : presentationLinkProps, $[9] = isCurrentTool, $[10] = presentationLinkProps, $[11] = t3) : t3 = $[11];
const t4 = isCurrentTool ? handleCurrentToolClick : presentationLinkProps.onClick;
let t5;
$[12] === Symbol.for("react.memo_cache_sentinel") ? (t5 = /* @__PURE__ */ jsx(Box, { flex: "none", children: /* @__PURE__ */ jsx(Text, { size: 1, children: /* @__PURE__ */ jsx(DesktopIcon, {}) }) }), $[12] = t5) : t5 = $[12];
let t6;
$[13] !== node.title ? (t6 = /* @__PURE__ */ jsx(Text, { size: 1, weight: "medium", children: node.title }), $[13] = node.title, $[14] = t6) : t6 = $[14];
let t7;
$[15] !== node.href ? (t7 = /* @__PURE__ */ jsx(Text, { muted: !0, size: 1, textOverflow: "ellipsis", children: node.href }), $[15] = node.href, $[16] = t7) : t7 = $[16];
let t8;
$[17] !== t6 || $[18] !== t7 ? (t8 = /* @__PURE__ */ jsxs(Flex, { gap: 3, children: [
t5,
/* @__PURE__ */ jsxs(Stack, { flex: 1, space: 2, children: [
t6,
t7
] })
] }), $[17] = t6, $[18] = t7, $[19] = t8) : t8 = $[19];
let t9;
return $[20] !== active || $[21] !== node.href || $[22] !== t3 || $[23] !== t4 || $[24] !== t8 ? (t9 = /* @__PURE__ */ createElement(Card, { ...t3, as: "a", key: node.href, onClick: t4, padding: 3, radius: 1, pressed: active, tone: "inherit" }, t8), $[20] = active, $[21] = node.href, $[22] = t3, $[23] = t4, $[24] = t8, $[25] = t9) : t9 = $[25], t9;
}
const LocationStack = styled(Stack)`
min-height: ${rem(42)};
& + &:empty {
display: none;
}
`;
function PresentationDocumentHeader(props2) {
const $ = c(21), {
documentId,
options,
schemaType,
version
} = props2, context = useContext(PresentationDocumentContext), t0 = options.resolve?.locations || options.locate;
let t1;
$[0] !== documentId || $[1] !== schemaType.name || $[2] !== t0 || $[3] !== version ? (t1 = {
id: documentId,
version,
resolvers: t0,
type: schemaType.name
}, $[0] = documentId, $[1] = schemaType.name, $[2] = t0, $[3] = version, $[4] = t1) : t1 = $[4];
const {
state,
status
} = useDocumentLocations(t1);
if (context && context.options[0] !== options || status === "empty")
return null;
let t2;
$[5] !== context?.options ? (t2 = context?.options || [], $[5] = context?.options, $[6] = t2) : t2 = $[6];
const contextOptions = t2;
let t3;
if ($[7] !== contextOptions || $[8] !== documentId || $[9] !== schemaType || $[10] !== state || $[11] !== status) {
let t42;
$[13] !== contextOptions.length || $[14] !== documentId || $[15] !== schemaType || $[16] !== state || $[17] !== status ? (t42 = (options_0, idx) => /* @__PURE__ */ jsx(LocationsBanner, { documentId, isResolving: status === "resolving", options: options_0, schemaType, showPresentationTitle: contextOptions.length > 1, state }, idx), $[13] = contextOptions.length, $[14] = documentId, $[15] = schemaType, $[16] = state, $[17] = status, $[18] = t42) : t42 = $[18], t3 = contextOptions.map(t42), $[7] = contextOptions, $[8] = documentId, $[9] = schemaType, $[10] = state, $[11] = status, $[12] = t3;
} else
t3 = $[12];
let t4;
return $[19] !== t3 ? (t4 = /* @__PURE__ */ jsx(LocationStack, { marginBottom: 5, space: 5, children: /* @__PURE__ */ jsx(Stack, { space: 2, children: t3 }) }), $[19] = t3, $[20] = t4) : t4 = $[20], t4;
}
function PresentationDocumentProvider(props2) {
const $ = c(15), {
children,
options
} = props2, parent = useContext(PresentationDocumentContext), parentRegister = parent?.register, [optionsArray, setOptionsArray] = useState(_temp);
let t0;
$[0] !== parentRegister ? (t0 = (options_0) => parentRegister ? parentRegister(options_0) : (setOptionsArray((prev) => [options_0].concat(prev)), () => {
setOptionsArray((prev_0) => prev_0.filter((o) => o !== options_0));
}), $[0] = parentRegister, $[1] = t0) : t0 = $[1];
const register = t0;
let t1;
const t2 = parent?.options || optionsArray;
let t3;
$[2] !== register || $[3] !== t2 ? (t3 = {
options: t2,
register
}, $[2] = register, $[3] = t2, $[4] = t3) : t3 = $[4], t1 = t3;
const context = t1;
let t4;
$[5] !== register ? (t4 = (options_1) => register(options_1), $[5] = register, $[6] = t4) : t4 = $[6];
const registerEffectEvent = useEffectEvent(t4);
let t5;
$[7] !== options || $[8] !== registerEffectEvent ? (t5 = () => registerEffectEvent(options), $[7] = options, $[8] = registerEffectEvent, $[9] = t5) : t5 = $[9];
let t6;
$[10] !== options ? (t6 = [options], $[10] = options, $[11] = t6) : t6 = $[11], useLayoutEffect(t5, t6);
let t7;
return $[12] !== children || $[13] !== context ? (t7 = /* @__PURE__ */ jsx(PresentationDocumentContext.Provider, { value: context, children }), $[12] = children, $[13] = context, $[14] = t7) : t7 = $[14], t7;
}
function _temp() {
return [];
}
function useOpenInStructureAction(props2) {
const $ = c(13), {
documentId,
documentType,
path
} = props2, workspace = useWorkspace(), {
navigateIntent
} = useRouter(), presentation = useContext(PresentationContext);
let t0;
const t1 = presentation?.name || DEFAULT_TOOL_NAME;
let t2;
$[0] !== documentId || $[1] !== documentType || $[2] !== t1 || $[3] !== workspace.tools ? (t2 = findStructureTool(workspace.tools, documentId, documentType, t1), $[0] = documentId, $[1] = documentType, $[2] = t1, $[3] = workspace.tools, $[4] = t2) : t2 = $[4], t0 = t2;
const defaultStructureTool = t0, t3 = !presentation || path.length > 0 || !defaultStructureTool, t4 = defaultStructureTool?.icon || MasterDetailIcon, t5 = `Open in ${defaultStructureTool?.title || "Structure"}`;
let t6;
return $[5] !== documentId || $[6] !== documentType || $[7] !== navigateIntent || $[8] !== path || $[9] !== t3 || $[10] !== t4 || $[11] !== t5 ? (t6 = {
type: "action",
hidden: t3,
icon: t4,
title: t5,
onAction() {
navigateIntent("edit", {
id: documentId,
type: documentType,
mode: "structure",
path: pathToString(path)
});
},
renderAsButton: !0
}, $[5] = documentId, $[6] = documentType, $[7] = navigateIntent, $[8] = path, $[9] = t3, $[10] = t4, $[11] = t5, $[12] = t6) : t6 = $[12], t6;
}
const openInStructure = defineDocumentFieldAction({
name: "presentation/openInStructure",
useAction: useOpenInStructureAction
});
function findStructureTool(tools, documentId, documentType, presentationToolName) {
const results = tools.filter((t) => t.name !== presentationToolName).map((t) => {
const match = t.canHandleIntent?.("edit", {
id: documentId,
type: documentType,
mode: "structure"
}, {});
return {
tool: t,
match
};
}), modeMatches = results.filter((t) => isRecord(t.match) && t.match.mode);
return modeMatches.length > 0 ? modeMatches[0].tool : results.filter((t) => t.match)[0]?.tool;
}
const preservedSearchParamKeys = ["preview", "viewport"];
function getIntentState(intent, params, routerState, payload) {
const {
id,
mode,
path,
presentation,
type,
...searchParams
} = params, _searchParams = {
...(routerState?._searchParams || []).filter(([key]) => preservedSearchParamKeys.includes(key)).reduce((acc, [key, value]) => ({
...acc,
[key]: value
}), {}),
...searchParams
};
return intent === "edit" && id ? (_searchParams.preview = _searchParams.preview || new URLSearchParams(window.location.search).get("preview") || "/", {
type: type || "*",
id: getPublishedId(id),
path,
_searchParams: Object.entries(_searchParams)
}) : intent === "create" ? (_searchParams.preview = _searchParams.preview || new URLSearchParams(window.location.search).get("preview") || "/", payload && typeof payload == "object" && (_searchParams.templateParams = encodeJsonParams(payload)), {
type: type || "*",
id: id || uuid(),
_searchParams: Object.entries(_searchParams)
}) : {
intent,
params,
payload
};
}
function PresentationSpinner() {
const $ = c(1);
let t0;
return $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = /* @__PURE__ */ jsx(Flex, { align: "center", direction: "column", height: "fill", justify: "center", style: {
width: "100%"
}, children: /* @__PURE__ */ jsx(Spinner, {}) }), $[0] = t0) : t0 = $[0], t0;
}
const router = route.create("/", {
__unsafe_disableScopedSearchParams: !0
}, [route.intents("/intent"), route.create(":type", [route.create(":id", [route.create(":path")])])]), PresentationTool = lazy(() => import("./PresentationToolGrantsCheck.mjs")), BroadcastDisplayedDocument = lazy(() => import("./BroadcastDisplayedDocument.mjs"));
function defineLocations(resolver) {
return resolver;
}
function defineDocuments(resolvers) {
return resolvers;
}
const presentationTool = definePlugin((options) => {
const toolName = options.name || DEFAULT_TOOL_NAME;
"locate" in options && console.warn("Presentation\u2019s `locate` option is deprecated. Use `resolve.locations` instead.");
const hasLocationsResolver = !!(options.resolve?.locations || options.locate);
function PresentationDocumentInput(props2) {
const $ = c(22), value = props2.value;
let t0;
$[0] !== value?._id ? (t0 = value?._id ? getPublishedId(value?._id) : void 0, $[0] = value?._id, $[1] = t0) : t0 = $[1];
const documentId = t0;
let t1;
$[2] !== value ? (t1 = value?._id ? getVersionFromId(value._id) : void 0, $[2] = value, $[3] = t1) : t1 = $[3];
const documentVersion = t1;
if (isDocumentSchemaType(props2.schemaType)) {
let t22;
$[4] !== documentId || $[5] !== documentVersion || $[6] !== props2.schemaType ? (t22 = hasLocationsResolver && documentId && /* @__PURE__ */ jsx(PresentationDocumentHeader, { documentId, version: documentVersion, options, schemaType: props2.schemaType }), $[4] = documentId, $[5] = documentVersion, $[6] = props2.schemaType, $[7] = t22) : t22 = $[7];
let t3;
$[8] === Symbol.for("react.memo_cache_sentinel") ? (t3 = /* @__PURE__ */ jsx(PresentationSpinner, {}), $[8] = t3) : t3 = $[8];
let t4;
$[9] !== props2 ? (t4 = props2.renderDefault(props2), $[9] = props2, $[10] = t4) : t4 = $[10];
let t5;
$[11] !== t4 ? (t5 = /* @__PURE__ */ jsx(Suspense, { fallback: t3, children: t4 }), $[11] = t4, $[12] = t5) : t5 = $[12];
let t6;
$[13] !== documentId || $[14] !== value ? (t6 = /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(BroadcastDisplayedDocument, { value }, documentId) }, "broadcast-displayed-document"), $[13] = documentId, $[14] = value, $[15] = t6) : t6 = $[15];
let t7;
return $[16] !== t22 || $[17] !== t5 || $[18] !== t6 ? (t7 = /* @__PURE__ */ jsxs(PresentationDocumentProvider, { options, children: [
t22,
t5,
t6
] }), $[16] = t22, $[17] = t5, $[18] = t6, $[19] = t7) : t7 = $[19], t7;
}
let t2;
return $[20] !== props2 ? (t2 = props2.renderDefault(props2), $[20] = props2, $[21] = t2) : t2 = $[21], t2;
}
function canHandleCreateIntent(params) {
return !("type" in params) || "presentation" in params && params.presentation !== toolName ? !1 : "template" in params ? {
template: !0
} : !0;
}
function canHandleEditIntent(params) {
return !("type" in params) || !("id" in params) || "presentation" in params && params.presentation !== toolName ? !1 : "mode" in params ? {
mode: params.mode === EDIT_INTENT_MODE
} : !0;
}
return {
i18n: {
bundles: [presentationUsEnglishLocaleBundle]
},
document: {
unstable_fieldActions: (prev) => [
...prev.filter((a) => a.name !== openInStructure.name),
// prevent duplication
openInStructure
]
},
form: {
components: {
input: PresentationDocumentInput
}
},
tools: [{
icon: options.icon || DEFAULT_TOOL_ICON,
name: toolName,
title: options.title,
component: PresentationTool,
options,
canHandleIntent(intent, params) {
return intent === "create" ? canHandleCreateIntent(params) : intent === "edit" ? canHandleEditIntent(params) : !1;
},
getIntentState,
router,
__internalApplicationType: "sanity/presentation"
}]
};
}), ACTION_IFRAME_LOADED = "ACTION_IFRAME_LOADED", ACTION_IFRAME_REFRESH = "ACTION_IFRAME_REFRESH", ACTION_IFRAME_RELOAD = "ACTION_IFRAME_RELOAD", ACTION_VISUAL_EDITING_OVERLAYS_TOGGLE = "ACTION_VISUAL_EDITING_OVERLAYS_TOGGLE", presentationReducer = (state, action) => {
switch (action.type) {
case ACTION_IFRAME_LOADED:
return state.iframe.status === "loaded" ? state : {
...state,
iframe: {
...state.iframe,
status: "loaded"
}
};
case ACTION_IFRAME_REFRESH:
return state.iframe.status === "refreshing" ? state : {
...state,
iframe: {
...state.iframe,
status: "refreshing"
}
};
case ACTION_IFRAME_RELOAD:
return state.iframe.status === "reloading" ? state : {
...state,
iframe: {
...state.iframe,
status: "reloading"
}
};
case ACTION_VISUAL_EDITING_OVERLAYS_TOGGLE:
return toggleVisualEditingOverlays(state, action);
default:
return state;
}
}, toggleVisualEditingOverlays = (state, action) => state.visualEditing.overlaysEnabled === action.enabled ? state : {
...state,
visualEditing: {
...state.visualEditing,
overlaysEnabled: action.enabled
}
}, mainDocumentSchema = fallback(boolean(), !1), iframeStatusSchema = picklist(["loading", "loaded", "refreshing", "reloading"]), initStateSchema = object({
mainDocument: mainDocumentSchema,
iframe: object({
status: iframeStatusSchema
}),
visualEditing: object({
overlaysEnabled: boolean()
})
}), INITIAL_PRESENTATION_STATE = {
mainDocument: !1,
iframe: {
status: "loading"
},
visualEditing: {
overlaysEnabled: !1
}
};
function presentationReducerInit(state) {
return parse(initStateSchema, {
...INITIAL_PRESENTATION_STATE,
...state
});
}
function usePresentationNavigate() {
const navigate = useContext(PresentationNavigateContext);
if (!navigate)
throw new Error("Presentation navigate context is missing");
return navigate;
}
function usePresentationParams(t0) {
const throwOnMissingContext = t0 === void 0 ? !0 : t0, params = useContext(PresentationParamsContext);
if (throwOnMissingContext && !params)
throw new Error("Presentation params context is missing");
return params;
}
export {
ACTION_IFRAME_LOADED,
ACTION_IFRAME_REFRESH,
ACTION_IFRAME_RELOAD,
ACTION_VISUAL_EDITING_OVERLAYS_TOGGLE,
API_VERSION,
DEFAULT_TOOL_NAME,
EDIT_INTENT_MODE,
LOADER_QUERY_GC_INTERVAL,
MAX_TIME_TO_OVERLAYS_CONNECTION,
MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL,
POPUP_CHECK_INTERVAL,
PresentationSpinner,
defineDocuments,
defineLocations,
presentationLocaleNamespace,
presentationReducer,
presentationReducerInit,
presentationTool,
usePresentationNavigate,
usePresentationParams,
usePresentationTool,
useSharedState
};
//# sourceMappingURL=presentation.mjs.map