# TextField

Ein TextField ermöglicht es dem Nutzer, Text über die Tastatur in ein User Interface einzugeben. Ein Label und eine optionale FieldDescription unterstützen dabei, die Anforderungen an die Eingabe klar zu kommunizieren.

## Overview

# Playground

Verwende `<TextField />`, um ein TextField anzuzeigen. Nutze ein `<Label />`, um
Informationen zu vermitteln, die das Verständnis der Eingabeanforderungen
erleichtern. Weiterführende Informationen (z. B. Formatierungshinweise) können
über die `<FieldDescription />` ergänzt werden.

```tsx
import {
  FieldDescription,
  Label,
  TextField,
} from "@mittwald/flow-react-components";

<TextField>
  <Label>URL</Label>
  <FieldDescription>Beginnt mit https://</FieldDescription>
</TextField>
```

---

# Disabled

Wenn das TextField disabled ist, kann nicht mit ihm interagiert werden. Sobald
die Ursache für die Deaktivierung behoben ist, kann das TextField wieder normal
verwendet werden.

```tsx
import {
  Label,
  TextField,
} from "@mittwald/flow-react-components";

<TextField isDisabled>
  <Label>URL</Label>
</TextField>
```

---

# Validierung

Um das textField zu validieren, stehen folgende Properties zur Verfügung:

- `isRequired` für Pflichtfelder.
- `validate` für eigene Validierungen.
- HTML Input Properties wie `type="email"`, `minLength`.

Wenn die Benutzereingabe nicht den Anforderungen entspricht, wird das TextField
invalidiert. Mittels `<FieldError />` kann eine Fehlermeldung angezeigt werden.

```tsx
import {
  FieldError,
  Label,
  TextField,
} from "@mittwald/flow-react-components";

<TextField isInvalid defaultValue="hello">
  <Label>URL</Label>
  <FieldError>Das ist keine URL</FieldError>
</TextField>
```

---

# Value

Standardmäßig ist der Value eines TextFields leer. Es ist möglich dem TextField
eine uncontrolled `defaultValue` mitzugeben. Es kann auch ein controlled `value`
für das TextField gesetzt werden, um dieses über `onChange` zu updaten.

```tsx
import {
  Label,
  TextField,
} from "@mittwald/flow-react-components";

<TextField defaultValue="https://mittwald.de">
  <Label>URL</Label>
</TextField>
```

---

# Input Properties

Das TextField unterstützt die Standard-Properties eines HTML `<input />` Feldes.
(s. [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input))

```tsx
import {
  Label,
  TextField,
} from "@mittwald/flow-react-components";

<TextField name="email" type="email">
  <Label>E-Mail</Label>
</TextField>
```

---

# Character Count

Über das `showCharacterCount` Property wird eine FieldDescription hinzugefügt,
die aktuelle Anzahl der Zeichen und, falls angegeben, die maximale Zeichenanzahl
anzeigt.

```tsx
import {
  Label,
  TextField,
} from "@mittwald/flow-react-components";

<TextField showCharacterCount maxLength={10}>
  <Label>Benutzername</Label>
</TextField>
```

---

# Passwort

TextFields mit `type="password"` erhalten automatisch einen Button zum ein- und
ausblenden des Passworts.

```tsx
import {
  Label,
  TextField,
} from "@mittwald/flow-react-components";

<TextField type="password">
  <Label>Passwort</Label>
</TextField>
```

---

# Kombiniere mit ...

## Align

Benutze die [Align](/04-components/structure/align/overview) Komponente, um
einem Button neben deinem TextField zu platzieren.

```tsx
import {
  Align,
  Button,
  Label,
  TextField,
} from "@mittwald/flow-react-components";

<Align>
  <TextField>
    <Label>Weiterleitungsziel</Label>
  </TextField>
  <Button>Hinzufügen</Button>
</Align>
```

## ContextualHelp

Benutze die [ContextualHelp](/04-components/overlays/contextual-help/overview)
Komponente, wenn du weitere Informationen bereitstellen möchtest, und diese zu
lang für die FieldDescription sind.

