@sanity/visual-editing
Version:
[](https://npm-stat.com/charts.html?package=@sanity/visual-editing) [](https://
753 lines (649 loc) • 18.1 kB
text/typescript
import {SanityClient} from '@sanity/client'
import type {SanityDocument} from '@sanity/client'
import {Mutation, NodePatchList} from '@sanity/mutate'
import {createSharedListener, DocumentMutatorMachineInput} from '@sanity/mutate/_unstable_machine'
import {
DocumentSchema,
HistoryRefresh,
HistoryUpdate,
SanityNode,
SanityStegaNode,
SchemaArrayItem,
SchemaArrayNode,
SchemaBooleanNode,
SchemaInlineNode,
SchemaNode,
SchemaNullNode,
SchemaNumberNode,
SchemaObjectField,
SchemaObjectNode,
SchemaStringNode,
SchemaUnionNode,
SchemaUnionNodeOptions,
SchemaUnionOption,
SchemaUnknownNode,
} from '@sanity/presentation-comlink'
import type {SanityDocument as SanityDocument_2} from '@sanity/types'
import {
CreateDataAttribute,
createDataAttribute,
CreateDataAttributeProps,
WithRequired,
} from '@sanity/visual-editing-csm'
import type {
ComponentType,
FunctionComponent,
HTMLAttributes,
PropsWithChildren,
ReactElement,
} from 'react'
export {CreateDataAttribute}
export {createDataAttribute}
export {CreateDataAttributeProps}
/**
* Creates a controller which dispatches overlay related events
*
* @param handler - Dispatched event handler
* @param overlayElement - Parent element containing rendered overlay elements
* @public
*/
export declare function createOverlayController({
handler,
overlayElement,
inFrame,
inPopUp,
optimisticActorReady,
}: OverlayOptions): OverlayController
/**
* @public
* @deprecated Use `import type {DatasetMutatorMachineInput} from '@sanity/visual-editing/optimistic'` instead
*/
export declare type DatasetMutatorMachineInput = DatasetMutatorMachineInputDeprecated
export declare interface DatasetMutatorMachineInputDeprecated
extends Omit<DocumentMutatorMachineInput, 'id'> {
client: SanityClient
/** A shared listener can be provided, if not it'll be created using `client.listen()` */
sharedListener?: ReturnType<typeof createSharedListener>
}
/**
* Cleanup function used when e.g. unmounting
* @public
*/
export declare type DisableVisualEditing = () => void
export {DocumentSchema}
/**
* @public
* @deprecated Use `import type {DocumentsGet} from '@sanity/visual-editing/optimistic'` instead
*/
export declare type DocumentsGet = DocumentsGetDeprecated
export declare type DocumentsGetDeprecated = <T extends Record<string, any>>(
documentId: string,
) => OptimisticDocumentDeprecated<T>
/**
* @public
* @deprecated Use `import type {DocumentsMutate} from '@sanity/visual-editing/optimistic'` instead
*/
export declare type DocumentsMutate = DocumentsMutateDeprecated
export declare type DocumentsMutateDeprecated = (
documentId: string,
mutations: Mutation[],
options?: {
commit?:
| boolean
| {
debounce: number
}
},
) => void
/** @public */
export declare interface DragEndEvent {
insertPosition: DragInsertPosition
target: SanityNode
dragGroup: string | null
flow: string
preventInsertDefault: boolean
}
/** @public */
export declare type DragInsertPosition = {
top?: {
rect: OverlayRect
sanity: SanityNode
} | null
left?: {
rect: OverlayRect
sanity: SanityNode
} | null
bottom?: {
rect: OverlayRect
sanity: SanityNode
} | null
right?: {
rect: OverlayRect
sanity: SanityNode
} | null
} | null
/** @public */
export declare type DragSkeleton = {
w: number
h: number
offsetX: number
offsetY: number
childRects: {
x: number
y: number
w: number
h: number
tagName: string
}[]
maxWidth: number
}
/**
* @public
*/
export declare interface ElementChildTarget {
sanity: SanityNode | SanityStegaNode
element: ElementNode
}
/**
* Element focus state
* @public
*/
export declare type ElementFocusedState = 'clicked' | 'duplicate' | boolean
/**
* An element that is safe to parse
* @internal
*/
export declare type ElementNode = HTMLElement | SVGElement
/**
* Element state for consuming applications
* @public
*/
export declare interface ElementState {
id: string
activated: boolean
element: ElementNode
focused: ElementFocusedState
hovered: boolean
rect: OverlayRect
sanity: SanityNode | SanityStegaNode
dragDisabled: boolean
targets: ElementChildTarget[]
elementType: 'element' | 'group'
}
/**
* Enables Visual Editing overlay in a page with sourcemap encoding.
*
* This will overlay UI on hovered elements that deep-links to Sanity Studio.
* @public
*/
export declare function enableVisualEditing(options?: VisualEditingOptions): DisableVisualEditing
export declare function getArrayItemKeyAndParentPath(pathOrNode: string | SanityNode): {
path: string
key: string
hasExplicitKey: boolean
}
/**
*
* @public
*/
export declare interface HistoryAdapter {
subscribe: (navigate: HistoryAdapterNavigate) => () => void
update: (update: HistoryUpdate) => void
}
/**
*
* @public
*/
export declare type HistoryAdapterNavigate = (update: HistoryUpdate) => void
export {HistoryRefresh}
export {HistoryUpdate}
/**
* Base controller dispatched message
* @typeParam T - Type of message
* @public
*/
export declare interface Msg<T extends string> {
type: T
}
/**
* @public
* @deprecated Use `import type {OptimisticDocument} from '@sanity/visual-editing/optimistic'` instead
*/
export declare type OptimisticDocument = OptimisticDocumentDeprecated
export declare type OptimisticDocumentDeprecated<
T extends Record<string, any> = Record<string, any>,
> = {
/**
* The document ID
*/
id: string
/**
* Commits any locally applied mutations to the remote document
*/
commit: () => void
/**
* @deprecated - use `getSnapshot` instead
*/
get: {
(): SanityDocument<T> | undefined
<P extends PathDeprecated<T, keyof T>>(path: P): PathValueDeprecated<T, P> | undefined
}
/**
* Returns a promise that resolves to the current document snapshot
*/
getSnapshot: () => Promise<SanityDocument<T> | null>
/**
* Applies the given patches to the document
*/
patch: (
patches: OptimisticDocumentPatchesDeprecated<T>,
options?: {
commit?:
| boolean
| {
debounce: number
}
},
) => void
}
/**
* @public
* @deprecated Use `import type {OptimisticDocumentPatches} from '@sanity/visual-editing/optimistic'` instead
*/
export declare type OptimisticDocumentPatches = OptimisticDocumentPatchesDeprecated
export declare type OptimisticDocumentPatchesDeprecated<
T extends Record<string, any> = Record<string, any>,
> =
| ((context: {
draftId: string
publishedId: string
/**
* @deprecated - use `getSnapshot` instead
*/
snapshot: SanityDocument<T> | undefined
getSnapshot: () => Promise<SanityDocument<T> | null>
}) => Promise<NodePatchList> | NodePatchList)
| NodePatchList
/**
* @public
* @deprecated Use `import type {OptimisticReducer} from '@sanity/visual-editing/optimistic'` instead
*/
export declare type OptimisticReducer<T, U> = OptimisticReducerDeprecated<T, U>
/**
* @public
* @deprecated Use `import type {OptimisticReducerAction} from '@sanity/visual-editing/optimistic'` instead
*/
export declare type OptimisticReducerAction<T> = OptimisticReducerActionDeprecated<T>
export declare type OptimisticReducerActionDeprecated<T> = {
document: T
id: string
originalId: string
type: 'appear' | 'mutate' | 'disappear'
}
export declare type OptimisticReducerDeprecated<T, U> = (
state: T,
action: OptimisticReducerActionDeprecated<U>,
) => T
/**
* @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 element node that the Sanity node data is detected on
*/
targetElement: 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
}
/**
* Object returned by a controller instantiation
* @public
*/
export declare interface OverlayController {
activate: () => void
deactivate: () => void
destroy: () => void
}
export declare type OverlayElementField =
| SchemaArrayItem
| SchemaObjectField
| SchemaUnionOption
| undefined
export declare type OverlayElementParent =
| DocumentSchema
| SchemaNode
| SchemaArrayItem
| SchemaUnionOption
| SchemaUnionNode
| undefined
/**
* Callback function used for handling dispatched controller messages
* @public
*/
export declare type OverlayEventHandler = (message: OverlayMsg) => void
/**
* Controller dispatched messages
* @public
*/
export declare type OverlayMsg =
| OverlayMsgActivate
| OverlayMsgBlur
| OverlayMsgDeactivate
| OverlayMsgDragEnd
| OverlayMsgDragEndMinimapTransition
| OverlayMsgDragStart
| OverlayMsgDragStartMinimapTransition
| OverlayMsgDragToggleMinimap
| OverlayMsgDragToggleMinimapPrompt
| OverlayMsgDragUpdateCursorPosition
| OverlayMsgDragUpdateGroupRect
| OverlayMsgDragUpdateInsertPosition
| OverlayMsgDragUpdateSkeleton
| OverlayMsgElementActivate
| OverlayMsgElementClick
| OverlayMsgElementContextMenu
| OverlayMsgElementDeactivate
| OverlayMsgElementMouseEnter
| OverlayMsgElementMouseLeave
| OverlayMsgElementRegister
| OverlayMsgElementUnregister
| OverlayMsgElementUpdate
| OverlayMsgElementUpdateRect
| OverlayMsgSetCursor
| OverlayMsgResetMouseState
/** @public */
export declare type OverlayMsgActivate = Msg<'overlay/activate'>
/** @public */
export declare type OverlayMsgBlur = Msg<'overlay/blur'>
/** @public */
export declare type OverlayMsgDeactivate = Msg<'overlay/deactivate'>
/** @public */
export declare type OverlayMsgDragEnd = Msg<'overlay/dragEnd'> & DragEndEvent
/** @public */
export declare type OverlayMsgDragEndMinimapTransition = Msg<'overlay/dragEndMinimapTransition'>
/** @public */
export declare type OverlayMsgDragStart = Msg<'overlay/dragStart'> & {
flow: 'horizontal' | 'vertical'
}
/** @public */
export declare type OverlayMsgDragStartMinimapTransition = Msg<'overlay/dragStartMinimapTransition'>
/** @public */
export declare type OverlayMsgDragToggleMinimap = Msg<'overlay/dragToggleMinimap'> & {
display: boolean
}
/** @public */
export declare type OverlayMsgDragToggleMinimapPrompt = Msg<'overlay/dragToggleMinimapPrompt'> & {
display: boolean
}
/** @public */
export declare type OverlayMsgDragUpdateCursorPosition = Msg<'overlay/dragUpdateCursorPosition'> & {
x: number
y: number
}
/** @public */
export declare type OverlayMsgDragUpdateGroupRect = Msg<'overlay/dragUpdateGroupRect'> & {
groupRect: OverlayRect | null
}
/** @public */
export declare type OverlayMsgDragUpdateInsertPosition = Msg<'overlay/dragUpdateInsertPosition'> & {
insertPosition: DragInsertPosition | null
}
/** @public */
export declare type OverlayMsgDragUpdateSkeleton = Msg<'overlay/dragUpdateSkeleton'> & {
skeleton: DragSkeleton
}
/** @public */
export declare interface OverlayMsgElement<T extends string> extends Msg<`element/${T}`> {
id: string
}
/** @public */
export declare type OverlayMsgElementActivate = OverlayMsgElement<'activate'>
/** @public */
export declare type OverlayMsgElementClick = OverlayMsgElement<'click'> & {
sanity: SanityNode | SanityStegaNode
}
/** @public */
export declare type OverlayMsgElementContextMenu =
| OverlayMsgElement<'contextmenu'>
| (OverlayMsgElement<'contextmenu'> & {
position: {
x: number
y: number
}
sanity: SanityNode
})
/** @public */
export declare type OverlayMsgElementDeactivate = OverlayMsgElement<'deactivate'>
/** @public */
export declare type OverlayMsgElementMouseEnter = OverlayMsgElement<'mouseenter'> & {
rect: OverlayRect
}
/** @public */
export declare type OverlayMsgElementMouseLeave = OverlayMsgElement<'mouseleave'>
/** @public */
export declare type OverlayMsgElementRegister = OverlayMsgElement<'register'> & {
element: ElementNode
sanity: SanityNode | SanityStegaNode
rect: OverlayRect
dragDisabled: boolean
targets: ElementChildTarget[]
elementType: 'element' | 'group'
}
/** @public */
export declare type OverlayMsgElementUnregister = OverlayMsgElement<'unregister'>
/** @public */
export declare type OverlayMsgElementUpdate = OverlayMsgElement<'update'> & {
sanity: SanityNode | SanityStegaNode
rect: OverlayRect
targets: ElementChildTarget[]
elementType: 'element' | 'group'
}
/** @public */
export declare type OverlayMsgElementUpdateRect = OverlayMsgElement<'updateRect'> & {
rect: OverlayRect
}
/** @public */
export declare type OverlayMsgResetMouseState = Msg<'overlay/reset-mouse-state'>
/** @public */
export declare type OverlayMsgSetCursor = Msg<'overlay/setCursor'> & {
element: ElementNode
cursor: string | undefined
}
/**
* Options passed when instantiating an overlay controller
* @public
*/
export declare interface OverlayOptions {
handler: OverlayEventHandler
overlayElement: HTMLElement
inFrame: boolean
inPopUp: boolean
optimisticActorReady: boolean
}
/** @public */
export declare type OverlayPluginDefinition =
| OverlayPluginExclusiveDefinition
| OverlayPluginHudDefinition
/** @public */
export declare interface OverlayPluginDefinitionBase {
name: string
title?: string
icon?: ComponentType
guard?: (context: OverlayComponentResolverContext | undefined) => boolean
}
/** @public */
export declare interface OverlayPluginExclusiveDefinition extends OverlayPluginDefinitionBase {
type: 'exclusive'
component?: OverlayComponent<
Record<string, unknown> & {
closeExclusiveView: () => void
},
any
>
}
/** @public */
export declare interface OverlayPluginHudDefinition extends OverlayPluginDefinitionBase {
type: 'hud'
component?: OverlayComponent<Record<string, unknown>, any>
}
/**
* @public
*/
export declare interface OverlayRect {
x: number
y: number
w: number
h: number
}
/**
* @public
* @deprecated Use `import type {Path} from '@sanity/visual-editing/optimistic'` instead
*/
export declare type Path<T, K extends keyof T> = PathDeprecated<T, K>
export declare type PathDeprecated<T, K extends keyof T> = K extends string
? T[K] extends Record<string, any>
? `${K}.${PathDeprecated<T[K], keyof T[K]>}` | K
: K
: never
/**
* @public
* @deprecated Use `import type {PathValue} from '@sanity/visual-editing/optimistic'` instead
*/
export declare type PathValue<T, P extends string> = PathValueDeprecated<T, P>
export declare type PathValueDeprecated<T, P extends string> = P extends `${infer K}.${infer Rest}`
? K extends keyof T
? PathValueDeprecated<T[K], Rest>
: never
: P extends keyof T
? T[P]
: never
export {SanityNode}
export {SanityStegaNode}
export {SchemaArrayItem}
export {SchemaArrayNode}
export {SchemaBooleanNode}
export {SchemaInlineNode}
export {SchemaNode}
export {SchemaNullNode}
export {SchemaNumberNode}
export {SchemaObjectField}
export {SchemaObjectNode}
export {SchemaStringNode}
export {SchemaUnionNode}
export {SchemaUnionNodeOptions}
export {SchemaUnionOption}
export {SchemaUnknownNode}
/**
* @public
* @deprecated Use `import {useDocuments} from '@sanity/visual-editing/react'` instead
*/
export declare const useDocuments: typeof useDocumentsDeprecated
export declare function useDocumentsDeprecated(): {
getDocument: DocumentsGetDeprecated
mutateDocument: DocumentsMutateDeprecated
}
/**
* @public
* @deprecated Use `import {useOptimistic} from '@sanity/visual-editing/react'` instead
*/
export declare const useOptimistic: typeof useOptimisticDeprecated
export declare function useOptimisticDeprecated<T, U = SanityDocument_2>(
passthrough: T,
reducer: OptimisticReducerDeprecated<T, U> | Array<OptimisticReducerDeprecated<T, U>>,
): T
export declare function useSharedState<
T extends boolean | null | number | object | string | undefined | unknown = unknown,
>(key: string): T
/**
* @public
*/
export declare interface VisualEditingOptions {
/**
* @alpha
* This API is unstable and could change at any time.
*/
plugins?: OverlayPluginDefinition[]
/**
* @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
}
export {WithRequired}
export {}