diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/constants.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/constants.ts new file mode 100644 index 0000000000000..3d3b6bc74e72d --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/constants.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const TABLE_CLASS_NAME = 'rule-update-diff-table'; +export const CODE_CLASS_NAME = 'rule-update-diff-code'; +export const GUTTER_CLASS_NAME = 'rule-update-diff-gutter'; +export const DARK_THEME_CLASS_NAME = 'rule-update-diff-dark-theme'; + +export const COLORS = { + light: { + gutterBackground: { + deletion: 'rgb(255, 215, 213)', + insertion: 'rgb(204, 255, 216)', + }, + lineBackground: { + deletion: 'rgb(255, 235, 233)', + insertion: 'rgb(230, 255, 236)', + }, + characterBackground: { + deletion: 'rgba(255, 129, 130, 0.4)', + insertion: 'rgb(171, 242, 188)', + }, + }, + dark: { + gutterBackground: { + deletion: 'rgba(248, 81, 73, 0.3)', + insertion: 'rgba(63, 185, 80, 0.3)', + }, + lineBackground: { + deletion: 'rgba(248, 81, 73, 0.1)', + insertion: 'rgba(46, 160, 67, 0.15)', + }, + characterBackground: { + deletion: 'rgba(248, 81, 73, 0.4)', + insertion: 'rgba(46, 160, 67, 0.4)', + }, + }, +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/diff_view.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/diff_view.tsx index 8905d0aca4e6f..3139cb5478907 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/diff_view.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/diff_view.tsx @@ -6,6 +6,7 @@ */ import React, { useMemo } from 'react'; +import classNames from 'classnames'; import { css, Global } from '@emotion/react'; import { Diff, @@ -23,9 +24,16 @@ import type { HunkTokens, } from 'react-diff-view'; import unidiff from 'unidiff'; -import { useEuiTheme } from '@elastic/eui'; +import { useEuiTheme, COLOR_MODES_STANDARD } from '@elastic/eui'; import { Hunks } from './hunks'; import { markEdits, DiffMethod } from './mark_edits'; +import { + TABLE_CLASS_NAME, + CODE_CLASS_NAME, + GUTTER_CLASS_NAME, + DARK_THEME_CLASS_NAME, + COLORS, +} from './constants'; interface UseExpandReturn { expandRange: (start: number, end: number) => void; @@ -137,53 +145,73 @@ const convertToDiffFile = (oldSource: string, newSource: string) => { return diffFile; }; -const TABLE_CLASS_NAME = 'rule-update-diff-table'; -const CODE_CLASS_NAME = 'rule-update-diff-code'; -const GUTTER_CLASS_NAME = 'rule-update-diff-gutter'; - const CustomStyles: React.FC = ({ children }) => { const { euiTheme } = useEuiTheme(); const customCss = css` - .${TABLE_CLASS_NAME} .diff-gutter-col { - width: ${euiTheme.size.xl}; + .${CODE_CLASS_NAME}.diff-code { + padding: 0 ${euiTheme.size.l} 0 ${euiTheme.size.m}; } - .${CODE_CLASS_NAME}.diff-code, .${GUTTER_CLASS_NAME}.diff-gutter { - background: transparent; + .${TABLE_CLASS_NAME} .diff-gutter-col { + width: ${euiTheme.size.xl}; } + /* Vertical line separating two sides of the diff view */ .${GUTTER_CLASS_NAME}:nth-child(3) { border-left: 1px solid ${euiTheme.colors.mediumShade}; } + /* Gutter of a line with deletions */ .${GUTTER_CLASS_NAME}.diff-gutter-delete { - color: ${euiTheme.colors.dangerText}; font-weight: bold; + background: ${COLORS.light.gutterBackground.deletion}; + } + .${DARK_THEME_CLASS_NAME} .${GUTTER_CLASS_NAME}.diff-gutter-delete { + background: ${COLORS.dark.gutterBackground.deletion}; } + /* Gutter of a line with insertions */ .${GUTTER_CLASS_NAME}.diff-gutter-insert { - color: ${euiTheme.colors.successText}; font-weight: bold; + background: ${COLORS.light.gutterBackground.insertion}; + } + .${DARK_THEME_CLASS_NAME} .${GUTTER_CLASS_NAME}.diff-gutter-insert { + background: ${COLORS.dark.gutterBackground.insertion}; } - .${CODE_CLASS_NAME}.diff-code { - padding: 0 ${euiTheme.size.l} 0 ${euiTheme.size.m}; + /* Background of a line with deletions */ + .${CODE_CLASS_NAME}.diff-code-delete { + background: ${COLORS.light.lineBackground.deletion}; + } + .${DARK_THEME_CLASS_NAME} .${CODE_CLASS_NAME}.diff-code-delete { + background: ${COLORS.dark.lineBackground.deletion}; } - .${CODE_CLASS_NAME}.diff-code-delete .diff-code-edit, - .${CODE_CLASS_NAME}.diff-code-insert .diff-code-edit { - background: transparent; + /* Background of a line with insertions */ + .${CODE_CLASS_NAME}.diff-code-insert { + background: ${COLORS.light.lineBackground.insertion}; + } + .${DARK_THEME_CLASS_NAME} .${CODE_CLASS_NAME}.diff-code-insert { + background: ${COLORS.dark.lineBackground.insertion}; } + /* Accented background of removed characters / words */ .${CODE_CLASS_NAME}.diff-code-delete .diff-code-edit { - color: ${euiTheme.colors.dangerText}; - text-decoration: line-through; + font-weight: 700; + background: ${COLORS.light.characterBackground.deletion}; + } + .${DARK_THEME_CLASS_NAME} .${CODE_CLASS_NAME}.diff-code-delete .diff-code-edit { + background: ${COLORS.dark.characterBackground.deletion}; } + /* Accented background of inserted characters / words */ .${CODE_CLASS_NAME}.diff-code-insert .diff-code-edit { - color: ${euiTheme.colors.successText}; - text-decoration: underline; + font-weight: 700; + background: ${COLORS.light.characterBackground.insertion}; + } + .${DARK_THEME_CLASS_NAME} .${CODE_CLASS_NAME}.diff-code-insert .diff-code-edit { + background: ${COLORS.dark.characterBackground.insertion}; } `; @@ -229,6 +257,12 @@ export const DiffView = ({ */ const tokens = useTokens(hunks, diffMethod, oldSource); + const { colorMode } = useEuiTheme(); + + const tableClassName = classNames(TABLE_CLASS_NAME, { + [DARK_THEME_CLASS_NAME]: colorMode === COLOR_MODES_STANDARD.dark, + }); + return (