```tsx
import {
  Button,
  ContextualHelp,
  ContextualHelpTrigger,
  Heading,
  Label,
  Text,
  TextField,
} from "@mittwald/flow-react-components";

<TextField>
  <Label>
    URL
    <ContextualHelpTrigger>
      <Button />
      <ContextualHelp>
        <Heading>Weitere Informationen</Heading>
        <Text>
          Hier gibt es weitere Informationen, die zu lang
          für die FieldDescription sind.
        </Text>
      </ContextualHelp>
    </ContextualHelpTrigger>
  </Label>
</TextField>
```

## React Hook Form

```tsx
import {
  Label,
  Section,
  TextField,
} from "@mittwald/flow-react-components";
import { useForm } from "react-hook-form";
import {
  Form,
  SubmitButton,
  typedField,
} from "@mittwald/flow-react-components/react-hook-form";
import { sleep } from "@/content/04-components/actions/action/examples/lib";

export default () => {
  const form = useForm<{ url: string }>();
  const Field = typedField(form);

  return (
    <Section>
      <Form form={form} onSubmit={sleep}>
        <Field
          name="url"
          rules={{
            required: "Bitte gib eine URL ein",
          }}
        >
          <TextField>
            <Label>URL</Label>
          </TextField>
        </Field>
        <SubmitButton>Speichern</SubmitButton>
      </Form>
    </Section>
  );
}
```

## Button

Du kannst einen Button zum TextField hinzufügen, um benutzerdefinierte Aktionen
auszuführen.

```tsx
import {
  Label,
  TextField,
  Button,
  IconStar,
} from "@mittwald/flow-react-components";

<TextField>
  <Label>Label</Label>
  <Button aria-label="Custom Button">
    <IconStar />
  </Button>
</TextField>
```


## Develop

# Properties

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `showCharacterCount` | `boolean` | - | Whether a character count should be displayed inside the field description. |
| `id` | `string` | - | The element's unique identifier. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id). |
| `translate` | `"yes" \| "no"` | - | - |
| `className` | `ClassNameOrFunction<TextFieldRenderProps>` | `'react-aria-TextField'` | The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the element. A function may be provided to compute the class based on component state. |
| `style` | `StyleOrFunction<TooltipRenderProps>` | - | The inline [style](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style) for the element. A function may be provided to compute the style based on component state. |
| `render` | `DOMRenderFunction<"div", TooltipRenderProps>` | - | Overrides the default DOM element with a custom render function. This allows rendering existing components with built-in styles and behaviors such as router links, animation libraries, and pre-styled components. Requirements: - You must render the expected element type (e.g. if `<button>` is expected, you cannot render an `<a>`). - Only a single root DOM element can be rendered (no fragments). - You must pass through props and ref to the underlying DOM element, merging with your own prop as appropriate. |
| `dir` | `string` | - | - |
| `lang` | `string` | - | - |
| `hidden` | `boolean` | - | - |
| `inert` | `boolean` | - | - |
| `validationBehavior` | `"native" \| "aria"` | `'native'` | Whether to use native HTML form validation to prevent form submission when the value is missing or invalid, or mark the field as required or invalid via ARIA. |
| `isDisabled` | `boolean` | - | Whether the input is disabled. |
| `isReadOnly` | `boolean` | - | Whether the input can be selected but not changed by the user. |
| `isRequired` | `boolean` | - | Whether user input is required on the input before form submission. |
| `isInvalid` | `boolean` | - | Whether the value is invalid. |
| `validate` | `((value: TimeValue) => true \| ValidationError)` | - | A function that returns an error message if a given value is invalid. Validation errors are displayed to the user when the form is submitted if `validationBehavior="native"`. For realtime validation, use the `isInvalid` prop instead. |
| `autoFocus` | `boolean` | - | Whether the element should receive focus on render. |
| `value` | `TimeValue` | - | The current value (controlled). |
| `defaultValue` | `TimeValue` | - | The default value (uncontrolled). |
| `name` | `string` | - | The name of the input element, used when submitting an HTML form. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefname). |
| `form` | `string` | - | The `<form>` element to associate the input with. The value of this attribute must be the id of a `<form>` in the same document. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input#form). |
| `slot` | `string` | - | A slot name for the component. Slots allow the component to receive props from a parent component. An explicit `null` value indicates that the local props completely override all props received from a parent. |
| `enterKeyHint` | `"enter" \| "done" \| "go" \| "next" \| "previous" \| "search" \| "send"` | - | An enumerated attribute that defines what action label or icon to preset for the enter key on virtual keyboards. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/enterkeyhint). |
| `excludeFromTabOrder` | `boolean` | - | Whether to exclude the element from the sequential tab order. If true, the element will not be focusable via the keyboard by tabbing. This should be avoided except in rare scenarios where an alternative means of accessing the element or its functionality via the keyboard is available. |
| `autoComplete` | `string` | - | Describes the type of autocomplete functionality the input should provide if any. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefautocomplete). |
| `maxLength` | `number` | - | The maximum number of characters supported by the input. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefmaxlength). |
| `minLength` | `number` | - | The minimum number of characters required by the input. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefminlength). |
| `pattern` | `string` | - | Regex pattern that the value of the input must match to be valid. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefpattern). |
| `type` | `"text" \| "search" \| "url" \| "tel" \| "email" \| "password" \| (string & {})` | `'text'` | The type of input to render. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdeftype). |
| `inputMode` | `"text" \| "none" \| "search" \| "url" \| "tel" \| "email" \| "numeric" \| "decimal"` | - | Hints at the type of data that might be entered by the user while editing the element or its contents. See [MDN](https://html.spec.whatwg.org/multipage/interaction.html#input-modalities:-the-inputmode-attribute). |
| `autoCorrect` | `string` | - | An attribute that takes as its value a space-separated string that describes what, if any, type of autocomplete functionality the input should provide. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#autocomplete). |
| `spellCheck` | `string` | - | An enumerated attribute that defines whether the element may be checked for spelling errors. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/spellcheck). |
| `children` | `ReactNode` | - | - |
| `placeholder` | `string` | - | Temporary text that occupies the text input when it is empty. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/placeholder). |
| `wrapWith` | `ReactElement<unknown, string \| JSXElementConstructor<any>>` | - | - |
| `ref` | `Ref<HTMLSpanElement>` | - | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). @see [React Docs](https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom) |
| `key` | `Key` | - | - |

