UNPKG

@portabletext/editor

Version:

Portable Text Editor made in React

92 lines (86 loc) 2.74 kB
import {useSelector} from '@xstate/react' import type {Editor} from '../editor' import type {PortableTextSlateEditor} from '../types/editor' import type {InternalEditor} from './create-editor' import type {EditorActor} from './editor-machine' import type {EditorSnapshot} from './editor-snapshot' import {getActiveAnnotations} from './get-active-annotations' import {getActiveDecorators} from './get-active-decorators' function defaultCompare<T>(a: T, b: T) { return a === b } /** * @public */ export type EditorSelector<TSelected> = (snapshot: EditorSnapshot) => TSelected /** * @public * Hook to select a value from the editor state. * @example * Pass a selector as the second argument * ```tsx * import { useEditorSelector } from '@portabletext/editor' * * function MyComponent(editor) { * const value = useEditorSelector(editor, selector) * } * ``` * @example * Pass an inline selector as the second argument. * In this case, use the editor context to obtain the schema. * ```tsx * import { useEditorSelector } from '@portabletext/editor' * * function MyComponent(editor) { * const schema = useEditorSelector(editor, (snapshot) => snapshot.context.schema) * } * ``` * @group Hooks */ export function useEditorSelector<TSelected>( editor: Editor, selector: EditorSelector<TSelected>, compare: (a: TSelected, b: TSelected) => boolean = defaultCompare, ) { return useSelector( (editor as InternalEditor)._internal.editorActor, (editorActorSnapshot) => { const snapshot = getEditorSnapshot({ editorActorSnapshot, slateEditorInstance: (editor as InternalEditor)._internal.slateEditor .instance, }) return selector(snapshot) }, compare, ) } export function getEditorSnapshot({ editorActorSnapshot, slateEditorInstance, }: { editorActorSnapshot: ReturnType<EditorActor['getSnapshot']> slateEditorInstance: PortableTextSlateEditor }): EditorSnapshot { return { context: { converters: [...editorActorSnapshot.context.converters], keyGenerator: editorActorSnapshot.context.keyGenerator, readOnly: editorActorSnapshot.matches({'edit mode': 'read only'}), schema: editorActorSnapshot.context.schema, selection: editorActorSnapshot.context.selection, value: slateEditorInstance.value, }, beta: { activeAnnotations: getActiveAnnotations({ markState: slateEditorInstance.markState, schema: editorActorSnapshot.context.schema, }), activeDecorators: getActiveDecorators({ decoratorState: slateEditorInstance.decoratorState, markState: slateEditorInstance.markState, schema: editorActorSnapshot.context.schema, }), }, } }