]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-19173 - Create a "code snippet" component design-system
authorKevin Silva <kevin.silva@sonarsource.com>
Wed, 17 May 2023 10:17:17 +0000 (12:17 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 17 May 2023 20:02:41 +0000 (20:02 +0000)
12 files changed:
server/sonar-web/design-system/package.json
server/sonar-web/design-system/src/components/CodeSnippet.tsx [new file with mode: 0644]
server/sonar-web/design-system/src/components/Highlighter.tsx [new file with mode: 0644]
server/sonar-web/design-system/src/components/__tests__/CodeSnippet-test.tsx [new file with mode: 0644]
server/sonar-web/design-system/src/components/__tests__/Highlighter-test.tsx [new file with mode: 0644]
server/sonar-web/design-system/src/components/__tests__/__snapshots__/CodeSnippet-test.tsx.snap [new file with mode: 0644]
server/sonar-web/design-system/src/components/__tests__/__snapshots__/Highlighter-test.tsx.snap [new file with mode: 0644]
server/sonar-web/design-system/src/components/icons/PencilIcon.tsx [new file with mode: 0644]
server/sonar-web/design-system/src/components/icons/index.ts
server/sonar-web/design-system/src/components/index.ts
server/sonar-web/design-system/src/theme/light.ts
server/sonar-web/yarn.lock

index 45633e20409a53b854e172404bf7bec17f8fec42..ff65cf5ab5bafaa825508651648dddbb85de199d 100644 (file)
@@ -34,6 +34,7 @@
     "eslint-plugin-import": "2.27.5",
     "eslint-plugin-local-rules": "1.3.2",
     "eslint-plugin-typescript-sort-keys": "2.3.0",
+    "highlight.js": "11.7.0",
     "history": "5.3.0",
     "jest": "29.5.0",
     "postcss": "8.4.21",
diff --git a/server/sonar-web/design-system/src/components/CodeSnippet.tsx b/server/sonar-web/design-system/src/components/CodeSnippet.tsx
new file mode 100644 (file)
index 0000000..e1fed4f
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import styled from '@emotion/styled';
+import classNames from 'classnames';
+import tw from 'twin.macro';
+import { themeBorder, themeColor } from '../helpers/theme';
+import { isDefined } from '../helpers/types';
+import { Highlighter, RegisteredLanguages } from './Highlighter';
+import { ClipboardButton } from './clipboard';
+
+interface Props {
+  className?: string;
+  highlight?: boolean;
+  isOneLine?: boolean;
+  join?: string;
+  language?: RegisteredLanguages;
+  noCopy?: boolean;
+  render?: string;
+  snippet: string | Array<string | undefined>;
+  toggleEdit?: VoidFunction;
+  wrap?: boolean;
+}
+
+// keep this "useless" concatenation for the readability reason
+// eslint-disable-next-line no-useless-concat
+const s = ' \\' + '\n  ';
+
+export function CodeSnippet(props: Props) {
+  const {
+    className,
+    isOneLine,
+    highlight,
+    join = s,
+    language,
+    noCopy,
+    render,
+    snippet,
+    toggleEdit,
+    wrap,
+  } = props;
+  const snippetArray = Array.isArray(snippet) ? snippet.filter(isDefined) : [snippet];
+  const finalSnippet = isOneLine ? snippetArray.join(' ') : snippetArray.join(join);
+
+  const isSimpleOneLine = isOneLine && noCopy;
+
+  const copyButton = isOneLine ? (
+    <StyledSingleLineClipboardButton copyValue={finalSnippet} />
+  ) : (
+    <StyledClipboardButton copyValue={finalSnippet} />
+  );
+
+  return (
+    <Wrapper
+      className={classNames(
+        {
+          'code-snippet-highlighted-oneline': isOneLine,
+          'code-snippet-simple-oneline': isSimpleOneLine,
+        },
+        className,
+        'fs-mask'
+      )}
+    >
+      {!noCopy && copyButton}
+      <Highlighter
+        code={render ?? finalSnippet}
+        highlight={highlight}
+        isSimpleOneLine={isSimpleOneLine}
+        language={language}
+        toggleEdit={isOneLine ? toggleEdit : undefined}
+        wrap={wrap}
+      />
+    </Wrapper>
+  );
+}
+
+const Wrapper = styled.div`
+  background-color: ${themeColor('codeSnippetBackground')};
+  border: ${themeBorder('default', 'codeSnippetBorder')};
+
+  ${tw`sw-rounded-2`}
+  ${tw`sw-relative`}
+  ${tw`sw-my-2`}
+
+  &.code-snippet-simple-oneline {
+    ${tw`sw-my-0`}
+    ${tw`sw-rounded-1`}
+  }
+`;
+
+const StyledClipboardButton = styled(ClipboardButton)`
+  ${tw`sw-select-none`}
+  ${tw`sw-body-sm`}
+  ${tw`sw-top-6 sw-right-6`}
+  ${tw`sw-absolute`}
+
+  .code-snippet-highlighted-oneline & {
+    ${tw`sw-bottom-2`}
+  }
+`;
+
+const StyledSingleLineClipboardButton = styled(StyledClipboardButton)`
+  ${tw`sw-top-6 sw-bottom-6`}
+`;
diff --git a/server/sonar-web/design-system/src/components/Highlighter.tsx b/server/sonar-web/design-system/src/components/Highlighter.tsx
new file mode 100644 (file)
index 0000000..7369031
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import styled from '@emotion/styled';
+import classNames from 'classnames';
+import hljs from 'highlight.js/lib/core';
+import bash from 'highlight.js/lib/languages/bash';
+import gradle from 'highlight.js/lib/languages/gradle';
+import plaintext from 'highlight.js/lib/languages/plaintext';
+import powershell from 'highlight.js/lib/languages/powershell';
+import properties from 'highlight.js/lib/languages/properties';
+import shell from 'highlight.js/lib/languages/shell';
+import xml from 'highlight.js/lib/languages/xml';
+import yaml from 'highlight.js/lib/languages/yaml';
+import { useMemo } from 'react';
+import tw from 'twin.macro';
+import { translate } from '../helpers/l10n';
+import { themeColor, themeContrast } from '../helpers/theme';
+import { InteractiveIcon } from './InteractiveIcon';
+import { PencilIcon } from './icons';
+
+hljs.registerLanguage('yaml', yaml);
+hljs.registerLanguage('gradle', gradle);
+hljs.registerLanguage('properties', properties);
+hljs.registerLanguage('xml', xml);
+hljs.registerLanguage('bash', bash);
+hljs.registerLanguage('powershell', powershell);
+hljs.registerLanguage('shell', shell);
+hljs.registerLanguage('plaintext', plaintext);
+
+hljs.addPlugin({
+  'after:highlight': (data) => {
+    data.value = data.value
+      .replace(/&lt;mark&gt;/g, '<mark>')
+      .replace(/&lt;\/mark&gt;/g, '</mark>');
+  },
+});
+
+export type RegisteredLanguages =
+  | 'bash'
+  | 'gradle'
+  | 'plaintext'
+  | 'powershell'
+  | 'properties'
+  | 'shell'
+  | 'xml'
+  | 'yaml';
+
+interface Props {
+  className?: string;
+  code: string;
+  highlight?: boolean;
+  isSimpleOneLine?: boolean;
+  language?: RegisteredLanguages;
+  toggleEdit?: VoidFunction;
+  wrap?: boolean;
+}
+
+export function Highlighter({
+  className,
+  code,
+  highlight = true,
+  isSimpleOneLine = false,
+  language = 'yaml',
+  toggleEdit,
+  wrap,
+}: Props) {
+  const highlighted = useMemo(
+    () => hljs.highlight(code, { language: highlight ? language : 'plaintext' }),
+    [code, highlight, language]
+  );
+
+  return (
+    <StyledPre
+      className={classNames({ 'code-wrap': wrap, 'simple-one-line': isSimpleOneLine }, className)}
+    >
+      <code
+        className={classNames('hljs', { 'sw-inline': toggleEdit })}
+        // Safe: value is escaped by highlight.js
+        // eslint-disable-next-line react/no-danger
+        dangerouslySetInnerHTML={{ __html: highlighted.value }}
+      />
+      {toggleEdit && (
+        <InteractiveIcon
+          Icon={PencilIcon}
+          aria-label={translate('edit')}
+          className="sw-ml-2"
+          onClick={toggleEdit}
+        />
+      )}
+    </StyledPre>
+  );
+}
+
+const StyledPre = styled.pre`
+  ${tw`sw-flex sw-items-center`}
+  ${tw`sw-overflow-x-auto`}
+  ${tw`sw-p-6`}
+
+  code {
+    color: ${themeColor('codeSnippetBody')};
+    background: ${themeColor('codeSnippetBackground')};
+    ${tw`sw-code`};
+
+    &.hljs {
+      padding: unset;
+    }
+  }
+
+  .hljs-variable,
+  .hljs-meta {
+    color: ${themeColor('codeSnippetBody')};
+  }
+
+  .hljs-doctag,
+  .hljs-title,
+  .hljs-title.class_,
+  .hljs-title.function_ {
+    color: ${themeColor('codeSnippetAnnotations')};
+  }
+
+  .hljs-comment {
+    color: ${themeColor('codeSnippetComments')};
+
+    ${tw`sw-code-comment`}
+  }
+
+  .hljs-tag,
+  .hljs-type,
+  .hljs-keyword {
+    color: ${themeColor('codeSnippetKeyword')};
+
+    ${tw`sw-code-highlight`}
+  }
+
+  .hljs-literal,
+  .hljs-number {
+    color: ${themeColor('codeSnippetConstants')};
+  }
+
+  .hljs-string {
+    color: ${themeColor('codeSnippetString')};
+  }
+
+  .hljs-meta .hljs-keyword {
+    color: ${themeColor('codeSnippetPreprocessingDirective')};
+  }
+
+  &.code-wrap {
+    ${tw`sw-whitespace-pre-wrap`}
+    ${tw`sw-break-all`}
+  }
+
+  mark {
+    color: ${themeContrast('codeSnippetHighlight')};
+    background-color: ${themeColor('codeSnippetHighlight')};
+    ${tw`sw-font-regular`}
+    ${tw`sw-rounded-1`}
+    ${tw`sw-p-1`}
+  }
+
+  &.simple-one-line {
+    ${tw`sw-min-h-[1.25rem]`}
+    ${tw`sw-py-0 sw-px-1`}
+  }
+`;
diff --git a/server/sonar-web/design-system/src/components/__tests__/CodeSnippet-test.tsx b/server/sonar-web/design-system/src/components/__tests__/CodeSnippet-test.tsx
new file mode 100644 (file)
index 0000000..41e98ce
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import { screen } from '@testing-library/react';
+import { HelmetProvider } from 'react-helmet-async';
+import { renderWithContext } from '../../helpers/testUtils';
+import { FCProps } from '../../types/misc';
+import { CodeSnippet } from '../CodeSnippet';
+
+it('should show full size when multiline with no editting', () => {
+  const { container } = setupWithProps();
+  const copyButton = screen.getByRole('button', { name: 'copy' });
+  expect(copyButton).toHaveStyle('top: 1.5rem');
+  expect(container).toMatchSnapshot();
+});
+
+it('should show reduced size when single line with no editting', () => {
+  const { container } = setupWithProps({ isOneLine: true, snippet: 'foobar' });
+  const copyButton = screen.getByRole('button', { name: 'copy' });
+  expect(copyButton).toHaveStyle('top: 1.5rem');
+  expect(container).toMatchSnapshot();
+});
+
+function setupWithProps(props: Partial<FCProps<typeof CodeSnippet>> = {}) {
+  return renderWithContext(
+    <HelmetProvider>
+      <CodeSnippet snippet={'foo\nbar'} {...props} />
+    </HelmetProvider>
+  );
+}
diff --git a/server/sonar-web/design-system/src/components/__tests__/Highlighter-test.tsx b/server/sonar-web/design-system/src/components/__tests__/Highlighter-test.tsx
new file mode 100644 (file)
index 0000000..c02ca7f
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+import { renderWithContext } from '../../helpers/testUtils';
+import { FCProps } from '../../types/misc';
+import { Highlighter } from '../Highlighter';
+
+it('renders correctly', () => {
+  expect(setupWithProps().container).toMatchSnapshot();
+});
+
+it('should handle multiple lines of code', () => {
+  expect(
+    setupWithProps({
+      code: `foo: bar
+              pleh: help
+              stuff:
+               foo: bar
+               bar: foo`,
+      language: 'yaml',
+    }).container
+  ).toMatchSnapshot();
+});
+
+it('should display edit functions', () => {
+  expect(
+    setupWithProps({ code: 'One line command', toggleEdit: jest.fn() }).container
+  ).toMatchSnapshot();
+});
+
+function setupWithProps(props: Partial<FCProps<typeof Highlighter>> = {}) {
+  return renderWithContext(<Highlighter code="foo\nbar" {...props} />);
+}
diff --git a/server/sonar-web/design-system/src/components/__tests__/__snapshots__/CodeSnippet-test.tsx.snap b/server/sonar-web/design-system/src/components/__tests__/__snapshots__/CodeSnippet-test.tsx.snap
new file mode 100644 (file)
index 0000000..715c4e4
--- /dev/null
@@ -0,0 +1,471 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should show full size when multiline with no editting 1`] = `
+.emotion-0 {
+  background-color: rgb(252,252,253);
+  border: 1px solid rgb(225,230,243);
+  border-radius: 0.5rem;
+  position: relative;
+  margin-top: 0.5rem;
+  margin-bottom: 0.5rem;
+}
+
+.emotion-0.code-snippet-simple-oneline {
+  margin-top: 0;
+  margin-bottom: 0;
+  border-radius: 0.25rem;
+}
+
+.emotion-4 {
+  box-sizing: border-box;
+  -webkit-text-decoration: none;
+  text-decoration: none;
+  outline: none;
+  border: var(--border);
+  color: var(--color);
+  background-color: var(--background);
+  -webkit-transition: background-color 0.2s ease,outline 0.2s ease;
+  transition: background-color 0.2s ease,outline 0.2s ease;
+  display: -webkit-inline-box;
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  -webkit-align-items: center;
+  -webkit-box-align: center;
+  -ms-flex-align: center;
+  align-items: center;
+  height: 2.25rem;
+  font-family: Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-weight: 600;
+  padding-left: 1rem;
+  padding-right: 1rem;
+  padding-top: 0.5rem;
+  padding-bottom: 0.5rem;
+  border-radius: 0.5rem;
+  cursor: pointer;
+  --background: rgb(255,255,255);
+  --backgroundHover: rgb(239,242,249);
+  --color: rgb(62,67,87);
+  --focus: rgba(197,205,223,0.2);
+  --border: 1px solid rgb(197,205,223);
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  font-family: Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-weight: 400;
+  right: 1.5rem;
+  top: 1.5rem;
+  position: absolute;
+}
+
+.emotion-4:hover {
+  color: var(--color);
+  background-color: var(--backgroundHover);
+}
+
+.emotion-4:focus,
+.emotion-4:active {
+  color: var(--color);
+  outline: 4px solid var(--focus);
+}
+
+.emotion-4:disabled,
+.emotion-4:disabled:hover {
+  color: rgb(166,173,194);
+  background-color: rgb(239,242,249);
+  border: 1px solid rgb(197,205,223);
+  cursor: not-allowed;
+}
+
+.emotion-4>svg {
+  margin-right: 0.25rem;
+}
+
+.emotion-4 [disabled] {
+  pointer-events: none;
+}
+
+.code-snippet-highlighted-oneline .emotion-4 {
+  bottom: 0.5rem;
+}
+
+.emotion-6 {
+  display: -webkit-box;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+  -webkit-box-align: center;
+  -ms-flex-align: center;
+  align-items: center;
+  overflow-x: auto;
+  padding: 1.5rem;
+}
+
+.emotion-6 code {
+  color: rgb(51,53,60);
+  background: rgb(252,252,253);
+  font-family: Ubuntu Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-weight: 400;
+}
+
+.emotion-6 code.hljs {
+  padding: unset;
+}
+
+.emotion-6 .hljs-variable,
+.emotion-6 .hljs-meta {
+  color: rgb(51,53,60);
+}
+
+.emotion-6 .hljs-doctag,
+.emotion-6 .hljs-title,
+.emotion-6 .hljs-title.class_,
+.emotion-6 .hljs-title.function_ {
+  color: rgb(34,84,192);
+}
+
+.emotion-6 .hljs-comment {
+  color: rgb(109,111,119);
+  font-family: Ubuntu Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-style: italic;
+}
+
+.emotion-6 .hljs-tag,
+.emotion-6 .hljs-type,
+.emotion-6 .hljs-keyword {
+  color: rgb(152,29,150);
+  font-family: Ubuntu Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-weight: 700;
+}
+
+.emotion-6 .hljs-literal,
+.emotion-6 .hljs-number {
+  color: rgb(126,83,5);
+}
+
+.emotion-6 .hljs-string {
+  color: rgb(32,105,31);
+}
+
+.emotion-6 .hljs-meta .hljs-keyword {
+  color: rgb(47,103,48);
+}
+
+.emotion-6.code-wrap {
+  white-space: pre-wrap;
+  word-break: break-all;
+}
+
+.emotion-6 mark {
+  color: rgb(217,45,32);
+  background-color: rgb(197,205,223);
+  font-weight: 400;
+  border-radius: 0.25rem;
+  padding: 0.25rem;
+}
+
+.emotion-6.simple-one-line {
+  min-height: 1.25rem;
+  padding-left: 0.25rem;
+  padding-right: 0.25rem;
+  padding-top: 0;
+  padding-bottom: 0;
+}
+
+<div>
+  <div
+    class="fs-mask emotion-0 emotion-1"
+  >
+    <button
+      class="sw-select-none emotion-2 emotion-3 emotion-4 emotion-5"
+      data-clipboard-text="foo
+bar"
+      type="button"
+    >
+      <svg
+        aria-hidden="true"
+        class="octicon octicon-copy"
+        fill="currentColor"
+        focusable="false"
+        height="16"
+        role="img"
+        style="display: inline-block; user-select: none; vertical-align: middle; overflow: visible;"
+        viewBox="0 0 16 16"
+        width="16"
+      >
+        <path
+          d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"
+        />
+        <path
+          d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"
+        />
+      </svg>
+      copy
+    </button>
+    <pre
+      class=" emotion-6 emotion-7"
+    >
+      <code
+        class="hljs"
+      >
+        <span
+          class="hljs-string"
+        >
+          foo
+        </span>
+        
+
+        <span
+          class="hljs-string"
+        >
+          bar
+        </span>
+      </code>
+    </pre>
+  </div>
+</div>
+`;
+
+exports[`should show reduced size when single line with no editting 1`] = `
+.emotion-0 {
+  background-color: rgb(252,252,253);
+  border: 1px solid rgb(225,230,243);
+  border-radius: 0.5rem;
+  position: relative;
+  margin-top: 0.5rem;
+  margin-bottom: 0.5rem;
+}
+
+.emotion-0.code-snippet-simple-oneline {
+  margin-top: 0;
+  margin-bottom: 0;
+  border-radius: 0.25rem;
+}
+
+.emotion-4 {
+  box-sizing: border-box;
+  -webkit-text-decoration: none;
+  text-decoration: none;
+  outline: none;
+  border: var(--border);
+  color: var(--color);
+  background-color: var(--background);
+  -webkit-transition: background-color 0.2s ease,outline 0.2s ease;
+  transition: background-color 0.2s ease,outline 0.2s ease;
+  display: -webkit-inline-box;
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  -webkit-align-items: center;
+  -webkit-box-align: center;
+  -ms-flex-align: center;
+  align-items: center;
+  height: 2.25rem;
+  font-family: Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-weight: 600;
+  padding-left: 1rem;
+  padding-right: 1rem;
+  padding-top: 0.5rem;
+  padding-bottom: 0.5rem;
+  border-radius: 0.5rem;
+  cursor: pointer;
+  --background: rgb(255,255,255);
+  --backgroundHover: rgb(239,242,249);
+  --color: rgb(62,67,87);
+  --focus: rgba(197,205,223,0.2);
+  --border: 1px solid rgb(197,205,223);
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  font-family: Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-weight: 400;
+  right: 1.5rem;
+  top: 1.5rem;
+  position: absolute;
+  bottom: 1.5rem;
+  top: 1.5rem;
+}
+
+.emotion-4:hover {
+  color: var(--color);
+  background-color: var(--backgroundHover);
+}
+
+.emotion-4:focus,
+.emotion-4:active {
+  color: var(--color);
+  outline: 4px solid var(--focus);
+}
+
+.emotion-4:disabled,
+.emotion-4:disabled:hover {
+  color: rgb(166,173,194);
+  background-color: rgb(239,242,249);
+  border: 1px solid rgb(197,205,223);
+  cursor: not-allowed;
+}
+
+.emotion-4>svg {
+  margin-right: 0.25rem;
+}
+
+.emotion-4 [disabled] {
+  pointer-events: none;
+}
+
+.code-snippet-highlighted-oneline .emotion-4 {
+  bottom: 0.5rem;
+}
+
+.emotion-6 {
+  display: -webkit-box;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+  -webkit-box-align: center;
+  -ms-flex-align: center;
+  align-items: center;
+  overflow-x: auto;
+  padding: 1.5rem;
+}
+
+.emotion-6 code {
+  color: rgb(51,53,60);
+  background: rgb(252,252,253);
+  font-family: Ubuntu Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-weight: 400;
+}
+
+.emotion-6 code.hljs {
+  padding: unset;
+}
+
+.emotion-6 .hljs-variable,
+.emotion-6 .hljs-meta {
+  color: rgb(51,53,60);
+}
+
+.emotion-6 .hljs-doctag,
+.emotion-6 .hljs-title,
+.emotion-6 .hljs-title.class_,
+.emotion-6 .hljs-title.function_ {
+  color: rgb(34,84,192);
+}
+
+.emotion-6 .hljs-comment {
+  color: rgb(109,111,119);
+  font-family: Ubuntu Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-style: italic;
+}
+
+.emotion-6 .hljs-tag,
+.emotion-6 .hljs-type,
+.emotion-6 .hljs-keyword {
+  color: rgb(152,29,150);
+  font-family: Ubuntu Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-weight: 700;
+}
+
+.emotion-6 .hljs-literal,
+.emotion-6 .hljs-number {
+  color: rgb(126,83,5);
+}
+
+.emotion-6 .hljs-string {
+  color: rgb(32,105,31);
+}
+
+.emotion-6 .hljs-meta .hljs-keyword {
+  color: rgb(47,103,48);
+}
+
+.emotion-6.code-wrap {
+  white-space: pre-wrap;
+  word-break: break-all;
+}
+
+.emotion-6 mark {
+  color: rgb(217,45,32);
+  background-color: rgb(197,205,223);
+  font-weight: 400;
+  border-radius: 0.25rem;
+  padding: 0.25rem;
+}
+
+.emotion-6.simple-one-line {
+  min-height: 1.25rem;
+  padding-left: 0.25rem;
+  padding-right: 0.25rem;
+  padding-top: 0;
+  padding-bottom: 0;
+}
+
+<div>
+  <div
+    class="code-snippet-highlighted-oneline fs-mask emotion-0 emotion-1"
+  >
+    <button
+      class="sw-select-none emotion-2 emotion-3 emotion-4 emotion-5"
+      data-clipboard-text="foobar"
+      type="button"
+    >
+      <svg
+        aria-hidden="true"
+        class="octicon octicon-copy"
+        fill="currentColor"
+        focusable="false"
+        height="16"
+        role="img"
+        style="display: inline-block; user-select: none; vertical-align: middle; overflow: visible;"
+        viewBox="0 0 16 16"
+        width="16"
+      >
+        <path
+          d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"
+        />
+        <path
+          d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"
+        />
+      </svg>
+      copy
+    </button>
+    <pre
+      class=" emotion-6 emotion-7"
+    >
+      <code
+        class="hljs"
+      >
+        <span
+          class="hljs-string"
+        >
+          foobar
+        </span>
+      </code>
+    </pre>
+  </div>
+</div>
+`;
diff --git a/server/sonar-web/design-system/src/components/__tests__/__snapshots__/Highlighter-test.tsx.snap b/server/sonar-web/design-system/src/components/__tests__/__snapshots__/Highlighter-test.tsx.snap
new file mode 100644 (file)
index 0000000..45b4dd7
--- /dev/null
@@ -0,0 +1,463 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+.emotion-0 {
+  display: -webkit-box;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+  -webkit-box-align: center;
+  -ms-flex-align: center;
+  align-items: center;
+  overflow-x: auto;
+  padding: 1.5rem;
+}
+
+.emotion-0 code {
+  color: rgb(51,53,60);
+  background: rgb(252,252,253);
+  font-family: Ubuntu Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-weight: 400;
+}
+
+.emotion-0 code.hljs {
+  padding: unset;
+}
+
+.emotion-0 .hljs-variable,
+.emotion-0 .hljs-meta {
+  color: rgb(51,53,60);
+}
+
+.emotion-0 .hljs-doctag,
+.emotion-0 .hljs-title,
+.emotion-0 .hljs-title.class_,
+.emotion-0 .hljs-title.function_ {
+  color: rgb(34,84,192);
+}
+
+.emotion-0 .hljs-comment {
+  color: rgb(109,111,119);
+  font-family: Ubuntu Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-style: italic;
+}
+
+.emotion-0 .hljs-tag,
+.emotion-0 .hljs-type,
+.emotion-0 .hljs-keyword {
+  color: rgb(152,29,150);
+  font-family: Ubuntu Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-weight: 700;
+}
+
+.emotion-0 .hljs-literal,
+.emotion-0 .hljs-number {
+  color: rgb(126,83,5);
+}
+
+.emotion-0 .hljs-string {
+  color: rgb(32,105,31);
+}
+
+.emotion-0 .hljs-meta .hljs-keyword {
+  color: rgb(47,103,48);
+}
+
+.emotion-0.code-wrap {
+  white-space: pre-wrap;
+  word-break: break-all;
+}
+
+.emotion-0 mark {
+  color: rgb(217,45,32);
+  background-color: rgb(197,205,223);
+  font-weight: 400;
+  border-radius: 0.25rem;
+  padding: 0.25rem;
+}
+
+.emotion-0.simple-one-line {
+  min-height: 1.25rem;
+  padding-left: 0.25rem;
+  padding-right: 0.25rem;
+  padding-top: 0;
+  padding-bottom: 0;
+}
+
+<div>
+  <pre
+    class=" emotion-0 emotion-1"
+  >
+    <code
+      class="hljs"
+    >
+      <span
+        class="hljs-string"
+      >
+        foo\\nbar
+      </span>
+    </code>
+  </pre>
+</div>
+`;
+
+exports[`should display edit functions 1`] = `
+.emotion-0 {
+  display: -webkit-box;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+  -webkit-box-align: center;
+  -ms-flex-align: center;
+  align-items: center;
+  overflow-x: auto;
+  padding: 1.5rem;
+}
+
+.emotion-0 code {
+  color: rgb(51,53,60);
+  background: rgb(252,252,253);
+  font-family: Ubuntu Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-weight: 400;
+}
+
+.emotion-0 code.hljs {
+  padding: unset;
+}
+
+.emotion-0 .hljs-variable,
+.emotion-0 .hljs-meta {
+  color: rgb(51,53,60);
+}
+
+.emotion-0 .hljs-doctag,
+.emotion-0 .hljs-title,
+.emotion-0 .hljs-title.class_,
+.emotion-0 .hljs-title.function_ {
+  color: rgb(34,84,192);
+}
+
+.emotion-0 .hljs-comment {
+  color: rgb(109,111,119);
+  font-family: Ubuntu Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-style: italic;
+}
+
+.emotion-0 .hljs-tag,
+.emotion-0 .hljs-type,
+.emotion-0 .hljs-keyword {
+  color: rgb(152,29,150);
+  font-family: Ubuntu Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-weight: 700;
+}
+
+.emotion-0 .hljs-literal,
+.emotion-0 .hljs-number {
+  color: rgb(126,83,5);
+}
+
+.emotion-0 .hljs-string {
+  color: rgb(32,105,31);
+}
+
+.emotion-0 .hljs-meta .hljs-keyword {
+  color: rgb(47,103,48);
+}
+
+.emotion-0.code-wrap {
+  white-space: pre-wrap;
+  word-break: break-all;
+}
+
+.emotion-0 mark {
+  color: rgb(217,45,32);
+  background-color: rgb(197,205,223);
+  font-weight: 400;
+  border-radius: 0.25rem;
+  padding: 0.25rem;
+}
+
+.emotion-0.simple-one-line {
+  min-height: 1.25rem;
+  padding-left: 0.25rem;
+  padding-right: 0.25rem;
+  padding-top: 0;
+  padding-bottom: 0;
+}
+
+.emotion-3 {
+  box-sizing: border-box;
+  border: none;
+  outline: none;
+  -webkit-text-decoration: none;
+  text-decoration: none;
+  color: var(--color);
+  background-color: var(--background);
+  -webkit-transition: background-color 0.2s ease,outline 0.2s ease,color 0.2s ease;
+  transition: background-color 0.2s ease,outline 0.2s ease,color 0.2s ease;
+  display: -webkit-inline-box;
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  -webkit-align-items: center;
+  -webkit-box-align: center;
+  -ms-flex-align: center;
+  align-items: center;
+  -webkit-box-pack: center;
+  -ms-flex-pack: center;
+  -webkit-justify-content: center;
+  justify-content: center;
+  cursor: pointer;
+  height: 2.25rem;
+  border-radius: 0.5rem;
+  padding-left: 0.625rem;
+  padding-right: 0.625rem;
+  --background: transparent;
+  --backgroundHover: rgb(232,235,255);
+  --color: rgb(75,86,187);
+  --colorHover: rgb(43,51,104);
+  --focus: rgba(93,108,208,0.2);
+}
+
+.emotion-3:hover,
+.emotion-3:focus,
+.emotion-3:active {
+  color: var(--colorHover);
+  background-color: var(--backgroundHover);
+}
+
+.emotion-3:focus,
+.emotion-3:active {
+  outline: 4px solid var(--focus);
+}
+
+.emotion-3:disabled,
+.emotion-3:disabled:hover {
+  color: rgb(166,173,194);
+  background-color: var(--background);
+  cursor: not-allowed;
+}
+
+<div>
+  <pre
+    class=" emotion-0 emotion-1"
+  >
+    <code
+      class="hljs sw-inline"
+    >
+      <span
+        class="hljs-string"
+      >
+        One
+      </span>
+       
+      <span
+        class="hljs-string"
+      >
+        line
+      </span>
+       
+      <span
+        class="hljs-string"
+      >
+        command
+      </span>
+    </code>
+    <button
+      aria-label="edit"
+      class="sw-ml-2 emotion-2 emotion-3 emotion-4"
+      type="button"
+    >
+      <svg
+        aria-hidden="true"
+        class=""
+        fill="currentColor"
+        focusable="false"
+        height="16"
+        role="img"
+        style="display: inline-block; user-select: none; vertical-align: middle; overflow: visible;"
+        viewBox="0 0 16 16"
+        width="16"
+      >
+        <path
+          d="M11.013 1.427a1.75 1.75 0 0 1 2.474 0l1.086 1.086a1.75 1.75 0 0 1 0 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 0 1-.927-.928l.929-3.25c.081-.286.235-.547.445-.758l8.61-8.61Zm.176 4.823L9.75 4.81l-6.286 6.287a.253.253 0 0 0-.064.108l-.558 1.953 1.953-.558a.253.253 0 0 0 .108-.064Zm1.238-3.763a.25.25 0 0 0-.354 0L10.811 3.75l1.439 1.44 1.263-1.263a.25.25 0 0 0 0-.354Z"
+        />
+      </svg>
+    </button>
+  </pre>
+</div>
+`;
+
+exports[`should handle multiple lines of code 1`] = `
+.emotion-0 {
+  display: -webkit-box;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+  -webkit-box-align: center;
+  -ms-flex-align: center;
+  align-items: center;
+  overflow-x: auto;
+  padding: 1.5rem;
+}
+
+.emotion-0 code {
+  color: rgb(51,53,60);
+  background: rgb(252,252,253);
+  font-family: Ubuntu Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-weight: 400;
+}
+
+.emotion-0 code.hljs {
+  padding: unset;
+}
+
+.emotion-0 .hljs-variable,
+.emotion-0 .hljs-meta {
+  color: rgb(51,53,60);
+}
+
+.emotion-0 .hljs-doctag,
+.emotion-0 .hljs-title,
+.emotion-0 .hljs-title.class_,
+.emotion-0 .hljs-title.function_ {
+  color: rgb(34,84,192);
+}
+
+.emotion-0 .hljs-comment {
+  color: rgb(109,111,119);
+  font-family: Ubuntu Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-style: italic;
+}
+
+.emotion-0 .hljs-tag,
+.emotion-0 .hljs-type,
+.emotion-0 .hljs-keyword {
+  color: rgb(152,29,150);
+  font-family: Ubuntu Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+  font-weight: 700;
+}
+
+.emotion-0 .hljs-literal,
+.emotion-0 .hljs-number {
+  color: rgb(126,83,5);
+}
+
+.emotion-0 .hljs-string {
+  color: rgb(32,105,31);
+}
+
+.emotion-0 .hljs-meta .hljs-keyword {
+  color: rgb(47,103,48);
+}
+
+.emotion-0.code-wrap {
+  white-space: pre-wrap;
+  word-break: break-all;
+}
+
+.emotion-0 mark {
+  color: rgb(217,45,32);
+  background-color: rgb(197,205,223);
+  font-weight: 400;
+  border-radius: 0.25rem;
+  padding: 0.25rem;
+}
+
+.emotion-0.simple-one-line {
+  min-height: 1.25rem;
+  padding-left: 0.25rem;
+  padding-right: 0.25rem;
+  padding-top: 0;
+  padding-bottom: 0;
+}
+
+<div>
+  <pre
+    class=" emotion-0 emotion-1"
+  >
+    <code
+      class="hljs"
+    >
+      <span
+        class="hljs-attr"
+      >
+        foo:
+      </span>
+       
+      <span
+        class="hljs-string"
+      >
+        bar
+      </span>
+      
+              
+      <span
+        class="hljs-attr"
+      >
+        pleh:
+      </span>
+       
+      <span
+        class="hljs-string"
+      >
+        help
+      </span>
+      
+              
+      <span
+        class="hljs-attr"
+      >
+        stuff:
+      </span>
+      
+               
+      <span
+        class="hljs-attr"
+      >
+        foo:
+      </span>
+       
+      <span
+        class="hljs-string"
+      >
+        bar
+      </span>
+      
+               
+      <span
+        class="hljs-attr"
+      >
+        bar:
+      </span>
+       
+      <span
+        class="hljs-string"
+      >
+        foo
+      </span>
+    </code>
+  </pre>
+</div>
+`;
diff --git a/server/sonar-web/design-system/src/components/icons/PencilIcon.tsx b/server/sonar-web/design-system/src/components/icons/PencilIcon.tsx
new file mode 100644 (file)
index 0000000..5fec48b
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import { PencilIcon as PencilOcticonIcon } from '@primer/octicons-react';
+import { OcticonHoc } from './Icon';
+
+export const PencilIcon = OcticonHoc(PencilOcticonIcon);
index ce7c413ff6342d14ff18ee6b6ef49fe800cf17f3..6f4a7a4c893874769f3b0b4936785d31d1d793fe 100644 (file)
@@ -49,6 +49,7 @@ export { OpenCloseIndicator } from './OpenCloseIndicator';
 export { OpenNewTabIcon } from './OpenNewTabIcon';
 export { OverviewQGNotComputedIcon } from './OverviewQGNotComputedIcon';
 export { OverviewQGPassedIcon } from './OverviewQGPassedIcon';
+export { PencilIcon } from './PencilIcon';
 export { ProjectIcon } from './ProjectIcon';
 export { PullRequestIcon } from './PullRequestIcon';
 export { RefreshIcon } from './RefreshIcon';
index 7fefefbfc7f2eb5b72e20cc48018646c4cf70fa4..51a75a9969cb31a899916f5918fd4b61625480ff 100644 (file)
@@ -23,6 +23,7 @@ export * from './Avatar';
 export { Badge } from './Badge';
 export { BarChart } from './BarChart';
 export * from './Card';
+export * from './CodeSnippet';
 export * from './CoverageIndicator';
 export * from './DatePicker';
 export * from './DateRangePicker';
index 7a3756efbdec70b2cc988e7ed04f88d0f381b112..4854e46adb7fe9ec3ee6cf56d622ef3e19f96d56 100644 (file)
@@ -43,6 +43,17 @@ const danger = {
   darker: COLORS.red[800],
 };
 
+const codeSnippetLight = {
+  annotations: [34, 84, 192],
+  body: [51, 53, 60],
+  constants: [126, 83, 5],
+  comments: [109, 111, 119],
+  keyword: [152, 29, 150],
+  string: [32, 105, 31],
+  'keyword-light': [28, 28, 163], // Not used currently in code snippet
+  'preprocessing-directive': [47, 103, 48],
+};
+
 export const lightTheme = {
   id: 'light-theme',
   highlightTheme: 'atom-one-light.css',
@@ -170,6 +181,15 @@ export const lightTheme = {
     codeSnippetBackground: COLORS.blueGrey[25],
     codeSnippetBorder: COLORS.blueGrey[100],
     codeSnippetHighlight: secondary.default,
+    codeSnippetBody: codeSnippetLight.body,
+    codeSnippetAnnotations: codeSnippetLight.annotations,
+    codeSnippetComments: codeSnippetLight.comments,
+    codeSnippetConstants: codeSnippetLight.constants,
+    codeSnippetKeyword: codeSnippetLight.keyword,
+    codeSnippetString: codeSnippetLight.string,
+    codeSnippetKeywordLight: codeSnippetLight['keyword-light'],
+    codeSnippetPreprocessingDirective: codeSnippetLight['preprocessing-directive'],
+    codeSnippetInline: COLORS.blueGrey[500],
 
     // code viewer
     codeLineIssueIndicator: COLORS.blueGrey[400], // Should be blueGrey[300], to be changed once code viewer is reworked
index 1847ec4d86aaee2e2f4f0d1d32382f2e6b996436..90e4d51539df1501a7f0babc8f07c44128ef2712 100644 (file)
@@ -6146,6 +6146,7 @@ __metadata:
     eslint-plugin-import: 2.27.5
     eslint-plugin-local-rules: 1.3.2
     eslint-plugin-typescript-sort-keys: 2.3.0
+    highlight.js: 11.7.0
     history: 5.3.0
     jest: 29.5.0
     postcss: 8.4.21
@@ -7839,6 +7840,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"highlight.js@npm:11.7.0":
+  version: 11.7.0
+  resolution: "highlight.js@npm:11.7.0"
+  checksum: 19e3fb8b56f4b361b057a8523b989dfeb6479bbd1e29cec3fac6fa5c78d09927d5fa61b7dba6631fdb57cfdca9b3084aa4da49405ceaf4a67f67beae2ed5b77d
+  languageName: node
+  linkType: hard
+
 "history@npm:5.3.0":
   version: 5.3.0
   resolution: "history@npm:5.3.0"