Skip to content

chore: migrate reactstrap to react bootstrap #8897

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/accessibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ For example:
</Button>
```

Known reactstrap components that accept the `color` prop and work with custom Treeherder colors: `Badge`, `Button`, `Card`, `DropdownToggle`, `FormText`, `NavBar`, `Progress`, `Spinner`.
Known reactstrap components that accept the `color` prop and work with custom Treeherder colors: `Badge`, `Button`, `Card`, `Dropdown.Toggle`, `FormText`, `NavBar`, `Progress`, `Spinner`.

In case you need to add more custom colors, please add on [treeherder-custom-styles.css](https://github.com/mozilla/treeherder/blob/master/ui/css/treeherder-custom-styles.css#L348) style sheet.

Expand Down Expand Up @@ -102,7 +102,7 @@ If your case is more specific, please check [this guide](https://css-tricks.com/

## Interactive elements

When creating elements that have event listeners, prefer any component of the reactstrap interactive elements. Examples are: `Button`, `Input`, `DropdownToggle`. You can also choose a HTML `<a>` element.
When creating elements that have event listeners, prefer any component of the reactstrap interactive elements. Examples are: `Button`, `Input`, `Dropdown.Toggle`. You can also choose a HTML `<a>` element.

If you need to insert an event listener in a non-interactive element, such as a `span`, add also an `aria-role` of `button`, `link`, `checkbox`, or whatever seems closer to the functionality of the element.

Expand All @@ -116,10 +116,10 @@ If you need to insert an event listener in a non-interactive element, such as a

There is a special case when you are creating a dropdown menu. First of all, try to follow [reactstrap structure](https://reactstrap.github.io/components/dropdowns/).

Lastly, insert an additional tag `prop` to `DropdownItem` component.
Lastly, insert an additional tag `prop` to `Dropdown.Item` component.

```jsx
<DropdownItem tag="a"> Menu Item </DropdownItem>
<Dropdown.Item tag="a"> Menu Item </Dropdown.Item>
```

## Forms, inputs and buttons
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"prop-types": "15.8.1",
"query-string": "7.0.1",
"react": "18.3.1",
"react-bootstrap": "2.10.10",
"react-dates": "21.8.0",
"react-dom": "18.3.1",
"react-helmet": "6.1.0",
Expand All @@ -55,7 +56,6 @@
"react-split-pane": "0.1.92",
"react-table-6": "6.11.0",
"react-tabs": "6.1.0",
"reactstrap": "8.10.1",
"redoc": "2.4.0",
"redux": "4.2.1",
"redux-debounce": "1.0.1",
Expand Down
2 changes: 1 addition & 1 deletion ui/infra-compare/InfraCompareTable.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { Table } from 'reactstrap';
import { Table } from 'react-bootstrap';
import PropTypes from 'prop-types';

import { getJobsUrl } from '../helpers/url';
Expand Down
10 changes: 5 additions & 5 deletions ui/infra-compare/InfraCompareTableControls.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Container, CustomInput, Label } from 'reactstrap';
import { Container, Form } from 'react-bootstrap';

import FilterControls from '../shared/FilterControls';

Expand Down Expand Up @@ -110,11 +110,11 @@ export default class CompareTableControls extends React.Component {
updateFilter={this.updateFilter}
updateFilterText={this.updateFilterText}
/>
<Label for="filterPercent">Filter percentage: {filterPercent}%</Label>
<CustomInput
type="range"
<Form.Label htmlFor="filterPercent">
Filter percentage: {filterPercent}%
</Form.Label>
<Form.Range
id="filterPercent"
name="customSelect"
min={0}
max={20}
value={filterPercent}
Expand Down
127 changes: 63 additions & 64 deletions ui/infra-compare/InfraCompareTableRow.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import React from 'react';
import PropTypes from 'prop-types';
import { UncontrolledTooltip } from 'reactstrap';
import { OverlayTrigger, Tooltip } from 'react-bootstrap';

import { getJobsUrl } from '../helpers/url';

export default class InfraCompareTableRow extends React.PureComponent {
render() {
const {
hashkey,
rowLevelResults: {
suite,
platform,
Expand All @@ -24,80 +23,80 @@ export default class InfraCompareTableRow extends React.PureComponent {
} = this.props;

return (
<tr color="danger">
<tr className="table-danger">
<th className="text-left">{suite}</th>
<td>
<span
style={{ textDecoration: 'underline', color: 'blue' }}
id={`originalValue${hashkey}`}
>
{originalValue}
</span>
<UncontrolledTooltip
<OverlayTrigger
placement="top"
target={`originalValue${hashkey}`}
autohide={false}
overlay={
<Tooltip>
{originalJobs.size > 0 ? (
Array.from(originalJobs).map(([jobName, durations]) => (
<p key={jobName}>
{jobName}: {durations.join(', ')}
</p>
))
) : (
<p className="lead text-center">No jobs to show</p>
)}
<a
href={getJobsUrl({
repo: originalProject,
revision: originalRevision,
searchStr: `${platform} ${suite}`,
})}
target="_blank"
rel="noopener noreferrer"
>
Go to treeherder Job View
</a>
</Tooltip>
}
delay={{ show: 0, hide: 0 }}
>
{originalJobs.size > 0 ? (
Array.from(originalJobs).map(([jobName, durations]) => (
<p>
{jobName}: {durations.join(', ')}
</p>
))
) : (
<p className="lead text-center">No jobs to show</p>
)}
<a
href={getJobsUrl({
repo: originalProject,
revision: originalRevision,
searchStr: `${platform} ${suite}`,
})}
target="_blank"
rel="noopener noreferrer"
>
Go to treeherder Job View
</a>
</UncontrolledTooltip>
<span style={{ textDecoration: 'underline', color: 'blue' }}>
{originalValue}
</span>
</OverlayTrigger>
</td>
<td>
{originalValue < newValue && <span>&lt;</span>}
{originalValue > newValue && <span>&gt;</span>}
</td>
<td>
<span
style={{ textDecoration: 'underline', color: 'blue' }}
id={`newValue${hashkey}`}
<OverlayTrigger
placement="top"
overlay={
<Tooltip>
{newJobs.size > 0 ? (
Array.from(newJobs).map(([jobName, duration]) => (
<p key={jobName}>
{jobName}: {duration.join(', ')}
</p>
))
) : (
<p className="lead text-center">No jobs to show</p>
)}
<a
href={getJobsUrl({
repo: newProject,
revision: newRevision,
searchStr: `${platform} ${suite}`,
})}
target="_blank"
rel="noopener noreferrer"
>
Go to treeherder Job View
</a>
</Tooltip>
}
delay={{ show: 0, hide: 0 }}
>
{newValue}
</span>
<span style={{ textDecoration: 'underline', color: 'blue' }}>
{newValue}
</span>
</OverlayTrigger>
</td>
<UncontrolledTooltip
placement="top"
target={`newValue${hashkey}`}
autohide={false}
>
{newJobs.size > 0 ? (
Array.from(newJobs).map(([jobName, duration]) => (
<p>
{jobName}: {duration.join(', ')}
</p>
))
) : (
<p className="lead text-center">No jobs to show</p>
)}
<a
href={getJobsUrl({
repo: newProject,
revision: newRevision,
searchStr: `${platform} ${suite}`,
})}
target="_blank"
rel="noopener noreferrer"
>
Go to treeherder Job View
</a>
</UncontrolledTooltip>
<td>{originalFailures}</td>
<td>
{originalFailures < newFailures && <span>&lt;</span>}
Expand Down
4 changes: 2 additions & 2 deletions ui/infra-compare/InfraCompareTableView.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Col, Row, Container, Alert } from 'reactstrap';
import { Col, Row, Container, Alert } from 'react-bootstrap';

import ErrorMessages from '../shared/ErrorMessages';
import { genericErrorMessage, errorMessageClass } from '../helpers/constants';
Expand Down Expand Up @@ -211,7 +211,7 @@ export default class InfraCompareTableView extends React.Component {
{jobsNotDisplayed && jobsNotDisplayed.length > 0 && (
<Row className="pt-5 justify-content-center">
<Col small="12" className="px-0 max-width-default">
<Alert color="warning">
<Alert variant="warning">
<TruncatedText
title="Tests without results: "
maxLength={174}
Expand Down
2 changes: 1 addition & 1 deletion ui/intermittent-failures/App.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { Route, Switch, Redirect } from 'react-router-dom';
import { Container } from 'reactstrap';
import { Container } from 'react-bootstrap';
import { hot } from 'react-hot-loader/root';

import ErrorMessages from '../shared/ErrorMessages';
Expand Down
2 changes: 1 addition & 1 deletion ui/intermittent-failures/BugDetailsView.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { Row, Col, Breadcrumb, BreadcrumbItem } from 'reactstrap';
import { Row, Col, Breadcrumb, BreadcrumbItem } from 'react-bootstrap';
import { Link } from 'react-router-dom';
import ReactTable from 'react-table-6';
import PropTypes from 'prop-types';
Expand Down
18 changes: 4 additions & 14 deletions ui/intermittent-failures/DateOptions.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { ButtonDropdown, DropdownToggle } from 'reactstrap';
import { DropdownButton } from 'react-bootstrap';
import moment from 'moment';
import PropTypes from 'prop-types';

Expand All @@ -12,15 +12,10 @@ export default class DateOptions extends React.Component {
constructor(props) {
super(props);
this.state = {
dropdownOpen: false,
dateRange: '',
};
}

toggle = () => {
this.setState((prevState) => ({ dropdownOpen: !prevState.dropdownOpen }));
};

updateDateRange = (dateRange) => {
this.setState({ dateRange });
if (dateRange === 'custom range') {
Expand All @@ -42,7 +37,7 @@ export default class DateOptions extends React.Component {

render() {
const { updateState } = this.props;
const { dropdownOpen, dateRange } = this.state;
const { dateRange } = this.state;
const dateOptions = [
'last 7 days',
'last 30 days',
Expand All @@ -52,18 +47,13 @@ export default class DateOptions extends React.Component {

return (
<div className="d-inline-block">
<ButtonDropdown
className="mr-3"
isOpen={dropdownOpen}
toggle={this.toggle}
>
<DropdownToggle caret>date range</DropdownToggle>
<DropdownButton className="mr-3" title="date range">
<DropdownMenuItems
options={dateOptions}
updateData={this.updateDateRange}
selectedItem={dateRange}
/>
</ButtonDropdown>
</DropdownButton>
{dateRange === 'custom range' && (
<DateRangePicker updateState={updateState} />
)}
Expand Down
4 changes: 2 additions & 2 deletions ui/intermittent-failures/DateRangePicker.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { DateRangePickerPhrases } from 'react-dates/lib/defaultPhrases';
import { DateRangePicker as DatePickerAirbnb } from 'react-dates';
import moment from 'moment';
import PropTypes from 'prop-types';
import { Button } from 'reactstrap';
import { Button } from 'react-bootstrap';

import { ISODate } from './helpers';

Expand Down Expand Up @@ -91,7 +91,7 @@ export default class DateRangePicker extends React.Component {
isOutsideRange={(day) => moment().diff(day) < 0}
phrases={defaultPhrases}
/>
<Button color="secondary" className="ml-3" onClick={this.updateData}>
<Button variant="secondary" className="ml-3" onClick={this.updateData}>
update
</Button>
</div>
Expand Down
2 changes: 1 addition & 1 deletion ui/intermittent-failures/Graph.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { VictoryChart, VictoryLine, VictoryLegend } from 'victory';
import { Col } from 'reactstrap';
import { Col } from 'react-bootstrap';

const Graph = ({ graphData, title, legendData }) => (
<Col
Expand Down
4 changes: 2 additions & 2 deletions ui/intermittent-failures/GraphsContainer.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { Row, Button, Col } from 'reactstrap';
import { Row, Button, Col } from 'react-bootstrap';
import PropTypes from 'prop-types';

import Graph from './Graph';
Expand Down Expand Up @@ -59,7 +59,7 @@ export default class GraphsContainer extends React.Component {
{showAlternateView ? 'Show graph view' : 'Show table view'}
</Button>
<Button
color="secondary"
variant="secondary"
onClick={this.toggleGraph}
className="d-inline-block mr-3"
>
Expand Down
2 changes: 1 addition & 1 deletion ui/intermittent-failures/Layout.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { Container } from 'reactstrap';
import { Container } from 'react-bootstrap';
import PropTypes from 'prop-types';

import ErrorBoundary from '../shared/ErrorBoundary';
Expand Down
2 changes: 1 addition & 1 deletion ui/intermittent-failures/MainView.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { Row, Col, Breadcrumb, BreadcrumbItem } from 'reactstrap';
import { Row, Col, Breadcrumb, BreadcrumbItem } from 'react-bootstrap';
import PropTypes from 'prop-types';
import moment from 'moment';
import ReactTable from 'react-table-6';
Expand Down
Loading