Skip to content

Commit 714b3e1

Browse files
authored
fix(core): clean up portable text input's selection change handling (#7525)
1 parent 8c677c2 commit 714b3e1

File tree

1 file changed

+28
-29
lines changed

1 file changed

+28
-29
lines changed

packages/sanity/src/core/form/inputs/PortableText/PortableTextInput.tsx

+28-29
Original file line numberDiff line numberDiff line change
@@ -178,35 +178,35 @@ export function PortableTextInput(props: PortableTextInputProps): ReactNode {
178178
}
179179
}, [hasFocusWithin])
180180

181-
const setFocusPathFromEditorSelection = useCallback(() => {
182-
const selection = nextSelectionRef.current
183-
const focusPath = selection?.focus.path
184-
if (!focusPath) return
185-
186-
// Report focus on spans with `.text` appended to the reported focusPath.
187-
// This is done to support the Presentation tool which uses this kind of paths to refer to texts.
188-
// The PT-input already supports these paths the other way around.
189-
// It's a bit ugly right here, but it's a rather simple way to support the Presentation tool without
190-
// having to change the PTE's internals.
191-
const isSpanPath =
192-
focusPath.length === 3 && // A span path is always 3 segments long
193-
focusPath[1] === 'children' && // Is a child of a block
194-
isKeySegment(focusPath[2]) && // Contains the key of the child
195-
!portableTextMemberItems.some(
196-
(item) => isKeySegment(focusPath[2]) && item.member.key === focusPath[2]._key,
197-
)
198-
const nextFocusPath = isSpanPath ? focusPath.concat(['text']) : focusPath
181+
const setFocusPathFromEditorSelection = useCallback(
182+
(nextSelection: EditorSelection) => {
183+
const focusPath = nextSelection?.focus.path
184+
if (!focusPath) return
185+
186+
// Report focus on spans with `.text` appended to the reported focusPath.
187+
// This is done to support the Presentation tool which uses this kind of paths to refer to texts.
188+
// The PT-input already supports these paths the other way around.
189+
// It's a bit ugly right here, but it's a rather simple way to support the Presentation tool without
190+
// having to change the PTE's internals.
191+
const isSpanPath =
192+
focusPath.length === 3 && // A span path is always 3 segments long
193+
focusPath[1] === 'children' && // Is a child of a block
194+
isKeySegment(focusPath[2]) && // Contains the key of the child
195+
!portableTextMemberItems.some(
196+
(item) => isKeySegment(focusPath[2]) && item.member.key === focusPath[2]._key,
197+
)
198+
const nextFocusPath = isSpanPath ? focusPath.concat(['text']) : focusPath
199199

200-
// Must called in a transition useTrackFocusPath hook
201-
// will try to effectuate a focusPath that is different from what currently is the editor focusPath
202-
startTransition(() => {
203-
onPathFocus(nextFocusPath, {
204-
selection,
200+
// Must called in a transition useTrackFocusPath hook
201+
// will try to effectuate a focusPath that is different from what currently is the editor focusPath
202+
startTransition(() => {
203+
onPathFocus(nextFocusPath, {
204+
selection: nextSelection,
205+
})
205206
})
206-
})
207-
}, [onPathFocus, portableTextMemberItems])
208-
209-
const nextSelectionRef = useRef<EditorSelection | null>(null)
207+
},
208+
[onPathFocus, portableTextMemberItems],
209+
)
210210

211211
// Handle editor changes
212212
const handleEditorChange = useCallback(
@@ -223,8 +223,7 @@ export function PortableTextInput(props: PortableTextInputProps): ReactNode {
223223
}
224224
break
225225
case 'selection':
226-
nextSelectionRef.current = change.selection
227-
setFocusPathFromEditorSelection()
226+
setFocusPathFromEditorSelection(change.selection)
228227
break
229228
case 'focus':
230229
setIsActive(true)

0 commit comments

Comments
 (0)