@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
742 lines (674 loc) • 21.5 kB
Markdown
---
title: 'Input'
description: 'The Input component is an umbrella component for all inputs which share the same style as the classic text input field.'
version: 10.104.0
generatedAt: 2026-04-17T18:46:09.843Z
checksum: d4e0105ff52d99ebc19fd8699b68ec6b4c20fa81c4d9cbf5c8049278ad3d11dd
---
# Input
## Import
```tsx
import { Input } from '@dnb/eufemia'
```
## Description
The Input component is an umbrella component for all inputs that share the same style as the classic `text` input field.
## Relevant links
- [Figma](https://www.figma.com/design/cdtwQD8IJ7pTeE45U148r1/%F0%9F%92%BB-Eufemia---Web?node-id=4243-1495)
- [Source code](https://github.com/dnbexperience/eufemia/tree/main/packages/dnb-eufemia/src/components/input)
- [Docs code](https://github.com/dnbexperience/eufemia/tree/main/packages/dnb-design-system-portal/src/docs/uilib/components/input)
### Formatted input fields (masked values)
You may consider using [InputMasked](/uilib/components/input-masked/) for formatted strings and [Eufemia Forms](/uilib/extensions/forms/) fields like [Field.Number](/uilib/extensions/forms/base-fields/Number/) and [Field.Currency](/uilib/extensions/forms/feature-fields/Currency/) for formatted numbers:
```tsx
render(
<Field.Currency
label="Amount"
value={1234}
onChange={(value) => console.log('onChange', value)}
/>
)
```
### Browser autofill styling
When users insert values using autofill in their browser, the browser applies its own background and text colors that override Eufemia's styling.
Different browsers use different color schemes. However, Eufemia does not currently overwrite the `:autofill` background color. We only ensure the border (outline) is styled correctly in all states.
### Accessibility
Please avoid using the `maxlength` attribute when possible, as it may reduce accessibility. You can instead use the [TextCounter](/uilib/components/fragments/text-counter/) component.
You may also consider using a multiline input with a `characterCounter`:
```tsx
render(
<Field.String
label="Label text"
placeholder="Enter your text"
multiline
rows={1}
characterCounter={40}
/>
)
```
## Demos
### Placeholder text
```tsx
render(
<Wrapper>
<ComponentBox data-visual-test="input-placeholder">
<Input label="Label" placeholder="Placeholder text" />
</ComponentBox>
</Wrapper>
)
```
### Search text placeholder
```tsx
render(
<Wrapper>
<ComponentBox data-visual-test="input-search">
<Input
label="Search"
type="search"
placeholder="Search text placeholder"
on_change={({ value }) => {
console.log('on_change', value)
}}
on_submit={({ value }) => {
console.log('Submit:', value)
}}
/>
</ComponentBox>
</Wrapper>
)
```
### Medium and stretched search input
```tsx
render(
<Wrapper>
<ComponentBox data-visual-test="input-medium">
<Input
size="medium"
type="search"
stretch={true}
value="Medium search value"
on_change={({ value }) => {
console.log('on_change', value)
}}
/>
</ComponentBox>
</Wrapper>
)
```
### Input with icon
With left / right aligned text
```tsx
render(
<Wrapper>
<ComponentBox data-visual-test="input-icon">
<Input
label="Input with icon"
placeholder="Input"
label_direction="vertical"
icon="check"
bottom
/>
<Input
label="Input with icon"
label_sr_only
placeholder="Input with a placeholder"
icon_position="right"
icon="check"
align="right"
/>
</ComponentBox>
</Wrapper>
)
```
### Disabled input
```tsx
render(
<Wrapper>
<ComponentBox data-visual-test="input-disabled">
<Input
disabled
label="Disabled input"
placeholder="Disabled Input with a placeholder"
/>
</ComponentBox>
</Wrapper>
)
```
### With FormStatus
```tsx
render(
<Wrapper>
<ComponentBox>
<Provider
formElement={{
label_direction: 'vertical',
}}
>
<Flex.Vertical>
<div data-visual-test="input-error">
<Input
label="With FormStatus"
status="You have to fill in this field"
value="Input value with error"
/>
</div>
<div data-visual-test="input-error-button">
<Input
label="With button"
status="You have to fill in this field"
value="Input value with error"
type="search"
/>
</div>
</Flex.Vertical>
</Provider>
</ComponentBox>
</Wrapper>
)
```
### Input with suffix and custom label component
```tsx
render(
<Wrapper>
<ComponentBox>
<Input
label={<Span className="dnb-p--lead">Fødselsnummer</Span>}
label_direction="vertical"
autocomplete="on"
placeholder="Placeholder text"
suffix={
<HelpButton title="Info" size="large">
Some content
</HelpButton>
}
on_change={({ value }) => {
console.log('on_change', value)
}}
/>
</ComponentBox>
</Wrapper>
)
```
### Stretched `Input` in horizontal flex and a long label
```tsx
render(
<Wrapper>
<ComponentBox data-visual-test="input-stretch">
<Provider
formElement={{
label_direction: 'vertical',
}}
>
<FieldBlock
label="Long label labwl Adipiscing mauris dis proin nec"
forId="input-id"
>
<Input
id="input-id"
value="I stretch ..."
stretch
status="Status message"
status_state="warn"
/>
</FieldBlock>
</Provider>
</ComponentBox>
</Wrapper>
)
```
### Numbers are using DNB Mono (monospace)
Also, this example manipulates the value during typing.
```tsx
render(
<Wrapper>
<ComponentBox>
<Input
label="Label"
autocomplete="on"
placeholder="Placeholder text"
status="Numbers are using DNB Mono (monospace)"
status_state="info"
value="1234567890"
on_change={({ value }) => {
console.log('on_change', value)
return String(value).toUpperCase()
}}
/>
</ComponentBox>
</Wrapper>
)
```
### Submit Form with Input
Pressing the enter key will trigger a submit.
```tsx
render(
<Wrapper>
<ComponentBox>
<Form.Handler
onSubmit={(event) => {
console.log(event)
}}
>
<FormLabel forId="search">Label</FormLabel>
<Flex.Horizontal align="baseline">
<Input
id="search"
type="search"
value="Input ..."
selectall={true}
on_submit={(event) => {
console.log('Input.on_submit', event)
}}
on_change={({ value }) => {
console.log('on_change:', value)
}}
/>
<Form.SubmitButton />
</Flex.Horizontal>
</Form.Handler>
</ComponentBox>
</Wrapper>
)
```
### Input with clear button
Pushing the clear button will clear the input.
```tsx
render(
<Wrapper>
<ComponentBox data-visual-test="input-clear">
<Flex.Vertical>
<Input clear={true} value="Value ..." size="medium" />
<Input clear={true} value="Value ..." type="search" />
<Input clear={true} value="Value ..." icon="loupe" type="search" />
</Flex.Vertical>
</ComponentBox>
</Wrapper>
)
```
### Prevent typing of invalid characters
You can check out the [Field.String](/uilib/extensions/forms/base-fields/String/#prevent-typing-of-invalid-characters) example for more information using `onInput` event handler property.
### Input password type
The password component has to ensure that there is still room for password managers to inject the input with their UX functionality.
In order to get the show/hide button, you may have to import the component like so:
```js
import InputPassword from '/eufemia/components/input/InputPassword'
```
```tsx
render(
<Wrapper>
<ComponentBox
scope={{
InputPassword,
}}
data-visual-test="input-password"
>
<InputPassword
label="Label"
placeholder="A placeholder text"
onChange={(value: string) => {
console.log('onChange:', value)
}}
onShowPassword={() => {
console.log('onShowPassword')
}}
onHidePassword={() => {
console.log('onHidePassword')
}}
/>
</ComponentBox>
</Wrapper>
)
```
```tsx
render(
<Wrapper>
<ComponentBox data-visual-test="input-align">
<Provider
formElement={{
label_direction: 'vertical',
}}
>
<FieldBlock label="Left aligned">
<Flex.Vertical>
<Input value="Plain" />
<Input value="Search" type="search" />
<Input value="Search" size="medium" type="search" />
<Input value="Search" size="large" type="search" />
<Input
value="Value Eu pretium sit magnis suscipit cursus dis proin rutrum elementum"
icon="calendar"
/>
<Input
placeholder="Placeholder Eu pretium sit magnis suscipit cursus dis proin rutrum elementum"
icon_position="right"
icon="calendar"
/>
<Input size="medium" value="Value" icon="calendar" />
<Input
size="medium"
placeholder="Placeholder"
icon_position="right"
icon="calendar"
/>
<Input size="large" value="Value" icon="calendar" />
<Input
size="large"
placeholder="Placeholder"
icon_position="right"
icon="calendar"
/>
</Flex.Vertical>
</FieldBlock>
<FieldBlock top label="Right aligned">
<Flex.Vertical>
<Input value="Plain" align="right" />
<Input value="Search" type="search" align="right" />
<Input
value="Search"
size="medium"
type="search"
align="right"
/>
<Input
value="Search"
size="large"
type="search"
align="right"
/>
<Input
value="Value Eu pretium sit magnis suscipit cursus dis proin rutrum elementum"
icon="calendar"
align="right"
/>
<Input
placeholder="Placeholder Eu pretium sit magnis suscipit cursus dis proin rutrum elementum"
icon_position="right"
icon="calendar"
align="right"
/>
<Input
size="medium"
value="Value"
icon="calendar"
align="right"
/>
<Input
size="medium"
placeholder="Placeholder"
icon_position="right"
icon="calendar"
align="right"
/>
<Input
size="large"
value="Value"
icon="calendar"
align="right"
/>
<Input
size="large"
placeholder="Placeholder"
icon_position="right"
icon="calendar"
align="right"
/>
</Flex.Vertical>
</FieldBlock>
</Provider>
</ComponentBox>
</Wrapper>
)
```
## Properties
```json
{
"props": {
"value": {
"doc": "The content value of the input.",
"type": "string",
"status": "optional"
},
"align": {
"doc": "Defines the text alignment of the input. Can be `left`, `right` or `center`. Defaults to `left`.",
"type": "string",
"status": "optional"
},
"label": {
"doc": "Prepends the Form Label component. If no ID is provided, a random ID is created.",
"type": "React.Node",
"status": "optional"
},
"label_sr_only": {
"doc": "Use `true` to make the label only readable by screen readers.",
"type": "boolean",
"status": "optional"
},
"label_direction": {
"doc": "Use `label_direction=\"vertical\"` to change the label layout direction. Defaults to `horizontal`.",
"type": "string",
"status": "optional"
},
"status": {
"doc": "Text with a status message. The style defaults to an error message. You can use `true` to only get the status color, without a message.",
"type": ["error", "info", "boolean"],
"status": "optional"
},
"status_state": {
"doc": "Defines the state of the status. Currently, there are two statuses `[error, info]`. Defaults to `error`.",
"type": ["error", "info"],
"status": "optional"
},
"status_props": {
"doc": "Use an object to define additional FormStatus properties.",
"type": "object",
"status": "optional"
},
"globalStatus": {
"doc": "The [configuration](/uilib/components/global-status/properties/#configuration-object) used for the target [GlobalStatus](/uilib/components/global-status).",
"type": "object",
"status": "optional"
},
"placeholder": {
"doc": "The placeholder which shows up once the input value is empty.",
"type": "string",
"status": "optional"
},
"icon": {
"doc": "Icon to show before or after the input / placeholder. Can be either a string defining a primary icon or a Component using an SVG icon of either 16px or 24px.",
"type": ["string", "React.Node"],
"status": "optional"
},
"icon_position": {
"doc": "Defines the position of icon inside the input. Set to `left` or `right`. Defaults to `left` if not set.",
"type": "string",
"status": "optional"
},
"icon_size": {
"doc": "The icon size of the icon shows. Defaults to `medium`.",
"type": "string",
"status": "optional"
},
"keep_placeholder": {
"doc": "Set to `true` in case the `placeholder` has to be kept during focus. By default, the placeholder disappears on focus.",
"type": "boolean",
"status": "optional"
},
"input_class": {
"doc": "In case we have to set a custom input class.",
"type": "string",
"status": "optional"
},
"type": {
"doc": "Choose between `text`, `number`, `email`, `password`, `url`, `tel` and `search`.",
"type": "string",
"status": "optional"
},
"autocomplete": {
"doc": "Defaults to `off`. Set to `on` or any of [allowed `attributes`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-autocomplete). Keep in mind, 1. you may have to define a `name`, 2. have the input as a descendant of a `<form>` element, 3. and have a submit button inside the form.",
"type": "string",
"status": "optional"
},
"submit_button_title": {
"doc": "Title attribute for the search/submit button. Only relevant when `type=\"search\"`.",
"type": "string",
"status": "optional"
},
"suffix": {
"doc": "Text describing the content of the input more than the label. you can also send in a React component, so it gets wrapped inside the Input component.",
"type": ["string", "React.Node"],
"status": "optional"
},
"size": {
"doc": "The sizes you can choose is `default` (2rem), `medium` (2.5rem) and `large` (3rem) are supported component sizes. Defaults to `default` / `null`. Also, if you define a number like `size={2}` then it will be forwarded as the input element attribute.",
"type": ["string", "number"],
"status": "optional"
},
"selectall": {
"doc": "If set to `true`, then the whole input value gets selected on the entry focus. A second click will place the cursor on the wanted position.",
"type": "boolean",
"status": "optional"
},
"clear": {
"doc": "If set to `true`, then a clear button will be shown which lets the user clear any given input value.",
"type": "boolean",
"status": "optional"
},
"stretch": {
"doc": "If set to `true`, then the input field will be 100% in `width`.",
"type": "boolean",
"status": "optional"
},
"skeleton": {
"doc": "If set to `true`, an overlaying skeleton with animation will be shown.",
"type": "boolean",
"status": "optional"
},
"input_attributes": {
"doc": "Provide the Input element with any attributes by using an Object `input_attributes={{size:'2'}}` or a JSON Object `input_attributes='{\"size\":\"2\"}'`. **NB:** Keep in mind, that also every not listed component property will be sent along and set as an Input element attribute.",
"type": "object",
"status": "optional"
},
"input_state": {
"doc": "Defines a custom visual state of the input. Use it only if you have to simulate a custom state. Currently are three statuses `virgin` , `focus` and `dirty`. Defaults to `null`.",
"type": "string",
"status": "optional"
},
"submit_element": {
"doc": "Accepts a React element which will show up like the \"submit button\" would do on `type=\"search\"`.",
"type": ["string", "React.Element"],
"status": "optional"
},
"inner_ref": {
"doc": "By providing a React.ref we can get the internally used input element (DOM). E.g. `inner_ref={myRef}` by using `React.createRef()` or `React.useRef()`.",
"type": "React.RefObject",
"status": "optional"
},
"input_element": {
"doc": "By providing a new component we can change the internally used element. Also supports a string only, like `input_element=\"input\"`.",
"type": ["string", "React.Element"],
"status": "internal"
},
"inner_element": {
"doc": "By providing a new component to be rendered inside the \"shell\" – we can add a freely customizable internal element. Used by the Autocomplete component.",
"type": ["string", "React.Element"],
"status": "internal"
},
"[Space](/uilib/layout/space/properties)": {
"doc": "Spacing properties like `top` or `bottom` are supported.",
"type": ["string", "object"],
"status": "optional"
}
}
}
```
## Translations
```json
{
"locales": ["da-DK", "en-GB", "nb-NO", "sv-SE"],
"entries": {
"Input.clear_button_title": {
"nb-NO": "Nullstill",
"en-GB": "Clear value",
"sv-SE": "Återställ",
"da-DK": "Nulstil"
},
"Input.submit_button_title": {
"nb-NO": "Send",
"en-GB": "Submit button",
"sv-SE": "Skicka",
"da-DK": "Indsend"
}
}
}
```
## Events
```json
{
"props": {
"on_change": {
"doc": "Will be called on value changes made by the user. Returns an object with the value as a string and the native event: `{ value, event }`.",
"type": "function",
"status": "optional"
},
"on_focus": {
"doc": "Will be called on focus set by the user. Returns `{ value, event }`.",
"type": "function",
"status": "optional"
},
"on_key_down": {
"doc": "Will be called on key down by the user. Returns `{ value, event }`.",
"type": "function",
"status": "optional"
},
"on_blur": {
"doc": "Will be called on blur set by the user. Returns `{ value, event }`.",
"type": "function",
"status": "optional"
},
"on_submit": {
"doc": "Will be called on enter key press or submit button click. Returns `{ value, event }`.",
"type": "function",
"status": "optional"
},
"on_submit_focus": {
"doc": "Will be called on submit button focus. Only relevant when `type=\"search\"`. Returns `{ value, event }`.",
"type": "function",
"status": "optional"
},
"on_submit_blur": {
"doc": "Will be called on submit button blur. Only relevant when `type=\"search\"`. Returns `{ value, event }`.",
"type": "function",
"status": "optional"
},
"on_clear": {
"doc": "Will be called on a clear button click. Returns `{ value, previousValue, event }`.",
"type": "function",
"status": "optional"
}
}
}
```
### Manipulate the input value during typing
You have two possibilities to manipulate the value while a user is typing. Either you handle the value with your own state, or you return a modified value in the `on_change` event listener:
```jsx
import { format } from '/eufemia/components/number-format/NumberUtils'
function Component() {
const onChangeHandler = ({ value }) => {
return format(value)
}
return <Input on_change={onChangeHandler} />
}
```
### Prevent setting a new value
You can use e.g. `event.preventDefault()` during `on_key_down`, or return false during `on_change`. They are not 100% the same user experience, but can both be useful in different use cases.
```jsx
function Component() {
const onKeyDownHandler = ({ event }) => {
event.preventDefault()
}
const onChangeHandler = ({ value }) => {
return false
}
return (
<Input on_key_down={onKeyDownHandler} on_change={onChangeHandler} />
)
}
```