Skip to content
Merged
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
52 changes: 26 additions & 26 deletions packages/crud/test/dom/__snapshots__/crud.test.snap.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,25 +106,25 @@ snapshots["vaadin-crud host default"] =
</vaadin-grid-column-group>
<vaadin-crud-edit-column>
</vaadin-crud-edit-column>
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-0">
<vaadin-grid-cell-content slot="vaadin-grid-header-cell-content-0-0">
<vaadin-grid-sorter
aria-label="Sort by Name"
path="name"
>
Name
</vaadin-grid-sorter>
</vaadin-grid-cell-content>
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-1">
<vaadin-grid-cell-content slot="vaadin-grid-header-cell-content-0-2">
<vaadin-grid-sorter
aria-label="Sort by Age"
path="age"
>
Age
</vaadin-grid-sorter>
</vaadin-grid-cell-content>
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-2">
<vaadin-grid-cell-content slot="vaadin-grid-header-cell-content-0-4">
</vaadin-grid-cell-content>
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-3">
<vaadin-grid-cell-content slot="vaadin-grid-header-cell-content-1-1">
<vaadin-grid-filter
aria-label="Filter by Name"
path="name"
Expand All @@ -136,26 +136,26 @@ snapshots["vaadin-crud host default"] =
theme="small"
>
<label
for="input-vaadin-text-field-6"
id="label-vaadin-text-field-0"
for="input-vaadin-text-field-8"
id="label-vaadin-text-field-5"
slot="label"
>
</label>
<div
hidden=""
id="error-message-vaadin-text-field-2"
id="error-message-vaadin-text-field-7"
slot="error-message"
>
</div>
<input
id="input-vaadin-text-field-6"
id="input-vaadin-text-field-8"
slot="input"
type="text"
>
</vaadin-text-field>
</vaadin-grid-filter>
</vaadin-grid-cell-content>
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-4">
<vaadin-grid-cell-content slot="vaadin-grid-header-cell-content-1-3">
<vaadin-grid-filter
aria-label="Filter by Age"
path="age"
Expand All @@ -167,52 +167,52 @@ snapshots["vaadin-crud host default"] =
theme="small"
>
<label
for="input-vaadin-text-field-7"
id="label-vaadin-text-field-3"
for="input-vaadin-text-field-12"
id="label-vaadin-text-field-9"
slot="label"
>
</label>
<div
hidden=""
id="error-message-vaadin-text-field-5"
id="error-message-vaadin-text-field-11"
slot="error-message"
>
</div>
<input
id="input-vaadin-text-field-7"
id="input-vaadin-text-field-12"
slot="input"
type="text"
>
</vaadin-text-field>
</vaadin-grid-filter>
</vaadin-grid-cell-content>
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-5">
<vaadin-grid-cell-content slot="vaadin-grid-header-cell-content-1-4">
</vaadin-grid-cell-content>
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-6">
<vaadin-grid-cell-content slot="vaadin-grid-footer-cell-content-1-1">
</vaadin-grid-cell-content>
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-7">
<vaadin-grid-cell-content slot="vaadin-grid-footer-cell-content-1-3">
</vaadin-grid-cell-content>
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-8">
<vaadin-grid-cell-content slot="vaadin-grid-footer-cell-content-1-4">
</vaadin-grid-cell-content>
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-9">
<vaadin-grid-cell-content slot="vaadin-grid-footer-cell-content-0-0">
</vaadin-grid-cell-content>
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-10">
<vaadin-grid-cell-content slot="vaadin-grid-footer-cell-content-0-2">
</vaadin-grid-cell-content>
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-11">
<vaadin-grid-cell-content slot="vaadin-grid-footer-cell-content-0-4">
</vaadin-grid-cell-content>
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-12">
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-0">
</vaadin-grid-cell-content>
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-13">
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-1">
</vaadin-grid-cell-content>
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-14">
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-2">
</vaadin-grid-cell-content>
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-15">
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-3">
John
</vaadin-grid-cell-content>
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-16">
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-4">
30
</vaadin-grid-cell-content>
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-17">
<vaadin-grid-cell-content slot="vaadin-grid-cell-content-5">
<vaadin-crud-edit
aria-label="Edit"
role="button"
Expand Down
32 changes: 32 additions & 0 deletions packages/grid/src/directives/cell-content-directive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* @license
* Copyright (c) 2016 - 2026 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
import { html } from 'lit';
import { AsyncDirective, directive } from 'lit/async-directive.js';

