GrafanaUI: Prevent code editors from 'trapping' scroll (#77125)

* GrafanaUI: Prevent CodeEditor from 'trapping' scroll

* fix test

* fix lint for unused import
This commit is contained in:
Josh Hunt 2023-10-25 16:21:54 +00:00 committed by GitHub
parent 1e81ffccac
commit 333c858bc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 22 additions and 8 deletions

View File

@ -853,9 +853,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"]
],
"packages/grafana-ui/src/components/Monaco/CodeEditor.tsx:5381": [
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
],
"packages/grafana-ui/src/components/PageLayout/PageToolbar.tsx:5381": [
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
],

View File

@ -387,7 +387,7 @@ export const Components = {
singleLink: 'Data link',
},
CodeEditor: {
container: 'Code editor container',
container: 'data-testid Code editor container',
},
DashboardImportPage: {
textarea: 'data-testid-import-dashboard-textarea',

View File

@ -101,6 +101,7 @@ class UnthemedCodeEditor extends PureComponent<Props> {
if (getSuggestions && this.modelId) {
this.completionCancel = registerSuggestions(monaco, language, getSuggestions, this.modelId);
}
// Save when pressing Ctrl+S or Cmd+S
editor.onKeyDown((e: monacoType.IKeyboardEvent) => {
if (e.keyCode === monaco.KeyCode.KeyS && (e.ctrlKey || e.metaKey)) {
@ -122,6 +123,8 @@ class UnthemedCodeEditor extends PureComponent<Props> {
render() {
const { theme, language, width, height, showMiniMap, showLineNumbers, readOnly, monacoOptions } = this.props;
const { alwaysConsumeMouseWheel, ...restMonacoOptions } = monacoOptions ?? {};
const value = this.props.value ?? '';
const longText = value.length > 100;
@ -147,6 +150,10 @@ class UnthemedCodeEditor extends PureComponent<Props> {
bottom: 0.5 * theme.spacing.gridSize,
},
fixedOverflowWidgets: true, // Ensures suggestions menu is drawn on top
scrollbar: {
alwaysConsumeMouseWheel: alwaysConsumeMouseWheel ?? false,
},
};
if (!showLineNumbers) {
@ -157,7 +164,7 @@ class UnthemedCodeEditor extends PureComponent<Props> {
}
return (
<div className={containerStyles} onBlur={this.onBlur} aria-label={selectors.components.CodeEditor.container}>
<div className={containerStyles} onBlur={this.onBlur} data-testid={selectors.components.CodeEditor.container}>
<ReactMonacoEditorLazy
width={width}
height={height}
@ -165,7 +172,7 @@ class UnthemedCodeEditor extends PureComponent<Props> {
value={value}
options={{
...options,
...(monacoOptions ?? {}),
...(restMonacoOptions ?? {}),
}}
beforeMount={this.handleBeforeMount}
onMount={this.handleOnMount}

View File

@ -147,4 +147,11 @@ export interface MonacoOptionsWithGrafanaDefaults extends monacoType.editor.ISta
* Defaults to true.
*/
automaticLayout?: boolean;
/**
* Always consume mouse wheel events (always call preventDefault() and stopPropagation() on the browser events).
* Always consuming mouse wheel events will prevent the page from scrolling if the cursor is over the editor.
* Defaults to `false`.
*/
alwaysConsumeMouseWheel?: boolean;
}

View File

@ -2,8 +2,9 @@ import { render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { TestProvider } from 'test/helpers/TestProvider';
import { byLabelText, byRole, byTestId } from 'testing-library-selector';
import { byRole, byTestId } from 'testing-library-selector';
import { selectors } from '@grafana/e2e-selectors';
import { locationService, setDataSourceSrv } from '@grafana/runtime';
import { contextSrv } from 'app/core/services/context_srv';
import store from 'app/core/store';
@ -82,7 +83,7 @@ const ui = {
confirmButton: byRole('button', { name: /Yes, reset configuration/ }),
resetButton: byRole('button', { name: /Reset configuration/ }),
saveButton: byRole('button', { name: /Save/ }),
configInput: byLabelText(/Code editor container/),
configInput: byTestId(selectors.components.CodeEditor.container),
readOnlyConfig: byTestId('readonly-config'),
};

View File

@ -40,6 +40,7 @@ const options: monacoTypes.editor.IStandaloneEditorConstructionOptions = {
verticalScrollbarSize: 8, // used as "padding-right"
horizontal: 'hidden',
horizontalScrollbarSize: 0,
alwaysConsumeMouseWheel: false,
},
scrollBeyondLastLine: false,
suggest: getSuggestOptions(),

View File

@ -38,6 +38,7 @@ const options: monacoTypes.editor.IStandaloneEditorConstructionOptions = {
verticalScrollbarSize: 8, // used as "padding-right"
horizontal: 'hidden',
horizontalScrollbarSize: 0,
alwaysConsumeMouseWheel: false,
},
scrollBeyondLastLine: false,
suggest: getSuggestOptions(),