Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
7394393
refactor virtualization, virtualization settings, and derived props
Sep 20, 2018
81e0802
refactor renaming paging / pagination props
Sep 20, 2018
646068b
refactor virtual, viewport and pagination into adapters
Sep 20, 2018
3b13dbb
isolate derived props
Sep 20, 2018
4e0ecad
build update
Sep 20, 2018
fadbe4b
fix regression
Sep 20, 2018
8c60f0b
improve typing
Sep 20, 2018
7013574
fix test regression
Sep 20, 2018
b606834
simplify pagination adapter / refactor
Sep 20, 2018
ec68944
lint
Sep 20, 2018
ba80945
clean up unused props
Sep 20, 2018
f9ce473
- change factory
Sep 20, 2018
78a1844
Merge remote-tracking branch 'origin/master' into 3.0-props-refactoring
Sep 20, 2018
452de9b
fix lint
Sep 20, 2018
8ec667e
bump version
Sep 21, 2018
b334918
add dash level props for virtual_dataframe
Sep 21, 2018
1ad6d66
cleaup offsets
Sep 21, 2018
651682f
triad validation
Sep 21, 2018
3a8e448
- define external facing classes and attributes
Sep 21, 2018
1c39abb
fix regression, update build
Sep 21, 2018
b559a47
fix test regression (invalid props)
Sep 21, 2018
77c21b4
update test name
Sep 21, 2018
80a2c02
refactor fp / derived props
Sep 23, 2018
2b674ee
derived props
Sep 23, 2018
b2fc917
refactor viewport and virtual controlled props
Sep 23, 2018
6ba5403
fix fp regression
Sep 23, 2018
e546390
fix fp regression
Sep 23, 2018
a520da6
refactor controlled table / table fp
Sep 23, 2018
d9e294d
controlled table purecomponent
Sep 23, 2018
770effa
fix test (rebrake it!)
Sep 23, 2018
6577df5
fix selection regression for be paging/sorting/filtering
Sep 24, 2018
e86b8fd
improve re-renders & controlled props
Sep 24, 2018
c816691
fix test regressions
Sep 24, 2018
f02ee15
update inner-selection fixture
Sep 24, 2018
cd06e6c
merge master into 3.0-props-refactoring
Sep 24, 2018
0aba66b
Merge remote-tracking branch 'origin/3.0-props-refactoring' into 3.0-…
Sep 24, 2018
5af4a70
remove useless spy
Sep 24, 2018
dd70844
Merge remote-tracking branch 'origin/3.0-props-refactoring' into 3.0-…
Sep 24, 2018
7414d0b
- control columns into visible columns
Sep 24, 2018
71a09a8
update changelog
Sep 24, 2018
9e89e8d
clean up header factory
Sep 24, 2018
4d71b40
apply style on first controlled table render
Sep 25, 2018
e1be8a7
Merge remote-tracking branch 'origin/develop' into 3.0-clean-offsets
Sep 25, 2018
3e53af1
typo/merge miss
Sep 25, 2018
0304c69
derived visible columns
Sep 25, 2018
16730e5
- visual tests for hidden columns
Sep 25, 2018
6ffd3c2
rename functions
Sep 25, 2018
d38c599
- fix dropdown styling regression
Sep 25, 2018
8be5143
lint
Sep 25, 2018
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
36 changes: 35 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,4 +232,38 @@ Derived properties allow the component to expose complex state that can be usefu
- derived_virtual_dataframe
- derived_virtual_indices

In the event where sorting, filtering or pagination is done on the Dash Server, it is possible that some or all derived dataframes will be equal to the dataframe prop.
In the event where sorting, filtering or pagination is done on the Dash Server, it is possible that some or all derived dataframes will be equal to the dataframe prop.

## RC2 - Clean up column offsets

- 1 new internal facing derived/controlled property:
columns: Columns -> columns: VisibleColumns
Gets rid of conditional processing for hidden columns in the cell and header factories as well as in navigation/selection handlers

- A bunch of offsets were introduced to the table in the previous development cycle (2.x -> 3.0). Turns out these offsets are neither useful or necessary
- Validate compatibility of filtering, sorting, pagination
- External facing classes and attributes
* (ATTRIBUTE) data-dash-column=<columnId>

.dash-cell,
.dash-header {
&[data-dash-column='ticker'] {
// styling
}
}

