Skip to content

Presentation: Improve custom property value renderers' docs #3370

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@itwin/components-react",
"comment": "",
"type": "none"
}
],
"packageName": "@itwin/components-react"
}
2 changes: 1 addition & 1 deletion common/config/rush/browser-approved-packages.json
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@
},
{
"name": "@testing-library/react",
"allowedCategories": [ "extensions", "frontend" ]
"allowedCategories": [ "extensions", "frontend", "internal" ]
},
{
"name": "@testing-library/react-hooks",
Expand Down
10 changes: 2 additions & 8 deletions common/config/rush/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion docs/changehistory/2.16.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ instance. The related instance, possibly being a of a different ECClass, might h

### Custom category renderers

[VirtualizedPropertyGrid]($components-react) now allows developers to fully customize displayed category contents, if the category is assigned a custom renderer via Presentation Rules. You can read more about that in our [Category customization learning page](../presentation/Customization/PropertyCategoryRenderers.md).
[VirtualizedPropertyGrid]($components-react) now allows developers to fully customize displayed category contents, if the category is assigned a custom renderer via Presentation Rules. You can read more about that in our [Category customization learning page](../presentation/Content/PropertyCategoryRenderers.md).

### Custom category nesting

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This page explains how to leverage custom category renderers to create fully cus

## 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](../Content/PropertyCategorySpecification.md):
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](./PropertyCategorySpecification.md):

```json
...
Expand All @@ -20,7 +20,7 @@ To make use of custom category rendering system, we will need to define a custom
...
```

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](../Content/PropertyCategorization.md) page.
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](./PropertyCategorization.md) page.

## Registering a custom renderer

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ Custom category [renderer specification](./RendererSpecification.md) that allows
in UI. This specification is used to set up [CategoryDescription.renderer]($presentation-common) for this category and it's up to
the UI component to make sure appropriate renderer is used to render the category.

See [Custom property category renderers](../Customization/PropertyCategoryRenderers.md) page for information on how custom categories
See [Custom property category renderers](./PropertyCategoryRenderers.md) page for information on how custom categories
are handled in our UI components.

```ts
Expand Down
2 changes: 1 addition & 1 deletion docs/presentation/Content/PropertySpecification.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ Custom property [renderer specification](./RendererSpecification.md) that allows
specification is used to set up [Field.renderer]($presentation-common) for this property and it's up to the UI component to make sure
appropriate renderer is used to render the property.

See [Custom property value renderers](../Customization/PropertyValueRenderers.md) page for a list of available renderers or how to register a custom one.
See [Custom property value renderers](./PropertyValueRenderers.md) page for a list of available renderers or how to register a custom one.

```ts
[[include:Content.Customization.PropertySpecification.Renderer.Ruleset]]
Expand Down
76 changes: 76 additions & 0 deletions docs/presentation/Content/PropertyValueRenderers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Custom property value renderers

Data in [PropertyGrid]($components-react) and [Table]($components-react) components is displayed by property value renderers. By defining and registering custom renderers, users can extend property rendering system to support new data types and UI interactions.

