feat(joint-core): add paper eventSurface option - #3441
Open
kumilingus wants to merge 1 commit into
Open
Conversation
DOM content rendered into `paper.el` - a ruler, a gutter, a toolbar - is only half
interactive. A press on it opens a blank interaction, but every other handler runs
`guard()`, which rejects a target that is not on the paper's event surface, so the
same content gets no `blank:pointerclick` and no hover events.
`eventSurface` declares such a subtree part of the surface, and every handler then
treats it as a blank area:
new dia.Paper({ eventSurface: '.ruler' })
It takes a CSS selector (matched with `closest`, so it covers any number of
subtrees), an element, an array of elements, or a `function(target) { ... }`.
`guard` is consulted before the surface test, so the two compose in opposite
directions: `eventSurface` opens a subtree, `guard` still closes single events
within it - surface a ruler, then veto wheel events on it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
kumilingus
force-pushed
the
feat/event-surface-option
branch
from
July 29, 2026 08:40
5ce7b9e to
24e4eb1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Independent of #3438 — one commit, joint-core only, based on
dev.The gap
DOM content rendered into
paper.el— a ruler, a gutter, a toolbar — is only half interactive. A press on it opens a blank interaction, but every other handler runs the fullguard(), which rejects a target that is not on the paper's event surface. So the same content getsblank:pointerdownand the drag that follows it, but noblank:pointerclickand no hover events.The option
eventSurfacedeclares a DOM subtree part of the paper's interaction surface, and every handler then treats it as a blank area. It accepts:closest, so it covers any number of subtrees(target) => booleanHow it composes
options.guardis consulted before the surface test, so the two hooks work in opposite directions and cover the whole space:eventSurfaceopens a subtree,guardstill closes individual events within it. Surface a ruler, then veto wheel events on it — neither hook alone can express that.Scope worth knowing: the option only ever widens. It cannot exclude anything — that is
guard— and pointing it outsidepaper.elis inert, because the paper's handlers are delegated onpaper.eland never see those events.Tests
eventSurfacegesture (hover and click appear only once surfaced), the drag through a surfaced subtree, all four option forms, and a non-element targettest:tsand lint cleanRelation to #3438
Independent — the two touch
guard()in the same region, so whichever lands second needs a trivial rebase.One follow-up belongs after both: joint-react's paper preset keeps portaled
<Paper>children off the event surface (#3438), and should defer to this option so an overlay meant to drive the canvas can say so. That is a one-line change to the preset'sguardExplicitoverride and is deliberately not in either PR, since it needs both.🤖 Generated with Claude Code