aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorRevanshu Paliwal <revanshu.paliwal@sonarsource.com>2023-06-27 12:16:58 +0200
committersonartech <sonartech@sonarsource.com>2023-07-04 20:03:09 +0000
commita2124bcdd58dadee846cb87eaa77f4d9c2cd331a (patch)
tree2a433f281d7bbc7a6b16841b7a09fabd0eefb56f /server
parentebece82669c46e8657d10407ee1d5dc957af3a6c (diff)
downloadsonarqube-a2124bcdd58dadee846cb87eaa77f4d9c2cd331a.tar.gz
sonarqube-a2124bcdd58dadee846cb87eaa77f4d9c2cd331a.zip
[NO-JIRA] Design system refactor: inputs and buttons
Diffstat (limited to 'server')
-rw-r--r--server/sonar-web/design-system/src/components/ColorsLegend.tsx5
-rw-r--r--server/sonar-web/design-system/src/components/DropdownMenu.tsx4
-rw-r--r--server/sonar-web/design-system/src/components/SelectionCard.tsx2
-rw-r--r--server/sonar-web/design-system/src/components/TagsSelector.tsx2
-rw-r--r--server/sonar-web/design-system/src/components/buttons.tsx314
-rw-r--r--server/sonar-web/design-system/src/components/buttons/BareButtons.tsx89
-rw-r--r--server/sonar-web/design-system/src/components/buttons/Button.tsx163
-rw-r--r--server/sonar-web/design-system/src/components/buttons/ButtonPrimary.tsx37
-rw-r--r--server/sonar-web/design-system/src/components/buttons/ButtonSecondary.tsx36
-rw-r--r--server/sonar-web/design-system/src/components/buttons/DangerButtonPrimary.tsx31
-rw-r--r--server/sonar-web/design-system/src/components/buttons/DangerButtonSecondary.tsx37
-rw-r--r--server/sonar-web/design-system/src/components/buttons/DownloadButton.tsx30
-rw-r--r--server/sonar-web/design-system/src/components/buttons/ThirdPartyButton.tsx48
-rw-r--r--server/sonar-web/design-system/src/components/buttons/WrapperButton.tsx31
-rw-r--r--server/sonar-web/design-system/src/components/buttons/__tests__/buttons-test.tsx (renamed from server/sonar-web/design-system/src/components/__tests__/buttons-test.tsx)4
-rw-r--r--server/sonar-web/design-system/src/components/buttons/index.ts47
-rw-r--r--server/sonar-web/design-system/src/components/index.ts14
-rw-r--r--server/sonar-web/design-system/src/components/input/Checkbox.tsx (renamed from server/sonar-web/design-system/src/components/Checkbox.tsx)8
-rw-r--r--server/sonar-web/design-system/src/components/input/DatePicker.tsx (renamed from server/sonar-web/design-system/src/components/DatePicker.tsx)18
-rw-r--r--server/sonar-web/design-system/src/components/input/DateRangePicker.tsx (renamed from server/sonar-web/design-system/src/components/DateRangePicker.tsx)4
-rw-r--r--server/sonar-web/design-system/src/components/input/DiscreetSelect.tsx (renamed from server/sonar-web/design-system/src/components/DiscreetSelect.tsx)4
-rw-r--r--server/sonar-web/design-system/src/components/input/FormField.tsx (renamed from server/sonar-web/design-system/src/components/FormField.tsx)4
-rw-r--r--server/sonar-web/design-system/src/components/input/InputField.tsx (renamed from server/sonar-web/design-system/src/components/InputField.tsx)6
-rw-r--r--server/sonar-web/design-system/src/components/input/InputMultiSelect.tsx (renamed from server/sonar-web/design-system/src/components/InputMultiSelect.tsx)10
-rw-r--r--server/sonar-web/design-system/src/components/input/InputSearch.tsx (renamed from server/sonar-web/design-system/src/components/InputSearch.tsx)18
-rw-r--r--server/sonar-web/design-system/src/components/input/InputSelect.tsx (renamed from server/sonar-web/design-system/src/components/InputSelect.tsx)10
-rw-r--r--server/sonar-web/design-system/src/components/input/MultiSelectMenu.tsx (renamed from server/sonar-web/design-system/src/components/MultiSelectMenu.tsx)10
-rw-r--r--server/sonar-web/design-system/src/components/input/MultiSelectMenuOption.tsx (renamed from server/sonar-web/design-system/src/components/MultiSelectMenuOption.tsx)2
-rw-r--r--server/sonar-web/design-system/src/components/input/RadioButton.tsx (renamed from server/sonar-web/design-system/src/components/RadioButton.tsx)2
-rw-r--r--server/sonar-web/design-system/src/components/input/SearchSelect.tsx (renamed from server/sonar-web/design-system/src/components/SearchSelect.tsx)6
-rw-r--r--server/sonar-web/design-system/src/components/input/SearchSelectDropdown.tsx (renamed from server/sonar-web/design-system/src/components/SearchSelectDropdown.tsx)8
-rw-r--r--server/sonar-web/design-system/src/components/input/SearchSelectDropdownControl.tsx (renamed from server/sonar-web/design-system/src/components/SearchSelectDropdownControl.tsx)8
-rw-r--r--server/sonar-web/design-system/src/components/input/__tests__/DatePicker-test.tsx (renamed from server/sonar-web/design-system/src/components/__tests__/DatePicker-test.tsx)2
-rw-r--r--server/sonar-web/design-system/src/components/input/__tests__/DateRangePicker-test.tsx (renamed from server/sonar-web/design-system/src/components/__tests__/DateRangePicker-test.tsx)2
-rw-r--r--server/sonar-web/design-system/src/components/input/__tests__/DiscreetSelect-test.tsx (renamed from server/sonar-web/design-system/src/components/__tests__/DiscreetSelect-test.tsx)4
-rw-r--r--server/sonar-web/design-system/src/components/input/__tests__/FormField-test.tsx (renamed from server/sonar-web/design-system/src/components/__tests__/FormField-test.tsx)2
-rw-r--r--server/sonar-web/design-system/src/components/input/__tests__/InputField-test.tsx (renamed from server/sonar-web/design-system/src/components/__tests__/InputField-test.tsx)0
-rw-r--r--server/sonar-web/design-system/src/components/input/__tests__/InputMultiSelect-test.tsx (renamed from server/sonar-web/design-system/src/components/__tests__/InputMultiSelect-test.tsx)2
-rw-r--r--server/sonar-web/design-system/src/components/input/__tests__/InputSearch-test.tsx (renamed from server/sonar-web/design-system/src/components/__tests__/InputSearch-test.tsx)4
-rw-r--r--server/sonar-web/design-system/src/components/input/__tests__/InputSelect-test.tsx (renamed from server/sonar-web/design-system/src/components/__tests__/InputSelect-test.tsx)4
-rw-r--r--server/sonar-web/design-system/src/components/input/__tests__/MultiSelectMenu-test.tsx (renamed from server/sonar-web/design-system/src/components/__tests__/MultiSelectMenu-test.tsx)0
-rw-r--r--server/sonar-web/design-system/src/components/input/__tests__/RadioButton-test.tsx (renamed from server/sonar-web/design-system/src/components/__tests__/RadioButton-test.tsx)4
-rw-r--r--server/sonar-web/design-system/src/components/input/__tests__/SearchSelectDropdown-test.tsx (renamed from server/sonar-web/design-system/src/components/__tests__/SearchSelectDropdown-test.tsx)4
-rw-r--r--server/sonar-web/design-system/src/components/input/index.ts32
44 files changed, 664 insertions, 408 deletions
diff --git a/server/sonar-web/design-system/src/components/ColorsLegend.tsx b/server/sonar-web/design-system/src/components/ColorsLegend.tsx
index c5f6e2f1082..5b5ed6d8555 100644
--- a/server/sonar-web/design-system/src/components/ColorsLegend.tsx
+++ b/server/sonar-web/design-system/src/components/ColorsLegend.tsx
@@ -20,11 +20,10 @@
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import tw from 'twin.macro';
+import { themeBorder, themeColor, themeContrast } from '../helpers';
import { BubbleColorVal } from '../types/charts';
-import { Checkbox } from './Checkbox';
import Tooltip from './Tooltip';
-
-import { themeBorder, themeColor, themeContrast } from '../helpers';
+import { Checkbox } from './input/Checkbox';
export interface ColorFilterOption {
ariaLabel?: string;
diff --git a/server/sonar-web/design-system/src/components/DropdownMenu.tsx b/server/sonar-web/design-system/src/components/DropdownMenu.tsx
index 74c41581703..d6cd692bac0 100644
--- a/server/sonar-web/design-system/src/components/DropdownMenu.tsx
+++ b/server/sonar-web/design-system/src/components/DropdownMenu.tsx
@@ -25,12 +25,12 @@ import tw from 'twin.macro';
import { INPUT_SIZES } from '../helpers/constants';
import { themeBorder, themeColor, themeContrast } from '../helpers/theme';
import { InputSizeKeys, ThemedProps } from '../types/theme';
-import { Checkbox } from './Checkbox';
import { BaseLink, LinkProps } from './Link';
import NavLink from './NavLink';
-import { RadioButton } from './RadioButton';
import Tooltip from './Tooltip';
import { ClipboardBase } from './clipboard';
+import { Checkbox } from './input/Checkbox';
+import { RadioButton } from './input/RadioButton';
interface Props extends React.HtmlHTMLAttributes<HTMLMenuElement> {
children?: React.ReactNode;
diff --git a/server/sonar-web/design-system/src/components/SelectionCard.tsx b/server/sonar-web/design-system/src/components/SelectionCard.tsx
index 31df423e578..41c5541a3ea 100644
--- a/server/sonar-web/design-system/src/components/SelectionCard.tsx
+++ b/server/sonar-web/design-system/src/components/SelectionCard.tsx
@@ -22,9 +22,9 @@ import classNames from 'classnames';
import tw from 'twin.macro';
import { translate } from '../helpers/l10n';
import { themeBorder, themeColor, themeContrast, themeShadow } from '../helpers/theme';
-import { RadioButtonStyled } from './RadioButton';
import { LightLabel } from './Text';
import { RecommendedIcon } from './icons/RecommendedIcon';
+import { RadioButtonStyled } from './input/RadioButton';
export interface SelectionCardProps {
children?: React.ReactNode;
diff --git a/server/sonar-web/design-system/src/components/TagsSelector.tsx b/server/sonar-web/design-system/src/components/TagsSelector.tsx
index 9a748075138..4e1f7b47f70 100644
--- a/server/sonar-web/design-system/src/components/TagsSelector.tsx
+++ b/server/sonar-web/design-system/src/components/TagsSelector.tsx
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { MultiSelectMenu } from './MultiSelectMenu';
+import { MultiSelectMenu } from './input/MultiSelectMenu';
interface Props {
allowNewElements?: boolean;
diff --git a/server/sonar-web/design-system/src/components/buttons.tsx b/server/sonar-web/design-system/src/components/buttons.tsx
deleted file mode 100644
index e71a3cee200..00000000000
--- a/server/sonar-web/design-system/src/components/buttons.tsx
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * 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 { css } from '@emotion/react';
-import styled from '@emotion/styled';
-import React from 'react';
-import tw from 'twin.macro';
-import { OPACITY_20_PERCENT } from '../helpers/constants';
-import { themeBorder, themeColor, themeContrast } from '../helpers/theme';
-import { ThemedProps } from '../types/theme';
-import { BaseLink, LinkProps } from './Link';
-
-type AllowedButtonAttributes = Pick<
- React.ButtonHTMLAttributes<HTMLButtonElement>,
- 'aria-label' | 'autoFocus' | 'id' | 'name' | 'role' | 'style' | 'title' | 'type' | 'form'
->;
-
-export interface ButtonProps extends AllowedButtonAttributes {
- children?: React.ReactNode;
- className?: string;
- disabled?: boolean;
- download?: string;
- icon?: React.ReactNode;
- innerRef?: React.Ref<HTMLButtonElement>;
- isExternal?: LinkProps['isExternal'];
- onClick?: (event?: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => unknown;
-
- preventDefault?: boolean;
- reloadDocument?: LinkProps['reloadDocument'];
- stopPropagation?: boolean;
- target?: LinkProps['target'];
- to?: LinkProps['to'];
-}
-
-class Button extends React.PureComponent<ButtonProps> {
- handleClick = (event: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => {
- const { disabled, onClick, stopPropagation = false, type } = this.props;
- const { preventDefault = type !== 'submit' } = this.props;
-
- if (preventDefault || disabled) {
- event.preventDefault();
- }
-
- if (stopPropagation) {
- event.stopPropagation();
- }
-
- if (onClick && !disabled) {
- onClick(event);
- }
- };
-
- render() {
- const {
- children,
- disabled,
- icon,
- innerRef,
- onClick,
- preventDefault,
- stopPropagation,
- to,
- type = 'button',
- ...htmlProps
- } = this.props;
-
- const props = {
- ...htmlProps,
- 'aria-disabled': disabled,
- disabled,
- type,
- };
-
- if (to) {
- return (
- <BaseButtonLink {...props} onClick={onClick} to={to}>
- {icon}
- {children}
- </BaseButtonLink>
- );
- }
-
- return (
- <BaseButton {...props} onClick={this.handleClick} ref={innerRef}>
- {icon}
- {children}
- </BaseButton>
- );
- }
-}
-
-const buttonStyle = (props: ThemedProps) => css`
- box-sizing: border-box;
- text-decoration: none;
- outline: none;
- border: var(--border);
- color: var(--color);
- background-color: var(--background);
- transition: background-color 0.2s ease, outline 0.2s ease;
-
- ${tw`sw-inline-flex sw-items-center`}
- ${tw`sw-h-control`}
- ${tw`sw-body-sm-highlight`}
- ${tw`sw-py-2 sw-px-4`}
- ${tw`sw-rounded-2`}
- ${tw`sw-cursor-pointer`}
-
- &:hover {
- color: var(--color);
- background-color: var(--backgroundHover);
- }
-
- &:focus,
- &:active {
- color: var(--color);
- outline: ${themeBorder('focus', 'var(--focus)')(props)};
- }
-
- &:disabled,
- &:disabled:hover {
- color: ${themeContrast('buttonDisabled')(props)};
- background-color: ${themeColor('buttonDisabled')(props)};
- border: ${themeBorder('default', 'buttonDisabledBorder')(props)};
-
- ${tw`sw-cursor-not-allowed`}
- }
-
- & > svg {
- ${tw`sw-mr-1`}
- }
-`;
-
-const BaseButtonLink = styled(BaseLink)`
- ${buttonStyle}
-`;
-
-const BaseButton = styled.button`
- ${buttonStyle}
-
- /* Workaround for tooltips issue with onMouseLeave in disabled buttons: https://github.com/facebook/react/issues/4251 */
- & [disabled] {
- ${tw`sw-pointer-events-none`};
- }
-`;
-
-const PrimaryStyle = (props: ThemedProps) => css`
- background: ${themeColor('button')(props)};
- backgroundhover: ${themeColor('buttonHover')(props)};
- color: ${themeContrast('primary')(props)};
- focus: ${themeColor('button', OPACITY_20_PERCENT)(props)};
- border: ${themeBorder('default', 'transparent')(props)};
-`;
-
-export const ButtonPrimary: React.FC<ButtonProps> = styled(Button)`
- ${PrimaryStyle}
-`;
-
-export const DownloadButton = styled.a`
- ${buttonStyle}
- ${PrimaryStyle}
- &:hover {
- border-bottom-color: transparent;
- }
-`;
-
-export const ButtonSecondary: React.FC<ButtonProps> = styled(Button)`
- --background: ${themeColor('buttonSecondary')};
- --backgroundHover: ${themeColor('buttonSecondaryHover')};
- --color: ${themeContrast('buttonSecondary')};
- --focus: ${themeColor('buttonSecondaryBorder', OPACITY_20_PERCENT)};
- --border: ${themeBorder('default', 'buttonSecondaryBorder')};
-
- &:hover,
- &:active,
- &:focus {
- border-color: ${themeColor('buttonSecondaryBorder')};
- }
-`;
-
-export const DangerButtonPrimary: React.FC<ButtonProps> = styled(Button)`
- --background: ${themeColor('dangerButton')};
- --backgroundHover: ${themeColor('dangerButtonHover')};
- --color: ${themeContrast('dangerButton')};
- --focus: ${themeColor('dangerButtonFocus', OPACITY_20_PERCENT)};
- --border: ${themeBorder('default', 'transparent')};
-`;
-
-export const DangerButtonSecondary: React.FC<ButtonProps> = styled(Button)`
- --background: ${themeColor('dangerButtonSecondary')};
- --backgroundHover: ${themeColor('dangerButtonSecondaryHover')};
- --color: ${themeContrast('dangerButtonSecondary')};
- --focus: ${themeColor('dangerButtonSecondaryFocus', OPACITY_20_PERCENT)};
- --border: ${themeBorder('default', 'dangerButtonSecondaryBorder')};
-
- &:hover,
- &:active,
- &:focus {
- border-color: ${themeColor('dangerButtonSecondaryBorder')};
- }
-`;
-
-export const WrapperButton: React.FC<ButtonProps> = styled(Button)`
- --background: none;
- --backgroundHover: none;
- --color: none;
- --focus: ${themeColor('button', OPACITY_20_PERCENT)};
- --border: none;
-`;
-
-interface ThirdPartyProps extends Omit<ButtonProps, 'Icon'> {
- iconPath: string;
- name: string;
-}
-
-export function ThirdPartyButton({ children, iconPath, name, ...buttonProps }: ThirdPartyProps) {
- const size = 16;
- return (
- <ThirdPartyButtonStyled {...buttonProps}>
- <img alt={name} className="sw-mr-1" height={size} src={iconPath} width={size} />
- {children}
- </ThirdPartyButtonStyled>
- );
-}
-
-const ThirdPartyButtonStyled: React.FC<ButtonProps> = styled(Button)`
- --background: ${themeColor('thirdPartyButton')};
- --backgroundHover: ${themeColor('thirdPartyButtonHover')};
- --color: ${themeContrast('thirdPartyButton')};
- --focus: ${themeColor('thirdPartyButtonBorder', OPACITY_20_PERCENT)};
- --border: ${themeBorder('default', 'thirdPartyButtonBorder')};
-`;
-
-export const BareButton = styled.button`
- all: unset;
- cursor: pointer;
-
- &:focus-visible {
- background-color: ${themeColor('dropdownMenuHover')};
- }
-`;
-
-interface CodeViewerExpanderProps {
- direction: 'UP' | 'DOWN';
-}
-
-export const CodeViewerExpander = styled(BareButton)<CodeViewerExpanderProps>`
- ${tw`sw-flex sw-items-center sw-gap-2`}
- ${tw`sw-px-2 sw-py-1`}
- ${tw`sw-code`}
- ${tw`sw-w-full`}
- ${tw`sw-box-border`}
-
- color: ${themeContrast('codeLineEllipsis')};
- background-color: ${themeColor('codeLineEllipsis')};
-
- &:hover {
- color: ${themeContrast('codeLineEllipsisHover')};
- background-color: ${themeColor('codeLineEllipsisHover')};
- }
-
- border-top: ${(props) =>
- props.direction === 'DOWN' ? themeBorder('default', 'codeLineBorder') : 'none'};
-
- border-bottom: ${(props) =>
- props.direction === 'UP' ? themeBorder('default', 'codeLineBorder') : 'none'};
-`;
-
-export const IssueIndicatorButton = styled(BareButton)`
- color: ${themeColor('codeLineMeta')};
- text-decoration: none;
-
- ${tw`sw-whitespace-nowrap`}
-`;
-
-export const DuplicationBlock = styled(BareButton)`
- background-color: ${themeColor('codeLineDuplication')};
- outline: none;
-
- ${tw`sw-block`}
- ${tw`sw-w-1 sw-h-full`}
- ${tw`sw-ml-1/2`}
- ${tw`sw-cursor-pointer`}
-`;
-
-export const LineSCMStyled = styled(BareButton)`
- outline: none;
-
- ${tw`sw-pr-2`}
- ${tw`sw-truncate`}
- ${tw`sw-whitespace-nowrap`}
- ${tw`sw-cursor-pointer`}
- ${tw`sw-w-full sw-h-full`}
-
-&:hover {
- color: ${themeColor('codeLineMetaHover')};
- }
-`;
diff --git a/server/sonar-web/design-system/src/components/buttons/BareButtons.tsx b/server/sonar-web/design-system/src/components/buttons/BareButtons.tsx
new file mode 100644
index 00000000000..2d3842daa3b
--- /dev/null
+++ b/server/sonar-web/design-system/src/components/buttons/BareButtons.tsx
@@ -0,0 +1,89 @@
+/*
+ * 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 { themeBorder, themeColor, themeContrast } from '../../helpers';
+
+export const BareButton = styled.button`
+ all: unset;
+ cursor: pointer;
+
+ &:focus-visible {
+ background-color: ${themeColor('dropdownMenuHover')};
+ }
+`;
+
+interface CodeViewerExpanderProps {
+ direction: 'UP' | 'DOWN';
+}
+
+export const CodeViewerExpander = styled(BareButton)<CodeViewerExpanderProps>`
+ ${tw`sw-flex sw-items-center sw-gap-2`}
+ ${tw`sw-px-2 sw-py-1`}
+ ${tw`sw-code`}
+ ${tw`sw-w-full`}
+ ${tw`sw-box-border`}
+
+ color: ${themeContrast('codeLineEllipsis')};
+ background-color: ${themeColor('codeLineEllipsis')};
+
+ &:hover {
+ color: ${themeContrast('codeLineEllipsisHover')};
+ background-color: ${themeColor('codeLineEllipsisHover')};
+ }
+
+ border-top: ${(props) =>
+ props.direction === 'DOWN' ? themeBorder('default', 'codeLineBorder') : 'none'};
+
+ border-bottom: ${(props) =>
+ props.direction === 'UP' ? themeBorder('default', 'codeLineBorder') : 'none'};
+`;
+
+export const IssueIndicatorButton = styled(BareButton)`
+ color: ${themeColor('codeLineMeta')};
+ text-decoration: none;
+
+ ${tw`sw-whitespace-nowrap`}
+`;
+
+export const DuplicationBlock = styled(BareButton)`
+ background-color: ${themeColor('codeLineDuplication')};
+ outline: none;
+
+ ${tw`sw-block`}
+ ${tw`sw-w-1 sw-h-full`}
+ ${tw`sw-ml-1/2`}
+ ${tw`sw-cursor-pointer`}
+`;
+
+export const LineSCMStyled = styled(BareButton)`
+ outline: none;
+
+ ${tw`sw-pr-2`}
+ ${tw`sw-truncate`}
+ ${tw`sw-whitespace-nowrap`}
+ ${tw`sw-cursor-pointer`}
+ ${tw`sw-w-full sw-h-full`}
+
+&:hover {
+ color: ${themeColor('codeLineMetaHover')};
+ }
+`;
diff --git a/server/sonar-web/design-system/src/components/buttons/Button.tsx b/server/sonar-web/design-system/src/components/buttons/Button.tsx
new file mode 100644
index 00000000000..3a969b0a1ff
--- /dev/null
+++ b/server/sonar-web/design-system/src/components/buttons/Button.tsx
@@ -0,0 +1,163 @@
+/*
+ * 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 { css } from '@emotion/react';
+import styled from '@emotion/styled';
+import React from 'react';
+import tw from 'twin.macro';
+import { themeBorder, themeColor, themeContrast } from '../../helpers/theme';
+import { ThemedProps } from '../../types/theme';
+import { BaseLink, LinkProps } from '../Link';
+
+type AllowedButtonAttributes = Pick<
+ React.ButtonHTMLAttributes<HTMLButtonElement>,
+ 'aria-label' | 'autoFocus' | 'id' | 'name' | 'role' | 'style' | 'title' | 'type' | 'form'
+>;
+
+export interface ButtonProps extends AllowedButtonAttributes {
+ children?: React.ReactNode;
+ className?: string;
+ disabled?: boolean;
+ download?: string;
+ icon?: React.ReactNode;
+ innerRef?: React.Ref<HTMLButtonElement>;
+ isExternal?: LinkProps['isExternal'];
+ onClick?: (event?: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => unknown;
+
+ preventDefault?: boolean;
+ reloadDocument?: LinkProps['reloadDocument'];
+ stopPropagation?: boolean;
+ target?: LinkProps['target'];
+ to?: LinkProps['to'];
+}
+
+export class Button extends React.PureComponent<ButtonProps> {
+ handleClick = (event: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => {
+ const { disabled, onClick, stopPropagation = false, type } = this.props;
+ const { preventDefault = type !== 'submit' } = this.props;
+
+ if (preventDefault || disabled) {
+ event.preventDefault();
+ }
+
+ if (stopPropagation) {
+ event.stopPropagation();
+ }
+
+ if (onClick && !disabled) {
+ onClick(event);
+ }
+ };
+
+ render() {
+ const {
+ children,
+ disabled,
+ icon,
+ innerRef,
+ onClick,
+ preventDefault,
+ stopPropagation,
+ to,
+ type = 'button',
+ ...htmlProps
+ } = this.props;
+
+ const props = {
+ ...htmlProps,
+ 'aria-disabled': disabled,
+ disabled,
+ type,
+ };
+
+ if (to) {
+ return (
+ <BaseButtonLink {...props} onClick={onClick} to={to}>
+ {icon}
+ {children}
+ </BaseButtonLink>
+ );
+ }
+
+ return (
+ <BaseButton {...props} onClick={this.handleClick} ref={innerRef}>
+ {icon}
+ {children}
+ </BaseButton>
+ );
+ }
+}
+
+export const buttonStyle = (props: ThemedProps) => css`
+ box-sizing: border-box;
+ text-decoration: none;
+ outline: none;
+ border: var(--border);
+ color: var(--color);
+ background-color: var(--background);
+ transition: background-color 0.2s ease, outline 0.2s ease;
+
+ ${tw`sw-inline-flex sw-items-center`}
+ ${tw`sw-h-control`}
+ ${tw`sw-body-sm-highlight`}
+ ${tw`sw-py-2 sw-px-4`}
+ ${tw`sw-rounded-2`}
+ ${tw`sw-cursor-pointer`}
+
+ &:hover {
+ color: var(--color);
+ background-color: var(--backgroundHover);
+ }
+
+ &:focus,
+ &:active {
+ color: var(--color);
+ outline: ${themeBorder('focus', 'var(--focus)')(props)};
+ }
+
+ &:disabled,
+ &:disabled:hover {
+ color: ${themeContrast('buttonDisabled')(props)};
+ background-color: ${themeColor('buttonDisabled')(props)};
+ border: ${themeBorder('default', 'buttonDisabledBorder')(props)};
+
+ ${tw`sw-cursor-not-allowed`}
+ }
+
+ & > svg {
+ ${tw`sw-mr-1`}
+ }
+`;
+
+const BaseButtonLink = styled(BaseLink)`
+ ${buttonStyle}
+`;
+
+const BaseButton = styled.button`
+ ${buttonStyle}
+
+ /*
+ Workaround for tooltips issue with onMouseLeave in disabled buttons:
+ https://github.com/facebook/react/issues/4251
+ */
+ & [disabled] {
+ ${tw`sw-pointer-events-none`};
+ }
+`;
diff --git a/server/sonar-web/design-system/src/components/buttons/ButtonPrimary.tsx b/server/sonar-web/design-system/src/components/buttons/ButtonPrimary.tsx
new file mode 100644
index 00000000000..117456532b6
--- /dev/null
+++ b/server/sonar-web/design-system/src/components/buttons/ButtonPrimary.tsx
@@ -0,0 +1,37 @@
+/*
+ * 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 { css } from '@emotion/react';
+import styled from '@emotion/styled';
+import { OPACITY_20_PERCENT, themeBorder, themeColor, themeContrast } from '../../helpers';
+import { ThemedProps } from '../../types';
+import { Button, ButtonProps } from './Button';
+
+export const PrimaryStyle = (props: ThemedProps) => css`
+ background: ${themeColor('button')(props)};
+ backgroundhover: ${themeColor('buttonHover')(props)};
+ color: ${themeContrast('primary')(props)};
+ focus: ${themeColor('button', OPACITY_20_PERCENT)(props)};
+ border: ${themeBorder('default', 'transparent')(props)};
+`;
+
+export const ButtonPrimary: React.FC<ButtonProps> = styled(Button)`
+ ${PrimaryStyle}
+`;
diff --git a/server/sonar-web/design-system/src/components/buttons/ButtonSecondary.tsx b/server/sonar-web/design-system/src/components/buttons/ButtonSecondary.tsx
new file mode 100644
index 00000000000..8769d3f4052
--- /dev/null
+++ b/server/sonar-web/design-system/src/components/buttons/ButtonSecondary.tsx
@@ -0,0 +1,36 @@
+/*
+ * 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 { OPACITY_20_PERCENT, themeBorder, themeColor, themeContrast } from '../../helpers';
+import { Button, ButtonProps } from './Button';
+
+export const ButtonSecondary: React.FC<ButtonProps> = styled(Button)`
+ --background: ${themeColor('buttonSecondary')};
+ --backgroundHover: ${themeColor('buttonSecondaryHover')};
+ --color: ${themeContrast('buttonSecondary')};
+ --focus: ${themeColor('buttonSecondaryBorder', OPACITY_20_PERCENT)};
+ --border: ${themeBorder('default', 'buttonSecondaryBorder')};
+
+ &:hover,
+ &:active,
+ &:focus {
+ border-color: ${themeColor('buttonSecondaryBorder')};
+ }
+`;
diff --git a/server/sonar-web/design-system/src/components/buttons/DangerButtonPrimary.tsx b/server/sonar-web/design-system/src/components/buttons/DangerButtonPrimary.tsx
new file mode 100644
index 00000000000..d954a539dfa
--- /dev/null
+++ b/server/sonar-web/design-system/src/components/buttons/DangerButtonPrimary.tsx
@@ -0,0 +1,31 @@
+/*
+ * 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 { OPACITY_20_PERCENT, themeBorder, themeColor, themeContrast } from '../../helpers';
+import { Button, ButtonProps } from './Button';
+
+export const DangerButtonPrimary: React.FC<ButtonProps> = styled(Button)`
+ --background: ${themeColor('dangerButton')};
+ --backgroundHover: ${themeColor('dangerButtonHover')};
+ --color: ${themeContrast('dangerButton')};
+ --focus: ${themeColor('dangerButtonFocus', OPACITY_20_PERCENT)};
+ --border: ${themeBorder('default', 'transparent')};
+`;
diff --git a/server/sonar-web/design-system/src/components/buttons/DangerButtonSecondary.tsx b/server/sonar-web/design-system/src/components/buttons/DangerButtonSecondary.tsx
new file mode 100644
index 00000000000..0decc1751b3
--- /dev/null
+++ b/server/sonar-web/design-system/src/components/buttons/DangerButtonSecondary.tsx
@@ -0,0 +1,37 @@
+/*
+ * 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 { OPACITY_20_PERCENT, themeBorder, themeColor, themeContrast } from '../../helpers';
+import { Button, ButtonProps } from './Button';
+
+export const DangerButtonSecondary: React.FC<ButtonProps> = styled(Button)`
+ --background: ${themeColor('dangerButtonSecondary')};
+ --backgroundHover: ${themeColor('dangerButtonSecondaryHover')};
+ --color: ${themeContrast('dangerButtonSecondary')};
+ --focus: ${themeColor('dangerButtonSecondaryFocus', OPACITY_20_PERCENT)};
+ --border: ${themeBorder('default', 'dangerButtonSecondaryBorder')};
+
+ &:hover,
+ &:active,
+ &:focus {
+ border-color: ${themeColor('dangerButtonSecondaryBorder')};
+ }
+`;
diff --git a/server/sonar-web/design-system/src/components/buttons/DownloadButton.tsx b/server/sonar-web/design-system/src/components/buttons/DownloadButton.tsx
new file mode 100644
index 00000000000..68f8c1e7c57
--- /dev/null
+++ b/server/sonar-web/design-system/src/components/buttons/DownloadButton.tsx
@@ -0,0 +1,30 @@
+/*
+ * 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 { buttonStyle } from './Button';
+import { PrimaryStyle } from './ButtonPrimary';
+
+export const DownloadButton = styled.a`
+ ${buttonStyle}
+ ${PrimaryStyle}
+ &:hover {
+ border-bottom-color: transparent;
+ }
+`;
diff --git a/server/sonar-web/design-system/src/components/buttons/ThirdPartyButton.tsx b/server/sonar-web/design-system/src/components/buttons/ThirdPartyButton.tsx
new file mode 100644
index 00000000000..86a9e0b54ac
--- /dev/null
+++ b/server/sonar-web/design-system/src/components/buttons/ThirdPartyButton.tsx
@@ -0,0 +1,48 @@
+/*
+ * 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 React from 'react';
+import { OPACITY_20_PERCENT } from '../../helpers/constants';
+import { themeBorder, themeColor, themeContrast } from '../../helpers/theme';
+import { Button, ButtonProps } from './Button';
+
+interface ThirdPartyProps extends Omit<ButtonProps, 'Icon'> {
+ iconPath: string;
+ name: string;
+}
+
+export function ThirdPartyButton({ children, iconPath, name, ...buttonProps }: ThirdPartyProps) {
+ const size = 16;
+ return (
+ <ThirdPartyButtonStyled {...buttonProps}>
+ <img alt={name} className="sw-mr-1" height={size} src={iconPath} width={size} />
+ {children}
+ </ThirdPartyButtonStyled>
+ );
+}
+
+const ThirdPartyButtonStyled: React.FC<ButtonProps> = styled(Button)`
+ --background: ${themeColor('thirdPartyButton')};
+ --backgroundHover: ${themeColor('thirdPartyButtonHover')};
+ --color: ${themeContrast('thirdPartyButton')};
+ --focus: ${themeColor('thirdPartyButtonBorder', OPACITY_20_PERCENT)};
+ --border: ${themeBorder('default', 'thirdPartyButtonBorder')};
+`;
diff --git a/server/sonar-web/design-system/src/components/buttons/WrapperButton.tsx b/server/sonar-web/design-system/src/components/buttons/WrapperButton.tsx
new file mode 100644
index 00000000000..64d86fc613f
--- /dev/null
+++ b/server/sonar-web/design-system/src/components/buttons/WrapperButton.tsx
@@ -0,0 +1,31 @@
+/*
+ * 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 { OPACITY_20_PERCENT, themeColor } from '../../helpers';
+import { Button, ButtonProps } from './Button';
+
+export const WrapperButton: React.FC<ButtonProps> = styled(Button)`
+ --background: none;
+ --backgroundHover: none;
+ --color: none;
+ --focus: ${themeColor('button', OPACITY_20_PERCENT)};
+ --border: none;
+`;
diff --git a/server/sonar-web/design-system/src/components/__tests__/buttons-test.tsx b/server/sonar-web/design-system/src/components/buttons/__tests__/buttons-test.tsx
index f2a0886ea84..e8e0007d5b7 100644
--- a/server/sonar-web/design-system/src/components/__tests__/buttons-test.tsx
+++ b/server/sonar-web/design-system/src/components/buttons/__tests__/buttons-test.tsx
@@ -19,8 +19,8 @@
*/
import { screen } from '@testing-library/react';
-import { render } from '../../helpers/testUtils';
-import { CodeViewerExpander } from '../buttons';
+import { render } from '../../../helpers/testUtils';
+import { CodeViewerExpander } from '../BareButtons';
it('renders CodeViewerExpander correctly when direction is UP', () => {
render(<CodeViewerExpander direction="UP">Hello</CodeViewerExpander>);
diff --git a/server/sonar-web/design-system/src/components/buttons/index.ts b/server/sonar-web/design-system/src/components/buttons/index.ts
new file mode 100644
index 00000000000..a813c49afc8
--- /dev/null
+++ b/server/sonar-web/design-system/src/components/buttons/index.ts
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+/*
+ * 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.
+ */
+export * from './BareButtons';
+export * from './Button';
+export * from './ButtonPrimary';
+export * from './ButtonSecondary';
+export * from './DangerButtonPrimary';
+export * from './DangerButtonSecondary';
+export * from './DownloadButton';
+export * from './ThirdPartyButton';
+export * from './WrapperButton';
diff --git a/server/sonar-web/design-system/src/components/index.ts b/server/sonar-web/design-system/src/components/index.ts
index 1a1f1db8ea6..d5bb51707e8 100644
--- a/server/sonar-web/design-system/src/components/index.ts
+++ b/server/sonar-web/design-system/src/components/index.ts
@@ -25,15 +25,11 @@ export { BarChart } from './BarChart';
export { Breadcrumbs } from './Breadcrumbs';
export * from './BubbleChart';
export * from './Card';
-export * from './Checkbox';
export * from './CodeSnippet';
export * from './CodeSyntaxHighlighter';
export * from './ColorsLegend';
export * from './CoverageIndicator';
-export * from './DatePicker';
-export * from './DateRangePicker';
export { DeferredSpinner } from './DeferredSpinner';
-export * from './DiscreetSelect';
export { ActionsDropdown, Dropdown } from './Dropdown';
export * from './DropdownMenu';
export { DropdownToggler } from './DropdownToggler';
@@ -44,17 +40,12 @@ export * from './FacetItem';
export { FailedQGConditionLink } from './FailedQGConditionLink';
export { FlagMessage } from './FlagMessage';
export * from './FlowStep';
-export * from './FormField';
export * from './GenericAvatar';
export * from './HighlightedSection';
export { Histogram } from './Histogram';
export { HotspotRating } from './HotspotRating';
export * from './HtmlFormatter';
export { IllustratedSelectionCard } from './IlllustredSelectionCard';
-export * from './InputField';
-export * from './InputMultiSelect';
-export { InputSearch } from './InputSearch';
-export * from './InputSelect';
export * from './InteractiveIcon';
export * from './IssueMessageHighlighting';
export * from './KeyboardHint';
@@ -65,15 +56,11 @@ export * from './MainAppBar';
export * from './MainMenu';
export * from './MainMenuItem';
export * from './MetricsRatingBadge';
-export * from './MultiSelectMenu';
export * from './NavBarTabs';
export * from './NewCodeLegend';
export * from './OutsideClickHandler';
export { QualityGateIndicator } from './QualityGateIndicator';
-export * from './RadioButton';
export * from './SearchHighlighter';
-export * from './SearchSelect';
-export * from './SearchSelectDropdown';
export * from './SelectionCard';
export * from './Separator';
export * from './SizeIndicator';
@@ -99,6 +86,7 @@ export * from './code-line/LineStyles';
export * from './code-line/LineToken';
export * from './code-line/LineWrapper';
export * from './icons';
+export * from './input';
export * from './layouts';
export * from './modal/Modal';
export * from './popups';
diff --git a/server/sonar-web/design-system/src/components/Checkbox.tsx b/server/sonar-web/design-system/src/components/input/Checkbox.tsx
index 238a52cba6e..707cae6aa65 100644
--- a/server/sonar-web/design-system/src/components/Checkbox.tsx
+++ b/server/sonar-web/design-system/src/components/input/Checkbox.tsx
@@ -21,10 +21,10 @@
import styled from '@emotion/styled';
import React from 'react';
import tw from 'twin.macro';
-import { themeBorder, themeColor, themeContrast } from '../helpers/theme';
-import { DeferredSpinner } from './DeferredSpinner';
-import { CheckIcon } from './icons/CheckIcon';
-import { CustomIcon } from './icons/Icon';
+import { themeBorder, themeColor, themeContrast } from '../../helpers/theme';
+import { DeferredSpinner } from '../DeferredSpinner';
+import { CheckIcon } from '../icons/CheckIcon';
+import { CustomIcon } from '../icons/Icon';
interface Props {
checked: boolean;
diff --git a/server/sonar-web/design-system/src/components/DatePicker.tsx b/server/sonar-web/design-system/src/components/input/DatePicker.tsx
index 838fbd04cc0..fc8f1e7c96b 100644
--- a/server/sonar-web/design-system/src/components/DatePicker.tsx
+++ b/server/sonar-web/design-system/src/components/input/DatePicker.tsx
@@ -40,17 +40,17 @@ import {
useDayPicker,
} from 'react-day-picker';
import tw from 'twin.macro';
-import { PopupPlacement, PopupZLevel, themeBorder, themeColor, themeContrast } from '../helpers';
-import { InputSizeKeys } from '../types/theme';
-import EscKeydownHandler from './EscKeydownHandler';
-import { FocusOutHandler } from './FocusOutHandler';
+import { PopupPlacement, PopupZLevel, themeBorder, themeColor, themeContrast } from '../../helpers';
+import { InputSizeKeys } from '../../types/theme';
+import EscKeydownHandler from '../EscKeydownHandler';
+import { FocusOutHandler } from '../FocusOutHandler';
+import { InteractiveIcon } from '../InteractiveIcon';
+import { OutsideClickHandler } from '../OutsideClickHandler';
+import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from '../icons';
+import { CloseIcon } from '../icons/CloseIcon';
+import { Popup } from '../popups';
import { InputField } from './InputField';
import { InputSelect } from './InputSelect';
-import { InteractiveIcon } from './InteractiveIcon';
-import { OutsideClickHandler } from './OutsideClickHandler';
-import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from './icons';
-import { CloseIcon } from './icons/CloseIcon';
-import { Popup } from './popups';
// When no minDate is given, year dropdown will show year options up to PAST_MAX_YEARS in the past
const YEARS_TO_DISPLAY = 10;
diff --git a/server/sonar-web/design-system/src/components/DateRangePicker.tsx b/server/sonar-web/design-system/src/components/input/DateRangePicker.tsx
index f44ca09e0ca..f3f65ea29c1 100644
--- a/server/sonar-web/design-system/src/components/DateRangePicker.tsx
+++ b/server/sonar-web/design-system/src/components/input/DateRangePicker.tsx
@@ -20,9 +20,9 @@
import classNames from 'classnames';
import { max, min } from 'date-fns';
import * as React from 'react';
-import { PopupZLevel } from '../helpers';
+import { PopupZLevel } from '../../helpers';
+import { LightLabel } from '../Text';
import { DatePicker } from './DatePicker';
-import { LightLabel } from './Text';
interface DateRange {
from?: Date;
diff --git a/server/sonar-web/design-system/src/components/DiscreetSelect.tsx b/server/sonar-web/design-system/src/components/input/DiscreetSelect.tsx
index 085caf1b12b..543f182bb8c 100644
--- a/server/sonar-web/design-system/src/components/DiscreetSelect.tsx
+++ b/server/sonar-web/design-system/src/components/input/DiscreetSelect.tsx
@@ -20,8 +20,8 @@
import styled from '@emotion/styled';
import tw from 'twin.macro';
-import { themeBorder, themeColor, themeContrast } from '../helpers/theme';
-import { InputSizeKeys } from '../types/theme';
+import { themeBorder, themeColor, themeContrast } from '../../helpers/theme';
+import { InputSizeKeys } from '../../types/theme';
import { InputSelect, LabelValueSelectOption } from './InputSelect';
interface Props<V> {
diff --git a/server/sonar-web/design-system/src/components/FormField.tsx b/server/sonar-web/design-system/src/components/input/FormField.tsx
index a6bac58d5e8..3397bc41381 100644
--- a/server/sonar-web/design-system/src/components/FormField.tsx
+++ b/server/sonar-web/design-system/src/components/input/FormField.tsx
@@ -20,8 +20,8 @@
import styled from '@emotion/styled';
import { ReactNode } from 'react';
import tw from 'twin.macro';
-import { Highlight, Note } from './Text';
-import { RequiredIcon } from './icons';
+import { Highlight, Note } from '../Text';
+import { RequiredIcon } from '../icons';
interface Props {
ariaLabel?: string;
diff --git a/server/sonar-web/design-system/src/components/InputField.tsx b/server/sonar-web/design-system/src/components/input/InputField.tsx
index 1dab905fced..ec3ddad5a4f 100644
--- a/server/sonar-web/design-system/src/components/InputField.tsx
+++ b/server/sonar-web/design-system/src/components/input/InputField.tsx
@@ -21,9 +21,9 @@ import { css } from '@emotion/react';
import styled from '@emotion/styled';
import { forwardRef } from 'react';
import tw from 'twin.macro';
-import { INPUT_SIZES } from '../helpers/constants';
-import { themeBorder, themeColor, themeContrast } from '../helpers/theme';
-import { InputSizeKeys, ThemedProps } from '../types/theme';
+import { INPUT_SIZES } from '../../helpers/constants';
+import { themeBorder, themeColor, themeContrast } from '../../helpers/theme';
+import { InputSizeKeys, ThemedProps } from '../../types/theme';
interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {
as?: React.ElementType;
diff --git a/server/sonar-web/design-system/src/components/InputMultiSelect.tsx b/server/sonar-web/design-system/src/components/input/InputMultiSelect.tsx
index 6a7eca741bf..6020898fbd5 100644
--- a/server/sonar-web/design-system/src/components/InputMultiSelect.tsx
+++ b/server/sonar-web/design-system/src/components/input/InputMultiSelect.tsx
@@ -19,11 +19,11 @@
*/
import styled from '@emotion/styled';
import classNames from 'classnames';
-import { themeBorder } from '../helpers';
-import { Badge } from './Badge';
-import { LightLabel } from './Text';
-import { ButtonProps, WrapperButton } from './buttons';
-import { ChevronDownIcon } from './icons';
+import { themeBorder } from '../../helpers';
+import { Badge } from '../Badge';
+import { LightLabel } from '../Text';
+import { ButtonProps, WrapperButton } from '../buttons';
+import { ChevronDownIcon } from '../icons';
interface Props extends Pick<ButtonProps, 'onClick'> {
className?: string;
diff --git a/server/sonar-web/design-system/src/components/InputSearch.tsx b/server/sonar-web/design-system/src/components/input/InputSearch.tsx
index 354fab3b5d2..beb1ef1ca18 100644
--- a/server/sonar-web/design-system/src/components/InputSearch.tsx
+++ b/server/sonar-web/design-system/src/components/input/InputSearch.tsx
@@ -23,15 +23,15 @@ import classNames from 'classnames';
import { debounce } from 'lodash';
import React, { PropsWithChildren, useEffect, useMemo, useRef, useState } from 'react';
import tw, { theme } from 'twin.macro';
-import { DEBOUNCE_DELAY, INPUT_SIZES } from '../helpers/constants';
-import { Key } from '../helpers/keyboard';
-import { themeBorder, themeColor, themeContrast } from '../helpers/theme';
-import { isDefined } from '../helpers/types';
-import { InputSizeKeys } from '../types/theme';
-import { DeferredSpinner, Spinner } from './DeferredSpinner';
-import { InteractiveIcon } from './InteractiveIcon';
-import { CloseIcon } from './icons/CloseIcon';
-import { SearchIcon } from './icons/SearchIcon';
+import { DEBOUNCE_DELAY, INPUT_SIZES } from '../../helpers/constants';
+import { Key } from '../../helpers/keyboard';
+import { themeBorder, themeColor, themeContrast } from '../../helpers/theme';
+import { isDefined } from '../../helpers/types';
+import { InputSizeKeys } from '../../types/theme';
+import { DeferredSpinner, Spinner } from '../DeferredSpinner';
+import { InteractiveIcon } from '../InteractiveIcon';
+import { CloseIcon } from '../icons/CloseIcon';
+import { SearchIcon } from '../icons/SearchIcon';
interface Props {
autoFocus?: boolean;
diff --git a/server/sonar-web/design-system/src/components/InputSelect.tsx b/server/sonar-web/design-system/src/components/input/InputSelect.tsx
index 4edc8e58442..586ae032180 100644
--- a/server/sonar-web/design-system/src/components/InputSelect.tsx
+++ b/server/sonar-web/design-system/src/components/input/InputSelect.tsx
@@ -29,11 +29,11 @@ import ReactSelect, {
StylesConfig,
components,
} from 'react-select';
-import { INPUT_SIZES } from '../helpers';
-import { themeBorder, themeColor, themeContrast } from '../helpers/theme';
-import { InputSizeKeys } from '../types/theme';
-import { SearchHighlighter } from './SearchHighlighter';
-import { ChevronDownIcon } from './icons';
+import { INPUT_SIZES } from '../../helpers';
+import { themeBorder, themeColor, themeContrast } from '../../helpers/theme';
+import { InputSizeKeys } from '../../types/theme';
+import { SearchHighlighter } from '../SearchHighlighter';
+import { ChevronDownIcon } from '../icons';
export interface LabelValueSelectOption<V> {
Icon?: ReactNode;
diff --git a/server/sonar-web/design-system/src/components/MultiSelectMenu.tsx b/server/sonar-web/design-system/src/components/input/MultiSelectMenu.tsx
index ecfaa459512..191de5d27f8 100644
--- a/server/sonar-web/design-system/src/components/MultiSelectMenu.tsx
+++ b/server/sonar-web/design-system/src/components/input/MultiSelectMenu.tsx
@@ -20,8 +20,8 @@
import classNames from 'classnames';
import { difference } from 'lodash';
import { PureComponent } from 'react';
-import { Key } from '../helpers/keyboard';
-import { ItemDivider, ItemHeader } from './DropdownMenu';
+import { Key } from '../../helpers/keyboard';
+import { ItemDivider, ItemHeader } from '../DropdownMenu';
import { InputSearch } from './InputSearch';
import { MultiSelectMenuOption } from './MultiSelectMenuOption';
@@ -177,10 +177,12 @@ export class MultiSelectMenu extends PureComponent<Props, State> {
this.props.onSelect(item);
};
- onUnselectItem = (item: string) => this.props.onUnselect(item);
+ onUnselectItem = (item: string) => {
+ this.props.onUnselect(item);
+ };
isNewElement = (elem: string, { selectedElements, elements }: Props) =>
- elem.length > 0 && selectedElements.indexOf(elem) === -1 && elements.indexOf(elem) === -1;
+ elem.length > 0 && !selectedElements.includes(elem) && !elements.includes(elem);
updateSelectedElements = (props: PropsWithDefault) => {
this.setState((state: State) => {
diff --git a/server/sonar-web/design-system/src/components/MultiSelectMenuOption.tsx b/server/sonar-web/design-system/src/components/input/MultiSelectMenuOption.tsx
index e68dd7c3687..f801a5d062f 100644
--- a/server/sonar-web/design-system/src/components/MultiSelectMenuOption.tsx
+++ b/server/sonar-web/design-system/src/components/input/MultiSelectMenuOption.tsx
@@ -19,7 +19,7 @@
*/
import classNames from 'classnames';
import { identity } from 'lodash';
-import { ItemCheckbox } from './DropdownMenu';
+import { ItemCheckbox } from '../DropdownMenu';
export interface MultiSelectOptionProps {
active?: boolean;
diff --git a/server/sonar-web/design-system/src/components/RadioButton.tsx b/server/sonar-web/design-system/src/components/input/RadioButton.tsx
index 069f6d2c78f..c9748461aed 100644
--- a/server/sonar-web/design-system/src/components/RadioButton.tsx
+++ b/server/sonar-web/design-system/src/components/input/RadioButton.tsx
@@ -21,7 +21,7 @@ import styled from '@emotion/styled';
import classNames from 'classnames';
import React from 'react';
import tw from 'twin.macro';
-import { themeBorder, themeColor } from '../helpers/theme';
+import { themeBorder, themeColor } from '../../helpers/theme';
type AllowedRadioButtonAttributes = Pick<
React.InputHTMLAttributes<HTMLInputElement>,
diff --git a/server/sonar-web/design-system/src/components/SearchSelect.tsx b/server/sonar-web/design-system/src/components/input/SearchSelect.tsx
index c17c22b62b6..79b654a70fa 100644
--- a/server/sonar-web/design-system/src/components/SearchSelect.tsx
+++ b/server/sonar-web/design-system/src/components/input/SearchSelect.tsx
@@ -23,9 +23,9 @@ import React, { RefObject } from 'react';
import { GroupBase, InputProps, components } from 'react-select';
import AsyncSelect, { AsyncProps } from 'react-select/async';
import Select from 'react-select/dist/declarations/src/Select';
-import { INPUT_SIZES } from '../helpers';
-import { Key } from '../helpers/keyboard';
-import { translate } from '../helpers/l10n';
+import { INPUT_SIZES } from '../../helpers';
+import { Key } from '../../helpers/keyboard';
+import { translate } from '../../helpers/l10n';
import { InputSearch } from './InputSearch';
import { LabelValueSelectOption, SelectProps, selectStyle } from './InputSelect';
diff --git a/server/sonar-web/design-system/src/components/SearchSelectDropdown.tsx b/server/sonar-web/design-system/src/components/input/SearchSelectDropdown.tsx
index f44bff6484d..2e105e2365f 100644
--- a/server/sonar-web/design-system/src/components/SearchSelectDropdown.tsx
+++ b/server/sonar-web/design-system/src/components/input/SearchSelectDropdown.tsx
@@ -30,11 +30,11 @@ import {
import { AsyncProps } from 'react-select/async';
import Select from 'react-select/dist/declarations/src/Select';
import tw from 'twin.macro';
-import { DEBOUNCE_DELAY, PopupPlacement, PopupZLevel, themeBorder } from '../helpers';
-import { InputSizeKeys } from '../types/theme';
-import { DropdownToggler } from './DropdownToggler';
+import { DEBOUNCE_DELAY, PopupPlacement, PopupZLevel, themeBorder } from '../../helpers';
+import { InputSizeKeys } from '../../types/theme';
+import { DropdownToggler } from '../DropdownToggler';
+import { SearchHighlighterContext } from '../SearchHighlighter';
import { IconOption, LabelValueSelectOption, SelectProps } from './InputSelect';
-import { SearchHighlighterContext } from './SearchHighlighter';
import { SearchSelect } from './SearchSelect';
import { SearchSelectDropdownControl } from './SearchSelectDropdownControl';
diff --git a/server/sonar-web/design-system/src/components/SearchSelectDropdownControl.tsx b/server/sonar-web/design-system/src/components/input/SearchSelectDropdownControl.tsx
index 83873796134..7090d3c4c91 100644
--- a/server/sonar-web/design-system/src/components/SearchSelectDropdownControl.tsx
+++ b/server/sonar-web/design-system/src/components/input/SearchSelectDropdownControl.tsx
@@ -21,10 +21,10 @@
import styled from '@emotion/styled';
import classNames from 'classnames';
import tw from 'twin.macro';
-import { INPUT_SIZES, themeBorder, themeColor, themeContrast } from '../helpers';
-import { Key } from '../helpers/keyboard';
-import { InputSizeKeys } from '../types/theme';
-import { ChevronDownIcon } from './icons';
+import { INPUT_SIZES, themeBorder, themeColor, themeContrast } from '../../helpers';
+import { Key } from '../../helpers/keyboard';
+import { InputSizeKeys } from '../../types/theme';
+import { ChevronDownIcon } from '../icons';
interface SearchSelectDropdownControlProps {
ariaLabel?: string;
diff --git a/server/sonar-web/design-system/src/components/__tests__/DatePicker-test.tsx b/server/sonar-web/design-system/src/components/input/__tests__/DatePicker-test.tsx
index 01aa68be4c7..81d9f167caf 100644
--- a/server/sonar-web/design-system/src/components/__tests__/DatePicker-test.tsx
+++ b/server/sonar-web/design-system/src/components/input/__tests__/DatePicker-test.tsx
@@ -21,7 +21,7 @@
import { screen, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { getMonth, getYear, parseISO } from 'date-fns';
-import { render } from '../../helpers/testUtils';
+import { render } from '../../../helpers/testUtils';
import { DatePicker } from '../DatePicker';
it('behaves correctly', async () => {
diff --git a/server/sonar-web/design-system/src/components/__tests__/DateRangePicker-test.tsx b/server/sonar-web/design-system/src/components/input/__tests__/DateRangePicker-test.tsx
index 6710f23ce0a..62902dfcb1c 100644
--- a/server/sonar-web/design-system/src/components/__tests__/DateRangePicker-test.tsx
+++ b/server/sonar-web/design-system/src/components/input/__tests__/DateRangePicker-test.tsx
@@ -20,7 +20,7 @@
import { screen, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { formatISO, parseISO } from 'date-fns';
-import { render } from '../../helpers/testUtils';
+import { render } from '../../../helpers/testUtils';
import { DateRangePicker } from '../DateRangePicker';
beforeEach(() => {
diff --git a/server/sonar-web/design-system/src/components/__tests__/DiscreetSelect-test.tsx b/server/sonar-web/design-system/src/components/input/__tests__/DiscreetSelect-test.tsx
index fea6a4c0cc3..7db557af2a0 100644
--- a/server/sonar-web/design-system/src/components/__tests__/DiscreetSelect-test.tsx
+++ b/server/sonar-web/design-system/src/components/input/__tests__/DiscreetSelect-test.tsx
@@ -19,8 +19,8 @@
*/
import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { render } from '../../helpers/testUtils';
-import { FCProps } from '../../types/misc';
+import { render } from '../../../helpers/testUtils';
+import { FCProps } from '../../../types/misc';
import { DiscreetSelect } from '../DiscreetSelect';
it('should render discreet select and invoke CB on value click', async () => {
diff --git a/server/sonar-web/design-system/src/components/__tests__/FormField-test.tsx b/server/sonar-web/design-system/src/components/input/__tests__/FormField-test.tsx
index ee86ad31e26..a8a4faeb025 100644
--- a/server/sonar-web/design-system/src/components/__tests__/FormField-test.tsx
+++ b/server/sonar-web/design-system/src/components/input/__tests__/FormField-test.tsx
@@ -20,7 +20,7 @@
import { screen } from '@testing-library/react';
import { FCProps } from '~types/misc';
-import { render } from '../../helpers/testUtils';
+import { render } from '../../../helpers/testUtils';
import { FormField } from '../FormField';
it('should render correctly', () => {
diff --git a/server/sonar-web/design-system/src/components/__tests__/InputField-test.tsx b/server/sonar-web/design-system/src/components/input/__tests__/InputField-test.tsx
index 47fcac116ca..47fcac116ca 100644
--- a/server/sonar-web/design-system/src/components/__tests__/InputField-test.tsx
+++ b/server/sonar-web/design-system/src/components/input/__tests__/InputField-test.tsx
diff --git a/server/sonar-web/design-system/src/components/__tests__/InputMultiSelect-test.tsx b/server/sonar-web/design-system/src/components/input/__tests__/InputMultiSelect-test.tsx
index d40de11ab10..d362d00db85 100644
--- a/server/sonar-web/design-system/src/components/__tests__/InputMultiSelect-test.tsx
+++ b/server/sonar-web/design-system/src/components/input/__tests__/InputMultiSelect-test.tsx
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { render, screen } from '@testing-library/react';
-import { FCProps } from '../../types/misc';
+import { FCProps } from '../../../types/misc';
import { InputMultiSelect } from '../InputMultiSelect';
it('should render correctly', () => {
diff --git a/server/sonar-web/design-system/src/components/__tests__/InputSearch-test.tsx b/server/sonar-web/design-system/src/components/input/__tests__/InputSearch-test.tsx
index 683c2e5fb74..fa5f5c71b73 100644
--- a/server/sonar-web/design-system/src/components/__tests__/InputSearch-test.tsx
+++ b/server/sonar-web/design-system/src/components/input/__tests__/InputSearch-test.tsx
@@ -18,8 +18,8 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { screen, waitFor } from '@testing-library/react';
-import { render } from '../../helpers/testUtils';
-import { FCProps } from '../../types/misc';
+import { render } from '../../../helpers/testUtils';
+import { FCProps } from '../../../types/misc';
import { InputSearch } from '../InputSearch';
it('should warn when input is too short', async () => {
diff --git a/server/sonar-web/design-system/src/components/__tests__/InputSelect-test.tsx b/server/sonar-web/design-system/src/components/input/__tests__/InputSelect-test.tsx
index 8d835940dfc..fefc767f86b 100644
--- a/server/sonar-web/design-system/src/components/__tests__/InputSelect-test.tsx
+++ b/server/sonar-web/design-system/src/components/input/__tests__/InputSelect-test.tsx
@@ -19,8 +19,8 @@
*/
import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { render } from '../../helpers/testUtils';
-import { FCProps } from '../../types/misc';
+import { render } from '../../../helpers/testUtils';
+import { FCProps } from '../../../types/misc';
import { InputSelect } from '../InputSelect';
it('should render select input and be able to click and change', async () => {
diff --git a/server/sonar-web/design-system/src/components/__tests__/MultiSelectMenu-test.tsx b/server/sonar-web/design-system/src/components/input/__tests__/MultiSelectMenu-test.tsx
index a1c7b5800ea..a1c7b5800ea 100644
--- a/server/sonar-web/design-system/src/components/__tests__/MultiSelectMenu-test.tsx
+++ b/server/sonar-web/design-system/src/components/input/__tests__/MultiSelectMenu-test.tsx
diff --git a/server/sonar-web/design-system/src/components/__tests__/RadioButton-test.tsx b/server/sonar-web/design-system/src/components/input/__tests__/RadioButton-test.tsx
index deff53b4071..b84f0bc377e 100644
--- a/server/sonar-web/design-system/src/components/__tests__/RadioButton-test.tsx
+++ b/server/sonar-web/design-system/src/components/input/__tests__/RadioButton-test.tsx
@@ -19,8 +19,8 @@
*/
import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { render } from '../../helpers/testUtils';
-import { FCProps } from '../../types/misc';
+import { render } from '../../../helpers/testUtils';
+import { FCProps } from '../../../types/misc';
import { RadioButton } from '../RadioButton';
const value = 'value';
diff --git a/server/sonar-web/design-system/src/components/__tests__/SearchSelectDropdown-test.tsx b/server/sonar-web/design-system/src/components/input/__tests__/SearchSelectDropdown-test.tsx
index 18ee6f860aa..1c7d4874136 100644
--- a/server/sonar-web/design-system/src/components/__tests__/SearchSelectDropdown-test.tsx
+++ b/server/sonar-web/design-system/src/components/input/__tests__/SearchSelectDropdown-test.tsx
@@ -19,8 +19,8 @@
*/
import { act, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { render } from '../../helpers/testUtils';
-import { FCProps } from '../../types/misc';
+import { render } from '../../../helpers/testUtils';
+import { FCProps } from '../../../types/misc';
import { LabelValueSelectOption } from '../InputSelect';
import { SearchSelectDropdown } from '../SearchSelectDropdown';
diff --git a/server/sonar-web/design-system/src/components/input/index.ts b/server/sonar-web/design-system/src/components/input/index.ts
new file mode 100644
index 00000000000..ad389e9f27f
--- /dev/null
+++ b/server/sonar-web/design-system/src/components/input/index.ts
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+export * from './Checkbox';
+export * from './DatePicker';
+export * from './DateRangePicker';
+export * from './DiscreetSelect';
+export * from './FormField';
+export * from './InputField';
+export * from './InputMultiSelect';
+export * from './InputSearch';
+export * from './InputSelect';
+export * from './MultiSelectMenu';
+export * from './RadioButton';
+export * from './SearchSelect';
+export * from './SearchSelectDropdown';