UNPKG

@itwin/presentation-components

Version:

React components based on iTwin.js Presentation library

78 lines 4.57 kB
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ import "./NavigationPropertyTargetSelector.scss"; import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react"; import { PropertyValueFormat } from "@itwin/appui-abstract"; import { PropertyValueRendererManager } from "@itwin/components-react"; import { ComboBox } from "@itwin/itwinui-react"; import { LabelDefinition } from "@itwin/presentation-common"; import { translate } from "../../common/Utils.js"; import { FILTER_WARNING_OPTION, VALUE_BATCH_SIZE } from "./ItemsLoader.js"; import { useNavigationPropertyTargetsLoader, useNavigationPropertyTargetsRuleset } from "./UseNavigationPropertyTargetsLoader.js"; /** @internal */ export const NavigationPropertyTargetSelector = forwardRef((props, ref) => { const { imodel, getNavigationPropertyInfo, propertyRecord, onCommit } = props; const [selectedTarget, setSelectedTarget] = useState(() => getNavigationTargetFromPropertyRecord(propertyRecord)); const [searchInput, setSearchInput] = useState(); const targetsRuleset = useNavigationPropertyTargetsRuleset(getNavigationPropertyInfo, propertyRecord.property); const { selectOptions, loadedOptions, isLoading } = useNavigationPropertyTargetsLoader({ imodel, ruleset: targetsRuleset, filterText: searchInput, initialSelectedTarget: selectedTarget?.label.displayValue, }); const divRef = useRef(null); const emptyContent = useMemo(() => { return isLoading ? translate("navigation-property-editor.loading-target-instances") : translate("navigation-property-editor.no-target-instances"); }, [isLoading]); const onChange = useCallback((newValue) => { const newSelectedTarget = loadedOptions.find((loadedOption) => loadedOption.label.displayValue === newValue); setSelectedTarget(newSelectedTarget); newSelectedTarget && onCommit && onCommit({ propertyRecord, newValue: getPropertyValue(newSelectedTarget) }); }, [loadedOptions, onCommit, propertyRecord]); useImperativeHandle(ref, () => ({ getValue: () => getPropertyValue(selectedTarget), htmlElement: divRef.current, }), [selectedTarget]); useEffect(() => { setSelectedTarget(getNavigationTargetFromPropertyRecord(propertyRecord)); }, [propertyRecord]); if (!targetsRuleset) { return _jsx(ReadonlyNavigationPropertyTarget, { record: props.propertyRecord }); } return (_jsx(ComboBox, { multiple: false, enableVirtualization: true, options: selectOptions, onChange: onChange, filterFunction: (options, inputValue) => { const filteredOptions = options .filter((option) => option.label.toLowerCase().includes(inputValue.toLowerCase()) && option.value !== FILTER_WARNING_OPTION.value) .slice(0, VALUE_BATCH_SIZE); if (filteredOptions.length >= VALUE_BATCH_SIZE) { filteredOptions.push(FILTER_WARNING_OPTION); } return filteredOptions; }, emptyStateMessage: emptyContent, value: selectedTarget?.label.displayValue, inputProps: { placeholder: translate("navigation-property-editor.select-target-instance"), size: "small", onChange: (e) => { setSearchInput(e.target.value); }, } })); }); NavigationPropertyTargetSelector.displayName = "NavigationPropertyTargetSelector"; /** @internal */ export function ReadonlyNavigationPropertyTarget(props) { const { record } = props; return _jsx(_Fragment, { children: PropertyValueRendererManager.defaultManager.render(record) }); } function getPropertyValue(target) { return { valueFormat: PropertyValueFormat.Primitive, value: target?.key, displayValue: target?.label.displayValue }; } function getNavigationTargetFromPropertyRecord(record) { const value = record.value; if (value.valueFormat !== PropertyValueFormat.Primitive || !value.value || !value.displayValue) { return undefined; } return { key: value.value, label: LabelDefinition.fromLabelString(value.displayValue) }; } //# sourceMappingURL=NavigationPropertyTargetSelector.js.map