diff --git a/.circleci/config.yml b/.circleci/config.yml
index 803e5ea88..75ed4940b 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -1,13 +1,20 @@
-version: 2
+version: 2.1
jobs:
"server-test":
docker:
- image: circleci/python:3.7.6-node-browsers
+ environment:
+ PERCY_PARALLEL_TOTAL: -1
- image: cypress/base:10
steps:
- checkout
+ - run:
+ name: Inject Percy Environment variables
+ command: |
+ echo 'export PERCY_TOKEN="$PERCY_TOKEN_E2E"' >> $BASH_ENV
+
- restore_cache:
key: dep-{{ .Branch }}-{{ checksum "package-lock.json" }}-{{ checksum "package.json" }}-{{ checksum ".circleci/config.yml" }}
- run:
@@ -44,6 +51,10 @@ jobs:
command: |
. venv/bin/activate
npm run test.server
+ - run:
+ name: 🦔 percy finalize
+ command: npx percy finalize --all
+ when: always
"standalone-test":
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 98da0dddf..37f9decc7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- [#841](https://github.com/plotly/dash-table/pull/841)
- Fix prop-types regression causing console errors in browser devtools
- Fix syntax highlighting regression for Markdown cells
+- [#844](https://github.com/plotly/dash-table/pull/844) Fix a bug where the table is using classes that are styled by Bootstrap
- [#842](https://github.com/plotly/dash-table/pull/842) Fix a regression introduced with [#722](https://github.com/plotly/dash-table/pull/722) causing the tooltips to be misaligned with respect to their parent cell and incompletely addressed in [#817](https://github.com/plotly/dash-table/pull/817)
### Added
diff --git a/dev-requirements.txt b/dev-requirements.txt
index ff7e6f601..54c6d04fc 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -1,3 +1,4 @@
+dash-bootstrap-components==0.10.7
pandas
preconditions
xlrd
\ No newline at end of file
diff --git a/package.json b/package.json
index 0999bc6ea..23deb5851 100644
--- a/package.json
+++ b/package.json
@@ -40,7 +40,7 @@
"postbuild": "es-check es5 dash_table/*.js",
"format": "run-s private::format.*",
"lint": "run-s private::lint.*",
- "test.server": "pytest tests/selenium",
+ "test.server": "pytest --nopercyfinalize tests/selenium",
"test.standalone": "run-p --race private::host_js private::test.standalone",
"test.unit": "run-s private::test.python private::test.unit",
"test.visual": "build-storybook && percy-storybook",
diff --git a/src/dash-table/components/ControlledTable/index.tsx b/src/dash-table/components/ControlledTable/index.tsx
index 0e0c87124..b205cdd34 100644
--- a/src/dash-table/components/ControlledTable/index.tsx
+++ b/src/dash-table/components/ControlledTable/index.tsx
@@ -1010,7 +1010,7 @@ export default class ControlledTable extends PureComponent<
{arrayMap3(
diff --git a/src/dash-table/components/Table/Table.less b/src/dash-table/components/Table/Table.less
index def317038..a303dbb0c 100644
--- a/src/dash-table/components/Table/Table.less
+++ b/src/dash-table/components/Table/Table.less
@@ -222,6 +222,11 @@
flex-direction: row;
position: relative;
+ // This overrides Bootstrap 3.4.1 body styling
+ // https://github.com/twbs/bootstrap/blob/v3-dev/dist/css/bootstrap.css#L1087
+ // Also unapplies with the latest `in development` 5.0.0-alpha2 (https://github.com/twbs/bootstrap/blob/main/dist/css/bootstrap.css#L51)
+ line-height: initial;
+
// This overrides Chrome's default `font-size: medium;` which is causing performance issues
// with AutoInputResize sub-component in react-select
// https://github.com/JedWatson/react-input-autosize/blob/05b0f86a7f8b16de99c2b31296ff0d3307f15957/src/AutosizeInput.js#L58
@@ -234,6 +239,19 @@
}
}
+ input[type="radio"] {
+ // These override Bootstrap 3.4.1 type="radio" styling
+ // https://github.com/twbs/bootstrap/blob/v3-dev/dist/css/bootstrap.css#L2621
+ // This is not a problem with the latest `in development` 5.0.0-alpha2
+ margin: initial;
+ line-height: initial;
+ // These override Bootstrap 4.5.0 type="radio" styling
+ // https://github.com/twbs/bootstrap/blob/v4-dev/dist/css/bootstrap.css#L287
+ // This is not a problem with the latest `in development` 5.0.0-alpha2
+ box-sizing: initial;
+ padding: initial;
+ }
+
.dash-spreadsheet-inner {
box-sizing: border-box;
display: flex;
@@ -295,7 +313,7 @@
}
&:not(.dash-empty-11) {
- .row-0 {
+ .dt-table-container__row-0 {
tr:last-of-type {
td, th {
border-bottom: none !important;
@@ -344,13 +362,13 @@
&.dash-virtualized {
overflow: hidden !important;
- .row-0 {
+ .dt-table-container__row-0 {
display: flex;
flex: 0 0 auto;
flex-direction: row;
}
- .row-1 {
+ .dt-table-container__row-1 {
display: flex;
flex-direction: row;
overflow: auto;
diff --git a/tests/cypress/src/DashTable.ts b/tests/cypress/src/DashTable.ts
index e27b2105e..ad07e4809 100644
--- a/tests/cypress/src/DashTable.ts
+++ b/tests/cypress/src/DashTable.ts
@@ -149,7 +149,7 @@ export class DashTableHelper {
}
public toggleScroll(toggled: boolean) {
- cy.get('.row-1').then($el => {
+ cy.get('.dt-table-container__row-1').then($el => {
$el[0].style.overflow = toggled ? '' : 'unset';
});
}
diff --git a/tests/cypress/tests/standalone/scrolling_test.ts b/tests/cypress/tests/standalone/scrolling_test.ts
index fb583f945..9d129d990 100644
--- a/tests/cypress/tests/standalone/scrolling_test.ts
+++ b/tests/cypress/tests/standalone/scrolling_test.ts
@@ -21,7 +21,7 @@ variants.forEach(([mode, flavors]) => {
DashTable.clickCellById(0, 'rows');
DashTable.getSelectedCells().should('have.length', 1);
- cy.get('.row-1').scrollTo(0, 1000);
+ cy.get('.dt-table-container__row-1').scrollTo(0, 1000);
DashTable.getSelectedCells().should('have.length', 0);
});
@@ -29,10 +29,10 @@ variants.forEach(([mode, flavors]) => {
DashTable.clickCellById(0, 'rows');
DashTable.getActiveCell().should('have.length', 1);
- cy.get('.row-1').scrollTo(0, 1000);
+ cy.get('.dt-table-container__row-1').scrollTo(0, 1000);
DashTable.getActiveCell().should('have.length', 0);
- cy.get('.row-1').scrollTo(0, 0);
+ cy.get('.dt-table-container__row-1').scrollTo(0, 0);
DashTable.getActiveCell().should('have.length', 1);
});
@@ -45,10 +45,10 @@ variants.forEach(([mode, flavors]) => {
DashTable.getSelectedCells().should('have.length', 6);
- cy.get('.row-1').scrollTo(0, 1000);
+ cy.get('.dt-table-container__row-1').scrollTo(0, 1000);
DashTable.getSelectedCells().should('have.length', 0);
- cy.get('.row-1').scrollTo(0, 0);
+ cy.get('.dt-table-container__row-1').scrollTo(0, 0);
DashTable.getSelectedCells().should('have.length', 6);
});
@@ -57,7 +57,7 @@ variants.forEach(([mode, flavors]) => {
DashTable.clickCell(0, 0);
DashTable.toggleScroll(true);
- cy.get('.row-1').scrollTo(0, 1000);
+ cy.get('.dt-table-container__row-1').scrollTo(0, 1000);
cy.wait(1000);
DashTable.clickCell(10, 1);
diff --git a/tests/selenium/conftest.py b/tests/selenium/conftest.py
index 176b45381..0530fa14b 100644
--- a/tests/selenium/conftest.py
+++ b/tests/selenium/conftest.py
@@ -376,9 +376,7 @@ def test(request, dash_thread_server, tmpdir):
remote_url=request.config.getoption("remote_url"),
headless=request.config.getoption("headless"),
options=request.config.hook.pytest_setup_options(),
- download_path=tmpdir.mkdir("download").strpath,
- percy_assets_root=request.config.getoption("percy_assets"),
+ download_path=tmpdir.mkdir("dt-download").strpath,
percy_finalize=request.config.getoption("nopercyfinalize"),
- percy_run=False,
) as dc:
yield dc
diff --git a/tests/selenium/test_bootstrap.py b/tests/selenium/test_bootstrap.py
new file mode 100644
index 000000000..c38f0bb9c
--- /dev/null
+++ b/tests/selenium/test_bootstrap.py
@@ -0,0 +1,76 @@
+import dash
+import pytest
+
+import dash_bootstrap_components as dbc
+import dash_html_components as html
+from dash_table import DataTable
+
+import pandas as pd
+
+url = "https://github.com/plotly/datasets/raw/master/" "26k-consumer-complaints.csv"
+rawDf = pd.read_csv(url)
+df = rawDf.to_dict("rows")
+
+
+def get_app(fixed_rows, fixed_columns, ops):
+ app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
+
+ props = dict(
+ id="table",
+ data=df[0:250],
+ columns=[
+ {"name": i, "id": i, "hideable": i == "Complaint ID"} for i in rawDf.columns
+ ],
+ style_table=dict(height="500px", maxHeight="500px", overflow="auto"),
+ editable=True,
+ sort_action="native",
+ include_headers_on_copy_paste=True,
+ **fixed_rows,
+ **fixed_columns,
+ **ops
+ )
+
+ app.layout = html.Div([DataTable(**props)])
+
+ return app
+
+
+@pytest.mark.parametrize(
+ "fixed_rows,fixed_rows_description",
+ [(dict(), "unfixed_rows"), (dict(fixed_rows=dict(headers=True)), "fixed_rows")],
+)
+@pytest.mark.parametrize(
+ "fixed_columns,fixed_columns_description",
+ [
+ (dict(), "unfixed_columns"),
+ (dict(fixed_columns=dict(headers=True)), "fixed_columns"),
+ ],
+)
+@pytest.mark.parametrize(
+ "ops,ops_description",
+ [
+ (dict(), "ops: none"),
+ (dict(row_selectable="single", row_deletable=True), "ops: sinle+deletable"),
+ (dict(row_selectable="multi", row_deletable=True), "ops: multi+deletable"),
+ ],
+)
+def test_tbbs001_display(
+ dash_thread_server,
+ dash_duo,
+ test,
+ fixed_rows,
+ fixed_columns,
+ ops,
+ fixed_rows_description,
+ fixed_columns_description,
+ ops_description,
+):
+ test.start_server(get_app(fixed_rows, fixed_columns, ops))
+
+ test.table("table").is_ready()
+
+ test.percy_snapshot(
+ "DataTable Bootstrap side-effects with rows={} columns={} ops={}".format(
+ fixed_rows_description, fixed_columns_description, ops_description
+ )
+ )
diff --git a/tests/selenium/test_scrolling.py b/tests/selenium/test_scrolling.py
index bd7cea152..f70da7a4c 100644
--- a/tests/selenium/test_scrolling.py
+++ b/tests/selenium/test_scrolling.py
@@ -29,13 +29,15 @@ def get_margin(test):
def get_scroll(test):
return test.driver.execute_script(
- "return document.querySelector('#table .row-1').scrollLeft;"
+ "return document.querySelector('#table .dt-table-container__row-1').scrollLeft;"
)
def scroll_by(test, value):
test.driver.execute_script(
- "document.querySelector('#table .row-1').scrollBy({}, 0);".format(value)
+ "document.querySelector('#table .dt-table-container__row-1').scrollBy({}, 0);".format(
+ value
+ )
)
diff --git a/tests/visual/percy-storybook/Hideable.percy.tsx b/tests/visual/percy-storybook/Hideable.percy.tsx
index e93fd417e..2b8b60e5d 100644
--- a/tests/visual/percy-storybook/Hideable.percy.tsx
+++ b/tests/visual/percy-storybook/Hideable.percy.tsx
@@ -6,6 +6,7 @@ import { storiesOf } from '@storybook/react';
import DataTable from 'dash-table/dash/DataTable';
import dataset from './../../assets/gapminder.csv';
+
const result = parser.parse(dataset, { delimiter: ',', header: true });
const getColumns = () => R.addIndex(R.map)(