int captionHeight;
VCaption caption = getCaption();
+ Style captionStyle = caption == null ? null : caption.getElement().getStyle();
if (caption == null || caption.shouldBePlacedAfterComponent()) {
style.clearPaddingTop();
captionHeight = 0;
padding += captionHeight;
widget.getElement().getStyle().setTop(padding, Unit.PX);
+ if (captionStyle != null) {
+ captionStyle.setTop(padding - captionHeight, Unit.PX);
+ }
} else {
// Reset top when changing back to align top
widget.getElement().getStyle().clearTop();
-
+ if (captionStyle != null) {
+ captionStyle.setTop(0, Unit.PX);
+ }
}
}
--- /dev/null
+package com.vaadin.tests.layouts.gridlayout;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.GridLayout;
+import com.vaadin.ui.TextField;
+
+public class GridLayoutCaptionOnBottomAlignedComponent extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ GridLayout layout = new GridLayout();
+ layout.setHeight("200px");
+ layout.setWidth("100%");
+
+ TextField component = new TextField("Oh Caption My Caption");
+ layout.addComponent(component);
+ layout.setComponentAlignment(component, Alignment.BOTTOM_CENTER);
+
+ addComponent(layout);
+
+ Button realign = new Button("Realign", evt -> {
+ layout.setComponentAlignment(component, Alignment.TOP_LEFT);
+ });
+ addComponent(realign);
+ }
+}
--- /dev/null
+package com.vaadin.tests.layouts.gridlayout;
+
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.elements.GridLayoutElement;
+import com.vaadin.testbench.elements.TextFieldElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import static org.junit.Assert.assertEquals;
+
+public class GridLayoutCaptionOnBottomAlignedComponentTest extends MultiBrowserTest {
+
+ @Test
+ public void captionShouldBeImmediatelyAboveItsComponent() {
+ openTestURL();
+ GridLayoutElement gridLayout = $(GridLayoutElement.class).first();
+ WebElement caption = gridLayout.findElement(By.className("v-caption"));
+ TextFieldElement component = $(TextFieldElement.class).first();
+
+ assertEquals("Caption and component have the same horizontal alignment",
+ caption.getLocation().x, component.getLocation().x);
+
+ // We have to do the assertion in this way because different browsers on different operating systems
+ // measure the height of the caption in different ways.
+ int diff = Math.abs(caption.getLocation().y - component.getLocation().y + caption.getSize().height);
+ assertLessThanOrEqual("Caption is placed directly above the component", diff, 1);
+ }
+
+ @Test
+ public void captionShouldStillBeImmediatelyAboveItsComponentEvenWhenRealigned() {
+ openTestURL();
+ GridLayoutElement gridLayout = $(GridLayoutElement.class).first();
+ WebElement caption = gridLayout.findElement(By.className("v-caption"));
+ TextFieldElement component = $(TextFieldElement.class).first();
+
+ // Click the button, this changes the alignment of the component
+ $(ButtonElement.class).first().click();
+
+ assertEquals("Caption and component have the same horizontal alignment",
+ caption.getLocation().x, component.getLocation().x);
+
+ assertEquals("Caption is placed in the top-left corner",
+ gridLayout.getLocation().y, caption.getLocation().y);
+ }
+}