VirtualizedTreeNode.tsx 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. export class VirtualizedTreeNode<T> {
  2. node: T;
  3. parent: VirtualizedTreeNode<T> | null;
  4. children: VirtualizedTreeNode<T>[];
  5. expanded: boolean;
  6. depth: number;
  7. constructor(
  8. node: T,
  9. parent: VirtualizedTreeNode<T> | null,
  10. depth: number,
  11. expanded: boolean = false
  12. ) {
  13. this.node = node;
  14. this.parent = parent;
  15. this.expanded = expanded ?? false;
  16. this.children = [];
  17. this.depth = depth;
  18. }
  19. getVisibleChildrenCount(): number {
  20. if (!this.expanded || !this.children.length) {
  21. return 0;
  22. }
  23. let count = 0;
  24. const queue = [...this.children];
  25. while (queue.length > 0) {
  26. const next = queue.pop();
  27. if (next === undefined) {
  28. throw new Error('Undefined queue node, this should never happen');
  29. }
  30. if (next.expanded) {
  31. for (let i = 0; i < next.children.length; i++) {
  32. queue.push(next.children[i]);
  33. }
  34. }
  35. count++;
  36. }
  37. return count;
  38. }
  39. setExpanded(value: boolean, opts?: {expandChildren: boolean}) {
  40. if (value === this.expanded) {
  41. return [];
  42. }
  43. // We are closing a node, so we need to remove all of its children. To do that, we just get the
  44. // count of visible children and return it.
  45. if (!value) {
  46. const removedCount = this.getVisibleChildrenCount();
  47. this.expanded = value;
  48. return new Array(removedCount);
  49. }
  50. // If we are opening a node, we need to add all of its children to the list and insert it
  51. this.expanded = value;
  52. // Collect the newly visible children.
  53. const list: VirtualizedTreeNode<T>[] = [];
  54. function visit(node: VirtualizedTreeNode<T>): void {
  55. if (opts?.expandChildren) {
  56. node.expanded = true;
  57. }
  58. list.push(node);
  59. if (!node.expanded) {
  60. return;
  61. }
  62. for (let i = 0; i < node.children.length; i++) {
  63. visit(node.children[i]);
  64. }
  65. }
  66. for (let i = 0; i < this.children.length; i++) {
  67. visit(this.children[i]);
  68. }
  69. return list;
  70. }
  71. }