A custom renderer can be used by assigning it to specific properties through a property override. See [`PropertySpecification.renderer` section](../Content/PropertySpecification.md#attribute-renderer) for an example.

## Built-in renderers

iTwin.js UI and presentation packages register some built-in value renderers that can be used out of the box.

### `SelectableInstance`

> **Component:** [InstanceKeyValueRenderer]($presentation-components)
>
> **Prerequisites:**
>
> - Property value type is [Primitives.InstanceKey]($appui-abstract). Generally those are navigation type of properties.
> - The property is rendered within a unified selection context. See [useUnifiedSelectionContext]($presentation-components) for more details.

The renderer renders nothing when property value is `undefined`. When it's defined, the value is rendered as a clickable text.

The property display value is used for the displayed text. If it is not set, then the [Type Converter](../../learning/ui/components/TypeConverters.md) system is used to calculate displayed string from the raw property value.

When the clickable text clicked on, the available unified selection context is used to replace active selection with the instance key stored in the value by calling [UnifiedSelectionContext.replaceSelection]($presentation-components).

| Default rendering | `SelectableInstance` rendering |
| ---------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| ![Default navigation property value rendering](./media/property-value-renderers/default-navigation-property.png) | ![Selectable instance property value rendering](./media/property-value-renderers/selectable-instance.png) |

### `url`

> **Component:** [UrlPropertyValueRenderer]($components-react)
>
> **Prerequisites:**
>
> - Property type is one of [StandardTypeNames.URL]($appui-abstract), [StandardTypeNames.String]($appui-abstract) or [StandardTypeNames.Text]($appui-abstract).
>
> **Default for:** Properties with [StandardTypeNames.URL]($appui-abstract) type name. Generally those are properties with `"URI"` extended type in ECSchema.

The renderer renders nothing when property value is `undefined`. When it's defined, the value is rendered as a clickable text.

The property value is passed through the [Type Converter](../../learning/ui/components/TypeConverters.md) system to calculate displayed string. When the text clicked on, the user is navigated to the URL set to that text. **Note:** the renderer doesn't validate the text to really be a URL.

| Default rendering | `url` rendering |
| -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| ![Default url property value rendering](./media/property-value-renderers/default-url-property.png) | ![Url property value rendering](./media/property-value-renderers/url.png) |

### `multiline`

> **Component:** [MultilineTextPropertyValueRenderer]($components-react)
>
> **Prerequisites:**
>
> - Property value is of primitive type.

The renderer renders nothing when property value is `undefined`. When it's defined, the value is passed through the [Type Converter](../../learning/ui/components/TypeConverters.md) system to calculate displayed string. The string is rendered in a single line with ellipsis and is allowed to be expanded into multiple lines to fit the whole string.

| Default rendering | `multiline` rendering |
| -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Default string property value rendering](./media/property-value-renderers/default-string-property.png) | ![Multiline collapsed property value rendering](./media/property-value-renderers/multiline-collapsed.png) ![Multiline expanded property value rendering](./media/property-value-renderers/multiline-expanded.png) |

## Adding a custom renderer

A new custom property value renderer can be added by registering a class implementing [IPropertyValueRenderer]($components-react) to the [PropertyValueRendererManager]($components-react):

```tsx
[[include:Content.Customization.PropertySpecification.Renderer.Register]]
```

The renderer registered above is used whenever a property with that renderer name is being rendered. The below ruleset demonstrates assigning the renderer to a property:

```ts
[[include:Content.Customization.PropertySpecification.Renderer.Ruleset]]
```

![Using a custom property value renderer](./media/property-value-renderers/custom.png)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
31 changes: 0 additions & 31 deletions docs/presentation/Customization/PropertyValueRenderers.md

This file was deleted.

2 changes: 0 additions & 2 deletions docs/presentation/leftNav.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@
### [Customization](./Customization/index.md)

- [Rules](./Customization/index.md#rules)
- [Property value renderers](./Customization/PropertyValueRenderers.md)
- [Property category renderers](./Customization/PropertyCategoryRenderers.md)
- [ECExpressions](./Customization/ECExpressions.md)

 
Expand Down
3 changes: 2 additions & 1 deletion full-stack-tests/presentation/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"build:watch": "tsc -w",
"clean": "rimraf lib .rush/temp/package-deps*.json",
"docs": "npm run -s extract",
"extract": "betools extract --fileExt=ts --extractFrom=./src --recursive --out=../../generated-docs/extract",
"extract": "betools extract --fileExt=ts,tsx --extractFrom=./src --recursive --out=../../generated-docs/extract",
"lint": "eslint -f visualstudio \"./src/**/*.ts\" 1>&2",
"test": "cross-env NODE_ENV=development mocha --no-config --grep \"#with-services|#performance\" --invert",
"test:integration": "mocha --no-config --grep \"#with-services\"",
Expand All @@ -39,6 +39,7 @@
"@itwin/presentation-components": "workspace:*",
"@itwin/presentation-frontend": "workspace:*",
"@itwin/presentation-testing": "workspace:*",
"@testing-library/react": "^12.0.0",
"@testing-library/react-hooks": "^7.0.2",
"@types/chai": "^4.1.4",
"@types/chai-as-promised": "^7",
Expand Down
Loading