import com.google.gwt.animation.client.AnimationScheduler.AnimationCallback;
import com.google.gwt.animation.client.AnimationScheduler.AnimationHandle;
import com.google.gwt.core.client.Duration;
+import com.google.gwt.core.client.JavaScriptException;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.Scheduler;
TableCellElement cellClone = TableCellElement
.as((Element) cell.cloneNode(withContent));
+ if (!withContent || columnConfiguration
+ .getColumnWidth(cell.getCellIndex()) < 0) {
+ clearRelativeWidthContents(cellClone);
+ }
cellClone.getStyle().clearHeight();
cellClone.getStyle().clearWidth();
return requiredWidth;
}
+ /**
+ * Contents of an element that is configured to have relative width
+ * shouldn't be taken into consideration when measuring minimum widths.
+ * Thus any such contents within the element hierarchy need to be
+ * cleared out for accurate results. The element itself should remain,
+ * however, in case it has styles that affect the end results.
+ *
+ * @param elem
+ * an element that might have unnecessary content that
+ * interferes with minimum width calculations
+ */
+ private void clearRelativeWidthContents(Element elem) {
+ try {
+ String width = elem.getStyle().getWidth();
+ if (width != null && width.endsWith("%")) {
+ if (elem.hasChildNodes()) {
+ elem.removeAllChildren();
+ // add a fake child so that :empty behavior doesn't
+ // change
+ elem.setInnerHTML("<a/>");
+ } else {
+ elem.setInnerHTML(null);
+ }
+ }
+ } catch (JavaScriptException e) {
+ // no width set, move on
+ }
+ for (int i = 0; i < elem.getChildCount(); ++i) {
+ Node node = elem.getChild(i);
+ if (node instanceof Element) {
+ clearRelativeWidthContents((Element) node);
+ }
+ }
+ }
+
/**
* Gets the minimum width needed to display the cell properly.
*
--- /dev/null
+package com.vaadin.tests.components.grid;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vaadin.data.provider.DataProvider;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.CssLayout;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+
+public class GridWithFullWidthComponents extends AbstractTestUI {
+ private String s = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, "
+ + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ getPage().getStyles()
+ .add(".v-grid .v-label, .v-grid .v-csslayout:not(:empty) { "
+ + "background-color: yellow; min-width: 300px; }");
+
+ List<Integer> content = new ArrayList<>();
+ for (int i = 0; i < 100; ++i) {
+ content.add(i);
+ }
+
+ Grid<Integer> grid = new Grid<>(DataProvider.ofCollection(content));
+ grid.setSizeFull();
+ grid.setSelectionMode(Grid.SelectionMode.NONE);
+ grid.setBodyRowHeight(70);
+ grid.addComponentColumn(this::labelResponse).setCaption("Label");
+ grid.addComponentColumn(this::hLayoutResponse)
+ .setCaption("HorizontalLayout");
+ grid.addComponentColumn(this::cssLayoutResponse)
+ .setCaption("CssLayout");
+
+ addComponent(grid);
+ }
+
+ private Label labelResponse(Integer item) {
+ Label label = new Label(s);
+ label.setWidthFull();
+ return label;
+ }
+
+ private HorizontalLayout hLayoutResponse(Integer ite) {
+ HorizontalLayout layout = new HorizontalLayout();
+ layout.setWidthFull();
+ for (int i = 0; i < 5; ++i) {
+ layout.addComponent(new Button("Button" + i));
+ }
+ return layout;
+ }
+
+ private CssLayout cssLayoutResponse(Integer ite) {
+ CssLayout layout = new CssLayout();
+ layout.setWidthFull();
+ for (int i = 0; i < 5; ++i) {
+ layout.addComponent(new Button("Button" + i));
+ }
+ return layout;
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "All column contents are components with 100% width, "
+ + "in first and third column the contents are styled "
+ + "to have background color and minimum width of 300px. "
+ + "Initial render and browser resize should behave accordingly.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 11973;
+ }
+}
--- /dev/null
+package com.vaadin.tests.components.grid;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.openqa.selenium.Dimension;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class GridWithFullWidthComponentsTest extends MultiBrowserTest {
+
+ @Test
+ public void testResizeUpAndDown() {
+ openTestURL();
+
+ WebElement hScrollBar = findElement(
+ By.className("v-grid-scroller-horizontal"));
+ assertEquals("Unexpected horizontal scrollbar visibility", "none",
+ hScrollBar.getCssValue("display"));
+
+ // increase the browser size
+ getDriver().manage().window().setSize(new Dimension(2000, 850));
+ sleep(300);
+
+ assertEquals("Unexpected horizontal scrollbar visibility", "none",
+ hScrollBar.getCssValue("display"));
+
+ // scale back again
+ getDriver().manage().window().setSize(new Dimension(1500, 850));
+ sleep(300);
+
+ assertEquals("Unexpected horizontal scrollbar visibility", "none",
+ hScrollBar.getCssValue("display"));
+ }
+
+ @Test
+ public void testResizeDownAndUp() {
+ openTestURL();
+
+ WebElement hScrollBar = findElement(
+ By.className("v-grid-scroller-horizontal"));
+ assertEquals("Unexpected horizontal scrollbar visibility", "none",
+ hScrollBar.getCssValue("display"));
+
+ // decrease the browser size far enough that scrollbars are needed
+ getDriver().manage().window().setSize(new Dimension(800, 850));
+ sleep(300);
+
+ assertEquals("Unexpected horizontal scrollbar visibility", "block",
+ hScrollBar.getCssValue("display"));
+
+ // scale back again
+ getDriver().manage().window().setSize(new Dimension(1500, 850));
+ sleep(300);
+
+ assertEquals("Unexpected horizontal scrollbar visibility", "none",
+ hScrollBar.getCssValue("display"));
+ }
+}