diff --git a/packages/dashboard/src/vaadin-dashboard-layout-mixin.d.ts b/packages/dashboard/src/vaadin-dashboard-layout-mixin.d.ts index d7f06f2bce..8ff76e23f5 100644 --- a/packages/dashboard/src/vaadin-dashboard-layout-mixin.d.ts +++ b/packages/dashboard/src/vaadin-dashboard-layout-mixin.d.ts @@ -18,4 +18,9 @@ export declare function DashboardLayoutMixin> base: T, ): Constructor & Constructor & T; -export declare class DashboardLayoutMixinClass {} +export declare class DashboardLayoutMixinClass { + /** + * Whether the dashboard layout is dense. + */ + dense: boolean; +} diff --git a/packages/dashboard/src/vaadin-dashboard-layout-mixin.js b/packages/dashboard/src/vaadin-dashboard-layout-mixin.js index f0d7986334..77939a0977 100644 --- a/packages/dashboard/src/vaadin-dashboard-layout-mixin.js +++ b/packages/dashboard/src/vaadin-dashboard-layout-mixin.js @@ -30,6 +30,10 @@ export const DashboardLayoutMixin = (superClass) => display: none !important; } + :host([dense]) #grid { + grid-auto-flow: dense; + } + #grid { box-sizing: border-box; padding: 20px; @@ -91,6 +95,20 @@ export const DashboardLayoutMixin = (superClass) => `; } + static get properties() { + return { + /** + * Whether the dashboard layout is dense. + * @type {boolean} + */ + dense: { + type: Boolean, + value: false, + reflectToAttribute: true, + }, + }; + } + /** @protected */ ready() { super.ready(); diff --git a/packages/dashboard/src/vaadin-dashboard-layout.d.ts b/packages/dashboard/src/vaadin-dashboard-layout.d.ts index ab4d7425eb..090d8f743b 100644 --- a/packages/dashboard/src/vaadin-dashboard-layout.d.ts +++ b/packages/dashboard/src/vaadin-dashboard-layout.d.ts @@ -10,11 +10,12 @@ */ import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js'; import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; +import { DashboardLayoutMixin } from './vaadin-dashboard-layout-mixin.js'; /** * A responsive, grid-based dashboard layout component */ -declare class DashboardLayout extends ElementMixin(ThemableMixin(HTMLElement)) {} +declare class DashboardLayout extends DashboardLayoutMixin(ElementMixin(ThemableMixin(HTMLElement))) {} declare global { interface HTMLElementTagNameMap { diff --git a/packages/dashboard/test/dashboard-layout.test.ts b/packages/dashboard/test/dashboard-layout.test.ts index 14ddd7e281..f4b812d43f 100644 --- a/packages/dashboard/test/dashboard-layout.test.ts +++ b/packages/dashboard/test/dashboard-layout.test.ts @@ -553,4 +553,33 @@ describe('dashboard layout', () => { }); }); }); + + describe('dense', () => { + beforeEach(async () => { + dashboard.appendChild(fixtureSync('
Item 2
')); + childElements = [...dashboard.querySelectorAll('div')]; + setColspan(childElements[1], 2); + dashboard.dense = true; + await nextFrame(); + }); + + it('should display the items in dense mode', () => { + /* prettier-ignore */ + expectLayout(dashboard, [ + [0, 2], + [1, 1], + ]); + }); + + it('should retain the order of items', async () => { + dashboard.dense = false; + await nextFrame(); + /* prettier-ignore */ + expectLayout(dashboard, [ + [0], + [1, 1], + [2], + ]); + }); + }); }); diff --git a/packages/dashboard/test/typings/dashboard.types.ts b/packages/dashboard/test/typings/dashboard.types.ts index 912a91a7b3..239f022abf 100644 --- a/packages/dashboard/test/typings/dashboard.types.ts +++ b/packages/dashboard/test/typings/dashboard.types.ts @@ -35,6 +35,7 @@ assertType(genericDashboard); assertType(genericDashboard); assertType> | null | undefined>(genericDashboard.items); assertType(genericDashboard.editable); +assertType(genericDashboard.dense); assertType<{ selectWidget: string; @@ -112,6 +113,7 @@ narrowedDashboard.addEventListener('dashboard-item-resize-mode-changed', (event) /* DashboardLayout */ const layout = document.createElement('vaadin-dashboard-layout'); assertType(layout); +assertType(layout.dense); assertType(layout); assertType(layout);