> ## Documentation Index
> Fetch the complete documentation index at: https://bkey.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Forms

> BMoniTextFormField, BMoniTextAreaField, and FileUploadWidget.

## BMoniTextFormField

A form field with two variants (`filled` and `outlined`), three sizes, and label / helper / error slots. Wraps Flutter's `TextFormField`.

### Filled variant

```dart theme={null}
BMoniTextFormField.filled(
  label: 'Email',
  hintText: 'you@example.com',
  keyboardType: TextInputType.emailAddress,
  size: BMoniTextFieldSize.medium,     // small | medium | large
  prefixIcon: const Icon(Icons.mail_outline),
  validator: (value) => value!.isEmpty ? 'Required' : null,
)
```

### Outlined variant

```dart theme={null}
BMoniTextFormField.outlined(
  label: 'Reference',
  hintText: 'INV-001',
)
```

### Common props

| Prop           | Type                          | Description                                            |
| -------------- | ----------------------------- | ------------------------------------------------------ |
| `label`        | `String?`                     | Floating label text.                                   |
| `hintText`     | `String?`                     | Placeholder text.                                      |
| `helperText`   | `String?`                     | Hint below the field.                                  |
| `errorText`    | `String?`                     | Error message below the field (overrides `validator`). |
| `size`         | `BMoniTextFieldSize`          | Controls height and font size.                         |
| `prefixIcon`   | `Widget?`                     | Widget shown at the start of the field.                |
| `suffixIcon`   | `Widget?`                     | Widget shown at the end of the field.                  |
| `controller`   | `TextEditingController?`      | Optional controller.                                   |
| `validator`    | `FormFieldValidator<String>?` | Validation callback.                                   |
| `onChanged`    | `ValueChanged<String>?`       | Called on every keystroke.                             |
| `keyboardType` | `TextInputType?`              | Keyboard type.                                         |
| `obscureText`  | `bool`                        | Obscure input (for passwords).                         |
| `readOnly`     | `bool`                        | Disable editing.                                       |
| `enabled`      | `bool`                        | Whether the field is interactive.                      |

***

## BMoniTextAreaField

A multiline text input with a grapheme-aware character counter built in.

```dart theme={null}
BMoniTextAreaField(
  controller: _noteController,
  label: 'Add a note',
  hintText: 'Optional message to the recipient',
  maxLength: 120,
  maxLines: 4,
)
```

| Prop         | Type                     | Default | Description                                                     |
| ------------ | ------------------------ | ------- | --------------------------------------------------------------- |
| `controller` | `TextEditingController?` | —       | Optional controller.                                            |
| `label`      | `String?`                | —       | Label text above the field.                                     |
| `hintText`   | `String?`                | —       | Placeholder text.                                               |
| `maxLength`  | `int?`                   | —       | Maximum character count; shown as `n/maxLength` in the counter. |
| `maxLines`   | `int`                    | `5`     | Maximum visible lines before scrolling.                         |
| `onChanged`  | `ValueChanged<String>?`  | —       | Called on every keystroke.                                      |

***

## FileUploadWidget

A dotted-border upload area. Switches automatically between placeholder, loading, and uploaded states based on the props you pass.

```dart theme={null}
FileUploadWidget(
  fileBytes: bytes,         // Uint8List? — set after the user picks a file
  fileName: 'invoice.pdf',  // shown once uploaded
  isLoading: false,         // shows a spinner while uploading
  onTap: pickFile,          // opens a file picker
  onRemove: () => setState(() => bytes = null),
  errorMessage: validationError,  // shown below the widget
)
```

| Prop           | Type            | Description                                                        |
| -------------- | --------------- | ------------------------------------------------------------------ |
| `fileBytes`    | `Uint8List?`    | Raw file bytes. When non-null the widget shows the uploaded state. |
| `fileName`     | `String?`       | File name displayed in the uploaded state.                         |
| `isLoading`    | `bool`          | When `true`, shows a spinner instead of the upload prompt.         |
| `onTap`        | `VoidCallback`  | Called to trigger the file picker.                                 |
| `onRemove`     | `VoidCallback?` | Called when the user removes the uploaded file.                    |
| `errorMessage` | `String?`       | Validation error shown below the widget.                           |
