fix(grid): improve scrolling and sidebar responsiveness

This commit is contained in:
juve authored and GitHub committed 2026-07-13 16:12:54 +08:00
1 parent 67541232a2
commit 29b351691a
8 files changed
+142 -41

No files matched your search

@@ -381,16 +381,14 @@ export function drawCanvasDataGrid(options: DrawCanvasDataGridOptions) {
ctx.font = value === null ? italicFont : tabularFont;
setCanvasNumericVariant(ctx, value === null ? "normal" : "tabular-nums");
const textLeft = alignCanvasPixel(drawX + 12, dpr);
const paddedMaxWidth = Math.max(0, drawX + colWidth - textLeft - 12);
const cellMaxWidth = Math.max(0, colWidth - 24);
const isEditingThisCell = editingCell?.rowId === item.id && editingCell.col === actualColIdx;
const rawDisplayText = item.isDraft && value === null ? (draftCellPlaceholder ?? "") : formatCell(value, actualColIdx);
const displayText = isEditingThisCell ? "" : firstLineCellDisplayValue(rawDisplayText);
const needsTruncation = ctx.measureText(displayText).width > paddedMaxWidth;
const textMaxWidth = needsTruncation ? Math.max(0, drawX + colWidth - textLeft) : paddedMaxWidth;
const text = isEditingThisCell ? displayText : fitCanvasText(ctx, displayText, textMaxWidth - 12);
const text = isEditingThisCell ? displayText : fitCanvasText(ctx, displayText, cellMaxWidth);
ctx.fillText(text, textLeft, textY);
if (item.isDeleted && text) {
const textWidth = Math.min(ctx.measureText(text).width, textMaxWidth);
const textWidth = ctx.measureText(text).width;
ctx.strokeStyle = theme.foreground;
ctx.beginPath();
ctx.moveTo(textLeft, textY);
@@ -0,0 +1,40 @@
export type SidebarPasteHandler = () => void;
export interface SidebarPasteHandlerRegistry {
register: (nodeId: string, handler: SidebarPasteHandler) => () => void;
request: (nodeId: string) => boolean;
}
export function createSidebarPasteHandlerRegistry(): SidebarPasteHandlerRegistry {
const handlersByNodeId = new Map<string, Set<SidebarPasteHandler>>();
function register(nodeId: string, handler: SidebarPasteHandler) {
let handlers = handlersByNodeId.get(nodeId);
if (!handlers) {
handlers = new Set();
handlersByNodeId.set(nodeId, handlers);
}
handlers.add(handler);
return () => {
const currentHandlers = handlersByNodeId.get(nodeId);
if (!currentHandlers) return;
currentHandlers.delete(handler);
if (currentHandlers.size === 0) handlersByNodeId.delete(nodeId);
};
}
function request(nodeId: string): boolean {
const handlers = handlersByNodeId.get(nodeId);
if (!handlers?.size) return false;
// The sticky database row may duplicate a virtualized row. Prefer the most
// recently registered live instance while keeping older owners as fallback.
let activeHandler: SidebarPasteHandler | undefined;
for (const handler of handlers) activeHandler = handler;
activeHandler?.();
return true;
}
return { register, request };
}
@@ -5,6 +5,7 @@ export interface SidebarTreeContext {
getVisibleNodes: () => TreeNode[];
getVisibleNodeIndex: (id: string) => number;
setTableSearchQuery?: (parentNodeId: string, query: string) => void;
registerPasteHandler?: (nodeId: string, callback: () => void) => () => void;
}
export const sidebarTreeContextKey: InjectionKey<SidebarTreeContext> = Symbol("sidebar-tree-context");