This directory contains optional features that extend the app’s functionality when they are included and enabled.
If you are looking for an adapter that connects them to the app, check out @/features/plugins-core.
https://app.workflowbuilder.io/
Here is the full version of the Workflow Builder with plugins (e.g., edges, layout, widgets).
You can compare it with your local version.
- Allows users to create plugins in the plugin directory and remove them without breaking the app
- Vite serves stubs for removed plugins (there is a log in the console when it is served)
- ESLint warns users that they cannot import files directly from @/plugins and must use adapters
- Plugins can modify the base code, alter function inputs and outputs, add hooks, and customize prompts
- Plugins have an additional parameter priority, allowing the user to define which plugin should be applied first
If you want to see how the plugin logic works in a smaller example, we have prepared a showcase repository: https://github.com/synergycodes/optional-plugins-demo
- Create your plugin directory, for example:
plugins/example. - Add your
<ExampleComponent />toplugins/example/components/example-component.tsx. - In
plugins/example/plugin-exportsimport dependencies and add:
registerComponentDecorator('OptionalFooterContent', {
content: ExampleComponent,
place: 'after',
});- Import your plugin to
apps/demo/src/app/features/plugins-core/index.tswith lineimport '@/plugins/example/plugin-exports'; - Refresh the page.
Your component should now be displayed in the left sidebar (palette) footer.
Simply remove the folder of your plugin and restart the application. It will still work with empty stubs instead of registration.
Go to apps/demo/src/app/features/plugins-core/index.ts and remove the import there.
You have place and priority. Set place: 'before' to add your component before the content. The priority determines which plugin is shown first.
registerComponentDecorator('OptionalFooterContent', {
content: ExampleComponent,
place: 'after',
priority: 1,
});With the modifyProps property, you can change the properties passed to the plugin. For example, below we added a new label type dottedEdge to the diagram.
import { registerComponentDecorator } from '@workflowbuilder/sdk';
import type { DiagramContainerProps } from '@workflowbuilder/sdk';
registerComponentDecorator<DiagramContainerProps>('DiagramContainer', {
modifyProps: (props) => ({
...props,
edgeTypes: {
...props.edgeTypes,
dottedEdge: DottedEdge,
},
}),
});Set the name property for the injected content:
registerComponentDecorator('OptionalAppBarControls', {
content: TreeButton,
place: 'before',
name: 'TreeButton',
});Use the name property:
const wasTreePluginAdded = hasRegisteredComponentDecorator('OptionalAppBarControls', 'TreeButton');In your plugin-exports.ts file, you can add an if statement.
if (SHOULD_ADD_TREE_BUTTON === true) {
registerComponentDecorator('OptionalAppBarControls', {
content: TreeButton,
place: 'before',
});
}Set name property.
registerComponentDecorator('OptionalAppBarControls', {
content: TreeButton,
place: 'before',
name: 'TreeButton',
});Use name property.
if (hasRegisteredComponentDecorator('OptionalAppBarControls', 'TreeButton')) {
registerComponentDecorator('OptionalAppBarControls', {
content: SecondTreeButton,
place: 'before',
});
}The order in which plugins are imported in @features/plugins-core/index is important.