@sanity/visual-editing
Version:
[](https://npm-stat.com/charts.html?package=@sanity/visual-editing) [](https://
64 lines (57 loc) • 2.23 kB
text/typescript
import type {ClientPerspective, ContentSourceMapDocuments} from '@sanity/client'
import {useCallback, useEffect, useRef} from 'react'
import type {ElementState, VisualEditingNode} from '../types'
import {orderSanityNodesByPosition} from './orderSanityNodesByPosition'
/**
* Hook for reporting in use documents to Presentation
* @internal
*/
export function useReportDocuments(
comlink: VisualEditingNode | undefined,
elements: ElementState[],
perspective: ClientPerspective,
): void {
const lastReported = useRef<
| {
orderedIds: string[]
perspective: ClientPerspective
}
| undefined
>(undefined)
const reportDocuments = useCallback(
(documents: ContentSourceMapDocuments, perspective: ClientPerspective) => {
comlink?.post('visual-editing/documents', {
documents,
perspective,
})
},
[comlink],
)
useEffect(() => {
// Report only nodes of type `SanityNode`. Untransformed `SanityStegaNode`
// nodes without an `id`, are not reported as they will not contain the
// necessary document data. Nodes are sorted by visual position so the
// reported order reflects appearance on the page.
const orderedNodes = orderSanityNodesByPosition(elements)
const orderedIds = orderedNodes.map((node) => node.id)
// Report if:
// - Documents not yet reported
// - Document IDs changed or their visual order changed
// - Perspective changed
const lastOrderedIds = lastReported.current?.orderedIds
const orderChanged =
!lastOrderedIds ||
lastOrderedIds.length !== orderedIds.length ||
orderedIds.some((id, index) => id !== lastOrderedIds[index])
if (orderChanged || perspective !== lastReported.current?.perspective) {
const documentsOnPage: ContentSourceMapDocuments = orderedNodes.map((node) => {
const {id: _id, type, projectId: _projectId, dataset: _dataset} = node
return _projectId && _dataset
? {_id, _type: type!, _projectId, _dataset}
: {_id, _type: type!}
})
lastReported.current = {orderedIds, perspective}
reportDocuments(documentsOnPage, perspective)
}
}, [elements, perspective, reportDocuments])
}