Custom property category renderers

This page explains how to leverage custom category renderers to create fully customizable property categories for VirtualizedPropertyGrid.

Defining a custom category

To make use of custom category rendering system, we will need to define a custom category and assign it a renderer with Presentation Rules. This is achievable using PropertyCategorySpecification:

...
  },
  "propertyCategories": [
    {
      "id": "my_custom_category",
      "label": "My Custom Category",
      "renderer": {
        "rendererName": "my_custom_renderer"
      }
    },
...

Now when my_custom_category is expanded, my_custom_renderer will be invoked to render properties assigned to this category. To learn more on property mapping to categories, visit Property Categorization page.

Registering a custom renderer

In order to tell the VirtualizedPropertyGrid which React component my_custom_renderer refers to, we will need to register a component factory under this custom renderer name:

PropertyCategoryRendererManager.defaultManager.addRenderer("my_custom_renderer", () => MyCustomRenderer);

const MyCustomRenderer: React.FC<PropertyCategoryRendererProps> = (props) => {
  const primitiveItems = props.categoryItem.getChildren().filter((item) => item.type === FlatGridItemType.Primitive) as CategorizedPropertyItem[];

  return (
    <>
      {primitiveItems.map((item) => {
        return (
          <PrimitivePropertyRenderer
            key={item.key}
            propertyRecord={item.derivedRecord}
            valueElement={PropertyValueRendererManager.defaultManager.render(item.derivedRecord)}
            orientation={props.gridContext.orientation}
          />
        );
      })}
    </>
  );
};

Once the code above is run, VirtualizedPropertyGrid will render contents of my_custom_category using our new custom component, which currently displays primitive properties encountered in this category.

Connecting properties to instances

Sometimes we need to know which instance(s) a specific PropertyRecord refers to. If we know that PresentationPropertyDataProvider is being used to load properties into the grid, then the instance keys could be retrieved the following way:

// <Somewhere within MyCustomRenderer component>
useEffect(
  () => {
    void (async () => {
      const properties = props.categoryItem.getChildren() as CategorizedPropertyItem[];
      const dataProvider = props.gridContext.dataProvider as PresentationPropertyDataProvider;
      const instanceKeys = properties.map(async ({ derivedRecord }) => dataProvider.getPropertyRecordInstanceKeys(derivedRecord));
      setInstanceKeys(await Promise.all(instanceKeys));
    })();
  },
  // eslint-disable-next-line react-hooks/exhaustive-deps
  [],
);

Last Updated: 15 May, 2024