Skip to content

Commit

Permalink
feat: wip - virtual tree recursive
Browse files Browse the repository at this point in the history
  • Loading branch information
Jinnie committed Nov 4, 2024
1 parent 71b0056 commit 323d8c1
Show file tree
Hide file tree
Showing 7 changed files with 581 additions and 11 deletions.
20 changes: 19 additions & 1 deletion projects/angular/src/data/tree-view/_tree-view.clarity.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@
@include meta.load-css('properties.tree-view');

@include mixins.exports('tree-view.clarity') {
.example-viewport {
height: 150px;
width: 400px;
}

.example-item {
height: 25px;
}

.cdk-virtual-scroll-content-wrapper {
width: 100%;
position: block;
}

.clr-tree-node {
//Display
display: block;
Expand Down Expand Up @@ -50,7 +64,11 @@
//Display
display: flex;
align-items: center;

// position: sticky;
// top: 0px;
overflow-x: hidden !important;
background-color: white;
z-index: 1;
@include mixins.generate-typography-token('SECONDARY-13-RG-CPT');

& > .clr-treenode-checkbox.clr-checkbox-wrapper {
Expand Down
51 changes: 45 additions & 6 deletions projects/angular/src/data/tree-view/recursive-children.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
* The full license information can be found in LICENSE in the root directory of this project.
*/

import { Component, Input, Optional } from '@angular/core';
import { Subscription } from 'rxjs';
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
import { ChangeDetectorRef, Component, ElementRef, Input, Optional, ViewChild } from '@angular/core';
import { debounceTime, fromEvent, Subscription } from 'rxjs';

import { IfExpandService } from '../../utils/conditional/if-expanded.service';
import { RecursiveTreeNodeModel } from './models/recursive-tree-node.model';
Expand All @@ -17,11 +18,16 @@ import { TreeFeaturesService } from './tree-features.service';
@Component({
selector: 'clr-recursive-children',
template: `
<ng-container *ngIf="shouldRender()">
<ng-container *ngFor="let child of parent?.children || children">
<cdk-virtual-scroll-viewport
*ngIf="shouldRender()"
itemSize="50"
class="example-viewport"
[style.overflow]="!parent ? 'hidden' : null"
>
<ng-container *cdkVirtualFor="let child of parent?.children || children" class="example-item">
<ng-container *ngTemplateOutlet="featuresService.recursion.template; context: getContext(child)"></ng-container>
</ng-container>
</ng-container>
</cdk-virtual-scroll-viewport>
`,
host: {
'[attr.role]': 'role', // Safari + VO needs direct relationship between treeitem and group; no element should exist between them
Expand All @@ -37,10 +43,28 @@ export class RecursiveChildren<T> {
@Input('parent') parent: TreeNodeModel<T>;
@Input('children') children: TreeNodeModel<T>[];

// @HostListener('scroll', ['$event']) // for scroll events of the current element
// @HostListener('window:scroll', ['$event']) // for window scroll events
// onScroll(event) {
// console.log(event);
// }

scrollTop = 0;

// get scrollTop() {
// return this.viewportElement?.nativeElement.scrollTop;
// }

subscription: Subscription;
role: string;

constructor(public featuresService: TreeFeaturesService<T>, @Optional() private expandService: IfExpandService) {
@ViewChild(CdkVirtualScrollViewport, { read: ElementRef }) private viewportElement: ElementRef;

constructor(
public featuresService: TreeFeaturesService<T>,
@Optional() private expandService: IfExpandService,
private cdr: ChangeDetectorRef
) {
if (expandService) {
this.subscription = expandService.expandChange.subscribe(value => {
if (!value && this.parent && !featuresService.eager && featuresService.recursion) {
Expand All @@ -57,6 +81,21 @@ export class RecursiveChildren<T> {
this.setAriaRoles();
}

ngAfterViewInit() {
fromEvent(this.viewportElement.nativeElement, 'scroll')
.pipe(debounceTime(50))
.subscribe((event: Event) => {
console.log(this.parent?.textContent || '#', this.viewportElement.nativeElement.scrollTop);
this.scrollTop = parseInt(this.viewportElement.nativeElement.scrollTop);
event.preventDefault();
// this.cdr.detectChanges();
});
// this.viewportElement.nativeElement.addEventListener("scroll", (event) => {
// console.log(">", this.viewportElement.nativeElement.scrollTop);
// this.scrollTop = this.viewportElement.nativeElement.scrollTop;
// });
}

shouldRender() {
return (
this.featuresService.recursion &&
Expand Down
3 changes: 2 additions & 1 deletion projects/angular/src/data/tree-view/tree-node.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
class="clr-treenode-caret-icon"
shape="angle"
[attr.direction]="expandService.expanded ? 'down' : 'right'"
[style.transform]="rotateDeg(recursiveChildren)"
></cds-icon>
</button>
<div class="clr-treenode-spinner-container" *ngIf="expandService.loading || isModelLoading">
Expand Down Expand Up @@ -77,5 +78,5 @@
>
<ng-content select="clr-tree-node"></ng-content>
<ng-content select="[clrIfExpanded]"></ng-content>
<clr-recursive-children [parent]="_model"></clr-recursive-children>
<clr-recursive-children [parent]="_model" #recursiveChildren></clr-recursive-children>
</div>
6 changes: 6 additions & 0 deletions projects/angular/src/data/tree-view/tree-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { LoadingListener } from '../../utils/loading/loading-listener';
import { DeclarativeTreeNodeModel } from './models/declarative-tree-node.model';
import { ClrSelectedState } from './models/selected-state.enum';
import { TreeNodeModel } from './models/tree-node.model';
import { RecursiveChildren } from './recursive-children';
import { TREE_FEATURES_PROVIDER, TreeFeaturesService } from './tree-features.service';
import { TreeFocusManagerService } from './tree-focus-manager.service';
import { ClrTreeNodeLink } from './tree-node-link';
Expand All @@ -63,6 +64,7 @@ const TREE_TYPE_AHEAD_TIMEOUT = 200;
host: {
'[class.clr-tree-node]': 'true',
'[class.disabled]': 'this._model.disabled',
'[style.position]': 'relative',
},
})
export class ClrTreeNode<T> implements OnInit, AfterContentInit, AfterViewInit, OnDestroy {
Expand Down Expand Up @@ -259,6 +261,10 @@ export class ClrTreeNode<T> implements OnInit, AfterContentInit, AfterViewInit,
}
}

rotateDeg(children: RecursiveChildren<T>) {
return this.expanded && children.scrollTop > 0 ? 'rotate(135deg)' : null;
}

broadcastFocusOnContainer() {
this.focusManager.broadcastFocusedNode(this.nodeId);
}
Expand Down
3 changes: 2 additions & 1 deletion projects/angular/src/data/tree-view/tree-view.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* The full license information can be found in LICENSE in the root directory of this project.
*/

import { ScrollingModule } from '@angular/cdk/scrolling';
import { CommonModule } from '@angular/common';
import { NgModule, Type } from '@angular/core';
import { angleIcon, ClarityIcons } from '@cds/core/icon';
Expand All @@ -20,7 +21,7 @@ import { ClrTreeNodeLink } from './tree-node-link';
export const CLR_TREE_VIEW_DIRECTIVES: Type<any>[] = [ClrTree, ClrTreeNode, ClrRecursiveForOf, ClrTreeNodeLink];

@NgModule({
imports: [CommonModule, ClrIconModule, ClrLoadingModule],
imports: [CommonModule, ClrIconModule, ClrLoadingModule, ScrollingModule],
declarations: [CLR_TREE_VIEW_DIRECTIVES, RecursiveChildren],
exports: [CLR_TREE_VIEW_DIRECTIVES],
})
Expand Down
Loading

0 comments on commit 323d8c1

Please sign in to comment.