Skip to content

Apply application's theme to MarkdownEditor component #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

flang
Copy link

@flang flang commented Apr 14, 2025

Close #10

Summary by CodeRabbit

  • New Features
    • Upgraded the Markdown Editor to version 2.0.0 with improved dynamic theme synchronization.
    • The editor now automatically adapts its appearance based on the hosting application's theme changes.
    • Removed manual color mode selection from demos to streamline user experience with automatic theme detection.

@flang flang requested review from mlopezFC and paodb April 14, 2025 17:17
Copy link

coderabbitai bot commented Apr 14, 2025

Walkthrough

This pull request updates the project version in the pom.xml from 1.1.1-SNAPSHOT to 2.0.0-SNAPSHOT. It refactors the BaseMarkdownComponent by removing the DataColorMode enum and related setter, replacing them with lifecycle hooks that run JavaScript commands to observe theme changes on the client side. A new JavaScript connector is added to dynamically monitor and respond to theme attribute changes on the document, updating the editor's data-color-mode attribute accordingly. The demo classes remove all UI controls and logic related to manual color mode selection, relying instead on automatic theme synchronization.

Changes

Files Change Summary
pom.xml Updated version from 1.1.1-SNAPSHOT to 2.0.0-SNAPSHOT.
src/main/java/com/flowingcode/vaadin/addons/markdown/BaseMarkdownComponent.java and src/main/resources/META-INF/resources/frontend/connector.js Removed DataColorMode enum and setDataColorMode method. Added runBeforeClientResponse method and overridden onAttach and onDetach to invoke JS connector functions for theme observation. Added @JavaScript annotation to include the connector script. Created JS connector with observeThemeChange and unobserveThemeChange methods to handle dynamic theme attribute changes.
src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditorDemo.java Removed all UI elements and code related to color mode selection and setting on the markdown editor.
src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewerDemo.java Removed all UI elements and code related to color mode selection and setting on the markdown viewer.
src/main/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewer.java Removed unused imports related to NpmPackage and ReactAdapterComponent. No logic changes.

Assessment against linked issues

