Skip to main content
Glama
ValueSetAutocomplete.tsx3.77 kB
// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors // SPDX-License-Identifier: Apache-2.0 import { Group, Text } from '@mantine/core'; import type { ValueSetExpandParams } from '@medplum/core'; import type { ValueSetExpansionContains } from '@medplum/fhirtypes'; import { useMedplum } from '@medplum/react-hooks'; import { IconCheck } from '@tabler/icons-react'; import type { JSX } from 'react'; import { forwardRef, useCallback } from 'react'; import type { AsyncAutocompleteOption, AsyncAutocompleteProps } from '../AsyncAutocomplete/AsyncAutocomplete'; import { AsyncAutocomplete } from '../AsyncAutocomplete/AsyncAutocomplete'; export interface ValueSetAutocompleteProps extends Omit< AsyncAutocompleteProps<ValueSetExpansionContains>, 'loadOptions' | 'toKey' | 'toOption' > { readonly binding: string | undefined; readonly creatable?: boolean; readonly clearable?: boolean; readonly expandParams?: Partial<ValueSetExpandParams>; readonly withHelpText?: boolean; } function toKey(element: ValueSetExpansionContains): string { if (typeof element.code === 'string') { return element.code; } return JSON.stringify(element); } function getDisplay(item: ValueSetExpansionContains): string { if (typeof item.display === 'string') { return item.display; } return toKey(item); } function toOption(element: ValueSetExpansionContains): AsyncAutocompleteOption<ValueSetExpansionContains> { return { value: toKey(element), label: getDisplay(element), resource: element, }; } function createValue(input: string): ValueSetExpansionContains { return { code: input, display: input, }; } /** * A low-level component to autocomplete based on a FHIR Valueset. * This is the base component for CodeableConceptInput, CodingInput, and CodeInput. * @param props - The ValueSetAutocomplete React props. * @returns The ValueSetAutocomplete React node. */ export function ValueSetAutocomplete(props: ValueSetAutocompleteProps): JSX.Element { const medplum = useMedplum(); const { binding, creatable, clearable, expandParams, withHelpText, ...rest } = props; const loadValues = useCallback( async (input: string, signal: AbortSignal): Promise<ValueSetExpansionContains[]> => { if (!binding) { return []; } const valueSet = await medplum.valueSetExpand( { ...expandParams, url: binding, filter: input, count: 10, }, { signal } ); const valueSetElements = valueSet.expansion?.contains ?? []; const newData: ValueSetExpansionContains[] = []; for (const valueSetElement of valueSetElements) { if (valueSetElement.code && !newData.some((item) => item.code === valueSetElement.code)) { newData.push(valueSetElement); } } return newData; }, [medplum, expandParams, binding] ); return ( <AsyncAutocomplete {...rest} creatable={creatable ?? true} clearable={clearable ?? true} toOption={toOption} loadOptions={loadValues} onCreate={createValue} itemComponent={withHelpText ? ItemComponent : undefined} /> ); } const ItemComponent = forwardRef<HTMLDivElement, AsyncAutocompleteOption<ValueSetExpansionContains>>( ({ label, resource, active, ...others }: AsyncAutocompleteOption<ValueSetExpansionContains>, ref) => { return ( <div ref={ref} {...others}> <Group wrap="nowrap" gap="xs"> {active && <IconCheck size={12} />} <div> <Text>{label}</Text> <Text size="xs" c="dimmed"> {`${resource.system}#${resource.code}`} </Text> </div> </Group> </div> ); } );

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/medplum/medplum'

If you have feedback or need assistance with the MCP directory API, please join our Discord server