-
Notifications
You must be signed in to change notification settings - Fork 2
/
PrimitivePropertyValueRenderer.tsx
102 lines (95 loc) · 3.22 KB
/
PrimitivePropertyValueRenderer.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/*---------------------------------------------------------------------------------------------
* 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 * as React from "react";
import type { LinkElementsInfo, PropertyRecord } from "@itwin/appui-abstract";
import { PropertyValueFormat } from "@itwin/appui-abstract";
import { useAsyncValue } from "../../../common/UseAsyncValue";
import { PropertyGridCommons } from "../../../propertygrid/component/PropertyGridCommons";
import { LinksRenderer } from "../../LinkHandler";
import type {
IPropertyValueRenderer,
PropertyValueRendererContext,
} from "../../ValueRendererManager";
import { convertRecordToString } from "./Common";
/** Default Primitive Property Renderer
* @public
*/
export class PrimitivePropertyValueRenderer implements IPropertyValueRenderer {
/** Checks if the renderer can handle given property */
public canRender(record: PropertyRecord) {
return record.value.valueFormat === PropertyValueFormat.Primitive;
}
/** Method that returns a JSX representation of PropertyRecord */
public render(
record: PropertyRecord,
context?: PropertyValueRendererContext
) {
return (
<PrimitivePropertyValueRendererImpl
record={record}
context={context}
stringValueCalculator={convertRecordToString}
/>
);
}
}
/** @internal */
interface PrimitivePropertyValueRendererImplProps {
record: PropertyRecord;
stringValueCalculator: (record: PropertyRecord) => string | Promise<string>;
context?: PropertyValueRendererContext;
linksHandler?: LinkElementsInfo;
}
/** @internal */
export function PrimitivePropertyValueRendererImpl(
props: PrimitivePropertyValueRendererImplProps
) {
const { stringValue, element } = useRenderedStringValue(
props.record,
props.stringValueCalculator,
props.context,
props.linksHandler
);
return (
<span style={props.context?.style} title={stringValue}>
{element}
</span>
);
}
/**
* Default link handler used for handling records,
* which did not have any specified LinkElementsInfo.
*
* Default matcher matches all URLs using regex.
* Default onClick opens window or sets location.href with found URL.
* @public
*/
export const DEFAULT_LINKS_HANDLER: LinkElementsInfo = {
matcher: PropertyGridCommons.getLinks,
onClick: PropertyGridCommons.handleLinkClick,
};
/** @internal */
export function useRenderedStringValue(
record: PropertyRecord,
stringValueCalculator: (record: PropertyRecord) => string | Promise<string>,
context?: PropertyValueRendererContext,
linksHandler?: LinkElementsInfo
): { stringValue?: string; element: React.ReactNode } {
const stringValue = useAsyncValue(stringValueCalculator(record));
const el =
stringValue === undefined ? (
context?.defaultValue
) : (
<LinksRenderer
value={stringValue}
links={record.links ?? linksHandler ?? DEFAULT_LINKS_HANDLER}
highlighter={context?.textHighlighter}
/>
);
return { stringValue, element: el };
}