# Currency input

An enhanced input field that provides visual and non-visual cues to a user when entering an amount of money in a specified currency.

Tabs: [Guidelines](/components/web/currency-input/currency-input.guidelines.md) · [Code](/components/web/currency-input/currency-input.code.md)

## Features

- Supports specifying an showing currency codes

- Format numbers based on the users locale

- Specify the number of fraction digits

- Compatible with our [Form control](/components/web/form-control/form-control.guidelines) component

- Adheres to [our form accessibility guidelines](/patterns/forms/forms.accessibility).

## When to use

Use a currency input when you need users to provide an amount of money. The component provides a cue to the user when entering an amount in a specified currency.

## Examples

Information:

We promote usage of this component in combination with our [Form control](/components/web/form-control/form-control.guidelines) component to maintain layout consistency and ensure form accessibility. The Form control supports advanced use cases such as [hint text](/components/web/form-control/form-control.guidelines#hint-text), [help popovers](/components/web/form-control/form-control.guidelines#help-popover) and [error messages](/components/web/form-control/form-control.guidelines#error).

### Label

The label of a form element should be clear and concise, ideally under three words. It should describe the value of the element and not what the user needs to do in order to fill it out properly.

Information:

**Never omit a label**. Form labels are required for accessibility purposes. However, it may be acceptable to [hide the label visually](/patterns/forms/forms.accessibility#hiding-a-label-visually) in certain cases.

```tsx
const Example = () => {
    const [value, setValue] = React.useState('')
    return (
        <FormControl maxWidth="200px">
            <FormControl.Label>Expense amount</FormControl.Label>
            <CurrencyInput
                onChange={(e) => setValue(e.target.value)}
                value={value}
                currency="EUR"
                postfix="EUR"
                locale="en-GB"
            />
        </FormControl>
    )
}

render(<Example />)
```

### Required or optional

Mark the minority of form elements in a form as required or optional. This helps users scan the form and understand what is required of them. Type out the word optional or required in the label. E.g. "Per purchase limit (optional)". Don't use asterisks or other symbols.

```tsx
const Example = () => {
    const [value, setValue] = React.useState('')
    return (
        <FormControl maxWidth="200px">
            <FormControl.Label>Expense amount (required)</FormControl.Label>
            <CurrencyInput
                isRequired
                onChange={(e) => setValue(e.target.value)}
                value={value}
                currency="EUR"
                postfix="EUR"
                locale="en-GB"
            />
        </FormControl>
    )
}

render(<Example />)
```

### Hint text

Use hint text to give users clear guidance for data entry. Keep it brief and avoid repeating the label or other form details. If it feels redundant, try removing it. We keep help text above the input field to have the reading order match the visual order, which is needed for screen readers.

```tsx
const Example = () => {
    const [value, setValue] = React.useState('')
    return (
        <FormControl maxWidth="200px">
            <FormControl.Label>Expense amount</FormControl.Label>
            <FormControl.HintText>The amount found on your invoice</FormControl.HintText>
            <CurrencyInput
                onChange={(e) => setValue(e.target.value)}
                value={value}
                currency="EUR"
                postfix="EUR"
                locale="en-GB"
            />
        </FormControl>
    )
}

render(<Example />)
```

### Help popover

Use help popovers to aid first-time users or to clarify complex concepts. The help popover can contain interactive content and may be used to provide links for further information.

```tsx
const Example = () => {
    const [value, setValue] = React.useState('')
    return (
        <FormControl maxWidth="200px">
            <FormControl.LabelWrapper>
                <FormControl.Label>Expense amount</FormControl.Label>
                <FormControl.Help>
                    For invoices, the amount due is usually displayed at the bottom of an invoice,
                    often both in numbers and spelled out.
                </FormControl.Help>
            </FormControl.LabelWrapper>
            <CurrencyInput
                onChange={(e) => setValue(e.target.value)}
                value={value}
                currency="EUR"
                postfix="EUR"
                locale="en-GB"
            />
        </FormControl>
    )
}

render(<Example />)
```

### Error

Provide clear and helpful error messages that guide users toward a solution. Instead of merely stating the problem, ensure the message is specific and actionable. Avoid vague or shaming language.

```tsx
const Example = () => {
    const [value, setValue] = React.useState('')
    return (
        <FormControl maxWidth="200px">
            <FormControl.Label>Expense amount</FormControl.Label>
            <CurrencyInput
                isInvalid
                onChange={(e) => setValue(e.target.value)}
                value={value}
                currency="EUR"
                postfix="EUR"
                locale="en-GB"
            />
            <FormControl.Error>Enter an amount</FormControl.Error>
        </FormControl>
    )
}

render(<Example />)
```

### Skeleton

Use a "skeleton" version of this component to display a loading state while data is being fetched. It provides a visual placeholder, giving users a preview of the UI structure before the actual content is loaded. This enhances the user experience by offering a more accurate representation of the final layout during data retrieval.

```tsx
<FormControl maxWidth="200px" skeleton>
    <FormControl.Label>Expense amount</FormControl.Label>
    <CurrencyInput name="amount" value="" currency="EUR" skeleton />
    <FormControl.HintText>The amount found on your invoice</FormControl.HintText>
</FormControl>
```

### Disabled

Disable a form element to indicate that it’s currently unavailable. This can be used to maintain layout consistency and communicate that the element may become available later. If the form element will never be available in a given context, leave it out.

```tsx
<FormControl maxWidth="200px">
    <FormControl.Label>Expense amount</FormControl.Label>
    <CurrencyInput name="amount" value="" currency="EUR" postfix="EUR" locale="en-GB" disabled />
</FormControl>
```

### Localisation

Use the user's locale to determine the decimal and thousand separators. This ensures that the user is presented with a familiar format. For instance, the locale in Denmark (`da-DK`) uses a comma as the decimal separator and a period as the thousand separator.

> [Currency code](#currency-code) and locale are independent of each other. The currency determines the currency code shown and the locale determines the formatting of the number.

```tsx
const Example = () => {
    const [value, setValue] = React.useState('')
    return (
        <FormControl maxWidth="200px">
            <FormControl.Label>Udgiftsbeløb</FormControl.Label>
            <CurrencyInput
                isInvalid
                onChange={(e) => setValue(e.target.value)}
                value={value}
                locale="da-DK"
                currency="EUR"
                postfix="EUR"
            />
        </FormControl>
    )
}

render(<Example />)
```

### Currency code

Use a postfix to visually indicate the currency expected, enhancing usability for sighted users. Use currency codes (EUR, GBP, DKK, SEK, etc) and not symbols (€/£/$), because some symbols (like $) could mean multiple different currencies.

> When establishing a unified approach in regards to currency formatting, we decided to go with [Currency input API](/components/web/currency-input/currency-input.code).

```tsx
const Example = () => {
    const [value, setValue] = React.useState('')
    return (
        <FormControl maxWidth="200px">
            <FormControl.Label>Expense amount</FormControl.Label>
            <CurrencyInput
                onChange={(e) => setValue(e.target.value)}
                value={value}
                locale="en-GB"
                currency="GBP"
                postfix="GBP"
            />
        </FormControl>
    )
}

render(<Example />)
```

### Fraction digits

By default, the currency input allows for two fraction digits (decimal places), but you should feel free to define a different number of digits if it makes sense for your use case. For instance, we only allow whole numbers when admins to set card limits.

> It's always possible for users to enter fractions, but the component will round the number to the to the number of fraction digits specified.

```tsx
const Example = () => {
    const [value, setValue] = React.useState('')
    return (
        <FormControl maxWidth="200px">
            <FormControl.Label>Card limit</FormControl.Label>
            <CurrencyInput
                onChange={(e) => setValue(e.target.value)}
                value={value}
                locale="en-GB"
                currency="EUR"
                postfix="EUR"
                formatterConfig={{
                    minimumFractionDigits: 0,
                    maximumFractionDigits: 0,
                }}
            />
        </FormControl>
    )
}

render(<Example />)
```

## Accessibility

The implementation of this component has been informed by [our form accessibility guidelines](/patterns/forms/forms.accessibility).

## Best practices

Refer to our [Forms guidelines](/patterns/forms/forms.about) for general advice on forms structure, validation, and more.

## Related components

- [Form control](/components/web/form-control/form-control.guidelines): Form control displays a labelled input and, optionally, associated validation text, help popover, and/or hint text.
- [Input](/components/web/input/input.guidelines): A form element that enables users to enter a single line of text.