* (CLASS) dash-cell
* (CLASS) dash-header

* (CLASS) dash-delete-cell
* (CLASS) dash-delete-header
* (CLASS) dash-select-cell
* (CLASS) dash-select-header

* (CLASS) dash-cell-value

* (CLASS) dash-freeze-left
* (CLASS) dash-freeze-top
* (CLASS) dash-spreadsheet
* (CLASS) dash-spreadsheet-container
* (CLASS) dash-spreadsheet-inner
6 changes: 3 additions & 3 deletions dash_table/bundle.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions dash_table/demo.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dash_table/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dash-table",
"version": "3.1.0rc1",
"version": "3.1.0rc2",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bump version

"description": "Dash table",
"main": "build/index.js",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion demo/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class App extends Component {
}
],
table_style: [
{ selector: '.dash-spreadsheet.freeze-left', rule: 'width: 1000px; max-width: 1000px;' }
{ selector: '.dash-spreadsheet.dash-freeze-left', rule: 'width: 1000px; max-width: 1000px;' }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style -- add prefix for external/contract classes

]
}
};
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dash-table",
"version": "3.1.0rc1",
"version": "3.1.0rc2",
"description": "Dash table",
"main": "build/index.js",
"scripts": {
Expand Down
23 changes: 23 additions & 0 deletions src/dash-table/Table.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,32 @@ import PropTypes from 'prop-types';
import RealTable from 'dash-table/components/Table';

import 'dash-table/style/component.less';
import Logger from 'core/Logger';

export default class Table extends Component {
render() {
const {
filtering,
sorting,
pagination_mode
} = this.props;

function isFrontEnd(value: any) {
return ['fe', true, false].indexOf(value) !== -1;
}

function isBackEnd(value: any) {
return ['be', false].indexOf(value) !== -1;
}

const isValid = isFrontEnd(pagination_mode) ||
(isBackEnd(filtering) && isBackEnd(sorting));

if (!isValid) {
Logger.error(`Invalid combination of filtering / sorting / pagination`, filtering, sorting, pagination_mode);
return (<div>Invalid props combination</div>);
}

return (<RealTable {...this.props} />);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Table.js is the Dash component wrapper, its role is to

  • bridge the dash and TS worlds
  • make sure the props are sane

Here we add the first sanity check: are the sorting/paging/filtering props compatible with each other?

If paging is done BE -> sort/filter must be off or in BE
Otherwise all combos are valid

}
}
Expand Down
6 changes: 5 additions & 1 deletion src/dash-table/components/Cell/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export default class Cell extends Component<ICellProps, ICellState> {
} = this.propsWithDefaults;

return [
'dash-cell',
...(active ? ['focused'] : []),
...(!editable ? ['cell--uneditable'] : []),
...(selected ? ['cell--selected'] : []),
Expand Down Expand Up @@ -113,7 +114,7 @@ export default class Cell extends Component<ICellProps, ICellState> {
const classes = [
...(active ? ['input-active'] : []),
...(focused ? ['focused'] : ['unfocused']),
...['cell-value']
...['dash-cell-value']
];

const attributes = {
Expand Down Expand Up @@ -219,11 +220,14 @@ export default class Cell extends Component<ICellProps, ICellState> {
}

render() {
const { property } = this.props;

return (<td
ref='td'
tabIndex={-1}
className={this.classes.join(' ')}
style={this.style}
data-dash-column={property}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of exposing the columns as column-{index} classes, expose as an attribute with value equal to column id -- this is more consistent with what the user gives us and less about implementation details

>
{this.renderInner()}
</td>);
Expand Down
2 changes: 1 addition & 1 deletion src/dash-table/components/Cell/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { ColumnId } from 'dash-table/components/Table/props';
export interface ICellProps {
active: boolean;
classes?: string[];
clearable: boolean;
clearable?: boolean;
conditionalDropdowns?: IConditionalDropdown[];
conditionalStyles?: IConditionalStyle[];
datum: any;
Expand Down
50 changes: 9 additions & 41 deletions src/dash-table/components/CellFactory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,8 @@ export default class CellFactory {

private handleClick = (idx: number, i: number, e: any) => {
const {
columns,
editable,
is_focused,
row_deletable,
row_selectable,
selected_cell,
setProps
} = this.props;
Expand All @@ -55,25 +52,13 @@ export default class CellFactory {
return;
}

// visible col indices
const columnIndexOffset =
(row_deletable ? 1 : 0) +
(row_selectable ? 1 : 0);

e.preventDefault();
const cellLocation: [number, number] = [idx, i + columnIndexOffset];
const cellLocation: [number, number] = [idx, i];
const newProps: Partial<ICellFactoryOptions> = {
is_focused: false,
active_cell: cellLocation
};

const vci: any[] = [];
columns.forEach((c, ci: number) => {
if (!c.hidden) {
vci.push(ci + columnIndexOffset);
}
});

const selectedRows = R.uniq(R.pluck(0, selected_cell)).sort((a, b) => a - b);
const selectedCols = R.uniq(R.pluck(1, selected_cell)).sort((a, b) => a - b);
const minRow = selectedRows[0];
Expand All @@ -89,7 +74,7 @@ export default class CellFactory {
R.min(minCol, cellLocation[1]),
R.max(minCol, cellLocation[1]) + 1
)
).filter(c => R.contains(c[1], vci)) as any;
) as any;
} else {
newProps.selected_cell = [cellLocation];
}
Expand All @@ -101,21 +86,14 @@ export default class CellFactory {
const {
editable,
is_focused,
row_deletable,
row_selectable,
setProps
} = this.props;

if (!editable) {
return;
}

// visible col indices
const columnIndexOffset =
(row_deletable ? 1 : 0) +
(row_selectable ? 1 : 0);

const cellLocation: [number, number] = [idx, i + columnIndexOffset];
const cellLocation: [number, number] = [idx, i];

if (!is_focused) {
e.preventDefault();
Expand Down Expand Up @@ -165,7 +143,7 @@ export default class CellFactory {

return !row_selectable ? null : (<td
key='select'
className='select-cell'
className='dash-select-cell'
style={{ width: `30px`, maxWidth: `30px`, minWidth: `30px` }}
>
<input
Expand Down Expand Up @@ -194,7 +172,7 @@ export default class CellFactory {

return !row_deletable ? null : (<td
key='delete'
className='delete-cell'
className='dash-delete-cell'
onClick={() => setProps(actions.deleteRow(idx, this.props))}
style={{ width: `30px`, maxWidth: `30px`, minWidth: `30px` }}
>
Expand All @@ -214,27 +192,17 @@ export default class CellFactory {
editable,
id,
is_focused,
row_deletable,
row_selectable,
selected_cell,
viewport
} = this.props;

const visibleColumns = columns.filter(column => !column.hidden);

const offset =
(row_deletable ? 1 : 0) +
(row_selectable ? 1 : 0);

return viewport.dataframe.map((datum, viewportIdx) => {
const realIdx = viewport.indices[viewportIdx];

const deleteCell = this.rowDeleteCell(realIdx);
const selectCell = this.rowSelectCell(realIdx);

const cells = visibleColumns.map((column, visibleIndex) => {
visibleIndex += offset;

const cells = columns.map((column, visibleIndex) => {
let legacyDropdown: any = (
(
dropdown_properties &&
Expand All @@ -249,7 +217,7 @@ export default class CellFactory {

const index = columns.indexOf(column);

const classes = [`column-${index + offset}`];
const classes = [`column-${index}`];

let conditionalDropdowns = column_conditional_dropdowns.find((cd: any) => cd.id === column.id);
let staticDropdown = column_static_dropdown.find((sd: any) => sd.id === column.id);
Expand All @@ -265,7 +233,7 @@ export default class CellFactory {

return (<Cell
key={`${column.id}-${visibleIndex}`}
active={active_cell[0] === viewportIdx && active_cell[1] === index + offset}
active={active_cell[0] === viewportIdx && active_cell[1] === index}
classes={classes}
clearable={column.clearable}
conditionalDropdowns={conditionalDropdowns}
Expand All @@ -278,7 +246,7 @@ export default class CellFactory {
onPaste={this.handlePaste}
onChange={this.getEventHandler(this.handleChange, realIdx, index)}
property={column.id}
selected={R.contains([viewportIdx, index + offset], selected_cell)}
selected={R.contains([viewportIdx, index], selected_cell)}
staticDropdown={staticDropdown}
staticStyle={staticStyle}
tableId={id}
Expand Down
Loading