mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-11 17:53:59 +02:00
Fix child element decorations (#4910)
* fix slate-react handling of nested element decorations * chore: add changeset * changes from review
This commit is contained in:
5
.changeset/poor-hats-design.md
Normal file
5
.changeset/poor-hats-design.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'slate-react': patch
|
||||
---
|
||||
|
||||
Fix decorations applied across nested elements
|
@@ -5,7 +5,6 @@ import ElementComponent from '../components/element'
|
||||
import TextComponent from '../components/text'
|
||||
import { ReactEditor } from '..'
|
||||
import { useSlateStatic } from './use-slate-static'
|
||||
import { useDecorate } from './use-decorate'
|
||||
import { NODE_TO_INDEX, NODE_TO_PARENT } from '../utils/weak-maps'
|
||||
import {
|
||||
RenderElementProps,
|
||||
@@ -34,7 +33,6 @@ const useChildren = (props: {
|
||||
renderLeaf,
|
||||
selection,
|
||||
} = props
|
||||
const decorate = useDecorate()
|
||||
const editor = useSlateStatic()
|
||||
const path = ReactEditor.findPath(editor, node)
|
||||
const children = []
|
||||
@@ -50,7 +48,11 @@ const useChildren = (props: {
|
||||
const range = Editor.range(editor, p)
|
||||
const sel = selection && Range.intersection(range, selection)
|
||||
|
||||
const ds = decorations.filter(dec => Range.intersection(dec, range))
|
||||
const ds = decorations.reduce<Range[]>((acc, dec) => {
|
||||
const intersection = Range.intersection(dec, range)
|
||||
if (intersection) acc.push(intersection)
|
||||
return acc
|
||||
}, [])
|
||||
|
||||
if (Element.isElement(n)) {
|
||||
children.push(
|
||||
|
@@ -6,7 +6,9 @@ import {
|
||||
withReact,
|
||||
DefaultEditable,
|
||||
RenderElementProps,
|
||||
RenderLeafProps,
|
||||
DefaultElement,
|
||||
DefaultLeaf,
|
||||
} from '../src'
|
||||
|
||||
describe('slate-react', () => {
|
||||
@@ -96,6 +98,79 @@ describe('slate-react', () => {
|
||||
|
||||
expect(renderElement).toHaveBeenCalledTimes(3)
|
||||
})
|
||||
|
||||
it('should pass the intersecting part of decorations to nested elements', () => {
|
||||
const editor = withReact(createEditor())
|
||||
|
||||
const value = [
|
||||
{
|
||||
type: 'parent',
|
||||
children: [
|
||||
{ type: 'block', children: [{ text: 'foo', highlight: false }] },
|
||||
{ type: 'block', children: [{ text: 'bar', highlight: false }] },
|
||||
{ type: 'block', children: [{ text: 'baz', highlight: false }] },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const decorate = jest.fn<Range[], [NodeEntry]>(([node]) => {
|
||||
if (node !== value[0]) {
|
||||
return []
|
||||
}
|
||||
return [
|
||||
{
|
||||
anchor: { path: [0, 1, 0], offset: 1 },
|
||||
focus: { path: [0, 2, 0], offset: 2 },
|
||||
highlight: true,
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
const renderLeaf = jest.fn<JSX.Element, [RenderLeafProps]>(DefaultLeaf)
|
||||
const onChange = jest.fn<void, []>()
|
||||
let el: ReactTestRenderer
|
||||
|
||||
act(() => {
|
||||
el = create(
|
||||
<Slate editor={editor} value={value} onChange={onChange}>
|
||||
<DefaultEditable decorate={decorate} renderLeaf={renderLeaf} />
|
||||
</Slate>,
|
||||
{ createNodeMock }
|
||||
)
|
||||
})
|
||||
|
||||
// 4 renders, for foo,b,ar,ba,z
|
||||
expect(renderLeaf).toHaveBeenCalledTimes(5)
|
||||
expect(renderLeaf.mock.calls).toEqual(
|
||||
expect.arrayContaining([
|
||||
[
|
||||
expect.objectContaining({
|
||||
leaf: { highlight: false, text: 'foo' },
|
||||
}),
|
||||
],
|
||||
[
|
||||
expect.objectContaining({
|
||||
leaf: { highlight: false, text: 'b' },
|
||||
}),
|
||||
],
|
||||
[
|
||||
expect.objectContaining({
|
||||
leaf: { highlight: true, text: 'ar' },
|
||||
}),
|
||||
],
|
||||
[
|
||||
expect.objectContaining({
|
||||
leaf: { highlight: true, text: 'ba' },
|
||||
}),
|
||||
],
|
||||
[
|
||||
expect.objectContaining({
|
||||
leaf: { highlight: false, text: 'z' },
|
||||
}),
|
||||
],
|
||||
])
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
Reference in New Issue
Block a user