diff --git a/flow-server/src/main/java/com/vaadin/flow/component/HasSize.java b/flow-server/src/main/java/com/vaadin/flow/component/HasSize.java index e0510915129..6021502950a 100644 --- a/flow-server/src/main/java/com/vaadin/flow/component/HasSize.java +++ b/flow-server/src/main/java/com/vaadin/flow/component/HasSize.java @@ -19,6 +19,7 @@ import com.vaadin.flow.dom.Element; import com.vaadin.flow.dom.ElementConstants; +import com.vaadin.flow.server.Constants; /** * Any component implementing this interface supports setting the size of the @@ -47,6 +48,7 @@ public interface HasSize extends HasElement { */ default void setWidth(String width) { getElement().getStyle().setWidth(width); + getElement().removeAttribute(Constants.ATTRIBUTE_WIDTH_FULL); } /** @@ -194,6 +196,7 @@ default Optional getWidthUnit() { */ default void setHeight(String height) { getElement().getStyle().setHeight(height); + getElement().removeAttribute(Constants.ATTRIBUTE_HEIGHT_FULL); } /** @@ -332,20 +335,47 @@ default Optional getHeightUnit() { * This is just a convenience method which delegates its call to the * {@link #setWidth(String)} and {@link #setHeight(String)} methods with * {@literal "100%"} as the argument value + *

+ * When adding full-size components as a child of a Vaadin layout component + * that is based on CSS Flexbox, such as HorizontalLayout or VerticalLayout, + * this can result in unexpected behavior. For example, other components + * with a fixed size may shrink to allow the full-size component to take up + * as much space as possible, or the full-size component may cause the + * layout to overflow. To improve this, you can enable the + * {@code com.vaadin.experimental.layoutComponentImprovements} feature flag + * to effectively make full-size components take up the remaining + * space in the layout, rather than explicitly using 100% size of the + * layout. This applies additional CSS styles that allow the component to + * shrink below 100% if there are other components with fixed or relative + * sizes in the layout. */ default void setSizeFull() { - setWidth("100%"); - setHeight("100%"); + setWidthFull(); + setHeightFull(); } /** * Sets the width of the component to "100%". *

* This is just a convenience method which delegates its call to the - * {@link #setWidth(String)} with {@literal "100%"} as the argument value + * {@link #setWidth(String)} with {@literal "100%"} as the argument value. + *

+ * When adding full-size components as a child of a Vaadin layout component + * that is based on CSS Flexbox, such as HorizontalLayout or VerticalLayout, + * this can result in unexpected behavior. For example, other components + * with a fixed size may shrink to allow the full-size component to take up + * as much space as possible, or the full-size component may cause the + * layout to overflow. To improve this, you can enable the + * {@code com.vaadin.experimental.layoutComponentImprovements} feature flag + * to effectively make full-size components take up the remaining + * space in the layout, rather than explicitly using 100% size of the + * layout. This applies additional CSS styles that allow the component to + * shrink below 100% if there are other components with fixed or relative + * sizes in the layout. */ default void setWidthFull() { setWidth("100%"); + getElement().setAttribute(Constants.ATTRIBUTE_WIDTH_FULL, true); } /** @@ -353,9 +383,23 @@ default void setWidthFull() { *

* This is just a convenience method which delegates its call to the * {@link #setHeight(String)} with {@literal "100%"} as the argument value + *

+ * When adding full-size components as a child of a Vaadin layout component + * that is based on CSS Flexbox, such as HorizontalLayout or VerticalLayout, + * this can result in unexpected behavior. For example, other components + * with a fixed size may shrink to allow the full-size component to take up + * as much space as possible, or the full-size component may cause the + * layout to overflow. To improve this, you can enable the + * {@code com.vaadin.experimental.layoutComponentImprovements} feature flag + * to effectively make full-size components take up the remaining + * space in the layout, rather than explicitly using 100% size of the + * layout. This applies additional CSS styles that allow the component to + * shrink below 100% if there are other components with fixed or relative + * sizes in the layout. */ default void setHeightFull() { setHeight("100%"); + getElement().setAttribute(Constants.ATTRIBUTE_HEIGHT_FULL, true); } /** diff --git a/flow-server/src/main/java/com/vaadin/flow/server/Constants.java b/flow-server/src/main/java/com/vaadin/flow/server/Constants.java index 9c3a33e00c7..f53f76e7124 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/Constants.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/Constants.java @@ -396,6 +396,18 @@ public final class Constants implements Serializable { */ public static final String DISABLE_PREPARE_FRONTEND_CACHE = "disable.prepare.frontend.cache"; + /** + * Attribute used by HasSize to mark elements that have been set to full + * width. + */ + public static final String ATTRIBUTE_WIDTH_FULL = "data-width-full"; + + /** + * Attribute used by HasSize to mark elements that have been set to full + * height. + */ + public static final String ATTRIBUTE_HEIGHT_FULL = "data-height-full"; + private Constants() { // prevent instantiation constants class only } diff --git a/flow-server/src/test/java/com/vaadin/flow/component/HasSizeTest.java b/flow-server/src/test/java/com/vaadin/flow/component/HasSizeTest.java index 03a430dd53a..e91533a2433 100644 --- a/flow-server/src/test/java/com/vaadin/flow/component/HasSizeTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/component/HasSizeTest.java @@ -15,6 +15,7 @@ */ package com.vaadin.flow.component; +import com.vaadin.flow.server.Constants; import org.junit.Assert; import org.junit.Test; @@ -136,6 +137,47 @@ public void setSizeFull() { Assert.assertEquals("100%", component.getHeight()); } + @Test + public void setSizeFull_addsDataAttribute() { + HasSizeComponent component = new HasSizeComponent(); + component.setSizeFull(); + + Assert.assertTrue(component.getElement() + .hasAttribute(Constants.ATTRIBUTE_WIDTH_FULL)); + Assert.assertTrue(component.getElement() + .hasAttribute(Constants.ATTRIBUTE_HEIGHT_FULL)); + } + + @Test + public void setSizeFull_setSize_removesDataAttribute() { + HasSizeComponent component = new HasSizeComponent(); + component.setSizeFull(); + + component.setWidth("10px"); + Assert.assertFalse(component.getElement() + .hasAttribute(Constants.ATTRIBUTE_WIDTH_FULL)); + Assert.assertTrue(component.getElement() + .hasAttribute(Constants.ATTRIBUTE_HEIGHT_FULL)); + + component.setHeight("10px"); + Assert.assertFalse(component.getElement() + .hasAttribute(Constants.ATTRIBUTE_WIDTH_FULL)); + Assert.assertFalse(component.getElement() + .hasAttribute(Constants.ATTRIBUTE_HEIGHT_FULL)); + } + + @Test + public void setSizeFull_setSizeUndefined_removesDataAttribute() { + HasSizeComponent component = new HasSizeComponent(); + component.setSizeFull(); + component.setSizeUndefined(); + + Assert.assertFalse(component.getElement() + .hasAttribute(Constants.ATTRIBUTE_WIDTH_FULL)); + Assert.assertFalse(component.getElement() + .hasAttribute(Constants.ATTRIBUTE_HEIGHT_FULL)); + } + @Test public void setWidthFull() { HasSizeComponent component = new HasSizeComponent(); @@ -144,6 +186,29 @@ public void setWidthFull() { Assert.assertEquals("100%", component.getWidth()); } + @Test + public void setWidthFull_addsDataAttribute() { + HasSizeComponent component = new HasSizeComponent(); + component.setWidthFull(); + + Assert.assertTrue(component.getElement() + .hasAttribute(Constants.ATTRIBUTE_WIDTH_FULL)); + Assert.assertFalse(component.getElement() + .hasAttribute(Constants.ATTRIBUTE_HEIGHT_FULL)); + } + + @Test + public void setWidthFull_setWidth_removesDataAttribute() { + HasSizeComponent component = new HasSizeComponent(); + component.setWidthFull(); + component.setWidth("10px"); + + Assert.assertFalse(component.getElement() + .hasAttribute(Constants.ATTRIBUTE_WIDTH_FULL)); + Assert.assertFalse(component.getElement() + .hasAttribute(Constants.ATTRIBUTE_HEIGHT_FULL)); + } + @Test public void setHeightFull() { HasSizeComponent component = new HasSizeComponent(); @@ -152,6 +217,29 @@ public void setHeightFull() { Assert.assertEquals("100%", component.getHeight()); } + @Test + public void setHeightFull_addsDataAttribute() { + HasSizeComponent component = new HasSizeComponent(); + component.setHeightFull(); + + Assert.assertFalse(component.getElement() + .hasAttribute(Constants.ATTRIBUTE_WIDTH_FULL)); + Assert.assertTrue(component.getElement() + .hasAttribute(Constants.ATTRIBUTE_HEIGHT_FULL)); + } + + @Test + public void setHeightFull_setHeight_removesDataAttribute() { + HasSizeComponent component = new HasSizeComponent(); + component.setHeightFull(); + component.setHeight("10px"); + + Assert.assertFalse(component.getElement() + .hasAttribute(Constants.ATTRIBUTE_WIDTH_FULL)); + Assert.assertFalse(component.getElement() + .hasAttribute(Constants.ATTRIBUTE_HEIGHT_FULL)); + } + @Test public void setSizeUndefined() { HasSizeComponent component = new HasSizeComponent();