Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
5 changes: 4 additions & 1 deletion packages/grid/src/vaadin-grid-column-reordering-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -457,9 +457,12 @@ export const ColumnReorderingMixin = (superClass) =>
}
});

[...this.$.items.children, this.$.sizer].forEach((row) => {
Comment thread
vursen marked this conversation as resolved.
this._updateFirstAndLastColumnForRow(row);
});

Comment thread
tomivirkki marked this conversation as resolved.
this.__scheduleRenderHeaderFooter();
this._debounceUpdateFrozenColumn();
this._updateFirstAndLastColumn();
}

/**
Expand Down
8 changes: 0 additions & 8 deletions packages/grid/src/vaadin-grid-dynamic-columns-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,6 @@ export const DynamicColumnsMixin = (superClass) =>
});
}

/** @protected */
_updateFirstAndLastColumn() {
// The sizer is a <caption> element, so it isn't matched by the <tr> selector
[...this.shadowRoot.querySelectorAll('tr'), this.$.sizer].forEach((row) => {
this._updateFirstAndLastColumnForRow(row);
});
}

/**
* @param {!HTMLElement} row
* @protected
Expand Down
109 changes: 87 additions & 22 deletions packages/grid/src/vaadin-grid-header-footer-rendering-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
*/
import { html, nothing, render } from 'lit';
import { cache } from 'lit/directives/cache.js';
import { classMap } from 'lit/directives/class-map.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { repeat } from 'lit/directives/repeat.js';
import { microTask } from '@vaadin/component-base/src/async.js';
import { Debouncer } from '@vaadin/component-base/src/debounce.js';
import { partMap } from '@vaadin/component-base/src/directives/part-map.js';
import { cellContent } from './directives/cell-content-directive.js';

function isEmptyCell(column, level, columnTree) {
Expand Down Expand Up @@ -78,10 +80,10 @@ export const HeaderFooterRenderingMixin = (superClass) =>
}

