tiny-essentials
Version:
Collection of small, essential scripts designed to be used across various projects. These simple utilities are crafted for speed, ease of use, and versatility.
658 lines • 25.8 kB
text/typescript
export default TinySmartScroller;
/**
* Represents the dimensions of a DOM element.
*/
export type NodeSizes = {
/**
* - The height of the element in pixels.
*/
height: number;
/**
* - The width of the element in pixels.
*/
width: number;
};
/**
* A callback function that receives node size change data and optionally returns a modified NodeSizes object.
*/
export type NodeSizesEvent = (elem: Element, sizes: {
old: NodeSizes;
now: NodeSizes;
}, elemAmount: {
old: number;
now: number;
}) => NodeSizes | undefined;
/**
* A generic scroll-related event listener callback function.
*/
export type ScrollListenersFunc = (payload: any) => void;
/**
* Represents the dimensions of a DOM element.
*
* @typedef {Object} NodeSizes
* @property {number} height - The height of the element in pixels.
* @property {number} width - The width of the element in pixels.
*/
/**
* A callback function that receives node size change data and optionally returns a modified NodeSizes object.
*
* @callback NodeSizesEvent
* @param {Element} elem - The DOM element whose size is being tracked.
* @param {{ old: NodeSizes, now: NodeSizes }} sizes - The old and new size measurements of the element.
* @param {{ old: number, now: number }} elemAmount - The number of matching elements before and after the update.
* @returns {NodeSizes|undefined} A modified NodeSizes object to override the default measurement, or undefined to use the original.
*/
/**
* A generic scroll-related event listener callback function.
*
* @callback ScrollListenersFunc
* @param {any} payload - The data payload passed when the scroll event is triggered. The type may vary depending on the event.
* @returns {void}
*/
/**
* TinySmartScroller is a utility class designed to enhance and manage scroll behaviors within containers or the window.
*
* It enables advanced scroll monitoring, auto-scrolling to bottom, preserving scroll position during DOM changes,
* and detecting visibility changes of elements. This is particularly useful for dynamic UIs like chat applications,
* feed viewers, or live content containers.
*
* Features:
* - Detects when the scroll reaches the top, bottom, or custom boundaries
* - Supports automatic scrolling to the bottom unless the user scrolls away
* - Observes DOM mutations and resizes, and adapts scroll position accordingly
* - Emits scroll-related events such as 'onScrollBoundary', 'onAutoScroll', and 'onScrollPause'
* - Includes customizable scroll correction filters for layout shift mitigation
* - Handles media element load events (e.g. `<img>`, `<iframe>`, `<video>`) to prevent sudden scroll jumps
*
* This class is **not framework-dependent** and works with vanilla DOM elements and the window object.
*/
declare class TinySmartScroller {
static Utils: {
TinyHtml: typeof TinyHtml;
getElsRelativeCenterOffset(rect1: ObjRect, rect2: ObjRect): {
x: number;
y: number;
};
getElsCollDirDepth(rect1: ObjRect, rect2: ObjRect): {
inDir: Dirs | null;
dirX: Dirs | null;
dirY: Dirs | null;
depthX: number;
depthY: number;
};
getElsCollDetails(rect1: ObjRect, rect2: ObjRect): {
depth: CollData;
dirs: CollDirs;
isNeg: NegCollDirs;
};
areElsCollTop: (rect1: ObjRect, rect2: ObjRect) => boolean;
areElsCollBottom: (rect1: ObjRect, rect2: ObjRect) => boolean;
areElsCollLeft: (rect1: ObjRect, rect2: ObjRect) => boolean;
areElsCollRight: (//////////////////////////////////////////
/**
* Adds a event listener.
*
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
* @param {ScrollListenersFunc} handler - Callback function to be called when event fires.
*/
rect1: ObjRect
/**
* Adds a event listener.
*
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
* @param {ScrollListenersFunc} handler - Callback function to be called when event fires.
*/
, ////////////////////////////////////
/**
* Adds a event listener.
*
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
* @param {ScrollListenersFunc} handler - Callback function to be called when event fires.
*/
rect2: ObjRect
/**
* Adds a event listener.
*
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
* @param {ScrollListenersFunc} handler - Callback function to be called when event fires.
*/
) => boolean;
areElsCollPerfTop: (rect1: ObjRect, rect2: ObjRect) => boolean;
areElsCollPerfBottom: (rect1: ObjRect, rect2: ObjRect) => boolean;
areElsCollPerfLeft: (rect1: ObjRect, rect2: ObjRect) => boolean;
areElsCollPerfRight: (rect1: ObjRect, rect2: ObjRect) => boolean;
areElsColliding: (/**
* Removes a previously registered event listener.
*
* @param {string} event - The name of the event to remove the handler from.
* @param {ScrollListenersFunc} handler - The specific callback function to remove.
*/ rect1: ObjRect, rect2: ObjRect) => boolean;
areElsPerfColliding: (rect1: ObjRect, rect2: ObjRect) => boolean;
getElsColliding: (rect1: ObjRect, rect2: ObjRect) => string | null;
getElsPerfColliding: (rect1: ObjRect, rect2: ObjRect) => "top" | "bottom" | "left" | "right" | null;
getElsCollOverlap: (rect1: ObjRect, rect2: ObjRect) => {
overlapLeft: number;
overlapRight: number;
overlapTop: number;
overlapBottom: number;
};
getElsCollOverlapPos: ({ overlapLeft, overlapRight, overlapTop, overlapBottom, }?: {
overlapLeft?: number | undefined;
overlapRight?: number | undefined;
overlapTop?: number | undefined;
overlapBottom?: number | undefined;
}) => {
dirX: Dirs;
dirY: Dirs;
};
getRectCenter: (rect: ObjRect) => {
x: number;
y: number;
};
};
/**
* Creates a new instance of TinySmartScroller, attaching scroll and resize observers to manage
* automatic scroll behaviors, layout shift correction, and visibility tracking.
*
* @param {Element|Window} target - The scroll container to monitor. Can be an element or `window`.
* @param {Object} [options={}] - Optional settings to configure scroll behavior.
* @param {number} [options.extraScrollBoundary=0] - Extra margin in pixels to extend scroll boundary detection.
* @param {boolean} [options.autoScrollBottom=true] - Whether to auto-scroll to bottom on layout updates.
* @param {boolean} [options.observeMutations=true] - Enables MutationObserver to detect DOM changes.
* @param {boolean} [options.preserveScrollOnLayoutShift=true] - Prevents scroll jumps when layout changes.
* @param {number} [options.debounceTime=100] - Debounce time in milliseconds for scroll events.
* @param {string|null} [options.querySelector=null] - Optional CSS selector to filter observed child nodes.
* @param {string[]|Set<string>|null} [options.attributeFilter=['class', 'style', 'src', 'data-*', 'height', 'width']]
* - Which attributes to observe for changes.
*/
constructor(target: Element | Window, { extraScrollBoundary, autoScrollBottom, observeMutations, preserveScrollOnLayoutShift, debounceTime, querySelector, attributeFilter, }?: {
extraScrollBoundary?: number | undefined;
autoScrollBottom?: boolean | undefined;
observeMutations?: boolean | undefined;
preserveScrollOnLayoutShift?: boolean | undefined;
debounceTime?: number | undefined;
querySelector?: string | null | undefined;
attributeFilter?: string[] | Set<string> | null | undefined;
});
/**
* Enables or disables throwing an error when the maximum number of listeners is exceeded.
*
* @param {boolean} shouldThrow - If true, an error will be thrown when the max is exceeded.
*/
setThrowOnMaxListeners(shouldThrow: boolean): void;
/**
* Checks whether an error will be thrown when the max listener limit is exceeded.
*
* @returns {boolean} True if an error will be thrown, false if only a warning is shown.
*/
getThrowOnMaxListeners(): boolean;
/**
* Adds a listener to the beginning of the listeners array for the specified event.
*
* @param {string} event - Event name.
* @param {ScrollListenersFunc} handler - The callback function.
*/
prependListener(event: string, handler: ScrollListenersFunc): void;
/**
* Adds a one-time listener to the beginning of the listeners array for the specified event.
*
* @param {string} event - Event name.
* @param {ScrollListenersFunc} handler - The callback function.
* @returns {ScrollListenersFunc} - The wrapped handler used internally.
*/
prependListenerOnce(event: string, handler: ScrollListenersFunc): ScrollListenersFunc;
/**
* Adds a event listener.
*
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
* @param {ScrollListenersFunc} handler - Callback function to be called when event fires.
*/
appendListener(event: string, handler: ScrollListenersFunc): void;
/**
* Registers an event listener that runs only once, then is removed.
*
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
* @param {ScrollListenersFunc} handler - The callback function to run on event.
* @returns {ScrollListenersFunc} - The wrapped version of the handler.
*/
appendListenerOnce(event: string, handler: ScrollListenersFunc): ScrollListenersFunc;
/**
* Adds a event listener.
*
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
* @param {ScrollListenersFunc} handler - Callback function to be called when event fires.
*/
on(event: string, handler: ScrollListenersFunc): void;
/**
* Registers an event listener that runs only once, then is removed.
*
* @param {string} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
* @param {ScrollListenersFunc} handler - The callback function to run on event.
* @returns {ScrollListenersFunc} - The wrapped version of the handler.
*/
once(event: string, handler: ScrollListenersFunc): ScrollListenersFunc;
/**
* Removes a previously registered event listener.
*
* @param {string} event - The name of the event to remove the handler from.
* @param {ScrollListenersFunc} handler - The specific callback function to remove.
*/
off(event: string, handler: ScrollListenersFunc): void;
/**
* Removes all event listeners of a specific type from the element.
*
* @param {string} event - The event type to remove (e.g. 'onScrollBoundary').
*/
offAll(event: string): void;
/**
* Removes all event listeners of all types from the element.
*/
offAllTypes(): void;
/**
* Returns the number of listeners for a given event.
*
* @param {string} event - The name of the event.
* @returns {number} Number of listeners for the event.
*/
listenerCount(event: string): number;
/**
* Returns a copy of the array of listeners for the specified event.
*
* @param {string} event - The name of the event.
* @returns {ScrollListenersFunc[]} Array of listener functions.
*/
listeners(event: string): ScrollListenersFunc[];
/**
* Returns a copy of the array of listeners for the specified event.
*
* @param {string} event - The name of the event.
* @returns {ScrollListenersFunc[]} Array of listener functions.
*/
onceListeners(event: string): ScrollListenersFunc[];
/**
* Returns a copy of the internal listeners array for the specified event,
* including wrapper functions like those used by `.once()`.
* @param {string | symbol} event - The event name.
* @returns {ScrollListenersFunc[]} An array of raw listener functions.
*/
allListeners(event: string | symbol): ScrollListenersFunc[];
/**
* Returns an array of event names for which there are registered listeners.
*
* @returns {string[]} Array of registered event names.
*/
eventNames(): string[];
/**
* Emits an event, triggering all registered handlers for that event.
*
* @param {string} event - The event name to emit.
* @param {...any} payload - Optional data to pass to each handler.
* @returns {boolean} True if any listeners were called, false otherwise.
*/
emit(event: string, ...payload: any[]): boolean;
/**
* Sets the maximum number of listeners per event before a warning is shown.
*
* @param {number} n - The maximum number of listeners.
*/
setMaxListeners(n: number): void;
/**
* Gets the maximum number of listeners allowed per event.
*
* @returns {number} The maximum number of listeners.
*/
getMaxListeners(): number;
/**
* Returns a size difference callback that only reacts when height changes, filtered by tag name.
*
* @param {string[]} filter - List of tag names to allow. If empty, all tags are accepted.
* @returns {NodeSizesEvent} A function that compares previous and current height, returning height delta.
*/
getSimpleOnHeight(filter?: string[]): NodeSizesEvent;
/**
* Adds a height difference callback to the size filter system.
*
* @param {string[]} filter - List of tag names to allow.
* @returns {NodeSizesEvent} The added size difference callback.
*/
addSimpleOnHeight(filter: string[]): NodeSizesEvent;
/**
* Returns a list of all currently tracked load tags.
*
* @returns {string[]} Array of tag names.
*/
getLoadTags(): string[];
/**
* Adds a new tag to the set of load tags.
*
* @param {string} tag - The tag name to add (e.g., 'IMG').
*/
addLoadTag(tag: string): void;
/**
* Removes a tag from the set of load tags.
*
* @param {string} tag - The tag name to remove.
*/
removeLoadTag(tag: string): void;
/**
* Checks whether a tag is tracked as a load tag.
*
* @param {string} tag - The tag name to check.
* @returns {boolean} True if the tag is being tracked.
*/
hasLoadTag(tag: string): boolean;
/**
* Clears the set of load tags. If `addDefault` is true, it will reset to the default tags: 'IMG', 'IFRAME', and 'VIDEO'.
*
* @param {boolean} [addDefault=false] - Whether to restore the default tags after clearing.
* @throws {TypeError} If `addDefault` is not a boolean.
*/
resetLoadTags(addDefault?: boolean): void;
/**
* Returns a list of all currently tracked attribute filters.
*
* @returns {string[]} Array of attribute names.
*/
getAttributeFilters(): string[];
/**
* Adds an attribute to the filter list.
*
* @param {string} attr - The attribute name to add.
*/
addAttributeFilter(attr: string): void;
/**
* Removes an attribute from the filter list.
*
* @param {string} attr - The attribute name to remove.
*/
removeAttributeFilter(attr: string): void;
/**
* Checks whether a specific attribute is being filtered.
*
* @param {string} attr - The attribute name to check.
* @returns {boolean} True if the attribute is being filtered.
*/
hasAttributeFilter(attr: string): boolean;
/**
* Clears the set of observed attribute filters. If `addDefault` is true, it will reset to the default attributes:
* 'class', 'style', 'src', 'data-*', 'height', and 'width'.
*
* @param {boolean} [addDefault=false] - Whether to restore the default attribute filters after clearing.
* @throws {TypeError} If `addDefault` is not a boolean.
*/
resetAttributeFilters(addDefault?: boolean): void;
/**
* Registers a custom node size change handler to the internal size filter set.
*
* @param {NodeSizesEvent} handler - Function that compares old and new sizes.
*/
onSize(handler: NodeSizesEvent): void;
/**
* Unregisters a previously registered size handler from the internal filter set.
*
* @param {NodeSizesEvent} handler - The handler function to remove.
*/
offSize(handler: NodeSizesEvent): void;
/**
* Checks which elements inside the target are currently visible and updates internal maps.
*
* @returns {Map<Element, { oldIsVisible: boolean; isVisible: boolean }>} Visibility comparison results.
*/
_scrollDataUpdater(): Map<Element, {
oldIsVisible: boolean;
isVisible: boolean;
}>;
/**
* Emits a scroll-related event to all registered listeners.
*
* @param {string} event - Event name.
* @param {*} [payload] - Optional event data payload.
* @deprecated - Use emit() instead.
*/
_emit(event: string, payload?: any): void;
/**
* Handles scroll events, calculates position-related statuses, and emits appropriate events.
*/
_onScroll(): void;
/**
* Attempts to correct the scroll position when layout shifts happen, preserving the user position if needed.
*
* @param {Element[]} [targets=[]] - List of elements involved in the size change.
*/
_fixScroll(targets?: Element[]): void;
/**
* Sets up a MutationObserver to watch for DOM changes and react accordingly to maintain scroll consistency.
*/
_observeMutations(): void;
/**
* Adds a ResizeObserver to monitor elements' size changes and trigger layout adjustments.
*
* @param {NodeListOf<Element>|Element[]|HTMLCollection} elements - Elements to observe.
*/
_observeResizes(elements: NodeListOf<Element> | Element[] | HTMLCollection): void;
/**
* Listens for media/content load events (e.g., images, iframes, videos) to trigger scroll updates.
*
* @param {NodeListOf<Element>|Element} elements - Target element(s) to listen on.
*/
_listenLoadEvents(elements: NodeListOf<Element> | Element): void;
/**
* Returns the internal scroll container element being monitored.
*
* @returns {Element} The DOM element used as the scroll container target.
*/
get target(): Element;
/**
* Returns the previous size of a given element, or undefined if not tracked.
*
* @param {Element} el - The DOM element to query.
* @returns {NodeSizes|null} The old size, or undefined.
*/
getOldSize(el: Element): NodeSizes | null;
/**
* Returns the current size of a given element, or undefined if not tracked.
*
* @param {Element} el - The DOM element to query.
* @returns {NodeSizes|null} The new size, or undefined.
*/
getNewSize(el: Element): NodeSizes | null;
/**
* Returns whether the given element was visible in the last scroll update.
*
* @param {Element} el - The DOM element to check.
* @returns {boolean} True if visible, false if not, or undefined if not tracked.
*/
wasVisible(el: Element): boolean;
/**
* Returns whether the given element is currently visible.
*
* @param {Element} el - The DOM element to check.
* @returns {boolean} True if visible, false if not, or undefined if not tracked.
*/
isVisible(el: Element): boolean;
/**
* Returns whether the element was visible in the last time-based visibility check.
*
* @param {Element} el - The DOM element to check.
* @returns {boolean} Visibility state from the previous timed check.
*/
wasTimedVisible(el: Element): boolean;
/**
* Returns whether the element is currently visible in the time-based check.
*
* @param {Element} el - The DOM element to check.
* @returns {boolean} Visibility state from the current timed check.
*/
isTimedVisible(el: Element): boolean;
/**
* Sets the extra scroll boundary margin used when determining if the user is at a "custom" bottom or top.
*
* @param {number} value - Pixels of additional margin to use.
*/
setExtraScrollBoundary(value: number): void;
/**
* Returns the current extra scroll boundary setting.
*
* @returns {number}
*/
getExtraScrollBoundary(): number;
/**
* Returns the last known distance (in pixels) from the bottom of the scroll container.
*
* @returns {number}
*/
getLastKnownScrollBottomOffset(): number;
/**
* Forces the scroll position to move to the very bottom of the target.
*/
scrollToBottom(): void;
/**
* Forces the scroll position to move to the very top of the target.
*/
scrollToTop(): void;
/**
* Checks if the user is within the defined extra scroll boundary from the bottom.
*
* @returns {boolean}
*/
isAtCustomBottom(): boolean;
/**
* Checks if the user is within the defined extra scroll boundary from the top.
*
* @returns {boolean}
*/
isAtCustomTop(): boolean;
/**
* Returns true if the user is currently scrolled to the bottom of the element.
*
* @returns {boolean}
*/
isAtBottom(): boolean;
/**
* Returns true if the user is currently scrolled to the top of the element.
*
* @returns {boolean}
*/
isAtTop(): boolean;
/**
* Returns true if the user has already passed beyond the bottom boundary at some point.
*
* @returns {boolean}
*/
isPastAtBottom(): boolean;
/**
* Returns true if the user has already passed beyond the top boundary at some point.
*
* @returns {boolean}
*/
isPastAtTop(): boolean;
/**
* Returns true if the user has passed beyond the defined extra scroll boundary from the top at some point.
*
* @returns {boolean}
*/
isPastAtCustomTop(): boolean;
/**
* Returns true if the user has passed beyond the defined extra scroll boundary from the bottom at some point.
*
* @returns {boolean}
*/
isPastAtCustomBottom(): boolean;
/**
* Checks if the user is within the defined extra scroll boundary from the bottom.
*
* @returns {boolean}
* @deprecated - Use isAtCustomBottom instead.
*/
isUserAtCustomBottom(): boolean;
/**
* Checks if the user is within the defined extra scroll boundary from the top.
*
* @returns {boolean}
* @deprecated - Use isAtCustomTop instead.
*/
isUserAtCustomTop(): boolean;
/**
* Returns true if the user is currently scrolled to the bottom of the element.
*
* @returns {boolean}
* @deprecated - Use isAtBottom instead.
*/
isUserAtBottom(): boolean;
/**
* Returns true if the user is currently scrolled to the top of the element.
*
* @returns {boolean}
* @deprecated - Use isAtTop instead.
*/
isUserAtTop(): boolean;
/**
* Returns true if automatic scrolling is currently paused.
*
* @returns {boolean}
*/
isScrollPaused(): boolean;
/**
* Returns whether the target is the window object.
*
* @returns {boolean} True if the scroll target is window, false otherwise.
*/
isWindow(): boolean;
/**
* Returns whether the instance has been destroyed.
*
* @returns {boolean} True if the instance is destroyed, false otherwise.
*/
isDestroyed(): boolean;
/**
* Returns whether auto-scroll-to-bottom is enabled.
*
* @returns {boolean} True if auto-scroll is active, false otherwise.
*/
getAutoScrollBottom(): boolean;
/**
* Returns whether MutationObserver is enabled.
*
* @returns {boolean} True if mutation observation is active, false otherwise.
*/
getObserveMutations(): boolean;
/**
* Returns whether layout shift protection is enabled.
*
* @returns {boolean} True if scroll preservation is active, false otherwise.
*/
getPreserveScrollOnLayoutShift(): boolean;
/**
* Returns the debounce delay in milliseconds used for scroll events.
*
* @returns {number} Debounce delay time.
*/
getDebounceTime(): number;
/**
* Returns the current number of matching elements observed inside the scroll target.
*
* @returns {number} Current count of matching elements.
*/
getElemAmount(): number;
/**
* Returns the previous known count of matching elements from the last update.
*
* @returns {number} Previous count of matching elements.
*/
getPrevElemAmount(): number;
/**
* Returns the query selector string used to filter observed elements.
*
* @returns {string} The CSS selector string, or an empty string if none was provided.
*/
getQuerySelector(): string;
/**
* Disconnects all listeners, observers, and clears memory structures.
* Once destroyed, this instance should no longer be used.
*/
destroy(): void;
#private;
}
import TinyHtml from './TinyHtml.mjs';
import * as TinyCollision from '../basics/collision.mjs';
//# sourceMappingURL=TinySmartScroller.d.mts.map