# Text Inputs

> Material Design 3 text fields, from the HTML.

## Anatomy

A `.field` is the container. The `<label>` after the control is the floating label. An icon names its side with `prefix` or `suffix` and is `aria-hidden`. `<small>` is supporting text. The default is the M3 filled field; add `outlined` for the outlined variant.

Tokens follow the [M3 text field spec](https://m3.material.io/components/text-fields/specs). Height is 56dp. Filled is a `surface-variant` well with 4dp top corners and a 1dp / 2dp bottom indicator. Outlined is a 1dp / 2dp `outline` at 4dp. The label is `body-large` at rest and `body-small` floated. Input text is `body-large` / `on-surface`. Icons are 24dp, 12dp from the edge.

Add `placeholder=" "` (one space) so the label floats with CSS only. A missing placeholder, or any other string, keeps the label floated. Importing the bundle runs `Forms.Init()`; it validates `.validate` fields on `change` and starts textareas and file paths. Character Counter is not in `AutoInit()`.

 First name Supporting text

 Last name

 Disabled

 Disabled

 Location

 Failing input Invalid characters. Please use 0-9 only.

```
<div class="field">
  <input id="first_name" type="text" placeholder=" " aria-describedby="first_name_help">
  <label for="first_name">First name</label>
  <small id="first_name_help">Supporting text</small>
</div>

<div class="field outlined">
  <input id="last_name" type="text" placeholder=" ">
  <label for="last_name">Last name</label>
</div>

<div class="field">
  <span class="material-symbols prefix" aria-hidden="true">place</span>
  <span class="material-symbols suffix" aria-hidden="true">gps_fixed</span>
  <input id="loc" type="text" placeholder=" ">
  <label for="loc">Location</label>
</div>
```

Put `invalid` or `aria-invalid="true"` on the input for the error state. Do not put `error` on the wrapper — that class is a color utility and fills the field. `.supporting-text` and `.prefix` / `.suffix` remain as aliases.

## Input types

`email`, `password`, and the other native text-like types are styled the same way. `validate` uses HTML5 constraint validation on `change` and toggles `invalid` on the input. There is no green `valid` style.

 Email Supporting text

 Password

```
<div class="field">
  <input id="email" type="email" class="validate" placeholder=" " aria-describedby="email_help">
  <label for="email">Email</label>
  <small id="email_help" data-error="Enter a valid email">Supporting text</small>
</div>
```

`validate` also honors `data-length`: the field is marked `invalid` when the value is longer than that number. Prefer `maxlength` when you want the browser to cap input.

## Inline

Add `inline` to sit the field in a line of text.

This is an inline input field:  Email

```
This is an inline input field:
<span class="field inline">
  <input id="email_inline" type="email" class="validate" placeholder=" ">
  <label for="email_inline">Email</label>
</span>
```

## Textarea

Use `textarea.expressive-textarea` inside `.field`. That class name is Expressive’s; there is no `.materialize-textarea`. Textareas grow with their content. `Forms.Init()` starts every `.expressive-textarea` on `DOMContentLoaded`.

Textarea

Message

```
<div class="field">
  <textarea id="textarea1" class="expressive-textarea" placeholder=" "></textarea>
  <label for="textarea1">Textarea</label>
</div>
```

If you add a textarea after load, initialize it yourself:

```
Expressive.Forms.InitTextarea(document.querySelector('#textarea1'));
```

Setting `.value` in script does not resize the field. Call `textareaAutoResize` afterwards.

## File input

A `.file-field.field` pairs a button with a path field. `Forms.Init()` copies the chosen file name into `input.file-path`.

File 

```
<div class="file-field field">
  <label class="button">
    File
    <input type="file">
  </label>
  <div class="file-path-wrapper">
    <input class="file-path" type="text" placeholder=" " readonly aria-label="Selected file">
  </div>
</div>
```

Add `multiple` to allow more than one file.

## Character counter

Character Counter is not in `AutoInit()`. It reads `maxlength` (not `data-length`) and writes `current/max` into a `.character-counter` span. Overflow adds `invalid` on the field.

 Input text

Textarea

```
Expressive.CharacterCounter.init(
  document.querySelectorAll('#input_text, #textarea2')
);
```
