{"version":3,"file":"ngx-category-scroll.mjs","sources":["../../../projects/ngx-category-scroll/src/lib/ngx-category-scroll.component.ts","../../../projects/ngx-category-scroll/src/lib/ngx-category-scoll.component.html","../../../projects/ngx-category-scroll/src/public-api.ts","../../../projects/ngx-category-scroll/src/ngx-category-scroll.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\r\nimport { Component, ElementRef, EventEmitter, Input, OnChanges, Output, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren } from '@angular/core';\r\nimport debounce from 'lodash/debounce';\r\n\r\n@Component({\r\n\tselector: 'ngx-category-scroll',\r\n\timports: [CommonModule],\r\n\ttemplateUrl: './ngx-category-scoll.component.html',\r\n\tstyleUrls: ['./ngx-category-scoll.component.scss']\r\n})\r\nexport class NgxCategoryScroll implements OnChanges {\r\n\tngOnChanges(changes: SimpleChanges): void {\r\n\t\tthis.addObserver();\r\n\t\tsetTimeout(() => {\r\n\t\t\tthis.sectionRefs?.forEach((ref) => {\r\n\t\t\t\tthis.observer.observe(ref.nativeElement);\r\n\t\t\t\tthis.visibilityMap.set(ref.nativeElement, 0);\r\n\t\t\t});\r\n\t\t}, 500);\r\n\t}\r\n\r\n\t@Input() template!: TemplateRef<any>;\r\n\r\n\t@Input(\"data\") categories: any;\r\n\tselectedIndex = 0;\r\n\r\n\tisCategoryClick = false;\r\n\r\n\t@ViewChild('bottomScroll') bottomListRef!: ElementRef;\r\n\t@ViewChildren('sectionRef') sectionRefs!: QueryList<ElementRef>;\r\n\t@ViewChildren('topItemRef') topItemRefs!: QueryList<ElementRef>;\r\n\r\n\t@ViewChild('container') container!: ElementRef;\r\n\r\n\t@Input() listContainerCss = '';\r\n\t@Input() categoryContainerCss = '';\r\n\r\n\t@Output() selectedCategory = new EventEmitter();\r\n\t@Output() selectedItem = new EventEmitter();\r\n\r\n\tvisibilityMap = new Map<HTMLElement, number>();\r\n\tobserver: any;\r\n\r\n\r\n\tngAfterViewInit(): void {\r\n\t\tthis.addObserver();\r\n\t\tthis.sectionRefs?.forEach((ref) => {\r\n\t\t\tthis.observer.observe(ref.nativeElement);\r\n\t\t\tthis.visibilityMap.set(ref.nativeElement, 0);\r\n\t\t});\r\n\t}\r\n\r\n\taddObserver() {\r\n\t\t// const sectionElements = document.querySelectorAll('.category-section');\r\n\r\n\t\t// const observer = new IntersectionObserver((entries: any) => {\r\n\r\n\t\t// \t// console.log('entries:...', entries)\r\n\t\t// \t// let greter: any = entries[0];\r\n\t\t// \t// entries.forEach((entry: any) => {\r\n\t\t// \t// \tif (entry.isIntersecting) {\r\n\t\t// \t// \t\tconsole.log(entry)\r\n\t\t// \t// \t}\r\n\t\t// \t// \tif (entry.isIntersecting > (greter?.isIntersecting ?? 0)) {\r\n\t\t// \t// \t\tgreter = entry;\r\n\t\t// \t// \t}\r\n\t\t// \t// });\r\n\r\n\t\t// \t// if (greter) {\r\n\t\t// \t// \tconst index = greter.target.getAttribute('data-index');\r\n\t\t// \t// \tthis.inView(null, Number(index))\r\n\t\t// \t// }\r\n\r\n\t\t// \tlet maxRatio = 0;\r\n\t\t// \tlet mostVisibleElement: any = null;\r\n\t\t// \tentries.forEach((entry: any) => {\r\n\t\t// \t\tif (entry.isIntersecting && entry.intersectionRatio > maxRatio) {\r\n\t\t// \t\t\tmaxRatio = entry.intersectionRatio;\r\n\t\t// \t\t\tmostVisibleElement = entry.target;\r\n\t\t// \t\t}\r\n\t\t// \t});\r\n\r\n\t\t// \tif (mostVisibleElement) {\r\n\t\t// \t\tconsole.log('Most visible element:', mostVisibleElement);\r\n\t\t// \t\tconsole.log('Visibility ratio:', maxRatio);\r\n\r\n\t\t// \t\t// Do something like add a highlight class\r\n\t\t// \t\t// document.querySelectorAll('.category-section').forEach(el => {\r\n\t\t// \t\t// \tel.classList.remove('highlight');\r\n\t\t// \t\t// });\r\n\t\t// \t\t// mostVisibleElement?.classList.add('highlight');\r\n\t\t// \t\tconst index = mostVisibleElement.getAttribute('data-index');\r\n\t\t// \t\tthis.inView(null, Number(index))\r\n\t\t// \t}\r\n\r\n\t\t// }, {\r\n\t\t// \tthreshold: buildThresholdList()\r\n\t\t// });\r\n\r\n\t\t// sectionElements.forEach(section => observer.observe(section));\r\n\r\n\t\t// function buildThresholdList() {\r\n\t\t// \tconst thresholds = [];\r\n\t\t// \tfor (let i = 0; i <= 1.0; i += 0.005) {\r\n\t\t// \t\tthresholds.push(i);\r\n\t\t// \t}\r\n\t\t// \treturn thresholds;\r\n\t\t// }\r\n\r\n\r\n\t\tthis.visibilityMap = new Map<HTMLElement, number>();\r\n\r\n\t\tthis.observer = new IntersectionObserver((entries) => {\r\n\t\t\t// Update visibility status\r\n\t\t\tentries.forEach(entry => {\r\n\t\t\t\tif (entry.isIntersecting) {\r\n\t\t\t\t\tthis.visibilityMap.set(entry.target as HTMLElement, entry.intersectionRatio);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.visibilityMap.set(entry.target as HTMLElement, 0);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\t// Find the element with max visibility\r\n\t\t\tlet mostVisible: HTMLElement | null | any = null;\r\n\t\t\tlet maxRatio = 0;\r\n\r\n\t\t\tthis.visibilityMap.forEach((ratio, el) => {\r\n\t\t\t\tif (ratio > maxRatio) {\r\n\t\t\t\t\tmaxRatio = ratio;\r\n\t\t\t\t\tmostVisible = el;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\tif (mostVisible) {\r\n\t\t\t\t// Optional: highlight it\r\n\t\t\t\t// document.querySelectorAll('.category-section').forEach(el =>\r\n\t\t\t\t// \tel.classList.remove('highlight')\r\n\t\t\t\t// );\r\n\t\t\t\t// mostVisible.classList.add('highlight');\r\n\t\t\t\tconst index = mostVisible.getAttribute('data-index');\r\n\t\t\t\tthis.inView(null, Number(index))\r\n\t\t\t}\r\n\t\t}, {\r\n\t\t\tthreshold: buildThresholdList()\r\n\t\t});\r\n\r\n\t\tfunction buildThresholdList() {\r\n\t\t\tconst steps = 10;\r\n\t\t\treturn Array.from({ length: steps + 1 }, (_, i) => i / steps);\r\n\t\t}\r\n\r\n\r\n\r\n\t\t// Observe all your elements\r\n\t\t// document.querySelectorAll('.category-section').forEach((el: any) => {\r\n\t\t// \tobserver.observe(el);\r\n\t\t// \tvisibilityMap.set(el, 0); // initialize\r\n\t\t// });\r\n\r\n\r\n\r\n\t}\r\n\r\n\tscrollToCategory(category: any, index: number) {\r\n\t\tthis.isCategoryClick = true;\r\n\t\tthis.selectedIndex = index;\r\n\r\n\t\tconst section = this.sectionRefs.toArray()[index];\r\n\t\tsection.nativeElement.scrollIntoView({ behavior: 'smooth', block: 'start' });\r\n\r\n\t\tconst el = this.topItemRefs.toArray()[index];\r\n\t\tel?.nativeElement.scrollIntoView({ behavior: 'smooth', inline: 'center' });\r\n\t\tsetTimeout(() => {\r\n\t\t\tthis.isCategoryClick = false;\r\n\t\t}, 1000);\r\n\t}\r\n\r\n\tinView(cat: any, index: number) {\r\n\t\tthis.selectedIndex = index;\r\n\t\tif (!this.isCategoryClick) {\r\n\t\t\tconst el = this.topItemRefs.toArray()[index];\r\n\t\t\tel?.nativeElement.scrollIntoView({ behavior: 'smooth', inline: 'center' });\r\n\t\t}\r\n\t}\r\n}\r\n","<!-- Top horizontal category list -->\r\n<div #container>\r\n  <div class=\"top-category-container {{categoryContainerCss}}\" id=\"top-category-scroll\">\r\n    <div class=\"category-item\" *ngFor=\"let cat of categories; let i = index\" [class.active]=\"selectedIndex === i\"\r\n      (click)=\"scrollToCategory(cat, i)\" [attr.data-index]=\"i\" [attr.data-id]=\"cat.id\" [attr.data-name]=\"cat.name\"\r\n      #topItemRef>\r\n      {{ cat.name }}\r\n    </div>\r\n  </div>\r\n\r\n  <!-- Bottom vertical list -->\r\n  <div class=\"bottom-list {{listContainerCss}}\">\r\n    <div *ngFor=\"let cat of categories; let i = index\" class=\"category-section\" [attr.data-index]=\"i\"\r\n      [attr.data-id]=\"cat.id\" [attr.data-name]=\"cat.name\" #sectionRef>\r\n      <h2 class=\"category-title\">{{ cat.name }}</h2>\r\n      <div *ngFor=\"let item of cat.items\" class=\"item\">\r\n        @if(template) {\r\n        <ng-container *ngTemplateOutlet=\"template; context: { $implicit: item }\"></ng-container>\r\n        }\r\n        @else {\r\n        {{item.name}}\r\n        }\r\n      </div>\r\n    </div>\r\n  </div>\r\n</div>","/*\r\n * Public API Surface of ngx-category-scroll\r\n */\r\n\r\nexport * from './lib/ngx-category-scroll.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}