Skip to content
This repository was archived by the owner on Nov 5, 2023. It is now read-only.

Commit 5e33290

Browse files
committed
feat: support running inside a native web component
1 parent f0b3cdc commit 5e33290

File tree

2 files changed

+48
-22
lines changed

2 files changed

+48
-22
lines changed

src/Grid.vue

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717

1818
<template
1919
v-for="internalItem in buffer"
20-
:key="getKey ? getKey(internalItem) : keyPrefix + '.' + internalItem.index"
20+
:key="
21+
getKey ? getKey(internalItem) : keyPrefix + '.' + internalItem.index
22+
"
2123
>
2224
<slot
2325
v-if="internalItem.value === undefined"
@@ -49,7 +51,7 @@ import {
4951
import {
5052
fromProp,
5153
fromResizeObserver,
52-
fromWindowScroll,
54+
fromScrollParent,
5355
useObservable,
5456
} from "./utilites";
5557
import { InternalItem, PageProvider, pipeline, ScrollAction } from "./pipeline";
@@ -113,7 +115,9 @@ export default defineComponent({
113115
default: "div",
114116
},
115117
getKey: {
116-
type: Function as PropType<(internalItem: InternalItem) => number | string>,
118+
type: Function as PropType<
119+
(internalItem: InternalItem) => number | string
120+
>,
117121
required: false,
118122
default: undefined,
119123
},
@@ -139,7 +143,7 @@ export default defineComponent({
139143
// a stream of root elements when it is resized
140144
rootResize$: fromResizeObserver(rootRef, "target"),
141145
// a stream of root elements when scrolling
142-
scroll$: fromWindowScroll(rootRef),
146+
scroll$: fromScrollParent(rootRef),
143147
respectScrollToOnResize$: fromProp(props, "respectScrollToOnResize"),
144148
scrollTo$: fromProp(props, "scrollTo"),
145149
});

src/utilites.ts

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import {
22
animationFrameScheduler,
33
filter,
4-
fromEvent,
54
fromEventPattern,
5+
map,
66
mergeAll,
77
Observable,
8-
pluck,
98
scheduled,
9+
Subject,
1010
} from "rxjs";
11-
import { Ref, ref, watchEffect } from "vue";
11+
import { onMounted, Ref, ref, watchEffect } from "vue";
1212
import { partial, pipe, unary } from "ramda";
1313
import {
1414
MaybeElementRef,
@@ -36,25 +36,46 @@ export function fromResizeObserver<T extends keyof ResizeObserverEntry>(
3636
pipe(unary, partial(useResizeObserver, [elRef]))
3737
),
3838
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)
5139
).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]
5443
)
5544
);
5645
}
5746

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+
5879
export function useObservable<H>(observable: Observable<H>): Readonly<Ref<H>> {
5980
const valueRef = ref<H>();
6081
const subscription = observable.subscribe((val) => (valueRef.value = val));
@@ -92,7 +113,8 @@ export function getScrollParents(
92113

93114
for (
94115
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);
96118

97119
) {
98120
const parentStyle = getComputedStyle(parent);

0 commit comments

Comments
 (0)