Skip to content
BigBang

Popular

    ↑↓Navigate↵OpenEscClose
    TR

    Components

    TextInput

    Lets people enter a single line of text or a number, with the label, help text and error message tied to the field.

    Storybook
    Storybook
    Source
    Source

    The example below loads live from Storybook; open it in Storybook to use the controls.

    Live example, StorybookOpen in Storybook

    TextInput always comes with a visible label. The label is bound to the input, so clicking it focuses the field. The default size is medium (36 px).

    import { TextInput } from '@bigbang/ui';
    export default function Default() {
    return <TextInput label="Field label" name="field" className="w-full max-w-80" />;
    }

    description tells what the field expects in more detail than the label can: format, length, where to find the value. Screen readers read it with the field.

    Help or instruction text goes here

    import { TextInput } from '@bigbang/ui';
    export default function WithDescription() {
    return (
    <TextInput
    label="Field label"
    description="Help or instruction text goes here"
    name="field"
    className="w-full max-w-80"
    />
    );
    }

    When error is set, the field is marked invalid: the border turns to the danger colour, the message shows under the help text, and screen readers read it with the field, after the help text. The message says what is wrong and how to fix it. When the message is shown elsewhere, such as in an error summary at the top of the form, set invalid alone: the field is marked invalid without a message under it.

    Error message goes here
    import { TextInput } from '@bigbang/ui';
    export default function Invalid() {
    return (
    <TextInput
    label="Field label"
    error="Error message goes here"
    name="field"
    defaultValue="Value"
    className="w-full max-w-80"
    />
    );
    }

    required makes the value required: the input gets the native required attribute, so screen readers say “required”, and the label gets a * with a visually hidden “required”. A form marks the minority: when most fields are required, set necessityIndicator="optional" on every field and the optional ones show “(optional)” instead. Use one convention per form. The marker text comes from the library’s string catalogue in the Provider language.

    import { Provider, TextInput } from '@bigbang/ui';
    export default function Necessity() {
    // The Provider reads the library's own strings, such as the necessity marker, in English.
    return (
    <Provider locale="en-GB">
    <TextInput label="Field label" name="required-field" required className="w-full max-w-80" />
    <TextInput label="Note" name="optional-field" necessityIndicator="optional" className="w-full max-w-80" />
    </Provider>
    );
    }

    startContent and endContent place content inside the field box, before and after the input: a decorative icon, a currency or unit, or one small action such as copy. Content that only decorates is hidden from screen readers; a unit that matters belongs in the label or the help text too.

    items
    import { Icon, TextInput } from '@bigbang/ui';
    export default function StartEndContent() {
    return (
    <>
    <TextInput label="Quantity" name="quantity" inputMode="numeric" endContent="items" className="w-full max-w-80" />
    <TextInput label="Field label" name="search" startContent={<Icon name="search" size="sm" />} className="w-full max-w-80" />
    </>
    );
    }

    A readOnly field shows a value that cannot be changed here. Unlike a disabled field, it stays focusable, its text can be selected and copied, and its value is submitted with the form.

    The value can be copied but not changed.

    import { TextInput } from '@bigbang/ui';
    export default function ReadOnly() {
    return (
    <TextInput
    label="Reference number"
    description="The value can be copied but not changed."
    name="reference"
    defaultValue="Value"
    readOnly
    className="w-full max-w-80"
    />
    );
    }

    There are two sizes. Pick the size by density and device.

    • Medium (md, 36 px): Most places, including desktop forms and filter fields.
    • Large (lg, 40 px): Mobile forms. The Button in the same form should be large too.
    import { TextInput } from '@bigbang/ui';
    export default function Sizes() {
    return (
    <div className="flex w-full max-w-80 flex-col gap-xl">
    <TextInput label="Medium" size="md" name="field-md" />
    <TextInput label="Large" size="lg" name="field-lg" />
    </div>
    );
    }

    A disabled field cannot be edited, does not take focus, and its value is not submitted with the form. Use it for information people need to see but cannot change, and explain why in the help text.

    Help or instruction text goes here

    import { TextInput } from '@bigbang/ui';
    export default function Disabled() {
    return <TextInput label="Field label" description="Help or instruction text goes here" defaultValue="Value" disabled className="w-full max-w-80" />;
    }

    To format the value while typing or tie it to another field, pass value and onValueChange together. This example shows the character count in the help text.

    0/20 characters

    import { TextInput } from '@bigbang/ui';
    import { useState } from 'react';
    const MAX_LENGTH = 20;
    export default function Controlled() {
    const [value, setValue] = useState('');
    return (
    <TextInput
    label="Field label"
    description={`${value.length}/${MAX_LENGTH} characters`}
    name="field"
    value={value}
    onValueChange={setValue}
    maxLength={MAX_LENGTH}
    className="w-full max-w-96"
    />
    );
    }

    TextInput takes all its colours from semantic tokens, so light and dark mode need no extra setup.

    Error message goes here
    Error message goes here
    import { TextInput } from '@bigbang/ui';
    export default function Invalid() {
    return (
    <TextInput
    label="Field label"
    error="Error message goes here"
    name="field"
    defaultValue="Value"
    className="w-full max-w-80"
    />
    );
    }