vaadin / flow-components

Java counterpart of Vaadin Web Components
100 stars 66 forks source link

Updating themes of CRUD buttons doesn't work if the CRUD hasn't been initialized first #6123

Closed OlliTietavainenVaadin closed 6 months ago

OlliTietavainenVaadin commented 6 months ago

Description

Changing a CRUD's save button's theme doesn't work if you do it on the server right after the object has been instantiated.

Expected outcome

Theme should be updated correctly

Minimal reproducible example

Example:

package org.vaadin.example;

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.crud.BinderCrudEditor;
import com.vaadin.flow.component.crud.Crud;
import com.vaadin.flow.component.crud.CrudEditor;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.router.Route;

@Route
public class MainView extends VerticalLayout {

    public MainView() {
        Crud<Bean> crud = new Crud<>(Bean.class, createGrid(), createEditor());
        add(crud);
        // doesn't work
        crud.getSaveButton().setThemeName(ButtonVariant.LUMO_SUCCESS.getVariantName());
        Button b = new Button("change", e -> {
            // this works
            crud.getSaveButton().setThemeName(ButtonVariant.LUMO_ERROR.getVariantName());
        });
        add(b);
    }

    private CrudEditor<Bean> createEditor() {
        TextField firstName = new TextField("Foo");
        TextField lastName = new TextField("Bar");

        FormLayout form = new FormLayout(firstName, lastName);

        Binder<Bean> binder = new Binder<>(Bean.class);
        binder.forField(firstName).asRequired().bind("foo");
        binder.forField(lastName).asRequired().bind("bar");

        return new BinderCrudEditor<>(binder, form);
    }

    private Grid<Bean> createGrid() {
        Grid<Bean> res = new Grid<>(Bean.class);
        res.setItems(new Bean("foo1", "bar1"), new Bean("foo2", "bar2"));
        return res;
    }

    public static class Bean {
        String foo;
        String bar;

        public Bean(String foo, String bar) {
            this.foo = foo;
            this.bar = bar;
        }

        public String getFoo() {
            return foo;
        }

        public void setFoo(String foo) {
            this.foo = foo;
        }

        public String getBar() {
            return bar;
        }

        public void setBar(String bar) {
            this.bar = bar;
        }
    }

}

Steps to reproduce

  1. Run the UI
  2. Click "New item" and fill in some data
  3. Observe it should be using the "success" theme, not the "primary" one on the save button
  4. go back to the main screen and click Change
  5. Click "new item" again and fill in some data
  6. Observe it's now correctly using the "error" theme

Environment

Vaadin version(s): 24.3 OS: n/a

Browsers

No response

stefanuebe commented 6 months ago

Workaround:

Button saveButton = crud.getSaveButton();
saveButton.getElement()
        .executeJs("")
        .then(jsonValue -> saveButton.addThemeVariants(ButtonVariant.LUMO_SUCCESS));
sissbruecker commented 6 months ago

Looks like the web component overrides the theme attribute for slotted buttons from the Flow component: https://github.com/vaadin/web-components/blob/1875686236814dcc065a0e067c87adb80153ce60/packages/crud/src/vaadin-crud-controllers.js#L39-L46