|
1 | 1 | import { |
2 | 2 | animationFrameScheduler, |
3 | 3 | filter, |
4 | | - fromEvent, |
5 | 4 | fromEventPattern, |
| 5 | + map, |
6 | 6 | mergeAll, |
7 | 7 | Observable, |
8 | | - pluck, |
9 | 8 | scheduled, |
| 9 | + Subject, |
10 | 10 | } from "rxjs"; |
11 | | -import { Ref, ref, watchEffect } from "vue"; |
| 11 | +import { onMounted, Ref, ref, watchEffect } from "vue"; |
12 | 12 | import { partial, pipe, unary } from "ramda"; |
13 | 13 | import { |
14 | 14 | MaybeElementRef, |
@@ -36,25 +36,46 @@ export function fromResizeObserver<T extends keyof ResizeObserverEntry>( |
36 | 36 | pipe(unary, partial(useResizeObserver, [elRef])) |
37 | 37 | ), |
38 | 38 | animationFrameScheduler |
39 | | - ).pipe(mergeAll(), pluck<ResizeObserverEntry, T>(pluckTarget)); |
40 | | -} |
41 | | - |
42 | | -export function fromWindowScroll(elRef: MaybeElementRef): Observable<Element> { |
43 | | - return fromEvent( |
44 | | - window, |
45 | | - "scroll", |
46 | | - { |
47 | | - passive: true, |
48 | | - capture: true, |
49 | | - }, |
50 | | - () => unrefElement(elRef) |
51 | 39 | ).pipe( |
52 | | - filter<Element | undefined | null, Element>((el): el is Element => |
53 | | - Boolean(el) |
| 40 | + mergeAll(), |
| 41 | + map<ResizeObserverEntry, ResizeObserverEntry[T]>( |
| 42 | + (entry) => entry[pluckTarget] |
54 | 43 | ) |
55 | 44 | ); |
56 | 45 | } |
57 | 46 |
|
| 47 | +export function fromScrollParent(elRef: MaybeElementRef): Observable<Element> { |
| 48 | + const scrollSubject = new Subject<Element>(); |
| 49 | + |
| 50 | + onMounted(() => { |
| 51 | + const el = unrefElement(elRef); |
| 52 | + |
| 53 | + if (el) { |
| 54 | + const { vertical, horizontal } = getScrollParents(el); |
| 55 | + |
| 56 | + const scrollParents = |
| 57 | + vertical === horizontal ? [vertical] : [vertical, horizontal]; |
| 58 | + |
| 59 | + const pushEl = () => scrollSubject.next(el); |
| 60 | + |
| 61 | + scrollParents.forEach((parent) => |
| 62 | + parent.addEventListener("scroll", pushEl, { |
| 63 | + passive: true, |
| 64 | + capture: true, |
| 65 | + }) |
| 66 | + ); |
| 67 | + |
| 68 | + tryOnUnmounted(() => |
| 69 | + scrollParents.forEach((parent) => |
| 70 | + parent.removeEventListener("scroll", pushEl) |
| 71 | + ) |
| 72 | + ); |
| 73 | + } |
| 74 | + }); |
| 75 | + |
| 76 | + return scrollSubject; |
| 77 | +} |
| 78 | + |
58 | 79 | export function useObservable<H>(observable: Observable<H>): Readonly<Ref<H>> { |
59 | 80 | const valueRef = ref<H>(); |
60 | 81 | const subscription = observable.subscribe((val) => (valueRef.value = val)); |
@@ -92,7 +113,8 @@ export function getScrollParents( |
92 | 113 |
|
93 | 114 | for ( |
94 | 115 | let parent: Element | null = element; |
95 | | - (parent = parent.parentElement); |
| 116 | + // parent.assignedSlot.parentElement find the correct parent if the grid is inside a native web component |
| 117 | + (parent = parent.assignedSlot?.parentElement ?? parent.parentElement); |
96 | 118 |
|
97 | 119 | ) { |
98 | 120 | const parentStyle = getComputedStyle(parent); |
|
0 commit comments