UNPKG

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

754 lines (749 loc) • 4.71 MB
import { jsx, jsxs, Fragment as Fragment$1 } from "react/jsx-runtime"; import { c } from "react/compiler-runtime"; import * as PathUtils from "@sanity/util/paths"; import { toString, FOCUS_TERMINATOR, startsWith, isEqual as isEqual$3, pathFor, get as get$1, trimLeft, fromString, trimChildPath as trimChildPath$1 } from "@sanity/util/paths"; import React, { forwardRef, useRef, useState, useId, useCallback, useMemo, useImperativeHandle, useEffect, isValidElement, Fragment, cloneElement, memo, useContext, useSyncExternalStore, Suspense, useReducer, startTransition, Component, useLayoutEffect, createContext, useDebugValue, PureComponent, Children, useTransition, useInsertionEffect, lazy, useEffectEvent, useDeferredValue, version, StrictMode } from "react"; import deepEquals from "react-fast-compare"; import { WorkspacesContext, LocaleContext, MediaLibraryIdsContext, PerspectiveContext, UserColorManagerContext, ResourceCacheContext, EventsContext, WorkspaceContext, DocumentChangeContext, ReviewChangesContext, DiffContext, PresenceContext, FormBuilderContext, ValidationContext, PortableTextMarkersContext, PortableTextMemberItemsContext, ChangeIndicatorTrackerContextStore, ChangeIndicatorTrackerContextGetSnapshot, FormCallbacksContext, ReferenceInputOptionsContext, DocumentIdContext, HoveredFieldContext, FieldActionsContext, FormValueContext, ReferenceItemRefContext, GetFormValueContext, EnhancedObjectDialogContext, DocumentFieldActionsContext, SortableItemIdContext, VirtualizerScrollInstanceContext, FullscreenPTEContext, PresenceTrackerContextStore, PresenceTrackerContextGetSnapshot, FormFieldPresenceContext, SourceContext, PortableTextMemberItemElementRefsContext, ScrollContext, AssetLimitUpsellContext, ReleasesUpsellContext, ReleasesMetadataContext, TableContext, SearchContext, SingleDocReleaseEnabledContext, SingleDocReleaseUpsellContext, SingleDocReleaseContext, ActiveWorkspaceMatcherContext, CalendarContext, AppIdCacheContext, CommentsAuthoringPathContext, CommentsIntentContext, CommentInputContext, CommentsContext, CommentsEnabledContext, CommentsOnboardingContext, CommentsSelectedPathContext, CommentsUpsellContext, AddonDatasetContext, SanityCreateConfigContext, ScheduledPublishingEnabledContext, SchedulesContext, SchedulePublishUpsellContext, DocumentActionPropsContext, TasksEnabledContext, IsLastPaneContext, MentionUserContext, TasksNavigationContext, TasksContext, TasksUpsellContext, RouterHistoryContext, ColorSchemeSetValueContext, ColorSchemeValueContext, DocumentLimitUpsellContext, NavbarContext, FreeTrialContext, PackageVersionInfoContext, StudioAnnouncementContext, CopyPasteContext, UserApplicationCacheContext, LiveUserApplicationContext, PreviewCardContext, ZIndexContext, zIndexContextDefaults } from "sanity/_singletons"; import { SchedulesContext as SchedulesContext2 } from "sanity/_singletons"; import { Badge, Grid, rem, Box, Stack, Card, Spinner, Text as Text$1, Layer, Flex, Skeleton, Heading, Avatar, AvatarStack, Inline, Breadcrumbs, useClickOutsideEvent, Code, useTheme, useGlobalKeyDown, MenuDivider, Menu, useElementRect, Autocomplete, useToast, Button as Button$1, useElementSize, AvatarCounter, TextInput as TextInput$1, Container as Container$2, Checkbox as Checkbox$1, Switch as Switch$1, Select, LayerProvider, ElementQuery, TabList, rgba, useLayer, MenuItem as MenuItem$1, useBoundaryElement, BoundaryElementProvider, usePortal, PortalProvider, Portal, _responsive, useRootTheme, useArrayProp, TextArea, TextSkeleton, useMediaIndex, isHTMLElement, Radio, TabPanel, studioTheme, Label, Dialog as Dialog$1, ThemeColorProvider, DialogProvider, focusLastDescendant, focusFirstDescendant, VirtualList as VirtualList$1, usePrefersDark, ThemeProvider, ToastProvider } from "@sanity/ui"; import { useVirtualizer, defaultRangeExtractor, elementScroll } from "@tanstack/react-virtual"; import { throttle, isEqual as isEqual$2, memoize as memoize$1, partition, groupBy, omit, isPlainObject as isPlainObject$1, get, flatten as flatten$1, uniqBy, sample, uniq, orderBy, xor, debounce, keyBy, toLower, compact, words, intersection, union, flow, trim, sortBy, isFinite, pickBy, findIndex as findIndex$1, clone, isObject, isString as isString$1, noop as noop$6, capitalize, deburr, startCase, last as last$1, difference, upperFirst, set as set$1, find, uniqueId, castArray, pick, sortedIndex, values, identity as identity$2, isEmpty as isEmpty$1, range, sum as sum$1, max, escapeRegExp as escapeRegExp$1 } from "lodash-es"; import { styled, css, keyframes, useTheme as useTheme$1, createGlobalStyle, ServerStyleSheet } from "styled-components"; import { EllipsisHorizontalIcon, ErrorOutlineIcon, CircleIcon, CalendarIcon, UnpublishIcon, PublishIcon, EditIcon, CloseIcon, TrashIcon, AddCircleIcon, TimelineIcon, ChevronRightIcon, DocumentIcon, ImageIcon, ChevronDownIcon, ArrowRightIcon, ArrowDownIcon, RevertIcon, WarningOutlineIcon, InfoOutlineIcon, CheckmarkIcon, AddIcon, HelpCircleIcon, AccessDeniedIcon, ToggleArrowRightIcon, SyncIcon, LaunchIcon, BulbOutlineIcon, UnknownIcon, UploadIcon, DragHandleIcon, SearchIcon, StackCompactIcon, PanelLeftIcon, InsertAboveIcon, InsertBelowIcon, CopyIcon, AddDocumentIcon, ChevronLeftIcon, EarthGlobeIcon, EarthAmericasIcon, LinkIcon, UlistIcon, OlistIcon, CodeIcon, UnderlineIcon, StrikethroughIcon, ItalicIcon, BoldIcon, BlockElementIcon, InlineElementIcon, CollapseIcon, ExpandIcon, ResetIcon, Icon, ChevronUpIcon, DownloadIcon, DocumentsIcon, ReadOnlyIcon, BinaryDocumentIcon, CropIcon, EyeOpenIcon, DotIcon, LockIcon, CheckmarkCircleIcon, PinFilledIcon, PinIcon, RestoreIcon, ClockIcon, CloseCircleIcon, UnarchiveIcon, ArchiveIcon, ArrowUpIcon, ControlsIcon, SpinnerIcon, ArrowLeftIcon, SortIcon, ComposeSparklesIcon, ClipboardIcon, StringIcon, NumberIcon, BlockContentIcon, UndoIcon, UnlinkIcon, LinkRemovedIcon, AddCommentIcon, CommentIcon, SelectIcon, TaskIcon, UserIcon, DesktopIcon, MoonIcon, SunIcon, EyeClosedIcon, DoubleChevronRightIcon, AddUserIcon, CogIcon, BoltIcon, LeaveIcon, UsersIcon, GithubIcon, RefreshIcon, MenuIcon } from "@sanity/icons"; import { Button, ErrorBoundary, Tooltip, Popover, MenuItem, MenuButton, TooltipDelayGroupProvider, Dialog, Tab } from "./_chunks-es/TooltipDelayGroupProvider.js"; import { Hotkeys } from "./_chunks-es/TooltipDelayGroupProvider.js"; import "./_singletons.js"; import { ResizeObserver as ResizeObserver$2 } from "@juggle/resize-observer"; import createPubSub from "nano-pubsub"; import { I18nextProvider, useTranslation as useTranslation$1, initReactI18next } from "react-i18next"; import { isIndexSegment, isKeySegment, isIndexTuple, isKeyedObject, isReference as isReference$1, isArrayOfBlocksSchemaType, isSlug, isTypedObject, isGlobalDocumentReference, isObjectSchemaType, isArraySchemaType, isPortableTextSpan, isPortableTextTextBlock, isPrimitiveSchemaType, isBooleanSchemaType, isDateTimeSchemaType, isCrossDatasetReferenceSchemaType, isReferenceSchemaType, isStringSchemaType, isNumberSchemaType, isArrayOfObjectsSchemaType, isArrayOfPrimitivesSchemaType, isCrossDatasetReference, isTitledListValue, isImage, isValidationErrorMarker, isImageSchemaType, isSearchStrategy, searchStrategies as searchStrategies$1, defineType, defineField, defineArrayMember, isValidationWarningMarker, isValidationInfoMarker, isDeprecatedSchemaType, isFileSchemaType, isBlockSchemaType } from "@sanity/types"; export * from "@sanity/types"; import { COLOR_HUES, hues, white, red, gray, yellow, purple, black, green, blue } from "@sanity/color"; import { of, concat, defer, EMPTY as EMPTY$5, map as map$1, defaultIfEmpty, catchError as catchError$1, switchMap as switchMap$1, take, concatMap, from, Observable, merge, Subject, fromEvent, throwError, timer, NEVER, pipe, distinctUntilChanged as distinctUntilChanged$1, shareReplay as shareReplay$1, BehaviorSubject, tap as tap$1, finalize, share as share$1, ReplaySubject, combineLatest, asyncScheduler, bufferTime, mergeMap as mergeMap$1, firstValueFrom, filter as filter$1, lastValueFrom, partition as partition$1, asapScheduler, using, repeat, iif, startWith as startWith$1, concatWith, scan as scan$1, count, isObservable, retry, expand, reduce as reduce$2, skip as skip$1, forkJoin, debounce as debounce$2, toArray as toArray$2, delay as delay$1, timeout as timeout$1, connect, debounceTime as debounceTime$1 } from "rxjs"; import { catchError, tap, switchMap, map, scan, distinctUntilChanged, shareReplay, filter, startWith, mergeMapTo, takeUntil, take as take$1, publishReplay, refCount, withLatestFrom, share, mergeMap, concatMap as concatMap$1, groupBy as groupBy$1, throttleTime, last, mergeAll, toArray as toArray$1, distinct, skip, first, debounceTime, auditTime, switchMapTo, delay, reduce as reduce$1, debounce as debounce$1, finalize as finalize$1, expand as expand$1, mapTo, retry as retry$1, timeout } from "rxjs/operators"; import { SANITY_VERSION } from "./_chunks-es/version.js"; import { createClient, ClientError } from "@sanity/client"; import { useObservable, useObservableEvent } from "react-rx"; import { observableCallback } from "observable-callback"; import { fromUrl } from "@sanity/bifur-client"; import debug$c from "debug"; import { isValidElementType } from "react-is"; import { isHotkey } from "is-hotkey-esm"; import FocusLock from "react-focus-lock"; import { defineEvent, createSessionId, createBatchedStore } from "@sanity/telemetry"; import { nanoid, customAlphabet } from "nanoid"; import { useTelemetry, TelemetryProvider } from "@sanity/telemetry/react"; import { getVersionId, getDraftId, getPublishedId, isPublishedId, isDraftId, getVersionFromId, isVersionId, DRAFTS_FOLDER } from "@sanity/client/csm"; import { DRAFTS_FOLDER as DRAFTS_FOLDER2, VERSION_FOLDER, getDraftId as getDraftId2, getPublishedId as getPublishedId2, getVersionFromId as getVersionFromId2, getVersionId as getVersionId2, isDraftId as isDraftId2, isPublishedId as isPublishedId2, isVersionId as isVersionId2 } from "@sanity/client/csm"; import * as legacyDateFormat from "@sanity/util/legacyDateFormat"; import { sanitizeLocale, format as format$1, DEFAULT_DATE_FORMAT, parse as parse$2, isValidTimeZoneString, DEFAULT_TIME_FORMAT } from "@sanity/util/legacyDateFormat"; import { getImageDimensions, isDefaultCrop, isDefaultHotspot, isImageSource, isFileSource, isAssetObjectStub, isImageAssetId, isFileAssetId } from "@sanity/asset-utils"; import { createImageUrlBuilder } from "@sanity/image-url"; import { tz, TZDate } from "@date-fns/tz"; import { formatRelative, isValid, parse, differenceInMonths, differenceInYears, differenceInWeeks, differenceInDays, differenceInHours, differenceInMinutes, differenceInSeconds, format, isPast, addDays, startOfMonth, eachWeekOfInterval, lastDayOfMonth, getWeek, isSameDay, isSameMonth, setDate, setMonth, addMonths, setYear, setMinutes, setHours, parseISO, getMinutes, startOfHour, addHours, isBefore, startOfMinute, isWeekend, startOfDay, endOfDay, isAfter, set as set$2, startOfToday, endOfMinute, sub, formatDistance, isToday, isThisISOWeek, addWeeks } from "date-fns"; import DataLoader from "dataloader"; import { getTheme_v2, rgba as rgba$1, parseColor, rgbToHex, screen, multiply, createColorTheme, buildTheme } from "@sanity/ui/theme"; import { mergeMapArray } from "rxjs-mergemap-array"; import { isVersionId as isVersionId$1, getVersionNameFromId } from "@sanity/id-utils"; import { useDevicePixelRatio, getDevicePixelRatio } from "use-device-pixel-ratio"; import classNames from "classnames"; import { DEFAULT_MAX_FIELD_DEPTH, builtinTypes, validateSchema, groupProblems, DescriptorConverter, ALL_FIELDS_GROUP_NAME, isActionEnabled, processSchemaSynchronization } from "@sanity/schema/_internal"; import { randomKey as randomKey$1, isDeepEmpty, resolveTypeName as resolveTypeName$2, isShallowEmptyObject } from "@sanity/util/content"; import shallowEquals from "shallow-equals"; import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, closestCenter } from "@dnd-kit/core"; import { restrictToHorizontalAxis, restrictToVerticalAxis } from "@dnd-kit/modifiers"; import { sortableKeyboardCoordinates, useSortable, SortableContext, horizontalListSortingStrategy, verticalListSortingStrategy } from "@dnd-kit/sortable"; import { CSS } from "@dnd-kit/utilities"; import { PortableText as PortableText$1, toPlainText as toPlainText$1 } from "@portabletext/react"; import { usePortableTextEditor, PortableTextEditor, usePortableTextEditorSelection, PortableTextEditable, EditorProvider, useEditor, keyGenerator as keyGenerator$1 } from "@portabletext/editor"; import { Rule as Rule$1, Schema } from "@sanity/schema"; import { BehaviorPlugin, EventListenerPlugin } from "@portabletext/editor/plugins"; import { defineBehavior, raise, forward } from "@portabletext/editor/behaviors"; import { OneLinePlugin } from "@portabletext/plugin-one-line"; import { cleanupEfficiency, makeDiff, DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL, applyPatches, parsePatch, makePatches } from "@sanity/diff-match-patch"; import { isPortableTextBlock, toPlainText } from "@portabletext/toolkit"; import QuickLRU from "quick-lru"; import { Mutation, BufferedDocument, extractWithPath, arrayToJSONMatchPath } from "@sanity/mutator"; import { createInstance } from "i18next"; import scrollIntoView$1 from "scroll-into-view-if-needed"; import { IntentLink, useRouter, RouterContext, useIntentLink, route, encodeJsonParams, useRouterState, useStateLink, Link as Link$3, StateLink, RouteScope, STICKY_PARAMS, RouterProvider } from "sanity/router"; import { useSyncExternalStore as useSyncExternalStore$1 } from "use-sync-external-store/shim/index.js"; import { uuid } from "@sanity/uuid"; import { motion, AnimatePresence } from "motion/react"; import { diffInput, wrap as wrap$1 } from "@sanity/diff"; import { ConfirmPopover, MenuGroup } from "./_chunks-es/MenuGroup.js"; import { normalizeBlock } from "@portabletext/block-tools"; import { generateHelpUrl } from "./_chunks-es/generate-help-url.esm.js"; import { registerLanguage } from "react-refractor"; import bash from "refractor/bash"; import javascript from "refractor/javascript"; import json from "refractor/json"; import jsx2 from "refractor/jsx"; import typescript from "refractor/typescript"; import { makeFetchTransport, inboundFiltersIntegration, functionToStringIntegration, browserApiErrorsIntegration, breadcrumbsIntegration, globalHandlersIntegration, linkedErrorsIntegration, dedupeIntegration, httpContextIntegration, isInitialized, getClient, getCurrentScope, BrowserClient, defaultStackParser, Scope, init, withScope, captureException } from "@sentry/react"; import { createMemoryHistory, createBrowserHistory } from "history"; import { useSyncExternalStoreWithSelector } from "use-sync-external-store/with-selector"; import { SanityLogo, SanityMonogram } from "@sanity/logos"; import DOMPurify from "isomorphic-dompurify"; import { renderToString, renderToStaticMarkup } from "react-dom/server"; import { darken, lighten, readableColor, hasBadContrast } from "color2k"; import semver, { satisfies } from "semver"; import { useHotModuleReload } from "use-hot-module-reload"; import arrify from "arrify"; import { parse as parse$1, evaluate } from "groq-js"; import { InsertMenu as InsertMenu$2 } from "@sanity/insert-menu"; import { applyPatch as applyPatch$1, incremental } from "mendoza"; import { exhaustMapWithTrailing } from "rxjs-exhaustmap-with-trailing"; import { reduce } from "json-reduce"; import { createClientConcurrencyLimiter } from "@sanity/util/client"; import { ConcurrencyLimiter } from "@sanity/util/concurrency-limiter"; import TTLCache from "@isaacs/ttlcache"; import { MarkdownShortcutsPlugin } from "@portabletext/plugin-markdown-shortcuts"; import { createDecoratorGuard, TypographyPlugin } from "@portabletext/plugin-typography"; import exif from "exif-component"; import speakingurl from "speakingurl"; import { createNode } from "@sanity/comlink"; import raf from "raf"; import { diffItem } from "@sanity/diff-patch"; import { createRoot } from "react-dom/client"; import { getLuminance, parseToRgb, rgb, mix } from "polished"; function BetaBadge(props2) { const $ = c(8); let rest, t0, t1; $[0] !== props2 ? ({ fontSize: t0, children: t1, ...rest } = props2, $[0] = props2, $[1] = rest, $[2] = t0, $[3] = t1) : (rest = $[1], t0 = $[2], t1 = $[3]); const fontSize = t0 === void 0 ? 1 : t0, children = t1 === void 0 ? "Beta" : t1; let t2; return $[4] !== children || $[5] !== fontSize || $[6] !== rest ? (t2 = /* @__PURE__ */ jsx(Badge, { ...rest, fontSize, radius: 2, tone: "primary", children }), $[4] = children, $[5] = fontSize, $[6] = rest, $[7] = t2) : t2 = $[7], t2; } function focusRingBorderStyle$3(border) { return `inset 0 0 0 ${border.width}px ${border.color}`; } const AlignedBottomGrid$1 = styled(Grid)` align-items: flex-end; `; function focusRingStyle$2(opts) { const { base, border, focusRing } = opts, focusRingOutsetWidth = focusRing.offset + focusRing.width, focusRingInsetWidth = 0 - focusRing.offset, bgColor = base ? base.bg : "var(--card-bg-color)"; return [focusRingInsetWidth > 0 && `inset 0 0 0 ${focusRingInsetWidth}px var(--card-focus-ring-color)`, border && focusRingBorderStyle$3(border), focusRingInsetWidth < 0 && `0 0 0 ${0 - focusRingInsetWidth}px ${bgColor}`, focusRingOutsetWidth > 0 && `0 0 0 ${focusRingOutsetWidth}px var(--card-focus-ring-color)`].filter(Boolean).join(","); } const LIST_ITEM_DATA_ATTR_ACTIVE = "data-active", LIST_ITEM_INTERACTIVE_SELECTOR = "a,button", FocusOverlayDiv = styled.div(({ theme, offset }) => css` bottom: ${-offset}px; border-radius: ${rem(theme.sanity.radius[1])}; left: ${-offset}px; pointer-events: none; position: absolute; right: ${-offset}px; top: ${-offset}px; z-index: 2; ${VirtualListBox}:focus-visible & { box-shadow: ${focusRingStyle$2({ base: theme.sanity.color.base, focusRing: theme.sanity.focusRing })}; } `), PointerOverlayDiv = styled.div` bottom: 0; display: none; left: 0; position: absolute; right: 0; top: 0; z-index: 1; @media (hover: hover) { &[data-enabled='true'] { display: block; } } `, VirtualListBox = styled(Box)` height: 100%; outline: none; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; width: 100%; `, VirtualListChildBox = styled(Box).attrs(({ $height }) => ({ style: { height: `${$height}px` } }))` position: relative; width: 100%; `, CommandListComponent = forwardRef(function({ activeItemDataAttr = LIST_ITEM_DATA_ATTR_ACTIVE, ariaLabel, ariaMultiselectable = !1, autoFocus, canReceiveFocus, fixedHeight, focusRingOffset = 0, getItemDisabled, getItemKey: getItemKey2, getItemSelected, initialIndex, initialScrollAlign = "start", inputElement, itemHeight, items, onEndReached, onEndReachedIndexOffset = 0, onlyShowSelectionWhenActive, overscan, renderItem: renderItem2, testId, wrapAround = !0, ...responsivePaddingProps }, ref) { const isMountedRef = useRef(!1), [commandListId] = useState(useId()), activeIndexRef = useRef(initialIndex ?? 0), [childContainerElement, setChildContainerElement] = useState(null), [hovered, setHovered] = useState(!1), [pointerOverlayElement, setPointerOverlayElement] = useState(null), [virtualListElement, setVirtualListElement] = useState(null), handleChange = useCallback((v) => { if (!onEndReached) return; const [lastItem] = [...v.getVirtualItems()].reverse(); lastItem && lastItem.index >= items.length - onEndReachedIndexOffset - 1 && isMountedRef.current && onEndReached(); }, [onEndReached, items.length, onEndReachedIndexOffset]), virtualizer = useVirtualizer({ count: items.length, getItemKey: getItemKey2, getScrollElement: () => virtualListElement, estimateSize: () => itemHeight, onChange: handleChange, overscan }), itemIndices = useMemo(() => getItemIndicies(items, getItemDisabled, getItemSelected), [getItemDisabled, getItemSelected, items]), activeItemCount = useMemo(() => itemIndices.filter((v_0) => !v_0.disabled).length, [itemIndices]), enableChildContainerPointerEvents = useCallback((enabled) => pointerOverlayElement?.setAttribute("data-enabled", (!enabled).toString()), [pointerOverlayElement]), getChildDescendantId = useCallback((index) => `${commandListId}-item-${index}`, [commandListId]), getCommandListChildrenId = useCallback(() => `${commandListId}-children`, [commandListId]), showChildrenActiveState = useCallback(() => { const hasFocus = [inputElement, virtualListElement].some((el) => document.activeElement === el); onlyShowSelectionWhenActive && !hasFocus && !hovered || Array.from(childContainerElement?.children || [])?.forEach((child) => { const virtualIndex = Number(child.dataset?.index), targetIndex = itemIndices[virtualIndex]?.activeIndex; child.querySelector(LIST_ITEM_INTERACTIVE_SELECTOR)?.toggleAttribute(activeItemDataAttr, targetIndex === activeIndexRef.current); }); }, [activeItemDataAttr, childContainerElement?.children, hovered, inputElement, itemIndices, onlyShowSelectionWhenActive, virtualListElement]), hideChildrenActiveState = useCallback(() => { Array.from(childContainerElement?.children || [])?.forEach((child_0) => { child_0.querySelector(LIST_ITEM_INTERACTIVE_SELECTOR)?.toggleAttribute(activeItemDataAttr, !1); }); }, [activeItemDataAttr, childContainerElement?.children]), refreshChildrenActiveStateThrottled = useMemo(() => throttle(showChildrenActiveState, 200), [showChildrenActiveState]), handleUpdateActiveDescendant = useCallback(() => { const activeIndex = activeIndexRef?.current; items.length > 0 ? (inputElement?.setAttribute("aria-activedescendant", getChildDescendantId(activeIndex)), virtualListElement?.setAttribute("aria-activedescendant", getChildDescendantId(activeIndex))) : (inputElement?.removeAttribute("aria-activedescendant"), virtualListElement?.removeAttribute("aria-activedescendant")); }, [getChildDescendantId, inputElement, items.length, virtualListElement]), handleGetTopIndex = useCallback(() => { const childContainerParentElement = childContainerElement?.parentElement; if (childContainerElement && childContainerParentElement) { const offset = childContainerParentElement.getBoundingClientRect().top - childContainerElement.getBoundingClientRect().top; return virtualizer.getVirtualItemForOffset(offset)?.index ?? -1; } return -1; }, [childContainerElement, virtualizer]), setActiveIndex = useCallback(({ index: index_0, scrollAlign, scrollIntoView: scrollIntoView2 = !0 }) => { if (activeIndexRef.current = index_0, handleUpdateActiveDescendant(), showChildrenActiveState(), scrollIntoView2) { const virtualListIndex = itemIndices.findIndex((i) => i.activeIndex === index_0); virtualListIndex > -1 && virtualizer.scrollToIndex(virtualListIndex, scrollAlign ? { align: scrollAlign } : {}); } }, [handleUpdateActiveDescendant, itemIndices, showChildrenActiveState, virtualizer]), selectAdjacentItemIndex = useCallback((direction) => { let nextIndex = -1; const lastIndex = activeItemCount - 1; if (direction === "next") { const wrapAroundIndex = wrapAround ? 0 : lastIndex; nextIndex = activeIndexRef.current < activeItemCount - 1 ? activeIndexRef.current + 1 : wrapAroundIndex; } if (direction === "previous") { const wrapAroundIndex_0 = wrapAround ? lastIndex : 0; nextIndex = activeIndexRef.current > 0 ? activeIndexRef.current - 1 : wrapAroundIndex_0; } setActiveIndex({ index: nextIndex, scrollIntoView: !0 }), enableChildContainerPointerEvents(!1); }, [activeItemCount, enableChildContainerPointerEvents, setActiveIndex, wrapAround]), focusElement = useCallback((type) => { switch (type) { case "input": inputElement?.focus(); break; case "list": virtualListElement?.focus(); break; } }, [inputElement, virtualListElement]), focusInputElement = useCallback(() => { inputElement?.focus(); }, [inputElement]), focusListElement = useCallback(() => { virtualListElement?.focus(); }, [virtualListElement]), handleChildMouseEnter = useCallback((index_1) => () => { setActiveIndex({ index: index_1, scrollIntoView: !1 }); }, [setActiveIndex]), handleFocus = useCallback(() => { showChildrenActiveState(); }, [showChildrenActiveState]), handleKeyDown = useCallback((type_0) => (event) => { const childElements_1 = Array.from(childContainerElement?.children || []); if (childElements_1.length && (event.key === "ArrowDown" && (event.preventDefault(), focusElement(type_0), selectAdjacentItemIndex("next")), event.key === "ArrowUp" && (event.preventDefault(), focusElement(type_0), selectAdjacentItemIndex("previous")), event.key === "Enter")) { event.preventDefault(), focusElement(type_0); const currentElement = childElements_1.find((el_0) => Number(el_0.dataset.index) === itemIndices.findIndex((i_0) => i_0.activeIndex === activeIndexRef.current)); currentElement && currentElement?.querySelector(LIST_ITEM_INTERACTIVE_SELECTOR)?.click(); } }, [childContainerElement?.children, focusElement, itemIndices, selectAdjacentItemIndex]), handleKeyDownInput = useCallback((event_0) => handleKeyDown("input")(event_0), [handleKeyDown]), handleKeyDownList = useCallback((event_1) => handleKeyDown("list")(event_1), [handleKeyDown]), handleVirtualListMouseEnter = useCallback(() => { onlyShowSelectionWhenActive && (showChildrenActiveState(), setHovered(!0)); }, [onlyShowSelectionWhenActive, showChildrenActiveState]), handleVirtualListMouseLeave = useCallback(() => { onlyShowSelectionWhenActive && (hideChildrenActiveState(), setHovered(!1)); }, [hideChildrenActiveState, onlyShowSelectionWhenActive]); useImperativeHandle(ref, () => ({ focusInputElement() { focusInputElement(); }, focusListElement() { focusListElement(); }, getTopIndex() { return handleGetTopIndex(); }, scrollToIndex(index_2) { setActiveIndex({ index: index_2 }), enableChildContainerPointerEvents(!0); } }), [enableChildContainerPointerEvents, focusInputElement, focusListElement, handleGetTopIndex, setActiveIndex]), useEffect(() => { typeof initialIndex < "u" && !isMountedRef.current && setActiveIndex({ index: initialIndex, scrollAlign: initialScrollAlign, scrollIntoView: !0 }), isMountedRef.current = !0; }, [initialIndex, initialScrollAlign, onlyShowSelectionWhenActive, setActiveIndex]), useEffect(() => { function handleMouseEvent() { enableChildContainerPointerEvents(!0); } return virtualListElement?.addEventListener("mousemove", handleMouseEvent), virtualListElement?.addEventListener("wheel", handleMouseEvent, { passive: !0 }), () => { virtualListElement?.removeEventListener("mousemove", handleMouseEvent), virtualListElement?.removeEventListener("wheel", handleMouseEvent); }; }, [enableChildContainerPointerEvents, virtualListElement]), useEffect(() => (inputElement?.addEventListener("focus", handleFocus), inputElement?.addEventListener("keydown", handleKeyDownInput), virtualListElement?.addEventListener("focus", handleFocus), virtualListElement?.addEventListener("keydown", handleKeyDownList), () => { inputElement?.removeEventListener("focus", handleFocus), inputElement?.removeEventListener("keydown", handleKeyDownInput), virtualListElement?.removeEventListener("focus", handleFocus), virtualListElement?.removeEventListener("keydown", handleKeyDownList); }), [canReceiveFocus, handleFocus, handleKeyDown, handleKeyDownInput, handleKeyDownList, hideChildrenActiveState, inputElement, showChildrenActiveState, virtualListElement]), useEffect(() => { handleUpdateActiveDescendant(); }, [handleUpdateActiveDescendant, items]), useEffect(() => { const mutationObserver = new MutationObserver(refreshChildrenActiveStateThrottled); return childContainerElement && mutationObserver.observe(childContainerElement, { childList: !0, subtree: !0 }), () => { mutationObserver.disconnect(); }; }, [childContainerElement, refreshChildrenActiveStateThrottled]), useEffect(() => { inputElement?.setAttribute("aria-autocomplete", "list"), inputElement?.setAttribute("aria-expanded", "true"), inputElement?.setAttribute("aria-controls", getCommandListChildrenId()), inputElement?.setAttribute("role", "combobox"); }, [getCommandListChildrenId, inputElement]), useEffect(() => { autoFocus && focusElement(autoFocus); }, [autoFocus, canReceiveFocus, focusListElement, focusInputElement, focusElement]); const rootTabIndex = canReceiveFocus ? 0 : -1; return /* @__PURE__ */ jsxs(VirtualListBox, { id: getCommandListChildrenId(), onMouseEnter: handleVirtualListMouseEnter, onMouseLeave: handleVirtualListMouseLeave, ref: setVirtualListElement, sizing: "border", tabIndex: rootTabIndex, "data-testid": testId, ...responsivePaddingProps, children: [ canReceiveFocus && /* @__PURE__ */ jsx(FocusOverlayDiv, { offset: focusRingOffset }), /* @__PURE__ */ jsx(PointerOverlayDiv, { "aria-hidden": "true", "data-enabled": !0, ref: setPointerOverlayElement }), virtualizer && /* @__PURE__ */ jsx(VirtualListChildBox, { forwardedAs: "ul", $height: virtualizer.getTotalSize(), "aria-label": ariaLabel, "aria-multiselectable": ariaMultiselectable, flex: 1, ref: setChildContainerElement, role: "listbox", children: virtualizer.getVirtualItems().map((virtualRow) => { const virtualIndex_0 = virtualRow.index, { activeIndex: activeIndex_0, disabled, selected } = itemIndices[virtualIndex_0], itemToRender = renderItem2(items[virtualIndex_0], { activeIndex: activeIndex_0, disabled, selected, virtualIndex: virtualIndex_0 }), clonedItem = isValidElement(itemToRender) && itemToRender.type != Fragment ? cloneElement(itemToRender, { // @ts-expect-error @TODO shift the responsibility of setting tabIndex to the consumer, so we can remove the need to clone tabIndex: -1 }) : itemToRender; return /* @__PURE__ */ jsx(CommandListItem2, { ref: fixedHeight ? void 0 : virtualizer.measureElement, activeIndex: activeIndex_0, activeItemCount, ariaMultiselectable, disabled, fixedHeight: fixedHeight ? `${virtualRow.size}px` : void 0, getChildDescendantId, handleChildMouseEnter, selected, virtualIndex: virtualIndex_0, virtualRowStart: virtualRow.start, children: clonedItem }, virtualRow.key); }) }) ] }); }), CommandList = memo(CommandListComponent); CommandList.displayName = "Memo(ForwardRef(CommandList))"; const CommandListItemComponent = forwardRef(function(props2, forwardedRef) { const $ = c(21), { children, activeIndex, activeItemCount, ariaMultiselectable, disabled, fixedHeight, getChildDescendantId, handleChildMouseEnter, selected, virtualIndex, virtualRowStart } = props2; let t0; $[0] !== activeIndex || $[1] !== disabled || $[2] !== handleChildMouseEnter ? (t0 = typeof activeIndex == "number" && !disabled ? handleChildMouseEnter(activeIndex) : void 0, $[0] = activeIndex, $[1] = disabled, $[2] = handleChildMouseEnter, $[3] = t0) : t0 = $[3]; const onMouseEnter = t0; let t1; $[4] !== activeIndex || $[5] !== activeItemCount || $[6] !== ariaMultiselectable || $[7] !== disabled || $[8] !== getChildDescendantId || $[9] !== selected ? (t1 = typeof activeIndex == "number" && !disabled ? { "aria-posinset": activeIndex + 1, ...ariaMultiselectable ? { "aria-selected": selected.toString() } : {}, "aria-setsize": activeItemCount, id: getChildDescendantId(activeIndex), role: "option" } : {}, $[4] = activeIndex, $[5] = activeItemCount, $[6] = ariaMultiselectable, $[7] = disabled, $[8] = getChildDescendantId, $[9] = selected, $[10] = t1) : t1 = $[10]; const activeAriaAttributes = t1, t2 = `translateY(${virtualRowStart}px)`; let t3; $[11] !== fixedHeight || $[12] !== t2 ? (t3 = { flex: 1, height: fixedHeight, left: 0, position: "absolute", top: 0, transform: t2, width: "100%" }, $[11] = fixedHeight, $[12] = t2, $[13] = t3) : t3 = $[13]; const style = t3; let t4; return $[14] !== activeAriaAttributes || $[15] !== children || $[16] !== forwardedRef || $[17] !== onMouseEnter || $[18] !== style || $[19] !== virtualIndex ? (t4 = /* @__PURE__ */ jsx(Stack, { as: "li", "data-index": virtualIndex, ref: forwardedRef, style, tabIndex: -1, ...activeAriaAttributes, onMouseEnter, children }), $[14] = activeAriaAttributes, $[15] = children, $[16] = forwardedRef, $[17] = onMouseEnter, $[18] = style, $[19] = virtualIndex, $[20] = t4) : t4 = $[20], t4; }), CommandListItem2 = memo(CommandListItemComponent); CommandListItem2.displayName = "Memo(ForwardRef(CommandListItem))"; function getItemIndicies(items, getItemDisabled, getItemSelected) { let i = -1; return items.reduce((acc, _, index) => { const disabled = getItemDisabled?.(index) ?? !1, selected = getItemSelected?.(index) ?? !1; return disabled || (i += 1), acc[index] = { activeIndex: disabled ? null : i, disabled, selected }, acc; }, []); } const ContextMenuButton = forwardRef(function(props2, ref) { const $ = c(17); let rest, t0, tone, tooltipProps; $[0] !== props2 ? ({ mode: t0, tooltipProps, tone, ...rest } = props2, $[0] = props2, $[1] = rest, $[2] = t0, $[3] = tone, $[4] = tooltipProps) : (rest = $[1], t0 = $[2], tone = $[3], tooltipProps = $[4]); const mode = t0 === void 0 ? "bleed" : t0, { t } = useTranslation(); let t1; $[5] !== t || $[6] !== tooltipProps?.content ? (t1 = tooltipProps?.content || t("common.context-menu-button.tooltip"), $[5] = t, $[6] = tooltipProps?.content, $[7] = t1) : t1 = $[7]; let t2; $[8] !== t1 || $[9] !== tooltipProps ? (t2 = { ...tooltipProps, content: t1 }, $[8] = t1, $[9] = tooltipProps, $[10] = t2) : t2 = $[10]; let t3; return $[11] !== mode || $[12] !== ref || $[13] !== rest || $[14] !== t2 || $[15] !== tone ? (t3 = /* @__PURE__ */ jsx(Button, { ...rest, icon: EllipsisHorizontalIcon, mode, ref, tone, tooltipProps: t2 }), $[11] = mode, $[12] = ref, $[13] = rest, $[14] = t2, $[15] = tone, $[16] = t3) : t3 = $[16], t3; }); function getWorkspaceIdentifier({ name, title }, index) { return typeof name == "string" && name.trim().length > 0 ? name : getNamelessWorkspaceIdentifier(title, index); } function getNamelessWorkspaceIdentifier(title, index) { const withTitle = typeof title == "string" && title.trim().length > 0 ? ` (titled "${title}")` : ""; return `at index ${index}${withTitle}`; } function useWorkspaces() { const workspaces = useContext(WorkspacesContext); if (!workspaces) throw new Error("Could not find `workspaces` context"); return workspaces; } class WorkspaceValidationError extends Error { constructor(message, options) { super(message), this.name = "WorkspaceValidationError", this.index = options?.index, this.identifier = options?.workspace && getWorkspaceIdentifier(options.workspace, options.index); } } function validateWorkspaces({ workspaces }) { if (workspaces.length === 0) throw new WorkspaceValidationError("At least one workspace is required."); validateNames(workspaces), validateBasePaths(workspaces); } function validateNames(workspaces) { const isSingleWorkspace = workspaces.length === 1, names = /* @__PURE__ */ new Map(); workspaces.forEach((workspace, index) => { const { name: rawName, title } = workspace, thisIdentifier = getNamelessWorkspaceIdentifier(title, index); if (!rawName && !isSingleWorkspace) throw new WorkspaceValidationError(`All workspaces must have a \`name\`, unless only a single workspace is defined. Workspace ${thisIdentifier} did not define a \`name\`.`, { workspace, index }); const name = isSingleWorkspace && typeof rawName > "u" ? "default" : rawName; if (typeof name != "string") throw new WorkspaceValidationError(`Workspace at index ${index} defined an invalid \`name\` - must be a string.`, { workspace, index }); const normalized = name.toLowerCase(), existingWorkspace = names.get(normalized); if (existingWorkspace) { const prevIdentifier = getNamelessWorkspaceIdentifier(existingWorkspace.workspace.title, existingWorkspace.index); throw new WorkspaceValidationError(`\`name\`s must be unique. Workspace ${prevIdentifier} and workspace ${thisIdentifier} both have the \`name\` \`${name}\``, { workspace, index }); } if (names.set(normalized, { index, workspace }), !/^[a-z0-9][a-z0-9_-]*$/i.test(name)) throw new WorkspaceValidationError(`All workspace \`name\`s must consist of only a-z, 0-9, underscore and dashes, and cannot begin with an underscore or dash. Workspace ${thisIdentifier} has the invalid name \`${name}\``, { workspace, index }); }); } function validateBasePaths(workspaces) { workspaces.length > 1 && workspaces.every(hasBasePath), workspaces.every(validateBasePath); const [firstWorkspace, ...restOfWorkspaces] = workspaces, firstWorkspaceSegmentCount = (firstWorkspace.basePath || "/").slice(1).split("/").filter(Boolean).length; restOfWorkspaces.forEach((workspace, index) => { const workspaceSegmentCount = (workspace.basePath || "/").slice(1).split("/").length; if (firstWorkspaceSegmentCount !== workspaceSegmentCount) throw new WorkspaceValidationError(`All workspace \`basePath\`s must have the same amount of segments. Workspace \`${getWorkspaceIdentifier(firstWorkspace, index)}\` had ${firstWorkspaceSegmentCount} segment${firstWorkspaceSegmentCount === 1 ? "" : "s"} \`${firstWorkspace.basePath}\` but workspace \`${getWorkspaceIdentifier(workspace, index)}\` had ${workspaceSegmentCount} segment${workspaceSegmentCount === 1 ? "" : "s"} \`${workspace.basePath}\``, { workspace, index }); }); const basePaths = /* @__PURE__ */ new Map(); workspaces.forEach((workspace, index) => { const basePath = (workspace.basePath || "").toLowerCase(), existingWorkspace = basePaths.get(basePath); if (existingWorkspace) throw new WorkspaceValidationError(`\`basePath\`s must be unique. Workspaces \`${existingWorkspace}\` and \`${getWorkspaceIdentifier(workspace, index)}\` both have the \`basePath\` \`${basePath}\``, { workspace, index }); basePaths.set(basePath, getWorkspaceIdentifier(workspace, index)); }); } function hasBasePath(workspace, index) { const { name, basePath } = workspace; if (basePath && typeof basePath == "string") return !0; throw typeof basePath > "u" ? new WorkspaceValidationError(`If more than one workspace is defined, every workspace must have a \`basePath\` defined. Workspace \`${name}\` is missing a \`basePath\``, { workspace, index }) : new WorkspaceValidationError(`If more than one workspace is defined, every workspace must have a \`basePath\` defined. Workspace \`${name}\` has an invalid \`basePath\` (must be a non-empty string)`, { workspace, index }); } function validateBasePath(workspace, index) { const { name, basePath } = workspace; if (!(!basePath || basePath === "/") && !/^\/[a-z0-9/_-]*[a-z0-9_-]+$/i.test(basePath)) throw new WorkspaceValidationError(`All workspace \`basePath\`s must start with a leading \`/\`, consist of only URL safe characters, and cannot end with a trailing \`/\`. Workspace \`${name}\`'s basePath is \`${basePath}\``, { workspace, index }); } const DEBUG_MODE$2 = !1, SPINNER_DELAY = 750, TEXT_DELAY = 2e3, StyledCard$6 = styled(Card)(({ $fill }) => css` align-items: center; box-sizing: border-box; display: flex; flex-direction: column; justify-content: center; ${$fill ? css` bottom: 0; height: 100%; left: 0; position: absolute; right: 0; top: 0; width: 100%; ` : css` min-height: 75px; height: stretch; height: -webkit-fill-available; width: stretch; width: -webkit-fill-available; `} ${DEBUG_MODE$2} > * { position: absolute; } `), StyledSpinner = styled(Spinner)(({ $animatePosition = !0 }) => css` @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes slideUp { from { transform: translateY(0); } to { transform: translateY(-15px); } } animation: ${$animatePosition ? `500ms ease-out ${SPINNER_DELAY}ms 1 normal both running fadeIn, 750ms ease-out ${TEXT_DELAY}ms 1 normal both running slideUp` : `500ms ease-out ${SPINNER_DELAY}ms 1 normal both running fadeIn`}; `), StyledText$7 = styled(Text$1)` @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes slideDown { from { transform: translateY(0); } to { transform: translateY(15px); } } animation: 1500ms ease-out ${TEXT_DELAY}ms 1 normal both running fadeIn, 750ms ease-out ${TEXT_DELAY}ms 1 normal both running slideDown; `; function LoadingBlock(t0) { const $ = c(10), { fill, showText, title } = t0, t1 = fill ? Layer : "div", t2 = !!showText; let t3; $[0] !== t2 ? (t3 = /* @__PURE__ */ jsx(StyledSpinner, { $animatePosition: t2, muted: !0 }), $[0] = t2, $[1] = t3) : t3 = $[1]; let t4; $[2] !== showText || $[3] !== title ? (t4 = showText && /* @__PURE__ */ jsx(LoadingText, { title }), $[2] = showText, $[3] = title, $[4] = t4) : t4 = $[4]; let t5; return $[5] !== fill || $[6] !== t1 || $[7] !== t3 || $[8] !== t4 ? (t5 = /* @__PURE__ */ jsxs(StyledCard$6, { $fill: fill, as: t1, "data-testid": "loading-block", children: [ t3, t4 ] }), $[5] = fill, $[6] = t1, $[7] = t3, $[8] = t4, $[9] = t5) : t5 = $[9], t5; } function LoadingText(t0) { const $ = c(5), { title } = t0, { t } = useTranslation(); let t1; $[0] !== t || $[1] !== title ? (t1 = title || t("common.loading"), $[0] = t, $[1] = title, $[2] = t1) : t1 = $[2]; let t2; return $[3] !== t1 ? (t2 = /* @__PURE__ */ jsx(StyledText$7, { muted: !0, size: 1, children: t1 }), $[3] = t1, $[4] = t2) : t2 = $[4], t2; } function defineLocaleResourceBundle(bundle) { return bundle; } function defineLocale(locale) { return locale; } function isStaticResourceBundle(bundle) { return !("then" in bundle.resources && typeof bundle.resources.then == "function"); } function defineLocalesResources(namespace, resources) { return resources; } function removeUndefinedLocaleResources(resources) { const result = {}; for (const key in resources) typeof resources[key] < "u" && (result[key] = resources[key]); return result; } const studioLocaleNamespace = "studio", validationLocaleNamespace = "validation", copyPasteLocalNamespace = "copy-paste", copyPasteLocaleStrings = defineLocalesResources("copy-paste", { /** Text on the field action button to copy a document */ "copy-paste.field-action-copy-button.document.title": "Copy document", /** Text on the field action button to copy a field */ "copy-paste.field-action-copy-button.field.title": "Copy field", /** Text on the field action button to paste a document */ "copy-paste.field-action-paste-button.document.title": "Paste document", /** Text on the field action button to paste a field */ "copy-paste.field-action-paste-button.field.title": "Paste field", /** --- On paste --- */ /** The validation message that is shown when pasting a value into a read-only target */ "copy-paste.on-paste.validation.read-only-target.description": "The target is read-only", /** The validation message that is shown when the source and target schema types are incompatible */ "copy-paste.on-paste.validation.schema-type-incompatible.description": "Source and target schema types are not compatible", /** The validation message that is shown when reference types are incompatible */ "copy-paste.on-paste.validation.reference-type-incompatible.description": 'References of type "{{sourceReferenceType}}" is not allowed in reference field that accepts types "{{targetReferenceTypes}}"', /** The validation message that is shown when reference is incompatible with filter */ "copy-paste.on-paste.validation.reference-filter-incompatible.description": "Reference is not allowed in reference field according to filter", /** The validation message that is shown when reference does not exist */ "copy-paste.on-paste.validation.reference-validation-failed.description": 'The referenced document "{{ref}}" does not exist', /** The validation message that is shown when image files are incompatible */ "copy-paste.on-paste.validation.image-file-incompatible.description": 'A "{{sourceSchemaType}}" is not allowed in a "{{targetSchemaType}}"', /** The validation message that is shown when array types are incompatible */ "copy-paste.on-paste.validation.array-type-incompatible.description": 'Value of type "{{type}}" is not allowed in this array field', /** The validation message that is shown when array values are incompatible */ "copy-paste.on-paste.validation.array-value-incompatible.description": 'Value of type "{{type}}" is not allowed in this array field', /** The validation message that is shown when string values are incompatible */ "copy-paste.on-paste.validation.string-value-incompatible.description": 'Value "{{value}}" is not allowed in "{{allowedStrings}}"', /** The validation message that is shown when primitive types are incompatible */ "copy-paste.on-paste.validation.primitive-type-incompatible.description": 'Value of type "{{type}}" is not allowed in this field', /** The validation message that is shown when the clipboard is empty */ "copy-paste.on-paste.validation.clipboard-empty.title": "Nothing to paste", /** The validation message that is shown when the clipboard item is invalid */ "copy-paste.on-paste.validation.clipboard-invalid.title": "Invalid clipboard item", /** The validation message that is shown when schema types are incompatible */ "copy-paste.on-paste.validation.schema-type-incompatible.title": "Could not resolve schema type for path: {{path}}", /** The warning message that is shown when not all values can be pasted */ "copy-paste.on-paste.validation.partial-warning.title": "Could not paste all values", /** The error message that is shown when the MIME type is not accepted */ "copy-paste.on-paste.validation.mime-type-incompatible.description": 'MIME type "{{mimeType}}" is not accepted for this field', /** The error message that is shown when the MIME type validation fails */ "copy-paste.on-paste.validation.mime-type-validation-failed.description": "MIME type validation failed", /** --- On copy --- */ /** The error message that is shown when schema types are incompatible */ "copy-paste.on-copy.validation.schema-type-incompatible.title": "Could not resolve schema type for path: {{path}}", /** The error message that is shown when there is no value to copy */ "copy-paste.on-copy.validation.no-value.title": "Empty value, nothing to copy", /** The error message that is shown when the clipboard is not supported */ "copy-paste.on-copy.validation.clipboard-not-supported.description": "Clipboard access required to copy this content. Allow clipboard permissions in your browser settings, then try copying again.", /** The error message that is shown when the clipboard is not supported */ "copy-paste.on-copy.validation.clipboard-not-supported.title": "Clipboard access blocked" }), copyPasteLocaleResources = { locale: "en-US", namespace: copyPasteLocalNamespace, resources: copyPasteLocaleStrings }, studioLocaleStrings = defineLocalesResources("studio", { /** "Configuration issue" header */ "about-dialog.configuration-issue.header": "Configuration issue detected", /** Message shown if sanity.cli.ts is missing deployment.appId */ "about-dialog.configuration-issue.missing-appid": "Auto updates is enabled, but no <code>deployment.appId</code> configured in <code>sanity.cli.ts</code>. This Studio is updating against the <strong>latest</strong>-channel.", /** "View documentation" link for auto-updating studios */ "about-dialog.configuration-issue.missing-appid.view-documentation": "View documentation", /** "Disabled" status for auto-updates in About-dialog */ "about-dialog.version-info.auto-updates.disabled": "Auto Updates not enabled", /** "Enabled" status for auto-updates in About-dialog */ "about-dialog.version-info.auto-updates.enabled": "Auto Updates Enabled", /** @deprecated "Auto Updates" status header in About-dialog */ "about-dialog.version-info.auto-updates.header": "Auto Updates", /** "How to enable" next to Disabled state for Auto updates in version info dialog */ "about-dialog.version-info.auto-updates.how-to-enable": "Enable", /** "Manage version" link text */ "about-dialog.version-info.auto-updates.manage-version": "Manage version", /** Text displayed on the "Copy to clipboard"-button after clicked */ "about-dialog.version-info.copy-to-clipboard-button.copied-text": "Copied to Clipboard. Happy pasting!", /** "Copy to Clipboard" button text for copying version details from About-dialog */ "about-dialog.version-info.copy-to-clipboard-button.text": "Copy to Clipboard", /** "Current version" header in version info dialog */ "about-dialog.version-info.current-version.header": "Current version", /** @deprecated "How to upgrade" link text */ "about-dialog.version-info.how-to-upgrade": "Update now", /** "Lates