]> git.openstreetmap.org Git - rails.git/blob - app/assets/javascripts/numbered_pagination.js
Merge remote-tracking branch 'upstream/pull/6314'
[rails.git] / app / assets / javascripts / numbered_pagination.js
1 (function () {
2   class ShadowEffect {
3     constructor(target) {
4       const [startList, scrollableList, endList] = $(target).children();
5       const [scrollableFirstItem] = $(scrollableList).children().first();
6       const [scrollableLastItem] = $(scrollableList).children().last();
7
8       if (scrollableFirstItem) {
9         this.scrollStartObserver = createScrollObserver(startList, "2px 0px");
10         this.scrollStartObserver.observe(scrollableFirstItem);
11       }
12
13       if (scrollableLastItem) {
14         this.scrollEndObserver = createScrollObserver(endList, "-2px 0px");
15         this.scrollEndObserver.observe(scrollableLastItem);
16       }
17
18       function createScrollObserver(shadowTarget, shadowOffset) {
19         const threshold = 0.95;
20         return new IntersectionObserver(([entry]) => {
21           const floating = entry.intersectionRatio < threshold;
22           $(shadowTarget)
23             .css("box-shadow", floating ? `rgba(0, 0, 0, 0.075) ${shadowOffset} 2px` : "")
24             .css("z-index", floating ? "5" : ""); // floating z-index should be larger than z-index of Bootstrap's .page-link:focus, which is 3
25         }, { threshold });
26       }
27     }
28
29     disable() {
30       this.scrollStartObserver?.disconnect();
31       this.scrollEndObserver?.disconnect();
32     }
33   }
34
35   $(document).on("click", "a.numbered_pagination_link", function (e) {
36     const targetItemId = $(this).attr("href");
37     const $targetItem = $(targetItemId);
38     $targetItem.trigger("numbered_pagination:center");
39     $targetItem.find("a.page-link").trigger("focus");
40     e.preventDefault();
41   });
42
43   $(document).on("numbered_pagination:enable", ".numbered_pagination", function () {
44     $(this).data("shadow-effect", new ShadowEffect(this));
45     $(this).trigger("numbered_pagination:center");
46   });
47
48   $(document).on("numbered_pagination:disable", ".numbered_pagination", function () {
49     $(this).data("shadow-effect")?.disable();
50     $(this).removeData("shadow-effect");
51   });
52
53   $(document).on("numbered_pagination:center", ".numbered_pagination", function () {
54     const [startList, scrollableList] = $(this).children();
55
56     if (!scrollableList) return;
57
58     const [activeStartItem] = $(startList).find(".page-item.active");
59     const [activeScrollableItem] = $(scrollableList).find(".page-item.active");
60
61     if (activeStartItem) {
62       scrollableList.scrollLeft = 0;
63     } else if (activeScrollableItem) {
64       scrollableList.scrollLeft = Math.round(activeScrollableItem.offsetLeft - (scrollableList.offsetWidth / 2) + (activeScrollableItem.offsetWidth / 2));
65     } else {
66       scrollableList.scrollLeft = scrollableList.scrollWidth - scrollableList.offsetWidth;
67     }
68   });
69 }());