rmuller
rmuller

Reputation: 12859

Using node icons in Vaadin Flow / 14 TreeGrid component

Example (VueJs / Vuetify) i want to achieve:

enter image description here

Vaadin only has TreeGrid#addHierarchyColumn(ValueProvider) which does not allow adding icons.

Upvotes: 2

Views: 737

Answers (2)

rmuller
rmuller

Reputation: 12859

Based on the answer of Tatu Lund we baked our own version, tested with Vaadin 14.1.23

/**
 * {@code IconTreeGrid} adds a convenience method for a `TreeGrid` with node icons.
 *
 * Based on these answers:
 *
 * + https://vaadin.com/forum/thread/17625675/treegrid-displaying-icon-for-hierachy-column
 * + https://stackoverflow.com/a/61268891/868941
 */
static class IconTreeGrid<T> extends TreeGrid<T> {

    IconTreeGrid(HierarchicalDataProvider<T, ?> dataProvider) {
        super(dataProvider);
    }

    public Column<T> addHierarchyColumn(Icon icon, ValueProvider<T, ?> valueProvider) {
        final Column<T> column = addColumn(TemplateRenderer.<T>of(
            "<vaadin-grid-tree-toggle leaf='[[item.leaf]]' expanded='{{expanded}}' level='[[level]]'>" +
            "<iron-icon icon='[[item.icon]]' style='margin-right: 0.2em; [[item.style]]'></iron-icon>[[item.name]]" +
            "</vaadin-grid-tree-toggle>")
            .withProperty("leaf", item -> !getDataCommunicator().hasChildren(item))
            .withProperty("icon", item -> icon.getElement().getAttribute("icon"))
            .withProperty("style", item -> icon.getElement().getAttribute("style"))
            .withProperty("name", item -> String.valueOf(valueProvider.apply(item))));
        final SerializableComparator<T> comparator =  (a, b) ->
            compareMaybeComparables(valueProvider.apply(a), valueProvider.apply(b));
        column.setComparator(comparator);
        return column;
    }

}

Works like a charm.

Upvotes: 3

Tatu Lund
Tatu Lund

Reputation: 10643

This feature is not yet in the Vaadin 14 framework, but it has just been actually implemented and is coming to the next minor version, i.e 14.2

Meanwhile it is possible to have a workaround using Template renderer, like I have done it in my FileSelect component.

Upvotes: 2

Related Questions