Implement ClickEvent.getRelativeX() and getRelativeY() methods
Adds relative coordinate methods to ClickEvent that provide mouse coordinates relative to the clicked component, restoring functionality that was available in Vaadin 8's MouseEvents.getRelativeY().
Problem
Vaadin 23's ClickEvent only provides screenX/Y (relative to screen) and clientX/Y (relative to viewport) coordinates. There was no way to get coordinates relative to the clicked component itself, which is essential for components like scrollbars, drawing areas, and overview maps where precise positioning within the component matters.
The current workaround required additional server roundtrips:
div.addClickListener(e -> {
div.getElement().executeJs("return this.getBoundingClientRect().top;").then(Double.class, viewportY ->
Notification.show("" + (e.clientY - viewportY)"));
});
Solution
Added getRelativeX() and getRelativeY() methods that calculate coordinates relative to the component's top-left corner using client-side JavaScript expressions:
div.addClickListener(event -> {
int relativeX = event.getRelativeX(); // Position within the component
int relativeY = event.getRelativeY(); // Position within the component
// Perfect for scrollbar controls, drawing components, etc.
});
Implementation Details
-
Zero performance overhead: Coordinates calculated during event processing using
@EventDataannotations -
Client-side calculation: Uses
element.getBoundingClientRect()to determine component position -
Consistent API: Follows same pattern as existing
getClientX/Y()andgetScreenX/Y()methods - Backward compatible: All existing code continues to work unchanged
Changes Made
- Added
relativeXandrelativeYfields toClickEvent - Updated constructor with
@EventDataannotations using JavaScript expressions:-
event.clientX - element.getBoundingClientRect().leftfor relativeX -
event.clientY - element.getBoundingClientRect().topfor relativeY
-
- Added
getRelativeX()andgetRelativeY()getter methods with proper Javadoc - Comprehensive test coverage for both server-side and client-side constructors
- Demo view showing all coordinate types in action
This directly addresses the customer use case mentioned in the issue - building scrollbar-like components and overview maps that need precise positioning within the component area.
Fixes #20488.
[!WARNING]
Firewall rules blocked me from connecting to one or more addresses
I tried to connect to the following addresses, but was blocked by firewall rules:
maven.vaadin.com
- Triggering command:
/usr/lib/jvm/temurin-17-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.10/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.10/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.10 -Dlibrary.jansi.path=/usr/share/apache-maven-3.9.10/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/flow/flow org.codehaus.plexus.classworlds.launcher.Launcher -q test-compile -pl flow-server(dns block)- Triggering command:
/usr/lib/jvm/temurin-17-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.10/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.10/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.10 -Dlibrary.jansi.path=/usr/share/apache-maven-3.9.10/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/flow/flow org.codehaus.plexus.classworlds.launcher.Launcher -q compile -Dmaven.test.skip=true(dns block)If you need me to access, download, or install something from one of these locations, you can either:
- Configure Actions setup steps to set up my environment, which run before the firewall is enabled
- Add the appropriate URLs or hosts to my firewall allow list
π‘ You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.
[!WARNING]
Firewall rules blocked me from connecting to one or more addresses
I tried to connect to the following addresses, but was blocked by firewall rules:
maven.vaadin.com
- Triggering command:
/usr/lib/jvm/temurin-17-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.10/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.10/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.10 -Dlibrary.jansi.path=/usr/share/apache-maven-3.9.10/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/flow/flow org.codehaus.plexus.classworlds.launcher.Launcher test -Dtest=ClickEventTest -pl flow-server(dns block)If you need me to access, download, or install something from one of these locations, you can either:
- Configure Actions setup steps to set up my environment, which run before the firewall is enabled
- Add the appropriate URLs or hosts to my firewall allow list
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.
[!WARNING]
Firewall rules blocked me from connecting to one or more addresses
I tried to connect to the following addresses, but was blocked by firewall rules:
maven.vaadin.com
- Triggering command:
/usr/lib/jvm/temurin-17-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.10/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.10/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.10 -Dlibrary.jansi.path=/usr/share/apache-maven-3.9.10/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/flow/flow org.codehaus.plexus.classworlds.launcher.Launcher -q compile test-compile -pl flow-tests/test-root-context(dns block)If you need me to access, download, or install something from one of these locations, you can either:
- Configure Actions setup steps to set up my environment, which run before the firewall is enabled
- Add the appropriate URLs or hosts to my firewall allow list
Test Results
1β049 filesβ β-β257ββ1β049 suitesβ β-β257βββ1h 3m 27s β±οΈ - 13m 17s 8β555 tests β-β616ββ8β012 β β-β1β092ββ63 π€ β-ββ4ββ51 β +51ββ429 π₯ +429β 8β646 runsβ β-β987ββ8β021 β β-β1β537ββ58 π€ β-β17ββ73 β +73ββ494 π₯ +494β
For more details on these failures and errors, see this check.
Results for commit 55056810.βΒ± Comparison against base commit 61ea69f1.
This pull request removes 621 and adds 5 tests. Note that renamed tests count towards both.
com.vaadin.flow.component.littemplate.BundleLitParserTest β parseTemplate
com.vaadin.flow.component.littemplate.BundleLitParserTest β parseTemplateWithComments_commentsProperlyIgnored
com.vaadin.flow.component.littemplate.BundleLitParserTest β parseTemplate_codeInRenderBeforeHtml_templateProperlyParsed
com.vaadin.flow.component.littemplate.BundleLitParserTest β parseTemplate_codeWithHtmlAfterRender_templateProperlyParsed
com.vaadin.flow.component.littemplate.BundleLitParserTest β parseTemplate_codeWithHtmlBeforeRender_templateProperlyParsed
com.vaadin.flow.component.littemplate.InjectableLitElementInitializerTest β initializeElement_disabled_exceptionIsThrown
com.vaadin.flow.component.littemplate.InjectableLitElementInitializerTest β initializeElement_setAttributeBinding_attributeIsIgnored
com.vaadin.flow.component.littemplate.InjectableLitElementInitializerTest β initializeElement_setClass_classIsSetAsAttribute
com.vaadin.flow.component.littemplate.InjectableLitElementInitializerTest β initializeElement_setDynamicValue_attributeIsIgnored
com.vaadin.flow.component.littemplate.InjectableLitElementInitializerTest β initializeElement_setHref_hrefIsSetAsAttribute
β¦
com.vaadin.flow.component.ClickEventTest β clientSideConstructor
com.vaadin.flow.component.ClickEventTest β oldClientSideConstructorBackwardCompatibility
com.vaadin.flow.component.ClickEventTest β relativeCoordinatesAreDistinctFromOtherCoordinates
com.vaadin.flow.component.ClickEventTest β serverSideConstructor
com.vaadin.flow.uitest.ui.RelativeCoordinatesIT β clickShowsRelativeCoordinates[any_Chrome_]
:recycle: This comment has been updated with latest results.
Format Checker Report
There are 4 files with format errors
-
To see a complete report of formatting issues, download the differences artifact
-
To fix the build, please run
mvn spotless:applyin your branch and commit the changes. -
Optionally you might add the following line in your
.git/hooks/pre-commitfile:mvn spotless:apply
Here is the list of files with format issues in your PR:
flow-server/src/main/java/com/vaadin/flow/component/ClickEvent.java
flow-server/src/test/java/com/vaadin/flow/component/ClickEventTest.java
flow-tests/test-root-context/src/main/java/com/vaadin/flow/uitest/ui/RelativeCoordinatesView.java
flow-tests/test-root-context/src/test/java/com/vaadin/flow/uitest/ui/RelativeCoordinatesIT.java
Quality Gate passed
Issues
0 New issues
0 Accepted issues
Measures
0 Security Hotspots
0.0% Coverage on New Code
0.0% Duplication on New Code