UNPKG

@sanity/visual-editing

Version:

[![npm stat](https://img.shields.io/npm/dm/@sanity/visual-editing.svg?style=flat-square)](https://npm-stat.com/charts.html?package=@sanity/visual-editing) [![npm version](https://img.shields.io/npm/v/@sanity/visual-editing.svg?style=flat-square)](https://

429 lines (393 loc) 10.5 kB
import type {StudioPathLike} from '@sanity/client/csm' import type {InsertMenuOptions} from '@sanity/insert-menu' import type {ArrayOptions} from '@sanity/types' import type { ComponentType, FunctionComponent, HTMLAttributes, PropsWithChildren, ReactElement, } from 'react' /** * @public */ export declare type CreateDataAttribute<T extends CreateDataAttributeProps> = (T extends WithRequired<CreateDataAttributeProps, 'id' | 'type' | 'path'> ? { /** * Returns a string representation of the data attribute * @param path - An optional path to concatenate with any existing path * @public */ (path?: StudioPathLike): string /** * Returns a string representation of the data attribute * @public */ toString(): string } : T extends WithRequired<CreateDataAttributeProps, 'id' | 'type'> ? (path: StudioPathLike) => string : object) & { /** * Concatenate the current path with a new path * @param path - A path to concatenate with any existing path * @public */ scope(path: StudioPathLike): CreateDataAttribute< T & { path: StudioPathLike } > /** * Combines the current props with additional props * @param props - New props to merge with any existing props * @public */ combine: <U extends CreateDataAttributeProps>(props: U) => CreateDataAttribute<T & U> } /** * A helper function for creating `data-sanity` attributes by explicitly providing metadata. * @returns An object with methods for incrementally adding and scoping metadata, and for generating a data attribute string. * @public */ export declare function createDataAttribute<T extends CreateDataAttributeProps>( props: T, ): CreateDataAttribute<T> /** * The metadata that can be embedded in a data attribute. * All values are marked optional in the base type as they can be provided incrementally using the `createDataAttribute` function. * @public */ export declare interface CreateDataAttributeProps { /** The studio base URL, optional */ baseUrl?: string /** The dataset, optional */ dataset?: string /** The document ID, required */ id?: string /** The field path, required */ path?: StudioPathLike /** The project ID, optional */ projectId?: string /** The studio tool name, optional */ tool?: string /** The document type, required */ type?: string /** The studio workspace, optional */ workspace?: string } export declare interface DocumentSchema { type: 'document' name: string title?: string icon?: string fields: Record<string, SchemaObjectField> } /** * An element that is safe to parse * @internal */ export declare type ElementNode = HTMLElement | SVGElement /** * * @public */ export declare interface HistoryAdapter { subscribe: (navigate: HistoryAdapterNavigate) => () => void update: (update: HistoryUpdate) => void } /** * * @public */ export declare type HistoryAdapterNavigate = (update: HistoryUpdate) => void /** * Preview frame history refresh event, emitted by Presentation Tool * @public */ export declare type HistoryRefresh = | { /** * source 'manual' means the refresh button were clicked by the user */ source: 'manual' /** * If true then there's either preview-kit or a loader connected on the page */ livePreviewEnabled: boolean } | { /** * source 'mutation' means a document were mutated and the preview might need to refresh */ source: 'mutation' /** * If true then there's either preview-kit or a loader connected on the page */ livePreviewEnabled: boolean /** * Select metadata about the document that were mutated * If it's prefixed with `drafts.` then it's a draft document, otherwise it's a published document. */ document: { /** * If it's prefixed with `drafts.` then it's a draft document, otherwise it's a published document. */ _id: string /** * The document type is frequently used in `revalidateTag` scenarios with Next.js App Router */ _type: string /** * The document revision, can be used to dedupe requests, as we always send two due to debouncing and handling Content Lake eventual consistency */ _rev: string /** * If the document has a top level slug field named `slug` with the type `slug`, then it'll be included here */ slug?: { current?: string | null } } } /** * Preview frame history update * @public */ export declare type HistoryUpdate = { type: 'push' | 'pop' | 'replace' title?: string url: string } /** * @public */ export declare type OverlayComponent< T extends Record<string, unknown> = Record<string, unknown>, P extends OverlayElementParent = OverlayElementParent, > = ComponentType<OverlayComponentProps<P | undefined> & T> /** * @public */ export declare interface OverlayComponentProps< P extends OverlayElementParent = OverlayElementParent, > extends OverlayComponentResolverContext<P> { PointerEvents: FunctionComponent<PropsWithChildren<HTMLAttributes<HTMLDivElement>>> } /** * @public */ export declare type OverlayComponentResolver< T extends OverlayComponent = OverlayComponent<Record<string, unknown>, any>, > = (context: OverlayComponentResolverContext) => | T | { component: T props?: Record<string, unknown> } | Array< | T | { component: T props?: Record<string, unknown> } > | ReactElement | undefined | void /** * @public */ export declare interface OverlayComponentResolverContext< P extends OverlayElementParent = OverlayElementParent, > { /** * The resolved field's document schema type */ document: DocumentSchema /** * The element node that the overlay is attached to */ element: ElementNode /** * The resolved field schema type */ field: OverlayElementField /** * Whether the overlay is focused or not */ focused: boolean /** * The Sanity node data that triggered the overlay */ node: SanityNode /** * The resolved field's parent schema type */ parent: P /** * A convience property, equal to `field.value.type` */ type: string } export declare type OverlayElementField = | SchemaArrayItem | SchemaObjectField | SchemaUnionOption | undefined export declare type OverlayElementParent = | DocumentSchema | SchemaNode | SchemaArrayItem | SchemaUnionOption | SchemaUnionNode | undefined /** * Data resolved from a Sanity node * @public */ export declare type SanityNode = { baseUrl: string dataset?: string id: string isDraft?: string path: string projectId?: string tool?: string type?: string workspace?: string } export declare interface SchemaArrayItem<T extends SchemaNode = SchemaNode> { type: 'arrayItem' name: string title?: string value: T } export declare interface SchemaArrayNode<T extends SchemaNode = SchemaNode> { type: 'array' of: SchemaArrayItem<T> } export declare interface SchemaBooleanNode { type: 'boolean' value?: boolean } export declare interface SchemaInlineNode { type: 'inline' /** the name of the referenced type */ name: string } export declare type SchemaNode = | SchemaArrayNode | SchemaBooleanNode | SchemaInlineNode | SchemaNullNode | SchemaNumberNode | SchemaObjectNode | SchemaStringNode | SchemaUnionNode | SchemaUnknownNode export declare interface SchemaNullNode { type: 'null' } export declare interface SchemaNumberNode { type: 'number' value?: number } export declare interface SchemaObjectField<T extends SchemaNode = SchemaNode> { type: 'objectField' name: string title?: string value: T optional?: boolean } export declare interface SchemaObjectNode<T extends SchemaNode = SchemaNode> { type: 'object' fields: Record<string, SchemaObjectField<T>> rest?: SchemaObjectNode | SchemaUnknownNode | SchemaInlineNode dereferencesTo?: string } export declare interface SchemaStringNode { type: 'string' value?: string } export declare interface SchemaUnionNode<T extends SchemaNode = SchemaNode> { type: 'union' of: SchemaUnionOption<T>[] | SchemaStringNode[] | SchemaNumberNode[] options?: SchemaUnionNodeOptions } export declare type SchemaUnionNodeOptions = Omit<ArrayOptions, 'insertMenu'> & { insertMenu?: Omit<InsertMenuOptions, 'views'> & { views?: Array< | { name: 'list' } | { name: 'grid' previewImageUrls?: Record<string, string | undefined> } > } } export declare interface SchemaUnionOption<T extends SchemaNode = SchemaNode> { type: 'unionOption' name: string title?: string icon?: string value: T } export declare interface SchemaUnknownNode { type: 'unknown' } /** * @public */ export declare function VisualEditing(props: VisualEditingProps): React.ReactElement | null /** * @public */ export declare interface VisualEditingOptions { /** * @alpha * This API is unstable and could change at any time. */ components?: OverlayComponentResolver /** * The history adapter is used for Sanity Presentation to navigate URLs in the preview frame. */ history?: HistoryAdapter /** * The refresh API allows smarter refresh logic than the default `location.reload()` behavior. */ refresh?: (payload: HistoryRefresh) => false | Promise<void> /** * The CSS z-index on the root node that renders overlays, tweak it accordingly to what layout you have. */ zIndex?: string | number } /** * @public */ export declare interface VisualEditingProps extends Omit<VisualEditingOptions, 'history' | 'refresh'> { /** * @deprecated The history adapter is already implemented */ history?: never /** * The refresh API allows smarter refresh logic than the default `location.reload()` behavior. * You can call the refreshDefault argument to trigger the default refresh behavior so you don't have to reimplement it. */ refresh?: ( payload: HistoryRefresh, refreshDefault: () => false | Promise<void>, ) => false | Promise<void> } /** * Helper * @internal */ export declare type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] } export {}