From 53e5a51f1cecc1e17a00bfa2981eba583f2d3f4a Mon Sep 17 00:00:00 2001 From: Wouter Admiraal Date: Wed, 10 Aug 2022 14:29:08 +0200 Subject: SONAR-16782 [893362] Function cannot be performed by keyboard alone --- .../SourceViewer/__tests__/SourceViewer-it.tsx | 4 +-- .../js/components/SourceViewer/components/Line.css | 4 ++- .../components/LineDuplicationBlock.tsx | 11 +++--- .../components/LineIssuesIndicator.tsx | 13 +++---- .../SourceViewer/components/LineNumber.tsx | 9 +++-- .../SourceViewer/components/LineOptionsPopup.tsx | 13 ++++--- .../components/SourceViewer/components/LineSCM.tsx | 5 ++- .../__tests__/LineIssuesIndicator-test.tsx | 3 +- .../LineIssuesIndicator-test.tsx.snap | 24 +++++-------- .../js/components/controls/ActionsDropdown.tsx | 21 ----------- .../controls/__tests__/ActionsDropdown-test.tsx | 11 +----- .../__snapshots__/ActionsDropdown-test.tsx.snap | 41 ---------------------- .../src/main/js/components/controls/buttons.css | 23 ++++++++++++ .../src/main/js/components/controls/buttons.tsx | 4 +++ 14 files changed, 67 insertions(+), 119 deletions(-) (limited to 'server/sonar-web') diff --git a/server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewer-it.tsx b/server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewer-it.tsx index df8ed428928..0c958bb6500 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewer-it.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewer-it.tsx @@ -54,7 +54,7 @@ it('should show a permalink on line number', async () => { }) ); await user.click( - rowScreen.getByRole('link', { + rowScreen.getByRole('button', { name: 'component_viewer.copy_permalink' }) ); @@ -89,7 +89,7 @@ it('should show a permalink on line number', async () => { ); expect( - lowerRowScreen.getByRole('link', { + lowerRowScreen.getByRole('button', { name: 'component_viewer.copy_permalink' }) ).toBeInTheDocument(); diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/Line.css b/server/sonar-web/src/main/js/components/SourceViewer/components/Line.css index 24016edd24d..985473db381 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/Line.css +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/Line.css @@ -186,7 +186,9 @@ display: block; } -.source-line-scm [role='button'] { +.source-line-scm button { + display: block; + width: 100%; height: 18px; } diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/LineDuplicationBlock.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/LineDuplicationBlock.tsx index 49dc0765919..038acbf733b 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/LineDuplicationBlock.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/LineDuplicationBlock.tsx @@ -25,6 +25,7 @@ import Tooltip from '../../../components/controls/Tooltip'; import { PopupPlacement } from '../../../components/ui/popups'; import { translate } from '../../../helpers/l10n'; import { SourceLine } from '../../../types/types'; +import { ButtonPlain } from '../../controls/buttons'; export interface LineDuplicationBlockProps { blocksLoaded: boolean; @@ -43,11 +44,11 @@ export function LineDuplicationBlock(props: LineDuplicationBlockProps) { 'source-line-duplicated': duplicated }); + const tooltip = dropdownOpen ? undefined : translate('source_viewer.tooltip.duplicated_block'); + return duplicated ? ( - +
setDropdownOpen(false)} @@ -57,7 +58,7 @@ export function LineDuplicationBlock(props: LineDuplicationBlockProps) { {props.renderDuplicationPopup(index, line.line)} }> -
{ @@ -66,8 +67,6 @@ export function LineDuplicationBlock(props: LineDuplicationBlockProps) { props.onClick(line); } }} - role="button" - tabIndex={0} />
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/LineIssuesIndicator.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/LineIssuesIndicator.tsx index 666f5c527d8..d1ddbdb2247 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/LineIssuesIndicator.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/LineIssuesIndicator.tsx @@ -25,6 +25,7 @@ import IssueIcon from '../../../components/icons/IssueIcon'; import { sortByType } from '../../../helpers/issues'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { Issue, SourceLine } from '../../../types/types'; +import { ButtonPlain } from '../../controls/buttons'; export interface LineIssuesIndicatorProps { issues: Issue[]; @@ -65,20 +66,14 @@ export function LineIssuesIndicator(props: LineIssuesIndicatorProps) { return ( - ) => { - e.preventDefault(); - e.currentTarget.blur(); - props.onClick(); - }} - role="button" - tabIndex={0}> + onClick={props.onClick}> {issues.length > 1 && {issues.length}} - + ); } diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/LineNumber.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/LineNumber.tsx index 348a8cae165..55ba93354d3 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/LineNumber.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/LineNumber.tsx @@ -21,6 +21,7 @@ import * as React from 'react'; import Toggler from '../../../components/controls/Toggler'; import { translateWithParameters } from '../../../helpers/l10n'; import { SourceLine } from '../../../types/types'; +import { ButtonPlain } from '../../controls/buttons'; import LineOptionsPopup from './LineOptionsPopup'; export interface LineNumberProps { @@ -42,15 +43,13 @@ export function LineNumber({ displayOptions, firstLineNumber, line }: LineNumber onRequestClose={() => setOpen(false)} open={isOpen} overlay={}> - setOpen(true)} - role="button" - tabIndex={0}> + onClick={() => setOpen(true)}> {lineNumber} - +
) : ( lineNumber diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/LineOptionsPopup.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/LineOptionsPopup.tsx index 975e2a7e41e..ef523ceb15f 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/LineOptionsPopup.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/LineOptionsPopup.tsx @@ -23,7 +23,7 @@ import { PopupPlacement } from '../../../components/ui/popups'; import { translate } from '../../../helpers/l10n'; import { getCodeUrl, getPathUrlAsString } from '../../../helpers/urls'; import { SourceLine } from '../../../types/types'; -import { ActionsDropdownItem } from '../../controls/ActionsDropdown'; +import { ClipboardButton } from '../../controls/clipboard'; import { SourceViewerContext } from '../SourceViewerContext'; export interface LineOptionsPopupProps { @@ -43,11 +43,14 @@ export function LineOptionsPopup({ firstLineNumber, line }: LineOptionsPopupProp className="big-spacer-left" noPadding={true} placement={isAtTop ? PopupPlacement.BottomLeft : PopupPlacement.TopLeft}> -
    - +
    + {translate('component_viewer.copy_permalink')} - -
+ +
); }} diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/LineSCM.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/LineSCM.tsx index 713f02a6c06..c06c6e41c5e 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/LineSCM.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/LineSCM.tsx @@ -22,6 +22,7 @@ import Dropdown from '../../../components/controls/Dropdown'; import { PopupPlacement } from '../../../components/ui/popups'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { SourceLine } from '../../../types/types'; +import { ButtonPlain } from '../../controls/buttons'; import SCMPopup from './SCMPopup'; export interface LineSCMProps { @@ -49,9 +50,7 @@ export function LineSCM({ line, previousLine }: LineSCMProps) { return ( } overlayPlacement={PopupPlacement.RightTop}> -
- {cell} -
+ {cell}
); diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineIssuesIndicator-test.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineIssuesIndicator-test.tsx index 72ad28cd99b..21d20fbb05b 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineIssuesIndicator-test.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineIssuesIndicator-test.tsx @@ -21,6 +21,7 @@ import { shallow } from 'enzyme'; import * as React from 'react'; import { mockIssue } from '../../../../helpers/testMocks'; import { click } from '../../../../helpers/testUtils'; +import { ButtonPlain } from '../../../controls/buttons'; import { LineIssuesIndicator, LineIssuesIndicatorProps } from '../LineIssuesIndicator'; it('should render correctly', () => { @@ -43,7 +44,7 @@ it('should correctly handle click', () => { const onClick = jest.fn(); const wrapper = shallowRender({ onClick }); - click(wrapper.find('span[role="button"]')); + click(wrapper.find(ButtonPlain)); expect(onClick).toHaveBeenCalled(); }); diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineIssuesIndicator-test.tsx.snap b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineIssuesIndicator-test.tsx.snap index 5f22c660993..dc67d02a1f9 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineIssuesIndicator-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineIssuesIndicator-test.tsx.snap @@ -5,11 +5,9 @@ exports[`should render correctly: default 1`] = ` className="source-meta source-line-issues source-line-with-issues" data-line-number={3} > - 2 - + `; @@ -32,11 +30,9 @@ exports[`should render correctly: multiple issues, same type 1`] = ` className="source-meta source-line-issues source-line-with-issues" data-line-number={3} > - 2 - + `; @@ -66,11 +62,9 @@ exports[`should render correctly: single issue 1`] = ` className="source-meta source-line-issues source-line-with-issues" data-line-number={3} > - - + `; diff --git a/server/sonar-web/src/main/js/components/controls/ActionsDropdown.tsx b/server/sonar-web/src/main/js/components/controls/ActionsDropdown.tsx index 1a87832a2f2..e0184dcb0f1 100644 --- a/server/sonar-web/src/main/js/components/controls/ActionsDropdown.tsx +++ b/server/sonar-web/src/main/js/components/controls/ActionsDropdown.tsx @@ -20,14 +20,11 @@ import classNames from 'classnames'; import * as React from 'react'; import { Link, To } from 'react-router-dom'; -import { translate } from '../../helpers/l10n'; import DropdownIcon from '../icons/DropdownIcon'; import SettingsIcon from '../icons/SettingsIcon'; import { PopupPlacement } from '../ui/popups'; import { Button } from './buttons'; -import { ClipboardBase } from './clipboard'; import Dropdown from './Dropdown'; -import Tooltip from './Tooltip'; export interface ActionsDropdownProps { className?: string; @@ -60,8 +57,6 @@ export default function ActionsDropdown(props: ActionsDropdownProps) { interface ItemProps { className?: string; children: React.ReactNode; - /** used to pass a string to copy to clipboard */ - copyValue?: string; destructive?: boolean; /** used to pass a name of downloaded file */ download?: string; @@ -106,22 +101,6 @@ export class ActionsDropdownItem extends React.PureComponent { ); } - if (this.props.copyValue) { - return ( - - {({ setCopyButton, copySuccess }) => ( - -
  • - - {this.props.children} - -
  • -
    - )} -
    - ); - } - return (
  • diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/ActionsDropdown-test.tsx b/server/sonar-web/src/main/js/components/controls/__tests__/ActionsDropdown-test.tsx index 8eed909458c..611920edcfd 100644 --- a/server/sonar-web/src/main/js/components/controls/__tests__/ActionsDropdown-test.tsx +++ b/server/sonar-web/src/main/js/components/controls/__tests__/ActionsDropdown-test.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 { mount, shallow } from 'enzyme'; +import { shallow } from 'enzyme'; import * as React from 'react'; import { click } from '../../../helpers/testUtils'; import { PopupPlacement } from '../../ui/popups'; @@ -62,19 +62,10 @@ describe('ActionsDropdownItem', () => { expect(onClick).toBeCalled(); }); - it('should render correctly copy item', () => { - const wrapper = mountRender({ copyValue: 'my content to copy to clipboard' }); - expect(wrapper).toMatchSnapshot(); - }); - function shallowRender(props: Partial = {}) { return shallow(renderContent(props)); } - function mountRender(props: Partial = {}) { - return mount(renderContent(props)); - } - function renderContent(props: Partial = {}) { return ( diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ActionsDropdown-test.tsx.snap b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ActionsDropdown-test.tsx.snap index 37677005279..2ebe48a75c0 100644 --- a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ActionsDropdown-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ActionsDropdown-test.tsx.snap @@ -103,44 +103,3 @@ exports[`ActionsDropdownItem should render correctly 3`] = `
  • `; - -exports[`ActionsDropdownItem should render correctly copy item 1`] = ` - - - - -
  • - - - Hello world - - -
  • -
    -
    -
    -
    -`; diff --git a/server/sonar-web/src/main/js/components/controls/buttons.css b/server/sonar-web/src/main/js/components/controls/buttons.css index 2a78bdffbac..4e4f215dab0 100644 --- a/server/sonar-web/src/main/js/components/controls/buttons.css +++ b/server/sonar-web/src/main/js/components/controls/buttons.css @@ -118,6 +118,29 @@ /* #endregion */ +/* #region .button-plain */ +.button-plain { + display: inline-flex; + height: auto; + line-height: inherit; + margin: 0; + padding: 0; + border: none; + border-radius: 0; + background: transparent; + color: inherit; + border-bottom: 0; + font-weight: inherit; + font-size: inherit; +} + +.button-plain:hover { + color: var(--blue); + background-color: transparent; +} + +/* #endregion */ + /* #region .button-link */ .button-link { display: inline-flex; diff --git a/server/sonar-web/src/main/js/components/controls/buttons.tsx b/server/sonar-web/src/main/js/components/controls/buttons.tsx index e4cf225e3f1..67548395ccb 100644 --- a/server/sonar-web/src/main/js/components/controls/buttons.tsx +++ b/server/sonar-web/src/main/js/components/controls/buttons.tsx @@ -92,6 +92,10 @@ export function ButtonLink({ className, ...props }: ButtonProps) { return