Skip to main content
Glama
MoneyInput.tsx3.08 kB
// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors // SPDX-License-Identifier: Apache-2.0 import { NativeSelect, TextInput } from '@mantine/core'; import type { Money } from '@medplum/fhirtypes'; import { IconCurrencyDollar } from '@tabler/icons-react'; import type { ChangeEvent, JSX } from 'react'; import { useCallback, useContext, useMemo, useState } from 'react'; import { ElementsContext } from '../ElementsInput/ElementsInput.utils'; import type { ComplexTypeInputProps } from '../ResourcePropertyInput/ResourcePropertyInput.utils'; /* * Based on: https://github.com/mantinedev/ui.mantine.dev/blob/master/components/CurrencyInput/CurrencyInput.tsx */ /** * List of currencies. * * Full list of currencies: * https://www.hl7.org/fhir/valueset-currencies.html * * Latest browsers can report list of supported currencies, but it's not widely supported: * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/supportedValuesOf * * Using a short list for simplicity for now. */ const data = ['USD', 'EUR', 'CAD', 'GBP', 'AUD']; export interface MoneyInputProps extends ComplexTypeInputProps<Money> { readonly label?: string; readonly placeholder?: string; } export function MoneyInput(props: MoneyInputProps): JSX.Element { const { onChange } = props; const [value, setValue] = useState(props.defaultValue); const { getExtendedProps } = useContext(ElementsContext); const [currencyProps, valueProps] = useMemo( () => ['currency', 'value'].map((field) => getExtendedProps(props.path + '.' + field)), [getExtendedProps, props.path] ); const setValueWrapper = useCallback( (newValue: Money): void => { setValue(newValue); if (onChange) { onChange(newValue); } }, [onChange] ); const handleCurrencyChange = useCallback( (e: ChangeEvent<HTMLSelectElement>) => { setValueWrapper({ ...value, currency: e.currentTarget.value as Money['currency'], }); }, [value, setValueWrapper] ); const handleValueChange = useCallback( (e: ChangeEvent<HTMLInputElement>) => { setValueWrapper({ ...value, value: e.currentTarget.valueAsNumber, }); }, [value, setValueWrapper] ); const select = ( <NativeSelect disabled={props.disabled || currencyProps?.readonly} defaultValue={value?.currency} data={data} styles={{ input: { fontWeight: 500, borderTopLeftRadius: 0, borderBottomLeftRadius: 0, width: 92, }, }} onChange={handleCurrencyChange} /> ); return ( <TextInput disabled={props.disabled || valueProps?.readonly} type="number" name={props.name} label={props.label} placeholder={props.placeholder ?? 'Value'} defaultValue={value?.value?.toString() ?? 'USD'} leftSection={<IconCurrencyDollar size={14} />} rightSection={select} rightSectionWidth={92} onChange={handleValueChange} /> ); }

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