Search code examples
vaadinvaadin8

Vaadin 8: can you right align a Button in a HorizontalLayout component cell of a TreeGrid component column?


I have a TreeGrid with 2 component columns. The first component column contains a HorizontalLayout with a Label and a Button. The second component column contains a HorizontalLayout with a Button. I was not able to right align the Button in the first component column. Is it doable? If it is not doable, do you have any workaround suggestions? My constraints are the TreeGrid, the 2 columns and that the first column should contain a Label and a right aligned Button. What i tried so far

TreeGrid<Object> treeGrid = new TreeGrid<>();
treeGrid.setSizeFull();
treeGrid.addComponentColumn(vp -> {
    Button button = new Button("button");
    HorizontalLayout cell = new HorizontalLayout(new Label("label"), button);
    cell.setSizeFull();
    cell.setExpandRatio(button, 1.0f);
    cell.setComponentAlignment(button, Alignment.MIDDLE_RIGHT);
    return cell;
}).setCaption("st column").setExpandRatio(1).setId("st column");
treeGrid.addComponentColumn(vp -> new HorizontalLayout(new Button("some other button")))
    .setCaption("nd column").setId("nd column").setWidth(200.0d);
TreeData<Object> objectTreeData = new TreeData<>();
objectTreeData.addRootItems(new Object());
treeGrid.setDataProvider(new TreeDataProvider<>(objectTreeData));
window.setContent(treeGrid);
UI.getCurrent().addWindow(window);
window.center();
window.setWidth("40%");
window.setHeight("40%");

The output is in the attached image.enter image description here


Solution

  • Looks like the node doesn't have a width set and the full width of the HorizontalLayout takes that width from the node rather than the entire cell.

    As a slightly hacky workaround you can use a StyleGenerator to give the column a style name (column.setStyleGenerator(item -> "myColumn");) and then add to your theme something like ".myColumn .v-treegrid-node {width:100%;}. If your theme now pushes the content slightly too far right, you could add some padding too to counteract that: .myColumn .v-horizontallayout {padding-right: 10px;}"

    If you add some hierarchy, you'll probably need to add more padding for each level: .myColumn .depth-1 .v-horizontallayout {padding-right: 26px;}, .myColumn .depth-2 .v-horizontallayout {padding-right: 42px;} and so forth (actual values would depend on your theme). Using plain Valo adds 1em (16px) of indent with each level of depth, which is what you need to counter.

    For a more complicated SASS solution, see how Valo does the indenting. Remember to add the basic padding from depth-0 level to the calculations.