vaadin / web-components

A set of high-quality standards based web components for enterprise web applications. Part of Vaadin 20+
https://vaadin.com/docs/latest/components
464 stars 83 forks source link

[tabs] Allow setting a action / suffix component #549

Open appreciated opened 4 years ago

appreciated commented 4 years ago

Description

First of all, I am not sure if this is a vaadin-tabs or a vaadin-tabs-flow issue for now I decided to open this issue here.

When using tabs to present content often a button to close open tabs and a button to open a new tab is needed. In browsers, this is usually being solved by offering the user a "+" action button directly beside the tabs.

grafik

While adding an extra component inside vaadin-tabs can be done easily. Adding such button seems not to be straightforward.

This feature can somehow be compared as a suffix/prefix as already available for components as vaadin-button or vaadin-textfield.

Expected outcome

vaadin-tabs should support setting one or multiple suffix (maybe also prefix but for my usecase this is irrelevant) component.

Actual outcome

vaadin-tabs does not support setting a suffix component.

Browsers Affected

Current Workaround

public class CustomTabs extends Tabs {

    private final Tab tab;
    private Runnable addListener;

    public CustomTabs() {
        setAutoselect(false);
        IconButton addButton = new IconButton(VaadinIcon.PLUS.create());
        addButton.getStyle()
                .set("padding", "0px")
                .set("font-size", "20px")
                .set("color", "black");
        tab = new Tab(addButton);
        tab.getStyle()
                .set("--lumo-primary-color", "transparent")
                .set("--lumo-contrast-60pct", "transparent");
        getStyle().set("padding-right", "0px");
        super.add(tab);
    }

    @Override
    public void add(Tab... tabs) {
        Arrays.stream(tabs)
                .peek(tab1 -> tab1.getElement().getStyle().set("padding", "0px"))
                .forEach(currentTab -> addComponentAtIndex(getComponentCount() - 1, currentTab));
    }

    @Override
    public Registration addSelectedChangeListener(ComponentEventListener<SelectedChangeEvent> listener) {
        return super.addSelectedChangeListener(event -> {
            if (event.getSelectedTab() == tab) {
                this.addListener.run();
                if (event.getPreviousTab() != null && getChildren().anyMatch(component -> component == event.getPreviousTab())) {
                    setSelectedTab(event.getPreviousTab());
                } else {
                    tab.setSelected(false);
                }
            } else {
                listener.onComponentEvent(event);
            }
        });
    }

    public void addAddListener(Runnable addListener) {
        this.addListener = addListener;
    }
}
DiegoCardoso commented 4 years ago

Hi @appreciated

The suffix/prefix you mention are meant to be on the Tabs container or for each Tab? The former could be achieved by placing an element right before/next of Tabs. We were wondering what would differ this functionality from, eg:

HorizontalLayout container = new HorizontalLayout(
    new Button("prefix"),
    new Tabs(...),
    new Button("suffix")
);
appreciated commented 4 years ago

The suffix/prefix you mention are meant to be on the Tabs container or for each Tab?

Sorry for the confusion, they are meant to be for the Tabs component. More precisly behind and in front of all tabs. This feature could also be more abstractly described as "allow adding non selectable Components to the Tabs component".

We were wondering what would differ this functionality from, eg:

From a functionality standpoint there is no difference. Without any aditional work from the developer the UX may differ slightly since the prefix and suffix component would visually, depending on the used theme, not belong to the tabs component. Sure the UX can be improved manually but from a developer standpoint this limitation (not being able to add non-Tab components to the Tabs component) seems a bit unnecessary.

rolfsmeds commented 3 years ago

I presume what you're thinking is that, by allowing prefix/suffix content, that content would be visually part of the Tabs e.g. by being above that bottom separator line?

image.png

appreciated commented 3 years ago

@rolfsmeds yes that is what I meant 👍. Note: the alignment of the "here"-Button is different to what I showed previously (right instead of left). The Firefox "+" Button beside the tabs could be used as a blueprint for my requested behaviour (also in regards to responsiveness).

rolfsmeds commented 3 years ago

Indeed, both use cases should be supported somehow, or maybe the suffix element could take whatever space is left after the tabs, and you can position the contentn in it manually as you wish.