Skip to content

Commit

Permalink
Merge pull request #7 from Yrobot/master
Browse files Browse the repository at this point in the history
release 3.0
  • Loading branch information
Yrobot authored Apr 8, 2024
2 parents c289424 + 59fd626 commit 7d05121
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 27 deletions.
20 changes: 17 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ autoScroll({ selector: "#scroll-container-id" });
> es
```ts
import autoScroll, { generateEscapeScrollUpContext } from "@yrobot/auto-scroll";
import autoScroll, { escapeWhenUpPlugin } from "@yrobot/auto-scroll";

autoScroll({
selector: "#scroll-container-id",
context: generateEscapeScrollUpContext(),
plugins: [escapeWhenUpPlugin()],
});
```

Expand All @@ -64,6 +64,20 @@ autoScroll({
```ts
autoScroll.default({
selector: "#scroll-container-id",
context: autoScroll.generateEscapeScrollUpContext(),
plugins: [autoScroll.escapeWhenUpPlugin()],
});
```

<!-- ## Customize plugins
```ts
import type { Plugin } from "@yrobot/auto-scroll";
const myPlugin: Plugin<{ name: string }> = ({ name }) => ({
escapeHook: (elm) => true,
onMount: (elm) => () => {},
onUnmount: (elm) => {},
});
```
the plugin should return the an object includes `escapeHook`, `onMount`, `onUnmount` functions. -->
44 changes: 24 additions & 20 deletions package/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,21 @@ export type Context = {
onUnmount?: OnUnmount;
};

export type Plugin<T = unknown> = (config?: T) => Context;

/**
* Generates the context for escaping auto scroll down when user scroll up.
* the auto-scroll plugin for escaping auto scroll down when user scroll up.
*
* @param {Object} config - The configs.
* @param {number} [config.threshold=24] - The threshold value for scroll up distance (default: 24).
* @param {number} [config.throttleTime=100] - The throttle time for scroll event (default: 100).
*
* @returns {Context} The generated context object. For autoScroll.param.context
* @returns {Context} The generated state object. For autoScroll.param.plugins
*/
export function generateEscapeScrollUpContext({
threshold = 24,
throttleTime = 100,
}: { threshold?: number; throttleTime?: number } = {}) {
export const escapeWhenUpPlugin: Plugin<{
threshold?: number;
throttleTime?: number;
}> = ({ threshold = 24, throttleTime = 100 } = {}) => {
const context: Context = {};
let isEscape = false;
const [onScroll] = throttle((evt: Event) => {
Expand All @@ -62,45 +64,46 @@ export function generateEscapeScrollUpContext({
};
context.escapeHook = () => isEscape;
return context;
}
};

/**
* @description auto scroll the selector dom to the bottom, when the size of the selector dom has been updated.
*
* @param {Object} options - The config options for the autoScroll function.
* @param {string} options.selector - The selector for the container element. (example: '#container')
* @param {Context} [options.context] - The context for the life cycle hooks of the autoScroll function. [escapeHook,onMount,onUnmount]
* @param {Context[]} [options.plugins] - The plugins for the life cycle hooks of the autoScroll function. [escapeHook,onMount,onUnmount]
* @param {number} [options.throttleTime=100] - The throttle time in milliseconds.
* @param {number} [options.offset=0] - The offset for the scroll position based on the container.scrollHeight.
*
* @return {function} The unObserverCallback function.
*
* @example autoScroll({ selector: "#scroll-container-id" })
* @example autoScroll({ selector: "#scroll-container-id", context: generateEscapeScrollUpContext() })
* @example autoScroll({ selector: "#scroll-container-id", plugins: [escapeWhenUpPlugin()] })
*/
export default function autoScroll({
selector,
throttleTime = 100,
context,
plugins = [],
offset = 0,
}: {
selector: string;
throttleTime?: number;
context?: Context;
plugins?: ReturnType<Plugin>[];
offset?: number;
}): unObserverCallback {
const container = document.querySelector(selector);

if (container === null)
throw new Error(`Element not found with selector [${selector}]`);

const returnOnUnmount = context?.onMount?.(container);
// plugins onMount
const mountReturnFuncList = plugins
.map((plugin) => plugin?.onMount?.(container))
.filter((result) => typeof result === "function") as OnUnmount[];

// main auto down scroll hook
const [scrollHook] = throttle(() => {
if (
typeof context?.escapeHook === "function" &&
context.escapeHook(container)
)
if (!!plugins.find((plugin) => plugin?.escapeHook?.(container) === true))
return false;
// use requestAnimationFrame for escape ResizeObserver loop
requestAnimationFrame(() => {
Expand All @@ -109,10 +112,10 @@ export default function autoScroll({
return true;
}, throttleTime);

// observers
const resizeObserver = new ResizeObserver(() => {
scrollHook();
});

const mutationObserver = new MutationObserver(() => {
scrollHook();
});
Expand All @@ -127,11 +130,12 @@ export default function autoScroll({
subtree: true,
childList: true,
});

// unmount
return () => {
resizeObserver.disconnect();
mutationObserver.disconnect();
// unmount
returnOnUnmount?.(container);
context?.onUnmount?.(container);
mountReturnFuncList.forEach((func) => func(container));
plugins.forEach((plugin) => plugin?.onUnmount?.(container));
};
}
8 changes: 4 additions & 4 deletions website/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect, useRef, useState } from "react";
import { createRoot } from "react-dom/client";

import autoScroll, { generateEscapeScrollUpContext } from "../package/index.ts";
import autoScroll, { escapeWhenUpPlugin } from "../package/index.ts";

import "./index.css";

Expand Down Expand Up @@ -32,11 +32,11 @@ import autoScroll from "@yrobot/auto-scroll";
autoScroll({ selector: "#scroll-container-id" });`,
escapeScrollUp: `
import autoScroll, { generateEscapeScrollUpContext } from "@yrobot/auto-scroll";
import autoScroll, { escapeWhenUpPlugin } from "@yrobot/auto-scroll";
autoScroll({
selector: "#scroll-container-id",
context: generateEscapeScrollUpContext(),
plugins: [escapeWhenUpPlugin()],
});`,
};

Expand Down Expand Up @@ -86,7 +86,7 @@ const EscapeScrollUpDemo = () => {
() =>
autoScroll({
selector: "#escape-scroll-up-list-container",
context: generateEscapeScrollUpContext(),
plugins: [escapeWhenUpPlugin()],
}),
[]
);
Expand Down

0 comments on commit 7d05121

Please sign in to comment.