mirror of
https://github.com/overleaf/overleaf.git
synced 2024-12-18 00:21:25 -05:00
af6ffdcf7c
Fix scroll issue when focusing a change in new review panel GitOrigin-RevId: 55784de415f65935ad9b1a8cd3ad82ea3ddac3c1
67 lines
2.3 KiB
TypeScript
67 lines
2.3 KiB
TypeScript
import { FC, useCallback, useState } from 'react'
|
|
import { AnyOperation } from '../../../../../types/change'
|
|
import {
|
|
useCodeMirrorStateContext,
|
|
useCodeMirrorViewContext,
|
|
} from '@/features/source-editor/components/codemirror-editor'
|
|
import { isSelectionWithinOp } from '../utils/is-selection-within-op'
|
|
import { EditorSelection } from '@codemirror/state'
|
|
import { EditorView } from '@codemirror/view'
|
|
import classNames from 'classnames'
|
|
import { highlightRanges } from '@/features/source-editor/extensions/ranges'
|
|
|
|
export const ReviewPanelEntry: FC<{
|
|
position: number
|
|
op: AnyOperation
|
|
top?: number
|
|
className?: string
|
|
selectLineOnFocus?: boolean
|
|
}> = ({ children, position, top, op, className, selectLineOnFocus = true }) => {
|
|
const state = useCodeMirrorStateContext()
|
|
const view = useCodeMirrorViewContext()
|
|
const [focused, setFocused] = useState(false)
|
|
|
|
const highlighted = isSelectionWithinOp(op, state.selection.main)
|
|
|
|
const focusHandler = useCallback(() => {
|
|
setTimeout(() => {
|
|
// without setTimeout, error "EditorView.update are not allowed while an update is in progress" can occur
|
|
// this can be avoided by using onClick rather than onFocus but it will then not pick up <Tab> or <Shift+Tab> events for focusing entries
|
|
if (selectLineOnFocus) {
|
|
view.dispatch({
|
|
selection: EditorSelection.cursor(position),
|
|
effects: EditorView.scrollIntoView(position, { y: 'center' }),
|
|
})
|
|
}
|
|
}, 0)
|
|
setFocused(true)
|
|
}, [view, position, selectLineOnFocus])
|
|
|
|
return (
|
|
<div
|
|
onFocus={focusHandler}
|
|
onBlur={() => setFocused(false)}
|
|
onMouseEnter={() => view.dispatch(highlightRanges(op))}
|
|
onMouseLeave={() => view.dispatch(highlightRanges())}
|
|
role="button"
|
|
tabIndex={position + 1}
|
|
className={classNames(
|
|
'review-panel-entry',
|
|
{
|
|
'review-panel-entry-focused': focused,
|
|
'review-panel-entry-highlighted': highlighted,
|
|
},
|
|
className
|
|
)}
|
|
data-top={top}
|
|
data-pos={position}
|
|
style={{
|
|
position: top === undefined ? 'relative' : 'absolute',
|
|
visibility: top === undefined ? 'visible' : 'hidden',
|
|
transition: 'top .3s, left .1s, right .1s',
|
|
}}
|
|
>
|
|
{children}
|
|
</div>
|
|
)
|
|
}
|