web-components
web-components copied to clipboard
[button] Add spinner/loading theme variant
Add a theme variant for a disabled button, to give users an indication that the action the button triggered is being performed.
Should be added for both Lumo and Material themes.
After vaadin/vaadin-button#112 is fixed, the spinner/loading variant should look like close to this:
In our v8 apps we have used this quite heavily for long running operations in combination with setDisableOnClick
To customize the icon and e.g. loading Text I would propose to add additional APIs for:
setDisableOnClickIcon
and setDisableOnClickCaption
to have dedicated icon and text for this.
This could also be done with a new method setDisableOnClick(true, VaadinIcon.LOADING, "Loading..")
as overloaded method, where the old method setDisableOnClick
just calls the second and third parameter with null.
Probably not the best looking solution, but if somebody needs it:
v22+
The style is automatically applied if the button is configured with setDisableOnClick(true)
and the user clicked the button.
:host([disableonclick][disabled]) {
color: transparent;
}
:host([disableonclick][disabled]) [part='label']::after {
content: "";
position: absolute;
width: 16px;
height: 16px;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
border: 4px solid transparent;
border-top-color: red;
border-radius: 50%;
animation: button-loading-spinner 1s ease infinite;
}
@keyframes button-loading-spinner {
from {
transform: rotate(0turn);
}
to {
transform: rotate(1turn);
}
}
Relevant article for technical design and a11y: https://adrianroselli.com/2021/01/multi-function-button.html
Nice feature to have in Vaadin
The framework usually automatically displays a loading indicator from the start of a server request and hides it after the response processing has ended.
However, in case the backend handles the action asynchronously, the loading indicator is not shown and in this case the UI remains otherwise active while the action is still in progress.
Tatu Lund has created an asynchronous button click handler example here: https://github.com/TatuLund/cdi-demo/blob/master/src/main/java/org/vaadin/cdidemo/views/admin/AdminPresenter.java#L41-L56
Here's how it looks:
As you can see, even though there is a spinner in the middle of the screen, the button state does not change and it does not contain the spinner, so the user can continue clicking on it, which is not ideal.
Adding a spinner button theme variant would be really great for this case.