sprotty icon indicating copy to clipboard operation
sprotty copied to clipboard

Complex and dynamic content with UIExtensions?

Open christoph-fricke opened this issue 3 years ago • 3 comments

I am currently looking into the ability to show an trigger-able options panel on top of a diagram. The possible options are dynamically provided by a remote diagram source. I initially thought that such UI would have to be handled outside of Sprotty, similar to the npm-dependency-graph standalone app. After stumbling on the commit that introduced UIExtensions, I think it might be possible to achieve this with UIExtensions instead of an abstraction layer on top of the diagram. Do you agree?

The only example usage of UIExtensions appears to be the CommandPalette and EditLabelUI. Both use imperative dom apis to create and configure the ui extension content. My fear is that this approach will not scale well for my use case and will quickly become unpleasant to work with. I would like to have a more ergonomic approach and be able to describe the content declaratively with JSX. Is this already possible? Other parts in Sprotty already use snabbdom as a declarative approach.

The best I got is this:

/** @jsx html */
import { html } from "snabbdom-jsx";
import toHTML from "snabbdom-to-html";

import { inject } from "inversify";
import { AbstractUIExtension } from "sprotty";

export class OptionsUIExtension extends AbstractUIExtension {
  static readonly ID = "options-overlay";

  id(): string {
    return OptionsUIExtension.ID;
  }

  containerClass(): string {
    return "options-overlay";
  }

  protected initializeContents(containerElement: HTMLElement): void {
    // This is nowhere near perfect as it is not possible to add a click handler to the button
    // or a class/className to an element...
    containerElement.innerHTML = toHTML(
      <div>
        <p>Content of the Options View</p>
        <button>Close</button>
      </div>
    );
    containerElement.setAttribute("role", "dialog");
  }
}

christoph-fricke avatar Apr 26 '21 14:04 christoph-fricke

We haven't tried using Snabbdom for UI extensions yet, but it should be possible. The code snippet above does not make use of the Snabbdom virtual DOM, so it might not scale well. Use the patch function as described in the documentation.

That said, I think it's totally fine to implement additional UI as an overlay above the diagram. That way you are free to use any UI framework you like. You may need to separate the code if you're using another JSX library, though. For example, snabbdom-jsx is not compatible with React.

spoenemann avatar Apr 30 '21 06:04 spoenemann

@spoenemann Thank you for your feedback. I am currently focusing on a few other things but will get back to this soon. My plan is to continue to explore UIExtensions and possibly integrate snabbdom with them. I can keep you updated about the journey if you are interested. :+1:

christoph-fricke avatar May 07 '21 09:05 christoph-fricke

Hi @spoenemann. :wave: I have been indeed able to use UI extenions with Snabbdom and the patch function provided by the PatcherProvider in Sprotty. The result is a sidebar floating above the diagram to display arbitrarily UI, which content is rendered with Snabbdom. In fact, the UI extension implementation inspired me to build an API abstraction for the sidebar, so new content can easily be added through the DI container. The implementation of the sidebar can be found here, in case you are interested.

Showcase of the UI extension floating above an diagram: uiextension-example

christoph-fricke avatar Jul 14 '21 10:07 christoph-fricke