Skip to content
Draft
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"@jupyterlab/services": "^7.0.0",
"@jupyterlab/ui-components": "^4.4.10",
"@lumino/datagrid": "^2.5.3",
"@lumino/polling": "^2.1.5",
"@lumino/widgets": "^2.7.1",
"apache-arrow": "^21.1.0"
},
Expand Down
48 changes: 48 additions & 0 deletions src/widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,60 @@ import {
DataGrid,
TextRenderer,
} from "@lumino/datagrid";
import { ConflatableMessage, MessageLoop } from "@lumino/messaging";
import { Debouncer } from "@lumino/polling";
import { Panel } from "@lumino/widgets";
import type { DocumentRegistry, IDocumentWidget } from "@jupyterlab/docregistry";
import type * as DataGridModule from "@lumino/datagrid";
import type { ISignal } from "@lumino/signaling";
import type { ScrollBar } from "@lumino/widgets";

import { FileType } from "./file-types";
import { ArrowModel } from "./model";
import { createToolbar } from "./toolbar";
import type { FileInfo, FileReadOptions } from "./file-options";

/* grid: DataGrid instance */

function installDebouncedScrollBarHook(grid: DataGrid, delay = 100) {
// Access the internal vertical scrollbar and its thumbMoved signal
// biome-ignore lint/suspicious/noExplicitAny: Hacking into private property
const vScrollBar = (grid as any)._vScrollBar as ScrollBar;
// biome-ignore lint/suspicious/noExplicitAny: Hacking into private property
const thumbMoved = (vScrollBar as any).thumbMoved as ISignal<ScrollBar, void>;

// Get the original handler method from the grid
// biome-ignore lint/suspicious/noExplicitAny: Hacking into private property
const originalHandler = (grid as any)._onThumbMoved as (sender: ScrollBar) => void;

// Disconnect the original handler
thumbMoved.disconnect(originalHandler, grid);

// Create a debouncer that posts the scroll request after the delay
// The debouncer ensures the last event is always processed
const debouncer = new Debouncer(() => {
MessageLoop.postMessage(grid.viewport, new ConflatableMessage("scroll-request"));
}, delay);

// Handler that invokes the debouncer on each thumb move
const debouncedHandler = () => {
void debouncer.invoke();
};

// Connect our debounced handler
thumbMoved.connect(debouncedHandler);

// Return cleanup function
return () => {
// Disconnect our handler
thumbMoved.disconnect(debouncedHandler);
// Reconnect the original handler
thumbMoved.connect(originalHandler, grid);
// Dispose the debouncer
debouncer.dispose();
};
}

export namespace ArrowGridViewer {
export interface Options {
path: string;
Expand Down Expand Up @@ -51,6 +96,9 @@ export class ArrowGridViewer extends Panel {
};

this.addWidget(this._grid);

installDebouncedScrollBarHook(this._grid, 100);

this._ready = this.initialize();
}

Expand Down
12 changes: 12 additions & 0 deletions yarn.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading