Open rolfsmeds opened 2 years ago
Possibly related: https://github.com/vaadin/web-components/issues/459
The example provided in the menu-bar docs is a good example of how to solve this using a factory method.
Regarding this:
The add-methods of MenuBar and ContextMenu could simply be overloaded with a second parameter for the prefix component: menubar.addItem(VaadinIcon.ABACUS.create(), "Calculate stuff");
I think this could be implemented with a default
method in the HasMenuItems interface. This solution overloads the other methods in the interface and provides developers with a one-line solution to add items with an icon and a label or just an icon.
default MenuItem addItem(Icon icon, String text, ComponentEventListener<ClickEvent<MenuItem>> clickListener) {
MenuItem item = addItem(icon, clickListener);
if (text != null) {
item.add(new Text(text));
}
return item;
}
This, however, doesn't provide a solution for ComboBox
or Select
since they don't implement the HasMenuItems
interface. It should also be noted, that additional styling might be needed to have the items render nicely in sub-menus
The solution above doesn't look quite good when items both with and without icon are mixed:
@Route("")
public class MainView extends VerticalLayout {
private static MenuItem addItem(HasMenuItems self, Icon icon, String text) {
MenuItem item = self.addItem(icon, event -> {});
if (text != null) {
item.add(new Text(text));
}
return item;
}
public MainView() {
final MenuBar menuBar = new MenuBar();
add(menuBar);
final MenuItem fooItem = menuBar.addItem("Foo");
addItem(fooItem.getSubMenu(), VaadinIcon.ABACUS.create(), "Abacus");
fooItem.getSubMenu().addItem("Text", e -> {});
}
}
The icon solution should look similar to checkable items solution:
The solution above doesn't look quite good when items both with and without icon are mixed
I think that case should be fixed with an empty icon instead of forcing the padding on all items.
Describe your motivation
Rendering icons or images as part of items in lists is an extremely common use case:
Yet implementing these with Vaadin components like
ComboBox
,Select
,MenuBar
andContextMenu
requires a significant amount of boilerplate code for creating the layout containing the image and the label, and applying a classname or a bit of inline css to it. What could be a single line of code tends to be closer to at least five, and it is far from trivial to figure out how to do it.Describe the solution you'd like
Simple, single-liner APIs for rendering images, icons, or why not any arbitrary component as a "prefix" to items in menus and lists.
Vaadin 8 had the
ItemIconGenerator
API, so that would seem like a pretty good option forComboBox
andSelect
(although I think ItemImageGenerator, or even ItemPrefixGenerator, would be preferable, as it's not always icons specifically).The add-methods of MenuBar and ContextMenu could simply be overloaded with a second parameter for the prefix component:
menubar.addItem(VaadinIcon.ABACUS.create(), "Calculate stuff");
In terms of implementation, it would seem logical to add a slot for the prefix element in
vaadin-item
, which all of the above components use for their items, and ensuring that it, and the label next to it, are rendered nicely.Additional context
This would also make it easier to migrate applications from Vaadin 7 and 8, in which corresponding APIs are used a lot.