Skip to content

Commit e5ab111

Browse files
Merge pull request #2719 from github/koesie10/fix-button-accessibility
Fix button accessibility
2 parents 2f4eed4 + d90fb69 commit e5ab111

File tree

9 files changed

+239
-109
lines changed

9 files changed

+239
-109
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import * as React from "react";
2+
3+
import { Meta, StoryFn } from "@storybook/react";
4+
5+
import CompareTableComponent from "../../view/compare/CompareTable";
6+
7+
import "../../view/results/resultsView.css";
8+
9+
export default {
10+
title: "Compare/Compare Table",
11+
component: CompareTableComponent,
12+
} as Meta<typeof CompareTableComponent>;
13+
14+
const Template: StoryFn<typeof CompareTableComponent> = (args) => (
15+
<CompareTableComponent {...args} />
16+
);
17+
18+
export const CompareTable = Template.bind({});
19+
CompareTable.args = {
20+
comparison: {
21+
t: "setComparisons",
22+
stats: {
23+
fromQuery: {
24+
name: "Query built from user-controlled sources",
25+
status: "finished in 0 seconds",
26+
time: "8/16/2023, 3:08:37 PM",
27+
},
28+
toQuery: {
29+
name: "Query built from user-controlled sources",
30+
status: "finished in 2 seconds",
31+
time: "8/16/2023, 3:07:21 PM",
32+
},
33+
},
34+
columns: [
35+
{ name: "a", kind: "e" },
36+
{ name: "b", kind: "e" },
37+
],
38+
commonResultSetNames: ["edges", "nodes", "subpaths", "#select"],
39+
currentResultSetName: "edges",
40+
rows: {
41+
from: [],
42+
to: [
43+
[
44+
{
45+
label: "url : String",
46+
url: {
47+
uri: "file:/home/runner/work/sql2o-example/sql2o-example/src/main/java/org/example/HelloController.java",
48+
startLine: 22,
49+
startColumn: 27,
50+
endLine: 22,
51+
endColumn: 57,
52+
},
53+
},
54+
{
55+
label: "url",
56+
url: {
57+
uri: "file:/home/runner/work/sql2o-example/sql2o-example/src/main/java/org/example/HelloController.java",
58+
startLine: 23,
59+
startColumn: 33,
60+
endLine: 23,
61+
endColumn: 35,
62+
},
63+
},
64+
],
65+
],
66+
},
67+
message: undefined,
68+
databaseUri: "file:///java",
69+
},
70+
};
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import * as React from "react";
2+
3+
import { Meta, StoryFn } from "@storybook/react";
4+
5+
import { ResultTablesHeader as ResultTablesHeaderComponent } from "../../view/results/ResultTablesHeader";
6+
7+
import "../../view/results/resultsView.css";
8+
9+
export default {
10+
title: "Results/Result Tables Header",
11+
component: ResultTablesHeaderComponent,
12+
} as Meta<typeof ResultTablesHeaderComponent>;
13+
14+
const Template: StoryFn<typeof ResultTablesHeaderComponent> = (args) => (
15+
<ResultTablesHeaderComponent {...args} />
16+
);
17+
18+
export const ResultTablesHeader = Template.bind({});
19+
ResultTablesHeader.args = {
20+
queryName: "test query",
21+
queryPath: "/a/b/c/query.ql",
22+
selectedTable: "#select",
23+
parsedResultSets: {
24+
pageNumber: 1,
25+
pageSize: 10,
26+
numPages: 2,
27+
numInterpretedPages: 2,
28+
resultSetNames: ["#select", "alerts"],
29+
resultSet: {
30+
t: "InterpretedResultSet",
31+
schema: {
32+
name: "#select",
33+
rows: 15,
34+
columns: [
35+
{
36+
name: "x",
37+
kind: "s",
38+
},
39+
],
40+
},
41+
name: "#select",
42+
interpretation: {
43+
sourceLocationPrefix: "/home/bulk-builder/bulk-builder",
44+
numTruncatedResults: 0,
45+
numTotalResults: 15,
46+
data: {
47+
t: "SarifInterpretationData",
48+
version: "2.1.0",
49+
runs: [],
50+
},
51+
},
52+
},
53+
},
54+
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import * as React from "react";
2+
3+
import { Meta, StoryFn } from "@storybook/react";
4+
5+
import { ClickableLocation as ClickableLocationComponent } from "../../../view/results/locations/ClickableLocation";
6+
7+
import "../../../view/results/resultsView.css";
8+
9+
export default {
10+
title: "Results/Clickable Location",
11+
component: ClickableLocationComponent,
12+
} as Meta<typeof ClickableLocationComponent>;
13+
14+
const Template: StoryFn<typeof ClickableLocationComponent> = (args) => (
15+
<ClickableLocationComponent {...args} />
16+
);
17+
18+
export const ClickableLocation = Template.bind({});
19+
ClickableLocation.args = {
20+
loc: {
21+
uri: "file:/home/runner/work/sql2o-example/sql2o-example/src/main/java/org/example/HelloController.java",
22+
startLine: 22,
23+
startColumn: 27,
24+
endLine: 22,
25+
endColumn: 57,
26+
},
27+
label: "url : String",
28+
};

extensions/ql-vscode/src/view/common/TextButton.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,22 @@ const StyledButton = styled.button<{ size: Size }>`
1515
const TextButton = ({
1616
size,
1717
onClick,
18+
className,
19+
title,
1820
children,
1921
}: {
2022
size?: Size;
2123
onClick: (e: React.MouseEvent) => void;
24+
className?: string;
25+
title?: string;
2226
children: React.ReactNode;
2327
}) => (
24-
<StyledButton size={size} onClick={onClick}>
28+
<StyledButton
29+
size={size}
30+
onClick={onClick}
31+
className={className}
32+
title={title}
33+
>
2534
{children}
2635
</StyledButton>
2736
);

extensions/ql-vscode/src/view/compare/CompareTable.tsx

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,19 @@ import { ResultRow } from "../../common/bqrs-cli-types";
77
import RawTableRow from "../results/RawTableRow";
88
import { vscode } from "../vscode-api";
99
import { sendTelemetry } from "../common/telemetry";
10+
import TextButton from "../common/TextButton";
11+
import { styled } from "styled-components";
1012

1113
interface Props {
1214
comparison: SetComparisonsMessage;
1315
}
1416

17+
const OpenButton = styled(TextButton)`
18+
cursor: pointer;
19+
text-decoration: underline;
20+
padding: 0;
21+
`;
22+
1523
export default function CompareTable(props: Props) {
1624
const comparison = props.comparison;
1725
const rows = props.comparison.rows!;
@@ -46,32 +54,14 @@ export default function CompareTable(props: Props) {
4654
<thead>
4755
<tr>
4856
<td>
49-
{/*
50-
eslint-disable-next-line
51-
jsx-a11y/anchor-is-valid,
52-
jsx-a11y/click-events-have-key-events,
53-
jsx-a11y/no-static-element-interactions
54-
*/}
55-
<a
56-
onClick={() => openQuery("from")}
57-
className="vscode-codeql__compare-open"
58-
>
57+
<OpenButton onClick={() => openQuery("from")}>
5958
{comparison.stats.fromQuery?.name}
60-
</a>
59+
</OpenButton>
6160
</td>
6261
<td>
63-
{/*
64-
eslint-disable-next-line
65-
jsx-a11y/anchor-is-valid,
66-
jsx-a11y/click-events-have-key-events,
67-
jsx-a11y/no-static-element-interactions
68-
*/}
69-
<a
70-
onClick={() => openQuery("to")}
71-
className="vscode-codeql__compare-open"
72-
>
62+
<OpenButton onClick={() => openQuery("to")}>
7363
{comparison.stats.toQuery?.name}
74-
</a>
64+
</OpenButton>
7565
</td>
7666
</tr>
7767
<tr>

extensions/ql-vscode/src/view/results/AlertTable.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { AlertTableHeader } from "./AlertTableHeader";
2222
import { SarifMessageWithLocations } from "./locations/SarifMessageWithLocations";
2323
import { SarifLocation } from "./locations/SarifLocation";
2424
import { EmptyQueryResultsMessage } from "./EmptyQueryResultsMessage";
25+
import TextButton from "../common/TextButton";
2526
import { AlertTableDropdownIndicatorCell } from "./AlertTableDropdownIndicatorCell";
2627

2728
type AlertTableProps = ResultTableProps & {
@@ -74,13 +75,9 @@ export class AlertTable extends React.Component<
7475
return (
7576
<span>
7677
No Alerts. See{" "}
77-
{/*
78-
eslint-disable-next-line
79-
jsx-a11y/anchor-is-valid,
80-
*/}
81-
<a href="#" onClick={this.props.showRawResults}>
78+
<TextButton onClick={this.props.showRawResults}>
8279
raw results
83-
</a>
80+
</TextButton>
8481
.
8582
</span>
8683
);

extensions/ql-vscode/src/view/results/ResultTablesHeader.tsx

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import {
88
ParsedResultSets,
99
} from "../../common/interface-types";
1010
import { basename } from "../../common/path";
11+
import { styled } from "styled-components";
12+
import TextButton from "../common/TextButton";
1113

1214
interface Props {
1315
queryName: string;
@@ -16,6 +18,47 @@ interface Props {
1618
selectedTable: string;
1719
}
1820

21+
const Container = styled.span`
22+
display: flex;
23+
padding: 0.5em 0;
24+
align-items: center;
25+
top: 0;
26+
background-color: var(--vscode-editorGutter-background);
27+
position: sticky;
28+
z-index: 1;
29+
`;
30+
31+
const PaginationButton = styled.button`
32+
padding: 0.3rem;
33+
margin: 0.2rem;
34+
border: 0;
35+
font-size: large;
36+
color: var(--vscode-editor-foreground);
37+
background-color: var(--vscode-editorGutter-background);
38+
cursor: pointer;
39+
opacity: 0.8;
40+
41+
&:hover {
42+
opacity: 1;
43+
}
44+
`;
45+
46+
const PageNumberInput = styled.input`
47+
border-radius: 0;
48+
padding: 0.3rem;
49+
margin: 0.2rem;
50+
width: 2rem;
51+
color: var(--vscode-editor-foreground);
52+
border: 0;
53+
border-bottom: 1px solid var(--vscode-editor-foreground);
54+
background-color: var(--vscode-editorGutter-background);
55+
outline: none;
56+
`;
57+
58+
const OpenQueryLink = styled(TextButton)`
59+
text-decoration: none;
60+
`;
61+
1962
export function ResultTablesHeader(props: Props) {
2063
const { queryPath, queryName, parsedResultSets, selectedTable } = props;
2164

@@ -104,9 +147,9 @@ export function ResultTablesHeader(props: Props) {
104147
}, [queryPath]);
105148

106149
return (
107-
<span className="vscode-codeql__table-selection-pagination">
108-
<button onClick={prevPageHandler}>&#xab;</button>
109-
<input
150+
<Container>
151+
<PaginationButton onClick={prevPageHandler}>&#xab;</PaginationButton>
152+
<PageNumberInput
110153
type="number"
111154
size={3}
112155
value={selectedPage}
@@ -117,24 +160,16 @@ export function ResultTablesHeader(props: Props) {
117160
onKeyDown={onKeyDownHandler}
118161
/>
119162
<span>/&nbsp;{numPages}</span>
120-
<button value=">" onClick={nextPageHandler}>
163+
<PaginationButton value=">" onClick={nextPageHandler}>
121164
&#xbb;
122-
</button>
165+
</PaginationButton>
123166
<div className={tableHeaderItemClassName}>{queryName}</div>
124167
<div className={tableHeaderItemClassName}>
125-
{/*
126-
eslint-disable-next-line
127-
jsx-a11y/anchor-is-valid
128-
*/}
129-
<a
130-
href="#"
131-
onClick={openQueryHandler}
132-
className="vscode-codeql__result-table-location-link"
133-
>
168+
<OpenQueryLink onClick={openQueryHandler}>
134169
Open {basename(queryPath)}
135-
</a>
170+
</OpenQueryLink>
136171
</div>
137-
</span>
172+
</Container>
138173
);
139174
}
140175

0 commit comments

Comments
 (0)