vaadin / flow-components

Java counterpart of Vaadin Web Components
82 stars 63 forks source link

RichTextEditor: add support for hiding toolbar buttons #6298

Open mvysny opened 1 month ago

mvysny commented 1 month ago

Describe your motivation

I want to severely limit the amount of formatting which the user can input via the toolbar buttons (e.g. I want to hide the code, subscript, superscript, image and link buttons). There looks to be no server-side API in RichTextEditor 23.4.0 to do that.

Describe the solution you'd like

setVisibleToolbarButtons(EnumSet<ToolbarButton>) would be great to have.

Describe alternatives you've considered

No response

Additional context

No response

web-padawan commented 1 month ago

Hiding these buttons is already doable with CSS e.g. using ::part() selectors like this:

vaadin-rich-text-editor::part(toolbar-group-block),
vaadin-rich-text-editor::part(toolbar-group-rich-text),
vaadin-rich-text-editor::part(toolbar-group-glyph-transformation) {
  display: none;
}
mvysny commented 1 month ago

True, but with Vaadin 23 that would require injecting styles into ShadowDOM of RichTextEditor; also I would have to create a css class for every combination of toolbar button that I'm using in my app.

tomivirkki commented 1 month ago

These part names are also available for RTE in Vaadin 23 so style injection should not be necessary

mvysny commented 1 month ago

Solved via this Java code:

public class Utils {
    public enum RichTextEditorToolbarButton {
        UNDO("btn-undo"),
        REDO("btn-redo"),
        BOLD("btn-bold"),
        ITALIC("btn-italic"),
        UNDERLINE("btn-underline"),
        STRIKE("btn-strike"),
        H1("btn-h1"),
        H2("btn-h2"),
        H3("btn-h3"),
        SUBSCRIPT("btn-subscript"),
        SUPERSCRIPT("btn-superscript"),
        OL("btn-ol"),
        UL("btn-ul"),
        LEFT_ALIGN("btn-left"),
        CENTER_ALIGN("btn-center"),
        RIGHT_ALIGN("btn-right"),
        IMAGE("btn-image"),
        LINK("btn-link"),
        BLOCKQUOTE("btn-blockquote"),
        CODE("btn-code"),
        RESET_FORMATTING("btn-clean");

        RichTextEditorToolbarButton(String javaScriptButtonId) {
            this.javaScriptButtonId = javaScriptButtonId;
        }

        public final String javaScriptButtonId;
    }

    public static void setVisibleToolbarButtons(RichTextEditor rte, EnumSet<RichTextEditorToolbarButton> buttons) {
        final List<String> visibleButtonIDs = buttons.stream().map(it -> it.javaScriptButtonId).collect(Collectors.toList());
        final JsonArray array = Json.createArray();
        for (int i = 0; i < visibleButtonIDs.size(); i++) {
            array.set(i, visibleButtonIDs.get(i));
        }
        rte.getElement().executeJs("Array.from(this._toolbar.getElementsByTagName(\"button\")).forEach(btn => btn.style.display = ($0.includes(btn.id) ? \"\" : \"none\"))", array);
    }
}