diff --git a/demos/aurelia/src/examples/slickgrid/example27.scss b/demos/aurelia/src/examples/slickgrid/example27.scss
index e4075e670..b8aef4aee 100644
--- a/demos/aurelia/src/examples/slickgrid/example27.scss
+++ b/demos/aurelia/src/examples/slickgrid/example27.scss
@@ -8,3 +8,10 @@
gap: 4px;
}
}
+
+/* limit the demo maxVisibleDepth input size */
+#maxVisibleDepthInput {
+ height: 22px;
+ width: 100%;
+ max-width: 150px;
+}
diff --git a/demos/aurelia/src/examples/slickgrid/example27.ts b/demos/aurelia/src/examples/slickgrid/example27.ts
index 0d055ec0c..61316b37f 100644
--- a/demos/aurelia/src/examples/slickgrid/example27.ts
+++ b/demos/aurelia/src/examples/slickgrid/example27.ts
@@ -121,6 +121,9 @@ export class Example27 {
indentMarginLeft: 15,
initiallyCollapsed: true,
+ // when `maxVisibleDepth` is defined, any tree node with a level greater than this number will be hidden from the grid display (but not removed from the dataset)
+ // maxVisibleDepth: 2,
+
// you can optionally sort by a different column and/or sort direction
// this is the recommend approach, unless you are 100% that your original array is already sorted (in most cases it's not)
// initialSort: {
@@ -379,4 +382,18 @@ export class Example27 {
document.querySelector('.subtitle')?.classList[action]('hidden');
this.aureliaGrid.resizerService.resizeGrid(0);
}
+
+ setMaxVisibleDepthFromInput() {
+ const input = document.querySelector('#maxVisibleDepthInput') as HTMLInputElement;
+ if (!input) return;
+ const value = parseInt(input.value, 10);
+ const maxVisibleDepth = Number.isFinite(value) ? value : undefined;
+ this.aureliaGrid.treeDataService.setMaxVisibleDepth(maxVisibleDepth as number | undefined);
+ }
+
+ clearMaxVisibleDepth() {
+ const input = document.querySelector('#maxVisibleDepthInput') as HTMLInputElement;
+ if (input) input.value = '';
+ this.aureliaGrid.treeDataService.clearMaxVisibleDepth();
+ }
}
diff --git a/demos/aurelia/test/cypress/e2e/example27.cy.ts b/demos/aurelia/test/cypress/e2e/example27.cy.ts
index 0959df93d..8b7674972 100644
--- a/demos/aurelia/test/cypress/e2e/example27.cy.ts
+++ b/demos/aurelia/test/cypress/e2e/example27.cy.ts
@@ -234,6 +234,48 @@ describe('Example 27 - Tree Data (from a flat dataset with parentId references)'
});
});
+ it('deterministic: hide Task 1 children with maxVisibleDepth=1 and restore on clear', () => {
+ // Task 1 was just expanded by the previous test; now ensure children exist
+ cy.get('[data-row="1"] > .slick-cell:nth(0) .slick-tree-title').should('contain', 'Task 1');
+
+ // ensure level-2 children exist; if not, expand Task 1 and re-check
+ cy.get('.slick-tree-title[level=2]')
+ .its('length')
+ .then((len) => {
+ if (len === 0) {
+ cy.get(
+ `.grid5 [style="transform: translateY(${GRID_ROW_HEIGHT * 1}px);"] > .slick-cell:nth(0) .slick-group-toggle.collapsed`
+ ).click({ force: true });
+ cy.get('.grid5').find('.slick-tree-title[level=2]').its('length').should('be.greaterThan', 0);
+ } else {
+ expect(len).to.be.greaterThan(0);
+ }
+ });
+
+ // apply maxVisibleDepth=1
+ cy.get('#maxVisibleDepthInput').clear().type('1');
+ cy.get('[data-test=set-max-visible-depth-btn]').click();
+
+ // children (level=2) should be hidden
+ cy.get('.slick-tree-title[level=2]').should('have.length', 0);
+
+ // clear the maxVisibleDepth and expect children to reappear
+ cy.get('[data-test=clear-max-visible-depth-btn]').click();
+ cy.get('.slick-tree-title[level=2]').its('length').should('be.greaterThan', 0);
+ });
+
+ it('should set max visible depth via demo input and hide deeper nodes', () => {
+ // ensure there are level-2 items before applying maxVisibleDepth
+ cy.get('.slick-tree-title[level=2]').its('length').should('be.greaterThan', 0);
+
+ // set max visible depth to 1 and apply
+ cy.get('#maxVisibleDepthInput').clear().type('1');
+ cy.get('[data-test=set-max-visible-depth-btn]').click();
+
+ // after applying, level-2 items should be hidden
+ cy.get('.slick-tree-title[level=2]').should('have.length', 0);
+ });
+
it('should be able to click on the "Collapse All (wihout event)" button', () => {
cy.get('[data-test=collapse-all-noevent-btn]').contains('Collapse All (without triggering event)').click();
});
diff --git a/demos/react/src/examples/slickgrid/Example27.tsx b/demos/react/src/examples/slickgrid/Example27.tsx
index dd29a2f19..300125b29 100644
--- a/demos/react/src/examples/slickgrid/Example27.tsx
+++ b/demos/react/src/examples/slickgrid/Example27.tsx
@@ -126,6 +126,9 @@ const Example27: React.FC = () => {
indentMarginLeft: 15,
initiallyCollapsed: true,
+ // when `maxVisibleDepth` is defined, any tree node with a level greater than this number will be hidden from the grid display (but not removed from the dataset)
+ // maxVisibleDepth: 2,
+
// you can optionally sort by a different column and/or sort direction
// this is the recommend approach, unless you are 100% that your original array is already sorted (in most cases it's not)
// initialSort: {
@@ -347,6 +350,20 @@ const Example27: React.FC = () => {
}
}
+ function setMaxVisibleDepthFromInput() {
+ const input = document.querySelector('#maxVisibleDepthInput') as HTMLInputElement;
+ if (!input) return;
+ const value = parseInt(input.value, 10);
+ const maxVisibleDepth = Number.isFinite(value) ? value : undefined;
+ reactGridRef.current?.treeDataService.setMaxVisibleDepth(maxVisibleDepth as number | undefined);
+ }
+
+ function clearMaxVisibleDepth() {
+ const input = document.querySelector('#maxVisibleDepthInput') as HTMLInputElement;
+ if (input) input.value = '';
+ reactGridRef.current?.treeDataService.clearMaxVisibleDepth();
+ }
+
function reapplyToggledItems() {
reactGridRef.current?.treeDataService.applyToggledItemStateChanges(treeToggleItems);
}
@@ -471,6 +488,35 @@ const Example27: React.FC = () => {
+
+
+
+
+
+
+
diff --git a/demos/react/src/examples/slickgrid/example27.scss b/demos/react/src/examples/slickgrid/example27.scss
index 80ffeb658..df012e5f2 100644
--- a/demos/react/src/examples/slickgrid/example27.scss
+++ b/demos/react/src/examples/slickgrid/example27.scss
@@ -1,9 +1,16 @@
// @use '@slickgrid-universal/common/dist/styles/sass/slickgrid-theme-material.lite.scss';
.icon {
- align-items: center;
- display: inline-flex;
- justify-content: center;
- height: 1.5rem;
- width: 1.5rem;
+ align-items: center;
+ display: inline-flex;
+ justify-content: center;
+ height: 1.5rem;
+ width: 1.5rem;
+}
+
+/* limit the demo maxVisibleDepth input size */
+#maxVisibleDepthInput {
+ height: 22px;
+ width: 100%;
+ max-width: 150px;
}
diff --git a/demos/react/test/cypress/e2e/example27.cy.ts b/demos/react/test/cypress/e2e/example27.cy.ts
index df3d2fd77..74b475087 100644
--- a/demos/react/test/cypress/e2e/example27.cy.ts
+++ b/demos/react/test/cypress/e2e/example27.cy.ts
@@ -231,6 +231,48 @@ describe('Example 27 - Tree Data (from a flat dataset with parentId references)'
});
});
+ it('deterministic: hide Task 1 children with maxVisibleDepth=1 and restore on clear', () => {
+ // Task 1 was just expanded by the previous test; now ensure children exist
+ cy.get('[data-row="1"] > .slick-cell:nth(0) .slick-tree-title').should('contain', 'Task 1');
+
+ // ensure level-2 children exist; if not, expand Task 1 and re-check
+ cy.get('.slick-tree-title[level=2]')
+ .its('length')
+ .then((len) => {
+ if (len === 0) {
+ cy.get(
+ `.grid5 [style="transform: translateY(${GRID_ROW_HEIGHT * 1}px);"] > .slick-cell:nth(0) .slick-group-toggle.collapsed`
+ ).click({ force: true });
+ cy.get('.grid5').find('.slick-tree-title[level=2]').its('length').should('be.greaterThan', 0);
+ } else {
+ expect(len).to.be.greaterThan(0);
+ }
+ });
+
+ // apply maxVisibleDepth=1
+ cy.get('#maxVisibleDepthInput').clear().type('1');
+ cy.get('[data-test=set-max-visible-depth-btn]').click();
+
+ // children (level=2) should be hidden
+ cy.get('.slick-tree-title[level=2]').should('have.length', 0);
+
+ // clear the maxVisibleDepth and expect children to reappear
+ cy.get('[data-test=clear-max-visible-depth-btn]').click();
+ cy.get('.slick-tree-title[level=2]').its('length').should('be.greaterThan', 0);
+ });
+
+ it('should set max visible depth via demo input and hide deeper nodes', () => {
+ // ensure there are level-2 items before applying maxVisibleDepth
+ cy.get('.slick-tree-title[level=2]').its('length').should('be.greaterThan', 0);
+
+ // set max visible depth to 1 and apply
+ cy.get('#maxVisibleDepthInput').clear().type('1');
+ cy.get('[data-test=set-max-visible-depth-btn]').click();
+
+ // after applying, level-2 items should be hidden
+ cy.get('.slick-tree-title[level=2]').should('have.length', 0);
+ });
+
it('should be able to click on the "Collapse All (wihout event)" button', () => {
cy.get('[data-test=collapse-all-noevent-btn]').contains('Collapse All (without triggering event)').click();
});
diff --git a/demos/vanilla/src/examples/example05.html b/demos/vanilla/src/examples/example05.html
index 134ad3f0e..d89855b09 100644
--- a/demos/vanilla/src/examples/example05.html
+++ b/demos/vanilla/src/examples/example05.html
@@ -73,6 +73,25 @@
Log Hierarchical Structure
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demos/vanilla/src/examples/example05.scss b/demos/vanilla/src/examples/example05.scss
index 114dffad2..82095d1b3 100644
--- a/demos/vanilla/src/examples/example05.scss
+++ b/demos/vanilla/src/examples/example05.scss
@@ -5,4 +5,10 @@
.slick-cell {
column-gap: 4px;
}
-}
\ No newline at end of file
+}
+
+/* limit the demo maxVisibleDepth input size */
+#maxVisibleDepthInput {
+ width: 100%;
+ max-width: 150px;
+}
diff --git a/demos/vanilla/src/examples/example05.ts b/demos/vanilla/src/examples/example05.ts
index 71064e57e..964e21898 100644
--- a/demos/vanilla/src/examples/example05.ts
+++ b/demos/vanilla/src/examples/example05.ts
@@ -280,6 +280,9 @@ export default class Example05 {
indentMarginLeft: 15,
initiallyCollapsed: true,
+ // when `maxVisibleDepth` is defined, any tree node with a level greater than this number will be hidden from the grid display (but not removed from the dataset)
+ // maxVisibleDepth: 2,
+
// you can optionally sort by a different column and/or sort direction
// this is the recommend approach, unless you are 100% that your original array is already sorted (in most cases it's not)
// initialSort: {
@@ -398,6 +401,20 @@ export default class Example05 {
this.sgb.filterService.updateFilters([{ columnId: 'percentComplete', operator: '<', searchTerms: [40] }]);
}
+ setMaxVisibleDepthFromInput() {
+ const input = document.querySelector('#maxVisibleDepthInput') as HTMLInputElement;
+ if (!input) return;
+ const value = parseInt(input.value, 10);
+ const maxVisibleDepth = Number.isFinite(value) ? value : undefined;
+ this.sgb.treeDataService.setMaxVisibleDepth(maxVisibleDepth as number | undefined);
+ }
+
+ clearMaxVisibleDepth() {
+ const input = document.querySelector('#maxVisibleDepthInput') as HTMLInputElement;
+ if (input) input.value = '';
+ this.sgb.treeDataService.clearMaxVisibleDepth();
+ }
+
logHierarchicalStructure() {
console.log('hierarchical array', this.sgb.treeDataService.datasetHierarchical);
}
diff --git a/demos/vue/src/components/Example27.vue b/demos/vue/src/components/Example27.vue
index 445a955ae..d7c886a9e 100644
--- a/demos/vue/src/components/Example27.vue
+++ b/demos/vue/src/components/Example27.vue
@@ -123,6 +123,9 @@ function defineGrid() {
indentMarginLeft: 15,
initiallyCollapsed: true,
+ // when `maxVisibleDepth` is defined, any tree node with a level greater than this number will be hidden from the grid display (but not removed from the dataset)
+ // maxVisibleDepth: 2,
+
// you can optionally sort by a different column and/or sort direction
// this is the recommend approach, unless you are 100% that your original array is already sorted (in most cases it's not)
// initialSort: {
@@ -373,6 +376,20 @@ function reapplyToggledItems() {
vueGrid.treeDataService.applyToggledItemStateChanges(treeToggleItems.value);
}
+function setMaxVisibleDepthFromInput() {
+ const input = document.querySelector('#maxVisibleDepthInput') as HTMLInputElement;
+ if (!input) return;
+ const value = parseInt(input.value, 10);
+ const maxVisibleDepth = Number.isFinite(value) ? value : undefined;
+ vueGrid.treeDataService.setMaxVisibleDepth(maxVisibleDepth as number | undefined);
+}
+
+function clearMaxVisibleDepth() {
+ const input = document.querySelector('#maxVisibleDepthInput') as HTMLInputElement;
+ if (input) input.value = '';
+ vueGrid.treeDataService.clearMaxVisibleDepth();
+}
+
function toggleSubTitle() {
showSubTitle.value = !showSubTitle.value;
const action = showSubTitle.value ? 'remove' : 'add';
@@ -487,6 +504,35 @@ function vueGridReady(grid: SlickgridVueInstance) {
Log Hierarchical Structure
+
+
+
+
+
+
+
@@ -519,4 +565,11 @@ function vueGridReady(grid: SlickgridVueInstance) {
gap: 4px;
}
}
+
+/* limit the demo maxVisibleDepth input size */
+#maxVisibleDepthInput {
+ height: 22px;
+ width: 100%;
+ max-width: 150px;
+}
diff --git a/demos/vue/test/cypress/e2e/example27.cy.ts b/demos/vue/test/cypress/e2e/example27.cy.ts
index 0959df93d..8b7674972 100644
--- a/demos/vue/test/cypress/e2e/example27.cy.ts
+++ b/demos/vue/test/cypress/e2e/example27.cy.ts
@@ -234,6 +234,48 @@ describe('Example 27 - Tree Data (from a flat dataset with parentId references)'
});
});
+ it('deterministic: hide Task 1 children with maxVisibleDepth=1 and restore on clear', () => {
+ // Task 1 was just expanded by the previous test; now ensure children exist
+ cy.get('[data-row="1"] > .slick-cell:nth(0) .slick-tree-title').should('contain', 'Task 1');
+
+ // ensure level-2 children exist; if not, expand Task 1 and re-check
+ cy.get('.slick-tree-title[level=2]')
+ .its('length')
+ .then((len) => {
+ if (len === 0) {
+ cy.get(
+ `.grid5 [style="transform: translateY(${GRID_ROW_HEIGHT * 1}px);"] > .slick-cell:nth(0) .slick-group-toggle.collapsed`
+ ).click({ force: true });
+ cy.get('.grid5').find('.slick-tree-title[level=2]').its('length').should('be.greaterThan', 0);
+ } else {
+ expect(len).to.be.greaterThan(0);
+ }
+ });
+
+ // apply maxVisibleDepth=1
+ cy.get('#maxVisibleDepthInput').clear().type('1');
+ cy.get('[data-test=set-max-visible-depth-btn]').click();
+
+ // children (level=2) should be hidden
+ cy.get('.slick-tree-title[level=2]').should('have.length', 0);
+
+ // clear the maxVisibleDepth and expect children to reappear
+ cy.get('[data-test=clear-max-visible-depth-btn]').click();
+ cy.get('.slick-tree-title[level=2]').its('length').should('be.greaterThan', 0);
+ });
+
+ it('should set max visible depth via demo input and hide deeper nodes', () => {
+ // ensure there are level-2 items before applying maxVisibleDepth
+ cy.get('.slick-tree-title[level=2]').its('length').should('be.greaterThan', 0);
+
+ // set max visible depth to 1 and apply
+ cy.get('#maxVisibleDepthInput').clear().type('1');
+ cy.get('[data-test=set-max-visible-depth-btn]').click();
+
+ // after applying, level-2 items should be hidden
+ cy.get('.slick-tree-title[level=2]').should('have.length', 0);
+ });
+
it('should be able to click on the "Collapse All (wihout event)" button', () => {
cy.get('[data-test=collapse-all-noevent-btn]').contains('Collapse All (without triggering event)').click();
});
diff --git a/docs/grid-functionalities/tree-data-grid.md b/docs/grid-functionalities/tree-data-grid.md
index 5e8a2ed4b..dec235059 100644
--- a/docs/grid-functionalities/tree-data-grid.md
+++ b/docs/grid-functionalities/tree-data-grid.md
@@ -10,6 +10,7 @@
- [`autoApproveParentItemWhenTreeColumnIsValid`](#autoapproveparentitemwhentreecolumnisvalid-boolean-option)
- [Tree Data Service Methods](#tree-data-service-methods) - extra methods to work with Tree Data
- `getItemCount(x)`, `getToggledItems()`, `getCurrentToggleState()`, `dynamicallyToggleItemState(x)`, `applyToggledItemStateChanges(x)`, ...
+- [Max Visible Depth](#max-visible-depth)
- [Tree Totals with Aggregators](#tree-totals-with-aggregators)
- [Tree Totals Formatter](#tree-totals-formatter)
- [Lazy Loading Tree Data](#lazy-loading-tree-data)
@@ -268,6 +269,37 @@ export class Example1 {
}
```
+### Max Visible Depth
+
+You can limit how deep tree nodes are visible in the grid without removing them from the dataset by using the `treeDataOptions.maxVisibleDepth` option. When defined, any row whose tree level property is greater than the provided value will be hidden by the tree filter logic.
+
+Example grid option (static):
+```ts
+this.gridOptions = {
+ treeDataOptions: {
+ columnId: 'title',
+ levelPropName: 'treeLevel',
+ // when `maxVisibleDepth` is defined, any tree node with a level greater than this number will be hidden
+ // maxVisibleDepth: 2,
+ }
+};
+```
+
+Runtime API (preferred): use the `TreeDataService` convenience methods to set or clear the value at runtime. This avoids relying on nested `setOptions()` merges and ensures the change is applied consistently across the grid and demos.
+
+Example usage:
+```ts
+// set maximum visible tree depth to 1
+this.sgb.treeDataService.setMaxVisibleDepth(1);
+
+// clear the runtime limit (revert to unlimited depth)
+this.sgb.treeDataService.clearMaxVisibleDepth();
+```
+
+Notes:
+- The option only hides rows from the visual grid (filtering), it does not remove them from the underlying dataset.
+- When reading or updating runtime options in code, prefer the `TreeDataService` methods above rather than mutating nested option objects directly.
+
### Tree Totals with Aggregators
##### requires `v3.2.0` or higher
diff --git a/frameworks/angular-slickgrid/docs/grid-functionalities/tree-data-grid.md b/frameworks/angular-slickgrid/docs/grid-functionalities/tree-data-grid.md
index 641cf17ba..2a5e4b9a9 100644
--- a/frameworks/angular-slickgrid/docs/grid-functionalities/tree-data-grid.md
+++ b/frameworks/angular-slickgrid/docs/grid-functionalities/tree-data-grid.md
@@ -10,6 +10,7 @@
- [`autoApproveParentItemWhenTreeColumnIsValid`](#autoapproveparentitemwhentreecolumnisvalid-boolean-option)
- [Tree Data Service Methods](#tree-data-service-methods) - extra methods to work with Tree Data
- `getItemCount(x)`, `getToggledItems()`, `getCurrentToggleState()`, `dynamicallyToggleItemState(x)`, `applyToggledItemStateChanges(x)`, ...
+- [Max Visible Depth](#max-visible-depth)
- [Tree Totals with Aggregators](#tree-totals-with-aggregators)
- [Tree Totals Formatter](#tree-totals-formatter)
- [Lazy Loading Tree Data](#lazy-loading-tree-data)
@@ -296,6 +297,37 @@ export class Example1 {
}
```
+### Max Visible Depth
+
+You can limit how deep tree nodes are visible in the grid without removing them from the dataset by using the `treeDataOptions.maxVisibleDepth` option. When defined, any row whose tree level property is greater than the provided value will be hidden by the tree filter logic.
+
+Example grid option (static):
+```ts
+this.gridOptions = {
+ treeDataOptions: {
+ columnId: 'title',
+ levelPropName: 'treeLevel',
+ // when `maxVisibleDepth` is defined, any tree node with a level greater than this number will be hidden
+ // maxVisibleDepth: 2,
+ }
+};
+```
+
+Runtime API (Angular): use the `treeDataService` on the grid instance to set or clear the value at runtime.
+
+Example usage:
+```ts
+// set maximum visible tree depth to 1
+this.angularGrid.treeDataService.setMaxVisibleDepth(1);
+
+// clear the runtime limit (revert to unlimited depth)
+this.angularGrid.treeDataService.clearMaxVisibleDepth();
+```
+
+Notes:
+- The option only hides rows from the visual grid (filtering), it does not remove them from the underlying dataset.
+- When reading or updating runtime options in code, prefer the `TreeDataService` methods rather than mutating nested option objects directly.
+
### Tree Totals with Aggregators
You can calculate Tree Totals by adding Aggregators to your `treeDataOptions` configuration in your grid options. The Aggregators are the same ones that can be used for both Tree Data and/or Grouping usage (they were modified internally to work for both use case). This feature also comes with other options that you can choose to enable or not, below is a list of these extra options that can be configured
diff --git a/frameworks/angular-slickgrid/src/demos/examples/example27.component.html b/frameworks/angular-slickgrid/src/demos/examples/example27.component.html
index 366c0bfe2..3cd729230 100644
--- a/frameworks/angular-slickgrid/src/demos/examples/example27.component.html
+++ b/frameworks/angular-slickgrid/src/demos/examples/example27.component.html
@@ -115,6 +115,35 @@
Dynamically Change Filter (% complete < 40)
+
+
+
+
+
+
+
diff --git a/frameworks/angular-slickgrid/src/demos/examples/example27.component.scss b/frameworks/angular-slickgrid/src/demos/examples/example27.component.scss
index e227c93ef..f7a9273e4 100644
--- a/frameworks/angular-slickgrid/src/demos/examples/example27.component.scss
+++ b/frameworks/angular-slickgrid/src/demos/examples/example27.component.scss
@@ -8,3 +8,10 @@
gap: 4px;
}
}
+
+/* limit the demo maxVisibleDepth input size */
+#maxVisibleDepthInput {
+ height: 22px;
+ width: 100%;
+ max-width: 150px;
+}
diff --git a/frameworks/angular-slickgrid/src/demos/examples/example27.component.ts b/frameworks/angular-slickgrid/src/demos/examples/example27.component.ts
index db9691a41..efe6d45ac 100644
--- a/frameworks/angular-slickgrid/src/demos/examples/example27.component.ts
+++ b/frameworks/angular-slickgrid/src/demos/examples/example27.component.ts
@@ -138,6 +138,9 @@ export class Example27Component implements OnInit {
indentMarginLeft: 15,
initiallyCollapsed: true,
+ // when `maxVisibleDepth` is defined, any tree node with a level greater than this number will be hidden from the grid display (but not removed from the dataset)
+ // maxVisibleDepth: 2,
+
// you can optionally sort by a different column and/or sort direction
// this is the recommend approach, unless you are 100% that your original array is already sorted (in most cases it's not)
initialSort: {
@@ -328,18 +331,24 @@ export class Example27Component implements OnInit {
/** Whenever a parent is being toggled, we'll keep a reference of all of these changes so that we can reapply them whenever we want */
handleOnTreeItemToggled(treeToggleExecution: TreeToggleStateChange) {
- this.hasNoExpandCollapseChanged = false;
- this.treeToggleItems = treeToggleExecution.toggledItems as TreeToggledItem[];
+ // defer to microtask to avoid ExpressionChangedAfterItHasBeenCheckedError in Angular
+ queueMicrotask(() => {
+ this.hasNoExpandCollapseChanged = false;
+ this.treeToggleItems = treeToggleExecution.toggledItems as TreeToggledItem[];
+ });
console.log('Tree Data changes', treeToggleExecution);
}
handleOnGridStateChanged(gridStateChange: GridStateChange) {
- this.hasNoExpandCollapseChanged = false;
+ // defer state updates to microtask to avoid ExpressionChangedAfterItHasBeenCheckedError
+ queueMicrotask(() => {
+ this.hasNoExpandCollapseChanged = false;
- if (gridStateChange?.change?.type === 'treeData') {
- console.log('Tree Data gridStateChange', gridStateChange?.gridState?.treeData);
- this.treeToggleItems = gridStateChange?.gridState?.treeData?.toggledItems as TreeToggledItem[];
- }
+ if (gridStateChange?.change?.type === 'treeData') {
+ console.log('Tree Data gridStateChange', gridStateChange?.gridState?.treeData);
+ this.treeToggleItems = gridStateChange?.gridState?.treeData?.toggledItems as TreeToggledItem[];
+ }
+ });
}
logTreeDataToggledItems() {
@@ -372,4 +381,18 @@ export class Example27Component implements OnInit {
document.querySelector('.subtitle')?.classList[action]('hidden');
this.angularGrid.resizerService.resizeGrid(0);
}
+
+ setMaxVisibleDepthFromInput() {
+ const input = document.getElementById('maxVisibleDepthInput') as HTMLInputElement;
+ if (!input) return;
+ const value = parseInt(input.value, 10);
+ const maxVisibleDepth = Number.isFinite(value) ? value : undefined;
+ this.angularGrid.treeDataService.setMaxVisibleDepth(maxVisibleDepth as number | undefined);
+ }
+
+ clearMaxVisibleDepth() {
+ const input = document.getElementById('maxVisibleDepthInput') as HTMLInputElement;
+ if (input) input.value = '';
+ this.angularGrid.treeDataService.clearMaxVisibleDepth();
+ }
}
diff --git a/frameworks/angular-slickgrid/test/cypress/e2e/example27.cy.ts b/frameworks/angular-slickgrid/test/cypress/e2e/example27.cy.ts
index fbdda5c62..afab0ccc9 100644
--- a/frameworks/angular-slickgrid/test/cypress/e2e/example27.cy.ts
+++ b/frameworks/angular-slickgrid/test/cypress/e2e/example27.cy.ts
@@ -229,6 +229,48 @@ describe('Example 27 - Tree Data (from a flat dataset with parentId references)'
});
});
+ it('deterministic: hide Task 1 children with maxVisibleDepth=1 and restore on clear', () => {
+ // Task 1 was just expanded by the previous test; now ensure children exist
+ cy.get('[data-row="1"] > .slick-cell:nth(0) .slick-tree-title').should('contain', 'Task 1');
+
+ // ensure level-2 children exist; if not, expand Task 1 and re-check
+ cy.get('.slick-tree-title[level=2]')
+ .its('length')
+ .then((len) => {
+ if (len === 0) {
+ cy.get(
+ `.grid5 [style="transform: translateY(${GRID_ROW_HEIGHT * 1}px);"] > .slick-cell:nth(0) .slick-group-toggle.collapsed`
+ ).click({ force: true });
+ cy.get('.grid5').find('.slick-tree-title[level=2]').its('length').should('be.greaterThan', 0);
+ } else {
+ expect(len).to.be.greaterThan(0);
+ }
+ });
+
+ // apply maxVisibleDepth=1
+ cy.get('#maxVisibleDepthInput').clear().type('1');
+ cy.get('[data-test=set-max-visible-depth-btn]').click();
+
+ // children (level=2) should be hidden
+ cy.get('.slick-tree-title[level=2]').should('have.length', 0);
+
+ // clear the maxVisibleDepth and expect children to reappear
+ cy.get('[data-test=clear-max-visible-depth-btn]').click();
+ cy.get('.slick-tree-title[level=2]').its('length').should('be.greaterThan', 0);
+ });
+
+ it('should set max visible depth via demo input and hide deeper nodes', () => {
+ // ensure there are level-2 items before applying maxVisibleDepth
+ cy.get('.slick-tree-title[level=2]').its('length').should('be.greaterThan', 0);
+
+ // set max visible depth to 1 and apply
+ cy.get('#maxVisibleDepthInput').clear().type('1');
+ cy.get('[data-test=set-max-visible-depth-btn]').click();
+
+ // after applying, level-2 items should be hidden
+ cy.get('.slick-tree-title[level=2]').should('have.length', 0);
+ });
+
it('should be able to click on the "Collapse All (wihout event)" button', () => {
cy.get('[data-test=collapse-all-noevent-btn]').contains('Collapse All (without triggering event)').click();
});
diff --git a/frameworks/aurelia-slickgrid/docs/grid-functionalities/tree-data-grid.md b/frameworks/aurelia-slickgrid/docs/grid-functionalities/tree-data-grid.md
index 10f36bd58..c966d7bdd 100644
--- a/frameworks/aurelia-slickgrid/docs/grid-functionalities/tree-data-grid.md
+++ b/frameworks/aurelia-slickgrid/docs/grid-functionalities/tree-data-grid.md
@@ -10,6 +10,7 @@
- [`autoApproveParentItemWhenTreeColumnIsValid`](#autoapproveparentitemwhentreecolumnisvalid-boolean-option)
- [Tree Data Service Methods](#tree-data-service-methods) - extra methods to work with Tree Data
- `getItemCount(x)`, `getToggledItems()`, `getCurrentToggleState()`, `dynamicallyToggleItemState(x)`, `applyToggledItemStateChanges(x)`, ...
+- [Max Visible Depth](#max-visible-depth)
- [Tree Totals with Aggregators](#tree-totals-with-aggregators)
- [Tree Totals Formatter](#tree-totals-formatter)
- [Lazy Loading Tree Data](#lazy-loading-tree-data)
@@ -309,6 +310,37 @@ export class Example1 {
}
```
+### Max Visible Depth
+
+You can limit how deep tree nodes are visible in the grid without removing them from the dataset by using the `treeDataOptions.maxVisibleDepth` option. When defined, any row whose tree level property is greater than the provided value will be hidden by the tree filter logic.
+
+Example grid option (static):
+```ts
+this.gridOptions = {
+ treeDataOptions: {
+ columnId: 'title',
+ levelPropName: 'treeLevel',
+ // when `maxVisibleDepth` is defined, any tree node with a level greater than this number will be hidden
+ // maxVisibleDepth: 2,
+ }
+};
+```
+
+Runtime API (Aurelia): use the `treeDataService` on the grid instance to set or clear the value at runtime.
+
+Example usage:
+```ts
+// set maximum visible tree depth to 1
+this.aureliaGrid.treeDataService.setMaxVisibleDepth(1);
+
+// clear the runtime limit (revert to unlimited depth)
+this.aureliaGrid.treeDataService.clearMaxVisibleDepth();
+```
+
+Notes:
+- The option only hides rows from the visual grid (filtering), it does not remove them from the underlying dataset.
+- When reading or updating runtime options in code, prefer the `TreeDataService` methods rather than mutating nested option objects directly.
+
### Tree Totals with Aggregators
You can calculate Tree Totals by adding Aggregators to your `treeDataOptions` configuration in your grid options. The Aggregators are the same ones that can be used for both Tree Data and/or Grouping usage (they were modified internally to work for both use case). This feature also comes with other options that you can choose to enable or not, below is a list of these extra options that can be configured
diff --git a/frameworks/slickgrid-react/docs/grid-functionalities/tree-data-grid.md b/frameworks/slickgrid-react/docs/grid-functionalities/tree-data-grid.md
index 218ceb69d..ac9b0a80c 100644
--- a/frameworks/slickgrid-react/docs/grid-functionalities/tree-data-grid.md
+++ b/frameworks/slickgrid-react/docs/grid-functionalities/tree-data-grid.md
@@ -10,6 +10,7 @@
- [`autoApproveParentItemWhenTreeColumnIsValid`](#autoapproveparentitemwhentreecolumnisvalid-boolean-option)
- [Tree Data Service Methods](#tree-data-service-methods) - extra methods to work with Tree Data
- `getItemCount(x)`, `getToggledItems()`, `getCurrentToggleState()`, `dynamicallyToggleItemState(x)`, `applyToggledItemStateChanges(x)`, ...
+- [Max Visible Depth](#max-visible-depth)
- [Tree Totals with Aggregators](#tree-totals-with-aggregators)
- [Tree Totals Formatter](#tree-totals-formatter)
- [Lazy Loading Tree Data](#lazy-loading-tree-data)
@@ -314,6 +315,37 @@ const Example: React.FC = () => {
}
```
+### Max Visible Depth
+
+You can limit how deep tree nodes are visible in the grid without removing them from the dataset by using the `treeDataOptions.maxVisibleDepth` option. When defined, any row whose tree level property is greater than the provided value will be hidden by the tree filter logic.
+
+Example grid option (static):
+```tsx
+const gridOptions: GridOption = {
+ treeDataOptions: {
+ columnId: 'title',
+ levelPropName: 'treeLevel',
+ // when `maxVisibleDepth` is defined, any tree node with a level greater than this number will be hidden
+ // maxVisibleDepth: 2,
+ }
+};
+```
+
+Runtime API (React): use the `treeDataService` on the grid instance to set or clear the value at runtime.
+
+Example usage:
+```tsx
+// set maximum visible tree depth to 1
+reactGridRef.current?.treeDataService.setMaxVisibleDepth(1);
+
+// clear the runtime limit (revert to unlimited depth)
+reactGridRef.current?.treeDataService.clearMaxVisibleDepth();
+```
+
+Notes:
+- The option only hides rows from the visual grid (filtering), it does not remove them from the underlying dataset.
+- When reading or updating runtime options in code, prefer the `TreeDataService` methods rather than mutating nested option objects directly.
+
### Tree Totals with Aggregators
You can calculate Tree Totals by adding Aggregators to your `treeDataOptions` configuration in your grid options. The Aggregators are the same ones that can be used for both Tree Data and/or Grouping usage (they were modified internally to work for both use case). This feature also comes with other options that you can choose to enable or not, below is a list of these extra options that can be configured
diff --git a/frameworks/slickgrid-vue/docs/grid-functionalities/tree-data-grid.md b/frameworks/slickgrid-vue/docs/grid-functionalities/tree-data-grid.md
index 699e86fb2..e4aea67f5 100644
--- a/frameworks/slickgrid-vue/docs/grid-functionalities/tree-data-grid.md
+++ b/frameworks/slickgrid-vue/docs/grid-functionalities/tree-data-grid.md
@@ -10,6 +10,7 @@
- [`autoApproveParentItemWhenTreeColumnIsValid`](#autoapproveparentitemwhentreecolumnisvalid-boolean-option)
- [Tree Data Service Methods](#tree-data-service-methods) - extra methods to work with Tree Data
- `getItemCount(x)`, `getToggledItems()`, `getCurrentToggleState()`, `dynamicallyToggleItemState(x)`, `applyToggledItemStateChanges(x)`, ...
+- [Max Visible Depth](#max-visible-depth)
- [Tree Totals with Aggregators](#tree-totals-with-aggregators)
- [Tree Totals Formatter](#tree-totals-formatter)
- [Lazy Loading Tree Data](#lazy-loading-tree-data)
@@ -325,6 +326,37 @@ function getTreeDataState() {
console.log(vueGrid.getCurrentToggleState());
}
+
+### Max Visible Depth
+
+You can limit how deep tree nodes are visible in the grid without removing them from the dataset by using the `treeDataOptions.maxVisibleDepth` option. When defined, any row whose tree level property is greater than the provided value will be hidden by the tree filter logic.
+
+Example grid option (static):
+```vue
+gridOptions.value = {
+ treeDataOptions: {
+ columnId: 'title',
+ levelPropName: 'treeLevel',
+ // when `maxVisibleDepth` is defined, any tree node with a level greater than this number will be hidden
+ // maxVisibleDepth: 2,
+ }
+};
+```
+
+Runtime API (Vue): use the `treeDataService` on the grid instance to set or clear the value at runtime.
+
+Example usage:
+```ts
+// set maximum visible tree depth to 1
+vueGrid.treeDataService.setMaxVisibleDepth(1);
+
+// clear the runtime limit (revert to unlimited depth)
+vueGrid.treeDataService.clearMaxVisibleDepth();
+```
+
+Notes:
+- The option only hides rows from the visual grid (filtering), it does not remove them from the underlying dataset.
+- When reading or updating runtime options in code, prefer the `TreeDataService` methods rather than mutating nested option objects directly.
```
### Tree Totals with Aggregators
diff --git a/packages/common/src/interfaces/treeDataOption.interface.ts b/packages/common/src/interfaces/treeDataOption.interface.ts
index b12326ff7..62a40b5de 100644
--- a/packages/common/src/interfaces/treeDataOption.interface.ts
+++ b/packages/common/src/interfaces/treeDataOption.interface.ts
@@ -78,6 +78,13 @@ export interface TreeDataOption extends TreeDataPropNames {
/** Optional Title Formatter (allows you to format/style the title text differently) */
titleFormatter?: Formatter;
+ /**
+ * Optional maximum visible tree depth. When provided, any tree node with a level
+ * greater than this number will be hidden from the grid display (but not removed
+ * from the dataset). Depths are zero-based (0 = root level).
+ */
+ maxVisibleDepth?: number;
+
/** Defaults to False, should we toggle the tree node when clicking on the tree node title or toggle icon (tree node must have element with `.slick-tree-title` class name) */
toggleOnNodeTitle?: boolean;
diff --git a/packages/common/src/services/__tests__/filter.service.spec.ts b/packages/common/src/services/__tests__/filter.service.spec.ts
index 2d7438682..d2d27653f 100644
--- a/packages/common/src/services/__tests__/filter.service.spec.ts
+++ b/packages/common/src/services/__tests__/filter.service.spec.ts
@@ -139,6 +139,7 @@ describe('FilterService', () => {
service = new FilterService(filterFactory, pubSubServiceStub, sharedService, backendUtilityService, rxjsResourceStub);
slickgridEventHandler = service.eventHandler;
vi.spyOn(gridStub, 'getHeaderRowColumn').mockReturnValue(div);
+ vi.spyOn(SharedService.prototype, 'gridOptions', 'get').mockReturnValue(gridOptionMock);
});
afterEach(() => {
@@ -1213,6 +1214,33 @@ describe('FilterService', () => {
expect(output).toBe(true);
});
+ it('should hide items deeper than treeDataOptions.maxVisibleDepth when tree data is enabled', () => {
+ // save previous values to avoid leaking state to other tests
+ const prevEnableTree = gridOptionMock.enableTreeData;
+ const prevTreeOptions = gridOptionMock.treeDataOptions;
+
+ try {
+ // enable tree data with maxVisibleDepth = 1
+ gridOptionMock.enableTreeData = true;
+ gridOptionMock.treeDataOptions = { columnId: 'file', levelPropName: '__treeLevel', maxVisibleDepth: 1 } as any;
+
+ const deepItem = { id: 10, __treeLevel: 2, __parentId: 1 } as any;
+ const shallowItem = { id: 11, __treeLevel: 1, __parentId: 1 } as any;
+
+ service.init(gridStub);
+
+ const deepOutput = service.customLocalFilter(deepItem, { dataView: dataViewStub, grid: gridStub, columnFilters: {} as any });
+ const shallowOutput = service.customLocalFilter(shallowItem, { dataView: dataViewStub, grid: gridStub, columnFilters: {} as any });
+
+ expect(deepOutput).toBe(false);
+ expect(shallowOutput).toBe(true);
+ } finally {
+ // restore previous state
+ gridOptionMock.enableTreeData = prevEnableTree;
+ gridOptionMock.treeDataOptions = prevTreeOptions;
+ }
+ });
+
it('should return True when using row detail and the item is found in its parent', () => {
gridOptionMock.enableRowDetailView = true;
const mockColumn1 = { id: 'zip', field: 'zip', filterable: true, queryFieldFilter: 'address.zip', type: 'number' } as Column;
diff --git a/packages/common/src/services/__tests__/treeData.service.spec.ts b/packages/common/src/services/__tests__/treeData.service.spec.ts
index f9f5e5650..e1573671e 100644
--- a/packages/common/src/services/__tests__/treeData.service.spec.ts
+++ b/packages/common/src/services/__tests__/treeData.service.spec.ts
@@ -68,6 +68,7 @@ const gridStub = {
onClick: new SlickEvent(),
onKeyDown: new SlickEvent(),
render: vi.fn(),
+ setOptions: vi.fn(),
setSortColumns: vi.fn(),
} as unknown as SlickGrid;
@@ -212,6 +213,26 @@ describe('TreeData Service', () => {
expect(service.datasetHierarchical).toEqual(mockHierarchical);
});
+ it('setMaxVisibleDepth should update sharedService.gridOptions.treeDataOptions and refresh filters', () => {
+ // prepare shared options
+ sharedService.gridOptions = { treeDataOptions: { columnId: 'file' } } as any;
+
+ service.setMaxVisibleDepth(2);
+
+ expect(sharedService.gridOptions.treeDataOptions.maxVisibleDepth).toBe(2);
+ expect(filterServiceStub.refreshTreeDataFilters).toHaveBeenCalled();
+ });
+
+ it('clearMaxVisibleDepth should remove maxVisibleDepth and refresh filters', () => {
+ // prepare shared options with existing maxVisibleDepth
+ sharedService.gridOptions = { treeDataOptions: { columnId: 'file', maxVisibleDepth: 3 } } as any;
+
+ service.clearMaxVisibleDepth();
+
+ expect(sharedService.gridOptions.treeDataOptions.maxVisibleDepth).toBeUndefined();
+ expect(filterServiceStub.refreshTreeDataFilters).toHaveBeenCalled();
+ });
+
describe('handleOnCellClick method', () => {
let div: HTMLDivElement;
let mockColumn: Column;
@@ -544,6 +565,9 @@ describe('TreeData Service', () => {
]);
};
+ // also set a maxVisibleDepth to ensure deeper nodes are hidden by filter logic
+ gridOptionsMock.treeDataOptions!.maxVisibleDepth = 1;
+
service.init(gridStub);
const eventData = new SlickEventData();
div.className = 'slick-group-toggle';
@@ -565,6 +589,16 @@ describe('TreeData Service', () => {
expect(service.getToggledItems()).toEqual([{ itemId: 123, isCollapsed: false }]);
expect(SharedService.prototype.hierarchicalDataset![0].file).toBe('myFile.txt');
expect(pubSubSpy).not.toHaveBeenCalledWith(`onTreeItemToggled`);
+
+ // Verify maxVisibleDepth has an effect in integration: the mocked flat dataset contains a level 2 node,
+ // but when maxVisibleDepth is 1 those deeper nodes would be hidden by the filter logic.
+ const maxDepth = gridOptionsMock.treeDataOptions!.maxVisibleDepth as number;
+ // mockFlatDataset defined above in this test
+ const visibleFlat = mockFlatDataset.filter((d) => d.__treeLevel <= maxDepth);
+ const hiddenFlat = mockFlatDataset.filter((d) => d.__treeLevel > maxDepth);
+
+ expect(hiddenFlat.some((d) => d.__treeLevel === 2)).toBe(true);
+ expect(visibleFlat.length).toBeLessThan(mockFlatDataset.length);
});
describe('toggleOnNodeTitle option', () => {
diff --git a/packages/common/src/services/filter.service.ts b/packages/common/src/services/filter.service.ts
index 89e685b5c..3023409bb 100644
--- a/packages/common/src/services/filter.service.ts
+++ b/packages/common/src/services/filter.service.ts
@@ -79,9 +79,13 @@ export class FilterService {
return this._onSearchChange;
}
- /** Getter for the Grid Options pulled through the Grid Object */
+ /** Getter for the Grid Options pulled through the Grid Object.
+ * Prefer the SharedService gridOptions when available to allow runtime updates
+ * made to `sharedService.gridOptions` to be visible without relying on SlickGrid's
+ * internal deep-merged `getOptions()` value.
+ */
protected get _gridOptions(): GridOption {
- return this._grid?.getOptions() ?? {};
+ return this.sharedService?.gridOptions ?? this._grid?.getOptions() ?? {};
}
/** Getter for the Column Definitions pulled through the Grid Object */
@@ -326,9 +330,16 @@ export class FilterService {
const collapsedPropName = treeDataOptions.collapsedPropName ?? Constants.treeDataProperties.COLLAPSED_PROP;
const parentPropName = treeDataOptions.parentPropName ?? Constants.treeDataProperties.PARENT_PROP;
const childrenPropName = treeDataOptions?.childrenPropName ?? Constants.treeDataProperties.CHILDREN_PROP;
+ const levelPropName = treeDataOptions.levelPropName ?? Constants.treeDataProperties.TREE_LEVEL_PROP;
+ const maxVisibleDepth = treeDataOptions.maxVisibleDepth;
const primaryDataId = this._gridOptions.datasetIdPropertyName ?? 'id';
const autoRecalcTotalsOnFilterChange = treeDataOptions.autoRecalcTotalsOnFilterChange ?? false;
+ // if a maxVisibleDepth is provided, hide any row deeper than that level
+ if (typeof maxVisibleDepth === 'number' && item[levelPropName] !== undefined && item[levelPropName] > maxVisibleDepth) {
+ return false;
+ }
+
// typically when a parent is collapsed we can exit early (by returning false) but we can't do that when we use auto-recalc totals
// if that happens, we need to keep a ref and recalculate total for all tree leafs then only after we can exit
let isParentCollapsed = false; // will be used only when auto-recalc is enabled
diff --git a/packages/common/src/services/treeData.service.ts b/packages/common/src/services/treeData.service.ts
index 8ea97a01b..3f08aaefd 100644
--- a/packages/common/src/services/treeData.service.ts
+++ b/packages/common/src/services/treeData.service.ts
@@ -292,6 +292,33 @@ export class TreeDataService {
return this._currentToggledItems;
}
+ /**
+ * Set or clear the runtime `maxVisibleDepth` for Tree Data and refresh the grid.
+ * Calling with `undefined` clears the value.
+ */
+ setMaxVisibleDepth(maxVisibleDepth?: number): void {
+ const gridOptions = this.sharedService.gridOptions ?? {};
+ const treeDataOptions = { ...(gridOptions.treeDataOptions || {}) } as any;
+
+ if (typeof maxVisibleDepth === 'number') {
+ treeDataOptions.maxVisibleDepth = maxVisibleDepth;
+ } else {
+ delete treeDataOptions.maxVisibleDepth;
+ }
+
+ gridOptions.treeDataOptions = treeDataOptions;
+ this.sharedService.gridOptions = gridOptions;
+ this._grid?.setOptions(gridOptions);
+
+ // refreshing the filters will trigger a grid refresh with new tree depth
+ this.filterService.refreshTreeDataFilters();
+ }
+
+ /** Clear the runtime `maxVisibleDepth` */
+ clearMaxVisibleDepth(): void {
+ this.setMaxVisibleDepth(undefined);
+ }
+
/** Clear the sorting and set it back to initial sort */
clearSorting(): void {
const initialSort = this.getInitialSort(this.sharedService.columnDefinitions, this.sharedService.gridOptions);
diff --git a/test/cypress/e2e/example05.cy.ts b/test/cypress/e2e/example05.cy.ts
index c70874700..b85d3e919 100644
--- a/test/cypress/e2e/example05.cy.ts
+++ b/test/cypress/e2e/example05.cy.ts
@@ -258,6 +258,48 @@ describe('Example 05 - Tree Data (from a flat dataset with parentId references)'
});
});
+ it('deterministic: hide Task 1 children with maxVisibleDepth=1 and restore on clear', () => {
+ // Task 1 was just expanded by the previous test; now ensure children exist
+ cy.get('[data-row="1"] > .slick-cell:nth(0) .slick-tree-title').should('contain', 'Task 1');
+
+ // ensure level-2 children exist; if not, expand Task 1 and re-check
+ cy.get('.slick-tree-title[level=2]')
+ .its('length')
+ .then((len) => {
+ if (len === 0) {
+ cy.get(
+ `.grid5 [style="transform: translateY(${GRID_ROW_HEIGHT * 1}px);"] > .slick-cell:nth(0) .slick-group-toggle.collapsed`
+ ).click({ force: true });
+ cy.get('.grid5').find('.slick-tree-title[level=2]').its('length').should('be.greaterThan', 0);
+ } else {
+ expect(len).to.be.greaterThan(0);
+ }
+ });
+
+ // apply maxVisibleDepth=1
+ cy.get('#maxVisibleDepthInput').clear().type('1');
+ cy.get('[data-test=set-max-visible-depth-btn]').click();
+
+ // children (level=2) should be hidden
+ cy.get('.slick-tree-title[level=2]').should('have.length', 0);
+
+ // clear the maxVisibleDepth and expect children to reappear
+ cy.get('[data-test=clear-max-visible-depth-btn]').click();
+ cy.get('.slick-tree-title[level=2]').its('length').should('be.greaterThan', 0);
+ });
+
+ it('should set max visible depth via demo input and hide deeper nodes', () => {
+ // ensure there are level-2 items before applying maxVisibleDepth
+ cy.get('.slick-tree-title[level=2]').its('length').should('be.greaterThan', 0);
+
+ // set max visible depth to 1 and apply
+ cy.get('#maxVisibleDepthInput').clear().type('1');
+ cy.get('[data-test=set-max-visible-depth-btn]').click();
+
+ // after applying, level-2 items should be hidden
+ cy.get('.slick-tree-title[level=2]').should('have.length', 0);
+ });
+
it('should be able to click on the "Collapse All (wihout event)" button', () => {
cy.get('[data-test=collapse-all-noevent-btn]').contains('Collapse All (without triggering event)').click();
});