@vaadin/grid
Advanced tools
Comparing version 24.4.0-alpha9 to 24.4.0-beta1
{ | ||
"name": "@vaadin/grid", | ||
"version": "24.4.0-alpha9", | ||
"version": "24.4.0-beta1", | ||
"publishConfig": { | ||
@@ -49,10 +49,10 @@ "access": "public" | ||
"@polymer/polymer": "^3.0.0", | ||
"@vaadin/a11y-base": "24.4.0-alpha9", | ||
"@vaadin/checkbox": "24.4.0-alpha9", | ||
"@vaadin/component-base": "24.4.0-alpha9", | ||
"@vaadin/lit-renderer": "24.4.0-alpha9", | ||
"@vaadin/text-field": "24.4.0-alpha9", | ||
"@vaadin/vaadin-lumo-styles": "24.4.0-alpha9", | ||
"@vaadin/vaadin-material-styles": "24.4.0-alpha9", | ||
"@vaadin/vaadin-themable-mixin": "24.4.0-alpha9", | ||
"@vaadin/a11y-base": "24.4.0-beta1", | ||
"@vaadin/checkbox": "24.4.0-beta1", | ||
"@vaadin/component-base": "24.4.0-beta1", | ||
"@vaadin/lit-renderer": "24.4.0-beta1", | ||
"@vaadin/text-field": "24.4.0-beta1", | ||
"@vaadin/vaadin-lumo-styles": "24.4.0-beta1", | ||
"@vaadin/vaadin-material-styles": "24.4.0-beta1", | ||
"@vaadin/vaadin-themable-mixin": "24.4.0-beta1", | ||
"lit": "^3.0.0" | ||
@@ -69,3 +69,3 @@ }, | ||
], | ||
"gitHead": "effb81abe3c6283a6ec620cc0cee56069af58226" | ||
"gitHead": "504787f741d677467ae93ca7cd31d84489366a9c" | ||
} |
@@ -8,3 +8,2 @@ # @vaadin/grid | ||
[![npm version](https://badgen.net/npm/v/@vaadin/grid)](https://www.npmjs.com/package/@vaadin/grid) | ||
[![Discord](https://img.shields.io/discord/732335336448852018?label=discord)](https://discord.gg/PHmkCKC) | ||
@@ -11,0 +10,0 @@ ```html |
@@ -19,3 +19,5 @@ /** | ||
_a11yGetHeaderRowCount(_columnTree) { | ||
return _columnTree.filter((level) => level.some((col) => col.headerRenderer || col.path || col.header)).length; | ||
return _columnTree.filter((level) => | ||
level.some((col) => col.headerRenderer || (col.path && col.header !== null) || col.header), | ||
).length; | ||
} | ||
@@ -22,0 +24,0 @@ |
@@ -240,9 +240,22 @@ /** | ||
} | ||
const cell = this.shadowRoot.elementFromPoint(x, y); | ||
const elementFromPoint = this.shadowRoot.elementFromPoint(x, y); | ||
this.$.scroller.toggleAttribute('no-content-pointer-events', false); | ||
// Make sure the element is actually a cell | ||
if (cell && cell._column) { | ||
return cell; | ||
return this._getCellFromElement(elementFromPoint); | ||
} | ||
/** @private */ | ||
_getCellFromElement(element) { | ||
if (element) { | ||
// Check if element is a cell | ||
if (element._column) { | ||
return element; | ||
} | ||
// Check if element is the cell of a focus button mode column | ||
const { parentElement } = element; | ||
if (parentElement && parentElement._focusButton === element) { | ||
return parentElement; | ||
} | ||
} | ||
return null; | ||
} | ||
@@ -249,0 +262,0 @@ |
@@ -209,6 +209,2 @@ /** | ||
_getItem(index, el) { | ||
if (index >= this._flatSize) { | ||
return; | ||
} | ||
el.index = index; | ||
@@ -329,5 +325,15 @@ | ||
_onDataProviderPageReceived() { | ||
// With the new items added, update the cache size and the grid's effective size | ||
this._flatSize = this._dataProviderController.flatSize; | ||
// If the page response affected the flat size | ||
if (this._flatSize !== this._dataProviderController.flatSize) { | ||
// Schedule an update of all rendered rows by _debouncerApplyCachedData, | ||
// to ensure that all pages associated with the rendered rows are loaded. | ||
this._shouldUpdateAllRenderedRowsAfterPageLoad = true; | ||
// TODO: Updating the flat size property can still result in a synchonous virtualizer update | ||
// if the size change requires the virtualizer to increase the amount of physical elements | ||
// to display new items e.g. the viewport fits 10 items and the size changes from 1 to 10. | ||
// This is something to be optimized in the future. | ||
this._flatSize = this._dataProviderController.flatSize; | ||
} | ||
// After updating the cache, check if some of the expanded items should have sub-caches loaded | ||
@@ -347,5 +353,8 @@ this._getRenderedRows().forEach((row) => { | ||
const shouldUpdateAllRenderedRowsAfterPageLoad = this._shouldUpdateAllRenderedRowsAfterPageLoad; | ||
this._shouldUpdateAllRenderedRowsAfterPageLoad = false; | ||
this._getRenderedRows().forEach((row) => { | ||
const { item } = this._dataProviderController.getFlatIndexContext(row.index); | ||
if (item) { | ||
if (item || shouldUpdateAllRenderedRowsAfterPageLoad) { | ||
this._getItem(row.index, row); | ||
@@ -380,3 +389,3 @@ } | ||
if (!this.__virtualizer.size) { | ||
if (!this.__virtualizer || !this.__virtualizer.size) { | ||
this._dataProviderController.loadFirstPage(); | ||
@@ -383,0 +392,0 @@ } |
@@ -33,11 +33,5 @@ /** | ||
static get observers() { | ||
return ['_onHeaderRendererOrBindingChanged(_headerRenderer, _headerCell, path, header, _filterValue)']; | ||
return ['_onHeaderRendererOrBindingChanged(_headerRenderer, _headerCell, path, header)']; | ||
} | ||
constructor() { | ||
super(); | ||
this.__boundOnFilterValueChanged = this.__onFilterValueChanged.bind(this); | ||
} | ||
/** | ||
@@ -58,3 +52,2 @@ * Renders the grid filter with the custom text field to the header cell. | ||
textField.setAttribute('focus-target', ''); | ||
textField.addEventListener('value-changed', this.__boundOnFilterValueChanged); | ||
filter.appendChild(textField); | ||
@@ -65,6 +58,3 @@ root.appendChild(filter); | ||
filter.path = this.path; | ||
filter.value = this._filterValue; | ||
textField.__rendererValue = this._filterValue; | ||
textField.value = this._filterValue; | ||
textField.label = this.__getHeader(this.header, this.path); | ||
@@ -84,17 +74,2 @@ } | ||
/** | ||
* Updates the internal filter value once the filter text field is changed. | ||
* The listener handles only user-fired events. | ||
* | ||
* @private | ||
*/ | ||
__onFilterValueChanged(e) { | ||
// Skip if the value is changed by the renderer. | ||
if (e.detail.value === e.target.__rendererValue) { | ||
return; | ||
} | ||
this._filterValue = e.detail.value; | ||
} | ||
/** @private */ | ||
@@ -101,0 +76,0 @@ __getHeader(header, path) { |
@@ -72,8 +72,4 @@ /** | ||
initializer: (field) => { | ||
field.addEventListener('value-changed', (e) => { | ||
if (field.__previousValue === undefined && e.detail.value === '') { | ||
field.__previousValue = e.detail.value; | ||
return; | ||
} | ||
this.value = e.detail.value; | ||
field.addEventListener('input', (e) => { | ||
this.value = e.target.value; | ||
}); | ||
@@ -92,8 +88,4 @@ | ||
} | ||
if (this._previousValue === undefined && value === '') { | ||
return; | ||
} | ||
textField.value = value; | ||
this._previousValue = value; | ||
@@ -100,0 +92,0 @@ this._debouncerFilterChanged = Debouncer.debounce(this._debouncerFilterChanged, timeOut.after(200), () => { |
@@ -817,6 +817,8 @@ /** | ||
if (rootTarget === this.$.table || rootTarget === this.$.focusexit) { | ||
// The focus enters the top (bottom) of the grid, meaning that user has | ||
// tabbed (shift-tabbed) into the grid. Move the focus to | ||
// the first (the last) focusable. | ||
this._predictFocusStepTarget(rootTarget, rootTarget === this.$.table ? 1 : -1).focus(); | ||
if (!this._isMousedown) { | ||
// The focus enters the top (bottom) of the grid, meaning that user has | ||
// tabbed (shift-tabbed) into the grid. Move the focus to | ||
// the first (the last) focusable. | ||
this._predictFocusStepTarget(rootTarget, rootTarget === this.$.table ? 1 : -1).focus(); | ||
} | ||
this._setInteracting(false); | ||
@@ -823,0 +825,0 @@ } else { |
@@ -320,7 +320,2 @@ /** | ||
/** @private */ | ||
__hasRowsWithClientHeight() { | ||
return !!Array.from(this.$.items.children).filter((row) => row.clientHeight).length; | ||
} | ||
/** @private */ | ||
__getIntrinsicWidth(col) { | ||
@@ -502,8 +497,22 @@ if (!this.__intrinsicWidthCache.has(col)) { | ||
__tryToRecalculateColumnWidthsIfPending() { | ||
if ( | ||
this.__pendingRecalculateColumnWidths && | ||
!isElementHidden(this) && | ||
!this._dataProviderController.isLoading() && | ||
this.__hasRowsWithClientHeight() | ||
) { | ||
if (!this.__pendingRecalculateColumnWidths || isElementHidden(this) || this._dataProviderController.isLoading()) { | ||
return; | ||
} | ||
// Delay recalculation if any rows are missing an index. | ||
// This can happen during the grid's initialization if the recalculation is triggered | ||
// as a result of the data provider responding synchronously to a page request created | ||
// in the middle of the virtualizer update loop. In this case, rows after the one that | ||
// triggered the page request may not have an index property yet. The lack of index | ||
// prevents _onDataProviderPageReceived from requesting children for these rows, | ||
// resulting in loading state being set to false and the recalculation beginning | ||
// before all the data is loaded. Note, rows without index get updated in later iterations | ||
// of the virtualizer update loop, ensuring the grid eventually reaches a stable state. | ||
const hasRowsWithUndefinedIndex = [...this.$.items.children].some((row) => row.index === undefined); | ||
if (hasRowsWithUndefinedIndex) { | ||
return; | ||
} | ||
const hasRowsWithClientHeight = [...this.$.items.children].some((row) => row.clientHeight > 0); | ||
if (hasRowsWithClientHeight) { | ||
this.__pendingRecalculateColumnWidths = false; | ||
@@ -673,2 +682,5 @@ this.recalculateColumnWidths(); | ||
cell = this._createCell('td', column); | ||
if (column._onCellKeyDown) { | ||
cell.addEventListener('keydown', column._onCellKeyDown.bind(column)); | ||
} | ||
column._cells.push(cell); | ||
@@ -717,3 +729,9 @@ } | ||
if (isColumnRow || column.localName === 'vaadin-grid-column-group') { | ||
cell = column[`_${section}Cell`] || this._createCell(tagName); | ||
cell = column[`_${section}Cell`]; | ||
if (!cell) { | ||
cell = this._createCell(tagName); | ||
if (column._onCellKeyDown) { | ||
cell.addEventListener('keydown', column._onCellKeyDown.bind(column)); | ||
} | ||
} | ||
cell._column = column; | ||
@@ -720,0 +738,0 @@ row.appendChild(cell); |
@@ -126,2 +126,15 @@ /** | ||
this._rowWithFocusedElement = e.composedPath()[itemsIndex - 1]; | ||
if (this._rowWithFocusedElement) { | ||
// Make sure the row with the focused element is fully inside the visible viewport | ||
this.__scrollIntoViewport(this._rowWithFocusedElement.index); | ||
if (!this.$.table.contains(e.relatedTarget)) { | ||
// Virtualizer can't catch the event because if orginates from the light DOM. | ||
// Dispatch a virtualizer-element-focused event for virtualizer to catch. | ||
this.$.table.dispatchEvent( | ||
new CustomEvent('virtualizer-element-focused', { detail: { element: this._rowWithFocusedElement } }), | ||
); | ||
} | ||
} | ||
}); | ||
@@ -239,3 +252,3 @@ this.$.items.addEventListener('focusout', () => { | ||
__updateColumnsBodyContentHidden() { | ||
if (!this._columnTree) { | ||
if (!this._columnTree || !this._areSizerCellsAssigned()) { | ||
return; | ||
@@ -245,8 +258,2 @@ } | ||
const columnsInOrder = this._getColumnsInOrder(); | ||
// Return if sizer cells are not yet assigned to columns | ||
if (!columnsInOrder[0] || !columnsInOrder[0]._sizerCell) { | ||
return; | ||
} | ||
let bodyContentHiddenChanged = false; | ||
@@ -491,3 +498,3 @@ | ||
if (this._lazyColumns) { | ||
if (this._lazyColumns && this._areSizerCellsAssigned()) { | ||
// Lazy column rendering is used, calculate the offset to apply to the frozen to end cells | ||
@@ -522,2 +529,7 @@ const columnsInOrder = this._getColumnsInOrder(); | ||
} | ||
/** @private */ | ||
_areSizerCellsAssigned() { | ||
return this._getColumnsInOrder().every((column) => column._sizerCell); | ||
} | ||
}; |
@@ -35,2 +35,10 @@ /** | ||
/** | ||
* Override `autoWidth` to enable auto-width | ||
*/ | ||
autoWidth: { | ||
type: Boolean, | ||
value: true, | ||
}, | ||
/** | ||
* Flex grow ratio for the cell widths. When set to 0, cell width is fixed. | ||
@@ -238,2 +246,12 @@ * @attr {number} flex-grow | ||
/** @private */ | ||
_onCellKeyDown(e) { | ||
const target = e.composedPath()[0]; | ||
// Toggle on Space without having to enter interaction mode first | ||
if (e.keyCode === 32 && (target === this._headerCell || (this._cells.includes(target) && !this.autoSelect))) { | ||
const checkbox = target._content.firstElementChild; | ||
checkbox.checked = !checkbox.checked; | ||
} | ||
} | ||
/** @private */ | ||
__dragAutoScroller() { | ||
@@ -240,0 +258,0 @@ if (this.__dragStartIndex === undefined) { |
@@ -128,6 +128,4 @@ /** | ||
/** @protected */ | ||
ready() { | ||
super.ready(); | ||
constructor() { | ||
super(); | ||
this.addEventListener('click', (e) => this._onClick(e)); | ||
@@ -134,0 +132,0 @@ } |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
668648
16114
98
+ Added@vaadin/a11y-base@24.4.0-beta1(transitive)
+ Added@vaadin/checkbox@24.4.0-beta1(transitive)
+ Added@vaadin/component-base@24.4.0-beta1(transitive)
+ Added@vaadin/field-base@24.4.0-beta1(transitive)
+ Added@vaadin/icon@24.4.0-beta1(transitive)
+ Added@vaadin/input-container@24.4.0-beta1(transitive)
+ Added@vaadin/lit-renderer@24.4.0-beta1(transitive)
+ Added@vaadin/text-field@24.4.0-beta1(transitive)
+ Added@vaadin/vaadin-lumo-styles@24.4.0-beta1(transitive)
+ Added@vaadin/vaadin-material-styles@24.4.0-beta1(transitive)
+ Added@vaadin/vaadin-themable-mixin@24.4.0-beta1(transitive)
- Removed@vaadin/a11y-base@24.4.0-alpha9(transitive)
- Removed@vaadin/checkbox@24.4.0-alpha9(transitive)
- Removed@vaadin/component-base@24.4.0-alpha9(transitive)
- Removed@vaadin/field-base@24.4.0-alpha9(transitive)
- Removed@vaadin/icon@24.4.0-alpha9(transitive)
- Removed@vaadin/input-container@24.4.0-alpha9(transitive)
- Removed@vaadin/lit-renderer@24.4.0-alpha9(transitive)
- Removed@vaadin/text-field@24.4.0-alpha9(transitive)
- Removed@vaadin/vaadin-lumo-styles@24.4.0-alpha9(transitive)
- Removed@vaadin/vaadin-material-styles@24.4.0-alpha9(transitive)
- Removed@vaadin/vaadin-themable-mixin@24.4.0-alpha9(transitive)