fix(client): re-ref editor (#42799)
This commit is contained in:
@ -1,4 +1,11 @@
|
||||
import React, { useState, useEffect, Suspense, RefObject } from 'react';
|
||||
import React, {
|
||||
useState,
|
||||
useEffect,
|
||||
Suspense,
|
||||
RefObject,
|
||||
forwardRef,
|
||||
ForwardedRef
|
||||
} from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import Loadable from '@loadable/component';
|
||||
@ -34,6 +41,7 @@ import type {
|
||||
Range as RangeType
|
||||
// eslint-disable-next-line import/no-duplicates
|
||||
} from 'monaco-editor/esm/vs/editor/editor.api';
|
||||
import type ReactMonacoEditor from 'react-monaco-editor';
|
||||
|
||||
import './editor.css';
|
||||
|
||||
@ -174,7 +182,8 @@ const initialData: DataType = {
|
||||
outputZoneHeight: null
|
||||
};
|
||||
|
||||
const Editor = (props: PropTypes): JSX.Element => {
|
||||
const Editor = forwardRef(
|
||||
(props: PropTypes, ref: ForwardedRef<ReactMonacoEditor>): JSX.Element => {
|
||||
// TODO: is there any point in initializing this? It should be fine with
|
||||
// data = {}
|
||||
const [data, setData] = useState(initialData);
|
||||
@ -416,7 +425,9 @@ const Editor = (props: PropTypes): JSX.Element => {
|
||||
}
|
||||
};
|
||||
|
||||
const viewZoneCallback = (changeAccessor: editor.IViewZoneChangeAccessor) => {
|
||||
const viewZoneCallback = (
|
||||
changeAccessor: editor.IViewZoneChangeAccessor
|
||||
) => {
|
||||
// TODO: is there any point creating this here? I know it's cached, but
|
||||
// would it not be better just sourced from the overlayWidget?
|
||||
const domNode = createDescription();
|
||||
@ -559,11 +570,6 @@ const Editor = (props: PropTypes): JSX.Element => {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
function focusOnEditor() {
|
||||
_editor?.focus();
|
||||
}
|
||||
|
||||
const onChange = (editorValue: string) => {
|
||||
const { updateFile } = props;
|
||||
// TODO: use fileKey everywhere?
|
||||
@ -596,7 +602,10 @@ const Editor = (props: PropTypes): JSX.Element => {
|
||||
lineNumber: editableBoundaries[0] + 1,
|
||||
column: 1
|
||||
});
|
||||
_editor?.revealLinesInCenter(editableBoundaries[0], editableBoundaries[1]);
|
||||
_editor?.revealLinesInCenter(
|
||||
editableBoundaries[0],
|
||||
editableBoundaries[1]
|
||||
);
|
||||
// }
|
||||
}
|
||||
|
||||
@ -757,7 +766,12 @@ const Editor = (props: PropTypes): JSX.Element => {
|
||||
// startColumnNumber <= x < endColumnNumber
|
||||
// so we add 1 here
|
||||
const endColumn = model?.getLineLength(endLineNumber) + 1;
|
||||
return new _monaco.Range(startLineNumber, 1, endLineNumber, endColumn);
|
||||
return new _monaco.Range(
|
||||
startLineNumber,
|
||||
1,
|
||||
endLineNumber,
|
||||
endColumn
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -802,13 +816,15 @@ const Editor = (props: PropTypes): JSX.Element => {
|
||||
// the first range should expand at the top
|
||||
// TODO: Unsure what this should be - returns an array, so I added [0] @ojeytonwilliams
|
||||
data.startEditDecId = highlightLines(
|
||||
_monaco?.editor?.TrackedRangeStickiness?.GrowsOnlyWhenTypingBefore ?? 2,
|
||||
_monaco?.editor?.TrackedRangeStickiness?.GrowsOnlyWhenTypingBefore ??
|
||||
2,
|
||||
model,
|
||||
ranges[0]
|
||||
)[0];
|
||||
|
||||
highlightText(
|
||||
_monaco?.editor?.TrackedRangeStickiness?.GrowsOnlyWhenTypingBefore ?? 2,
|
||||
_monaco?.editor?.TrackedRangeStickiness?.GrowsOnlyWhenTypingBefore ??
|
||||
2,
|
||||
model,
|
||||
ranges[0]
|
||||
);
|
||||
@ -834,7 +850,8 @@ const Editor = (props: PropTypes): JSX.Element => {
|
||||
// TODO: handle multiple simultaneous changes (multicursors do this)
|
||||
function getDeletedLine(event: editor.IModelContentChangedEvent) {
|
||||
const isDeleted =
|
||||
event.changes[0].text === '' && event.changes[0].range.endColumn === 1;
|
||||
event.changes[0].text === '' &&
|
||||
event.changes[0].range.endColumn === 1;
|
||||
return isDeleted ? event.changes[0].range.endLineNumber : 0;
|
||||
}
|
||||
|
||||
@ -971,8 +988,8 @@ const Editor = (props: PropTypes): JSX.Element => {
|
||||
...data,
|
||||
endEditDecId: preventOverlap(
|
||||
data.endEditDecId ?? '',
|
||||
_monaco?.editor?.TrackedRangeStickiness?.GrowsOnlyWhenTypingBefore ??
|
||||
2,
|
||||
_monaco?.editor?.TrackedRangeStickiness
|
||||
?.GrowsOnlyWhenTypingBefore ?? 2,
|
||||
highlightLines
|
||||
)
|
||||
});
|
||||
@ -1021,7 +1038,10 @@ const Editor = (props: PropTypes): JSX.Element => {
|
||||
|
||||
// Protect against ranges that extend outside the editor
|
||||
const startLineNumber = Math.max(1, range.startLineNumber);
|
||||
const endLineNumber = Math.min(model?.getLineCount(), range.endLineNumber);
|
||||
const endLineNumber = Math.min(
|
||||
model?.getLineCount(),
|
||||
range.endLineNumber
|
||||
);
|
||||
const endColumnText = model.getLineContent(endLineNumber);
|
||||
// NOTE: the end column is incremented by 2 so that the dangerous range
|
||||
// extends far enough to capture new text added to the end.
|
||||
@ -1150,17 +1170,19 @@ const Editor = (props: PropTypes): JSX.Element => {
|
||||
editorWillMount={editorWillMount}
|
||||
onChange={onChange}
|
||||
options={options}
|
||||
ref={ref}
|
||||
theme={editorTheme}
|
||||
/>
|
||||
</span>
|
||||
</Suspense>
|
||||
);
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
Editor.displayName = 'Editor';
|
||||
|
||||
// NOTE: withRef gets replaced by forwardRef in react-redux 6,
|
||||
// https://github.com/reduxjs/react-redux/releases/tag/v6.0.0
|
||||
export default connect(mapStateToProps, mapDispatchToProps, null, {
|
||||
forwardRef: true
|
||||
withRef: true
|
||||
})(Editor);
|
||||
|
@ -60,7 +60,7 @@ function Hotkeys({
|
||||
FOCUS_EDITOR: (e: React.KeyboardEvent) => {
|
||||
e.preventDefault();
|
||||
if (editorRef && editorRef.current) {
|
||||
editorRef.current.getWrappedInstance().focusOnEditor();
|
||||
editorRef.current.getWrappedInstance().editor.focus();
|
||||
}
|
||||
},
|
||||
NAVIGATION_MODE: () => setEditorFocusability(false),
|
||||
|
Reference in New Issue
Block a user