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

1,394 lines 624 kB
import * as _$react from "react"; import { CSSProperties, Component, ComponentProps, ComponentType, Dispatch, ElementType, ErrorInfo, FC, FocusEvent, FocusEventHandler, FormEvent, FormEventHandler, HTMLAttributes, HTMLProps, KeyboardEvent, MutableRefObject, PropsWithChildren, PureComponent, ReactElement, ReactNode, Ref, RefAttributes, RefObject, SVGProps, SetStateAction } from "react"; import * as _$_sanity_types0 from "@sanity/types"; import { ArraySchemaType, AssetMetadataType, AssetSource, AssetSourceSpec, BlockDecoratorDefinition, BlockListDefinition, BlockStyleDefinition, BooleanSchemaType, ConditionalProperty, CrossDatasetReferenceSchemaType, CrossDatasetReferenceValue, CrossDatasetType, CurrentUser, DeprecatedProperty, FieldGroup, File as File$1, FileAsset, FileSchemaType, FileValue, FormNodeValidation, GeopointValue, GlobalDocumentReferenceType, I18nTextRecord, Image, ImageAsset, ImageSchemaType, ImageUrlFitMode, ImageValue, IndexTuple, InitialValueProperty, InitialValueResolverContext, IntrinsicTypeName, KeyedObject, KeyedSegment, MendozaEffectPair, NumberSchemaType, ObjectField, ObjectFieldType, ObjectSchemaType, PatchOperations, Path, PathSegment, PortableTextBlock, PortableTextObject, PortableTextTextBlock, PrepareViewOptions, PreviewValue, Reference, ReferenceSchemaType, ReferenceValue, Role, RuleClass, SanityDocument, SanityDocumentLike, Schema, SchemaType, SchemaTypeDefinition, SearchStrategy, SlugSchemaType, SlugValue, SortOrdering, StrictVersionLayeringOptions, StringSchemaType, TextSchemaType, TransactionLogEventWithEffects, TransactionLogEventWithMutations, UploadState, User, ValidationMarker } from "@sanity/types"; import { BifurClient } from "@sanity/bifur-client"; import { ClientConfig, ClientPerspective, QueryParams, ReconnectEvent, ReleaseDocument, ReleaseDocument as ReleaseDocument$1, ReleaseType, ResetEvent, SanityClient, SanityDocument as SanityDocument$1, SingleActionResult, SingleMutationResult, StackablePerspective, WelcomeBackEvent, WelcomeEvent } from "@sanity/client"; import * as _$_sanity_ui0 from "@sanity/ui"; import { AvatarPosition, AvatarProps, AvatarSize, AvatarStatus, BadgeProps, BadgeTone, BoxProps, ButtonProps, ButtonTone, CardProps, DialogProps, HotkeysProps, MenuButtonProps, MenuItem, Placement, PopoverProps, ResponsivePaddingProps, ResponsiveWidthProps, Text, TextProps, ThemeColorSchemeKey, ToastParams, TooltipProps } from "@sanity/ui"; import { FlatNamespace, KeyPrefix, Namespace, TFunction, TFunction as TFunction$1, i18n as i18n$1 } from "i18next"; import { MonoTypeOperatorFunction, Observable, OperatorFunction, Subject } from "rxjs"; import { IntentLinkProps, IntentParameters, Router, RouterState, SearchParam } from "sanity/router"; import { ScrollToOptions } from "@tanstack/react-virtual"; import * as _$_sanity_telemetry0 from "@sanity/telemetry"; import { DRAFTS_FOLDER, DraftId, PublishedId, VERSION_FOLDER, getDraftId, getPublishedId, getVersionFromId, getVersionId, isDraftId, isPublishedId, isVersionId } from "/home/runner/work/sanity/sanity/node_modules/.pnpm/@sanity+client@7.22.0/node_modules/@sanity/client/dist/csm.js"; import * as _$sanity__singletons0 from "sanity/_singletons"; import { DocumentDivergencesContextValue, DocumentLimitUpsellContextValue, FeedbackContext, FeedbackContextValue, FieldActionsContextValue, HoveredFieldContextValue, LocaleContextValue, SchedulesContext, SingleDocReleaseContextValue } from "sanity/_singletons"; import { Mutation } from "@sanity/mutator"; import { CanvasResource, FrameMessages, MediaResource, StudioResource, WindowMessages } from "@sanity/message-protocol"; import { DocumentHandle } from "@sanity/sdk"; import { FallbackNs } from "react-i18next"; import { BrowserHistory, HashHistory, History, MemoryHistory } from "history"; import { RootTheme, ThemeColorSchemeKey as ThemeColorSchemeKey$1 } from "/home/runner/work/sanity/sanity/node_modules/.pnpm/@sanity+ui@3.1.14_@emotion+is-prop-valid@1.4.0_@sanity+styled-components@6.1.24_react-d_528b1f4be90cc37f64b725ea29f6a91b/node_modules/@sanity/ui/dist/theme.mjs"; import { EditorSelection, HotkeyOptions, InvalidValueResolution, OnCopyFn, OnPasteResultOrPromise, PasteData, Patch, PortableTextEditor, RangeDecoration, RangeDecorationOnMovedDetails, RenderBlockFunction } from "@portabletext/editor"; import { ColorHueKey, ColorTintKey, ColorTints } from "@sanity/color"; import { Subscriber } from "nano-pubsub"; import { ArrayDiff, BooleanDiff, Diff, ItemDiff, NullDiff, NumberDiff, ObjectDiff, StringDiff, StringSegmentChanged, StringSegmentUnchanged, TypeChangeDiff } from "@sanity/diff"; import * as _$styled_components0 from "styled-components"; import { CSSProperties as CSSProperties$1, ExecutionProps } from "styled-components"; import { ThrottleSettings } from "lodash-es/throttle.js"; import { DEFAULT_ANNOTATIONS, DEFAULT_DECORATORS } from "@sanity/schema"; import * as _$styled_components_dist_types0 from "/home/runner/work/sanity/sanity/node_modules/.pnpm/@sanity+styled-components@6.1.24_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@sanity/styled-components/dist/types.js"; import { PortableTextMemberSchemaTypes } from "@portabletext/sanity-bridge"; import { ImageUrlBuilder, ImageUrlBuilder as ImageUrlBuilder$1 } from "@sanity/image-url"; import { MarkdownShortcutsPluginProps } from "@portabletext/plugin-markdown-shortcuts"; import { PasteLinkPluginProps } from "@portabletext/plugin-paste-link"; import { TypographyPluginProps } from "@portabletext/plugin-typography"; import { Node } from "@sanity/comlink"; interface CreateSanityMediaLibrarySourceProps { i18nKey?: string; icon?: React.ComponentType; libraryId: string | null; name?: string; } /** * Create a new image asset source for the Media Library * * @beta */ declare function createSanityMediaLibraryImageSource(props: CreateSanityMediaLibrarySourceProps): AssetSource; /** * Create a new file asset source for the Media Library * * @beta */ declare function createSanityMediaLibraryFileSource(props: CreateSanityMediaLibrarySourceProps): AssetSource; interface SharedProps$1 { children?: ReactNode; header: string; width: ResponsiveWidthProps['width']; } interface DialogProps$2 extends SharedProps$1 { type: 'dialog'; id?: string; autofocus?: boolean; onClose?: () => void; } interface PopoverProps$3 extends SharedProps$1 { type: 'popover'; legacy_referenceElement: HTMLElement | null; onClose: () => void; } /** * @beta * Creates a dialog or a popover for editing content. * Handles presence and virtual scrolling. */ declare function EditPortal(props: PopoverProps$3 | DialogProps$2): React.JSX.Element; interface SharedProps { children?: ReactNode; header: string; width: ResponsiveWidthProps['width']; } interface DialogProps$1 extends SharedProps { type: 'dialog'; id?: string; autofocus?: boolean; onClose?: () => void; } interface PopoverProps$2 extends SharedProps { type: 'popover'; id?: string; legacy_referenceElement: HTMLElement | null; onClose: () => void; } /** * @beta * Creates a dialog or a popover for editing content. * Handles presence and virtual scrolling. * * When multiple dialogs are open, only the top-most dialog is visible. * Non-top dialogs are hidden via CSS while preserving their state. */ declare function EnhancedObjectDialog(props: PopoverProps$2 | DialogProps$1): React.JSX.Element; /** * Returns whether the given version name (e.g. from `getVersionFromId`) is an * agent bundle name (starts with `agent-`). * * @internal */ declare function isAgentBundleName(versionName: unknown): boolean; /** * Display overrides for an agent bundle version chip. * * @internal */ type AgentVersionDisplay = { displayName: string; tone: BadgeTone; }; /** * Filters a list of version document IDs and provides display metadata for * agent bundles. * * - Other users' `agent-*` versions are removed from the returned list. * - The current user's `agent-*` versions are kept and can be resolved to * display overrides via `getVersionDisplay`. * - Non-agent versions pass through unchanged. * - While the SSE connection is loading, only the currently active agent * bundle (if any) is kept; all others are hidden until ownership is confirmed. * * Call this hook once and thread the results down — don't call it per-item. * * @internal */ declare function useAgentVersionDisplay(versionIds: string[], activeBundleId?: string): { /** Version IDs with other users' agent bundles removed. */filteredVersionIds: string[]; /** * Returns display overrides for a version document ID if it's the current * user's agent bundle, or `null` for all other versions. */ getVersionDisplay: (versionDocumentId: string) => AgentVersionDisplay | null; }; /** * Login methods that may be used for Studio authentication. * * @public */ type LoginMethod = 'dual' | 'cookie' | 'token'; /** * Login methods that acknowledge cookieless authentication tokens. * * @internal * @hidden */ type CookielessCompatibleLoginMethod = Extract<LoginMethod, 'dual' | 'token'>; /** * Authentication options * * @public */ interface AuthConfig { /** * Login method to use for the studio. Can be one of: * - `dual` (default) - attempt to use cookies where possible, falling back to * storing authentication token in `localStorage` otherwise * - `cookie` - explicitly disable `localStorage` method, relying only on cookies. May fail due * to cookies being treated as third-party cookies in some browsers, thus the default is `dual`. * - `token` - explicitly disable cookies, relying only on `localStorage` method */ loginMethod?: LoginMethod; /** * Whether to append the providers specified in `providers` with the default providers from the * API, or replace the default providers with the ones specified. * * @deprecated Use the function form of `providers` instead for more control */ mode?: 'append' | 'replace'; /** * If true, the "Choose login provider" (eg "Google, "GitHub", "E-mail/password") screen * will be skipped if only a single provider is configured in the `providers` array - * instead it will redirect unauthenticated users straight to the authentication URL. */ redirectOnSingle?: boolean; /** * Array of authentication providers to use, or a function that takes an array of default * authentication providers (fetched from the Sanity API) and should return a new list of * providers. This can be used to selectively replace, add or remove providers from the * list of choices. * * @remarks If a static array of providers is provided, the `mode` property is taken into account * when determining what to do with it - `append` will append the providers to the default set * of providers, while `replace` will replace the default providers with the ones specified. * * If not set, the default providers will be used. */ providers?: AuthProvider[] | ((prev: AuthProvider[]) => AuthProvider[] | Promise<AuthProvider[]>); /** * The API hostname for requests. Should usually be left undefined, * but can be set if using custom cname for API domain. */ apiHost?: string; } /** * A provider of authentication. * * By default, a list of providers for a project will be fetched from the * {@link https://api.sanity.io/v1/auth/providers | Sanity API}, but you may choose to limit this * list by explicitly defining the providers you want to allow, or add additional custom providers * that conforms to the authentication provider specification outlined in * {@link https://www.sanity.io/docs/third-party-login | the documentation}. * * @public */ interface AuthProvider { /** * URL-friendly identifier/name for the provider, eg `github` */ name: string; /** * Human friendly title for the provider, eg `GitHub` */ title: string; /** * URL for the authentication endpoint that will trigger the authentication flow */ url: string; /** * URL for a logo to display next to the provider in the login screen */ logo?: string; } type AuthProbeResult = { authenticated: false; } | { authenticated: true; id: string; }; /** * The interface used by the Studio that produces a `SanityClient` and * `CurrentUser` that gets passed to the resulting `Workspace`s and `Source`s. * * NOTE: This interface is primarily for internal use. Refer to * `createAuthStore` instead. * * @beta * @hidden */ interface AuthStore { /** * Emits `AuthState`s. This should update when the user's auth state changes. * E.g. After a login, a new `AuthState` could be emitted with a non-null * `currentUser` and `authenticated: true` * * NOTE: all auth store implementations should emit on subscribe using * something like shareReplay(1) to ensure all new subscribers get an * `AuthState` value on subscribe */ state: Observable<AuthState>; /** * Emits auth tokens, or `null` if not configured to use them or they do not exist */ token?: Observable<string | null>; /** * Custom auth stores are expected to implement a UI that initiates the user's * authentication. For the typical case in `createAuthStore`, this means * loading the providers and showing them as options to the user. */ LoginComponent?: ComponentType<LoginComponentProps>; /** * Custom auth stores can implement a function that runs when the user logs * out. The implementation is expected to remove all credentials both locally * and on the server. */ logout?: () => Promise<void>; /** * Custom auth stores can implement a function that is designated to run when * the Studio loads (e.g. to trade a session ID for a token in cookie-less * mode). Within the Studio, this is called within the `AuthBoundary`. */ handleCallbackUrl?: () => Promise<HandleCallbackResult>; } /** * The unit an `AuthStore` emits to determine the user's authentication state. * * @beta * @hidden */ interface AuthState { /** * Similar to a logged-in flag. This state is used in places like the * `AuthBoundary` to determine whether or not it should render the * `NotAuthenticatedComponent`. Implementers may choose to set this to `true` * while also also emitting a `currentUser` of `null` if a `null` user is * accepted (e.g. a project that doesn't require a login) */ authenticated: boolean; /** * The value of the user logged in or `null` if none is provided */ currentUser: CurrentUser | null; /** * A client that is expected to be pre-configured to allow for any downstream * requests in the Studio */ client: SanityClient; } /** * @beta * @hidden */ type LoginComponentProps = { projectId: string; /** @deprecated use redirectPath instead */ basePath: string; redirectPath?: string; } | { projectId: string; redirectPath: string; /** @deprecated use redirectPath instead */ basePath?: string; }; /** * Result returned from `handleCallbackUrl` describing what happened during * the auth callback flow. Used for telemetry, diagnostics, and error handling * in the AuthBoundary. * * @internal */ interface HandleCallbackResult { /** The login method configured for this auth store (e.g. `'cookie'` or `'token'`). */ loginMethod: LoginMethod; /** * Which auth flow was taken: * - `'already-authenticated'`: No sid in hash - user was already authenticated or not. * - `'exchange'`: sid was present, went through /auth/exchange + probe flow. */ flow: 'already-authenticated' | 'exchange'; /** Whether the auth flow completed successfully. */ success: boolean; /** Total wall-clock time for the callback handling, in milliseconds. */ durationMs: number; /** Time spent on the /auth/exchange call specifically. Only set for `'exchange'` flow. */ exchangeDurationMs?: number; /** Time spent on the /users/me probe calls. Only set for `'exchange'` flow. */ probeDurationMs?: number; /** Which auth method was selected by the probes. Only set when `success` is `true` and flow is `'exchange'`. */ authMethod?: 'cookie' | 'token'; /** Human-readable reason for failure. Only set when `success` is `false`. */ failureReason?: string; /** * Structured error for the AuthBoundary to render appropriate UI. * Only set when `success` is `false` and flow is `'exchange'`. * * - `'cookie-blocked'`: cookie-only mode and the cookie probe failed. * The browser likely has strict cookie policies. * - `'auth-failed'`: all probe methods failed. The user should retry. */ error?: { type: 'cookie-blocked' | 'auth-failed'; message: string; }; } /** @internal */ interface AuthStoreOptions extends AuthConfig { clientFactory?: (options: ClientConfig) => SanityClient; projectId: string; dataset: string; /** * Retrieves the session ID from the URL hash for the auth callback flow. * Called by `handleCallbackUrl` to obtain the session ID that is exchanged * for a token or cookie. * @internal */ getSessionId: () => string | undefined; /** * Extracts and consumes a `#token=…` fragment from the URL hash. * Called at init to pick up hash tokens and on `hashchange` events. * @internal */ consumeHashToken: () => string | undefined; } /** * @internal */ declare function _createAuthStore({ clientFactory: clientFactoryOption, projectId, dataset, apiHost, loginMethod, getSessionId, consumeHashToken, ...providerOptions }: AuthStoreOptions): AuthStore; /** * Public options for `createAuthStore`. The `getSessionId` and `consumeHashToken` * dependencies are wired automatically using the default implementations. * @internal */ type CreateAuthStoreOptions = Omit<AuthStoreOptions, 'getSessionId' | 'consumeHashToken'>; /** * @internal */ declare const createAuthStore: (options: CreateAuthStoreOptions) => AuthStore; /** @internal */ interface MockAuthStoreOptions { currentUser: CurrentUser | null; client: SanityClient; } /** * Creates a mock `AuthStore` (for testing) that emits an `AuthState` derived * from the `client` and `currentUser` given. * * @internal */ declare function createMockAuthStore({ client, currentUser }: MockAuthStoreOptions): AuthStore; /** @internal */ declare function getProviderTitle(provider?: string): string | undefined; /** * Duck-type check for whether or not this looks like an auth store * * @param maybeStore - Item to check if matches the AuthStore interface * @returns True if auth store, false otherwise * @internal */ declare function isAuthStore(maybeStore: unknown): maybeStore is AuthStore; /** * Check whether the provided login method is compatible with cookieless auth, e.g. whether any * authentication token found in localStorage should be acknowledged. * * @internal */ declare function isCookielessCompatibleLoginMethod(loginMethod: LoginMethod): loginMethod is CookielessCompatibleLoginMethod; /** @internal */ interface ConnectionStatusStore { connectionStatus$: Observable<ConnectionStatus>; } /** @internal */ type ConnectingStatus = { type: 'connecting'; }; /** @internal */ type ErrorStatus = { type: 'error'; error: Error; attemptNo: number; isOffline: boolean; retryAt: Date; }; /** @internal */ type RetryingStatus = { type: 'retrying'; }; /** @internal */ type ConnectedStatus = { type: 'connected'; lastHeartbeat: Date; }; /** @internal */ declare const CONNECTING: ConnectingStatus; /** @internal */ type ConnectionStatus = ConnectingStatus | ErrorStatus | ConnectedStatus | RetryingStatus; /** @internal */ declare const onRetry: () => void; /** @internal */ interface ConnectionStatusStoreOptions { bifur: BifurClient; } /** * This is the beginning of what should be the data store tracking connection status in the Sanity studio. * * @internal */ declare function createConnectionStatusStore({ bifur }: ConnectionStatusStoreOptions): ConnectionStatusStore; /** @internal */ interface CorsOriginErrorOptions { projectId?: string; isStaging: boolean; } /** @internal */ declare class CorsOriginError extends Error { projectId?: string; isStaging: boolean; constructor({ projectId, isStaging }: CorsOriginErrorOptions); } /** @internal */ type BetaBadgeProps = Omit<BadgeProps, 'mode' | 'tone'>; /** @internal */ declare function BetaBadge(props: BetaBadgeProps & Omit<HTMLProps<HTMLDivElement>, 'ref'>): _$react.JSX.Element; /** @internal */ type CommandListElementType = 'input' | 'list'; /** @internal */ type CommandListGetItemDisabledCallback = (virtualIndex: number) => boolean; /** @internal */ type CommandListGetItemKeyCallback = (virtualIndex: number) => number | string; /** @internal */ type CommandListGetItemSelectedCallback = (virtualIndex: number) => boolean; /** @internal */ type CommandListItemContext = { activeIndex: number | null; disabled?: boolean; selected?: boolean; virtualIndex: number; }; /** @internal */ type CommandListRenderItemCallback<T> = (item: T, context: CommandListItemContext) => ReactNode; /** @internal */ interface CommandListHandle { focusInputElement: () => void; focusListElement: () => void; getTopIndex: () => number; scrollToIndex: (index: number) => void; } /** @internal */ interface CommandListProps<T = any> extends ResponsivePaddingProps { /** The data attribute to apply to any active virtual list items */ activeItemDataAttr?: string; /** `aria-label` to apply to the virtual list container element */ ariaLabel: string; /** Whether `aria-multiselectable` is enabled on the virtual list container element */ ariaMultiselectable?: boolean; /** Automatically focus the input or virtual list */ autoFocus?: CommandListElementType; /** Whether the virtual list can receive focus */ canReceiveFocus?: boolean; /** Pixel offset of the virtual list focus ring. Negative values will cause the focus ring to appear inset */ focusRingOffset?: number; /** Force a fixed height for all virtual list children and skip measurement (faster). */ fixedHeight?: boolean; /** Custom function to map disabled items */ getItemDisabled?: CommandListGetItemDisabledCallback; /** Custom function to map virtual list items to custom keys */ getItemKey?: CommandListGetItemKeyCallback; /** Custom function to map selected items */ getItemSelected?: CommandListGetItemSelectedCallback; /** Scroll alignment of the initial active index */ initialScrollAlign?: ScrollToOptions['align']; /** Initial active index on mount */ initialIndex?: number; /** Input element to associate with this virtual list. Associated inputs will receive focus and handle key events */ inputElement?: HTMLInputElement | null; /** Estimated height for each list item */ itemHeight: number; /** Virtual list item values, accessible to all rendered item components */ items: T[]; /** Callback fired when the virtual list is within `onEndReachedIndexThreshold` of rendered content */ onEndReached?: () => void; /** Number of items from the end of the virtual list before which `onEndReached` is triggered */ onEndReachedIndexOffset?: number; /** Only show selection state when the virtual list is active (is hovered or has focus) */ onlyShowSelectionWhenActive?: boolean; /** Number of items to render above and below the visible area*/ overscan?: number; /** Rendered component in virtual lists */ renderItem: CommandListRenderItemCallback<T>; /** `data-testid` to apply to outermost container */ testId?: string; /** Allow wraparound keyboard navigation between first and last items */ wrapAround?: boolean; } /** * Renders a Command List with support for the following: * * - Keyboard navigation (↑ / ↓ / ENTER) to children with a specified container (`childContainerRef`) * - Focus redirection when clicking child elements * - Pointer blocking when navigating with arrow keys (to ensure that only one active state is visible at any given time) * - ARIA attributes to define a `combobox` input that controls a separate `listbox` * * @internal */ declare const CommandList: _$react.NamedExoticComponent<CommandListProps<any> & _$react.RefAttributes<CommandListHandle>>; type BaseButtonProps = Pick<ButtonProps, 'as' | 'icon' | 'iconRight' | 'justify' | 'loading' | 'mode' | 'paddingY' | 'paddingLeft' | 'selected' | 'tone' | 'type' | 'width'> & { size?: 'default' | 'large'; radius?: 'full'; }; type ButtonWithText = { text: string; tooltipProps?: TooltipProps$1 | null; icon?: ButtonProps['icon']; }; type IconButton = { text?: undefined; icon?: ButtonProps['icon']; /** * When using a button with an icon, tooltipProps are required to enforce consistency in UI. */ tooltipProps: TooltipProps$1 | null; }; /** @internal */ type ButtonProps$1 = BaseButtonProps & (ButtonWithText | IconButton); /** * Customized Sanity UI <Button> with pre-defined layout options. * * @internal */ declare const Button: _$react.ForwardRefExoticComponent<(Omit<Pick<ButtonProps, "as" | "icon" | "iconRight" | "justify" | "loading" | "mode" | "paddingLeft" | "paddingY" | "selected" | "tone" | "type" | "width"> & { size?: 'default' | 'large'; radius?: 'full'; } & ButtonWithText & Omit<HTMLProps<HTMLButtonElement>, "as" | "size" | "title">, "ref"> | Omit<Pick<ButtonProps, "as" | "icon" | "iconRight" | "justify" | "loading" | "mode" | "paddingLeft" | "paddingY" | "selected" | "tone" | "type" | "width"> & { size?: 'default' | 'large'; radius?: 'full'; } & IconButton & Omit<HTMLProps<HTMLButtonElement>, "as" | "size" | "title">, "ref">) & _$react.RefAttributes<HTMLButtonElement>>; /** @internal */ type MenuButtonProps$1 = Omit<MenuButtonProps, 'popover'> & { popover?: Omit<PopoverProps, 'animate' | 'content' | 'open'>; }; /** @internal */ type TooltipProps$1 = Omit<TooltipProps, 'arrow' | 'padding' | 'shadow'> & { hotkeys?: HotkeysProps['keys']; }; /** @internal */ type PopoverProps$1 = PopoverProps; type ContextMenuButtonProps = Pick<ButtonProps$1, 'mode' | 'selected' | 'size' | 'tone' | 'tooltipProps' | 'loading'>; /** * Simple context menu button (with horizontal ellipsis icon) with shared localization. * * @internal */ declare const ContextMenuButton: _$react.ForwardRefExoticComponent<ContextMenuButtonProps & Pick<HTMLProps<HTMLButtonElement>, "disabled" | "hidden" | "onClick"> & _$react.RefAttributes<HTMLButtonElement>>; /** * Indicates the type of document variant, either `draft`, `version` or `published`. * Draft documents are prefixed with `drafts.`. * Version documents are prefixed with `versions.<versionName>` * The rest are considered published documents. * @public */ type DocumentVariantType = 'draft' | 'version' | 'published'; /** * Takes a document id and returns the variant type for that document * If it's a document that starts with `version.` it's a `version` document. * If it's a document that starts with `drafts.` it's a `draft` document. * Otherwise, it's a `published` document. * @public * */ declare function getDocumentVariantType(documentId: string): DocumentVariantType; /** * @internal */ declare const Chip: _$react.ForwardRefExoticComponent<Omit<Omit<_$_sanity_ui0.ButtonProps & Omit<_$react.HTMLProps<HTMLButtonElement>, "as" | "width">, "ref"> & _$react.RefAttributes<HTMLButtonElement>, "ref"> & _$react.RefAttributes<unknown>>; /** * * Checks if the document ID `documentId` has the same ID as `equalsDocumentId`, * ignoring the draft prefix. * * @public * * @param documentId - The document ID to check * @param equalsDocumentId - The document ID to check against * * @example * Draft vs published document ID, but representing the same document: * ``` * // Prints "true": * console.log(documentIdEquals('drafts.agot', 'agot')); * ``` * @example * Different documents: * ``` * // Prints "false": * console.log(documentIdEquals('hp-tcos', 'hp-hbp')); * ``` * * @returns `true` if the document IDs are equal, `false` otherwise */ declare function documentIdEquals(documentId: string, equalsDocumentId: string): boolean; /** @internal */ declare function isDraft(document: SanityDocumentLike): boolean; /** * TODO: Improve return type based on presence of `version` option. * * @internal */ declare function getIdPair(id: string, { version }?: { version?: string; }): { draftId: DraftId; publishedId: PublishedId; versionId?: string; }; /** * System bundles are sets of documents owned by the system. * * - Draft documents contain data that has not yet been published. These documents all exist in the "drafts" path. * - Published documents contain data that has been published. These documents all exist in the root path. * * These differ to user bundles, which are created when a user establishes a custom set of documents * (e.g. by creating a release). * * @public */ declare const systemBundles: readonly ['drafts', 'published']; /** * System bundles are sets of documents owned by the system. * * - Draft documents contain data that has not yet been published. These documents all exist in the "drafts" path. * - Published documents contain data that has been published. These documents all exist in the root path. * * These differ to user bundles, which are created when a user establishes a custom set of documents * (e.g. by creating a release). * * @public */ type SystemBundle = 'drafts' | 'published'; /** @internal */ declare function isSystemBundle(maybeSystemBundle: unknown): maybeSystemBundle is SystemBundle; /** @internal */ type SystemBundleName = 'draft' | 'published'; /** * `isSystemBundle` should be preferred, but some parts of the codebase currently use the singular * "draft" name instead of the plural "drafts". * * @internal */ declare function isSystemBundleName(maybeSystemBundleName: unknown): maybeSystemBundleName is SystemBundleName; /** * @internal * Given a perspective stack and a document id, returns true if the document id matches any of the provided perspectives * e.g. `idMatchesPerspective('['summer'], 'versions.summer.foo') === true` * e.g. `idMatchesPerspective('['drafts', 'summer'], 'versions.summer.foo') === true` * e.g. `idMatchesPerspective('['drafts'], 'versions.summer.foo') === false` * e.g. `idMatchesPerspective('['drafts', 'summer'], 'versions.winter.foo') === false` * * Note: a published id will match any perspective * e.g. `idMatchesPerspective('['drafts', 'summer'], 'foo') === true` */ declare function idMatchesPerspective(perspectiveStack: StackablePerspective[], documentId: string): boolean; /** @internal */ declare function createDraftFrom(document: SanityDocument): SanityDocument; /** @internal */ declare function newDraftFrom(document: SanityDocument): SanityDocument; /** @internal */ declare function createPublishedFrom(document: SanityDocument): SanityDocument; /** * Takes a list of documents and collates draft/published pairs into single entries * `{id: <published id>, draft?: <draft document>, published?: <published document>}` * * Note: because Map is ordered by insertion key the resulting array will be ordered by whichever * version appeared first * * @internal */ interface CollatedHit<T extends { _id: string; } = { _id: string; }> { id: string; type: string; draft?: T; published?: T; versions: T[]; } /** @internal */ declare function collate<T extends { _id: string; _type: string; }>(documents: T[]): CollatedHit<T>[]; /** @internal */ declare function removeDupes(documents: SanityDocumentLike[]): SanityDocumentLike[]; /** * @beta */ type ReleaseId = string; /** * A value representing a perspective, including the data describing it. This is either the name of a * system bundle, or a document describing a release. * * @public */ type TargetPerspective = ReleaseDocument | SystemBundle | string; /** * @beta * @deprecated Use `TargetPerspective` instead. */ type SelectedPerspective = TargetPerspective; /** * @beta */ type PerspectiveStack = ExtractArray<ClientPerspective>; /** * @beta */ interface PerspectiveContextValue { selectedPerspectiveName: 'published' | ReleaseId | undefined; /** * The releaseId as `r<string>`; it will be undefined if the selected perspective is `published` or `drafts` */ selectedReleaseId: ReleaseId | undefined; selectedPerspective: TargetPerspective; /** * The stacked array of perspectives ids ordered chronologically to represent the state of documents at the given point in time. * It can be used as the perspective param in the client to get the correct view of the documents. * @returns ["published"] | ["drafts"] | ["releaseId2", "releaseId1", "drafts"] */ perspectiveStack: PerspectiveStack; excludedPerspectives: string[]; } /** * @internal */ type ExtractArray<Union> = Union extends unknown[] ? Union : never; /** * @internal */ type ReleasesNavMenuItemPropsGetter = (content: { perspective: TargetPerspective; }) => Partial<ComponentProps<typeof MenuItem>>; /** * @internal */ declare const VersionChip: _$react.MemoExoticComponent<(props: { disabled?: boolean; selected: boolean; tooltipContent?: ReactNode; onClick: () => void; text: string; contextMenuPortal?: boolean; tone: BadgeTone; locked?: boolean; onCopyToDraftsNavigate: () => void; contextValues: { documentId: string; documentType: string; releases: ReleaseDocument[]; releasesLoading: boolean; bundleId: string; isVersion: boolean; disabled?: boolean; isGoingToUnpublish?: boolean; release?: ReleaseDocument; }; }) => _$react.JSX.Element>; /** @internal */ type ReleaseAvatarIconProps = { release: TargetPerspective; tone?: never; releaseType?: never; } | { releaseType: ReleaseType; tone?: never; release?: never; } | { /** * @deprecated - Prefer `release` or `releaseType`. */ tone: BadgeTone; release?: never; releaseType?: never; }; declare const ReleaseAvatarIcon: ({ tone, release, releaseType }: ReleaseAvatarIconProps) => _$react.JSX.Element; declare function ReleaseAvatar({ fontSize, padding, ...iconProps }: ReleaseAvatarIconProps & { fontSize?: number; padding?: number; }): React.JSX.Element; /** @internal */ interface ReleaseTitleDetails { displayTitle: string; fullTitle: string; isTruncated: boolean; } /** @internal */ interface ReleaseTitleProps { title: string | undefined; fallback: string; enableTooltip?: boolean; tooltipMaxWidth?: string; children?: (details: ReleaseTitleDetails) => ReactElement; textProps?: Omit<TextProps, 'children'> & { style?: CSSProperties; }; } /** @internal */ declare function ReleaseTitle(props: ReleaseTitleProps): ReactNode; /** * @internal */ declare const VersionInlineBadge: ({ children, $tone }: PropsWithChildren<{ $tone?: BadgeTone; }>) => _$react.JSX.Element; /** * @internal */ declare const getVersionInlineBadge: (release?: TargetPerspective) => FC<{ children?: _$react.ReactNode | undefined; }>; interface ObserveDocumentAPIConfig { dataset?: string; projectId?: string; apiVersion?: string; } type DocumentIdSetObserverState = { status: 'reconnecting' | 'connected'; documentIds: string[]; }; /** @internal */ type Id = string; /** * @hidden * @beta */ type Previewable = ({ _id: string; } | { _type: string; } | { _system?: { delete: boolean; }; } | { _ref: string; _dataset?: string; _projectId?: string; }) & { /** * optional object used to attach meta data to the prepared result. * currently used to add a flag for the invalid preview error fallback and * insufficient permissions fallback * @internal */ _internalMeta?: { type?: string; }; }; /** * TODO: unify with content path from `@sanity/types` * * * @hidden * @beta */ type PreviewPath = FieldName[]; /** @internal */ type Selection = [id: Id, fields: FieldName[]]; /** * @hidden * @beta */ type FieldName = string; /** @internal */ interface AvailabilityResponse { omitted: { id: string; reason: 'existence' | 'permission'; }[]; } /** @internal */ type AvailabilityReason = 'READABLE' | 'PERMISSION_DENIED' | 'NOT_FOUND'; /** * @hidden * @beta */ type PreviewableType = SchemaType | CrossDatasetType | GlobalDocumentReferenceType; /** * @hidden * @beta */ interface ApiConfig { projectId: string; dataset: string; } /** * @hidden * @beta */ type DocumentAvailability = { available: true; reason: 'READABLE'; } | { available: false; reason: 'PERMISSION_DENIED' | 'NOT_FOUND' | 'VERSION_DELETED'; }; /** * @hidden * @beta */ interface DraftsModelDocumentAvailability { /** * document readability for the published document */ published: DocumentAvailability; /** * document readability for the draft document */ draft: DocumentAvailability; /** * document readability for the version document */ version?: DocumentAvailability; } /** * @hidden * @beta */ interface DocumentStackAvailability { /** * Document id */ id: string; /** * Availability for the document in this stack */ availability: DocumentAvailability; } /** * @hidden * @beta */ interface DraftsModelDocument<T extends SanityDocumentLike = SanityDocumentLike> { id: string; type: string | null; draft: { availability: DocumentAvailability; snapshot: T | undefined; }; published: { availability: DocumentAvailability; snapshot: T | undefined; }; version?: { availability: DocumentAvailability; snapshot: T | undefined; }; } /** * Event emitted to notify preview subscribers when they need to refetch a document being previewed * - 'connected' will happen when the store is connected to the invalidation channel, both initially and after a reconnect after a connection loss * - 'mutation' will happen when a document has been mutated and the store needs to refetch a document * @hidden * @beta */ type InvalidationChannelEvent = { type: 'connected'; } | { type: 'mutation'; documentId: string; visibility: string; }; /** * @hidden * @beta */ interface PreparedSnapshot { type?: PreviewableType; snapshot: PreviewValue | null | undefined; } /** @internal */ type ObserveDocumentTypeFromIdFn = (id: string, apiConfig?: ApiConfig, perspective?: StackablePerspective[]) => Observable<string | undefined>; /** * @hidden * @beta */ interface ObservePathsFn { (value: Previewable, paths: (string | PreviewPath)[], apiConfig?: ApiConfig, perspective?: StackablePerspective[]): Observable<PreviewValue | SanityDocumentLike | Reference | string | null>; } /** * @hidden * @beta */ interface ObserveDocumentAvailabilityFn { (id: string, options?: { version?: string; }): Observable<{ draft: DocumentAvailability; published: DocumentAvailability; version?: DocumentAvailability; }>; } /** * @hidden * @beta */ type ObserveForPreviewFn = (value: Previewable, type: PreviewableType, options?: { viewOptions?: PrepareViewOptions; perspective?: StackablePerspective[]; apiConfig?: ApiConfig; }) => Observable<PreparedSnapshot>; /** * The document preview store supports subscribing to content for previewing purposes. * Documents observed by this store will be kept in sync and receive real-time updates from all collaborators, * but has no support for optimistic updates, so any local edits will require a server round-trip before becoming visible, * which means this store is less suitable for real-time editing scenarios. * * @hidden * @beta */ interface DocumentPreviewStore { observePaths: ObservePathsFn; observeForPreview: ObserveForPreviewFn; observeDocumentTypeFromId: (id: string, apiConfig?: ApiConfig, perspective?: StackablePerspective[]) => Observable<string | undefined>; /** * * @hidden * @beta */ unstable_observeDocumentPairAvailability: (id: string, options?: { version?: string; }) => Observable<DraftsModelDocumentAvailability>; /** * * @hidden * @beta */ unstable_observeDocumentStackAvailability: (id: string, perspectiveStack: StackablePerspective[]) => Observable<DocumentStackAvailability[]>; unstable_observePathsDocumentPair: <T extends SanityDocument = SanityDocument>(id: string, paths: PreviewPath[], options?: { version?: string; }) => Observable<DraftsModelDocument<T>>; /** * Observes a set of document IDs that matches the given groq-filter. The document ids are returned in ascending order and will update in real-time * Whenever a document appears or disappears from the set, a new array with the updated set of IDs will be pushed to subscribers. * The query is performed once, initially, and thereafter the set of ids are patched based on the `appear` and `disappear` * transitions on the received listener events. * This provides a lightweight way of subscribing to a list of ids for simple cases where you just want to subscribe to a set of documents ids * that matches a particular filter. * @hidden * @beta * @param filter - A groq filter to use for the document set * @param params - Parameters to use with the groq filter * @param options - Options for the observer * @param apiVersion - Specify the API version to use for the query */ unstable_observeDocumentIdSet: (filter: string, params?: QueryParams, options?: { /** * Where to insert new items into the set. Defaults to 'sorted' which is based on the lexicographic order of the id */ insert?: 'sorted' | 'prepend' | 'append'; apiVersion?: string; }) => Observable<DocumentIdSetObserverState>; /** * Observe a complete document with the given ID * @hidden * @beta */ unstable_observeDocument: (id: string, clientConfig?: ObserveDocumentAPIConfig) => Observable<SanityDocument | undefined>; /** * Observe a list of complete documents with the given IDs * @hidden * @beta */ unstable_observeDocuments: (ids: string[], clientConfig?: ObserveDocumentAPIConfig) => Observable<(SanityDocument | undefined)[]>; } /** @internal */ interface DocumentPreviewStoreOptions { client: SanityClient; } /** @internal */ declare function createDocumentPreviewStore({ client }: DocumentPreviewStoreOptions): DocumentPreviewStore; interface DocumentPerspectiveProps { documentId: string; } interface DocumentPerspectiveState { data: string[]; error?: unknown; loading: boolean; } /** * Fetches the document versions for a given document * @param props - document Id of the document (might include release id) * @returns - data: document versions, loading, errors * @hidden * @beta */ declare function useDocumentVersions(props: DocumentPerspectiveProps): DocumentPerspectiveState; interface useDocumentVersionTypeSortedListState { sortedDocumentList: ReleaseDocument[]; } /** * Fetches the document versions for a given document and sorts them by release type * * @param documentId - document id related to the document version list * @returns object with sortedDocumentList * * @beta */ declare const useDocumentVersionTypeSortedList: ({ documentId }: { documentId: string; }) => useDocumentVersionTypeSortedListState; /** * Returns a function that formats a release's publish date in the studio's * selected content-releases timezone (e.g. "today at 10:20 AM"). The returned * function is safe to call inside conditional JSX. * * @internal */ declare function useFormatRelativeLocalePublishDate(): (release: ReleaseDocument) => string; /** @internal */ declare const useIsReleaseActive: () => boolean; /** * Returns a boolean if the document has only versions * * @param documentId - document id related to the document version list * @returns if the document has only versions * * @beta */ declare const useOnlyHasVersions: ({ documentId }: { documentId: string; }) => boolean; interface VersionOperationsValue { createVersion: (releaseId: ReleaseId, documentId: string) => Promise<void>; discardVersion: (releaseId: string, documentId: string) => Promise<SingleActionResult>; unpublishVersion: (documentId: string) => Promise<SingleActionResult>; revertUnpublishVersion: (documentId: string) => Promise<SingleActionResult>; } /** @internal */ declare function useVersionOperations(): VersionOperationsValue; /** * Sorts releases by their release type and created date. * @internal */ declare function sortReleases(releases?: ReleaseDocument[]): ReleaseDocument[]; /** * This is used to draw the bar that wraps the diff components in the changes panel * * @internal */ declare const ChangeFieldWrapper: (props: { path: Path; children: ReactNode; hasRevertHover: boolean; }) => _$react.JSX.Element; /** @internal */ interface ChangeIndicatorProps { path: Path; hasFocus: boolean; isChanged: boolean; withHoverEffect?: boolean; } /** @internal */ declare function ChangeIndicator(props: ChangeIndicatorProps & Omit<HTMLProps<HTMLDivElement>, 'as'>): _$react.JSX.Element; /** @internal */ interface ConnectorContextValue { isReviewChangesOpen: boolean; onOpenReviewChanges: () => void | undefined; onSetFocus: (nextPath: Path) => void | undefined; isInteractive?: boolean; } /** @internal */ interface ChangeConnectorRootProps { children: ReactNode; className?: string; isReviewChangesOpen: boolean; onOpenReviewChanges: () => void; onSetFocus: (path: Path) => void; } /** @internal */ declare function ChangeConnectorRoot({ children, className, isReviewChangesOpen, onOpenReviewChanges, onSetFocus, ...restProps }: ChangeConnectorRootProps): _$react.JSX.Element; /** @internal */ type Reported<Value> = [string, Value]; /** @internal */ type ReporterHook<Payload> = (id: string | null, value: () => Payload, isEqual?: IsEqualFunction<Payload>) => void; /** @internal */ type IsEqualFunction<Value> = (a: Value | null, b: Value | null) => boolean; /** @internal */ interface TrackerContextStore<Value> { add: (id: string, value: Value) => void; update: (id: string, value: Value) => void; remove: (id: string) => void; } /** @internal */ type TrackerContextGetSnapshot<Value> = [string, Value][]; /** @internal */ declare function useTrackerStore<Value>(): { store: TrackerContextStore<Value>; snapshot: TrackerContextGetSnapshot<Value>; }; /** @internal */ declare function useTrackerStoreReporter<Value>(store: TrackerContextStore<Value> | null, id: string | null, value: () => Value, isEqual?: IsEqualFunction<Value>): void; /** @internal */ interface TrackedChange { element: HTMLElement | null; path: Path; isChanged: boolean; hasFocus: boolean; hasHover: boolean; hasRevertHover: boolean; zIndex: number; } /** @internal */ interface TrackedArea { element: HTMLElement | null; } /** @internal */ type ChangeIndicatorTrackerContextValue = TrackedChange; declare function ChangeIndicatorsTrackerComponent(props: { children: React.ReactNode; }): _$react.JSX.Element; /** * @internal */ declare const ChangeIndicatorsTracker: _$react.MemoExoticComponent<typeof ChangeIndicatorsTrackerComponent>; /** * @internal */ declare function useChangeIndicatorsReportedValues(): TrackerContextGetSnapshot<ChangeIndicatorTrackerContextValue>; /** * @internal */ declare const useChangeIndicatorsReporter: ReporterHook<ChangeIndicatorTrackerContextValue>; /** * @beta * @hidden */ interface CommentDeleteDialogProps { commentId: string; error: Error | null; isParent: boolean; loading: boolean; onClose: () => void; onConfirm: (id: string) => void; } /** * @beta * @hidden */ declare function CommentDeleteDialog(props: CommentDeleteDialogProps): _$react.JSX.Element; /** * @internal */ declare const CommentDisabledIcon: _$react.ForwardRefExoticComponent<Omit<SVGProps<SVGSVGElement>, "ref"> & _$react.RefAttributes<SVGSVGElement>>; /** * * @deprecated Calling `useClient()` without specifying an API version is deprecated - specify a date to prevent breaking changes, e.g. `useClient({apiVersion: "2025-02-07"})`. * * React hook that returns a configured Sanity client instance based on the given configuration. * Automatically uses the correct project and dataset based on the current active workspace. * * @public * @returns A configured Sanity client instance * @remarks The client instance is automatically memoized based on API version * @remarks The client will fallback to `v2025-02-07` of the API * @example Instantiating a client * ```ts * function MyComponent() { * const client = useClient({apiVersion: '2021-06-07'}) * // ... do something with client instance ... * } * ``` */ declare function useClient(): SanityClient; /** * React hook that returns a configured Sanity client instance based on the given configuration. * Automatically uses the correct project and dataset based on the current active workspace. * * @public * @param clientOptions - Options for the client. Specifying * {@link https://www.sanity.io/docs/api-versioning | apiVersion} is required in order to * prevent breaking changes if studio changes the API version used in other places. * See {@link SourceClientOptions} * @returns A configured Sanity client instance * @remarks The client instance is automatically memoized based on API version * @example Instantiating a client * ```ts * function MyComponent() { * const client = useClient({apiVersion: '2021-06-07'}) * // ... do something with client instance ... * } * ``` */ declare function useClient(clientOptions: SourceClientOptions): SanityClient; /** * Workaround to support conditional toast (e.g. a toast that is visible as long as a condition holds true) * @hidden * @internal */ declare function useConditionalToast(params: ToastParams & { id: string; enabled?: boolean; delay?: number; }): void; /** @internal */ type ConnectionState = 'connecting' | 'reconnecting' | 'connected'; /** @internal */ declare function useConnectionState(publishedDocId: string, docTypeName: string, version?: string): ConnectionState; /** * React hook