From d788e8d44e83ee6ccc8d47e09ae7afbca729f38c Mon Sep 17 00:00:00 2001 From: "grafana-delivery-bot[bot]" <132647405+grafana-delivery-bot[bot]@users.noreply.github.com> Date: Fri, 31 Jan 2025 11:46:08 +0200 Subject: [PATCH] [v11.5.x] CodeEditor: Fix cursor alignment (#99863) CodeEditor: Fix cursor alignment (#99090) * remeasure fonts once they've loaded * add test mock * fix unit test * remeasure fonts after the editor has mounted just to be safe (cherry picked from commit 8e59f618c11e72bdf190c64d1e237a6dd92e09f7) Co-authored-by: Ashley Harrison --- .../src/components/Monaco/ReactMonacoEditor.tsx | 11 ++++++++++- .../plugins/panel/datagrid/DataGridPanel.test.tsx | 12 +++++++----- public/test/jest-setup.ts | 3 +++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/packages/grafana-ui/src/components/Monaco/ReactMonacoEditor.tsx b/packages/grafana-ui/src/components/Monaco/ReactMonacoEditor.tsx index 2a5dfa1ea85..2d095d6d182 100644 --- a/packages/grafana-ui/src/components/Monaco/ReactMonacoEditor.tsx +++ b/packages/grafana-ui/src/components/Monaco/ReactMonacoEditor.tsx @@ -11,7 +11,7 @@ import type { ReactMonacoEditorProps } from './types'; monacoEditorLoader.config({ monaco }); export const ReactMonacoEditor = (props: ReactMonacoEditorProps) => { - const { beforeMount, options, ...restProps } = props; + const { beforeMount, onMount, options, ...restProps } = props; const theme = useTheme2(); const onMonacoBeforeMount = useCallback( @@ -31,6 +31,15 @@ export const ReactMonacoEditor = (props: ReactMonacoEditorProps) => { }} theme={theme.isDark ? 'grafana-dark' : 'grafana-light'} beforeMount={onMonacoBeforeMount} + onMount={(editor, monaco) => { + // we use a custom font in our monaco editor + // we need monaco to remeasure the fonts after they are loaded to prevent alignment issues + // see https://github.com/microsoft/monaco-editor/issues/648#issuecomment-564978560 + document.fonts.ready.then(() => { + monaco.editor.remeasureFonts(); + }); + onMount?.(editor, monaco); + }} /> ); }; diff --git a/public/app/plugins/panel/datagrid/DataGridPanel.test.tsx b/public/app/plugins/panel/datagrid/DataGridPanel.test.tsx index 79651066698..d08e7f2be33 100644 --- a/public/app/plugins/panel/datagrid/DataGridPanel.test.tsx +++ b/public/app/plugins/panel/datagrid/DataGridPanel.test.tsx @@ -59,15 +59,17 @@ describe('DataGrid', () => { jest.clearAllMocks(); }); - it('converts dataframe values to cell values properly', () => { + it('converts dataframe values to cell values properly', async () => { jest.useFakeTimers(); render(); prep(false); - expect(screen.getByTestId('glide-cell-1-0')).toHaveTextContent('1'); - expect(screen.getByTestId('glide-cell-2-1')).toHaveTextContent('b'); - expect(screen.getByTestId('glide-cell-3-2')).toHaveTextContent('c'); - expect(screen.getByTestId('glide-cell-3-3')).toHaveTextContent('d'); + await waitFor(() => { + expect(screen.getByTestId('glide-cell-1-0')).toHaveTextContent('1'); + expect(screen.getByTestId('glide-cell-2-1')).toHaveTextContent('b'); + expect(screen.getByTestId('glide-cell-3-2')).toHaveTextContent('c'); + expect(screen.getByTestId('glide-cell-3-3')).toHaveTextContent('d'); + }); }); it('should open context menu on right click', async () => { diff --git a/public/test/jest-setup.ts b/public/test/jest-setup.ts index c0286b53e06..72a8d66c0dc 100644 --- a/public/test/jest-setup.ts +++ b/public/test/jest-setup.ts @@ -61,6 +61,9 @@ const mockIntersectionObserver = jest disconnect: jest.fn(), })); global.IntersectionObserver = mockIntersectionObserver; +Object.defineProperty(document, 'fonts', { + value: { ready: Promise.resolve({}) }, +}); global.TextEncoder = TextEncoder; global.TextDecoder = TextDecoder;