mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-11 09:43:58 +02:00
feat: Forward ref from <Editable /> (#5681)
* feat: Forward ref from <Editable /> * docs: add changeset * Update packages/slate-react/src/components/editable.tsx * Update packages/slate-react/src/components/editable.tsx --------- Co-authored-by: Dylan Schiemann <dylan@dojotoolkit.org>
This commit is contained in:
5
.changeset/angry-brooms-whisper.md
Normal file
5
.changeset/angry-brooms-whisper.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'slate-react': minor
|
||||
---
|
||||
|
||||
Forward ref from Editable component
|
@@ -8,6 +8,8 @@ import React, {
|
||||
useReducer,
|
||||
useRef,
|
||||
useState,
|
||||
forwardRef,
|
||||
ForwardedRef,
|
||||
} from 'react'
|
||||
import { JSX } from 'react'
|
||||
import scrollIntoView from 'scroll-into-view-if-needed'
|
||||
@@ -130,7 +132,8 @@ export type EditableProps = {
|
||||
* Editable.
|
||||
*/
|
||||
|
||||
export const Editable = (props: EditableProps) => {
|
||||
export const Editable = forwardRef(
|
||||
(props: EditableProps, forwardedRef: ForwardedRef<HTMLDivElement>) => {
|
||||
const defaultRenderPlaceholder = useCallback(
|
||||
(props: RenderPlaceholderProps) => <DefaultPlaceholder {...props} />,
|
||||
[]
|
||||
@@ -590,7 +593,10 @@ export const Editable = (props: EditableProps) => {
|
||||
.createTreeWalker(anchorNode, NodeFilter.SHOW_TEXT)
|
||||
.lastChild() as DOMText | null
|
||||
|
||||
if (lastText === node && lastText.textContent?.length === offset) {
|
||||
if (
|
||||
lastText === node &&
|
||||
lastText.textContent?.length === offset
|
||||
) {
|
||||
native = false
|
||||
}
|
||||
}
|
||||
@@ -814,12 +820,18 @@ export const Editable = (props: EditableProps) => {
|
||||
}
|
||||
|
||||
ref.current = node
|
||||
if (typeof forwardedRef === 'function') {
|
||||
forwardedRef(node)
|
||||
} else if (forwardedRef) {
|
||||
forwardedRef.current = node
|
||||
}
|
||||
},
|
||||
[
|
||||
onDOMSelectionChange,
|
||||
scheduleOnDOMSelectionChange,
|
||||
editor,
|
||||
onDOMBeforeInput,
|
||||
forwardedRef,
|
||||
]
|
||||
)
|
||||
|
||||
@@ -1129,7 +1141,10 @@ export const Editable = (props: EditableProps) => {
|
||||
if (event.detail === TRIPLE_CLICK && path.length >= 1) {
|
||||
let blockPath = path
|
||||
if (
|
||||
!(Element.isElement(node) && Editor.isBlock(editor, node))
|
||||
!(
|
||||
Element.isElement(node) &&
|
||||
Editor.isBlock(editor, node)
|
||||
)
|
||||
) {
|
||||
const block = Editor.above(editor, {
|
||||
match: n =>
|
||||
@@ -1236,7 +1251,9 @@ export const Editable = (props: EditableProps) => {
|
||||
onCompositionStart={useCallback(
|
||||
(event: React.CompositionEvent<HTMLDivElement>) => {
|
||||
if (ReactEditor.hasSelectableTarget(editor, event.target)) {
|
||||
androidInputManagerRef.current?.handleCompositionStart(event)
|
||||
androidInputManagerRef.current?.handleCompositionStart(
|
||||
event
|
||||
)
|
||||
|
||||
if (
|
||||
isEventHandled(event, attributes.onCompositionStart) ||
|
||||
@@ -1314,7 +1331,10 @@ export const Editable = (props: EditableProps) => {
|
||||
// default, and calling `preventDefault` hides the cursor.
|
||||
const node = ReactEditor.toSlateNode(editor, event.target)
|
||||
|
||||
if (Element.isElement(node) && Editor.isVoid(editor, node)) {
|
||||
if (
|
||||
Element.isElement(node) &&
|
||||
Editor.isVoid(editor, node)
|
||||
) {
|
||||
event.preventDefault()
|
||||
}
|
||||
}
|
||||
@@ -1331,7 +1351,8 @@ export const Editable = (props: EditableProps) => {
|
||||
const node = ReactEditor.toSlateNode(editor, event.target)
|
||||
const path = ReactEditor.findPath(editor, node)
|
||||
const voidMatch =
|
||||
(Element.isElement(node) && Editor.isVoid(editor, node)) ||
|
||||
(Element.isElement(node) &&
|
||||
Editor.isVoid(editor, node)) ||
|
||||
Editor.void(editor, { at: path, voids: true })
|
||||
|
||||
// If starting a drag on a void node, make sure it is selected
|
||||
@@ -1610,7 +1631,9 @@ export const Editable = (props: EditableProps) => {
|
||||
event.preventDefault()
|
||||
|
||||
if (selection && Range.isExpanded(selection)) {
|
||||
Editor.deleteFragment(editor, { direction: 'backward' })
|
||||
Editor.deleteFragment(editor, {
|
||||
direction: 'backward',
|
||||
})
|
||||
} else {
|
||||
Editor.deleteBackward(editor)
|
||||
}
|
||||
@@ -1622,7 +1645,9 @@ export const Editable = (props: EditableProps) => {
|
||||
event.preventDefault()
|
||||
|
||||
if (selection && Range.isExpanded(selection)) {
|
||||
Editor.deleteFragment(editor, { direction: 'forward' })
|
||||
Editor.deleteFragment(editor, {
|
||||
direction: 'forward',
|
||||
})
|
||||
} else {
|
||||
Editor.deleteForward(editor)
|
||||
}
|
||||
@@ -1634,7 +1659,9 @@ export const Editable = (props: EditableProps) => {
|
||||
event.preventDefault()
|
||||
|
||||
if (selection && Range.isExpanded(selection)) {
|
||||
Editor.deleteFragment(editor, { direction: 'backward' })
|
||||
Editor.deleteFragment(editor, {
|
||||
direction: 'backward',
|
||||
})
|
||||
} else {
|
||||
Editor.deleteBackward(editor, { unit: 'line' })
|
||||
}
|
||||
@@ -1646,7 +1673,9 @@ export const Editable = (props: EditableProps) => {
|
||||
event.preventDefault()
|
||||
|
||||
if (selection && Range.isExpanded(selection)) {
|
||||
Editor.deleteFragment(editor, { direction: 'forward' })
|
||||
Editor.deleteFragment(editor, {
|
||||
direction: 'forward',
|
||||
})
|
||||
} else {
|
||||
Editor.deleteForward(editor, { unit: 'line' })
|
||||
}
|
||||
@@ -1658,7 +1687,9 @@ export const Editable = (props: EditableProps) => {
|
||||
event.preventDefault()
|
||||
|
||||
if (selection && Range.isExpanded(selection)) {
|
||||
Editor.deleteFragment(editor, { direction: 'backward' })
|
||||
Editor.deleteFragment(editor, {
|
||||
direction: 'backward',
|
||||
})
|
||||
} else {
|
||||
Editor.deleteBackward(editor, { unit: 'word' })
|
||||
}
|
||||
@@ -1670,7 +1701,9 @@ export const Editable = (props: EditableProps) => {
|
||||
event.preventDefault()
|
||||
|
||||
if (selection && Range.isExpanded(selection)) {
|
||||
Editor.deleteFragment(editor, { direction: 'forward' })
|
||||
Editor.deleteFragment(editor, {
|
||||
direction: 'forward',
|
||||
})
|
||||
} else {
|
||||
Editor.deleteForward(editor, { unit: 'word' })
|
||||
}
|
||||
@@ -1751,6 +1784,7 @@ export const Editable = (props: EditableProps) => {
|
||||
</ReadOnlyContext.Provider>
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* The props that get passed to renderPlaceholder
|
||||
|
Reference in New Issue
Block a user