FormModeler Properties Panel Provider - useContext error when using an entry component

Hello everyone;

I am trying to implement my properties panel provider for the FormModeler.

I followed both custom components ( form-js-examples/custom-components at master · bpmn-io/form-js-examples) and custom button ( form-js-examples/custom-button at master · bpmn-io/form-js-examples) examples.

Setup of provider and linking it to FormModeler (via additionalModules) are all fine. I can modify groups and entries in them but having context (Preact related?) error when trying to re-use any entry component from @bpmn-io/properties-panel.

This is my code:

import { isNumberFieldEntryEdited, NumberFieldEntry } from '@bpmn-io/properties-panel';

export default class DSFormPropertiesProvider {

    // registraton is fine
    constructor(propertiesPanel) {
        propertiesPanel.registerProvider(this, LOW_PRIORITY);
    }

    getGroups(field, editField) {
        return (groups) => {
            // please see below for how group entries are created 
            groups.push(this.createMyCustomGroup(field, editField));

            return groups;
        };
    }

    createMyCustomGroup(field, editField) {
        // these functions are mostly copy paste from samples:
        const onChange = (key) => {
            return (value) => {
                const style = get(field, ['style'], {});
                editField(field, ['style'], set(style, [key], value));
            };
        };

        const getValue = (key) => {
            return () => {
                return get(field, ['style', key]);
            };
        };

        const debounce = (fn) => fn;

        return {
           id: 'style',
           label: 'Style',
           entries: [
               {
                   id: 'my-custom-property-id',
                   // I have context related error here
                   component: () => NumberFieldEntry({
                       debounce,
                       element: field,
                       getValue: getValue('min'),
                       id,
                       label: 'Minimum',
                       setValue: onChange('min')
                   }),
                   getValue,
                   field,
                   isEdited: isNumberFieldEntryEdited,
                   onChange
               }
           ]
      };
  }

  // inject panel
  DSFormPropertiesProvider.$inject = [
    "propertiesPanel"
  ];

The error is:

Uncaught TypeError: Cannot read properties of null (reading 'context')

at q2 (index.js:344:19)
at useError (useError.js:6:22)
at NumberFieldEntry (NumberField.js:117:23)
at x.component [as constructor] (DSFormPropertiesProvider.js:55:38)
at x.B [as render] (index.js:659:14)
at j (index.js:240:14)
at $ (children.js:96:16)
at j (index.js:262:13)
at $ (children.js:96:16)
at N (index.js:527:4)

I have same problem with TextFieldEntry, SelectEntry etc. Seems like useError hook in entry components try to find ErrorContext but something is wrong.

I implemented a custom properties panel provider for BPMN Modeler too and had no problem re-using eg TextFieldEntry the same way.

The only difference I can see from samples are they are using FormPlayground and linking custom provider using editorAdditionalModules. Instead I am using FormModeler directly and linking my provider via additionalModules as in here:

    ....
    new FormEditor({
        container: container,
        additionalModules: [
            DSFormPropertiesProvider // my provider
        ]
    });
   ....

This is a React + Vite project I am working on. What is it I am doing wrong ?

Thank you.

Hi all;

I could not solve the problem yet, can it be because of multiple Preact versions in same project ?

I can see that form-js-editor pulls in Preact “10.5.14” and diagram-js (that I use for my custom BPMN Renderer) pulls in Preact “10.11.2”.

Did anyone tried providing both BPMN and Form properties panel in single project ?

Your extension likely bundles its own version of Preact, which creates a separate Preact instance, leading to issues like mismatched contexts.

To fix this issue, externalize preact in your extension’s bundler (e.g., Vite).

Thanks for the answer @philippfromme but I am not sure how to “externalize preact” as I am not including preact directly in my package.json.

When I search my package-lock.json I see 5 mentions of preact with 3 different versions:

“node_modules/@bpmn-io/diagram-js-ui”: { => “preact”: “^10.11.2”
“node_modules/@bpmn-io/form-js-editor”: { => “preact”: “^10.5.14”
“node_modules/@bpmn-io/form-js-playground”: { => “preact”: “^10.5.14”
“node_modules/@bpmn-io/form-js-viewer”: { => “preact”: “^10.5.14”
“node_modules/preact”: { => “version”: “10.26.4”

I know that this is not a Vite forum but any help will be appreciated:

1-) I tried with “resolve.dedupe” option in vite.config.ts:

 export default defineConfig({
   ...
   resolve: {
     dedupe: ['preact']
   }
 })

2-) There are some Vite “externalize dependency” plugins available from community. I think I managed to exclude preact (may be too muchh - all of them?) but then I have

preact not defined

Can you point me to right direction please ?