/**
* A directive that manages the `<vaadin-grid-cell-content>` element for a cell.
*/
class CellContentDirective extends AsyncDirective {
#cell;

update(part, [grid, slotName]) {
this.#cell = part.parentNode;
this.#cell._content ??= document.createElement('vaadin-grid-cell-content');
this.#cell._content.slot = slotName;

if (!grid.contains(this.#cell._content)) {
grid.appendChild(this.#cell._content);
}

return html`<slot name="${slotName}"></slot>`;
}

disconnected() {
this.#cell._content?.remove();
}
}

export const cellContent = directive(CellContentDirective);
6 changes: 1 addition & 5 deletions packages/grid/src/vaadin-grid-column-auto-width-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,7 @@ export const ColumnAutoWidthMixin = (superClass) =>
_recalculateColumnWidths() {
// Flush to make sure DOM is up-to-date when measuring the column widths
this.__virtualizer.flush();
[...this.$.header.children, ...this.$.footer.children].forEach((row) => {
if (row.__debounceUpdateHeaderFooterRowVisibility) {
row.__debounceUpdateHeaderFooterRowVisibility.flush();
}
});
this.__renderHeaderFooterDebouncer?.flush();

this.__hasHadRenderedRowsForColumnWidthCalculation ||= this._getRenderedRows().length > 0;

Expand Down
55 changes: 26 additions & 29 deletions packages/grid/src/vaadin-grid-column-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import { animationFrame } from '@vaadin/component-base/src/async.js';
import { Debouncer } from '@vaadin/component-base/src/debounce.js';
import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
import { get } from '@vaadin/component-base/src/path-utils.js';
import { updateCellState, updatePart } from './vaadin-grid-helpers.js';
import { generateUniqueId } from '@vaadin/component-base/src/unique-id-utils.js';
import { updateCellState } from './vaadin-grid-helpers.js';

export const ColumnBaseMixin = (superClass) =>
class ColumnBaseMixin extends superClass {
Expand Down Expand Up @@ -270,7 +271,7 @@ export const ColumnBaseMixin = (superClass) =>
'_onRendererOrBindingChanged(_renderer, _cells, _bodyContentHidden, path)',
'_onHeaderRendererOrBindingChanged(_headerRenderer, _headerCell, path, header)',
'_onFooterRendererOrBindingChanged(_footerRenderer, _footerCell)',
'_resizableChanged(resizable, _headerCell)',
'_resizableChanged(resizable)',
'_reorderStatusChanged(_reorderStatus, _headerCell, _footerCell, _cells)',
'_hiddenChanged(hidden, _headerCell, _footerCell, _cells)',
'_rowHeaderChanged(rowHeader, _cells)',
Expand Down Expand Up @@ -302,6 +303,19 @@ export const ColumnBaseMixin = (superClass) =>
.filter((cell) => cell);
}

constructor() {
super();

/**
* A stable unique id assigned once per column instance. Used to build
* cell content slot names that stay stable across re-renders, so lit
* can reuse the cell content elements when the column tree changes.
*
* @protected
*/
this._id = generateUniqueId();
}

/** @protected */
connectedCallback() {
super.connectedCallback();
Expand All @@ -313,7 +327,7 @@ export const ColumnBaseMixin = (superClass) =>
return;
}

this._allCells.forEach((cell) => {
this._cells?.forEach((cell) => {
if (!cell._content.parentNode) {
this._grid.appendChild(cell._content);
}
Expand All @@ -332,7 +346,7 @@ export const ColumnBaseMixin = (superClass) =>
return;
}

this._allCells.forEach((cell) => {
this._cells?.forEach((cell) => {
if (cell._content.parentNode) {
cell._content.parentNode.removeChild(cell._content);
}
Expand Down Expand Up @@ -485,27 +499,12 @@ export const ColumnBaseMixin = (superClass) =>
}

/** @private */
_resizableChanged(resizable, headerCell) {
if (resizable === undefined || headerCell === undefined) {
_resizableChanged(resizable) {
if (resizable === undefined || this._grid === undefined) {
return;
}

if (headerCell) {
[headerCell].concat(this._emptyCells).forEach((cell) => {
if (cell) {
const existingHandle = cell.querySelector('[part~="resize-handle"]');
if (existingHandle) {
cell.removeChild(existingHandle);
}

if (resizable) {
const handle = document.createElement('div');
updatePart(handle, 'resize-handle', true);
cell.appendChild(handle);
}
}
});
}
this._grid.__scheduleRenderHeaderFooter?.();
}

/** @private */
Expand All @@ -531,7 +530,7 @@ export const ColumnBaseMixin = (superClass) =>

if (!!hidden !== !!this._previousHidden && this._grid) {
if (hidden === true) {
this._allCells.forEach((cell) => {
this._cells?.forEach((cell) => {
if (cell._content.parentNode) {
cell._content.parentNode.removeChild(cell._content);
}
Expand Down Expand Up @@ -632,9 +631,8 @@ export const ColumnBaseMixin = (superClass) =>
}

this.__renderCellsContent(headerRenderer, [headerCell]);
if (this._grid && headerCell.parentElement) {
this._grid.__debounceUpdateHeaderFooterRowVisibility(headerCell.parentElement);
}

this._grid?.__scheduleRenderHeaderFooter();
}

/** @protected */
Expand Down Expand Up @@ -689,9 +687,8 @@ export const ColumnBaseMixin = (superClass) =>
}

this.__renderCellsContent(footerRenderer, [footerCell]);
if (this._grid && footerCell.parentElement) {
this._grid.__debounceUpdateHeaderFooterRowVisibility(footerCell.parentElement);
}

this._grid?.__scheduleRenderHeaderFooter();
}

/** @protected */
Expand Down
Loading
Loading