/
BlockActions.tsx
53 lines (46 loc) · 1.97 KB
/
BlockActions.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import {PortableTextEditor, usePortableTextEditor} from '@sanity/portable-text-editor'
import React, {useCallback, useMemo} from 'react'
import styled from 'styled-components'
import {PortableTextBlock} from '@sanity/types'
import {PatchArg} from '../../patch'
import {RenderBlockActionsCallback, RenderBlockActionsProps} from './types'
import {createInsertCallback, createSetCallback, createUnsetCallback} from './callbacks'
interface BlockActionsProps {
block: PortableTextBlock
onChange: (...patches: PatchArg[]) => void
renderBlockActions?: RenderBlockActionsCallback
}
const Root = styled.div`
display: flex;
pointer-events: 'all';
`
export function BlockActions(props: BlockActionsProps) {
const editor = usePortableTextEditor()
const {block, onChange, renderBlockActions} = props
const decoratorValues = useMemo(() => editor.types.decorators.map((d) => d.value), [editor])
const blockActions = useMemo(() => {
if (renderBlockActions) {
const blockActionProps: RenderBlockActionsProps = {
block,
value: PortableTextEditor.getValue(editor),
set: createSetCallback({allowedDecorators: decoratorValues, block, onChange}),
unset: createUnsetCallback({block, onChange}),
insert: createInsertCallback({allowedDecorators: decoratorValues, block, onChange}),
}
return renderBlockActions(blockActionProps)
}
return undefined
}, [renderBlockActions, block, editor, onChange, decoratorValues])
// Take focus away from the editor so dealing with block actions doesn't interfere with the editor focus
const handleClick = useCallback(() => {
PortableTextEditor.blur(editor)
}, [editor])
// Don't render anything if the renderBlockActions function returns null.
// Note that if renderBlockComponent is a React class, this will never be the case.
if (!blockActions) return null
return (
<Root contentEditable={false} onKeyDown={handleClick} onMouseDown={handleClick}>
{blockActions}
</Root>
)
}