diff --git a/packages/grid/src/vaadin-grid-data-provider-mixin.d.ts b/packages/grid/src/vaadin-grid-data-provider-mixin.d.ts index a34b222b644..dffcad9ac7a 100644 --- a/packages/grid/src/vaadin-grid-data-provider-mixin.d.ts +++ b/packages/grid/src/vaadin-grid-data-provider-mixin.d.ts @@ -101,6 +101,12 @@ export declare class DataProviderMixinClass { */ readonly loading: boolean | null | undefined; + /** + * Path to an item sub-property that indicates whether the item has child items. + * @attr {string} item-has-children-path + */ + itemHasChildrenPath: string; + /** * Path to an item sub-property that identifies the item. * @attr {string} item-id-path diff --git a/packages/grid/src/vaadin-grid-data-provider-mixin.js b/packages/grid/src/vaadin-grid-data-provider-mixin.js index de684232e56..ce43adabd49 100644 --- a/packages/grid/src/vaadin-grid-data-provider-mixin.js +++ b/packages/grid/src/vaadin-grid-data-provider-mixin.js @@ -186,6 +186,15 @@ export const DataProviderMixin = (superClass) => value: false }, + /** + * Path to an item sub-property that indicates whether the item has child items. + * @attr {string} item-has-children-path + */ + itemHasChildrenPath: { + type: String, + value: 'children' + }, + /** * Path to an item sub-property that identifies the item. * @attr {string} item-id-path diff --git a/packages/grid/src/vaadin-grid-keyboard-navigation-mixin.js b/packages/grid/src/vaadin-grid-keyboard-navigation-mixin.js index 64f5ab462db..bd6bd6bc99b 100644 --- a/packages/grid/src/vaadin-grid-keyboard-navigation-mixin.js +++ b/packages/grid/src/vaadin-grid-keyboard-navigation-mixin.js @@ -216,14 +216,12 @@ export const KeyboardNavigationMixin = (superClass) => } } - // TODO: A tree toggle component should not be the way to determine if the row is expandable /** @private */ __isRowExpandable(row) { - const treeToggle = [...row.children].reduce( - (value, cell) => value || cell._content.querySelector('vaadin-grid-tree-toggle'), - null - ); - return treeToggle && !treeToggle.expanded && !treeToggle.leaf; + if (this.itemHasChildrenPath) { + const item = row._item; + return item && this.get(this.itemHasChildrenPath, item) && !this._isExpanded(item); + } } /** @private */ diff --git a/packages/grid/src/vaadin-grid-tree-column.d.ts b/packages/grid/src/vaadin-grid-tree-column.d.ts index 3eb23e93b95..2b84ef604df 100644 --- a/packages/grid/src/vaadin-grid-tree-column.d.ts +++ b/packages/grid/src/vaadin-grid-tree-column.d.ts @@ -28,6 +28,7 @@ declare class GridTreeColumn extends GridColumn /** * JS Path of the property in the item that indicates whether the item has child items. * @attr {string} item-has-children-path + * @deprecated Use `grid.itemHasChildrenPath` instead. */ itemHasChildrenPath: string | null | undefined; } diff --git a/packages/grid/src/vaadin-grid-tree-column.js b/packages/grid/src/vaadin-grid-tree-column.js index a162adc7ba3..f928ac4fbd9 100644 --- a/packages/grid/src/vaadin-grid-tree-column.js +++ b/packages/grid/src/vaadin-grid-tree-column.js @@ -34,10 +34,11 @@ class GridTreeColumn extends GridColumn { /** * JS Path of the property in the item that indicates whether the item has child items. * @attr {string} item-has-children-path + * @deprecated Use `grid.itemHasChildrenPath` instead. */ itemHasChildrenPath: { type: String, - value: 'children' + observer: '_itemHasChildrenPathChanged' } }; } @@ -68,7 +69,7 @@ class GridTreeColumn extends GridColumn { toggle.__item = item; toggle.__rendererExpanded = expanded; toggle.expanded = expanded; - toggle.leaf = this.__isLeafItem(item, this.itemHasChildrenPath); + toggle.leaf = this.__isLeafItem(item, this._grid.itemHasChildrenPath); toggle.textContent = this.__getToggleContent(this.path, item); toggle.level = level; } @@ -84,6 +85,19 @@ class GridTreeColumn extends GridColumn { return this.__defaultRenderer; } + /** @private */ + _itemHasChildrenPathChanged(itemHasChildrenPath) { + if (itemHasChildrenPath) { + console.warn( + `WARNING: Since Vaadin 23, itemHasChildrenPath on is deprecated. Please set this property on the instead.` + ); + + if (this._grid) { + this._grid.itemHasChildrenPath = itemHasChildrenPath; + } + } + } + /** * Expands or collapses the row once the tree toggle is switched. * The listener handles only user-fired events. diff --git a/packages/grid/test/accessibility.test.js b/packages/grid/test/accessibility.test.js index 1b537fc0bd6..fd4889aed73 100644 --- a/packages/grid/test/accessibility.test.js +++ b/packages/grid/test/accessibility.test.js @@ -198,11 +198,9 @@ describe('accessibility', () => { beforeEach(() => { grid = fixtureSync(` - `); - grid.dataProvider = hierarchicalDataProvider; flushGrid(grid); }); diff --git a/packages/grid/test/data-provider.test.js b/packages/grid/test/data-provider.test.js index c285eb4b744..e6dc87aa99a 100644 --- a/packages/grid/test/data-provider.test.js +++ b/packages/grid/test/data-provider.test.js @@ -250,6 +250,10 @@ describe('data provider', () => { }); describe('first level', () => { + it('should set itemHasChildren path by default', () => { + expect(grid.itemHasChildrenPath).to.equal('children'); + }); + it('should have collapsed items by default', () => { for (let i = 0; i < grid._effectiveSize; i++) { expect(isIndexExpanded(grid, i)).to.be.false; diff --git a/packages/grid/test/scroll-to-index.test.js b/packages/grid/test/scroll-to-index.test.js index 351624360c8..7f4f6c1d8f3 100644 --- a/packages/grid/test/scroll-to-index.test.js +++ b/packages/grid/test/scroll-to-index.test.js @@ -30,8 +30,8 @@ const fixtures = { `, treeGrid: ` - - + + ` }; diff --git a/packages/grid/test/tree-toggle.test.js b/packages/grid/test/tree-toggle.test.js index 1e8137ca428..773c3efd7b5 100644 --- a/packages/grid/test/tree-toggle.test.js +++ b/packages/grid/test/tree-toggle.test.js @@ -144,18 +144,6 @@ describe('tree toggle', () => { expect(toggle.level).to.equal(0); }); - it('should have a higher level', () => { - column.itemHasChildrenPath = 'hasChildren'; - toggle.expanded = true; - const childToggle = getBodyCellContent(grid, 1, 0).firstElementChild; - expect(childToggle.level).to.equal(1); - }); - - it('should not be a leaf', () => { - column.itemHasChildrenPath = 'hasChildren'; - expect(toggle.leaf).to.be.false; - }); - it('should ignore a custom renderer', () => { column.renderer = (root) => { root.innerHTML = 'cell'; @@ -163,5 +151,37 @@ describe('tree toggle', () => { expect(getBodyCellContent(grid, 0, 0).firstElementChild).to.equal(toggle); }); + + describe('itemHasChildrenPath', () => { + beforeEach(() => { + sinon.stub(console, 'warn'); + }); + + afterEach(() => { + console.warn.restore(); + }); + + it('should have a higher level', () => { + column.itemHasChildrenPath = 'hasChildren'; + toggle.expanded = true; + const childToggle = getBodyCellContent(grid, 1, 0).firstElementChild; + expect(childToggle.level).to.equal(1); + }); + + it('should not be a leaf', () => { + column.itemHasChildrenPath = 'hasChildren'; + expect(toggle.leaf).to.be.false; + }); + + it('should warn when setting column property', () => { + column.itemHasChildrenPath = 'hasChildren'; + expect(console.warn.called).to.be.true; + }); + + it('should forward column property to the grid', () => { + column.itemHasChildrenPath = 'hasChildren'; + expect(grid.itemHasChildrenPath).to.equal('hasChildren'); + }); + }); }); }); diff --git a/packages/grid/test/typings/grid.types.ts b/packages/grid/test/typings/grid.types.ts index 2ea575e04f7..ddb107a36f2 100644 --- a/packages/grid/test/typings/grid.types.ts +++ b/packages/grid/test/typings/grid.types.ts @@ -141,6 +141,7 @@ assertType(narrowedGrid.pageSize); assertType(narrowedGrid.size); assertType(narrowedGrid.loading); assertType(narrowedGrid.itemIdPath); +assertType(narrowedGrid.itemHasChildrenPath); assertType(narrowedGrid.items); assertType(narrowedGrid.activeItem);