diff --git a/src/main/java/com/flowingcode/vaadin/addons/markdown/BaseMarkdownComponent.java b/src/main/java/com/flowingcode/vaadin/addons/markdown/BaseMarkdownComponent.java
index 2049209..89cda87 100644
--- a/src/main/java/com/flowingcode/vaadin/addons/markdown/BaseMarkdownComponent.java
+++ b/src/main/java/com/flowingcode/vaadin/addons/markdown/BaseMarkdownComponent.java
@@ -19,8 +19,12 @@
*/
package com.flowingcode.vaadin.addons.markdown;
+import com.vaadin.flow.component.AttachEvent;
+import com.vaadin.flow.component.DetachEvent;
import com.vaadin.flow.component.HasSize;
+import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.dependency.CssImport;
+import com.vaadin.flow.component.dependency.JavaScript;
import com.vaadin.flow.component.dependency.NpmPackage;
import com.vaadin.flow.component.react.ReactAdapterComponent;
import com.vaadin.flow.function.SerializableConsumer;
@@ -33,29 +37,9 @@
@NpmPackage(value = "mermaid", version = "11.2.1")
@NpmPackage(value = "@uiw/react-md-editor", version = "4.0.4")
@NpmPackage(value = "dompurify", version = "3.1.6")
+@JavaScript("./connector.js")
public class BaseMarkdownComponent extends ReactAdapterComponent implements HasSize {
- /**
- * Defines the color schemes for the Markdown component.
- *
- * The color mode can be set using the {@link #setDataColorMode(DataColorMode)} method.
- *
- *
- * - {@link #DARK}: Dark color scheme.
- *
- {@link #LIGHT}: Light color scheme.
- *
- {@link #AUTO}: Automatically detects the color scheme based on the user's system settings.
- *
- */
- public enum DataColorMode {
- DARK,
- LIGHT,
- /**
- * @deprecated Use LIGHT instead
- */
- @Deprecated
- LIGTH,
- AUTO};
-
private String content;
/**
@@ -96,24 +80,27 @@ public void addContentChangeListener(SerializableConsumer listener) {
addStateChangeListener("content", String.class, listener);
}
- /**
- * Sets the color mode of the Markdown component.
- *
- * @param mode the color mode of the component
- */
- public void setDataColorMode(DataColorMode mode) {
- switch (mode) {
- case DARK:
- getElement().setAttribute("data-color-mode", "dark");
- break;
- case LIGTH:
- case LIGHT:
- getElement().setAttribute("data-color-mode", "light");
- break;
- case AUTO:
- getElement().removeAttribute("data-color-mode");
- break;
- }
+ private void runBeforeClientResponse(SerializableConsumer command) {
+ getElement().getNode().runWhenAttached(ui -> ui
+ .beforeClientResponse(this, context -> command.accept(ui)));
}
-
+
+ @Override
+ protected void onAttach(AttachEvent attachEvent) {
+ super.onAttach(attachEvent);
+
+ runBeforeClientResponse(ui -> ui.getPage().executeJs(
+ "window.Vaadin.Flow.fcMarkdownEditorConnector.observeThemeChange($0)",
+ getElement()));
+ }
+
+ @Override
+ protected void onDetach(DetachEvent detachEvent) {
+ super.onDetach(detachEvent);
+
+ getUI().ifPresent(ui -> ui.getPage().executeJs(
+ "window.Vaadin.Flow.fcMarkdownEditorConnector.unobserveThemeChange($0)",
+ this.getElement()));
+ }
+
}
diff --git a/src/main/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditor.java b/src/main/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditor.java
index 81f2dc1..e18b65e 100644
--- a/src/main/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditor.java
+++ b/src/main/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditor.java
@@ -20,7 +20,6 @@
package com.flowingcode.vaadin.addons.markdown;
-import com.flowingcode.vaadin.addons.markdown.BaseMarkdownComponent.DataColorMode;
import com.vaadin.flow.component.AbstractCompositeField;
import com.vaadin.flow.component.HasSize;
@@ -101,15 +100,6 @@ public void setMaxLength(int maxLength) {
getEditor().setMaxLength(maxLength);
}
- /**
- * Sets the color mode of the Markdown component.
- *
- * @param mode the color mode of the component
- */
- public void setDataColorMode(DataColorMode mode) {
- getEditor().setDataColorMode(mode);
- }
-
@Override
protected void setPresentationValue(String newPresentationValue) {
getEditor().setContent(newPresentationValue);
diff --git a/src/main/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewer.java b/src/main/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewer.java
index 2904335..7011083 100644
--- a/src/main/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewer.java
+++ b/src/main/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewer.java
@@ -22,8 +22,6 @@
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.dependency.JsModule;
-import com.vaadin.flow.component.dependency.NpmPackage;
-import com.vaadin.flow.component.react.ReactAdapterComponent;
/**
* Component for displaying Markdown text
diff --git a/src/main/resources/META-INF/resources/frontend/connector.js b/src/main/resources/META-INF/resources/frontend/connector.js
new file mode 100644
index 0000000..3b572a6
--- /dev/null
+++ b/src/main/resources/META-INF/resources/frontend/connector.js
@@ -0,0 +1,82 @@
+/*-
+ * #%L
+ * Markdown Editor Add-on
+ * %%
+ * Copyright (C) 2025 Flowing Code
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+(function() {
+
+ window.Vaadin.Flow.fcMarkdownEditorConnector = {
+ observeThemeChange: markDownEditor => {
+ // Check whether the connector was already initialized for markDownEditor
+ if (markDownEditor.$connector) {
+ return;
+ }
+
+ markDownEditor.$connector = {};
+
+ const supportedTheme = theme => ['light', 'dark'].includes(theme);
+
+ const setDataColorMode = theme => {
+ if (supportedTheme(theme)) {
+ markDownEditor.setAttribute('data-color-mode', theme);
+ } else {
+ // force light theme which is Vaadin's default theme
+ markDownEditor.setAttribute('data-color-mode', 'light');
+ }
+ };
+
+ // Get theme from html element when using Vaadin's @Theme annotation
+ const mainTheme = document.documentElement.getAttribute('theme');
+ if (supportedTheme(mainTheme)) {
+ setDataColorMode(mainTheme);
+ } else {
+ // set light theme by default
+ markDownEditor.setAttribute('data-color-mode', 'light');
+ }
+
+ // options for the observer (which mutations to observe)
+ const config = { attributes: true };
+
+ // callback function to execute when mutations are observed
+ const callback = (mutationList, observer) => {
+ for (const mutation of mutationList) {
+ if (mutation.type === 'attributes' && mutation.attributeName === 'theme') {
+ const themeName = mutation.target.getAttribute(mutation.attributeName);
+ console.log("theme", themeName);
+ setDataColorMode(themeName);
+ }
+ }
+ };
+
+ // create an observer instance linked to the callback function
+ markDownEditor.$connector.themeChangeObserver = new MutationObserver(callback);
+
+ // observe html tag for configured mutations
+ markDownEditor.$connector.themeChangeObserver.observe(document.documentElement, config);
+
+ // observe body tag for configured mutations
+ markDownEditor.$connector.themeChangeObserver.observe(document.body, config);
+ },
+ unobserveThemeChange: markDownEditor => {
+ // stop observing the target node for configured mutations
+ if (markDownEditor.$connector.themeChangeObserver) {
+ markDownEditor.$connector.themeChangeObserver.disconnect();
+ markDownEditor.$connector.themeChangeObserver = null;
+ }
+ }
+ }
+})();
diff --git a/src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditorDemo.java b/src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditorDemo.java
index 3b4827f..86daa5b 100644
--- a/src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditorDemo.java
+++ b/src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditorDemo.java
@@ -20,7 +20,7 @@
package com.flowingcode.vaadin.addons.markdown;
import com.flowingcode.vaadin.addons.demo.DemoSource;
-import com.flowingcode.vaadin.addons.markdown.BaseMarkdownComponent.DataColorMode;
+import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.notification.Notification;
@@ -28,6 +28,8 @@
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
+import com.vaadin.flow.theme.lumo.Lumo;
+import java.util.List;
@DemoSource
@PageTitle("Markdown Editor Demo")
@@ -41,26 +43,6 @@ public MarkdownEditorDemo() {
mde.setSizeFull();
mde.setPlaceholder("Enter Markdown here");
mde.setMaxLength(500);
- mde.setDataColorMode(DataColorMode.LIGTH);
- ComboBox cb = new ComboBox();
- cb.setItems("Dark","Light","Automatic");
- cb.setLabel("Color mode");
- cb.setValue("Light");
- cb.addValueChangeListener(ev->{
- switch(ev.getValue()) {
- case "Dark":
- mde.setDataColorMode(DataColorMode.DARK);
- break;
- case "Light":
- mde.setDataColorMode(DataColorMode.LIGHT);
- break;
- case "Automatic":
- mde.setDataColorMode(DataColorMode.AUTO);
- break;
- default:
- break;
- }
- });
Button getContentButton = new Button("Show content",ev->Notification.show(mde.getValue()));
Button setSampleContent = new Button("Set sample content",ev->{
mde.setValue("""
@@ -90,6 +72,6 @@ public static void main(String[] args) {
~~This is strikethrough text~~
""");
});
- add(mde,cb,new HorizontalLayout(getContentButton,setSampleContent));
+ add(mde,new HorizontalLayout(getContentButton,setSampleContent));
}
}
diff --git a/src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewerDemo.java b/src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewerDemo.java
index f60ec19..130a3db 100644
--- a/src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewerDemo.java
+++ b/src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownViewerDemo.java
@@ -20,8 +20,6 @@
package com.flowingcode.vaadin.addons.markdown;
import com.flowingcode.vaadin.addons.demo.DemoSource;
-import com.flowingcode.vaadin.addons.markdown.BaseMarkdownComponent.DataColorMode;
-import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
@@ -36,7 +34,6 @@ public MarkdownViewerDemo() {
setSizeFull();
MarkdownViewer mdv = new MarkdownViewer();
mdv.setSizeFull();
- mdv.setDataColorMode(DataColorMode.LIGTH);
mdv.setContent("""
# h1 Heading
@@ -202,25 +199,6 @@ public MarkdownViewerDemo() {
[^second]: Footnote text.
""");
- ComboBox cb = new ComboBox();
- cb.setItems("Dark","Light","Automatic");
- cb.setLabel("Color mode");
- cb.setValue("Light");
- cb.addValueChangeListener(ev->{
- switch(ev.getValue()) {
- case "Dark":
- mdv.setDataColorMode(DataColorMode.DARK);
- break;
- case "Light":
- mdv.setDataColorMode(DataColorMode.LIGHT);
- break;
- case "Automatic":
- mdv.setDataColorMode(DataColorMode.AUTO);
- break;
- default:
- break;
- }
- });
- add(mdv,cb);
+ add(mdv);
}
}