import Body from '../body'; import { Label } from '../label/Label'; import { clsx } from 'clsx'; import { AnimatePresence, motion } from 'framer-motion'; import { useId, type ReactNode } from 'react'; import { type Props as CurrencySelectorProps, CurrencySelector, } from './currencySelector/CurrencySelector'; import { CommonProps } from '../common'; import { AmountInput } from './amountInput/AmountInput'; import { Chevron } from './chevron/Chevron'; import { InlinePrompt, type InlinePromptProps } from '../prompt/InlinePrompt'; type AmountType = number | null; export type CurrencyType = string; type DefaultCurrencySelectorInstanceType = Pick< CurrencySelectorProps, 'addons' | 'options' | 'onChange' | 'onOpen' | 'onSearchChange' >; type CustomCurrencySelectorInstanceType = { customRender?: (props: { id: string; labelId: string }) => ReactNode; }; type CurrencySelectorType = DefaultCurrencySelectorInstanceType & CustomCurrencySelectorInstanceType; export type Props = { label?: ReactNode; currencySelector?: CurrencySelectorType; amount?: AmountType; /** * The currency code, e.g. `USD`, `EUR`, `GBP`, etc. Governs the flag rendered in the currency selector. */ currency: CurrencyType; inlinePrompt?: { sentiment?: InlinePromptProps['sentiment']; message: InlinePromptProps['children']; media?: InlinePromptProps['media']; }; showChevron?: boolean; /** * If set, it auto-focuses the amount input upon component mount.
* ⚠️ **Use with caution**, as it may impact user experience and * fail [WCAG 2.4.3 requirements](https://www.w3.org/WAI/WCAG21/Understanding/focus-order.html) */ autoFocus?: boolean; /** * Dims the input to indicate a loading state. Does not disable it. */ loading?: boolean; onAmountChange: (amount: AmountType) => void; onFocusChange?: (focused: boolean) => void; } & CommonProps; /** * This component has been kindly contributed by our friends at the `Send` team 🎉. * * Some patterns and implementation details used in this component may differ * from what's commonly used in the Design System. The overall build and QA was managed * by the contributing team directly, and such did not follow a typical DS lifecycle. * * While we house this component and will help facilitate its future iterations, * direct contributions by consuming product teams are highly encouraged. * * > ⚠️ **Prerequisite:**
The component depends on the * [framer-motion](https://www.npmjs.com/package/framer-motion) package, which has been * deliberately excluded from the Design System bundle and kept as an opt-in only. * **Make sure to add it to your project dependencies.** */ export default function ExpressiveMoneyInput({ label, currency, currencySelector = { options: [] } as DefaultCurrencySelectorInstanceType, amount, onAmountChange, className, inlinePrompt, showChevron, autoFocus, loading, onFocusChange, }: Props) { const inputId = useId(); const labelId = useId(); const customAlertId = useId(); const currencyId = useId(); return (
{currencySelector.customRender?.({ id: currencyId, labelId }) ?? ( )}
{inlinePrompt && (
{inlinePrompt.sentiment && Object.keys(inlinePrompt.sentiment).length > 0 ? ( {inlinePrompt.message} ) : ( {inlinePrompt.message} )}
)}
); }