Skip to content

Commit a7b3e79

Browse files
authored
feat: add useIntersectionObserver (#27)
* WIP: intersectionObserver * WIP: IntersectionObserver * docs: add IntersectionObserver documentation * test: add intersectionObserver tests * types: fix Ref<Element> to use RefElement * changelog: added intersectionObserver to unreleased * trigger build * types: fix types * hiding debug method
1 parent b225f62 commit a7b3e79

File tree

11 files changed

+506
-10
lines changed

11 files changed

+506
-10
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
44
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
55

6+
## [Unreleased]
7+
------------------------------
8+
9+
### Added
10+
- [IntersectionObserver](composable/web/intersectionObserver) - Provides functionality to IntersectionObserver #27
11+
612
## 0.2.2
713
------------------------------
814
*2019-12-10*

docs/.vuepress/components/ArrayPaginationExample.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
</template>
1515

1616
<script>
17-
// import { useArrayPagination } from '../../../packages/core';
1817
import { useArrayPagination } from "vue-composable";
1918
2019
export default {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<template>
2+
<div>
3+
Visible: {{ isIntersecting }}
4+
5+
<p>Scroll down</p>
6+
7+
<div style="height:500px"/>
8+
9+
<div ref="el" style="background:lightgreen">
10+
Hide me
11+
</div>
12+
13+
<p>Scroll up</p>
14+
</div>
15+
</template>
16+
17+
<script>
18+
import {ref, watch, reactive} from '@vue/composition-api';
19+
import {useIntersectionObserver} from 'vue-composable';
20+
21+
export default {
22+
name: "intersection-observer-example",
23+
setup(){
24+
const el = ref(null);
25+
const o = useIntersectionObserver(el);
26+
return {
27+
...o,
28+
el
29+
}
30+
}
31+
}
32+
</script>

docs/.vuepress/config.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,9 @@ module.exports = {
196196
collapsable: false,
197197
children: [
198198
["composable/web/fetch", "fetch"],
199-
["composable/web/webSocket", "webSocket"]
199+
["composable/web/webSocket", "webSocket"],
200+
["composable/web/intersectionObserver", "IntersectionObserver"]
201+
200202
]
201203
},
202204
{

docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ Check out the [examples folder](examples) or start hacking on [codesandbox](http
7171

7272
- [Fetch](composable/web/fetch) - reactive `fetch` wrapper
7373
- [WebSocket](composable/web/webSocket) - reactive `WebSocket` wrapper
74+
- [IntersectionObserver](composable/web/intersectionObserver) - reactive `IntersectionObserver`
7475

7576
### External
7677

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# IntersectionObserver
2+
3+
> The [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API).
4+
5+
## State
6+
7+
The `useIntersectionObserver` function exposes the following reactive state:
8+
9+
```js
10+
import { useIntersectionObserver } from "vue-composable";
11+
12+
const { elements, isIntersecting } = useIntersectionObserver(options);
13+
```
14+
15+
| State | Type | Description |
16+
| -------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------- |
17+
| elements | `IntersectionObserverEntry[]` | [IntersectionObserverEntry](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserverEntry) |
18+
| isIntersecting | `Boolean` | Returns true if **all** observed elements are intersection |
19+
20+
## Methods
21+
22+
The `useIntersectionObserver` function exposes the following methods:
23+
24+
```js
25+
import { useIntersectionObserver } from "vue-composable";
26+
27+
const { observe, unobserve, disconnect, debug } = useIntersectionObserver();
28+
```
29+
30+
| Signature | Description |
31+
| ------------------- | ------------------------------------------------------------------------------------------------------------------- |
32+
| `observe(Element)` | Starts observing Element |
33+
| `unobserve(Element` | Stops observing Element |
34+
| `disconnect()` | [IntersectionObserver.disconnect](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/disconnect) |
35+
36+
<!-- | `debug()` | Provides some debug information: [WIP] | -->
37+
38+
## Example
39+
40+
```vue
41+
<template>
42+
<div>
43+
Visible: {{ isIntersecting }}
44+
45+
<p>Scroll down</p>
46+
<div style="height:500px" />
47+
48+
<div ref="el" style="background:lightgreen">
49+
Hide me
50+
</div>
51+
52+
<p>Scroll up</p>
53+
</div>
54+
</template>
55+
56+
<script>
57+
import { ref, watch, reactive } from "@vue/composition-api";
58+
import { useIntersectionObserver } from "vue-composable";
59+
60+
export default {
61+
name: "intersection-observer-example",
62+
setup() {
63+
const el = ref(null);
64+
const o = useIntersectionObserver(el);
65+
return {
66+
...o,
67+
el
68+
};
69+
}
70+
};
71+
</script>
72+
```
73+
74+
### Code
75+
76+
<ClientOnly>
77+
<intersection-observer-example/>
78+
</ClientOnly>

packages/core/src/utils.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22
import { Ref, isRef, ref } from "@vue/composition-api";
33

44
export type RefTyped<T> = T | Ref<T>;
5-
export type RefElement = RefTyped<Element>;
5+
export type RefElement = Element | Ref<Element | undefined>;
66

7-
// export function unwrap<T>(o: RefTyped<T>): T {
8-
// return isRef(o) ? o.value : o;
9-
// }
7+
export function unwrap(o: RefElement): Element;
8+
export function unwrap<T>(o: RefTyped<T>): T;
9+
export function unwrap<T>(o: RefTyped<T>): T {
10+
return isRef(o) ? o.value : o;
11+
}
12+
13+
export function wrap(o: RefElement): Ref<Element>;
14+
export function wrap<T>(o: RefTyped<T>): Ref<T>;
1015
export function wrap<T>(o: RefTyped<T>): Ref<T> {
1116
return isRef(o) ? o : ref(o);
1217
}
@@ -28,6 +33,9 @@ export const isNumber = (val: unknown): val is number =>
2833
export const isObject = (val: unknown): val is Record<any, any> =>
2934
val !== null && typeof val === "object";
3035

36+
export const isElement = (val: unknown): val is Element =>
37+
isObject(val) && !!val.tagName;
38+
3139
export function isPromise<T = any>(val: unknown): val is Promise<T> {
3240
return isObject(val) && isFunction(val.then) && isFunction(val.catch);
3341
}

0 commit comments

Comments
 (0)