1
0
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:
yf-yang
2024-08-08 03:29:40 +08:00
committed by GitHub
parent af21468a23
commit b8bf92dc7e
2 changed files with 1598 additions and 1559 deletions

View File

@@ -0,0 +1,5 @@
---
'slate-react': minor
---
Forward ref from Editable component

View File

@@ -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