Extending Features¶
SciFlow’s feature system keeps schema nodes, commands, and UI wiring isolated. Use this guide when you need to add a new capability or tweak an existing one.
Feature Anatomy¶
A feature lives under packages/editor/core/src/lib/features/<name> and typically exports:
Featureobject (name,initialize, optionalplugins,nodeViews).- Commands registered via
registerCommands. - Node views (Lit or vanilla) when the feature requires custom rendering.
export const figureFeature: Feature = {
name: 'figure',
initialize() {
registerCommands({
insertFigure:
(options: InsertFigureOptions) =>
(props) => runInsertFigure(props.state, options, getDispatch(props)),
});
},
nodeViews() {
return { figure: createDecoratedNodeViewFactory(FigureNodeView) };
},
};
Adding a New Feature¶
- Create the schema node (if required) under
packages/schema. - Add commands that manipulate the node or mark.
- Register ProseMirror plugins via the feature’s
addPluginshook (drop handlers, keymaps, etc.). - Expose UI hooks in the start package (toolbar buttons, dialogs, custom panels).
- Wire feature toggles – include the new feature in the
FEATURE_OPTIONSarray in the demo so QA can enable/disable it quickly.
Reuse helpers
The command system already provides getDispatch, withCommandRegistration, and flow helpers. Prefer them over hand-rolled dispatch logic to keep flows and availability checks working.
Testing Strategy¶
- Unit test commands in isolation (Vitest) by instantiating a ProseMirror state and running the command function.
- Add integration tests in
packages/editor/core/src/lib/features/<feature>/<feature>.spec.tsif the feature already has a suite. - Exercise node views in the demo to ensure Lit bindings update as expected.
Surfacing Feature APIs to Consumers¶
- Re-export the command helpers (e.g.,
runInsertFigure) from the feature index so downstream apps can call them with custom dispatchers. - Document any additional attributes/events in the User Guide (Customization or Packages chapters).
Updating the Web Components¶
- If the feature requires UI controls, modify
packages/editor/start/src/lib/format-bar.tsor add a dedicated panel. - Keep accessibility glued together (ARIA labels, keyboard interactions) to match existing nodes (heading, citations, etc.).
Feature toggles vs. bundles
Features are tree-shakeable: only the ones you register in editor.configureFeatures() end up active. This keeps the runtime lean even as the feature set grows.