-
Notifications
You must be signed in to change notification settings - Fork 0
/
InstanceKeyValueRenderer.tsx
72 lines (62 loc) · 3.04 KB
/
InstanceKeyValueRenderer.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/**
* @packageDocumentation
* @module Properties
*/
import { Primitives, PrimitiveValue, PropertyRecord, PropertyValueFormat } from "@itwin/appui-abstract";
import { IPropertyValueRenderer, PropertyValueRendererContext, TypeConverterManager, useAsyncValue } from "@itwin/components-react";
import { UnderlinedButton } from "@itwin/core-react";
import { translate } from "../common/Utils";
import { useUnifiedSelectionContext } from "../unified-selection/UnifiedSelectionContext";
/**
* Property value renderer for instance keys. If application provides a [[UnifiedSelectionContext]] and this value is
* clicked, the current selection is replaced with the instance pointed by the key. The selection changes at the default
* selection level as provided by the context.
* @beta
*/
export class InstanceKeyValueRenderer implements IPropertyValueRenderer {
public canRender(record: PropertyRecord) {
return record.value.valueFormat === PropertyValueFormat.Primitive && (record.value.value === undefined || isInstanceKey(record.value.value));
}
public render(record: PropertyRecord, context?: PropertyValueRendererContext) {
return <InstanceKeyValueRendererImpl record={record} context={context} />;
}
}
interface InstanceKeyValueRendererImplProps {
record: PropertyRecord;
context?: PropertyValueRendererContext;
}
const InstanceKeyValueRendererImpl: React.FC<InstanceKeyValueRendererImplProps> = (props) => {
const stringValue = useAsyncValue(convertRecordToString(props.record));
const valueElement = stringValue ?? props.context?.defaultValue;
const selectionContext = useUnifiedSelectionContext();
const instanceKey = (props.record.value as PrimitiveValue).value as Primitives.InstanceKey | undefined;
if (instanceKey === undefined || selectionContext === undefined) {
return (
<span style={props.context?.style} title={stringValue}>
{valueElement}
</span>
);
}
const title = translate("instance-key-value-renderer.select-instance");
const handleClick = () => selectionContext.replaceSelection([instanceKey]);
return (
<UnderlinedButton title={title} onClick={handleClick}>
{valueElement}
</UnderlinedButton>
);
};
function isInstanceKey(value: Primitives.Value): value is Primitives.InstanceKey {
const { className, id } = value as Primitives.InstanceKey;
return typeof className === "string" && typeof id === "string";
}
function convertRecordToString(record: PropertyRecord): string | Promise<string> {
const primitive = record.value as PrimitiveValue;
return (
primitive.displayValue ??
TypeConverterManager.getConverter(record.property.typename, record.property.converter?.name).convertPropertyToString(record.property, primitive.value)
);
}