/ shared / components / src / components / Shelf / utils / shelf-window.ts
shelf-window.ts
 1  /* eslint-disable import/prefer-default-export */
 2  
 3  /**
 4   * Keeps track of the items that are
 5   * within the viewport of a shelf.
 6   */
 7  export class ShelfWindow {
 8      /**
 9       * List of indexes of visible shelf items.
10       */
11      private visibleShelfEntries: Set<number> = new Set();
12  
13      /**
14       * The lowest visible index in the shelf viewport.
15       */
16      private lowestIndexInVisibleShelf: number | undefined;
17  
18      /**
19       * The highest visible index in the shelf viewport.
20       */
21      private highestIndexInVisibleShelf: number | undefined;
22  
23      /**
24       * Adds the index that has entered the viewport to to shelf item visibility set.
25       * @param index item's index that has entered the viewport
26       */
27      enterValue(index: number) {
28          this.visibleShelfEntries.add(index);
29          this.setMinAndMaxValuesOfViewport();
30      }
31  
32      /**
33       * Removes index that has left viewport from shelf item visibility set.
34       *
35       * @param index item index that has left the viewport
36       */
37      exitValue(index: number) {
38          this.visibleShelfEntries.delete(index);
39          this.setMinAndMaxValuesOfViewport();
40      }
41  
42      /**
43       * Set the min and max based on indexes in shelf item visiblity set.
44       */
45      private setMinAndMaxValuesOfViewport() {
46          this.lowestIndexInVisibleShelf = Math.min(...this.visibleShelfEntries);
47          this.highestIndexInVisibleShelf = Math.max(...this.visibleShelfEntries);
48      }
49  
50      /**
51       * Get the current visible indexes for a given shelf.
52       *
53       * @returns
54       * the first and last item indexes in a shelf viewport
55       * or null if both values are not set.
56       */
57      getViewport(): [number, number] | null {
58          const firstIndex = this.lowestIndexInVisibleShelf;
59          const secondIndex = this.highestIndexInVisibleShelf;
60  
61          if (typeof firstIndex === 'number' && typeof secondIndex === 'number') {
62              return [firstIndex, secondIndex];
63          }
64  
65          return null;
66      }
67  }