diff --git a/vaadin-flow-components-shared-parent/vaadin-flow-components-base/src/main/java/com/vaadin/flow/component/shared/Tooltip.java b/vaadin-flow-components-shared-parent/vaadin-flow-components-base/src/main/java/com/vaadin/flow/component/shared/Tooltip.java index 82618f60f0e..333cc008b8e 100644 --- a/vaadin-flow-components-shared-parent/vaadin-flow-components-base/src/main/java/com/vaadin/flow/component/shared/Tooltip.java +++ b/vaadin-flow-components-shared-parent/vaadin-flow-components-base/src/main/java/com/vaadin/flow/component/shared/Tooltip.java @@ -74,6 +74,18 @@ public enum TooltipPosition { public String getPosition() { return position; } + + /** + * Gets the {@link TooltipPosition} for the given position string. + * Returns {@link TooltipPosition#BOTTOM} if no match is found. + * + * @param position the position string + * @return the {@link TooltipPosition} + */ + public static TooltipPosition fromPosition(String position) { + return Arrays.stream(TooltipPosition.values()) + .filter(p -> p.getPosition().equals(position)).findFirst().orElse(BOTTOM); + } } /** diff --git a/vaadin-grid-flow-parent/vaadin-grid-flow/src/main/java/com/vaadin/flow/component/grid/Grid.java b/vaadin-grid-flow-parent/vaadin-grid-flow/src/main/java/com/vaadin/flow/component/grid/Grid.java index 2951ac06875..53311e4ca94 100755 --- a/vaadin-grid-flow-parent/vaadin-grid-flow/src/main/java/com/vaadin/flow/component/grid/Grid.java +++ b/vaadin-grid-flow-parent/vaadin-grid-flow/src/main/java/com/vaadin/flow/component/grid/Grid.java @@ -72,6 +72,7 @@ import com.vaadin.flow.component.shared.SelectionPreservationHandler; import com.vaadin.flow.component.shared.SelectionPreservationMode; import com.vaadin.flow.component.shared.SlotUtils; +import com.vaadin.flow.component.shared.Tooltip.TooltipPosition; import com.vaadin.flow.data.binder.BeanPropertySet; import com.vaadin.flow.data.binder.Binder; import com.vaadin.flow.data.binder.PropertyDefinition; @@ -4804,9 +4805,37 @@ public void setTooltipGenerator( this.dataCommunicator.reset(); } + /** + * Gets the tooltip position relative to the cell that is being hovered or + * focused. The default position is {@link TooltipPosition#BOTTOM}. + * + * @return the position of the tooltip + */ + public TooltipPosition getTooltipPosition() { + String position = getTooltipElement() + .map(tooltipElement -> tooltipElement.getAttribute("position")) + .orElse(null); + return TooltipPosition.fromPosition(position); + } + + /** + * Sets the tooltip position relative to the cell that is being hovered or + * focused. The default position is {@link TooltipPosition#BOTTOM}. + * + * @param position + * the position to set + */ + public void setTooltipPosition(TooltipPosition position) { + Objects.requireNonNull(position, "Position cannot be null"); + + addTooltipElementToTooltipSlot(); + + getTooltipElement().ifPresent(tooltipElement -> tooltipElement + .setAttribute("position", position.getPosition())); + } + private void addTooltipElementToTooltipSlot() { - if (this.getElement().getChildren().anyMatch(child -> Objects - .equals(child.getAttribute("slot"), "tooltip"))) { + if (getTooltipElement().isPresent()) { // the grid's tooltip slot has already been filled return; } @@ -4821,6 +4850,12 @@ private void addTooltipElementToTooltipSlot() { SlotUtils.addToSlot(this, "tooltip", tooltipElement); } + private Optional getTooltipElement() { + return this.getElement().getChildren().filter( + child -> Objects.equals(child.getAttribute("slot"), "tooltip")) + .findFirst(); + } + /** * Sets explicit drag operation details for when the user is dragging the * selected items. By default, the drag data only covers the items in the diff --git a/vaadin-grid-flow-parent/vaadin-grid-flow/src/test/java/com/vaadin/flow/component/grid/GridTooltipTest.java b/vaadin-grid-flow-parent/vaadin-grid-flow/src/test/java/com/vaadin/flow/component/grid/GridTooltipTest.java index 1f72aea4777..47b996ec22f 100644 --- a/vaadin-grid-flow-parent/vaadin-grid-flow/src/test/java/com/vaadin/flow/component/grid/GridTooltipTest.java +++ b/vaadin-grid-flow-parent/vaadin-grid-flow/src/test/java/com/vaadin/flow/component/grid/GridTooltipTest.java @@ -22,6 +22,7 @@ import org.junit.Before; import org.junit.Test; +import com.vaadin.flow.component.shared.Tooltip; import com.vaadin.flow.dom.Element; /** @@ -35,7 +36,7 @@ public class GridTooltipTest { @Before public void setup() { - grid = new Grid(); + grid = new Grid<>(); grid.addColumn(item -> item); } @@ -67,14 +68,14 @@ public void setColumnTooltipGenerator_hasFluidAPI() { public void setColumnTooltip_tooltipHasSlot() { grid.addColumn(item -> item).setTooltipGenerator(item -> item); Assert.assertEquals("tooltip", - getTooltipElement(grid).get().getAttribute("slot")); + getTooltipElement(grid).orElseThrow().getAttribute("slot")); } @Test public void setGridTooltip_tooltipHasSlot() { grid.setTooltipGenerator(item -> item); Assert.assertEquals("tooltip", - getTooltipElement(grid).get().getAttribute("slot")); + getTooltipElement(grid).orElseThrow().getAttribute("slot")); } @Test @@ -94,6 +95,58 @@ public void setNullGridTooltipGenerator_throws() { grid.setTooltipGenerator(null); } + @Test + public void setTooltipPosition_hasTooltipElement() { + grid.setTooltipPosition(Tooltip.TooltipPosition.START); + Assert.assertTrue(getTooltipElement(grid).isPresent()); + } + + @Test + public void setTooltipPosition_hasTooltipWithPosition() { + grid.setTooltipPosition(Tooltip.TooltipPosition.START); + Assert.assertEquals("start", + getTooltipElement(grid).orElseThrow().getAttribute("position")); + + grid.setTooltipPosition(Tooltip.TooltipPosition.END); + Assert.assertEquals("end", + getTooltipElement(grid).orElseThrow().getAttribute("position")); + } + + @Test + public void setTooltipPosition_throwsForNull() { + Assert.assertThrows(NullPointerException.class, + () -> grid.setTooltipPosition(null)); + } + + @Test + public void setTooltipPosition_getTooltipPosition() { + grid.setTooltipPosition(Tooltip.TooltipPosition.START); + Assert.assertEquals(Tooltip.TooltipPosition.START, + grid.getTooltipPosition()); + + grid.setTooltipPosition(Tooltip.TooltipPosition.END); + Assert.assertEquals(Tooltip.TooltipPosition.END, + grid.getTooltipPosition()); + } + + @Test + public void getTooltipPosition_defaultTooltipPosition() { + // without tooltip element + Assert.assertEquals(Tooltip.TooltipPosition.BOTTOM, + grid.getTooltipPosition()); + + // with tooltip element, unspecified position + grid.setTooltipGenerator(item -> item); + Assert.assertEquals(Tooltip.TooltipPosition.BOTTOM, + grid.getTooltipPosition()); + + // with tooltip element, invalid position + getTooltipElement(grid).orElseThrow().setAttribute("position", + "invalid"); + Assert.assertEquals(Tooltip.TooltipPosition.BOTTOM, + grid.getTooltipPosition()); + } + private Optional getTooltipElement(Grid grid) { return getTooltipElements(grid).findFirst(); }