Objective Addressed Explanation
Automatic dark mode support based on theme variant (#10)

Suggested reviewers

  • javier-godoy
✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 0

🧹 Nitpick comments (1)
src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditorDemo.java (1)

52-65: Good implementation of application-wide theme handling

The code now properly manages theme at the application level rather than just component level, which aligns with the PR objective. The implementation correctly handles all three cases (dark, light, and automatic) by manipulating the UI theme list.

One minor suggestion to consider - explicitly handling the default case with a notification or log entry might be helpful for debugging:

  default:
+   System.out.println("Unrecognized theme option: " + ev.getValue());
    break;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 655adb3 and 155178b.

📒 Files selected for processing (4)
  • pom.xml (1 hunks)
  • src/main/java/com/flowingcode/vaadin/addons/markdown/BaseMarkdownComponent.java (3 hunks)
  • src/main/resources/META-INF/resources/frontend/connector.js (1 hunks)
  • src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditorDemo.java (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-vaadin24
🔇 Additional comments (6)
pom.xml (1)

7-7: Version update correctly reflects the new feature addition

The version increment from 1.1.1-SNAPSHOT to 1.2.0-SNAPSHOT follows semantic versioning principles, appropriately indicating a new feature addition (theme support) while maintaining backward compatibility.

src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditorDemo.java (1)

24-25: Well-structured import additions

The new imports for UI and Lumo theme constants support the theme-based approach being implemented.

Also applies to: 32-32

src/main/resources/META-INF/resources/frontend/connector.js (1)

1-74: Well-implemented theme observation connector

The connector provides a clean implementation for observing theme changes and updating the component accordingly. The code:

  1. Properly handles initialization checks to prevent multiple observers
  2. Checks for themes at the document root level first
  3. Falls back to body-level theme observation with MutationObserver
  4. Includes proper cleanup in the unobserve method

This implementation follows best practices for frontend connectors in Vaadin.

src/main/java/com/flowingcode/vaadin/addons/markdown/BaseMarkdownComponent.java (3)

22-26: Appropriate import additions and JavaScript dependency

The new imports and JavaScript annotation properly set up the connection to the frontend connector.

Also applies to: 40-40


124-127: Well-structured utility method for client response timing

The runBeforeClientResponse method provides a clean abstraction for executing JavaScript at the appropriate time in the component lifecycle.


129-145: Excellent implementation of theme observation lifecycle

The overridden onAttach and onDetach methods properly manage the theme observation lifecycle:

  1. onAttach initializes theme observation when the component is added to the UI
  2. onDetach cleans up by removing the observer when the component is removed

This prevents memory leaks and ensures the component responds appropriately to theme changes throughout its lifecycle.

@paodb paodb moved this from To Do to In Progress in Flowing Code Addons Apr 14, 2025
@paodb paodb requested a review from javier-godoy April 21, 2025 14:00
@paodb paodb moved this from In Progress to To Do in Flowing Code Addons Apr 21, 2025
Copy link
Member

@mlopezFC mlopezFC left a comment

Choose a reason for hiding this comment

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

I've tested this and it seems that is not working correctly:

  • The idea of the combobox for selecting the variant, was to show how the component looks and not to change the theme variant of the page (for that there is a specific combobox)
  • If I change the theme variant by using the checkbox it is not affecting the component, and that was the idea behind the issue ("If the dark mode theme variant is applied to the current page, it should affect also the color mode support of the component.")

@github-project-automation github-project-automation bot moved this from To Do to In Progress in Flowing Code Addons Apr 21, 2025
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: 1

🧹 Nitpick comments (1)
src/main/java/com/flowingcode/vaadin/addons/markdown/BaseMarkdownComponent.java (1)

97-104: Potential double subscription after detach/attach cycle

observeThemeChange is invoked every time the component is attached, but unobserveThemeChange is called only when the component is detached from the current UI.
If the element is moved between UIs (admittedly rare) or re-attached before the previous beforeClientResponse has fired, you could end up with multiple observers.

Not critical for most apps, yet you might want to:

  1. Make observeThemeChange idempotent in the JS connector, or
  2. Keep a flag on the client element indicating an active observer.

Just a heads-up for future maintenance.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 155178b and 9c4dea9.

📒 Files selected for processing (6)
  • pom.xml (1 hunks)
  • src/main/java/com/flowingcode/vaadin/addons/markdown/BaseMarkdownComponent.java (3 hunks)
  • src/main/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewer.java (0 hunks)
  • src/main/resources/META-INF/resources/frontend/connector.js (1 hunks)
  • src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditorDemo.java (2 hunks)
  • src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewerDemo.java (1 hunks)
💤 Files with no reviewable changes (1)
  • src/main/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewer.java
✅ Files skipped from review due to trivial changes (1)
  • pom.xml
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditorDemo.java
  • src/main/resources/META-INF/resources/frontend/connector.js
🔇 Additional comments (3)
src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewerDemo.java (1)

33-37: Removal of manual color-mode controls aligns the demo with new automatic theming – looks good

The viewer is now added to the layout without the ComboBox that was previously used to pick a mode, which is exactly what the new connector takes care of automatically. Nothing else is required here.

Also applies to: 202-203

src/main/java/com/flowingcode/vaadin/addons/markdown/BaseMarkdownComponent.java (2)

40-41: Verify that the static resource path is correct for all build modes

@JavaScript("./connector.js") assumes that the file is placed in the root of the frontend folder (resolved as frontend://connector.js).
If the file really lives under META-INF/resources/frontend/connector.js (as mentioned in the PR description), Vaadin will also find it, but only when it is copied during the prepare-frontend phase. In production builds the path occasionally breaks if the file is relocated or renamed.
Please double-check that:

  1. mvn -Pproduction can still locate the script.
  2. The jar classifier (if any) does not strip the resource.

An explicit path such as @JavaScript("frontend://connector.js") can make the intent clearer.


83-86: Race-condition safeguard: schedule JS only when UI is attached

Good idea to wrap beforeClientResponse in runWhenAttached; this prevents NPEs during lazy attach.

Comment on lines +89 to +96
protected void onAttach(AttachEvent attachEvent) {
super.onAttach(attachEvent);

runBeforeClientResponse(ui -> ui.getPage().executeJs(
"window.Vaadin.Flow.fcMarkdownEditorConnector.observeThemeChange($0)",
getElement()));
}

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Guard against missing connector on first paint

ui.getPage().executeJs("window.Vaadin.Flow.fcMarkdownEditorConnector.observeThemeChange($0)", …) will throw a client-side error if the connector script has not yet been executed (e.g., if the bundle is still downloading).

Consider adding a defensive check:

- "window.Vaadin.Flow.fcMarkdownEditorConnector.observeThemeChange($0)"
+ "window.Vaadin && Vaadin.Flow && Vaadin.Flow.fcMarkdownEditorConnector "
+ + "? Vaadin.Flow.fcMarkdownEditorConnector.observeThemeChange($0) : undefined"

or wrap the call in the JS connector itself.

Committable suggestion skipped: line range outside the PR's diff.

@flang flang requested a review from mlopezFC April 25, 2025 19:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: In Progress
Development

Successfully merging this pull request may close these issues.

Automatic dark mode support based on theme variant
2 participants