### Events

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `onClick` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onClickCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onAuxClick` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onAuxClickCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onContextMenu` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onContextMenuCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onDoubleClick` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onDoubleClickCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseDown` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseDownCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseEnter` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseLeave` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseMove` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseMoveCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseOut` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseOutCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseOver` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseOverCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseUp` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseUpCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onTouchCancel` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchCancelCapture` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchEnd` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchEndCapture` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchMove` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchMoveCapture` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchStart` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchStartCapture` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onPointerDown` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerDownCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerMove` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerMoveCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerUp` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerUpCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerCancel` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerCancelCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerEnter` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerLeave` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerOver` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerOverCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerOut` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerOutCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onGotPointerCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onGotPointerCaptureCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onLostPointerCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onLostPointerCaptureCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onScroll` | `UIEventHandler<HTMLDivElement>` | - | - |
| `onScrollCapture` | `UIEventHandler<HTMLDivElement>` | - | - |
| `onWheel` | `WheelEventHandler<HTMLDivElement>` | - | - |
| `onWheelCapture` | `WheelEventHandler<HTMLDivElement>` | - | - |
| `onAnimationStart` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onAnimationStartCapture` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onAnimationEnd` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onAnimationEndCapture` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onAnimationIteration` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onAnimationIterationCapture` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onTransitionCancel` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionCancelCapture` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionEnd` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionEndCapture` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionRun` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionRunCapture` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionStart` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionStartCapture` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onFocus` | `((e: FocusEvent<Element, Element>) => void)` | - | Handler that is called when the element receives focus. |
| `onBlur` | `((e: FocusEvent<Element, Element>) => void)` | - | Handler that is called when the element loses focus. |
| `onFocusChange` | `((isFocused: boolean) => void)` | - | Handler that is called when the element's focus status changes. |
| `onKeyDown` | `((e: KeyboardEvent) => void)` | - | Handler that is called when a key is pressed. |
| `onKeyUp` | `((e: KeyboardEvent) => void)` | - | Handler that is called when a key is released. |
| `onChange` | `((value: TimeValue) => void)` | - | Handler that is called when the value changes. |
| `onCopy` | `ClipboardEventHandler<HTMLInputElement>` | - | Handler that is called when the user copies text. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/oncopy). |
| `onCut` | `ClipboardEventHandler<HTMLInputElement>` | - | Handler that is called when the user cuts text. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/oncut). |
| `onPaste` | `ClipboardEventHandler<HTMLInputElement>` | - | Handler that is called when the user pastes text. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/onpaste). |
| `onCompositionStart` | `CompositionEventHandler<HTMLInputElement>` | - | Handler that is called when a text composition system starts a new text composition session. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionstart_event). |
| `onCompositionEnd` | `CompositionEventHandler<HTMLInputElement>` | - | Handler that is called when a text composition system completes or cancels the current text composition session. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionend_event). |
| `onCompositionUpdate` | `CompositionEventHandler<HTMLInputElement>` | - | Handler that is called when a new character is received in the current text composition session. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionupdate_event). |
| `onSelect` | `ReactEventHandler<HTMLInputElement>` | - | Handler that is called when text in the input is selected. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/select_event). |
| `onBeforeInput` | `FormEventHandler<HTMLInputElement>` | - | Handler that is called when the input value is about to be modified. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/beforeinput_event). |
| `onInput` | `FormEventHandler<HTMLInputElement>` | - | Handler that is called when the input value is modified. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event). |

### Accessibility

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `aria-label` | `string` | - | Defines a string value that labels the current element. |
| `aria-labelledby` | `string` | - | Identifies the element (or elements) that labels the current element. |
| `aria-describedby` | `string` | - | Identifies the element (or elements) that describes the object. |
| `aria-details` | `string` | - | Identifies the element (or elements) that provide a detailed, extended description for the object. |
| `aria-activedescendant` | `string` | - | Identifies the currently active element when DOM focus is on a composite widget, textbox, group, or application. |
| `aria-autocomplete` | `"list" \| "none" \| "inline" \| "both"` | - | Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be presented if they are made. |
| `aria-haspopup` | `boolean \| "false" \| "true" \| "menu" \| "listbox" \| "tree" \| "grid" \| "dialog"` | - | Indicates the availability and type of interactive popup element, such as menu or dialog, that can be triggered by an element. |
| `aria-controls` | `string` | - | Identifies the element (or elements) whose contents or presence are controlled by the current element. |
| `aria-errormessage` | `string` | - | Identifies the element that provides an error message for the object. |


## Guidelines

# Grundlagen

## Best practices

- Frage nur nach Informationen, die wirklich notwendig sind.
- Stelle sicher, dass das [Label](/04-components/content/label/overview)
  prägnant, vollständig sichtbar und leicht verständlich ist.
- Verwende die FieldDescription für sinnvolle Beispiele oder
  Formatierungshinweise.
- Stelle sicher, dass Fehlermeldungen hilfreich sind, eine Lösung bieten und
  leicht umzusetzen sind.
- Verwende keine Placeholder für wesentliche Informationen.

---

# Anwendung

## Position

Das TextField wird meistens innerhalb eines
[ColumnLayouts](/04-components/structure/column-layout/overview) platziert und
füllt dort immer die zur Verfügung stehende Breite. Dadurch folgt es auch einer
Aufteilung in Spalten, sofern das ColumnLayout eine vorsieht. Am besten eignet
sich ein 1:1 Raster für TextFields, sodass sie maximal die Hälfte des
Content-Bereichs einnehmen können. Das ColumnLayout kann zudem erweitert werden,
um spezifischeren Layoutanforderungen gerecht zu werden.

**✅ Do**

Nutze ein 1:1 [ColumnLayout](/04-components/structure/column-layout/overview) für
TextFields. Darin kann ein weiteres Raster (z. B. 2:1) verwendet werden, um
sinnvolle Gruppierungen (z. B. Straße und Hausnummer) innerhalb des Layouts zu
erstellen.

```tsx
import {
  ColumnLayout,
  Label,
  TextField,
} from "@mittwald/flow-react-components";

