I’m creating a TemplateRendererFactory, and having problems making a <vaadin-button>
with a VaadinIcon prefix. I successfully implemented one that never has a Button label (button with only an icon). This is the working implementation for that:
public static <SOURCE> TemplateRenderer<SOURCE> iconButton(ValueProvider<SOURCE, VaadinIcon> iconProvider, SerializableConsumer<SOURCE> clickEvent){
String id = UUID.randomUUID().toString();
return TemplateRenderer.<SOURCE> of("<vaadin-button on-click='buttonClicked' theme='icon' class='template-renderer-button'><iron-icon icon='vaadin:[[item.iconType_"+id+"]
]' slot='prefix'></iron-icon></vaadin-button>")
.withProperty("iconType_"+id, item -> iconProvider.apply(item).name().toLowerCase(Locale.ENGLISH).replace('_', '-'))
.withEventHandler("buttonClicked", clickEvent);
}
An important aspect of that button is the theme='icon'
which takes care of reducing excess space/margins so that the icon is centered nicely in the button.
So far so good.
Now I want to have also a labelProvider, and I need to set the button’s theme to icon
if the provided label is empty.
This is my implementation, which I would expect to work:
public static <SOURCE> TemplateRenderer<SOURCE> iconButton(ValueProvider<SOURCE, String> labelProvider, ValueProvider<SOURCE, VaadinIcon> iconProvider, SerializableConsumer<SOURCE> clickEvent){
String id = UUID.randomUUID().toString();
return TemplateRenderer.<SOURCE> of("<vaadin-button on-click='buttonClicked' theme='[[item.theme_"+id+"]
]' class='template-renderer-button'><iron-icon icon='vaadin:[[item.iconType_"+id+"]
]' slot='prefix'></iron-icon>[[item.label_"+id+"]
]</vaadin-button>")
.withProperty("theme_"+id, item -> Strings.isEmpty(labelProvider.apply(item)) ? "icon" : "")
.withProperty("label_"+id, item -> {
String labelValue = labelProvider.apply(item);
return Strings.isEmpty(labelValue) ? "" : labelValue;
})
.withProperty("iconType_"+id, item -> iconProvider.apply(item).name().toLowerCase(Locale.ENGLISH).replace('_', '-'))
.withEventHandler("buttonClicked", clickEvent);
}
If the provided label is empty, the rendered button should have the attribute theme='icon'
, but it does not.
Why does this not work? Any help or pointers are appreciated.
more code for reproduction, and a screenshot of the result:
@Route(value = "Test")
public class TestView extends VerticalLayout {
public TestView() {
ValueProvider<String, VaadinIcon> iconProvider = item -> VaadinIcon.CHECK_CIRCLE;
SerializableConsumer<String> notifyString = item -> Notification.show(item);
Grid<String> templateRendererGrid = new Grid<>(String.class, false);
// theme='icon' is applied
templateRendererGrid.addColumn(TemplateRendererFactory.iconButton(iconProvider, notifyString)).setHeader("no-label API");
// no theme is applied (correct!)
templateRendererGrid.addColumn(TemplateRendererFactory.iconButton(item -> "Label", iconProvider, notifyString)).setHeader("Provided Label");
// no theme is applied (wrong!)
templateRendererGrid.addColumn(TemplateRendererFactory.iconButton(item -> null, iconProvider, notifyString)).setHeader("Provided Label: null");
templateRendererGrid.setItems("a", "b", "c");
templateRendererGrid.setHeightByRows(true);
templateRendererGrid.getColumns().forEach(row -> row.setResizable(true));
add(templateRendererGrid);
}
}
![grid result]
(https://i.imgur.com/uU3S1uR.png)