@@ -25,6 +25,7 @@ const InlineEditor = forwardRef(({
2525} , ref ) => {
2626 const [ slateValue , setSlateValue ] = useState ( value ) ;
2727 const focusRangeRef = useRef ( null ) ;
28+ const containerRef = useRef ( null ) ;
2829
2930 const editor = useMemo ( ( ) => {
3031 const _editor = inlineEditor ( ) ;
@@ -123,6 +124,42 @@ const InlineEditor = forwardRef(({
123124 // eslint-disable-next-line react-hooks/exhaustive-deps
124125 } , [ ] ) ;
125126
127+ // Keep outer scrollers still on input: the browser's native "scroll caret
128+ // into view" would otherwise scroll the page (e.g. the form body).
129+ useEffect ( ( ) => {
130+ if ( ! enableEdit ) return ;
131+ const container = containerRef . current ;
132+ if ( ! container ) return ;
133+
134+ const getOuterScrollers = ( ) => {
135+ const scrollers = [ ] ;
136+ let el = container . parentElement ;
137+ while ( el && el !== document . body && el !== document . documentElement ) {
138+ const { overflowY, overflowX } = window . getComputedStyle ( el ) ;
139+ const scrollableY = ( overflowY === 'auto' || overflowY === 'scroll' ) && el . scrollHeight > el . clientHeight ;
140+ const scrollableX = ( overflowX === 'auto' || overflowX === 'scroll' ) && el . scrollWidth > el . clientWidth ;
141+ if ( scrollableY || scrollableX ) scrollers . push ( el ) ;
142+ el = el . parentElement ;
143+ }
144+ return scrollers ;
145+ } ;
146+
147+ const onBeforeInput = ( ) => {
148+ const scrollers = getOuterScrollers ( ) ;
149+ if ( scrollers . length === 0 ) return ;
150+ const positions = scrollers . map ( el => ( { el, top : el . scrollTop , left : el . scrollLeft } ) ) ;
151+ requestAnimationFrame ( ( ) => {
152+ positions . forEach ( ( { el, top, left } ) => {
153+ if ( el . scrollTop !== top ) el . scrollTop = top ;
154+ if ( el . scrollLeft !== left ) el . scrollLeft = left ;
155+ } ) ;
156+ } ) ;
157+ } ;
158+
159+ container . addEventListener ( 'beforeinput' , onBeforeInput , true ) ;
160+ return ( ) => container . removeEventListener ( 'beforeinput' , onBeforeInput , true ) ;
161+ } , [ enableEdit ] ) ;
162+
126163 const handleClear = useCallback ( ( targetEditor ) => {
127164 if ( targetEditor . _id !== editor . _id ) return ;
128165 editor . children = [ {
@@ -171,7 +208,7 @@ const InlineEditor = forwardRef(({
171208 } , [ enableEdit , editor , focusNode , handelEnableEdit ] ) ;
172209
173210 return (
174- < div className = "sf-simple-slate-editor-container" >
211+ < div className = "sf-simple-slate-editor-container" ref = { containerRef } >
175212 { enableEdit && ( < InlineToolbar editor = { editor } isSupportFormula = { isSupportFormula } isSupportColumn = { ! ! columns } onExpandEditorToggle = { onExpandEditorToggle } /> ) }
176213 < div className = "sf-slate-editor-content" onClick = { onEditorClick } >
177214 < Slate editor = { editor } initialValue = { slateValue } onChange = { onChange } >
0 commit comments