diff --git a/src/main/java/org/vaadin/tinymce/TinyMce.java b/src/main/java/org/vaadin/tinymce/TinyMce.java index cdfe6ee..d921730 100644 --- a/src/main/java/org/vaadin/tinymce/TinyMce.java +++ b/src/main/java/org/vaadin/tinymce/TinyMce.java @@ -52,9 +52,23 @@ */ @Tag("div") @JavaScript("context://frontend/tinymceConnector.js") -@StyleSheet("context://frontend/tinymceLumo.css") +@StyleSheet("context://frontend/tinymce.css") public class TinyMce extends AbstractCompositeField - implements HasSize, Focusable { + implements HasSize, Focusable { + + /** + * Marks {@code } with a class ("aura" or "lumo") matching the + * application's active theme, so that {@code tinymce.css} can scope its + * rules with the corresponding design tokens. + */ + private static final String DETECT_AND_APPLY_THEME_CLASS = """ + const s = getComputedStyle(document.documentElement); + const t = s.getPropertyValue('--vaadin-aura-theme').trim() === '1' ? 'aura' + : (s.getPropertyValue('--vaadin-lumo-theme').trim() === '1' ? 'lumo' : ''); + if (t) { + document.documentElement.classList.add(t); + } + """; private final DomListenerRegistration domListenerRegistration; private String id; @@ -62,7 +76,7 @@ public class TinyMce extends AbstractCompositeField private String currentValue = ""; private String rawConfig; ObjectNode config = JsonNodeFactory.instance.objectNode(); - private Element ta = new Element("div"); + private final Element ta = new Element("div"); private int debounceTimeout = 0; private boolean basicTinyMCECreated; @@ -77,7 +91,7 @@ public class TinyMce extends AbstractCompositeField * mode. * * @deprecated No longer needed since version x.x - * + * * @param shadowRoot * true of shadow root hack should be used */ @@ -94,14 +108,14 @@ public TinyMce(boolean shadowRoot) { } domListenerRegistration = getElement().addEventListener("tchange", - (DomEventListener) event -> { - boolean value = event.getEventData() - .has("event.htmlString"); - String htmlString = event.getEventData() - .get("event.htmlString").asString(); - currentValue = htmlString; - setModelValue(htmlString, true); - }); + (DomEventListener) event -> { + boolean value = event.getEventData() + .has("event.htmlString"); + String htmlString = event.getEventData() + .get("event.htmlString").asString(); + currentValue = htmlString; + setModelValue(htmlString, true); + }); domListenerRegistration.addEventData("event.htmlString"); domListenerRegistration.debounce(debounceTimeout); } @@ -193,6 +207,7 @@ protected void onAttach(AttachEvent attachEvent) { super.onAttach(attachEvent); if (attachEvent.isInitialAttach()) injectTinyMceScript(); + attachEvent.getUI().getPage().executeJs(DETECT_AND_APPLY_THEME_CLASS); initConnector(); saveOnClose(); } @@ -202,8 +217,8 @@ protected void onDetach(DetachEvent detachEvent) { // See https://github.com/parttio/tinymce-for-flow/issues/33 if (isVisible()) { detachEvent.getUI().getPage().executeJs(""" - tinymce.get($0).remove(); - """, id); + tinymce.get($0).remove(); + """, id); } super.onDetach(detachEvent); initialContentSent = false; @@ -215,7 +230,7 @@ protected void onDetach(DetachEvent detachEvent) { private void initConnector() { runBeforeClientResponse(ui -> { - if(rawConfig == null) { + if (rawConfig == null) { rawConfig = "{}"; } ui.getPage().executeJs( @@ -224,18 +239,19 @@ private void initConnector() { "window.Vaadin.Flow.tinymceConnector.initLazy(rawconfig, $0, $1, $2, $3, $4)", getElement(), ta, config, currentValue, (enabled && !readOnly)) - .then(res -> initialContentSent = true); + .then(res -> initialContentSent = true); }); } - - private void saveOnClose(){ + + private void saveOnClose() { runBeforeClientResponse(ui -> { - getElement().callJsFunction("$connector.saveOnClose");}); + getElement().callJsFunction("$connector.saveOnClose"); + }); } void runBeforeClientResponse(SerializableConsumer command) { getElement().getNode().runWhenAttached(ui -> ui - .beforeClientResponse(this, context -> command.accept(ui))); + .beforeClientResponse(this, context -> command.accept(ui))); } public String getCurrentValue() { @@ -294,7 +310,7 @@ public TinyMce configureLanguage(Language language) { */ public void replaceSelectionContent(String htmlString) { runBeforeClientResponse(ui -> getElement().callJsFunction( - "$connector.replaceSelectionContent", htmlString)); + "$connector.replaceSelectionContent", htmlString)); } /** @@ -305,7 +321,7 @@ public void replaceSelectionContent(String htmlString) { */ protected void injectTinyMceScript() { getUI().get().getPage().addJavaScript( - "context://frontend/tinymce_addon/tinymce/tinymce.min.js"); + "context://frontend/tinymce_addon/tinymce/tinymce.min.js"); } @Override @@ -313,41 +329,41 @@ public void focus() { runBeforeClientResponse(ui -> { // Dialog has timing issues... getElement().executeJs(""" - const el = this; - if(el.$connector.isInDialog()) { - setTimeout(() => { - el.$connector.focus() - }, 150); - } else { - el.$connetor.focus(); - } - """); + const el = this; + if(el.$connector.isInDialog()) { + setTimeout(() => { + el.$connector.focus() + }, 150); + } else { + el.$connetor.focus(); + } + """); ; }); } @Override public Registration addFocusListener( - ComponentEventListener> listener) { + ComponentEventListener> listener) { DomListenerRegistration domListenerRegistration = getElement() - .addEventListener("tfocus", event -> listener - .onComponentEvent(new FocusEvent<>(this, false))); + .addEventListener("tfocus", event -> listener + .onComponentEvent(new FocusEvent<>(this, false))); return domListenerRegistration; } @Override public Registration addBlurListener( - ComponentEventListener> listener) { + ComponentEventListener> listener) { DomListenerRegistration domListenerRegistration = getElement() - .addEventListener("tblur", event -> listener - .onComponentEvent(new BlurEvent<>(this, false))); + .addEventListener("tblur", event -> listener + .onComponentEvent(new BlurEvent<>(this, false))); return domListenerRegistration; } @Override public void blur() { throw new RuntimeException( - "Not implemented, TinyMce does not support programmatic blur."); + "Not implemented, TinyMce does not support programmatic blur."); } @Override @@ -360,7 +376,7 @@ private void adjustEnabledState() { boolean reallyEnabled = this.enabled && !this.readOnly; super.setEnabled(reallyEnabled); runBeforeClientResponse(ui -> getElement() - .callJsFunction("$connector.setEnabled", reallyEnabled)); + .callJsFunction("$connector.setEnabled", reallyEnabled)); } @Override @@ -375,7 +391,7 @@ protected void setPresentationValue(String html) { this.currentValue = html; if (initialContentSent) { runBeforeClientResponse(ui -> getElement() - .callJsFunction("$connector.setEditorContent", html)); + .callJsFunction("$connector.setEditorContent", html)); } } @@ -384,15 +400,15 @@ private TinyMce createBasicTinyMce() { this.configure("branding", false); this.basicTinyMCECreated = true; this.configurePlugin(false, Plugin.AUTOLINK, - Plugin.LISTS, Plugin.SEARCH_REPLACE); + Plugin.LISTS, Plugin.SEARCH_REPLACE); this.configureMenubar(false, Menubar.FILE, Menubar.EDIT, Menubar.VIEW, - Menubar.FORMAT); + Menubar.FORMAT); this.configureToolbar(false, Toolbar.UNDO, Toolbar.REDO, - Toolbar.SEPARATOR, Toolbar.BLOCKS, Toolbar.SEPARATOR, - Toolbar.BOLD, Toolbar.ITALIC, Toolbar.SEPARATOR, - Toolbar.ALIGN_LEFT, Toolbar.ALIGN_CENTER, Toolbar.ALIGN_RIGHT, - Toolbar.ALIGN_JUSTIFY, Toolbar.SEPARATOR, Toolbar.OUTDENT, - Toolbar.INDENT); + Toolbar.SEPARATOR, Toolbar.BLOCKS, Toolbar.SEPARATOR, + Toolbar.BOLD, Toolbar.ITALIC, Toolbar.SEPARATOR, + Toolbar.ALIGN_LEFT, Toolbar.ALIGN_CENTER, Toolbar.ALIGN_RIGHT, + Toolbar.ALIGN_JUSTIFY, Toolbar.SEPARATOR, Toolbar.OUTDENT, + Toolbar.INDENT); return this; } @@ -422,7 +438,7 @@ public TinyMce configureMenubar(boolean basicTinyMCE, Menubar... menubars) { } String newconfig = Arrays.stream(menubars).map(m -> m.menubarLabel) - .collect(Collectors.joining(" ")); + .collect(Collectors.joining(" ")); String menubar; if (config.has("menubar")) { @@ -450,7 +466,7 @@ public TinyMce configureToolbar(boolean basicTinyMCE, Toolbar... toolbars) { for (int i = 0; i < toolbars.length; i++) { toolbarStr = toolbarStr.concat(" ").concat(toolbars[i].toolbarLabel) - .concat(" "); + .concat(" "); } config.put("toolbar", toolbarStr); diff --git a/src/main/resources/META-INF/resources/frontend/tinymce.css b/src/main/resources/META-INF/resources/frontend/tinymce.css new file mode 100644 index 0000000..6f7c5b0 --- /dev/null +++ b/src/main/resources/META-INF/resources/frontend/tinymce.css @@ -0,0 +1,304 @@ +/* Theme-agnostic rules, apply regardless of Aura/Lumo */ +.tox .tox-editor-container .tox-editor-header .tox-toolbar-overlord { + border-top: unset; + margin: 0; + padding: 0; +} + +.tox .tox-menu.tox-collection.tox-collection--list { + min-width: var(--tiny-mce-menu-width, 300px); +} + +.tinymce-flow[readonly] .tox-editor-header { + display: none; +} + +.tinymce-flow[disabled]:not([readonly]) { + opacity: 0.5; +} + +/* Aura theme */ + +.aura .tox .tox-editor-header > .tox-menubar { + background-color: var(--vaadin-background-container); + padding-left: var(--vaadin-padding-s); + padding-right: var(--vaadin-padding-s); +} + +.aura .tox .tox-editor-container .tox-editor-header .tox-toolbar-overlord > .tox-toolbar__primary { + background-color: var(--vaadin-background-container); + padding-left: var(--vaadin-padding-s); + padding-right: var(--vaadin-padding-s); + border-top: unset; +} + +.aura .tox .tox-editor-container .tox-editor-header:not(.tox-tinymce-inline) { + box-shadow: var(--aura-shadow-xs); + padding: 0; +} + +.aura .tox.tox-tinymce-aux .tox-toolbar__overflow { + background-color: var(--vaadin-overlay-background, var(--aura-surface-color-solid)) !important; + background-image: linear-gradient(var(--vaadin-background-container), var(--vaadin-background-container)) !important; +} + +.aura .tox:not([dir=rtl]) .tox-toolbar-overlord .tox-toolbar__group:not(:last-of-type) { + border-right: 1px solid var(--vaadin-border-color); +} + +.aura .tox button.tox-tbtn--enabled { + background: var(--aura-accent-color); +} + +.aura .tox button.tox-tbtn--enabled:hover { + background: var(--aura-accent-color); +} + +.aura .tox button.tox-tbtn:hover { + background: var(--vaadin-background-container-strong); +} + +.aura .tox .tox-tbtn--disabled[aria-disabled="true"] .tox-icon > svg { + fill: var(--vaadin-text-color-disabled); +} + +.aura .tox .tox-tbtn .tox-icon > svg { + fill: var(--vaadin-text-color-secondary); +} + +.aura .tox .tox-tbtn--enabled .tox-icon > svg { + fill: var(--aura-accent-contrast-color); +} + +.aura .tox .tox-tbtn--enabled:hover .tox-icon > svg { + fill: var(--aura-accent-contrast-color); +} + +.aura .tox.tox-tinymce { + border: 1px solid var(--vaadin-border-color); + border-radius: var(--vaadin-radius-m); +} + +.aura .tox .tox-statusbar__text-container .tox-statusbar__path-item { + color: var(--vaadin-text-color-secondary); +} + +.aura .tox .tox-statusbar__text-container .tox-statusbar__path-divider { + color: var(--vaadin-text-color-secondary); +} + +.aura .tox .tox-statusbar__text-container { + font-size: var(--aura-font-size-s); +} + +.aura button.tox-mbtn.tox-mbtn--select.tox-mbtn--active { + background: color-mix(in srgb, var(--aura-accent-color) 50%, transparent); + color: var(--aura-accent-contrast-color); +} + +.aura .tox-menubar > button.tox-mbtn.tox-mbtn--select:hover:not(:disabled) { + background: color-mix(in srgb, var(--aura-accent-color) 10%, transparent); +} + +.aura button.tox-mbtn.tox-mbtn--select { + color: var(--vaadin-text-color); + font-size: var(--aura-font-size-m); +} + +.aura button.tox-tbtn.tox-tbtn--select.tox-tbtn--bespoke { + color: var(--vaadin-text-color); +} + +.aura .tox-menu.tox-collection.tox-collection--list.tox-selected-menu { + border-radius: var(--vaadin-radius-m); +} + +.aura .tox-menu.tox-collection.tox-collection--list { + background: var(--vaadin-overlay-background, var(--aura-surface-color-solid)); + box-shadow: var(--aura-shadow-m); +} + +.aura .tox .tox-menu.tox-collection--list .tox-collection__item.tox-collection__item--active { + color: var(--vaadin-text-color); + background-color: color-mix(in srgb, var(--aura-accent-color) 10%, transparent); +} + +.aura .tox-menu-nav__js.tox-collection__item.tox-collection__item { + color: var(--vaadin-text-color); +} + +.aura .tox .tox-collection > .tox-collection__group { + border-color: var(--vaadin-border-color) !important; + padding-top: var(--vaadin-padding-s) !important; + padding-bottom: var(--vaadin-padding-s) !important; +} + +.aura div.tox-collection__item > div.tox-collection__item-accessory { + color: var(--vaadin-text-color-secondary); +} + +.aura div.tox-collection__item > div.tox-collection__item-label { + font-size: var(--aura-font-size-m); + line-height: var(--aura-line-height-m); +} + +.aura div.tox-collection__item > div.tox-collection__item-icon { + width: var(--vaadin-icon-size, 1lh); + height: var(--vaadin-icon-size, 1lh); +} + +.aura .tox .tox-collection__item > .tox-collection__item-caret svg { + fill: var(--vaadin-text-color-secondary); +} + +.aura .tox .tox-fancymenuitem .tox-insert-table-picker .tox-insert-table-picker__selected { + background-color: color-mix(in srgb, var(--aura-accent-color) 10%, transparent); + border-color: color-mix(in srgb, var(--aura-accent-color) 50%, transparent); +} + +.aura .tox .tox-fancymenuitem .tox-insert-table-picker .tox-insert-table-picker { + border-color: var(--vaadin-border-color); +} + +/* Lumo theme */ + +.lumo .tox .tox-editor-header > .tox-menubar { + background-color: var(--lumo-contrast-5pct); + padding-left: var(--lumo-space-s); + padding-right: var(--lumo-space-s); +} + +.lumo .tox .tox-editor-container .tox-editor-header .tox-toolbar-overlord > .tox-toolbar__primary { + background-color: var(--lumo-contrast-5pct); + padding-left: var(--lumo-space-s); + padding-right: var(--lumo-space-s); + border-top: unset; +} + +.lumo .tox .tox-editor-container .tox-editor-header:not(.tox-tinymce-inline) { + box-shadow: var(--lumo-box-shadow-xs); + padding: 0; +} + +.lumo .tox.tox-tinymce-aux .tox-toolbar__overflow { + background-color: var(--lumo-base-color) !important; + background-image: linear-gradient(var(--lumo-contrast-5pct), var(--lumo-contrast-5pct)) !important; +} + +.lumo .tox:not([dir=rtl]) .tox-toolbar-overlord .tox-toolbar__group:not(:last-of-type) { + border-right: 1px solid var(--lumo-contrast-20pct); +} + +.lumo .tox button.tox-tbtn--enabled { + background: var(--lumo-primary-color); +} + +.lumo .tox button.tox-tbtn--enabled:hover { + background: var(--lumo-primary-color); +} + +.lumo .tox button.tox-tbtn:hover { + background: var(--lumo-contrast-10pct); +} + +.lumo .tox .tox-tbtn--disabled[aria-disabled="true"] .tox-icon > svg { + fill: var(--lumo-contrast-20pct); +} + +.lumo .tox .tox-tbtn .tox-icon > svg { + fill: var(--lumo-contrast-60pct); +} + +.lumo .tox .tox-tbtn--enabled .tox-icon > svg { + fill: var(--lumo-primary-contrast-color); +} + +.lumo .tox .tox-tbtn--enabled:hover .tox-icon > svg { + fill: var(--lumo-primary-contrast-color); +} + +.lumo .tox.tox-tinymce { + border: 1px solid var(--lumo-contrast-20pct); + border-radius: var(--lumo-border-radius-m); +} + +.lumo .tox .tox-statusbar__text-container .tox-statusbar__path-item { + color: var(--lumo-secondary-text-color); +} + +.lumo .tox .tox-statusbar__text-container .tox-statusbar__path-divider { + color: var(--lumo-secondary-text-color); +} + +.lumo .tox .tox-statusbar__text-container { + font-size: var(--lumo-font-size-s); +} + +.lumo button.tox-mbtn.tox-mbtn--select.tox-mbtn--active { + background: var(--lumo-primary-color-50pct); + color: var(--lumo-primary-contrast-color); +} + +.lumo .tox-menubar > button.tox-mbtn.tox-mbtn--select:hover:not(:disabled) { + background: var(--lumo-primary-color-10pct); +} + +.lumo button.tox-mbtn.tox-mbtn--select { + color: var(--lumo-body-text-color); + font-size: var(--lumo-font-size-m); +} + +.lumo button.tox-tbtn.tox-tbtn--select.tox-tbtn--bespoke { + color: var(--lumo-body-text-color); +} + +.lumo .tox-menu.tox-collection.tox-collection--list.tox-selected-menu { + border-radius: var(--lumo-border-radius-m); +} + +.lumo .tox-menu.tox-collection.tox-collection--list { + background: var(--lumo-base-color); + box-shadow: var(--lumo-box-shadow-m); +} + +.lumo .tox .tox-menu.tox-collection--list .tox-collection__item.tox-collection__item--active { + color: var(--lumo-body-text-color); + background-color: var(--lumo-primary-color-10pct); +} + +.lumo .tox-menu-nav__js.tox-collection__item.tox-collection__item { + color: var(--lumo-body-text-color); +} + +.lumo .tox .tox-collection > .tox-collection__group { + border-color: var(--lumo-contrast-20pct) !important; + padding-top: var(--lumo-space-s) !important; + padding-bottom: var(--lumo-space-s) !important; +} + +.lumo div.tox-collection__item > div.tox-collection__item-accessory { + color: var(--lumo-secondary-text-color); +} + +.lumo div.tox-collection__item > div.tox-collection__item-label { + font-size: var(--lumo-font-size-m); + line-height: var(--lumo-line-height-m); +} + +.lumo div.tox-collection__item > div.tox-collection__item-icon { + width: var(--lumo-size-s); + height: var(--lumo-size-s); +} + +.lumo .tox .tox-collection__item > .tox-collection__item-caret svg { + fill: var(--lumo-contrast-50pct); +} + +.lumo .tox .tox-fancymenuitem .tox-insert-table-picker .tox-insert-table-picker__selected { + background-color: var(--lumo-primary-color-10pct); + border-color: var(--lumo-primary-color-50pct); +} + +.lumo .tox .tox-fancymenuitem .tox-insert-table-picker .tox-insert-table-picker { + border-color: var(--lumo-contrast-20pct); +} diff --git a/src/main/resources/META-INF/resources/frontend/tinymceLumo.css b/src/main/resources/META-INF/resources/frontend/tinymceLumo.css deleted file mode 100644 index 13f0813..0000000 --- a/src/main/resources/META-INF/resources/frontend/tinymceLumo.css +++ /dev/null @@ -1,154 +0,0 @@ -.tox .tox-editor-header > .tox-menubar { - background-color: var(--lumo-contrast-5pct); - padding-left: var(--lumo-space-s); - padding-right: var(--lumo-space-s); -} - -.tox .tox-editor-container .tox-editor-header .tox-toolbar-overlord > .tox-toolbar__primary { - background-color: var(--lumo-contrast-5pct); - padding-left: var(--lumo-space-s); - padding-right: var(--lumo-space-s); - border-top: unset; -} - -.tox .tox-editor-container .tox-editor-header:not(.tox-tinymce-inline) { - box-shadow: var(--lumo-box-shadow-xs); - padding: 0px; -} - -.tox .tox-editor-container .tox-editor-header .tox-toolbar-overlord { - border-top: unset; - margin: 0px; - padding: 0px; -} - -.tox:not([dir=rtl]) .tox-toolbar-overlord .tox-toolbar__group:not(:last-of-type) { - border-right: 1px solid var(--lumo-contrast-20pct); -} - -.tox button.tox-tbtn--enabled { - background: var(--lumo-primary-color); -} - -.tox button.tox-tbtn--enabled:hover { - background: var(--lumo-primary-color); -} - -.tox button.tox-tbtn:hover { - background: var(--lumo-contrast-10pct); -} - -.tox .tox-tbtn--disabled[aria-disabled="true"] .tox-icon > svg { - fill: var(--lumo-contrast-20pct); -} - -.tox .tox-tbtn .tox-icon > svg { - fill: var(--lumo-contrast-60pct); -} - -.tox .tox-tbtn--enabled .tox-icon > svg { - fill: var(--lumo-primary-contrast-color); -} - -.tox .tox-tbtn--enabled:hover .tox-icon > svg { - fill: var(--lumo-primary-contrast-color); -} - -.tox.tox-tinymce { - border: 1px solid var(--lumo-contrast-20pct); - border-radius: var(--lumo-border-radius-m); -} - -.tox .tox-statusbar__text-container .tox-statusbar__path-item { - color: var(--lumo-secondary-text-color); -} - -.tox .tox-statusbar__text-container .tox-statusbar__path-divider { - color: var(--lumo-secondary-text-color); -} - -.tox .tox-statusbar__text-container { - font-size: var(--lumo-font-size-s); -} - -button.tox-mbtn.tox-mbtn--select.tox-mbtn--active { - background: var(--lumo-primary-color-50pct); - color: var(--lumo-primary-contrast-color); -} - -.tox-menubar > button.tox-mbtn.tox-mbtn--select:hover:not(:disabled) { - background: var(--lumo-primary-color-10pct); -} - -button.tox-mbtn.tox-mbtn--select { - color: var(--lumo-body-text-color); - font-size: var(--lumo-font-size-m); -} - -button.tox-tbtn.tox-tbtn--select.tox-tbtn--bespoke { - color: var(--lumo-body-text-color); -} - -.tox-menu.tox-collection.tox-collection--list.tox-selected-menu { - border-radius: var(--lumo-border-radius-m); -} - -.tox-menu.tox-collection.tox-collection--list { - background: var(--lumo-base-color); - box-shadow: var(--lumo-box-shadow-s); - box-shadow: var(--lumo-box-shadow-m); -} - -.tox .tox-menu.tox-collection--list .tox-collection__item.tox-collection__item--active { - color: var(--lumo-body-text-color); - background-color: var(--lumo-primary-color-10pct); -} - -.tox .tox-menu.tox-collection.tox-collection--list { - min-width: var(--tiny-mce-menu-width, 300px); -} - -.tox-menu-nav__js.tox-collection__item.tox-collection__item { - color: var(--lumo-body-text-color); -} - -.tox .tox-collection > .tox-collection__group { - border-color: var(--lumo-contrast-20pct) !important; - padding-top: var(--lumo-space-s) !important; - padding-bottom: var(--lumo-space-s) !important; -} - -div.tox-collection__item > div.tox-collection__item-accessory { - color: var(--lumo-secondary-text-color); -} - -div.tox-collection__item > div.tox-collection__item-label { - font-size: var(--lumo-font-size-m); - line-height: var(--lumo-line-height-m); -} - -div.tox-collection__item > div.tox-collection__item-icon { - width: var(--lumo-size-s); - height: var(--lumo-size-s); -} - -.tox .tox-collection__item > .tox-collection__item-caret svg { - fill: var(--lumo-contrast-50pct); -} - -.tox .tox-fancymenuitem .tox-insert-table-picker .tox-insert-table-picker__selected { - background-color: var(--lumo-primary-color-10pct); - border-color: var(--lumo-primary-color-50pct); -} - -.tox .tox-fancymenuitem .tox-insert-table-picker .tox-insert-table-picker { - border-color: var(--lumo-contrast-20pct); -} - -.tinymce-flow[readonly] .tox-editor-header { - display: none; -} - -.tinymce-flow[disabled]:not([readonly]) { - opacity: 0.5; -} \ No newline at end of file