<ColumnLayout m={[1, 1]}>
  <TextField isRequired>
    <Label>Vorname</Label>
  </TextField>
  <TextField isRequired>
    <Label>Nachname</Label>
  </TextField>
  <ColumnLayout s={[2, 1]}>
    <TextField isRequired>
      <Label>Straße</Label>
    </TextField>
    <TextField isRequired>
      <Label>Hausnummer</Label>
    </TextField>
  </ColumnLayout>
  <ColumnLayout s={[2, 1]}>
    <TextField isRequired>
      <Label>Stadt</Label>
    </TextField>
    <TextField isRequired>
      <Label>PLZ</Label>
    </TextField>
  </ColumnLayout>
  <TextField isRequired>
    <Label>Land</Label>
  </TextField>
</ColumnLayout>
```

---

## isRequired

Um ein TextField als erforderlich zu markieren, benutze das dazugehörige
Property `isRequired`. Felder, die nicht required sind, werden als optional
gekennzeichnet.

```tsx
import {
  ColumnLayout,
  Label,
  TextField,
} from "@mittwald/flow-react-components";

<ColumnLayout m={[1, 1]}>
  <TextField isRequired>
    <Label>URL</Label>
  </TextField>
  <TextField>
    <Label>URL</Label>
  </TextField>
