Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,12 @@
},
"dependencies": {
"blurhash": "2.0.5",
"lodash.debounce": "4.0.8",
"react-merge-refs": "2.1.1",
"thumbhash": "0.1.1"
},
"devDependencies": {
"@splinetool/runtime": "^1.10.29",
"@types/animejs": "^3.1.12",
"@types/lodash.debounce": "^4.0.9",
"@types/node": "^20.14.1",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
Expand Down
2 changes: 1 addition & 1 deletion src/ParentSize.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Modified version of
// https://github.com/airbnb/visx/blob/master/packages/visx-responsive/src/components/ParentSize.tsx
'use client';
import debounce from 'lodash.debounce';
import debounce from './debounce';
import { forwardRef, useEffect, useMemo, useRef, useState } from 'react';
import { mergeRefs } from 'react-merge-refs';

Expand Down
71 changes: 71 additions & 0 deletions src/debounce.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
type DebouncedFunction<T extends (...args: any[]) => void> = T & {
cancel: () => void;
};

/**
* Lightweight debounce utility replacing lodash.debounce.
*
* Supports:
* - Trailing-only (default): fires after `delay` ms of inactivity
* - Leading+trailing: fires immediately on first call, then once more
* on trailing edge if additional calls occurred during the delay
* - cancel(): clears pending invocation and resets all state
*
* NOT supported (not needed by ParentSize):
* - { trailing: false } option
* - maxWait
* - flush() / pending()
*/
export default function debounce<T extends (...args: any[]) => void>(
fn: T,
delay: number,
{ leading = false }: { leading?: boolean } = {}
): DebouncedFunction<T> {
let timeoutId: ReturnType<typeof setTimeout> | undefined;
let isLeadingInvoked = false;
let lastThis: unknown;
let lastArgs: Parameters<T> | undefined;

const debounced = function (this: unknown, ...args: Parameters<T>) {
lastThis = this;
lastArgs = args;

if (leading && !isLeadingInvoked) {
isLeadingInvoked = true;
fn.apply(this, args);
lastArgs = undefined; // Clear so we can detect subsequent calls
}

if (timeoutId !== undefined) {
clearTimeout(timeoutId);
}

timeoutId = setTimeout(() => {
const thisCtx = lastThis;
const thisArgs = lastArgs;
// Reset state BEFORE calling fn so re-entrant calls work correctly
isLeadingInvoked = false;
timeoutId = undefined;
lastArgs = undefined;

if (!leading && thisArgs !== undefined) {
fn.apply(thisCtx, thisArgs);
} else if (thisArgs !== undefined) {
// Leading+trailing: only fire trailing if there were calls after the leading
fn.apply(thisCtx, thisArgs);
}
}, delay);
} as DebouncedFunction<T>;

debounced.cancel = () => {
if (timeoutId !== undefined) {
clearTimeout(timeoutId);
}
timeoutId = undefined;
isLeadingInvoked = false;
lastArgs = undefined;
lastThis = undefined;
};

return debounced;
}
1 change: 0 additions & 1 deletion vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ export default defineConfig({
'next/image',
// these are the dependencies, they are listed in the package.json already
'blurhash',
'lodash.debounce',
'react-merge-refs',
'thumbhash',
],
Expand Down
25 changes: 0 additions & 25 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1095,14 +1095,12 @@ __metadata:
dependencies:
"@splinetool/runtime": ^1.10.29
"@types/animejs": ^3.1.12
"@types/lodash.debounce": ^4.0.9
"@types/node": ^20.14.1
"@types/react": ^18.3.3
"@types/react-dom": ^18.3.0
"@vitejs/plugin-react": ^4.3.0
animejs: ^3.2.2
blurhash: 2.0.5
lodash.debounce: 4.0.8
modern-normalize: ^1.1.0
next: 15.0.0-rc.0
np: ^10.0.5
Expand Down Expand Up @@ -1223,22 +1221,6 @@ __metadata:
languageName: node
linkType: hard

"@types/lodash.debounce@npm:^4.0.9":
version: 4.0.9
resolution: "@types/lodash.debounce@npm:4.0.9"
dependencies:
"@types/lodash": "*"
checksum: 8183a152e01928e3b97ca773f6ae6038b8695e76493ba8bf6b743ec143948a62294fbc9d49fa4a78b52265b3ba4892ef57534e0c13d04aa0f111671b5a944feb
languageName: node
linkType: hard

"@types/lodash@npm:*":
version: 4.14.191
resolution: "@types/lodash@npm:4.14.191"
checksum: ba0d5434e10690869f32d5ea49095250157cae502f10d57de0a723fd72229ce6c6a4979576f0f13e0aa9fbe3ce2457bfb9fa7d4ec3d6daba56730a51906d1491
languageName: node
linkType: hard

"@types/node@npm:^20.14.1":
version: 20.14.1
resolution: "@types/node@npm:20.14.1"
Expand Down Expand Up @@ -3545,13 +3527,6 @@ __metadata:
languageName: node
linkType: hard

"lodash.debounce@npm:4.0.8":
version: 4.0.8
resolution: "lodash.debounce@npm:4.0.8"
checksum: a3f527d22c548f43ae31c861ada88b2637eb48ac6aa3eb56e82d44917971b8aa96fbb37aa60efea674dc4ee8c42074f90f7b1f772e9db375435f6c83a19b3bc6
languageName: node
linkType: hard

"lodash.zip@npm:^4.2.0":
version: 4.2.0
resolution: "lodash.zip@npm:4.2.0"
Expand Down