Skip to content

Add Vaadin 25 support while maintaining Vaadin 24 compatibility#28

Merged
javier-godoy merged 7 commits intomasterfrom
vaadin-25-support2
Mar 17, 2026
Merged

Add Vaadin 25 support while maintaining Vaadin 24 compatibility#28
javier-godoy merged 7 commits intomasterfrom
vaadin-25-support2

Conversation

@javier-godoy
Copy link
Member

@javier-godoy javier-godoy commented Mar 16, 2026

This PR adds Vaadin 25 compatibility while maintaining support for Vaadin 24, along with several refactorings and demo improvements. (Rebased from #27)

Changes:

Vaadin 24 & 25 compatibility

  • Updated JavaScript calls in ReplaceableLoginOverlay and LoginLayout to support both Vaadin 24 and Vaadin 25.
  • Adjusted tests to work with both versions.
  • Added testbench-rpc dependency to retrieve the Vaadin version during tests.

Code improvements

  • Refactored JavaScript snippets to use Java text blocks for improved readability.
  • Moved static methods from ReplaceableLoginOverlay interface into a dedicated utils class.

Demo improvements

  • Added AppShellConfiguratorImpl class.
  • Introduced separate stylesheets for Vaadin 25 compatibility.
  • Used the demo source condition attribute to switch between Vaadin 24 and 25 styles.
  • Added simple change password validation in the demo.

Summary by CodeRabbit

  • New Features

    • Added login overlay customization methods for replacing header/form, removing/replacing forgot-password and removing the submit button.
  • Improvements

    • Faster, more reliable login overlay DOM updates for improved UI responsiveness.
    • Demo and stylesheet additions with Vaadin-version-specific CSS for better appearance on different framework versions.
  • Chores

    • Updated Vaadin to 25.0.6 and added test infrastructure and test dependency support.

paodb and others added 5 commits March 16, 2026 12:53
Extract JavaScript DOM traversal into LoginOverlayUtils helper methods.
Update LoginLayout and ReplaceableLoginOverlay to use these methods,
and add removeForgotPassword() extracted from replaceForgotPassword().

Co-Authored-By: Javier Godoy <11554739+javier-godoy@users.noreply.github.com>
Add Vaadin 25 fallback logic to all LoginOverlayUtils helper methods.
When getElementById('vaadinLoginOverlayWrapper') returns null (Vaadin 25),
fall back to querying the vaadin-login-overlay shadow DOM for the wrapper.

Close #23

Co-Authored-By: Javier Godoy <11554739+javier-godoy@users.noreply.github.com>
Use demo source condition attribute to select between Vaadin 24 & Vaadin 25 styles.
@coderabbitai
Copy link

coderabbitai bot commented Mar 16, 2026

Walkthrough

Adds Vaadin 25.0.6 compatibility changes: new DOM-manipulation utilities, ReplaceableLoginOverlay API additions, RPC-based server-version support in integration tests, version-gated demo/styles, new integration test views, and Maven/test dependency updates.

Changes

Cohort / File(s) Summary
Maven configuration
pom.xml
Bumped vaadin.version 25.0.0 → 25.0.6, added test dependency com.flowingcode.vaadin.test:testbench-rpc:1.5.0, and expanded demo-jar test-jar exclusions to include AppShellConfiguratorImpl.class.
DOM utilities & login layout
src/main/java/com/flowingcode/vaadin/addons/extendedlogin/LoginOverlayUtils.java, src/main/java/com/flowingcode/vaadin/addons/extendedlogin/LoginLayout.java
New package-private LoginOverlayUtils producing cross-version JS snippets; LoginLayout refactored to use these utilities (replaces setTimeout replace scripts with utility-driven immediate DOM ops).
Public API: ReplaceableLoginOverlay
src/main/java/com/flowingcode/vaadin/addons/extendedlogin/ReplaceableLoginOverlay.java
Added default methods: replaceFormComponents, replaceHeaderComponent, removeForgotPassword, replaceForgotPassword, removeSubmitButton using LoginOverlayUtils for DOM changes.
Test scaffolding & RPC
src/test/java/com/flowingcode/vaadin/addons/AppShellConfiguratorImpl.java, src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/ServerVersionCallables.java, src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/TestExtendedLoginOverlayIntegrationView.java, src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/TestLoginLayoutIntegration.java, src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/TestLoginLayoutIntegrationView.java
Added AppShellConfigurator test class; introduced ServerVersionCallables interface; added integration test views and integration classes exposing @ClientCallable getMajorVersion() for server-version detection.
Test base & IT updates
src/test/java/com/flowingcode/vaadin/addons/AbstractViewTest.java, src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/ExtendedLoginOverlayIT.java, src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/LoginLayoutIT.java
AbstractViewTest implements HasRpcSupport and creates server proxy; integration tests updated to use RPC-based branching and LoginOverlayElement/version-aware element queries and routes (it/extended-login/...).
Demos & CSS (version-gated)
src/test/java/com/flowingcode/vaadin/addons/extendedlogin/ExtendedLoginOverlayDemo.java, src/test/java/com/flowingcode/vaadin/addons/extendedlogin/LoginLayoutDemo.java, src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestExtendedLoginOverlayView.java, src/test/resources/META-INF/frontend/styles/extended-login-styles-v25.css
Demo classes and test views now include preprocessor-guarded @DemoSource/@CssImport to select Vaadin 24 vs Vaadin 25+ styles; added new Vaadin-25-specific CSS file.
Test view adjustments
src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayout.java, src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayoutView.java
Minor formatting in TestLoginLayout; TestLoginLayoutView refactored to use class-level password fields, an onAccept() handler with validation, and version-gated CSS imports.
Miscellaneous tests/demos
src/test/java/com/flowingcode/vaadin/addons/extendedlogin/ExtendedLoginOverlayDemo.java, src/test/java/com/flowingcode/vaadin/addons/extendedlogin/LoginLayoutDemo.java, src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayoutView.java
Added conditional DemoSource/CssImport annotations (Vaadin version gating) alongside existing demo/test annotations.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • mlopezFC
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.77% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add Vaadin 25 support while maintaining Vaadin 24 compatibility' clearly and directly describes the main objective of the pull request, which is reflected across all file changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch vaadin-25-support2
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can approve the review once all CodeRabbit's comments are resolved.

Enable the reviews.request_changes_workflow setting to automatically approve the review once all CodeRabbit's comments are resolved.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (4)
src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayoutView.java (1)

76-83: Consider more specific validation feedback for demo clarity.

The current validation conflates two failure cases under one message:

  1. Password is null/blank → "Passwords do not match."
  2. Passwords actually don't match → "Passwords do not match."

For a demo showcasing form validation patterns, slightly more specific messages could be helpful, though the current implementation is functional.

♻️ Optional: More specific validation messages
   private void onAccept() {
     String passwordValue = this.password.getValue();
     String confirmPasswordValue = this.confirmPassword.getValue();
-    if (passwordValue != null && !passwordValue.isBlank() && passwordValue.equals(confirmPasswordValue)) {
+    if (passwordValue == null || passwordValue.isBlank()) {
+      Notification.show("Password cannot be empty.");
+    } else if (!passwordValue.equals(confirmPasswordValue)) {
+      Notification.show("Passwords do not match.");
+    } else {
       Notification.show("Password changed.");
-    } else {
-      Notification.show("Passwords do not match.");
     }
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayoutView.java`
around lines 76 - 83, The onAccept method currently treats a blank/null password
and a mismatched confirmation the same; update onAccept to first check that
password.getValue() is non-null and not blank and show a specific message like
"Password cannot be blank" (or set a validation error) if it fails, then
separately check password.equals(confirmPasswordValue) and show "Passwords do
not match" only in that case; locate the onAccept method and the variables
password, confirmPassword, passwordValue and confirmPasswordValue to implement
the two-step validation and corresponding Notification messages.
src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/AbstractViewTest.java (1)

53-53: Tighten the RPC proxy field contract.

Subclasses rely on this proxy, so leaving it package-private and mutable is looser than necessary. Marking it protected final makes the intended extension point explicit and prevents accidental reassignment.

♻️ Proposed tweak
-  ServerVersionCallables $server = createCallableProxy(ServerVersionCallables.class);
+  protected final ServerVersionCallables $server = createCallableProxy(ServerVersionCallables.class);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/AbstractViewTest.java`
at line 53, The field holding the RPC proxy (ServerVersionCallables $server) is
currently package-private and mutable; change its declaration to protected final
to tighten the contract so subclasses can use but not reassign it. Locate the
declaration of ServerVersionCallables $server in AbstractViewTest (the line with
createCallableProxy(ServerVersionCallables.class)) and update its modifier to
protected final, ensuring any initialization remains compatible with the
constructor or field initializer that calls createCallableProxy.
src/main/java/com/flowingcode/vaadin/addons/extendedlogin/ReplaceableLoginOverlay.java (1)

58-77: You can merge brand clear+append into a single executeJs call.

This would avoid two client round-trips and remove timing coupling between separate async snippets.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/main/java/com/flowingcode/vaadin/addons/extendedlogin/ReplaceableLoginOverlay.java`
around lines 58 - 77, The code issues two separate getElement().executeJs calls
to first clear and then append to the brand element causing extra round-trips
and timing coupling; merge them into a single executeJs invocation in
ReplaceableLoginOverlay that uses LoginOverlayUtils.getOverlayWrapperScript to
both clear (replaceChildren()) and append ($0) the passed withElement in one
script, keeping the same parameter (withElement) and call site so the operation
is atomic and reduces client-server round-trips.
src/main/java/com/flowingcode/vaadin/addons/extendedlogin/LoginOverlayUtils.java (1)

39-54: Consider extracting shared overlay-wrapper lookup to one internal template.

The Vaadin 24/25 wrapper resolution block is duplicated in two methods. Centralizing it would reduce drift risk when compatibility logic changes again.

Also applies to: 88-104

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/main/java/com/flowingcode/vaadin/addons/extendedlogin/LoginOverlayUtils.java`
around lines 39 - 54, Extract the duplicated Vaadin 24/25 overlay-wrapper lookup
into a single internal template/constant and reuse it from
getOverlayWrapperScript and the other method that contains the same block (the
overlay-close/cleanup script method), so the JS snippet is defined once and then
injected (e.g., via String.format or text block concatenation) into both
getOverlayWrapperScript and the sibling method; update both methods to reference
the new shared symbol (e.g., OVERLAY_WRAPPER_LOOKUP or
buildOverlayWrapperLookup()) and remove the duplicated JS block from each
method.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main/java/com/flowingcode/vaadin/addons/extendedlogin/LoginLayout.java`:
- Around line 54-65: Guard the usage of the content field in the onAttach logic
by checking content for null before executing the form replacement JS and DOM
manipulations: wrap the block that calls
this.getElement().executeJs(LoginOverlayUtils.getLoginFormWrapperScript(...)),
this.getElement().appendChild(content.getElement()),
content.getElement().setAttribute("slot","form"), and
content.getElement().executeJs(...) with an early-return or conditional (e.g.,
if (content == null) return; or if (content != null) { ... }); ensure you
reference the same symbols (content, this.getElement(),
LoginOverlayUtils.getLoginFormWrapperScript, formWrapper) so the DOM/script
operations only run when content is present.

In
`@src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/ServerVersionCallables.java`:
- Around line 20-29: The ServerVersionCallables interface is currently in the
integration-test (.it) package and is referenced by TestExtendedLoginOverlayView
and TestLoginLayout, which are included in the demo JAR; move the contract to a
neutral test-support package so the demo classifier can load the tests without
missing references. Create a new package (e.g.,
com.flowingcode.vaadin.addons.extendedlogin.testsupport) and relocate the
ServerVersionCallables interface there (keep the same interface name and
getMajorVersion() signature), then update imports in
TestExtendedLoginOverlayView and TestLoginLayout to point to the new package;
alternatively, if you prefer not to move files, ensure the interface is
explicitly included in the demo JAR by adjusting the build configuration to not
exclude it.

In `@src/test/resources/META-INF/frontend/styles/extended-login-styles-v25.css`:
- Line 1: The comment-whitespace-inside stylelint violations are caused by
comments that lack required spaces; update the comment tokens in this file by
inserting a space after the opening /* and before the closing */ — e.g., change
the leading comment token that is currently "/*-" to include a space ("/* -")
and change "/*Demo styles*/" to "/* Demo styles */" so they comply with the
comment-whitespace-inside rule; locate these comments in the CSS and adjust
their spacing accordingly.

---

Nitpick comments:
In
`@src/main/java/com/flowingcode/vaadin/addons/extendedlogin/LoginOverlayUtils.java`:
- Around line 39-54: Extract the duplicated Vaadin 24/25 overlay-wrapper lookup
into a single internal template/constant and reuse it from
getOverlayWrapperScript and the other method that contains the same block (the
overlay-close/cleanup script method), so the JS snippet is defined once and then
injected (e.g., via String.format or text block concatenation) into both
getOverlayWrapperScript and the sibling method; update both methods to reference
the new shared symbol (e.g., OVERLAY_WRAPPER_LOOKUP or
buildOverlayWrapperLookup()) and remove the duplicated JS block from each
method.

In
`@src/main/java/com/flowingcode/vaadin/addons/extendedlogin/ReplaceableLoginOverlay.java`:
- Around line 58-77: The code issues two separate getElement().executeJs calls
to first clear and then append to the brand element causing extra round-trips
and timing coupling; merge them into a single executeJs invocation in
ReplaceableLoginOverlay that uses LoginOverlayUtils.getOverlayWrapperScript to
both clear (replaceChildren()) and append ($0) the passed withElement in one
script, keeping the same parameter (withElement) and call site so the operation
is atomic and reduces client-server round-trips.

In
`@src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/AbstractViewTest.java`:
- Line 53: The field holding the RPC proxy (ServerVersionCallables $server) is
currently package-private and mutable; change its declaration to protected final
to tighten the contract so subclasses can use but not reassign it. Locate the
declaration of ServerVersionCallables $server in AbstractViewTest (the line with
createCallableProxy(ServerVersionCallables.class)) and update its modifier to
protected final, ensuring any initialization remains compatible with the
constructor or field initializer that calls createCallableProxy.

In
`@src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayoutView.java`:
- Around line 76-83: The onAccept method currently treats a blank/null password
and a mismatched confirmation the same; update onAccept to first check that
password.getValue() is non-null and not blank and show a specific message like
"Password cannot be blank" (or set a validation error) if it fails, then
separately check password.equals(confirmPasswordValue) and show "Passwords do
not match" only in that case; locate the onAccept method and the variables
password, confirmPassword, passwordValue and confirmPasswordValue to implement
the two-step validation and corresponding Notification messages.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fe931338-0769-4cc1-960e-95dcf11c9083

📥 Commits

Reviewing files that changed from the base of the PR and between 7586f5c and ab2d566.

📒 Files selected for processing (15)
  • pom.xml
  • src/main/java/com/flowingcode/vaadin/addons/extendedlogin/LoginLayout.java
  • src/main/java/com/flowingcode/vaadin/addons/extendedlogin/LoginOverlayUtils.java
  • src/main/java/com/flowingcode/vaadin/addons/extendedlogin/ReplaceableLoginOverlay.java
  • src/test/java/com/flowingcode/vaadin/addons/AppShellConfiguratorImpl.java
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/ExtendedLoginOverlayDemo.java
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/LoginLayoutDemo.java
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestExtendedLoginOverlayView.java
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayout.java
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayoutView.java
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/AbstractViewTest.java
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/ExtendedLoginOverlayIT.java
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/LoginLayoutIT.java
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/ServerVersionCallables.java
  • src/test/resources/META-INF/frontend/styles/extended-login-styles-v25.css

@paodb paodb force-pushed the vaadin-25-support2 branch from 23e5d67 to 56460c0 Compare March 17, 2026 18:21
@sonarqubecloud
Copy link

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/AbstractViewTest.java (1)

53-54: Consider renaming $server to follow Java naming conventions (optional).

SonarCloud flags the $ prefix as non-standard. While $server is a recognizable convention in some TestBench RPC contexts to denote server proxies, renaming to server or serverProxy would satisfy the linter and remain clear.

🔧 Suggested rename
-  ServerVersionCallables $server = createCallableProxy(ServerVersionCallables.class);
+  ServerVersionCallables server = createCallableProxy(ServerVersionCallables.class);

Note: If you apply this rename, update all usages in subclasses (e.g., $server.getMajorVersion()server.getMajorVersion()).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/AbstractViewTest.java`
around lines 53 - 54, The variable name $server uses a non-standard `$` prefix;
rename the field/variable to a conventional identifier (e.g., server or
serverProxy) where it is declared (the ServerVersionCallables $server
assignment) and update all usages throughout the test class and subclasses (for
example replace $server.getMajorVersion() with server.getMajorVersion()) to keep
references consistent and satisfy the linter.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/AbstractViewTest.java`:
- Around line 53-54: The variable name $server uses a non-standard `$` prefix;
rename the field/variable to a conventional identifier (e.g., server or
serverProxy) where it is declared (the ServerVersionCallables $server
assignment) and update all usages throughout the test class and subclasses (for
example replace $server.getMajorVersion() with server.getMajorVersion()) to keep
references consistent and satisfy the linter.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9340e2b9-4ea5-404b-a94b-f728bf492e53

📥 Commits

Reviewing files that changed from the base of the PR and between 23e5d67 and 56460c0.

📒 Files selected for processing (10)
  • pom.xml
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestExtendedLoginOverlayView.java
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/TestLoginLayout.java
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/AbstractViewTest.java
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/ExtendedLoginOverlayIT.java
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/LoginLayoutIT.java
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/ServerVersionCallables.java
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/TestExtendedLoginOverlayIntegrationView.java
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/TestLoginLayoutIntegration.java
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/TestLoginLayoutIntegrationView.java
🚧 Files skipped from review as they are similar to previous changes (4)
  • pom.xml
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/ServerVersionCallables.java
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/TestLoginLayoutIntegration.java
  • src/test/java/com/flowingcode/vaadin/addons/extendedlogin/it/ExtendedLoginOverlayIT.java

@paodb paodb requested a review from mlopezFC March 17, 2026 18:43
@javier-godoy javier-godoy requested a review from paodb March 17, 2026 18:59
@javier-godoy javier-godoy merged commit 38848ec into master Mar 17, 2026
5 checks passed
@javier-godoy javier-godoy deleted the vaadin-25-support2 branch March 17, 2026 19:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants