From 3eae0f4eea02136d5e6e2bad23f6b99968d1f167 Mon Sep 17 00:00:00 2001 From: "totally-not-ai[bot]" <290682512+totally-not-ai[bot]@users.noreply.github.com> Date: Sat, 26 Sep 2026 09:19:32 +0000 Subject: [PATCH 1/5] docs: add dynamic Grid cell styling and row height examples Add a Flow example of value-based cell styling with a column part name generator and class names in a renderer, and describe how rows adapt their height to content and how to align cell content to the top. Co-Authored-By: Claude Opus 5.5 --- articles/components/grid/styling.adoc | 39 +++++++++++++ frontend/themes/docs/grid-cell-styling.css | 25 +++++++++ frontend/themes/docs/styles.css | 1 + .../demo/component/grid/GridCellStyling.java | 55 +++++++++++++++++++ 4 files changed, 120 insertions(+) create mode 100644 frontend/themes/docs/grid-cell-styling.css create mode 100644 src/main/java/com/vaadin/demo/component/grid/GridCellStyling.java diff --git a/articles/components/grid/styling.adoc b/articles/components/grid/styling.adoc index 5514805489..be45a951d0 100644 --- a/articles/components/grid/styling.adoc +++ b/articles/components/grid/styling.adoc @@ -347,6 +347,15 @@ Cell in the first column frozen to the end:: `vaadin-grid++++++**::part(fir You can <<#part-name-generator,style individual cells, rows, and columns>> by applying custom part names to them. Cell padding can be configured using the `--vaadin-grid-cell-padding` style property. +The height of each row adapts to its tallest cell, so rows with taller content, such as multi-line text or larger components, can have different heights. Cell content is vertically centered by default. It can be aligned to the top of the row with the `align-items` property: + +[source,css] +---- +vaadin-grid::part(body-cell) { + align-items: start; +} +---- + === Selection Checkboxes @@ -459,6 +468,36 @@ include::{root}/frontend/themes/docs/grid-styling.css[] -- +=== Styling Individual Cells + +Part names can also be applied to individual cells, based on the value they display. This is useful, for example, for highlighting values that exceed a threshold with a background color. + +ifdef::flow[] +A part name generator set on a column with [methodname]`Column.setPartNameGenerator()` applies only to the cells of that column, whereas one set on the grid with [methodname]`Grid.setPartNameGenerator()` applies to entire rows. Both receive the item of the row, so the part names can depend on any of its data. + +To style only a part of the cell content, instead of the whole cell, apply class names to the content in the renderer. Rendered cell content isn't inside the shadow DOM of the grid, so it can be styled with regular CSS selectors. + +In the example below, the cells in the [guilabel]*Customer rating* column get a background color, based on their value, and the text in the [guilabel]*Level* column is colored with class names applied in a [classname]`LitRenderer`. + +[.example,themes="lumo,aura"] +-- +[source,java] +---- +include::{root}/src/main/java/com/vaadin/demo/component/grid/GridCellStyling.java[render,tags=snippet,indent=0,group=Flow] +---- + +[source,css] +---- +include::{root}/frontend/themes/docs/grid-cell-styling.css[] +---- +-- +endif::[] + +ifndef::flow[] +The cell part name generator is called for each cell with both the column and the item, as shown in the previous example. To style only a part of the cell content, instead of the whole cell, apply class names to the elements rendered by the column renderer. +endif::[] + + == Styling Header & Footer Cells Header and footer cells can be similarly styled through their own custom part names. diff --git a/frontend/themes/docs/grid-cell-styling.css b/frontend/themes/docs/grid-cell-styling.css new file mode 100644 index 0000000000..53a8c15625 --- /dev/null +++ b/frontend/themes/docs/grid-cell-styling.css @@ -0,0 +1,25 @@ +/* Add this to your global CSS, for example in: */ +/* src/main/resources/META-INF/resources/styles.css */ + +/* Cell background, based on a part name */ +vaadin-grid.cell-styling::part(high-rating-cell) { + background: rgba(122, 201, 122, 0.2); +} + +vaadin-grid.cell-styling::part(low-rating-cell) { + background: rgba(255, 128, 114, 0.2); +} + +/* Rendered cell content, based on a class name */ +vaadin-grid.cell-styling .rating-badge { + font-weight: 600; + text-transform: capitalize; +} + +vaadin-grid.cell-styling .rating-badge.high { + color: green; +} + +vaadin-grid.cell-styling .rating-badge.low { + color: red; +} diff --git a/frontend/themes/docs/styles.css b/frontend/themes/docs/styles.css index 26691b6df1..088b1773b2 100644 --- a/frontend/themes/docs/styles.css +++ b/frontend/themes/docs/styles.css @@ -10,6 +10,7 @@ @import './notification-position-example.css'; @import './grid-cell-focus.css'; @import './grid-styling.css'; +@import './grid-cell-styling.css'; @import './grid-header-footer-styling.css'; @import './menu-bar-class-name.css'; @import './message-list-class-name.css'; diff --git a/src/main/java/com/vaadin/demo/component/grid/GridCellStyling.java b/src/main/java/com/vaadin/demo/component/grid/GridCellStyling.java new file mode 100644 index 0000000000..1fa92c53e1 --- /dev/null +++ b/src/main/java/com/vaadin/demo/component/grid/GridCellStyling.java @@ -0,0 +1,55 @@ +package com.vaadin.demo.component.grid; + +import com.vaadin.demo.DemoExporter; // hidden-source-line +import com.vaadin.demo.domain.DataService; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.html.Div; +import com.vaadin.flow.data.renderer.LitRenderer; +import com.vaadin.flow.router.Route; + +import java.util.List; + +@Route("grid-cell-styling") +public class GridCellStyling extends Div { + + public GridCellStyling() { + Grid grid = new Grid<>(PersonWithRating.class, false); + grid.addClassName("cell-styling"); + grid.addColumn(PersonWithRating::getFirstName).setHeader("First name"); + grid.addColumn(PersonWithRating::getLastName).setHeader("Last name"); + // tag::snippet[] + // Style the whole cell based on its value + grid.addColumn(PersonWithRating::getFormattedRating) + .setHeader("Customer rating (0-10)") + .setPartNameGenerator(person -> { + if (person.getRating() >= 8) + return "high-rating-cell"; + if (person.getRating() <= 4) + return "low-rating-cell"; + return null; + }); + + // Style only part of the cell content + grid.addColumn(LitRenderer. of(""" + ${item.level} + """).withProperty("level", person -> person.getRating() >= 8 + ? "high" + : person.getRating() <= 4 ? "low" : "medium")) + .setHeader("Level"); + // end::snippet[] + + List people = createDataSet(); + grid.setItems(people); + + add(grid); + } + + private static List createDataSet() { + return DataService.getPeople().stream() + .map(PersonWithRating::generateFromPerson).toList(); + } + + public static class Exporter // hidden-source-line + extends DemoExporter { // hidden-source-line + } // hidden-source-line +} From 0e82309f88efa9966e0f0b2b43c409b8094d6aa9 Mon Sep 17 00:00:00 2001 From: "totally-not-ai[bot]" <290682512+totally-not-ai[bot]@users.noreply.github.com> Date: Sat, 26 Sep 2026 09:47:59 +0000 Subject: [PATCH 2/5] docs: apply spotless formatting to Grid cell styling example Co-Authored-By: Claude Opus 5.5 --- .../java/com/vaadin/demo/component/grid/GridCellStyling.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/vaadin/demo/component/grid/GridCellStyling.java b/src/main/java/com/vaadin/demo/component/grid/GridCellStyling.java index 1fa92c53e1..0b6a884fdc 100644 --- a/src/main/java/com/vaadin/demo/component/grid/GridCellStyling.java +++ b/src/main/java/com/vaadin/demo/component/grid/GridCellStyling.java @@ -32,8 +32,8 @@ public GridCellStyling() { // Style only part of the cell content grid.addColumn(LitRenderer. of(""" ${item.level} - """).withProperty("level", person -> person.getRating() >= 8 - ? "high" + """).withProperty("level", + person -> person.getRating() >= 8 ? "high" : person.getRating() <= 4 ? "low" : "medium")) .setHeader("Level"); // end::snippet[] From e3653f710ee7f2324ca1b15cc634753b471e6c20 Mon Sep 17 00:00:00 2001 From: "totally-not-ai[bot]" <290682512+totally-not-ai[bot]@users.noreply.github.com> Date: Mon, 28 Sep 2026 14:10:03 +0000 Subject: [PATCH 3/5] docs: remove Grid cell styling subsection already covered by part name docs Co-Authored-By: Claude Opus 5.5 --- articles/components/grid/styling.adoc | 30 ---------- frontend/themes/docs/grid-cell-styling.css | 25 --------- frontend/themes/docs/styles.css | 1 - .../demo/component/grid/GridCellStyling.java | 55 ------------------- 4 files changed, 111 deletions(-) delete mode 100644 frontend/themes/docs/grid-cell-styling.css delete mode 100644 src/main/java/com/vaadin/demo/component/grid/GridCellStyling.java diff --git a/articles/components/grid/styling.adoc b/articles/components/grid/styling.adoc index be45a951d0..7db036e6d0 100644 --- a/articles/components/grid/styling.adoc +++ b/articles/components/grid/styling.adoc @@ -468,36 +468,6 @@ include::{root}/frontend/themes/docs/grid-styling.css[] -- -=== Styling Individual Cells - -Part names can also be applied to individual cells, based on the value they display. This is useful, for example, for highlighting values that exceed a threshold with a background color. - -ifdef::flow[] -A part name generator set on a column with [methodname]`Column.setPartNameGenerator()` applies only to the cells of that column, whereas one set on the grid with [methodname]`Grid.setPartNameGenerator()` applies to entire rows. Both receive the item of the row, so the part names can depend on any of its data. - -To style only a part of the cell content, instead of the whole cell, apply class names to the content in the renderer. Rendered cell content isn't inside the shadow DOM of the grid, so it can be styled with regular CSS selectors. - -In the example below, the cells in the [guilabel]*Customer rating* column get a background color, based on their value, and the text in the [guilabel]*Level* column is colored with class names applied in a [classname]`LitRenderer`. - -[.example,themes="lumo,aura"] --- -[source,java] ----- -include::{root}/src/main/java/com/vaadin/demo/component/grid/GridCellStyling.java[render,tags=snippet,indent=0,group=Flow] ----- - -[source,css] ----- -include::{root}/frontend/themes/docs/grid-cell-styling.css[] ----- --- -endif::[] - -ifndef::flow[] -The cell part name generator is called for each cell with both the column and the item, as shown in the previous example. To style only a part of the cell content, instead of the whole cell, apply class names to the elements rendered by the column renderer. -endif::[] - - == Styling Header & Footer Cells Header and footer cells can be similarly styled through their own custom part names. diff --git a/frontend/themes/docs/grid-cell-styling.css b/frontend/themes/docs/grid-cell-styling.css deleted file mode 100644 index 53a8c15625..0000000000 --- a/frontend/themes/docs/grid-cell-styling.css +++ /dev/null @@ -1,25 +0,0 @@ -/* Add this to your global CSS, for example in: */ -/* src/main/resources/META-INF/resources/styles.css */ - -/* Cell background, based on a part name */ -vaadin-grid.cell-styling::part(high-rating-cell) { - background: rgba(122, 201, 122, 0.2); -} - -vaadin-grid.cell-styling::part(low-rating-cell) { - background: rgba(255, 128, 114, 0.2); -} - -/* Rendered cell content, based on a class name */ -vaadin-grid.cell-styling .rating-badge { - font-weight: 600; - text-transform: capitalize; -} - -vaadin-grid.cell-styling .rating-badge.high { - color: green; -} - -vaadin-grid.cell-styling .rating-badge.low { - color: red; -} diff --git a/frontend/themes/docs/styles.css b/frontend/themes/docs/styles.css index 088b1773b2..26691b6df1 100644 --- a/frontend/themes/docs/styles.css +++ b/frontend/themes/docs/styles.css @@ -10,7 +10,6 @@ @import './notification-position-example.css'; @import './grid-cell-focus.css'; @import './grid-styling.css'; -@import './grid-cell-styling.css'; @import './grid-header-footer-styling.css'; @import './menu-bar-class-name.css'; @import './message-list-class-name.css'; diff --git a/src/main/java/com/vaadin/demo/component/grid/GridCellStyling.java b/src/main/java/com/vaadin/demo/component/grid/GridCellStyling.java deleted file mode 100644 index 0b6a884fdc..0000000000 --- a/src/main/java/com/vaadin/demo/component/grid/GridCellStyling.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.vaadin.demo.component.grid; - -import com.vaadin.demo.DemoExporter; // hidden-source-line -import com.vaadin.demo.domain.DataService; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.html.Div; -import com.vaadin.flow.data.renderer.LitRenderer; -import com.vaadin.flow.router.Route; - -import java.util.List; - -@Route("grid-cell-styling") -public class GridCellStyling extends Div { - - public GridCellStyling() { - Grid grid = new Grid<>(PersonWithRating.class, false); - grid.addClassName("cell-styling"); - grid.addColumn(PersonWithRating::getFirstName).setHeader("First name"); - grid.addColumn(PersonWithRating::getLastName).setHeader("Last name"); - // tag::snippet[] - // Style the whole cell based on its value - grid.addColumn(PersonWithRating::getFormattedRating) - .setHeader("Customer rating (0-10)") - .setPartNameGenerator(person -> { - if (person.getRating() >= 8) - return "high-rating-cell"; - if (person.getRating() <= 4) - return "low-rating-cell"; - return null; - }); - - // Style only part of the cell content - grid.addColumn(LitRenderer. of(""" - ${item.level} - """).withProperty("level", - person -> person.getRating() >= 8 ? "high" - : person.getRating() <= 4 ? "low" : "medium")) - .setHeader("Level"); - // end::snippet[] - - List people = createDataSet(); - grid.setItems(people); - - add(grid); - } - - private static List createDataSet() { - return DataService.getPeople().stream() - .map(PersonWithRating::generateFromPerson).toList(); - } - - public static class Exporter // hidden-source-line - extends DemoExporter { // hidden-source-line - } // hidden-source-line -} From 853c649520d394b43ef5c1d0b0267681e0ba4ba8 Mon Sep 17 00:00:00 2001 From: "totally-not-ai[bot]" <290682512+totally-not-ai[bot]@users.noreply.github.com> Date: Mon, 28 Sep 2026 14:51:40 +0000 Subject: [PATCH 4/5] docs: move Grid row height note under Wrap Cell Content Co-Authored-By: Claude Opus 5.5 --- articles/components/grid/styling.adoc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/articles/components/grid/styling.adoc b/articles/components/grid/styling.adoc index 7db036e6d0..9259198589 100644 --- a/articles/components/grid/styling.adoc +++ b/articles/components/grid/styling.adoc @@ -80,6 +80,15 @@ include::{root}/frontend/demo/component/grid/react/grid-wrap-cell-content.tsx[re endif::[] -- +When content wraps, each row grows to fit its tallest cell, so rows can have different heights. Cell content is vertically centered by default. To align it to the top of the row instead, use the `align-items` property: + +[source,css] +---- +vaadin-grid::part(body-cell) { + align-items: start; +} +---- + <> can also be used to display content that doesn't fit into the cell. @@ -347,15 +356,6 @@ Cell in the first column frozen to the end:: `vaadin-grid++++++**::part(fir You can <<#part-name-generator,style individual cells, rows, and columns>> by applying custom part names to them. Cell padding can be configured using the `--vaadin-grid-cell-padding` style property. -The height of each row adapts to its tallest cell, so rows with taller content, such as multi-line text or larger components, can have different heights. Cell content is vertically centered by default. It can be aligned to the top of the row with the `align-items` property: - -[source,css] ----- -vaadin-grid::part(body-cell) { - align-items: start; -} ----- - === Selection Checkboxes From 5bcbb1862d3c79a2d82d038e6a5b69e07eb48e94 Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Mon, 28 Sep 2026 19:02:38 +0400 Subject: [PATCH 5/5] docs: trim Grid cell alignment note to the alignment tip Move the tooltip sentence directly after the wrap example and drop the row height sentence, which the Dynamic Height section already covers. Co-Authored-By: Claude Fable 5.1 --- articles/components/grid/styling.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/articles/components/grid/styling.adoc b/articles/components/grid/styling.adoc index 9259198589..9fb8124fe9 100644 --- a/articles/components/grid/styling.adoc +++ b/articles/components/grid/styling.adoc @@ -80,7 +80,9 @@ include::{root}/frontend/demo/component/grid/react/grid-wrap-cell-content.tsx[re endif::[] -- -When content wraps, each row grows to fit its tallest cell, so rows can have different heights. Cell content is vertically centered by default. To align it to the top of the row instead, use the `align-items` property: +<> can also be used to display content that doesn't fit into the cell. + +Wrapped cell content is vertically centered by default. To align it to the top of the row instead, set the `align-items` property on the body cell part: [source,css] ---- @@ -89,8 +91,6 @@ vaadin-grid::part(body-cell) { } ---- -<> can also be used to display content that doesn't fit into the cell. - === No Border