Skip to content

Commit 155178b

Browse files
committed
feat: apply application's theme to MarkdownEditor component
Close #10
1 parent 655adb3 commit 155178b

File tree

4 files changed

+113
-5
lines changed

4 files changed

+113
-5
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<groupId>com.flowingcode.vaadin.addons</groupId>
66
<artifactId>markdown-editor-addon</artifactId>
7-
<version>1.1.1-SNAPSHOT</version>
7+
<version>1.2.0-SNAPSHOT</version>
88
<name>Markdown Editor Add-on</name>
99
<description>Markdown Editor for Vaadin Flow</description>
1010
<url>https://www.flowingcode.com/en/open-source/</url>

src/main/java/com/flowingcode/vaadin/addons/markdown/BaseMarkdownComponent.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,12 @@
1919
*/
2020
package com.flowingcode.vaadin.addons.markdown;
2121

22+
import com.vaadin.flow.component.AttachEvent;
23+
import com.vaadin.flow.component.DetachEvent;
2224
import com.vaadin.flow.component.HasSize;
25+
import com.vaadin.flow.component.UI;
2326
import com.vaadin.flow.component.dependency.CssImport;
27+
import com.vaadin.flow.component.dependency.JavaScript;
2428
import com.vaadin.flow.component.dependency.NpmPackage;
2529
import com.vaadin.flow.component.react.ReactAdapterComponent;
2630
import com.vaadin.flow.function.SerializableConsumer;
@@ -33,6 +37,7 @@
3337
@NpmPackage(value = "mermaid", version = "11.2.1")
3438
@NpmPackage(value = "@uiw/react-md-editor", version = "4.0.4")
3539
@NpmPackage(value = "dompurify", version = "3.1.6")
40+
@JavaScript("./connector.js")
3641
public class BaseMarkdownComponent extends ReactAdapterComponent implements HasSize {
3742

3843
/**
@@ -115,5 +120,28 @@ public void setDataColorMode(DataColorMode mode) {
115120
break;
116121
}
117122
}
118-
123+
124+
private void runBeforeClientResponse(SerializableConsumer<UI> command) {
125+
getElement().getNode().runWhenAttached(ui -> ui
126+
.beforeClientResponse(this, context -> command.accept(ui)));
127+
}
128+
129+
@Override
130+
protected void onAttach(AttachEvent attachEvent) {
131+
super.onAttach(attachEvent);
132+
133+
runBeforeClientResponse(ui -> ui.getPage().executeJs(
134+
"window.Vaadin.Flow.fcMarkdownEditorConnector.observeThemeChange($0)",
135+
getElement()));
136+
}
137+
138+
@Override
139+
protected void onDetach(DetachEvent detachEvent) {
140+
super.onDetach(detachEvent);
141+
142+
getUI().ifPresent(ui -> ui.getPage().executeJs(
143+
"window.Vaadin.Flow.fcMarkdownEditorConnector.unobserveThemeChange($0)",
144+
this.getElement()));
145+
}
146+
119147
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*-
2+
* #%L
3+
* Markdown Editor Add-on
4+
* %%
5+
* Copyright (C) 2024 Flowing Code
6+
* %%
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
* #L%
19+
*/
20+
(function() {
21+
22+
window.Vaadin.Flow.fcMarkdownEditorConnector = {
23+
observeThemeChange: markDownEditor => {
24+
25+
// Check whether the connector was already initialized for markDownEditor
26+
if (markDownEditor.$connector) {
27+
return;
28+
}
29+
30+
markDownEditor.$connector = {};
31+
32+
// Get theme from html element when using Vaadin's @Theme annotation
33+
const mainTheme = document.documentElement.getAttribute('theme');
34+
if (['light', 'dark'].includes(mainTheme)) {
35+
markDownEditor.setAttribute('data-color-mode', mainTheme);
36+
} else {
37+
// Listen for theme changes in body element otherwise
38+
39+
// select the node that will be observed for mutations
40+
const targetNode = document.body;
41+
42+
// options for the observer (which mutations to observe)
43+
const config = { attributes: true };
44+
45+
// callback function to execute when mutations are observed
46+
const callback = (mutationList, observer) => {
47+
for (const mutation of mutationList) {
48+
if (mutation.type === 'attributes' && mutation.attributeName === 'theme') {
49+
const themeName = targetNode.attributes.getNamedItem(mutation.attributeName)?.value;
50+
if (['light', 'dark'].includes(themeName)) {
51+
markDownEditor.setAttribute('data-color-mode', themeName);
52+
} else {
53+
markDownEditor.removeAttribute('data-color-mode');
54+
}
55+
}
56+
}
57+
};
58+
59+
// create an observer instance linked to the callback function
60+
markDownEditor.$connector.themeChangeObserver = new MutationObserver(callback);
61+
62+
// start observing the target node for configured mutations
63+
markDownEditor.$connector.themeChangeObserver.observe(targetNode, config);
64+
}
65+
},
66+
unobserveThemeChange: markDownEditor => {
67+
// stop observing the target node for configured mutations
68+
if (markDownEditor.$connector.themeChangeObserver) {
69+
markDownEditor.$connector.themeChangeObserver.disconnect();
70+
markDownEditor.$connector.themeChangeObserver = null;
71+
}
72+
}
73+
}
74+
})();

src/test/java/com/flowingcode/vaadin/addons/markdown/MarkdownEditorDemo.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,15 @@
2121

2222
import com.flowingcode.vaadin.addons.demo.DemoSource;
2323
import com.flowingcode.vaadin.addons.markdown.BaseMarkdownComponent.DataColorMode;
24+
import com.vaadin.flow.component.UI;
2425
import com.vaadin.flow.component.button.Button;
2526
import com.vaadin.flow.component.combobox.ComboBox;
2627
import com.vaadin.flow.component.notification.Notification;
2728
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
2829
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
2930
import com.vaadin.flow.router.PageTitle;
3031
import com.vaadin.flow.router.Route;
32+
import com.vaadin.flow.theme.lumo.Lumo;
3133

3234
@DemoSource
3335
@PageTitle("Markdown Editor Demo")
@@ -47,15 +49,19 @@ public MarkdownEditorDemo() {
4749
cb.setLabel("Color mode");
4850
cb.setValue("Light");
4951
cb.addValueChangeListener(ev->{
52+
var themeList = UI.getCurrent().getElement().getThemeList();
5053
switch(ev.getValue()) {
5154
case "Dark":
52-
mde.setDataColorMode(DataColorMode.DARK);
55+
themeList.remove(Lumo.LIGHT);
56+
themeList.add(Lumo.DARK);
5357
break;
5458
case "Light":
55-
mde.setDataColorMode(DataColorMode.LIGHT);
59+
themeList.remove(Lumo.DARK);
60+
themeList.add(Lumo.LIGHT);
5661
break;
5762
case "Automatic":
58-
mde.setDataColorMode(DataColorMode.AUTO);
63+
themeList.remove(Lumo.DARK);
64+
themeList.remove(Lumo.LIGHT);
5965
break;
6066
default:
6167
break;

0 commit comments

Comments
 (0)