{"version":3,"file":"ng-doc-app-components-toc.mjs","sources":["../../../../libs/app/components/toc/toc-element/toc-element.component.ts","../../../../libs/app/components/toc/toc-element/toc-element.component.html","../../../../libs/app/components/toc/toc.component.ts","../../../../libs/app/components/toc/toc.component.html","../../../../libs/app/components/toc/ng-doc-app-components-toc.ts"],"sourcesContent":["import {\n  ChangeDetectionStrategy,\n  Component,\n  ElementRef,\n  HostBinding,\n  inject,\n  Input,\n} from '@angular/core';\nimport { RouterLink } from '@angular/router';\nimport { NgDocDecodeUriComponentPipe } from '@ng-doc/app/pipes/decode-uri-component';\n\n@Component({\n  selector: 'li[ng-doc-toc-element]',\n  templateUrl: './toc-element.component.html',\n  styleUrls: ['./toc-element.component.scss'],\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  imports: [RouterLink, NgDocDecodeUriComponentPipe],\n})\nexport class NgDocTocElementComponent {\n  @Input()\n  path: string = '';\n\n  @Input()\n  hash: string = '';\n\n  @Input()\n  @HostBinding('attr.data-ng-doc-selected')\n  selected: boolean = false;\n\n  @Input()\n  @HostBinding('attr.data-ng-doc-level')\n  level: number = 1;\n\n  readonly elementRef: ElementRef<HTMLElement> = inject(ElementRef);\n}\n","<a\n  [routerLink]=\"[]\"\n  [fragment]=\"hash | decodeUriComponent\"\n  [style.padding-left]=\"'calc(var(--ng-doc-toc-indent) * ' + level + ')'\">\n  <ng-content></ng-content>\n</a>\n","import {\n  afterNextRender,\n  ChangeDetectionStrategy,\n  ChangeDetectorRef,\n  Component,\n  DestroyRef,\n  DOCUMENT,\n  ElementRef,\n  inject,\n  Input,\n  NgZone,\n  OnInit,\n  QueryList,\n  Renderer2,\n  signal,\n  ViewChild,\n  ViewChildren,\n  WritableSignal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { Event as REvent, Router, Scroll } from '@angular/router';\nimport { NgDocPageToc, NgDocTocItem } from '@ng-doc/app/interfaces';\nimport { isPresent } from '@ng-doc/core/helpers/is-present';\nimport { ngDocZoneOptimize } from '@ng-doc/ui-kit';\nimport { fromEvent, merge, Observable } from 'rxjs';\nimport { debounceTime, distinctUntilChanged, filter, map, startWith } from 'rxjs/operators';\n\nimport { NgDocTocElementComponent } from './toc-element/toc-element.component';\n\n@Component({\n  selector: 'ng-doc-toc',\n  templateUrl: './toc.component.html',\n  styleUrls: ['./toc.component.scss'],\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  imports: [NgDocTocElementComponent],\n})\nexport class NgDocTocComponent implements NgDocPageToc, OnInit {\n  @Input()\n  tableOfContent: NgDocTocItem[] = [];\n\n  @ViewChild('selection', { read: ElementRef })\n  selection?: ElementRef<HTMLElement>;\n\n  @ViewChildren(NgDocTocElementComponent)\n  elements: QueryList<NgDocTocElementComponent> = new QueryList<NgDocTocElementComponent>();\n\n  activeItem: WritableSignal<NgDocTocItem | undefined> = signal(undefined);\n\n  protected readonly document: Document = inject(DOCUMENT);\n  protected readonly ngZone: NgZone = inject(NgZone);\n  protected readonly changeDetectorRef: ChangeDetectorRef = inject(ChangeDetectorRef);\n  protected readonly renderer: Renderer2 = inject(Renderer2);\n  protected readonly router: Router = inject(Router);\n  protected readonly destroyRef = inject(DestroyRef);\n\n  constructor() {\n    afterNextRender({\n      write: () => {\n        const scrollSelection: Observable<NgDocTocItem> = fromEvent(this.document, 'scroll').pipe(\n          filter(() => !!this.tableOfContent.length),\n          map((event: Event) => (event.target as Document).scrollingElement as HTMLElement),\n          startWith(this.document.scrollingElement as HTMLElement),\n          map((target: HTMLElement) => {\n            const percentage: number =\n              (target.scrollTop * 100) / (target.scrollHeight - target.offsetHeight);\n            const selectionLine: number =\n              target.scrollTop + (target.offsetHeight * percentage) / 100;\n            if (!this.tableOfContent.length) {\n              return null;\n            }\n            return this.tableOfContent.reduce((pTarget: NgDocTocItem, cTarget: NgDocTocItem) => {\n              const pTop: number = pTarget.element.getBoundingClientRect().top + target.scrollTop;\n              const cTop: number = cTarget.element.getBoundingClientRect().top + target.scrollTop;\n              return Math.abs(cTop - selectionLine) < Math.abs(pTop - selectionLine)\n                ? cTarget\n                : pTarget;\n            });\n          }),\n          filter(isPresent),\n        );\n        const routerSelection: Observable<NgDocTocItem> = this.router.events.pipe(\n          map((event: REvent) => {\n            if (event instanceof Scroll) {\n              const item: NgDocTocItem | undefined = this.tableOfContent.find(\n                (item: NgDocTocItem) => item.path.includes(event.routerEvent.url),\n              );\n              if (item) {\n                return item;\n              }\n            }\n            return null;\n          }),\n          filter(isPresent),\n          debounceTime(20),\n        );\n        const elementsChanges = this.elements.changes.pipe(\n          map(() => this.activeItem()),\n          filter(isPresent),\n        );\n        merge(merge(scrollSelection, routerSelection).pipe(distinctUntilChanged()), elementsChanges)\n          .pipe(\n            debounceTime(0),\n            ngDocZoneOptimize(this.ngZone),\n            takeUntilDestroyed(this.destroyRef),\n          )\n          .subscribe(this.select.bind(this));\n      },\n    });\n  }\n\n  ngOnInit(): void {\n    this.activeItem.set(this.tableOfContent[0]);\n  }\n\n  /**\n   * Selects the item in the table of content.\n   * @param item - Item to select.\n   */\n  protected select(item: NgDocTocItem): void {\n    const index: number = this.tableOfContent.indexOf(item);\n\n    if (this.selection) {\n      const element: HTMLElement | undefined =\n        this.elements.toArray()[index]?.elementRef.nativeElement;\n\n      if (element) {\n        this.renderer.setStyle(this.selection.nativeElement, 'top', `${element.offsetTop}px`);\n        this.renderer.setStyle(this.selection.nativeElement, 'height', `${element.offsetHeight}px`);\n\n        element.scrollIntoView({ block: 'nearest' });\n      }\n    }\n\n    this.activeItem.set(item);\n  }\n}\n","<div class=\"ng-doc-toc-wrapper\">\n  <div class=\"ng-doc-toc-container\">\n    <div class=\"ng-doc-toc-selection\" #selection></div>\n    <ul class=\"ng-doc-toc\">\n      @for (item of tableOfContent; track item) {\n        <li\n          ng-doc-toc-element\n          [path]=\"item.path\"\n          [hash]=\"item.hash\"\n          [level]=\"item.level\"\n          [selected]=\"item === activeItem()\">\n          {{ item.title }}\n        </li>\n      }\n    </ul>\n  </div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}