* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { Spinner } from '@sonarsource/echoes-react';
import classNames from 'classnames';
-import { Spinner } from 'design-system';
+import { ButtonPrimary, ButtonSecondary } from 'design-system';
import React, { useCallback, useEffect } from 'react';
import { FormattedMessage } from 'react-intl';
import DocumentationLink from '../../../components/common/DocumentationLink';
-import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
import NewCodeDefinitionDaysOption from '../../../components/new-code-definition/NewCodeDefinitionDaysOption';
import NewCodeDefinitionPreviousVersionOption from '../../../components/new-code-definition/NewCodeDefinitionPreviousVersionOption';
import { NewCodeDefinitionLevels } from '../../../components/new-code-definition/utils';
</div>
<div className="settings-definition-right">
- <Spinner loading={isLoading}>
+ <Spinner isLoading={isLoading}>
<form className="sw-flex sw-flex-col sw-items-stretch" onSubmit={onSubmit}>
<NewCodeDefinitionPreviousVersionOption
isDefault
}
/>
<NewCodeDefinitionDaysOption
- className="spacer-top sw-mb-4"
+ className="sw-mt-2 sw-mb-4"
days={numberOfDays}
currentDaysValue={
newCodeDefinition?.type === NewCodeDefinitionType.NumberOfDays
/>
<div className="sw-mt-4">
<p
- className={classNames('spacer-bottom', {
+ className={classNames('sw-mb-2', {
'sw-invisible': !isFormTouched,
})}
>
{translate('baseline.next_analysis_notice')}
</p>
- <Spinner className="spacer-right" loading={isSaving} />
+ <Spinner className="sw-mr-2" isLoading={isSaving} />
{!isSaving && (
<>
- <SubmitButton disabled={!isFormTouched || !isValid}>
+ <ButtonPrimary type="submit" disabled={!isFormTouched || !isValid}>
{translate('save')}
- </SubmitButton>
- <ResetButtonLink
- className="spacer-left"
+ </ButtonPrimary>
+ <ButtonSecondary
+ className="sw-ml-2"
disabled={!isFormTouched}
onClick={resetNewCodeDefinition}
>
{translate('cancel')}
- </ResetButtonLink>
+ </ButtonSecondary>
</>
)}
</div>
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { InputTextArea } from 'design-system';
+import styled from '@emotion/styled';
+import {
+ ButtonSecondary,
+ HtmlFormatter,
+ InputTextArea,
+ PencilIcon,
+ themeBorder,
+ themeColor,
+} from 'design-system';
import * as React from 'react';
import FormattingTipsWithLink from '../../../../components/common/FormattingTipsWithLink';
-import { Button } from '../../../../components/controls/buttons';
-import EditIcon from '../../../../components/icons/EditIcon';
import { translate } from '../../../../helpers/l10n';
import { sanitizeUserInput } from '../../../../helpers/sanitize';
import { DefaultSpecializedInputProps, getPropertyName } from '../../utils';
</div>
) : (
<>
- <div
- className="markdown-preview markdown"
- // eslint-disable-next-line react/no-danger
- dangerouslySetInnerHTML={{ __html: sanitizeUserInput(formattedValue ?? '') }}
- />
- <Button className="spacer-top" onClick={props.onEditing}>
- <EditIcon className="spacer-right" />
+ <HtmlFormatter>
+ <FormattedPreviewBox
+ // eslint-disable-next-line react/no-danger
+ dangerouslySetInnerHTML={{ __html: sanitizeUserInput(formattedValue ?? '') }}
+ />
+ </HtmlFormatter>
+
+ <ButtonSecondary className="sw-mt-2" onClick={props.onEditing} icon={<PencilIcon />}>
{translate('edit')}
- </Button>
+ </ButtonSecondary>
</>
);
}
+
+const FormattedPreviewBox = styled.div`
+ width: 450px;
+ background-color: ${themeColor('infoBackground')};
+ border: ${themeBorder('default', 'infoBorder')};
+ border-radius: 2px;
+ padding: 16px;
+ overflow-wrap: break-word;
+ line-height: 1.5;
+`;
justify-content: space-between;
margin: 0px -16px;
}
-
-.markdown-preview {
- width: 450px;
- background-color: var(--info50);
- border: 1px solid var(--info200);
- border-radius: 2px;
- padding: 16px;
- overflow-wrap: break-word;
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2024 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.
- */
-.button {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- vertical-align: middle;
- height: var(--controlHeight);
- line-height: calc(var(--controlHeight) - 2px);
- padding: 0 var(--gridSize);
- border: 1px solid var(--darkBlue);
- border-radius: 2px;
- box-sizing: border-box;
- background: transparent;
- color: var(--darkBlue);
- font-weight: 600;
- font-size: var(--smallFontSize);
- text-decoration: none;
- cursor: pointer;
- transition:
- border-color 0.2s ease,
- box-shadow 0.2s ease,
- background-color 0.2s ease;
-}
-
-.button:hover,
-.button.selected {
- background: var(--darkBlue);
- color: var(--white);
-}
-
-.button-primary {
- background: var(--darkBlue);
- border-color: var(--darkBlue);
- color: var(--white);
-}
-
-.button-primary:hover {
- background: var(--veryDarkBlue);
- border-color: var(--veryDarkBlue);
-}
-
-.button-primary.button-light {
- background: var(--blue);
- border-color: var(--blue);
- color: var(--white);
-}
-
-.button-primary.button-light:hover {
- background: var(--darkBlue);
- border-color: var(--darkBlue);
-}
-
-.button.disabled {
- color: var(--disableGrayText) !important;
- border-color: var(--disableGrayBorder) !important;
- background: var(--disableGrayBg) !important;
- cursor: not-allowed !important;
-}
-
-/* #region .button-red */
-.button-red {
- border-color: var(--red);
- color: var(--red);
-}
-
-.button-red:hover,
-.button-red.active {
- background: var(--red);
- color: var(--white);
-}
-
-/* #endregion */
-
-/* #region .button-success */
-.button-success {
- border-color: var(--green);
- color: var(--green);
-}
-
-.button-success:hover,
-.button-success.active {
- background: var(--green);
- color: var(--white);
-}
-
-/* #endregion */
-
-/* #region .button-plain */
-.button-plain {
- box-sizing: border-box;
- background: inherit;
- color: inherit;
- cursor: pointer;
- border: 0;
-}
-
-.button-plain:disabled {
- color: var(--disableGrayText) !important;
- cursor: not-allowed !important;
-}
-
-/* #endregion */
-
-/* #region .button-link */
-.button-link {
- display: inline-flex;
- height: auto;
- /* Keep this to not inherit the height from .button */
- line-height: 1;
- margin: 0;
- padding: 0;
- border: none;
- border-radius: 0;
- background: transparent;
- color: var(--darkBlue);
- border-bottom: 1px solid var(--primarya40);
- font-weight: 400;
- font-size: inherit;
- transition:
- border-color 0.2s ease,
- box-shadow 0.2s ease,
- color 0.2s ease,
- border-bottom 0.2s ease;
-}
-
-.dropdown .button-link {
- border-bottom: none;
-}
-
-.button-link:hover {
- background: transparent;
- color: var(--darkBlue);
- border-bottom-color: var(--primary);
-}
-
-.button-link.disabled {
- color: var(--secondFontColor) !important;
- background: transparent !important;
- cursor: default;
-}
-
-/* #endregion */
-
-.button-small {
- height: var(--smallControlHeight);
- line-height: 18px;
- padding: 0 6px;
- font-size: 11px;
-}
-
-.button-tiny {
- height: var(--tinyControlHeight);
- line-height: var(--tinyControlHeight);
- padding: 0 calc(var(--gridSize) / 2);
-}
-
-.button-large {
- height: var(--largeControlHeight);
- padding: 0 16px;
- font-size: var(--mediumFontSize);
-}
-
-.button-huge {
- flex-direction: column;
- padding: calc(2 * var(--gridSize)) var(--gridSize);
- width: 180px;
- height: 180px;
- background-color: var(--white);
- border: solid 1px var(--white);
- border-radius: 3px;
- transition: all 0.2s ease;
-}
-
-.button-huge:hover,
-.button-huge:focus,
-.button-huge:active {
- background-color: var(--white);
- color: var(--darkBlue);
- transform: translateY(-2px);
-}
-
-/* #region .button-icon */
-.button-icon {
- display: inline-flex;
- justify-content: center;
- align-items: center;
- vertical-align: middle;
- width: var(--controlHeight);
- height: var(--controlHeight);
- padding: 0;
- border: none;
- color: inherit;
-}
-
-.button-icon.button-small {
- width: var(--smallControlHeight);
- height: var(--smallControlHeight);
- padding: 0;
-}
-
-.button-icon.button-small svg {
- margin-top: 0;
-}
-
-.button-icon.button-tiny {
- width: var(--tinyControlHeight);
- height: var(--tinyControlHeight);
- padding: 0;
-}
-
-.button-icon.button-tiny svg {
- margin-top: 0;
-}
-
-.button-icon:hover,
-.button-icon:focus-visible {
- background-color: currentColor;
-}
-
-.button-icon:not(.disabled):hover svg,
-.button-icon:not(.disabled):focus-visible svg {
- color: var(--white);
-}
-
-.button.button-icon.disabled {
- background: transparent !important;
-}
-
-/* #endregion */
-
-.button-list {
- display: inline-flex;
- justify-content: space-between;
- height: auto;
- border: 1px solid var(--barBorderColor);
- padding: var(--gridSize);
- margin: calc(var(--gridSize) / 2);
- color: var(--secondFontColor);
- font-weight: normal;
-}
-
-.button-list:hover {
- background-color: white;
- border-color: var(--blue);
- color: var(--darkBlue);
-}
-
-.no-select {
- user-select: none !important;
-}
-
-a[download].button.disabled {
- pointer-events: none;
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2024 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 classNames from 'classnames';
-import * as React from 'react';
-import { colors } from '../../app/theme';
-import ChevronRightIcon from '../icons/ChevronRightIcon';
-import ClearIcon, { ClearIconProps } from '../icons/ClearIcon';
-import DeleteIcon from '../icons/DeleteIcon';
-import EditIcon from '../icons/EditIcon';
-import { IconProps } from '../icons/Icon';
-import './buttons.css';
-import Tooltip, { TooltipProps } from './Tooltip';
-
-type AllowedButtonAttributes = Pick<
- React.ButtonHTMLAttributes<HTMLButtonElement>,
- | 'aria-label'
- | 'className'
- | 'disabled'
- | 'id'
- | 'style'
- | 'title'
- | 'onFocus'
- | 'onBlur'
- | 'onMouseOver'
- | 'onMouseLeave'
- | 'tabIndex'
- | 'role'
->;
-
-interface ButtonProps extends AllowedButtonAttributes {
- autoFocus?: boolean;
- children?: React.ReactNode;
- innerRef?: React.Ref<HTMLButtonElement>;
- name?: string;
- onClick?: () => void;
- preventDefault?: boolean;
- stopPropagation?: boolean;
- type?: 'button' | 'submit' | 'reset';
-}
-
-export class Button extends React.PureComponent<ButtonProps> {
- handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
- const { disabled, onClick, preventDefault = true, stopPropagation = false } = this.props;
-
- if (preventDefault || disabled) {
- event.preventDefault();
- }
- if (stopPropagation) {
- event.stopPropagation();
- }
-
- if (onClick && !disabled) {
- onClick();
- }
- };
-
- render() {
- const {
- className,
- disabled,
- innerRef,
- onClick,
- preventDefault,
- stopPropagation,
- type = 'button',
- ...props
- } = this.props;
-
- // Instead of undoing button style we simply not apply the class.
- const isPlain = className && className.indexOf('button-plain') !== -1;
- return (
- <button
- {...props}
- aria-disabled={disabled}
- disabled={disabled}
- className={classNames(isPlain ? '' : 'button', className, { disabled })}
- id={this.props.id}
- onClick={this.handleClick}
- ref={this.props.innerRef}
- // eslint-disable-next-line react/button-has-type
- type={type}
- />
- );
- }
-}
-
-export function ButtonLink({ className, ...props }: ButtonProps) {
- return <Button {...props} className={classNames('button-link', className)} />;
-}
-
-export function ButtonPlain({ className, ...props }: ButtonProps) {
- return <Button {...props} className={classNames('button-plain', className)} />;
-}
-
-export function SubmitButton(props: Omit<ButtonProps, 'type'>) {
- // do not prevent default to actually submit a form
- return <Button {...props} preventDefault={false} type="submit" />;
-}
-
-export function ResetButtonLink(props: Omit<ButtonProps, 'type'>) {
- return <ButtonLink {...props} type="reset" />;
-}
-
-export interface ButtonIconProps extends ButtonProps {
- 'aria-label'?: string;
- 'aria-labelledby'?: string;
- className?: string;
- color?: string;
- onClick?: () => void;
- tooltip?: React.ReactNode;
- tooltipProps?: Partial<TooltipProps>;
-}
-
-export function ButtonIcon(props: ButtonIconProps) {
- const { className, color, tooltip, tooltipProps, ...other } = props;
- return (
- <Tooltip mouseEnterDelay={0.4} overlay={tooltip} {...tooltipProps}>
- <Button
- className={classNames(className, 'button-icon')}
- stopPropagation
- style={{ color: color || colors.darkBlue }}
- {...other}
- />
- </Tooltip>
- );
-}
-
-interface ClearButtonProps extends ButtonIconProps {
- className?: string;
- iconProps?: ClearIconProps;
- onClick?: () => void;
-}
-
-export function ClearButton({ color, iconProps = {}, ...props }: ClearButtonProps) {
- return (
- <ButtonIcon color={color || colors.gray60} {...props}>
- <ClearIcon {...iconProps} />
- </ButtonIcon>
- );
-}
-
-interface ActionButtonProps extends ButtonIconProps {
- className?: string;
- iconProps?: IconProps;
- onClick?: () => void;
-}
-
-export function DeleteButton({ iconProps = {}, ...props }: ActionButtonProps) {
- return (
- <ButtonIcon color={colors.red} {...props}>
- <DeleteIcon {...iconProps} />
- </ButtonIcon>
- );
-}
-
-export function EditButton({ iconProps = {}, ...props }: ActionButtonProps) {
- return (
- <ButtonIcon {...props}>
- <EditIcon {...iconProps} />
- </ButtonIcon>
- );
-}
-
-export function ListButton({ className, children, ...props }: ButtonProps) {
- return (
- <Button className={classNames('button-list', className)} {...props}>
- {children}
- <ChevronRightIcon />
- </Button>
- );
-}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import styled from '@emotion/styled';
-import { FlagMessage, SubTitle, themeBorder, themeColor } from 'design-system';
+import { ButtonSecondary, FlagMessage, SubTitle, themeBorder, themeColor } from 'design-system';
import * as React from 'react';
import { RuleDescriptionSection } from '../../apps/coding-rules/rule';
import { translate } from '../../helpers/l10n';
import { Dict } from '../../types/types';
-import { ButtonLink } from '../controls/buttons';
import RuleDescription from './RuleDescription';
import DefenseInDepth from './educationPrinciples/DefenseInDepth';
import NeverTrustUserInput from './educationPrinciples/NeverTrustUserInput';
<div className="sw-my-6 rule-desc">
{displayEducationalPrinciplesNotification && (
<FlagMessage variant="info">
- <p className="little-spacer-bottom little-spacer-top">
- {translate('coding_rules.more_info.notification_message')}
- </p>
+ <p className="sw-my-1">{translate('coding_rules.more_info.notification_message')}</p>
- <ButtonLink
+ <ButtonSecondary
+ className="sw-whitespace-nowrap"
onClick={() => {
this.handleNotificationScroll();
}}
>
{translate('coding_rules.more_info.scroll_message')}
- </ButtonLink>
+ </ButtonSecondary>
</FlagMessage>
)}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { IconProps, InteractiveIcon } from 'design-system';
import * as React from 'react';
import { DraggableCore, DraggableData } from 'react-draggable';
-import { ButtonIcon } from '../../components/controls/buttons';
import ClearIcon from '../../components/icons/ClearIcon';
import CollapseIcon from '../../components/icons/CollapseIcon';
import ExpandIcon from '../../components/icons/ExpandIcon';
-import { IconProps } from '../../components/icons/Icon';
import MinimizeIcon from '../../components/icons/MinimizeIcon';
import { translate } from '../../helpers/l10n';
+import Tooltip from '../controls/Tooltip';
export interface Props {
children: React.ReactNode;
<WorkspaceHeaderButton
icon={MinimizeIcon}
onClick={this.props.onCollapse}
- tooltip="workspace.minimize"
+ tooltipContent="workspace.minimize"
/>
{this.props.maximized ? (
<WorkspaceHeaderButton
icon={CollapseIcon}
onClick={this.props.onMinimize}
- tooltip="workspace.normal_size"
+ tooltipContent="workspace.normal_size"
/>
) : (
<WorkspaceHeaderButton
icon={ExpandIcon}
onClick={this.props.onMaximize}
- tooltip="workspace.full_window"
+ tooltipContent="workspace.full_window"
/>
)}
<WorkspaceHeaderButton
icon={ClearIcon}
onClick={this.props.onClose}
- tooltip="workspace.close"
+ tooltipContent="workspace.close"
/>
</div>
</header>
}
interface WorkspaceHeaderButtonProps {
- icon: React.FC<React.PropsWithChildren<IconProps>>;
+ icon: React.ComponentType<React.PropsWithChildren<IconProps>>;
onClick: () => void;
- tooltip: string;
+ tooltipContent: string;
}
-function WorkspaceHeaderButton({ icon: Icon, onClick, tooltip }: WorkspaceHeaderButtonProps) {
+function WorkspaceHeaderButton({ icon, onClick, tooltipContent }: WorkspaceHeaderButtonProps) {
return (
- <ButtonIcon
- className="workspace-header-icon"
- aria-label={translate(tooltip)}
- color="#fff"
- onClick={onClick}
- tooltip={translate(tooltip)}
- >
- <Icon fill={undefined} />
- </ButtonIcon>
+ <Tooltip overlay={translate(tooltipContent)}>
+ <InteractiveIcon
+ className="workspace-header-icon"
+ aria-label={translate(tooltipContent)}
+ Icon={icon}
+ currentColor
+ onClick={onClick}
+ size="small"
+ />
+ </Tooltip>
);
}
* 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 { CloseIcon, InteractiveIcon } from 'design-system';
import * as React from 'react';
-import { ClearButton } from '../../components/controls/buttons';
+import { translate } from '../../helpers/l10n';
export interface Props {
children: React.ReactNode;
render() {
return (
- <li className="workspace-nav-item">
+ <StyledWorkspaceNavItem className="workspace-nav-item">
<a className="workspace-nav-item-link" href="#" onClick={this.handleNameClick}>
{this.props.children}
</a>
- <ClearButton
- className="js-close workspace-nav-item-close workspace-header-icon button-small little-spacer-left"
- color="#fff"
- iconProps={{ size: 12 }}
+ <InteractiveIcon
+ aria-label={translate('close')}
+ className="js-close sw-ml-1 sw-absolute sw-right-1 sw-top-1"
onClick={this.props.onClose}
+ currentColor
+ Icon={CloseIcon}
+ size="small"
/>
- </li>
+ </StyledWorkspaceNavItem>
);
}
}
+
+const StyledWorkspaceNavItem = styled.li`
+ color: white;
+`;