Please read - I would really like feedback on this proposal re documentation

Would "Deep dives" into the Wappler .js components be useful for those looking to extend or interface directly from .js? (yes, it's AI generated). Sorry, some sections repeated, it's just a concept demo! (been cleaned up)
Something like:

:jigsaw: Component Overview

This defines a custom Wappler component called summernote, which wraps the Summernote WYSIWYG editor with reactive bindings, configuration options, and event handling.


:gear: Initial State & Attributes

Initial Data

initialData: {
  disabled: false,
  value: ""
}

Supported Attributes

These are the props you can pass to the component:

Attribute Type Default Description
value String "" Initial content of the editor
disabled Boolean false Whether the editor is disabled
config Object {} Custom Summernote config
height, minHeight, maxHeight Number null Editor height settings
autofocus Boolean false Auto-focus on load
lang String "en-US" Language setting
airMode Boolean false Enables Air Mode (inline editing)
toolbar, toolbarImage, toolbarLink, toolbarTable, toolbarAir Array null Toolbar configurations
blockquoteBreakingLevel Number 2 Controls blockquote behavior
styleTags, fontNames, fontNamesIgnoreCheck, fontSizeUnits, lineHeights Array null Styling options
placeholder String null Placeholder text
dialogsInBody, dialogsFade Boolean false Dialog behavior
disableDrop, disableShortcuts, disableTab, disableSpellcheck, disableGrammar Boolean false Feature toggles
codeviewFilter, codeviewIframeFilter Boolean true Security filters
plugins, buttons Object {} Custom plugins and buttons

:brain: Methods

These are exposed methods you can call on the component:

  • enable() / disable() β€” toggle editor state
  • empty() β€” clear content
  • insertText(text) β€” insert plain text
  • pasteHTML(html) β€” insert HTML
  • undo() / redo() / reset() β€” history actions
  • setValue(value) β€” set content programmatically
  • status(msg) / info(msg) / success(msg) / warning(msg) / danger(msg) β€” show status messages
  • invoke(method, args) β€” call any Summernote method directly

:satellite: Events

These are dispatched by the component:

  • init, focus, blur, enter, change, changed, input, updated
  • buttonclick β€” when a custom button is clicked
  • mediadelete β€” when media is removed

:dna: Lifecycle Hooks

  • init() β€” sets up debounce handlers and Summernote callbacks
  • render(el) β€” sets initial content and initializes the editor
  • performUpdate(changes) β€” reacts to prop changes
  • destroy() β€” cleans up the editor

:brick: Internal Logic Highlights

  • Toolbar Filtering: Only includes non-empty toolbar groups.
  • Popover Setup: Dynamically configures popovers for image, link, table, and air toolbars.
  • Language Check: Logs an error if the specified language file isn’t loaded.
  • Custom Buttons & Plugins: Watches for plugin and button attributes and dynamically registers them using Summernote’s UI API.

:test_tube: Utility Functions

  • _toCamelCase(str) β€” converts kebab-case to camelCase
  • $parseAttributes(el) β€” parses dynamic attributes like plugin and button and wires them into the editor

:compass: Visual Flow: Component Lifecycle & Interaction

[Attributes] ──▢ [Initialization] ──▢ [Editor Setup] ──▢ [User Interaction]
     β”‚                β”‚                    β”‚                    β”‚
     β–Ό                β–Ό                    β–Ό                    β–Ό
  Props like:     init() binds        render() sets        Events like:
  value, config   callbacks &         initial value        focus, blur,
  toolbar, etc.   debounce logic      & calls _initEditor  change, input
     β”‚                β”‚                    β”‚                    β”‚
     β–Ό                β–Ό                    β–Ό                    β–Ό
  performUpdate() ──▢ _initEditor() ──▢ Summernote API ──▢ dispatchEvent()

:brick: Modular Breakdown

1. Initialization

init() {
  this._initEditor = debounce(this._initEditor.bind(this));
  this._callbacks = {
    callbacks: {
      onBlur: this._blurHandler,
      onChange: this._changeHandler,
      ...
    }
  };
}

2. Editor Setup

render(el) {
  if (this.props.value) {
    el.tagName === "TEXTAREA" ? el.value = this.props.value : el.innerHTML = this.props.value;
  }
  this._initEditor();
}

3. Dynamic Updates

performUpdate(changes) {
  if (changes.has("value")) this._setValue(this.props.value);
  if (changes.has("disabled")) this._editor.invoke(this.props.disabled ? "disable" : "enable");
}

4. Custom Buttons & Plugins

$parseAttributes(el) {
  watch("plugin", value => {
    this.props.plugins[camelCase(arg)] = { ...defaults, ...value };
  });
  watch("button", value => {
    this.props.buttons[camelCase(arg)] = () => createButton(value);
  });
}

I think that gets a bit to technical and most of that information is not relevant. You could add it in some reference section but that would probably only need the list of attributes, methods, events and data of the component. The whole internal logic of a component is not needed.

Thanks for the feedback patrick.
Yes, it's pretty niche in value and it would be placed in a drilldown node below the main component tutorial so would not significantly interfere with the flow of the overall tree based layout.
I was just playing while drinking morning cuppa and thought i would as the question to users as it is so easy to add. Plenty to do before i get to that stage!

I'm a bit late to the party on this one, been away a lot.

This is a desperately needed addition to the Wappler stable - If anyone has the skills, patience and nous to do this its Brian. It looks like its getting a lot of support so I'd also like to put my skills forward for whatever may come up - I've had the benefit of creating some fairly unusual elements so I'm confident I can provide a little value to the project.

I say this repeatedly, It's also great to put something back in to this Forum, gives me warm, squishy feeling deep down inside my giblets :slight_smile:

3 Likes

Everything going well (even though i have been called for 2 weeks jury service and spending all day sitting in a courtroom).

Inital content has been correlated with current forum docs, existing videos integrated and editor functions being finalised. Missing content has been generated via AI ready for the "human touch" via contributers.

Additioanlly, users will have the ability to feedback to editors about any perceived errors or omissions which will generate a review task for the editor team. We are all in this together!

I hope to release the editor console to beta in 10-14 days, well ahead of schedule to give contributters a chance to review and where necessary update the content before initial public release.

Lots more exciting stuff to come!

8 Likes

Great work Brian - look forward to seeing it in action.