From 8f2ff648c212531458f2a5ea3fdad61d628045f5 Mon Sep 17 00:00:00 2001 From: Kieran Boyle Date: Fri, 2 Apr 2021 13:20:50 -0700 Subject: [PATCH 1/2] use a single observer per definition; expose observer props to interface --- README.md | 57 +++++++++++++++++++++++ docs/src/App.svelte | 14 +++--- docs/src/ContainerExample.svelte | 14 ++++-- docs/yarn.lock | 8 ++-- rollup.config.js | 1 - src/Viewable.svelte | 80 ++++++++++++++++++++------------ src/Viewable.test.js | 4 +- 7 files changed, 132 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 92b6184..ed8c86d 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,63 @@ npm i -D @svelte-plugins/viewable ``` +Try the basic example in [Svelte REPL](https://svelte.dev/repl/c811481b8e1b48e9bed0f6ff7d1fa9c2). + +## API + +### Props +| Prop name | Description | Value | +| :----------- | :---------------------------------------------------------------- | :---------------------------------------------------------------------------------------------- | +| element | Element to observe | `HTMLElement` | +| rules | Viewability rules | `object` (default: `null`) | +| intervalRate | Rate to check measurement while intersecting (ms) | `number` (default: `200`) | +| gridSize | Size of the obstruction grid | `number` (default: `20`) | +| detectObstructions | If `true`, obstructions impacting the element will affect measurement | 'boolean' (default: `false`) | +| root | Containing element | `null` or `HTMLElement` (default: `null`) | +| rootMargin | Margin offset of the containing element | `string` (default: `"0px"`) | +| intersecting | `true` if the observed element is intersecting the viewport | `boolean` (default: `false`) | +| observer | IntersectionObserver instance | [`IntersectionObserver`](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver) | +| debug | If `true`, debug ouput will be logged to console | `boolean` (default: `false`) | + +#### rules +| Prop name | Description | Value | +| :----------- | :------------------------------------------------------------------ | :---------------------------------- | +| duration | Consecutive time (seconds) that the element must be in view | `number` (default: `0`) | +| percentage | Percentage of the element that must be viewable | `number` (default: `0`) | +| repeat | If `true`, the rule will be applied indefinitely v once | `function` (default: `null`) | +| fn | Callback function to execute when rule has been met | `function` (default: `null`) | + + +```js +const rules = { + dwell: { + duration: 1, + percentage: 50, + fn: () => { + console.log('50% of the element was visible for at least 1 consecutive second.'); + } + } +} +``` + +### Debug props + +The properties below can be used to assist with debugging any issues you might have (ex: `bind:duration`, `bind:percent`, etc.) + +| Prop name | Description | Value | +| :----------- | :---------------------------------------------------------------- | :---------------------- | +| duration | Viewable duration of the tracked element | `number` (default: `0`) | +| percent | Percentage of total viewable area (X+Y) | `number` (default: `0`) | +| percentX | Percentage of horizontal viewable area | `number` (default: `0`) | +| percentY | Percentage of vertical viewable area | `number` (default: `0`) | + + +### Dispatched events + +- **on:observe**: Fired when an intersection change occurs (type `IntersectionObserverEntry`) +- **on:intersect**: Fired when an intersection change occurs and the element is intersecting (type `IntersectionObserverEntry`) +- **on:complete**: Fired when all rules have been executed + ## Changelog [Changelog](CHANGELOG.md) diff --git a/docs/src/App.svelte b/docs/src/App.svelte index 92edce9..76c2590 100644 --- a/docs/src/App.svelte +++ b/docs/src/App.svelte @@ -1,21 +1,21 @@ -{#if enableObstructionDetection} +{#if detectObstructions}
{/if}
-

Hint: Open dev console to see debug output.

@@ -48,7 +48,7 @@
- +
@@ -70,7 +70,7 @@
- + Hello World!
diff --git a/docs/src/ContainerExample.svelte b/docs/src/ContainerExample.svelte index 69400bc..ebb77a3 100644 --- a/docs/src/ContainerExample.svelte +++ b/docs/src/ContainerExample.svelte @@ -1,7 +1,7 @@ - +
diff --git a/docs/yarn.lock b/docs/yarn.lock index 381ca16..1d37c20 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -11,7 +11,7 @@ picomatch "^2.2.2" "@svelte-plugins/viewable@../": - version "0.1.2" + version "0.1.3" "@sveltejs/vite-plugin-svelte@^1.0.0-next.5": version "1.0.0-next.5" @@ -95,9 +95,9 @@ debug@^4.3.2: ms "2.1.2" electron-to-chromium@^1.3.649: - version "1.3.703" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.703.tgz#6d9b9a75c42a40775f5930329e642b22b227317f" - integrity sha512-SVBVhNB+4zPL+rvtWLw7PZQkw/Eqj1HQZs22xtcqW36+xoifzEOEEDEpkxSMfB6RFeSIOcG00w6z5mSqLr1Y6w== + version "1.3.705" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.705.tgz#9729956782ce44cd93bdb4197818cff71f7d5e9d" + integrity sha512-agtrL5vLSOIK89sE/YSzAgqCw76eZ60gf3J7Tid5RfLbSp5H4nWL28/dIV+H+ZhNNi1JNiaF62jffwYsAyXc0g== esbuild@^0.9.3: version "0.9.7" diff --git a/rollup.config.js b/rollup.config.js index 9ae8e4e..65703bb 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -36,7 +36,6 @@ export default () => { "babelHelpers": "bundled", "exclude": ["/node_modules/**"] }), - production && terser() ] }; diff --git a/src/Viewable.svelte b/src/Viewable.svelte index 8b72e12..98ccf76 100644 --- a/src/Viewable.svelte +++ b/src/Viewable.svelte @@ -1,5 +1,5 @@ - + diff --git a/src/Viewable.test.js b/src/Viewable.test.js index b9ac70c..7755b0c 100644 --- a/src/Viewable.test.js +++ b/src/Viewable.test.js @@ -54,7 +54,7 @@ describe(Viewable.name, () => { it('should execute rules when duration and percentage have been meet (immediate)', async () => { const mock = jest.fn(); - await TestHarness({ debug: true, enableObstructionDetection: true, rules: { immediate: { fn: mock } } }); + await TestHarness({ debug: true, detectObstructions: true, rules: { immediate: { fn: mock } } }); onIntersectionMock([{ isIntersecting: true }]); @@ -71,7 +71,7 @@ describe(Viewable.name, () => { const fn = jest.fn(); const { container } = await TestHarness({ - enableObstructionDetection: true, + detectObstructions: true, rules: { fifty4six: { percentage: 50, From c557fe20ad00dafc5bfb743b084812adea6000a4 Mon Sep 17 00:00:00 2001 From: Kieran Boyle Date: Fri, 2 Apr 2021 14:12:38 -0700 Subject: [PATCH 2/2] update documentation --- CHANGELOG.md | 6 ++++++ README.md | 5 +++-- package.json | 2 +- src/Viewable.svelte | 30 ++++++++++++++++++++++++++---- 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5f0e07..db7b91a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.0.0](https://github.com/svelte-plugins/svelte-viewable/releases/tag/v1.0.0) - 2021-04-02 + +- Interface changes that include exposing observer props and events +- Includes new `on:complete` event +- Replaced `enableObstructionDetection` with `detectObstructions` + ## [0.1.3](https://github.com/svelte-plugins/svelte-viewable/releases/tag/v0.1.3) - 2021-04-01 - Enable SSR support diff --git a/README.md b/README.md index ed8c86d..574f298 100644 --- a/README.md +++ b/README.md @@ -59,8 +59,9 @@ Try the basic example in [Svelte REPL](https://svelte.dev/repl/c811481b8e1b48e9b | detectObstructions | If `true`, obstructions impacting the element will affect measurement | 'boolean' (default: `false`) | | root | Containing element | `null` or `HTMLElement` (default: `null`) | | rootMargin | Margin offset of the containing element | `string` (default: `"0px"`) | -| intersecting | `true` if the observed element is intersecting the viewport | `boolean` (default: `false`) | +| intersecting | `true` if the observed element is intersecting | `boolean` (default: `false`) | | observer | IntersectionObserver instance | [`IntersectionObserver`](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver) | +| entry | Observed element metadata | [`IntersectionObserverEntry`](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserverEntry) | | debug | If `true`, debug ouput will be logged to console | `boolean` (default: `false`) | #### rules @@ -96,7 +97,7 @@ The properties below can be used to assist with debugging any issues you might h | percentY | Percentage of vertical viewable area | `number` (default: `0`) | -### Dispatched events +### Events - **on:observe**: Fired when an intersection change occurs (type `IntersectionObserverEntry`) - **on:intersect**: Fired when an intersection change occurs and the element is intersecting (type `IntersectionObserverEntry`) diff --git a/package.json b/package.json index 8f460fb..d86fefd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@svelte-plugins/viewable", - "version": "0.1.3", + "version": "1.0.0", "license": "MIT", "description": "A simple rule-based approach to tracking element viewability.", "author": "Kieran Boyle (https://github.com/dysfunc)", diff --git a/src/Viewable.svelte b/src/Viewable.svelte index 98ccf76..7a2efce 100644 --- a/src/Viewable.svelte +++ b/src/Viewable.svelte @@ -2,7 +2,7 @@ import { afterUpdate, createEventDispatcher, onDestroy, tick } from 'svelte'; /** - * HTML Element to track + * HTML Element to observe * @type {null | HTMLElement} */ export let element; @@ -47,17 +47,39 @@ */ export let gridSize = 20; /** - * Enables checking for elements obstructing the tracked elements view (popups, modals, overlays, etc.) + * If true, enables checking for anything obstructing the observed elements view (popups, modals, overlays, etc.) * @type {Boolean} */ export let detectObstructions = false; - + /** + * Containing element (Defaults to the browser viewport) + * @type {null | HTMLElement} + */ export let root = null; + /** + * Margin offset of the containing element + * @type {String} + */ export let rootMargin = '0px'; + /** + * Array of visibility thresholds that will result in a callback when + * the observed element crosses that each threshold (.1 = 10% visible inside of its container) + */ export let threshold = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]; - + /** + * Observed element metadata + * @type {null | Entry} + */ export let entry = null; + /** + * If true, the observed element is intersecting + * @type {Boolean} + */ export let intersecting = false; + /** + * IntersectionObserver instance + * @type {null | IntersectionObserver} + */ export let observer = null; let ready = null;