Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>org.vaadin.addons.flowingcode</groupId>
<artifactId>grid-helpers</artifactId>
<version>2.1.1-SNAPSHOT</version>
<version>2.2.0-SNAPSHOT</version>
<name>Grid Helpers Add-on</name>
<description>Grid Helpers Add-on for Vaadin Flow</description>
<url>https://www.flowingcode.com/en/open-source/</url>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* #%L
* Grid Helpers Add-on
* %%
* Copyright (C) 2022 - 2024 Flowing Code
* Copyright (C) 2022 - 2026 Flowing Code
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -26,6 +26,7 @@

package com.flowingcode.vaadin.addons.gridhelpers;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.ComponentEventListener;
import com.vaadin.flow.component.ComponentUtil;
import com.vaadin.flow.component.checkbox.Checkbox;
Expand All @@ -38,6 +39,7 @@
import com.vaadin.flow.component.menubar.MenuBarVariant;
import com.vaadin.flow.shared.Registration;
import java.io.Serializable;
import java.util.Objects;
import java.util.Optional;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
Expand All @@ -54,7 +56,9 @@ class ColumnToggleHelper<T> implements Serializable {

private final GridHelper<T> helper;

private Column<?> menuToggleColumn;
private MenuBar menuToggle;

private Component icon;

public void setColumnToggleVisible(boolean visible) {
// https://cookbook.vaadin.com/grid-column-toggle
Expand All @@ -66,35 +70,52 @@ public void setColumnToggleVisible(boolean visible) {
}

public boolean isColumnToggleVisible() {
return menuToggleColumn != null && menuToggleColumn.isVisible();
return menuToggle != null;
}

private Component getColumnToggleIcon() {
if (icon == null) {
icon = VaadinIcon.ELLIPSIS_DOTS_V.create();
}
return icon;
}

public void setColumnToggleIcon(Component icon) {
this.icon = Objects.requireNonNull(icon);
if (isColumnToggleVisible()) {
showColumnToggle();
}
}

private void showColumnToggle() {
createMenuToggle()
.ifPresent(
toggle -> {
Grid<?> grid = helper.getGrid();
if (menuToggleColumn == null) {
menuToggleColumn = grid.addColumn(t -> "").setWidth("auto").setFlexGrow(0);
} else {
menuToggleColumn.setVisible(true);
}
grid.getHeaderRows().get(0).getCell(menuToggleColumn).setComponent(toggle);
removeMenuToggle();
menuToggle = toggle;
grid.getElement().appendChild(toggle.getElement());
});
}

private void hideColumnToggle() {
if (menuToggleColumn != null) {
menuToggleColumn.setVisible(false);
removeMenuToggle();
}

private void removeMenuToggle() {
if (menuToggle != null) {
menuToggle.getElement().removeFromParent();
menuToggle = null;
}
}

private Optional<MenuBar> createMenuToggle() {
Grid<T> grid = helper.getGrid();

MenuBar menuBar = new MenuBar();
menuBar.getThemeNames().add(MenuBarVariant.LUMO_TERTIARY.getVariantName());
menuBar.getThemeNames().add(MenuBarVariant.LUMO_TERTIARY_INLINE.getVariantName());
MenuItem menuItem = menuBar.addItem(VaadinIcon.ELLIPSIS_DOTS_V.create());
MenuItem menuItem = menuBar.addItem(getColumnToggleIcon());
SubMenu subMenu = menuItem.getSubMenu();

for (Column<T> column : grid.getColumns()) {
Expand All @@ -110,6 +131,7 @@ private Optional<MenuBar> createMenuToggle() {
}

menuBar.getThemeNames().add(GRID_HELPER_TOGGLE_THEME);
menuBar.getElement().setAttribute("slot", "fc-column-toggle");
return Optional.of(menuBar).filter(_menuBar -> !_menuBar.getItems().isEmpty());
}

Expand Down Expand Up @@ -170,7 +192,4 @@ public void setHidingToggleCaption(Column<?> column, String caption) {
}
}

Column<?> getMenuToggleColumn() {
return menuToggleColumn;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* #%L
* Grid Helpers Add-on
* %%
* Copyright (C) 2022 - 2025 Flowing Code
* Copyright (C) 2022 - 2026 Flowing Code
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -38,19 +38,20 @@
import com.vaadin.flow.component.grid.HeaderRow;
import com.vaadin.flow.component.grid.HeaderRow.HeaderCell;
import com.vaadin.flow.component.grid.ItemClickEvent;
import com.vaadin.flow.component.icon.IconFactory;
import com.vaadin.flow.function.SerializableFunction;
import com.vaadin.flow.function.SerializablePredicate;
import com.vaadin.flow.shared.Registration;
import java.io.Serializable;
import java.util.Collection;
import java.util.Objects;
import lombok.AccessLevel;
import lombok.Getter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SuppressWarnings("serial")
@JsModule("./fcGridHelper/connector.js")
@CssImport(value = "./fcGridHelper/vaadin-menu-bar.css", themeFor = "vaadin-menu-bar")
@CssImport(value = GridHelper.GRID_STYLES, themeFor = "vaadin-grid")
@CssImport(
value = "./fcGridHelper/vaadin-context-menu-item.css",
Expand All @@ -67,6 +68,7 @@
@CssImport(
value = "./fcGridHelper/vaadin-checkbox.css",
themeFor = "vaadin-checkbox")
@CssImport(value = "./fcGridHelper/styles.css")
public final class GridHelper<T> implements Serializable {

private static final Logger logger = LoggerFactory.getLogger(GridHelper.class);
Expand Down Expand Up @@ -309,6 +311,28 @@
return getHelper(grid).columnToggleHelper.isColumnToggleVisible();
}

/**
* Sets the icon of the menu that toggles the visibility of grid columns.
*
* @param grid the grid to be configured
* @param icon the component that is rendered in the column toggle
* @throws NullPointerException if {@code icon} is {@code null}
*/
public static void setColumnToggleIcon(Grid<?> grid, Component icon) {
getHelper(grid).columnToggleHelper.setColumnToggleIcon(icon);
}

/**
* Sets the icon of the menu that toggles the visibility of grid columns.
*
* @param grid the grid to be configured
* @param icon the factory of the icon that is rendered in the column toggle
* @throws NullPointerException if {@code icon} is {@code null}
*/
public static void setColumnToggleIcon(Grid<?> grid, IconFactory icon) {
setColumnToggleIcon(grid, icon.create());
}

/**
* Returns whether this column can be hidden by the user. Default is {@code false}.
*
Expand Down Expand Up @@ -362,8 +386,20 @@
return getHelper(column.getGrid()).columnToggleHelper.getHidingToggleCaption(column);
}

/**
* Returns whether the given column renders the column toggle.
*
* @param column the column to test, not {@code null}
* @return always {@code false}
* @throws NullPointerException if {@code column} is {@code null}
* @deprecated Since 2.2.0, the column toggle is rendered in the {@code fc-column-toggle} slot
* instead of in a dedicated column, so no column is a menu toggle column and this
* method always returns {@code false}.
*/
@Deprecated(forRemoval = true, since = "2.2.0")
Comment thread
paodb marked this conversation as resolved.
public static boolean isMenuToggleColumn(Column<?> column) {

Check warning on line 400 in src/main/java/com/flowingcode/vaadin/addons/gridhelpers/GridHelper.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Do not forget to remove this deprecated code someday.

See more on https://sonarcloud.io/project/issues?id=FlowingCode_GridHelpers&issues=AaAWT4dGC2CdRiH18wY6&open=AaAWT4dGC2CdRiH18wY6&pullRequest=180
return column == getHelper(column).columnToggleHelper.getMenuToggleColumn();
Objects.requireNonNull(column);
return false;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

// Empty Label
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ import { Grid } from '@vaadin/grid/src/vaadin-grid.js';
(function () {
window.Vaadin.Flow.fcGridHelperConnector = {
initLazy: grid => {

if (!grid.shadowRoot.querySelector('slot[name="fc-column-toggle"]')) {
const slot = document.createElement('slot');
slot.setAttribute('name','fc-column-toggle');
grid.shadowRoot.appendChild(slot);
}

//https://cookbook.vaadin.com/grid-arrow-selection
grid.addEventListener('keyup', function(e) {
if (e.keyCode == 32) return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* #%L
* Grid Helpers Add-on
* %%
* Copyright (C) 2022 - 2024 Flowing Code
* Copyright (C) 2022 - 2026 Flowing Code
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,15 +17,18 @@
* limitations under the License.
* #L%
*/

:host([theme~="gridHelperToggle"]) {
vaadin-menu-bar[theme~="gridHelperToggle"][slot] {
position: absolute;
top: 0;
right: var(--fcgh-toggle-right);
height: 100%;
top: -4px;
right: calc( 6px - var(--vaadin-aura-theme,0)*1px);
}

vaadin-menu-bar[theme~="gridHelperToggle"][slot] vaadin-menu-bar-button::part(suffix) {
display:none;
}

:host([theme~="gridHelperToggle"]) [part="container"] {
vertical-align: middle;
height: 100%;
vaadin-menu-bar[theme~="gridHelperToggle"][slot] > vaadin-menu-bar-button {
padding: calc(var(--vaadin-aura-theme, 0) * 2px);
--lumo-size-m: 0;
}

Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,6 @@
min-height: calc(var(--lumo-size-xxs) - var(--_lumo-grid-border-width));
}

:host {
--fcgh-toggle-right: 0;
}

:host([overflow~="right"]), :host([overflow~="left"]),
:host([overflow~="start"]), :host([overflow~="end"]) {
--fcgh-toggle-right: 24px;
}

table[aria-multiselectable="true"] [part~="fcGh-noselect"][first-column] ::slotted(*) {
opacity: var(--fcgh-noselect-opacity, 0.5);
pointer-events: none;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.Grid.Column;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
Expand All @@ -43,6 +44,7 @@ public ColumnToggleMenuDemo() {
Column<Person> lastNameColumn = grid.addColumn(Person::getLastName).setHeader("Last name");
Column<Person> countryColumn = grid.addColumn(Person::getCountry).setHeader("Country");

GridHelper.setColumnToggleIcon(grid, VaadinIcon.CARET_DOWN);
GridHelper.setHidingToggleCaption(firstNameColumn, "First name");
GridHelper.setHidingToggleCaption(lastNameColumn, "Last name");
GridHelper.setHidingToggleCaption(countryColumn, "Country");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.Grid.SelectionMode;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;

import lombok.experimental.ExtensionMethod;

@PageTitle("Using Lombok")
Expand Down Expand Up @@ -55,6 +55,7 @@ public LombokDemo() {
grid.getColumns().forEach(c -> c.setAutoWidth(true));

grid.setColumnToggleVisible(true);
grid.setColumnToggleIcon(VaadinIcon.CARET_DOWN);
grid.setSelectionColumnFrozen(true);
grid.setSelectOnClick(true);
grid.setSelectionFilter(Person::isActive);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,23 +52,32 @@ public void testColumnToggleVisible() {

$server.setColumnToggleVisible(true);
assertNotNull("ColumnToggle should be present", grid.getColumnToggleButton());
assertThat(grid.getVisibleColumns(), hasSize(nColumns + 1));
assertThat(grid.getVisibleColumns(), hasSize(nColumns));

$server.setColumnToggleVisible(false);
assertNull("ColumnToggle should be absent", grid.getColumnToggleButton());
assertThat(grid.getVisibleColumns(), hasSize(nColumns));
}

@Test
public void testColumnToggleSlot() {
$server.setColumnToggleVisible(true);
assertNotNull("ColumnToggle should be present", grid.getColumnToggle());
assertEquals("fc-column-toggle", grid.getColumnToggleSlotName());

$server.setColumnToggleVisible(false);
assertNull("ColumnToggle should be absent", grid.getColumnToggle());
assertNull(grid.getColumnToggleSlotName());
}

@Test
public void testColumnToggleClick() {
int nColumns = grid.getVisibleColumns().size();

$server.setColumnToggleVisible(true);
grid.getColumnToggleButton().click();

// the toggle is rendered in its own column
assertThat(grid.getColumnToggleElements(), hasSize(nColumns));
assertThat(grid.getVisibleColumns(), hasSize(++nColumns));

grid.getColumnToggleElements().get(0).setChecked(false);
assertThat(grid.getVisibleColumns(), hasSize(nColumns - 1));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,26 @@ public TestBenchElement getColumnToggleButton() {
}
}

/**
* Returns the column toggle menu bar, which is slotted into the grid, or {@code null} if the
* column toggle is not visible.
*/
public TestBenchElement getColumnToggle() {
List<WebElement> elements =
findElements(By.cssSelector("vaadin-menu-bar[theme~='gridHelperToggle']"));
return (TestBenchElement) elements.stream().findFirst().orElse(null);
}

/**
* Returns the name of the slot that the column toggle is assigned to, or {@code null} if the
* column toggle is not visible or is not assigned to any slot.
*/
public String getColumnToggleSlotName() {
return (String) executeScript(
"const toggle = this.querySelector('vaadin-menu-bar[theme~=\"gridHelperToggle\"]');"
+ "return toggle && toggle.assignedSlot && toggle.assignedSlot.name;");
}

public List<CheckboxElement> getColumnToggleElements() {
try {
ElementQuery<TestBenchElement> query;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,11 @@ public void testSelectOnClick() {
}

@Test
public void testMenuToggleColumn() {
public void testMenuToggleSlot() {
grid.setColumnToggleVisible(true);

Column<Bean> toggleColumn=grid.getColumns().get(grid.getColumns().size()-1);
assertTrue(GridHelper.isMenuToggleColumn(toggleColumn));
assertTrue(grid.getElement().getChildren()
.anyMatch(e -> "fc-column-toggle".equals(e.getAttribute("slot"))));
}

@Test
Expand Down
Loading