</ColumnLayout>
```

---

# Inhalt

## Label

Jedes TextField sollte ein passendes
[Label](/04-components/content/label/overview) besitzen. Ein gutes Label
vermittelt alle notwendigen Informationen, um das TextField korrekt auszufüllen.
Außerdem sollte es knapp (max. 2 Wörter), präzise und weder versteckt noch
auspunktiert sein.

  

**✅ Do**

Verwende ein kurzes, präzises Label, das essentielle Eingabeanforderungen kommuniziert.

```tsx
import {
  FieldDescription,
  Label,
  TextField,
} from "@mittwald/flow-react-components";

<TextField>
  <Label>URL</Label>
  <FieldDescription>Beginnt mit https://</FieldDescription>
</TextField>
```

---

## FieldDescription

Die FieldDescription kann als optionaler Hilfstext unterhalb des TextFields
angezeigt werden, um dem Nutzer ergänzenden Informationen oder Anweisungen zu
bieten. Sie sollte sparsam verwendet werden und kann Eingabe- und
Formatierungsbeispiele liefern.

---

## Placeholder

Placeholder sind nicht accessible und dürfen daher keine Informationen
enthalten, die für das korrekte Ausfüllen des TextFields erforderlich sind. Das
größte Problem ist, dass Placeholder verschwinden, sobald Text eingegeben wird.
Darüber hinaus werden sie von manchen Assistenztechnologien nicht korrekt
erkannt und sind kognitiv schwieriger zu verarbeiten als die FieldDescription.
Statt einen Placeholder zu verwenden, ergänze das TextField mit ...

- einem [Label](/04-components/content/label/overview) für Informationen, die
  essenziell für das Verständnis der Eingabeanforderungen sind.
- einer FieldDescription, um dem Nutzer Beispiele oder Formatierungshinweise zu
  geben.

  

**⛔️ Don't**

Placeholder sollten keine essentiellen Informationen oder Formatierungshinweise enthalten.

```tsx
import {
  Label,
  TextField,
} from "@mittwald/flow-react-components";

<TextField placeholder="https://">
  <Label>URL</Label>
</TextField>
```

  

**✅ Do**

Verwende das [Label](/04-components/content/label/overview) für essentielle Informationen und die FieldDescription für Ergänzungen, z. B. Formatierungshinweise oder Beispiele.

```tsx
import {
  FieldDescription,
  Label,
  TextField,
} from "@mittwald/flow-react-components";

<TextField>
  <Label>URL</Label>
  <FieldDescription>Beginnt mit https://</FieldDescription>
</TextField>
```

---

# Accessibility

Das TextField kann sowohl über die Tastatur erreicht und aktiviert werden als
auch mit Assistenztechnologien angesteuert werden. Damit auch der Inhalt
barrierefrei ist, solltest du:

- wenn möglich ein [Label](/04-components/content/label/overview) verwenden,
  welches essenzielle Eingabeanforderungen über das Label kommuniziert. Können
  die Eingabeanforderungen an das TextField durch den Kontext erschlossen
  werden, kann auf den Einsatz eines Labels verzichtet werden. In diesem Fall
  muss das TextField über **aria-labelledby** verknüpft oder über ein
  **aria-label** beschrieben werden.
- die FieldDescription nutzen, um Unterstützung, Beispiele oder
  Formatierungshilfen zu geben.
- Placeholder nicht für Inhalte verwenden, die zum Ausfüllen des TextFields
  hilfreich sind.

