tabulator
tabulator copied to clipboard
Tree misaligned in 5.5, items change indentation when expanded/collapsed.
Describe the bug Tree nodes of various depths are aligned inconsistently. A node moves to the right when first collapsed; its children are moved to the left when expanded back.
Tabulator Info 5.5
Working Example 5.4 reference: https://jsfiddle.net/5wkmfh1o/135/ 5.5 regression: https://jsfiddle.net/4qg2Lomh/6/
To Reproduce Collapse, then expand the node "L 3 << Collapse/Expand".
Expected behavior Alignment in 5.5 identical to that in 5.4. The node that is collapsed/expanded and its children do not change their indentation.
Screenshots
Desktop: MacOS Chrome 19.0.6045.199
The problem is reproduced about half of the time: refresh repeatedly to see the change in alignment. https://jsfiddle.net/4qg2Lomh/6/
The indentation is created by assigning a left margin to the branch element (the HTML element that shows the corner/angle). Investigation shows that the width of this element is 0 for newly created tree children. This leads to wrong indentation, which is computed based on that width (so it gets worse with every further indentation level).
When the branch element is inserted it gets its initial width, but not when it is inserted the first time, which is the cause of the trouble. I cannot say why this is so, however.
do we have a work-around?
I'm afraid this is a fundamental problem. A new row is initialized in the virtual renderer before it is added to the DOM. This causes the branch element to stay with width 0, which ruins the indentation computation (which is done in the initialization step).
A possible solution would be to move the layoutRow()
call from the the "row-layout-after" event to any of the methods called for each row, after the row fragment has been added to the DOM. @olifolkerd would have to decide if that a good approach and how to change the current one.
is it fixed on 6 ? tnx
If the issue is still open it hasn't been fixed
Here are two possible workarounds:
Option 1
- Use your own expander element.
- Set the standard branch element width to 0 in your CSS.
- Assign a proper value to the
dataTreeChildIndent
(e.g. 16, which is a common width).
An example for the options to use:
const result: Options = {
index: options?.index ?? "id",
columns,
data: tableData,
frozenRows,
dataTree: options?.treeColumn != null,
dataTreeChildIndent: options?.treeChildIndent ?? 16,
dataTreeExpandElement: "<span class='treeToggle' />",
dataTreeCollapseElement: "<span class='treeToggle expanded' />",
dataTreeBranchElement: false,
...
};
This set of options will do 2 things: hide the standard branch element and show yours instead.
And the style for the default branch element:
.msg.treeGrid.tabulator .tabulator-row .tabulator-cell .tabulator-data-tree-branch-empty {
/*
* Keep the (hidden) tree branch element from automatic shrinking, as that creates an odd visual effect.
* Unfortunately, this element cannot be removed from the DOM, as it is used to determine the indentation.
*/
flex: none;
width: 0;
height: 100%;
}
Option 2
If you don't want to use an own branch element you can alternatively do an explicit reformat of the row that was expanded:
private reformatRowDelayed = (row: RowComponent): void => {
// Reformat the children after a moment, to fix wrong indentation. This is a regression introduced
// in Tabulator 5.5. Once this is fixed there, this method can be removed.
setTimeout(() => {
row.getTreeChildren().forEach((child) => {
child.reformat();
});
}, 10);
};