Button will not adjust width

I have tried every way I can think of to adjust the width of this form’s button. In App Start, it looks like this, which is exactly what I want:

But running locally it looks like this:

I tried everything I could think of, then removed it all.

public class FeedbackForm extends FormLayout {
    private final TextArea textArea = new TextArea("I need to find...");
    private final Button buttonPrimary = new Button("Send", new Icon(VaadinIcon.ARROW_RIGHT));

    public FeedbackForm() {
        super();
        textArea.setWidthFull();
        textArea.setMaxWidth("500px");
        textArea.setMinWidth("300px");
        buttonPrimary.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        buttonPrimary.setIconAfterText(true);
        add(textArea, buttonPrimary);
    }
}
@PageTitle("Home")
@Route("")
public class HomeView extends Composite<VerticalLayout> {

    public static final String KEYWORD = "AV Equipment Suppliers";

    public HomeView() {
        VerticalLayout mainLayout = createMainLayout(
                createTitle(),
                createSubtitle(),
                createFeedbackSection()
        );
        getContent().add(mainLayout);
    }

    private H1 createTitle() {
        H1 title = new H1("Find Trusted AV Equipment Suppliers for Every Project");
        title.setWidth("max-content");
        title.setMaxWidth("450px");
        return title;
    }

    private Paragraph createSubtitle() {
        Paragraph subtitle = new Paragraph("Connecting you with leading audio, visual, and lighting equipment suppliers.");
        subtitle.setWidth("100%");
        subtitle.setMaxWidth("450px");
        subtitle.addClassNames(LumoUtility.FontSize.LARGE);
        return subtitle;
    }

    private VerticalLayout createFeedbackSection() {
        H3 headingFeedback = new H3("What are you looking to accomplish on AV Equipment Suppliers today?");
        headingFeedback.setWidth("max-content");
        headingFeedback.setMaxWidth("270px");

        FeedbackForm feedbackForm = new FeedbackForm();

        HorizontalLayout feedbackRow = new HorizontalLayout(headingFeedback, feedbackForm);
        configureFeedbackRow(feedbackRow);

        VerticalLayout feedbackLayout = new VerticalLayout(feedbackRow);
        configureFeedbackLayout(feedbackLayout, feedbackRow);

        return feedbackLayout;
    }

    private void configureFeedbackRow(HorizontalLayout feedbackRow) {
        feedbackRow.setWidthFull();
        feedbackRow.setMaxWidth("900px");
        feedbackRow.setWidth("100%");
        feedbackRow.addClassName(LumoUtility.Gap.MEDIUM);
        feedbackRow.addClassName(LumoUtility.Padding.LARGE);
        feedbackRow.setHeight("min-content");
        feedbackRow.setAlignItems(FlexComponent.Alignment.CENTER);
        feedbackRow.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER);
    }

    private void configureFeedbackLayout(VerticalLayout feedbackLayout, HorizontalLayout feedbackRow) {
        feedbackLayout.setWidthFull();
        feedbackLayout.setPadding(false);
        feedbackLayout.setWidth("100%");
        feedbackLayout.setHeight("min-content");
        feedbackLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.START);
        feedbackLayout.setAlignItems(FlexComponent.Alignment.CENTER);
        feedbackLayout.setFlexGrow(1.0, feedbackRow);
    }

    private VerticalLayout createMainLayout(H1 title, Paragraph subtitle, VerticalLayout feedbackLayout) {
        Objects.requireNonNull(title, "Title component must not be null");
        Objects.requireNonNull(subtitle, "Subtitle component must not be null");
        Objects.requireNonNull(feedbackLayout, "Feedback layout must not be null");

        VerticalLayout mainLayout = new VerticalLayout(title, subtitle, feedbackLayout);
        mainLayout.setWidthFull();
        mainLayout.setMaxWidth("1200px");
        mainLayout.getStyle().set("flex-grow", "1");
        mainLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.START);
        mainLayout.setAlignItems(FlexComponent.Alignment.START);
        return mainLayout;
    }
}

Oh, and I did check the css and there’s nothing about button width in there.

The formlayout automatically applies full with to it’s direct children. Simplest hack would be to add(new Div(button)); instead of add(button); or you could work with the corresponding form item API

1 Like

Thanks!!

public class FeedbackForm extends FormLayout {
    private final TextArea textArea = new TextArea("I need to find...");
    private final Button buttonPrimary = new Button("Send", new Icon(VaadinIcon.ARROW_RIGHT));

    public FeedbackForm() {
        super();
        textArea.setWidthFull();
        textArea.setMaxWidth("500px");
        textArea.setMinWidth("300px");
        buttonPrimary.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        buttonPrimary.setIconAfterText(true);
        buttonPrimary.addClassNames(LumoUtility.Margin.MEDIUM);
        HorizontalLayout buttonContainer = new HorizontalLayout(buttonPrimary);
        buttonContainer.addClassNames(LumoUtility.JustifyContent.CENTER);
        add(textArea, buttonContainer);
    }
}

I guess it could also be mentioned that FormLayout is primarily intended for the fields of a form – anything else is, in most cases, better left outside of the FormLayout itself.

1 Like

Thanks Rolf. Can you say more about that? In traditional HTTP forms the button is always inside the form, so that’s my reference point. Everything else I know about Vaadin best practices comes from this post. Is there another resource I should reference instead?

Technically Vaadin doesn’t use the mechanism of <form> + form submit via HTTP: it sends the values to the server-side using its own internal synchronization protocol. That means that you don’t have to place components into a FormLayout, you can place those in any layout you need and everything will continue working.

FormLayout is purely about visual layouting - it contains no functionality with respect to form submitting via HTTP post. That means that if you can get your job done via other layouts easier, just do so :+1:

1 Like

I see now that the docs do reflect this pattern. Maybe the article I referenced should be updated?
I have a lot of forms that I have to go back and change now.