feat: add scrollbar and fix selection on scroll

This commit is contained in:
Brooklyn Nicholson 2026-04-14 14:34:33 -05:00
parent 9804aa7443
commit 52c11d172a
10 changed files with 397 additions and 126 deletions

View file

@ -1,6 +1,7 @@
import type { DOMElement } from './dom.js'
import { ClickEvent } from './events/click-event.js'
import type { EventHandlerProps } from './events/event-handlers.js'
import { MouseEvent } from './events/mouse-event.js'
import { nodeCache } from './node-cache.js'
/**
@ -101,6 +102,51 @@ export function dispatchClick(root: DOMElement, col: number, row: number, cellIs
return handled
}
type MouseHandler = 'onMouseDown' | 'onMouseUp' | 'onMouseDrag'
export function dispatchMouse(
root: DOMElement,
col: number,
row: number,
handlerName: MouseHandler,
button: number,
cellIsBlank = false,
target?: DOMElement
): DOMElement | undefined {
let node: DOMElement | undefined = target ?? hitTest(root, col, row) ?? undefined
if (!node) {
return undefined
}
const event = new MouseEvent(col, row, cellIsBlank, button)
let handled: DOMElement | undefined
while (node) {
const handler = node._eventHandlers?.[handlerName] as ((event: MouseEvent) => void) | undefined
if (handler) {
handled ??= node
const rect = nodeCache.get(node)
if (rect) {
event.localCol = col - rect.x
event.localRow = row - rect.y
}
handler(event)
if (event.didStopImmediatePropagation()) {
return handled
}
}
node = node.parentNode
}
return handled
}
/**
* Fire onMouseEnter/onMouseLeave as the pointer moves. Like DOM
* mouseenter/mouseleave: does NOT bubble moving between children does