From c7345a730db2df83e0aebb335dcbd69126ec6ced Mon Sep 17 00:00:00 2001 From: Anna Koskinen Date: Wed, 3 Mar 2021 12:08:38 +0200 Subject: [PATCH] Fix displaying checkboxes within Grid editor row. (#12212) * Fix displaying checkboxes within Grid editor row. - Checkbox margins should match regular row content margins. - Multiselect checkbox label should only be visible for assistive devices. --- .../java/com/vaadin/client/widgets/Grid.java | 7 ++ .../VAADIN/themes/valo/components/_grid.scss | 4 +- .../components/grid/GridEditorCheckBox.java | 89 +++++++++++++++++++ .../grid/GridEditorCheckBoxTest.java | 83 +++++++++++++++++ 4 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 uitest/src/main/java/com/vaadin/tests/components/grid/GridEditorCheckBox.java create mode 100644 uitest/src/test/java/com/vaadin/tests/components/grid/GridEditorCheckBoxTest.java diff --git a/client/src/main/java/com/vaadin/client/widgets/Grid.java b/client/src/main/java/com/vaadin/client/widgets/Grid.java index 99a4a269bd..8a78201cb4 100755 --- a/client/src/main/java/com/vaadin/client/widgets/Grid.java +++ b/client/src/main/java/com/vaadin/client/widgets/Grid.java @@ -1973,6 +1973,13 @@ public class Grid extends ResizeComposite implements HasSelectionHandlers, // editor overlay since the original one is hidden by // the overlay final CheckBox checkBox = GWT.create(CheckBox.class); + checkBox.setStylePrimaryName(grid.getStylePrimaryName() + + "-selection-checkbox"); + + // label of checkbox should only be visible for + // assistive devices + checkBox.addStyleName("v-assistive-device-only-label"); + checkBox.setValue( grid.isSelected(pinnedRowHandle.getRow())); checkBox.sinkEvents(Event.ONCLICK); diff --git a/themes/src/main/themes/VAADIN/themes/valo/components/_grid.scss b/themes/src/main/themes/VAADIN/themes/valo/components/_grid.scss index 813f39d753..33ab02105b 100644 --- a/themes/src/main/themes/VAADIN/themes/valo/components/_grid.scss +++ b/themes/src/main/themes/VAADIN/themes/valo/components/_grid.scss @@ -474,7 +474,7 @@ $v-grid-details-border-bottom-stripe: 1px solid darken($v-grid-row-background-co padding-right: $v-grid-cell-padding-horizontal / 2; } - input[type="checkbox"] { + :not(.v-assistive-device-only-label).v-widget > input[type="checkbox"] { margin-left: $v-grid-cell-padding-horizontal; } @@ -750,7 +750,7 @@ $v-grid-drag-indicator-color: $v-focus-color; padding-right: round($v-grid-cell-padding-horizontal / 2); } - .v-checkbox { + .v-checkbox.v-widget { margin: 0 round($v-grid-cell-padding-horizontal / 2) 0 $v-grid-cell-padding-horizontal; > input[type="checkbox"] { diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/GridEditorCheckBox.java b/uitest/src/main/java/com/vaadin/tests/components/grid/GridEditorCheckBox.java new file mode 100644 index 0000000000..932b49a8e4 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/tests/components/grid/GridEditorCheckBox.java @@ -0,0 +1,89 @@ +package com.vaadin.tests.components.grid; + +import java.util.ArrayList; +import java.util.List; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.CheckBox; +import com.vaadin.ui.Grid; +import com.vaadin.ui.renderers.HtmlRenderer; + +public class GridEditorCheckBox extends AbstractTestUI { + + @Override + protected String getTestDescription() { + return "Editor content alignments should match regular row content " + + "alignments.
(Double-click a row to open the editor.)"; + } + + @Override + protected void setup(VaadinRequest request) { + List items = new ArrayList<>(); + items.add(new Person(true, false, false)); + items.add(new Person(false, true, true)); + + CheckBox adminEditor = new CheckBox(); + CheckBox staffEditor = new CheckBox(); + staffEditor.setPrimaryStyleName("my-custom-checkbox"); + + final Grid grid = new Grid(); + grid.setSelectionMode(Grid.SelectionMode.MULTI); + + grid.addColumn(Person::isAdmin) + .setEditorComponent(adminEditor, Person::setAdmin) + .setCaption("Default"); + grid.addColumn(Person::isStaff) + .setEditorComponent(staffEditor, Person::setAdmin) + .setCaption("Custom"); + grid.addColumn(Person::isSpecialist).setRenderer( + s -> "", + new HtmlRenderer()).setCaption("HTML"); + grid.addColumn(Person::isSpecialist).setRenderer( + s -> "", + new HtmlRenderer()).setCaption("Spanned"); + grid.getEditor().setBuffered(false); + grid.getEditor().setEnabled(true); + grid.setItems(items); + + addComponents(grid); + } + + public class Person { + private boolean admin; + private boolean staff; + private boolean specialist; + + public Person(boolean admin, boolean staff, boolean specialist) { + this.admin = admin; + this.staff = staff; + this.specialist = specialist; + } + + public boolean isAdmin() { + return admin; + } + + public void setAdmin(final boolean admin) { + this.admin = admin; + } + + public boolean isStaff() { + return staff; + } + + public void setStaff(final boolean staff) { + this.staff = staff; + } + + public boolean isSpecialist() { + return specialist; + } + + public void setSpecialist(final boolean specialist) { + this.specialist = specialist; + } + } +} diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/GridEditorCheckBoxTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/GridEditorCheckBoxTest.java new file mode 100644 index 0000000000..bf80f11bac --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/components/grid/GridEditorCheckBoxTest.java @@ -0,0 +1,83 @@ +package com.vaadin.tests.components.grid; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.number.IsCloseTo.closeTo; +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class GridEditorCheckBoxTest extends MultiBrowserTest { + + @Test + public void testPositions() { + openTestURL(); + GridElement grid = $(GridElement.class).first(); + + // open editor for second row + grid.getCell(1, 1).doubleClick(); + waitForElementPresent(By.className("v-grid-editor")); + + // regular row cells + List rowCells = grid.getRow(0) + .findElements(By.className("v-grid-cell")); + + // editor cells are divided in two groups, first one for frozen columns, + // second one for the rest + List editorCellGroups = grid + .findElements(By.className("v-grid-editor-cells")); + int column = 0; + for (WebElement editorCellGroup : editorCellGroups) { + // find the actual editor cells (no shared class name) + List editorCells = editorCellGroup + .findElements(By.xpath("./child::*")); + for (WebElement editorCell : editorCells) { + + // find the margin within the editor row + List checkBoxElements = editorCell + .findElements(By.className("v-checkbox")); + WebElement editorInput; + if (checkBoxElements.isEmpty()) { + // use the actual input element for position check + editorInput = editorCell.findElement(By.tagName("input")); + } else { + // v-checkbox positions a fake input element + editorInput = checkBoxElements.get(0); + } + int editorMargin = editorInput.getLocation().getX() + - editorCell.getLocation().getX(); + + // find the margin within the regular row + WebElement rowCell = rowCells.get(column); + int comparisonMargin; + if (column == 1 || column == 2) { + // these columns have text content on regular rows, margin + // is created with padding + String padding = rowCell.getCssValue("padding-left"); + comparisonMargin = Integer.valueOf( + padding.substring(0, padding.indexOf("px"))); + } else { + WebElement rowContent = rowCell + .findElement(By.tagName("input")); + comparisonMargin = rowContent.getLocation().getX() + - rowCell.getLocation().getX(); + } + + // ensure that the editor input position matches the regular row + // content position + assertThat( + "Unexpected input location for column " + column + + " editor", + (double) editorMargin, closeTo(comparisonMargin, 1d)); + ++column; + } + } + assertEquals("Unexpect amount of checked columns,", 5, column); + } +} -- 2.39.5