@itwin/property-grid-react
TypeScript icon, indicating that this package has built-in type declarations

1.7.0 • Public • Published

@itwin/property-grid-react

Copyright © Bentley Systems, Incorporated. All rights reserved.

The @itwin/property-grid-react package provides React components to build a properties widget that shows properties of selected element(s).

Widget example

Usage

Typically, the package is used with an AppUI based application, but the building blocks may as well be used with any other iTwin.js React app.

In any case, before using any APIs or components delivered with the package, it needs to be initialized:

import { IModelApp } from "@itwin/core-frontend";
import { PropertyGridManager } from "@itwin/property-grid-react";
...
await PropertyGridManager.initialize(IModelApp.localization);

In AppUI based applications widgets are typically provided using UiItemsProvider implementations. The @itwin/property-grid-react package delivers PropertyGridUiItemsProvider that can be used to add the properties widget to UI:

import { UiItemsManager } from "@itwin/appui-abstract";
import { PropertyGridUiItemsProvider } from "@itwin/property-grid-react";
...
UiItemsManager.register(
  new PropertyGridUiItemsProvider()
);

The above example uses default widget parameters and results in a component similar to the one visible at the top of this README.

Customization is also possible:

import { UiItemsManager } from "@itwin/appui-react";
import {
  PropertyGridUiItemsProvider,
  AncestorsNavigationControls,
  AddFavoritePropertyContextMenuItem,
  RemoveFavoritePropertyContextMenuItem,
  CopyPropertyTextContextMenuItem,
  ShowHideNullValuesSettingsMenuItem,
  IModelAppUserPreferencesStorage,
} from "@itwin/property-grid-react";
...
UiItemsManager.register(
  new PropertyGridUiItemsProvider({
    // defaults to `StagePanelLocation.Right`
    defaultPanelLocation: StagePanelLocation.Left,

    // defaults to `StagePanelSection.End`
    defaultPanelSection: StagePanelSection.Start,

    // defaults to whatever the default `Widget.priority` in AppUI is
    defaultPanelWidgetPriority: 1000,

    // supplies props for the `PropertyGridComponent`
    propertyGridProps: {
      // enable auto-expanding all property categories
      autoExpandChildCategories: true,

      // enable ancestor navigation by supplying a component for that
      ancestorsNavigationControls: (props) => <AncestorsNavigationControls {...props} />,

      // the list populates the context menu shown when a property is right-clicked.
      contextMenuItems: [
        // allows adding properties to favorites list
        (props) => <AddFavoritePropertyContextMenuItem {...props} />,
        // allows removing properties from favorites list
        (props) => <RemoveFavoritePropertyContextMenuItem {...props} />,
        // allows copying property values
        (props) => <CopyPropertyTextContextMenuItem {...props} />,
      ],

      // the list populates the settings menu
      settingsMenuItems: [
        // allows hiding properties without values
        (props) => <ShowHideNullValuesSettingsMenuItem {...props} persist={true} />,
      ],

      // supply an optional custom storage for user preferences, e.g. the show/hide null values used above
      preferencesStorage: new IModelAppUserPreferencesStorage("my-favorites-namespace"),

      // supply an optional data provider factory method to create a custom property data provider
      createDataProvider: (imodel: IModelConnection) => new PresentationPropertyDataProvider({ imodel, ruleset: MY_CUSTOM_RULESET }),

      // ... and a number of props of `VirtualizedPropertyGridWithDataProvider` from `@itwin/components-react` is also accepted here
    },
  }),
);

As seen in the above code snippet, PropertyGridUiItemsProvider takes a number of props that allow customizing not only how the widget behaves, but also how it looks. The package delivers commonly used building blocks:

  • context and setting menu items
  • ancestor navigation controls
  • preferences storage that uses IModelApp.preferences

Consumers are free to use those blocks or replace them with their own.

Multi-element workflow

The property grid is most useful when viewing properties of a single element. When multiple elements are selected, their properties and values get merged together:

Properties of multi-element selection

Clicking the "Selected Elements" button opens an element list, which lets you pick one specific element from the selection:

Selected elements list

Selecting a specific element opens properties for it specifically:

Properties of a single element from elements list

Ancestor navigation

When ancestorsNavigationControls prop is provided, the widget allows navigating up/down the elements' hierarchy (though bis.ElementOwnsChildElements relationship):

