Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions airflow-core/newsfragments/64281.significant.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Rework Monaco Editor style to match Chakra UI color palette.
7 changes: 3 additions & 4 deletions airflow-core/src/airflow/ui/src/components/JsonEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import Editor, { type EditorProps } from "@monaco-editor/react";
import { useRef } from "react";

import { useColorMode } from "src/context/colorMode";
import { useMonacoTheme } from "src/context/colorMode";

type JsonEditorProps = {
readonly editable?: boolean;
Expand All @@ -39,7 +39,7 @@ export const JsonEditor = ({
value,
...rest
}: JsonEditorProps) => {
const { colorMode } = useColorMode();
const { beforeMount, theme } = useMonacoTheme();
const onBlurRef = useRef(onBlur);

onBlurRef.current = onBlur;
Expand All @@ -55,8 +55,6 @@ export const JsonEditor = ({
scrollBeyondLastLine: false,
};

const theme = colorMode === "dark" ? "vs-dark" : "vs-light";

const handleChange = (val: string | undefined) => {
onChange?.(val ?? "");
};
Expand All @@ -72,6 +70,7 @@ export const JsonEditor = ({
{...rest}
>
<Editor
beforeMount={beforeMount}
height={height}
language="json"
onChange={handleChange}
Expand Down
43 changes: 11 additions & 32 deletions airflow-core/src/airflow/ui/src/components/RenderedJsonField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,10 @@
*/
import { Flex, type FlexProps } from "@chakra-ui/react";
import Editor, { type OnMount } from "@monaco-editor/react";
import { useCallback, useState } from "react";
import { useCallback } from "react";

import { ClipboardRoot, ClipboardIconButton } from "src/components/ui";
import { useColorMode } from "src/context/colorMode";

const MAX_HEIGHT = 300;
const MIN_HEIGHT = 40;
import { useMonacoTheme } from "src/context/colorMode";

type Props = {
readonly collapsed?: boolean;
Expand All @@ -34,48 +31,30 @@ type Props = {

const RenderedJsonField = ({ collapsed = false, content, enableClipboard = true, ...rest }: Props) => {
const contentFormatted = JSON.stringify(content, undefined, 2);
const { colorMode } = useColorMode();
const { beforeMount, theme } = useMonacoTheme();
const lineCount = contentFormatted.split("\n").length;
const expandedHeight = Math.min(Math.max(lineCount * 19 + 10, MIN_HEIGHT), MAX_HEIGHT);
const [editorHeight, setEditorHeight] = useState(collapsed ? MIN_HEIGHT : expandedHeight);
const [isReady, setIsReady] = useState(!collapsed);
const theme = colorMode === "dark" ? "vs-dark" : "vs-light";
const height = `${Math.min(Math.max(lineCount * 19 + 10, 40), 300)}px`;

const handleMount: OnMount = useCallback(
(editorInstance) => {
editorInstance.onDidContentSizeChange(() => {
const contentHeight = editorInstance.getContentHeight();

setEditorHeight(Math.min(Math.max(contentHeight, MIN_HEIGHT), MAX_HEIGHT));
});

if (collapsed) {
const action = editorInstance.getAction("editor.foldAll");

if (action) {
void action.run().then(() => {
setIsReady(true);
});
} else {
setIsReady(true);
}
void editorInstance.getAction("editor.foldAll")?.run();
}
},
[collapsed],
);

return (
<Flex
flex={1}
gap={2}
minW={200}
// Hide the editor until it's ready to prevent a flickering effect when collapsing.
// The editor will be hidden until the fold action is completed (if collapsed) or immediately if not collapsed.
style={isReady ? undefined : { height: "0px", overflow: "hidden" }}
border="1px solid"
borderColor="border.emphasized"
borderRadius="md"
overflow="hidden"
{...rest}
>
<Editor
height={`${editorHeight}px`}
beforeMount={beforeMount}
height={height}
language="json"
onMount={handleMount}
options={{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@

export * from "./ColorModeProvider";
export * from "./useColorMode";
export * from "./useMonacoTheme";
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*!
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import type { Monaco } from "@monaco-editor/react";
import { useCallback } from "react";

import { useColorMode } from "./useColorMode";

const cssVarToHex = (cssVar: string): string => {
const value = getComputedStyle(document.documentElement).getPropertyValue(cssVar).trim();
const canvas = document.createElement("canvas");

canvas.width = 1;
canvas.height = 1;
const ctx = canvas.getContext("2d");

if (!ctx || !value) {
return "#000000";
}
ctx.fillStyle = value;
ctx.fillRect(0, 0, 1, 1);
const [red = 0, green = 0, blue = 0] = ctx.getImageData(0, 0, 1, 1).data;

return `#${red.toString(16).padStart(2, "0")}${green.toString(16).padStart(2, "0")}${blue.toString(16).padStart(2, "0")}`;
};

const defineMonacoThemes = (monaco: Monaco) => {
monaco.editor.defineTheme("airflow-light", {
base: "vs",
colors: {
"editor.background": cssVarToHex("--chakra-colors-gray-50"),
"editor.foreground": cssVarToHex("--chakra-colors-gray-900"),
"editor.inactiveSelectionBackground": cssVarToHex("--chakra-colors-gray-200"),
"editor.selectionBackground": cssVarToHex("--chakra-colors-brand-200"),
"editorGutter.background": cssVarToHex("--chakra-colors-gray-100"),
"editorLineNumber.activeForeground": cssVarToHex("--chakra-colors-gray-700"),
"editorLineNumber.foreground": cssVarToHex("--chakra-colors-gray-400"),
"editorSuggestWidget.background": cssVarToHex("--chakra-colors-gray-50"),
"editorWidget.background": cssVarToHex("--chakra-colors-gray-50"),
"editorWidget.border": cssVarToHex("--chakra-colors-gray-300"),
"scrollbarSlider.background": cssVarToHex("--chakra-colors-gray-300"),
"scrollbarSlider.hoverBackground": cssVarToHex("--chakra-colors-gray-400"),
},
inherit: true,
rules: [],
});

monaco.editor.defineTheme("airflow-dark", {
base: "vs-dark",
colors: {
"editor.background": cssVarToHex("--chakra-colors-gray-900"),
"editor.foreground": cssVarToHex("--chakra-colors-gray-100"),
"editor.inactiveSelectionBackground": cssVarToHex("--chakra-colors-gray-800"),
"editor.selectionBackground": cssVarToHex("--chakra-colors-brand-800"),
"editorGutter.background": cssVarToHex("--chakra-colors-gray-950"),
"editorLineNumber.activeForeground": cssVarToHex("--chakra-colors-gray-300"),
"editorLineNumber.foreground": cssVarToHex("--chakra-colors-gray-500"),
"editorSuggestWidget.background": cssVarToHex("--chakra-colors-gray-900"),
"editorWidget.background": cssVarToHex("--chakra-colors-gray-900"),
"editorWidget.border": cssVarToHex("--chakra-colors-gray-700"),
"scrollbarSlider.background": cssVarToHex("--chakra-colors-gray-700"),
"scrollbarSlider.hoverBackground": cssVarToHex("--chakra-colors-gray-600"),
},
inherit: true,
rules: [],
});
};

export const useMonacoTheme = () => {
const { colorMode } = useColorMode();

const beforeMount = useCallback((monaco: Monaco) => {
defineMonacoThemes(monaco);
}, []);

return {
beforeMount,
theme: colorMode === "dark" ? "airflow-dark" : "airflow-light",
};
};
7 changes: 3 additions & 4 deletions airflow-core/src/airflow/ui/src/pages/Dag/Code/Code.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import { ErrorAlert } from "src/components/ErrorAlert";
import Time from "src/components/Time";
import { ClipboardRoot, ClipboardButton, Tooltip } from "src/components/ui";
import { ProgressBar } from "src/components/ui";
import { useColorMode } from "src/context/colorMode";
import { useMonacoTheme } from "src/context/colorMode";
import useSelectedVersion from "src/hooks/useSelectedVersion";
import { useConfig } from "src/queries/useConfig";
import { renderDuration } from "src/utils";
Expand Down Expand Up @@ -115,7 +115,7 @@ export const Code = () => {
setIsCompareDropdownOpen(false);
};

const { colorMode } = useColorMode();
const { beforeMount, theme } = useMonacoTheme();

useHotkeys("w", toggleWrap);

Expand All @@ -137,8 +137,6 @@ export const Code = () => {
wordWrap: wrap ? "on" : "off",
};

const theme = colorMode === "dark" ? "vs-dark" : "vs-light";

const hasMultipleVersions = (dagVersions?.dag_versions.length ?? 0) >= 2;

return (
Expand Down Expand Up @@ -278,6 +276,7 @@ export const Code = () => {
<FileLocation fileloc={dag.fileloc} relativeFileloc={dag.relative_fileloc} />
)}
<Editor
beforeMount={beforeMount}
language="python"
options={editorOptions}
theme={theme}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import { Box } from "@chakra-ui/react";
import { DiffEditor, type DiffEditorProps } from "@monaco-editor/react";

import { useColorMode } from "src/context/colorMode";
import { useMonacoTheme } from "src/context/colorMode";

type CodeDiffViewerProps = {
readonly height?: string;
Expand All @@ -36,7 +36,7 @@ export const CodeDiffViewer = ({
originalCode,
renderSideBySide = true,
}: CodeDiffViewerProps) => {
const { colorMode } = useColorMode();
const { beforeMount, theme } = useMonacoTheme();

const diffOptions: DiffEditorProps["options"] = {
automaticLayout: true,
Expand All @@ -62,8 +62,6 @@ export const CodeDiffViewer = ({
},
};

const theme = colorMode === "dark" ? "vs-dark" : "vs-light";

return (
<Box
css={{
Expand All @@ -76,6 +74,7 @@ export const CodeDiffViewer = ({
zIndex={1}
>
<DiffEditor
beforeMount={beforeMount}
language={language}
modified={modifiedCode}
options={diffOptions}
Expand Down
Loading