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: 29 April, 2025