From 804a7a7d5a05ec01293c6ebfc85185b313b6670a Mon Sep 17 00:00:00 2001 From: Kevin Silva Date: Thu, 11 May 2023 14:53:21 +0200 Subject: [PATCH] SONAR-19167 - Create KeyboardHint component in DS --- .../src/components/KeyboardHint.tsx | 52 ++ .../src/components/KeyboardHintKeys.tsx | 78 +++ .../__tests__/KeyboardHint-test.tsx | 64 +++ .../__tests__/KeyboardHintKeys-test.tsx | 59 ++ .../__snapshots__/KeyboardHint-test.tsx.snap | 291 ++++++++++ .../KeyboardHintKeys-test.tsx.snap | 513 ++++++++++++++++++ .../src/components/icons/TriangleDownIcon.tsx | 23 + .../src/components/icons/TriangleLeftIcon.tsx | 23 + .../components/icons/TriangleRightIcon.tsx | 23 + .../src/components/icons/TriangleUpIcon.tsx | 23 + .../src/components/icons/index.ts | 4 + .../design-system/src/components/index.ts | 1 + .../design-system/src/helpers/keyboard.ts | 2 + .../design-system/src/theme/light.ts | 6 + 14 files changed, 1162 insertions(+) create mode 100644 server/sonar-web/design-system/src/components/KeyboardHint.tsx create mode 100644 server/sonar-web/design-system/src/components/KeyboardHintKeys.tsx create mode 100644 server/sonar-web/design-system/src/components/__tests__/KeyboardHint-test.tsx create mode 100644 server/sonar-web/design-system/src/components/__tests__/KeyboardHintKeys-test.tsx create mode 100644 server/sonar-web/design-system/src/components/__tests__/__snapshots__/KeyboardHint-test.tsx.snap create mode 100644 server/sonar-web/design-system/src/components/__tests__/__snapshots__/KeyboardHintKeys-test.tsx.snap create mode 100644 server/sonar-web/design-system/src/components/icons/TriangleDownIcon.tsx create mode 100644 server/sonar-web/design-system/src/components/icons/TriangleLeftIcon.tsx create mode 100644 server/sonar-web/design-system/src/components/icons/TriangleRightIcon.tsx create mode 100644 server/sonar-web/design-system/src/components/icons/TriangleUpIcon.tsx diff --git a/server/sonar-web/design-system/src/components/KeyboardHint.tsx b/server/sonar-web/design-system/src/components/KeyboardHint.tsx new file mode 100644 index 00000000000..cbfa57434c3 --- /dev/null +++ b/server/sonar-web/design-system/src/components/KeyboardHint.tsx @@ -0,0 +1,52 @@ +/* + * 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 tw from 'twin.macro'; +import { themeContrast } from '../helpers'; +import { Key } from '../helpers/keyboard'; +import { KeyboardHintKeys } from './KeyboardHintKeys'; + +interface Props { + command: string; + title?: string; +} + +export function KeyboardHint({ title, command }: Props) { + const normalizedCommand = command + .replace(Key.Control, isMacOS() ? 'Command' : 'Control') + .replace(Key.Alt, isMacOS() ? 'Option' : 'Alt'); + + return ( + + {title && {title}} + + + ); +} + +const Body = styled.div` + ${tw`sw-flex sw-gap-2 sw-justify-center`} + flex-wrap: wrap; + color: ${themeContrast('pageContentLight')}; +`; + +function isMacOS() { + return navigator.userAgent.toLocaleLowerCase().includes('mac os'); +} diff --git a/server/sonar-web/design-system/src/components/KeyboardHintKeys.tsx b/server/sonar-web/design-system/src/components/KeyboardHintKeys.tsx new file mode 100644 index 00000000000..7aa37f175d3 --- /dev/null +++ b/server/sonar-web/design-system/src/components/KeyboardHintKeys.tsx @@ -0,0 +1,78 @@ +/* + * 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 tw from 'twin.macro'; +import { themeColor, themeContrast } from '../helpers'; +import { Key } from '../helpers/keyboard'; +import { TriangleDownIcon, TriangleLeftIcon, TriangleRightIcon, TriangleUpIcon } from './icons'; + +const COMMAND = '⌘'; +const CTRL = 'Ctrl'; +const OPTION = '⌥'; +const ALT = 'Alt'; +const NON_KEY_SYMBOLS = ['+', ' ']; + +export function KeyboardHintKeys({ command }: { command: string }) { + const keys = command + .trim() + .split(' ') + .map((key, index) => { + const uniqueKey = `${key}-${index}`; + if (NON_KEY_SYMBOLS.includes(key)) { + return {key}; + } + + return {getKey(key)}; + }); + + return
{keys}
; +} + +export const KeyBox = styled.span` + ${tw`sw-flex sw-items-center sw-justify-center`} + ${tw`sw-px-1/2`} + ${tw`sw-rounded-1/2`} + + color: ${themeContrast('keyboardHintKey')}; + background-color: ${themeColor('keyboardHintKey')}; +`; + +function getKey(key: string) { + switch (key) { + case Key.Control: + return CTRL; + case Key.Command: + return COMMAND; + case Key.Alt: + return ALT; + case Key.Option: + return OPTION; + case Key.ArrowUp: + return ; + case Key.ArrowDown: + return ; + case Key.ArrowLeft: + return ; + case Key.ArrowRight: + return ; + default: + return key; + } +} diff --git a/server/sonar-web/design-system/src/components/__tests__/KeyboardHint-test.tsx b/server/sonar-web/design-system/src/components/__tests__/KeyboardHint-test.tsx new file mode 100644 index 00000000000..95afb94442e --- /dev/null +++ b/server/sonar-web/design-system/src/components/__tests__/KeyboardHint-test.tsx @@ -0,0 +1,64 @@ +/* + * 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 { Key } from '../../helpers/keyboard'; +import { render } from '../../helpers/testUtils'; +import { FCProps } from '../../types/misc'; +import { KeyboardHint } from '../KeyboardHint'; + +afterEach(() => { + jest.clearAllMocks(); +}); + +it('renders without title', () => { + const { container } = setupWithProps(); + expect(container).toMatchSnapshot(); +}); + +it('renders with title', () => { + const { container } = setupWithProps({ title: 'title' }); + expect(container).toMatchSnapshot(); +}); + +it('renders with command', () => { + const { container } = setupWithProps({ command: 'command' }); + expect(container).toMatchSnapshot(); +}); + +it('renders on mac', () => { + Object.defineProperty(navigator, 'userAgent', { + configurable: true, + value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4)', + }); + const { container } = setupWithProps({ command: `${Key.Control} ${Key.Alt}` }); + expect(container).toMatchSnapshot(); +}); + +it('renders on windows', () => { + Object.defineProperty(navigator, 'userAgent', { + configurable: true, + value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)', + }); + const { container } = setupWithProps({ command: `${Key.Control} ${Key.Alt}` }); + expect(container).toMatchSnapshot(); +}); + +function setupWithProps(props: Partial> = {}) { + return render(); +} diff --git a/server/sonar-web/design-system/src/components/__tests__/KeyboardHintKeys-test.tsx b/server/sonar-web/design-system/src/components/__tests__/KeyboardHintKeys-test.tsx new file mode 100644 index 00000000000..4d1ff44cede --- /dev/null +++ b/server/sonar-web/design-system/src/components/__tests__/KeyboardHintKeys-test.tsx @@ -0,0 +1,59 @@ +/* + * 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 { Key } from '../../helpers/keyboard'; +import { render } from '../../helpers/testUtils'; +import { FCProps } from '../../types/misc'; +import { KeyboardHintKeys } from '../KeyboardHintKeys'; + +it.each([ + Key.Control, + Key.Command, + Key.Alt, + Key.Option, + Key.ArrowUp, + Key.ArrowDown, + Key.ArrowLeft, + Key.ArrowRight, +])('should render %s', (key) => { + const { container } = setupWithProps({ command: key }); + expect(container).toMatchSnapshot(); +}); + +it('should render multiple keys', () => { + const { container } = setupWithProps({ command: `${Key.ArrowUp} ${Key.ArrowDown}` }); + expect(container).toMatchSnapshot(); +}); + +it('should render multiple keys with non-key symbols', () => { + const { container } = setupWithProps({ + command: `${Key.Control} + ${Key.ArrowDown} ${Key.ArrowUp}`, + }); + expect(container).toMatchSnapshot(); +}); + +it('should render a default text if no keys match', () => { + const { container } = setupWithProps({ command: `${Key.Control} + click` }); + expect(container).toMatchSnapshot(); +}); + +function setupWithProps(props: Partial> = {}) { + return render(); +} diff --git a/server/sonar-web/design-system/src/components/__tests__/__snapshots__/KeyboardHint-test.tsx.snap b/server/sonar-web/design-system/src/components/__tests__/__snapshots__/KeyboardHint-test.tsx.snap new file mode 100644 index 00000000000..081af387a40 --- /dev/null +++ b/server/sonar-web/design-system/src/components/__tests__/__snapshots__/KeyboardHint-test.tsx.snap @@ -0,0 +1,291 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders on mac 1`] = ` +.emotion-0 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + gap: 0.5rem; + -webkit-box-flex-wrap: wrap; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + color: rgb(106,117,144); +} + +.emotion-2 { + 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; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + padding-left: 0.125rem; + padding-right: 0.125rem; + border-radius: 0.125rem; + color: rgb(62,67,87); + background-color: rgb(225,230,243); +} + +
+
+
+ + ⌘ + + + ⌥ + +
+
+
+`; + +exports[`renders on windows 1`] = ` +.emotion-0 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + gap: 0.5rem; + -webkit-box-flex-wrap: wrap; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + color: rgb(106,117,144); +} + +.emotion-2 { + 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; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + padding-left: 0.125rem; + padding-right: 0.125rem; + border-radius: 0.125rem; + color: rgb(62,67,87); + background-color: rgb(225,230,243); +} + +
+
+
+ + Ctrl + + + Alt + +
+
+
+`; + +exports[`renders with command 1`] = ` +.emotion-0 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + gap: 0.5rem; + -webkit-box-flex-wrap: wrap; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + color: rgb(106,117,144); +} + +.emotion-2 { + 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; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + padding-left: 0.125rem; + padding-right: 0.125rem; + border-radius: 0.125rem; + color: rgb(62,67,87); + background-color: rgb(225,230,243); +} + +
+
+
+ + command + +
+
+
+`; + +exports[`renders with title 1`] = ` +.emotion-0 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + gap: 0.5rem; + -webkit-box-flex-wrap: wrap; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + color: rgb(106,117,144); +} + +.emotion-2 { + 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; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + padding-left: 0.125rem; + padding-right: 0.125rem; + border-radius: 0.125rem; + color: rgb(62,67,87); + background-color: rgb(225,230,243); +} + +
+
+ + title + +
+ + click + +
+
+
+`; + +exports[`renders without title 1`] = ` +.emotion-0 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + gap: 0.5rem; + -webkit-box-flex-wrap: wrap; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + color: rgb(106,117,144); +} + +.emotion-2 { + 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; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + padding-left: 0.125rem; + padding-right: 0.125rem; + border-radius: 0.125rem; + color: rgb(62,67,87); + background-color: rgb(225,230,243); +} + +
+
+
+ + click + +
+
+
+`; diff --git a/server/sonar-web/design-system/src/components/__tests__/__snapshots__/KeyboardHintKeys-test.tsx.snap b/server/sonar-web/design-system/src/components/__tests__/__snapshots__/KeyboardHintKeys-test.tsx.snap new file mode 100644 index 00000000000..907e3994ef0 --- /dev/null +++ b/server/sonar-web/design-system/src/components/__tests__/__snapshots__/KeyboardHintKeys-test.tsx.snap @@ -0,0 +1,513 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render Alt 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; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + padding-left: 0.125rem; + padding-right: 0.125rem; + border-radius: 0.125rem; + color: rgb(62,67,87); + background-color: rgb(225,230,243); +} + +
+
+ + Alt + +
+
+`; + +exports[`should render ArrowDown 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; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + padding-left: 0.125rem; + padding-right: 0.125rem; + border-radius: 0.125rem; + color: rgb(62,67,87); + background-color: rgb(225,230,243); +} + +
+
+ + + +
+
+`; + +exports[`should render ArrowLeft 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; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + padding-left: 0.125rem; + padding-right: 0.125rem; + border-radius: 0.125rem; + color: rgb(62,67,87); + background-color: rgb(225,230,243); +} + +
+
+ + + +
+
+`; + +exports[`should render ArrowRight 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; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + padding-left: 0.125rem; + padding-right: 0.125rem; + border-radius: 0.125rem; + color: rgb(62,67,87); + background-color: rgb(225,230,243); +} + +
+
+ + + +
+
+`; + +exports[`should render ArrowUp 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; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + padding-left: 0.125rem; + padding-right: 0.125rem; + border-radius: 0.125rem; + color: rgb(62,67,87); + background-color: rgb(225,230,243); +} + +
+
+ + + +
+
+`; + +exports[`should render Command 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; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + padding-left: 0.125rem; + padding-right: 0.125rem; + border-radius: 0.125rem; + color: rgb(62,67,87); + background-color: rgb(225,230,243); +} + +
+
+ + ⌘ + +
+
+`; + +exports[`should render Control 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; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + padding-left: 0.125rem; + padding-right: 0.125rem; + border-radius: 0.125rem; + color: rgb(62,67,87); + background-color: rgb(225,230,243); +} + +
+
+ + Ctrl + +
+
+`; + +exports[`should render Option 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; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + padding-left: 0.125rem; + padding-right: 0.125rem; + border-radius: 0.125rem; + color: rgb(62,67,87); + background-color: rgb(225,230,243); +} + +
+
+ + ⌥ + +
+
+`; + +exports[`should render a default text if no keys match 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; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + padding-left: 0.125rem; + padding-right: 0.125rem; + border-radius: 0.125rem; + color: rgb(62,67,87); + background-color: rgb(225,230,243); +} + +
+
+ + Ctrl + + + + + + + click + +
+
+`; + +exports[`should render multiple keys 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; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + padding-left: 0.125rem; + padding-right: 0.125rem; + border-radius: 0.125rem; + color: rgb(62,67,87); + background-color: rgb(225,230,243); +} + +
+
+ + + + + + +
+
+`; + +exports[`should render multiple keys with non-key symbols 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; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + padding-left: 0.125rem; + padding-right: 0.125rem; + border-radius: 0.125rem; + color: rgb(62,67,87); + background-color: rgb(225,230,243); +} + +
+
+ + Ctrl + + + + + + + + + + + +
+
+`; diff --git a/server/sonar-web/design-system/src/components/icons/TriangleDownIcon.tsx b/server/sonar-web/design-system/src/components/icons/TriangleDownIcon.tsx new file mode 100644 index 00000000000..44c8cc5c630 --- /dev/null +++ b/server/sonar-web/design-system/src/components/icons/TriangleDownIcon.tsx @@ -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 { TriangleDownIcon as Octicon } from '@primer/octicons-react'; +import { OcticonHoc } from './Icon'; + +export const TriangleDownIcon = OcticonHoc(Octicon); diff --git a/server/sonar-web/design-system/src/components/icons/TriangleLeftIcon.tsx b/server/sonar-web/design-system/src/components/icons/TriangleLeftIcon.tsx new file mode 100644 index 00000000000..2b2e0f29619 --- /dev/null +++ b/server/sonar-web/design-system/src/components/icons/TriangleLeftIcon.tsx @@ -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 { TriangleLeftIcon as Octicon } from '@primer/octicons-react'; +import { OcticonHoc } from './Icon'; + +export const TriangleLeftIcon = OcticonHoc(Octicon); diff --git a/server/sonar-web/design-system/src/components/icons/TriangleRightIcon.tsx b/server/sonar-web/design-system/src/components/icons/TriangleRightIcon.tsx new file mode 100644 index 00000000000..fd8dc00aa1a --- /dev/null +++ b/server/sonar-web/design-system/src/components/icons/TriangleRightIcon.tsx @@ -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 { TriangleRightIcon as Octicon } from '@primer/octicons-react'; +import { OcticonHoc } from './Icon'; + +export const TriangleRightIcon = OcticonHoc(Octicon); diff --git a/server/sonar-web/design-system/src/components/icons/TriangleUpIcon.tsx b/server/sonar-web/design-system/src/components/icons/TriangleUpIcon.tsx new file mode 100644 index 00000000000..9f192daf12b --- /dev/null +++ b/server/sonar-web/design-system/src/components/icons/TriangleUpIcon.tsx @@ -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 { TriangleUpIcon as Octicon } from '@primer/octicons-react'; +import { OcticonHoc } from './Icon'; + +export const TriangleUpIcon = OcticonHoc(Octicon); diff --git a/server/sonar-web/design-system/src/components/icons/index.ts b/server/sonar-web/design-system/src/components/icons/index.ts index 114132d4710..3b23d108df4 100644 --- a/server/sonar-web/design-system/src/components/icons/index.ts +++ b/server/sonar-web/design-system/src/components/icons/index.ts @@ -61,6 +61,10 @@ export { StatusConfirmedIcon } from './StatusConfirmedIcon'; export { StatusOpenIcon } from './StatusOpenIcon'; export { StatusReopenedIcon } from './StatusReopenedIcon'; export { StatusResolvedIcon } from './StatusResolvedIcon'; +export { TriangleDownIcon } from './TriangleDownIcon'; +export { TriangleLeftIcon } from './TriangleLeftIcon'; +export { TriangleRightIcon } from './TriangleRightIcon'; +export { TriangleUpIcon } from './TriangleUpIcon'; export { UnfoldDownIcon } from './UnfoldDownIcon'; export { UnfoldIcon } from './UnfoldIcon'; export { UnfoldUpIcon } from './UnfoldUpIcon'; diff --git a/server/sonar-web/design-system/src/components/index.ts b/server/sonar-web/design-system/src/components/index.ts index 83f42811301..1859acdfaba 100644 --- a/server/sonar-web/design-system/src/components/index.ts +++ b/server/sonar-web/design-system/src/components/index.ts @@ -40,6 +40,7 @@ export { HotspotRating } from './HotspotRating'; export { InputSearch } from './InputSearch'; export * from './InputSelect'; export * from './InteractiveIcon'; +export * from './KeyboardHint'; export * from './Link'; export { StandoutLink as Link } from './Link'; export * from './MainAppBar'; diff --git a/server/sonar-web/design-system/src/helpers/keyboard.ts b/server/sonar-web/design-system/src/helpers/keyboard.ts index 42bc6bdf52e..37b26e3cb2e 100644 --- a/server/sonar-web/design-system/src/helpers/keyboard.ts +++ b/server/sonar-web/design-system/src/helpers/keyboard.ts @@ -24,10 +24,12 @@ export enum Key { ArrowDown = 'ArrowDown', Alt = 'Alt', + Option = 'Option', Backspace = 'Backspace', CapsLock = 'CapsLock', Meta = 'Meta', Control = 'Control', + Command = 'Command', Delete = 'Delete', End = 'End', Enter = 'Enter', diff --git a/server/sonar-web/design-system/src/theme/light.ts b/server/sonar-web/design-system/src/theme/light.ts index 6a2f8bd5e95..24cd71f3ea3 100644 --- a/server/sonar-web/design-system/src/theme/light.ts +++ b/server/sonar-web/design-system/src/theme/light.ts @@ -472,6 +472,9 @@ export const lightTheme = { // project analyse page almCardBorder: COLORS.grey[100], + + // Keyboard hint + keyboardHintKey: COLORS.blueGrey[100], }, // contrast colors to be used for text when using a color background with the same name @@ -657,6 +660,9 @@ export const lightTheme = { newsTag: COLORS.blueGrey[500], roadmap: COLORS.blueGrey[600], roadmapContent: COLORS.blueGrey[500], + + // Keyboard hint + keyboardHintKey: COLORS.blueGrey[500], }, // predefined shadows -- 2.39.5