Files
SCM-Manager/scm-ui/ui-extensions
Sebastian Sdorra 2ab2079e07 prop transformer and binding of react elements
The ExtensionPoint component supports now the transformation of instance props and allows binding of already instantiated react components (Foo vs <Foo />).
2020-03-30 15:00:30 +02:00
..
2019-10-21 14:10:48 +02:00

ui-extensions

UI-Extensions contains the building blocks for the SCM-Manager ui extension system.

Extensions and ExtensionPoints

Extension points are spots in the ui, where the ui could be extended or modified. An extension point requires a unique name and is represented as React component.

Example:

<div>
  <h2>Repository</h2>
  <ExtensionPoint name="repo.details" />
</div>

We can register an extension, in the form of a React component, to the "repo.details" extension point, by using the binder:

import { binder } from "@scm-manager/ui-extensions";

const Rtfm = () => {
  return <strong>Read the f*** manual</strong>;
};

binder.bind("repo.details", Rtfm);

The ExtensionPoint will now find and render the Rtfm component.

Render multiple extensions

An extension point can render multiple extensions at one. This can be done with the renderAll parameter:

<div>
  <h2>Repository</h2>
  <ExtensionPoint name="repo.details" renderAll={true} />
</div>

Now we can bind multiple components to the same extension point.

const Rtfm = () => {
  return <strong>Read the f*** manual</strong>;
};

const RealyRtfm = () => {
  return <h1>Read the f*** manual</h1>;
};

binder.bind("repo.details", Rtfm);
binder.bind("repo.details", RealyRtfm);

Passing props to extensions

An extension point author can pass React properties to the extensions. This can be done with the props property:

<div>
  <ExtensionPoint name="repo.title" props={{name: "myrepo"}} />
</div>

The extension becomes now the defined react properties as input:

const Title = (props) => {
  return <h1>Repository {props.name}</h1>;
};

binder.bind("repo.title", Title);

Defaults

An ExtensionPoint is able to render a default, if no extension is bound to the ExtensionPoint. The default can be passed as React children:

<ExtensionPoint name="repo.title">
  <h1>Default Title</h1>
</ExtensionPoint>

Conditional rendering

An extension can specify a predicate function to the binder. This function becomes the props of the ExtensionPoint as input and only if the predicate returns true the extension will be rendered:

const GitAvatar = () => {
  return <img src="/git/avatar.png" alt="git avatar" />;
};

binder.bind("repo.avatar", GitAvatar, (props) => props.type === "git");
<ExtensionPoint name="repo.avatar" props={type: "git"} />