Ancestor navigation

Note that ancestor navigation is only rendered when there's only one element selected and it has a parent.

Context menu

When the user right clicks on a specific property, a context menu is displayed if at least one context menu item is provided through contextMenuItems prop:

Context menu

Favorite properties

The package delivers two context menu item components for adding properties to and removing them from favorite properties list: AddFavoritePropertyContextMenuItem and RemoveFavoritePropertyContextMenuItem. When selected element contains at least one favorite property, a new "Favorite" category is rendered at the top:

Favorite properties

Opening context menu for such properties now renders "Remove from Favorite" instead of "Add to Favorite":

Remove favorite property

Copy value

The package delivers CopyPropertyTextContextMenuItem component that allows copying selected property value to clipboard.

Custom context menu items

Adding a custom context menu item can be done as follows:

Define a menu item component:

function ExampleContextMenuItem(props: ContextMenuItemProps) {
  return (
    // render using `PropertyGridContextMenuItem` to get consistent style
    <PropertyGridContextMenuItem
      id="example"
      onSelect={async () => {
        console.log(`Selected property: ${props.record.property.displayLabel}`);
      }}
    >
      Click me!
    </PropertyGridContextMenuItem>
  );
}

Provide it to the widget:

new PropertyGridUiItemsProvider({
  propertyGridProps: {
    contextMenuItems: [(props) => <ExampleContextMenuItem {...props} />],
  },
});

Result:

Custom context menu item

Settings menu

The settings menu is an entry point for various settings that apply to the widget. It can be accessed by clicking on the three dots button on the right:

Widget settings menu

The entry point is only rendered if there's at least one settings menu item provided through the settingsMenuItems prop.

Hiding empty values

The package delivers ShowHideNullValuesSettingsMenuItem that allows users to hide / show properties that don't have values:

Empty values displayed Empty values hidden
Empty values displayed Empty values hidden

Custom setting menu items

Adding a custom settings menu item can be done as follows:

Define a menu item component:

function ExampleSettingsMenuItem() {
  return (
    // render using `PropertyGridSettingsMenuItem` to get consistent style
    <PropertyGridSettingsMenuItem
      id="example"
      onClick={() => {
        console.log("Settings menu clicked!");
      }}
    >
      Click me!
    </PropertyGridSettingsMenuItem>
  );
}

Provide it to the widget:

new PropertyGridUiItemsProvider({
  propertyGridProps: {
    settingsMenuItems: [(props) => <ExampleSettingsMenuItem />],
  },
});

Result:

Custom settings menu item

Property filtering

Property grid allows its users to filter out properties of an element based on text input.

When an item is selected, click the magnifying glass button and notice the search bar expand.

Search bar closed Search bar opened
Search bar closed Search bar opened

One can type into the search bar and notice how properties are automatically filtered based on the search bar input:

Widget search bar expanded

Note that when the search bar is closed, the filter is discarded and all properties are visible again.

Performance tracking

Components from this package allows consumers to track performance of specific features.

This can be achieved by passing onPerformanceMeasured function to PropertyGridComponent or PropertyGridUiItemsProvider. The function is invoked with feature id and time elapsed as the component is being used. List of tracked features:

  • "properties-load" - time it takes to load properties data after selection changes.
  • "elements-list-load" - time it takes to populate elements list when multiple elements are selected.

Example:

new PropertyGridUiItemsProvider({
  propertyGridProps: {
    onPerformanceMeasured: (feature, elapsedTime) => {
      telemetryClient.log(`PropertyGrid [${feature}] took ${elapsedTime} ms`);
    },
  },
});

To track performance of individual components when using them directly, rather than through PropertyGridUiItemsProvider, the onPerformanceMeasured callback should be supplied through TelemetryContextProvider:

return (
  <TelemetryContextProvider
    onPerformanceMeasured={(feature, elapsedTime) => {
      telemetryClient.log(`PropertyGrid [${feature}] took ${elapsedTime} ms`);
    }}
  >
    <PropertyGrid />
  </TelemetryContextProvider>
);

Package Sidebar

Install

npm i @itwin/property-grid-react

Weekly Downloads

1,994

Version

1.7.0

License

MIT

Unpacked Size

544 kB

Total Files

165

Last publish

Collaborators

  • wgoehrig
  • cshafer
  • aruniverse
  • imodeljs
  • colinkerr