#renderHeader(columnTree) {
render(columnTree.map(this.#renderHeaderRow), this.$.header, { host: this });
const rows = this.#getRows(columnTree, 'header');
render(rows.map(this.#renderHeaderRow), this.$.header, { host: this });

this.$.table.toggleAttribute('has-header', !!this.$.header.querySelector('tr:not([hidden])'));
this.__updateHeaderFooterRowParts('header');

this.$.header.querySelectorAll('.header-cell').forEach((cell) => {
const column = cell._column;
Expand All @@ -94,31 +96,45 @@ export const HeaderFooterRenderingMixin = (superClass) =>
});
}

#renderHeaderRow = (columns, level, columnTree) => {
#renderHeaderRow = ({ level, cells, isLastRow, isFirstRow, isRowVisible }) => {
const rowParts = {
'first-header-row': isFirstRow,
'last-header-row': isLastRow,
};

return html`
<tr
role="row"
part="row header-row"
class="row header-row"
part="row header-row ${partMap(rowParts)}"
Comment thread
vursen marked this conversation as resolved.
Outdated
class="row header-row ${classMap(rowParts)}"
tabindex="-1"
?hidden=${!isHeaderRowVisible(columns, level, columnTree)}
?hidden=${!isRowVisible}
>
${repeat(
columns,
(column) => column._id,
(column) => {
cells,
({ column }) => column._id,
({ column, isFirstCell, isLastCell }) => {
// `cache` keeps the cell and its rendered content when the
// column gets hidden, so it can be restored as-is when the
// column is shown again.
if (column.hidden) {
return cache(nothing);
}

const cellParts = {
Comment thread
vursen marked this conversation as resolved.
'first-header-row-cell': isFirstRow,
'last-header-row-cell': isLastRow,
'first-column-cell': isFirstCell,
'last-column-cell': isLastCell,
};

return cache(html`
<th
role="columnheader"
part="cell header-cell"
class="cell header-cell"
part="cell header-cell ${partMap(cellParts)}"
class="cell header-cell ${classMap(cellParts)}"
?first-column="${isFirstCell}"
?last-column="${isLastCell}"
@keydown="${this.__onCellKeyDown}"
@mousedown=${this.__onCellMouseDown}
@mouseenter=${this.__onCellMouseEnter}
Expand All @@ -139,10 +155,10 @@ export const HeaderFooterRenderingMixin = (superClass) =>
};

#renderFooter(columnTree) {
render(columnTree.map(this.#renderFooterRow).toReversed(), this.$.footer, { host: this });
const rows = this.#getRows(columnTree, 'footer');
render(rows.map(this.#renderFooterRow), this.$.footer, { host: this });

this.$.table.toggleAttribute('has-footer', !!this.$.footer.querySelector('tr:not([hidden])'));
this.__updateHeaderFooterRowParts('footer');

this.$.footer.querySelectorAll('.footer-cell').forEach((cell) => {
const column = cell._column;
Expand All @@ -155,31 +171,45 @@ export const HeaderFooterRenderingMixin = (superClass) =>
});
}

#renderFooterRow = (columns, level, columnTree) => {
#renderFooterRow = ({ level, cells, isLastRow, isFirstRow, isRowVisible }) => {
const rowParts = {
'first-footer-row': isFirstRow,
'last-footer-row': isLastRow,
};

return html`
<tr
role="row"
part="row footer-row"
class="row footer-row"
part="row footer-row ${partMap(rowParts)}"
class="row footer-row ${classMap(rowParts)}"
tabindex="-1"
?hidden=${!isFooterRowVisible(columns, level, columnTree)}
?hidden=${!isRowVisible}
>
${repeat(
columns,
(column) => column._id,
(column) => {
cells,
({ column }) => column._id,
({ column, isFirstCell, isLastCell }) => {
// `cache` keeps the cell and its rendered content when the
// column gets hidden, so it can be restored as-is when the
// column is shown again.
if (column.hidden) {
return cache(nothing);
}

const cellParts = {
'first-footer-row-cell': isFirstRow,
'last-footer-row-cell': isLastRow,
'first-column-cell': isFirstCell,
'last-column-cell': isLastCell,
};

return cache(html`
<td
role="gridcell"
part="cell footer-cell"
class="cell footer-cell"
part="cell footer-cell ${partMap(cellParts)}"
class="cell footer-cell ${classMap(cellParts)}"
?first-column="${isFirstCell}"
?last-column="${isLastCell}"
@keydown="${this.__onCellKeyDown}"
@mousedown=${this.__onCellMouseDown}
@mouseenter=${this.__onCellMouseEnter}
Expand All @@ -197,4 +227,39 @@ export const HeaderFooterRenderingMixin = (superClass) =>
</tr>
`;
};

#getRows(columnTree, section) {
let rows = columnTree.map((columns, level) => {
const visibleColumns = columns.filter((column) => !column.hidden);

return {
level,
cells: columns.map((column) => {
return {
column,
isFirstCell: column === visibleColumns.at(0),
isLastCell: column === visibleColumns.at(-1),
};
}),
isRowVisible:
section === 'header'
? isHeaderRowVisible(columns, level, columnTree)
: isFooterRowVisible(columns, level, columnTree),
};
});

if (section === 'footer') {
rows = rows.toReversed();
}

const visibleRows = rows.filter((row) => row.isRowVisible);

return rows.map((row) => {
return {
...row,
isFirstRow: row === visibleRows.at(0),
isLastRow: row === visibleRows.at(-1),
};
});
}
};
17 changes: 0 additions & 17 deletions packages/grid/src/vaadin-grid-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -597,30 +597,13 @@ export const GridMixin = (superClass) =>

this._resizeHandler();
this._frozenCellsChanged();
this._updateFirstAndLastColumn();
this._resetKeyboardNavigation();
this.__a11yUpdateHeaderRows();
this.__a11yUpdateFooterRows();
this.generateCellPartNames();
this.__updateHeaderAndFooter();
}

/** @private */
__updateHeaderFooterRowParts(section) {
const visibleRows = [...this.$[section].querySelectorAll('tr:not([hidden])')];
[...this.$[section].children].forEach((row) => {
updatePart(row, `first-${section}-row`, row === visibleRows.at(0));
updatePart(row, `last-${section}-row`, row === visibleRows.at(-1));

getBodyRowCells(row).forEach((cell) => {
updatePart(cell, `first-${section}-row-cell`, row === visibleRows.at(0));
updatePart(cell, `last-${section}-row-cell`, row === visibleRows.at(-1));
});

this._updateFirstAndLastColumnForRow(row);
});
}

/**
* @param {!HTMLElement} row
* @param {boolean} loading
Expand Down
Loading
Loading