Skip to content

Commit

Permalink
refactor(portable-text-editor): update types and add render callbacks…
Browse files Browse the repository at this point in the history
… to the PTE

This will make the PTE use the updated types for PT-conentent and for the block schema itself.
This will also add two new render callbacks 'renderListItem' and 'renderStyle' to complete them.
  • Loading branch information
skogsmaskin committed Dec 20, 2022
1 parent edb3bd0 commit 6202a8c
Show file tree
Hide file tree
Showing 43 changed files with 824 additions and 932 deletions.
Expand Up @@ -3,7 +3,6 @@ import {Element as SlateElement, Transforms, Path, Editor} from 'slate'
import {ReactEditor, useSlateStatic} from '@sanity/slate-react'
import {debugWithName} from '../utils/debug'
import {
IS_DRAGGING_CHILD_ELEMENT,
IS_DRAGGING_ELEMENT_TARGET,
IS_DRAGGING_BLOCK_ELEMENT,
IS_DRAGGING,
Expand All @@ -13,14 +12,14 @@ import {
const debug = debugWithName('components:DraggableBlock')
const debugRenders = false

type ElementProps = {
export interface DraggableBlockProps {
children: React.ReactNode
element: SlateElement
readOnly: boolean
blockRef: React.MutableRefObject<HTMLDivElement | null>
}

export const DraggableBlock = ({children, element, readOnly, blockRef}: ElementProps) => {
export const DraggableBlock = ({children, element, readOnly, blockRef}: DraggableBlockProps) => {
const editor = useSlateStatic()
const dragGhostRef: React.MutableRefObject<undefined | HTMLElement> = useRef()
const [isDragOver, setIsDragOver] = useState(false)
Expand Down
@@ -1,5 +1,5 @@
import React, {ReactElement, useRef, useMemo, useCallback} from 'react'
import {Element as SlateElement, Transforms, Editor} from 'slate'
import {Element as SlateElement, Transforms, Editor, Text} from 'slate'
import {ReactEditor, useSlateStatic} from '@sanity/slate-react'
import {debugWithName} from '../utils/debug'
import {IS_DRAGGING, IS_DRAGGING_ELEMENT_RANGE, IS_DRAGGING_CHILD_ELEMENT} from '../utils/weakMaps'
Expand All @@ -12,13 +12,13 @@ declare global {
}
}

type ElementProps = {
export interface DraggableChildProps {
children: ReactElement
element: SlateElement
element: Text | SlateElement
readOnly: boolean
}

export const DraggableChild = ({children, element, readOnly}: ElementProps) => {
export const DraggableChild = ({children, element, readOnly}: DraggableChildProps) => {
const editor = useSlateStatic()
const dragGhostRef: React.MutableRefObject<undefined | HTMLElement> = useRef()
const isVoid = useMemo(() => Editor.isVoid(editor, element), [editor, element])
Expand Down
65 changes: 37 additions & 28 deletions packages/@sanity/portable-text-editor/src/editor/Editable.tsx
@@ -1,6 +1,11 @@
import {BaseRange, Transforms} from 'slate'
import {BaseRange, Transforms, Text} from 'slate'
import React, {useCallback, useMemo, useEffect, forwardRef} from 'react'
import {Editable as SlateEditable, ReactEditor} from '@sanity/slate-react'
import {
Editable as SlateEditable,
ReactEditor,
RenderElementProps,
RenderLeafProps,
} from '@sanity/slate-react'
import {
EditorSelection,
OnBeforeInputFn,
Expand All @@ -11,6 +16,8 @@ import {
RenderBlockFunction,
RenderChildFunction,
RenderDecoratorFunction,
RenderListItemFunction,
RenderStyleFunction,
ScrollSelectionIntoViewFunction,
} from '../types/editor'
import {HotkeyOptions} from '../types/options'
Expand Down Expand Up @@ -63,7 +70,9 @@ export type PortableTextEditableProps = {
renderBlock?: RenderBlockFunction
renderChild?: RenderChildFunction
renderDecorator?: RenderDecoratorFunction
renderListItem?: RenderListItemFunction
renderPlaceholder?: () => React.ReactNode
renderStyle?: RenderStyleFunction
scrollSelectionIntoView?: ScrollSelectionIntoViewFunction
selection?: EditorSelection
spellCheck?: boolean
Expand All @@ -84,7 +93,9 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
renderBlock,
renderChild,
renderDecorator,
renderListItem,
renderPlaceholder,
renderStyle,
selection: propsSelection,
scrollSelectionIntoView,
spellCheck,
Expand All @@ -95,21 +106,18 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
const readOnly = usePortableTextEditorReadOnlyStatus()
const ref = useForwardedRef(forwardedRef)

const {
change$,
keyGenerator,
portableTextFeatures,
slateInstance: slateEditor,
} = portableTextEditor
const {change$, keyGenerator, types, slateInstance: slateEditor} = portableTextEditor

const blockTypeName = types.block.name

// React/UI-spesific plugins
const withInsertData = useMemo(
() => createWithInsertData(change$, portableTextFeatures, keyGenerator),
[change$, keyGenerator, portableTextFeatures]
() => createWithInsertData(change$, types, keyGenerator),
[change$, keyGenerator, types]
)
const withHotKeys = useMemo(
() => createWithHotkeys(portableTextFeatures, keyGenerator, portableTextEditor, hotkeys),
[hotkeys, keyGenerator, portableTextEditor, portableTextFeatures]
() => createWithHotkeys(types, keyGenerator, portableTextEditor, hotkeys),
[hotkeys, keyGenerator, portableTextEditor, types]
)

// Output a minimal React editor inside Editable when in readOnly mode.
Expand All @@ -125,21 +133,23 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
}, [readOnly, slateEditor, withHotKeys, withInsertData])

const renderElement = useCallback(
(eProps: any) => (
(eProps: RenderElementProps) => (
<Element
{...eProps}
portableTextFeatures={portableTextFeatures}
types={types}
readOnly={readOnly}
renderBlock={renderBlock}
renderChild={renderChild}
renderListItem={renderListItem}
renderStyle={renderStyle}
spellCheck={spellCheck}
/>
),
[portableTextFeatures, spellCheck, readOnly, renderBlock, renderChild]
[types, spellCheck, readOnly, renderBlock, renderChild, renderListItem, renderStyle]
)

const renderLeaf = useCallback(
(lProps: any) => {
(lProps: RenderLeafProps & {leaf: Text & {placeholder?: boolean}}) => {
if (renderPlaceholder && lProps.leaf.placeholder && lProps.text.text === '') {
return (
<>
Expand All @@ -149,7 +159,7 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
<Leaf
{...lProps}
keyGenerator={keyGenerator}
portableTextFeatures={portableTextFeatures}
types={types}
renderAnnotation={renderAnnotation}
renderChild={renderChild}
renderDecorator={renderDecorator}
Expand All @@ -162,7 +172,7 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
<Leaf
{...lProps}
keyGenerator={keyGenerator}
portableTextFeatures={portableTextFeatures}
types={types}
renderAnnotation={renderAnnotation}
renderChild={renderChild}
renderDecorator={renderDecorator}
Expand All @@ -171,13 +181,13 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
)
},
[
readOnly,
keyGenerator,
portableTextFeatures,
readOnly,
renderAnnotation,
renderChild,
renderDecorator,
renderPlaceholder,
types,
]
)

Expand All @@ -187,7 +197,7 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
debug(`Selection from props ${JSON.stringify(propsSelection)}`)
const normalizedSelection = normalizeSelection(
propsSelection,
fromSlateValue(slateEditor.children, portableTextFeatures.types.block.name)
fromSlateValue(slateEditor.children, blockTypeName)
)
if (normalizedSelection !== null) {
debug(`Normalized selection from props ${JSON.stringify(normalizedSelection)}`)
Expand All @@ -203,7 +213,7 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
}
}
}
}, [slateEditor, propsSelection, portableTextFeatures.types.block.name, change$])
}, [slateEditor, propsSelection, blockTypeName, change$])

// Set initial selection from props
useEffect(() => {
Expand Down Expand Up @@ -246,8 +256,7 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
event,
value: PortableTextEditor.getValue(portableTextEditor),
path: slateEditor.selection?.focus.path || [],
portableTextFeatures, // New key added in v.2.23.2
type: portableTextFeatures.types.portableText, // For legacy support
types,
})
)
})
Expand All @@ -260,7 +269,7 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
return
}
if (result && result.insert) {
slateEditor.insertFragment(toSlateValue(result.insert, {portableTextFeatures}))
slateEditor.insertFragment(toSlateValue(result.insert, {types}))
change$.next({type: 'loading', isLoading: false})
return
}
Expand All @@ -272,7 +281,7 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
return error
})
},
[change$, onPaste, portableTextEditor, portableTextFeatures, slateEditor]
[change$, onPaste, portableTextEditor, types, slateEditor]
)

const handleOnFocus = useCallback(() => {
Expand Down Expand Up @@ -310,7 +319,7 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
}, [portableTextEditor, scrollSelectionIntoView])

const decorate = useCallback(() => {
if (isEqualToEmptyEditor(slateEditor.children, portableTextFeatures)) {
if (isEqualToEmptyEditor(slateEditor.children, types)) {
return [
{
anchor: {
Expand All @@ -326,7 +335,7 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
]
}
return EMPTY_DECORATORS
}, [portableTextFeatures, slateEditor.children])
}, [types, slateEditor.children])

// The editor
const slateEditable = useMemo(
Expand Down

0 comments on commit 6202a8c

Please sign in to comment.