diff --git a/dev/dashboard-layout.html b/dev/dashboard-layout.html
index c02fbc7f75..97e34f781b 100644
--- a/dev/dashboard-layout.html
+++ b/dev/dashboard-layout.html
@@ -24,6 +24,7 @@
vaadin-dashboard-layout {
--vaadin-dashboard-col-min-width: 300px;
--vaadin-dashboard-col-max-width: 500px;
+ --vaadin-dashboard-row-min-height: 300px;
--vaadin-dashboard-gap: 20px;
--vaadin-dashboard-col-max-count: 3;
}
diff --git a/dev/dashboard.html b/dev/dashboard.html
index 017abfb110..1517f2d513 100644
--- a/dev/dashboard.html
+++ b/dev/dashboard.html
@@ -18,6 +18,7 @@
vaadin-dashboard {
--vaadin-dashboard-col-min-width: 300px;
--vaadin-dashboard-col-max-width: 500px;
+ --vaadin-dashboard-row-min-height: 300px;
--vaadin-dashboard-gap: 20px;
--vaadin-dashboard-col-max-count: 3;
}
diff --git a/packages/dashboard/src/vaadin-dashboard-layout-mixin.js b/packages/dashboard/src/vaadin-dashboard-layout-mixin.js
index 5fe15dd7ef..bca569d49e 100644
--- a/packages/dashboard/src/vaadin-dashboard-layout-mixin.js
+++ b/packages/dashboard/src/vaadin-dashboard-layout-mixin.js
@@ -54,6 +54,9 @@ export const DashboardLayoutMixin = (superClass) =>
var(--_vaadin-dashboard-col-max-count)
);
+ /* Effective row height */
+ --_vaadin-dashboard-row-height: minmax(var(--vaadin-dashboard-row-min-height, auto), auto);
+
display: grid;
overflow: auto;
height: 100%;
@@ -63,6 +66,8 @@ export const DashboardLayoutMixin = (superClass) =>
minmax(var(--_vaadin-dashboard-col-min-width), var(--_vaadin-dashboard-col-max-width))
);
+ grid-auto-rows: var(--_vaadin-dashboard-row-height);
+
gap: var(--vaadin-dashboard-gap, 1rem);
}
diff --git a/packages/dashboard/src/vaadin-dashboard-section.js b/packages/dashboard/src/vaadin-dashboard-section.js
index 21e5679066..409a2f9926 100644
--- a/packages/dashboard/src/vaadin-dashboard-section.js
+++ b/packages/dashboard/src/vaadin-dashboard-section.js
@@ -37,6 +37,13 @@ class DashboardSection extends ControllerMixin(ElementMixin(PolylitMixin(LitElem
--_vaadin-dashboard-section-column: 1 / calc(var(--_vaadin-dashboard-effective-col-count) + 1);
grid-column: var(--_vaadin-dashboard-section-column) !important;
gap: var(--vaadin-dashboard-gap, 1rem);
+ /* Dashbaord section header height */
+ --_vaadin-dashboard-section-header-height: minmax(0, auto);
+ grid-template-rows: var(--_vaadin-dashboard-section-header-height) repeat(
+ auto-fill,
+ var(--_vaadin-dashboard-row-height)
+ );
+ grid-auto-rows: var(--_vaadin-dashboard-row-height);
}
:host([hidden]) {
diff --git a/packages/dashboard/test/dashboard-layout.test.ts b/packages/dashboard/test/dashboard-layout.test.ts
index be32d0850b..3bee75cfc2 100644
--- a/packages/dashboard/test/dashboard-layout.test.ts
+++ b/packages/dashboard/test/dashboard-layout.test.ts
@@ -3,6 +3,7 @@ import { fixtureSync, nextFrame } from '@vaadin/testing-helpers';
import '../vaadin-dashboard-layout.js';
import '../vaadin-dashboard-section.js';
import type { DashboardLayout } from '../vaadin-dashboard-layout.js';
+import type { DashboardSection } from '../vaadin-dashboard-section.js';
import {
getColumnWidths,
getElementFromCell,
@@ -13,6 +14,7 @@ import {
setMaximumColumnCount,
setMaximumColumnWidth,
setMinimumColumnWidth,
+ setMinimumRowHeight,
} from './helpers.js';
/**
@@ -199,6 +201,33 @@ describe('dashboard layout', () => {
});
});
+ describe('minimum row height', () => {
+ const rowHeight = 100;
+
+ it('should have the row height of the highest wigdet on a row by default', () => {
+ childElements[0].style.height = `${rowHeight}px`;
+ childElements[1].style.height = '50px';
+ expect(getRowHeights(dashboard)).to.eql([rowHeight]);
+ });
+
+ it('should set a minimum row height', () => {
+ setMinimumRowHeight(dashboard, rowHeight);
+ expect(getRowHeights(dashboard)).to.eql([rowHeight]);
+ });
+
+ it('should not constrain widgets to the minumum row height', () => {
+ childElements[0].style.height = `${rowHeight * 2}px`;
+ setMinimumRowHeight(dashboard, rowHeight);
+ expect(getRowHeights(dashboard)).to.eql([rowHeight * 2]);
+ });
+
+ it('should use minimum row height for all rows', () => {
+ dashboard.style.width = `${columnWidth}px`;
+ setMinimumRowHeight(dashboard, rowHeight);
+ expect(getRowHeights(dashboard)).to.eql([rowHeight, rowHeight]);
+ });
+ });
+
describe('column span', () => {
it('should span multiple columns', async () => {
setColspan(childElements[0], 2);
@@ -365,9 +394,11 @@ describe('dashboard layout', () => {
});
describe('section', () => {
+ let section: DashboardSection;
+
beforeEach(async () => {
- const section = fixtureSync(`
-
+ section = fixtureSync(`
+
Section item 2
Section item 3
@@ -434,6 +465,27 @@ describe('dashboard layout', () => {
]);
});
+ it('should use minimum row height for all section rows', async () => {
+ dashboard.style.width = `${columnWidth}px`;
+ setMinimumRowHeight(dashboard, 300);
+ await nextFrame();
+
+ expect(childElements[2].offsetHeight).to.eql(300);
+ expect(childElements[3].offsetHeight).to.eql(300);
+ });
+
+ it('should not use minimum row height for section header row', async () => {
+ const title = section.querySelector('[slot="title"]')!;
+ title.style.height = '100%';
+
+ const titleHeight = title.offsetHeight;
+ setMinimumRowHeight(dashboard, 300);
+ await nextFrame();
+
+ const newTitleHeight = title.offsetHeight;
+ expect(newTitleHeight).to.eql(titleHeight);
+ });
+
describe('gap', () => {
it('should have a default gap', () => {
// Clear the gap used in the tests
diff --git a/packages/dashboard/test/helpers.ts b/packages/dashboard/test/helpers.ts
index cd16fedddc..75662401ca 100644
--- a/packages/dashboard/test/helpers.ts
+++ b/packages/dashboard/test/helpers.ts
@@ -98,3 +98,10 @@ export function setGap(dashboard: HTMLElement, gap?: number): void {
export function setMaximumColumnCount(dashboard: HTMLElement, count?: number): void {
dashboard.style.setProperty('--vaadin-dashboard-col-max-count', count !== undefined ? `${count}` : null);
}
+
+/**
+ * Sets the minimum row height of the dashboard.
+ */
+export function setMinimumRowHeight(dashboard: HTMLElement, height?: number): void {
+ dashboard.style.setProperty('--vaadin-dashboard-row-min-height', height !== undefined ? `${height}px` : null);
+}