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

# Image Picker

> A widget for selecting images via file picker or drag-and-drop, with built-in validation, error handling, and loading states.

## Examples

<Tabs>
  <Tab title="Basic">
    <Frame caption="Empty state of the image picker.">
      <img src="https://mintcdn.com/tvk/EnfSBsC4lDuv4PDt/images/widgets/pickers/image-picker/image_picker_basic_light.png?fit=max&auto=format&n=EnfSBsC4lDuv4PDt&q=85&s=7be52a82e86b29d3035ca1c14b36e83f" alt="Basic image picker example" noZoom className="block dark:hidden" width="1536" height="768" data-path="images/widgets/pickers/image-picker/image_picker_basic_light.png" />

      <img src="https://mintcdn.com/tvk/EnfSBsC4lDuv4PDt/images/widgets/pickers/image-picker/image_picker_basic_dark.png?fit=max&auto=format&n=EnfSBsC4lDuv4PDt&q=85&s=4b0cdc12813f1394dcbe3cfd6c4ea5d4" alt="Basic image picker example" noZoom className="hidden dark:block" width="1536" height="768" data-path="images/widgets/pickers/image-picker/image_picker_basic_dark.png" />
    </Frame>

    <CodeGroup>
      ```dart Basic Usage lines theme={null}
      NeoImagePicker(
        currentImage: imageBytes,
        onChanged: (bytes) {
          imageBytes = bytes;
        },
      ),
      ```
    </CodeGroup>
  </Tab>

  <Tab title="With Label & Description">
    <Frame caption="Image picker with label and description text.">
      <img src="https://mintcdn.com/tvk/EnfSBsC4lDuv4PDt/images/widgets/pickers/image-picker/image_picker_label_light.png?fit=max&auto=format&n=EnfSBsC4lDuv4PDt&q=85&s=586bbc2353780cc45aee0e278f6a9876" alt="Image picker with label example" noZoom className="block dark:hidden" width="1536" height="768" data-path="images/widgets/pickers/image-picker/image_picker_label_light.png" />

      <img src="https://mintcdn.com/tvk/EnfSBsC4lDuv4PDt/images/widgets/pickers/image-picker/image_picker_label_dark.png?fit=max&auto=format&n=EnfSBsC4lDuv4PDt&q=85&s=f1c34f7e9ceb22c290df8be87ecfe555" alt="Image picker with label example" noZoom className="hidden dark:block" width="1536" height="768" data-path="images/widgets/pickers/image-picker/image_picker_label_dark.png" />
    </Frame>

    <CodeGroup>
      ```dart With Label lines theme={null}
      NeoImagePicker(
        currentImage: imageBytes,
        onChanged: (bytes) {
          imageBytes = bytes;
        },
        label: "Profile Picture",
        description: "Max 5MB.",
        maxFileSize: 5 * 1024 * 1024,
      ),
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Custom Error Handling">
    <Frame caption="Image picker showing an error state with custom error messages.">
      <img src="https://mintcdn.com/tvk/EnfSBsC4lDuv4PDt/images/widgets/pickers/image-picker/image_picker_error_light.png?fit=max&auto=format&n=EnfSBsC4lDuv4PDt&q=85&s=79eae3f7b58c24882542ba817d069794" alt="Image picker error state example" noZoom className="block dark:hidden" width="1536" height="768" data-path="images/widgets/pickers/image-picker/image_picker_error_light.png" />

      <img src="https://mintcdn.com/tvk/EnfSBsC4lDuv4PDt/images/widgets/pickers/image-picker/image_picker_error_dark.png?fit=max&auto=format&n=EnfSBsC4lDuv4PDt&q=85&s=537516c17cc9843004b5337b66c66f4d" alt="Image picker error state example" noZoom className="hidden dark:block" width="1536" height="768" data-path="images/widgets/pickers/image-picker/image_picker_error_dark.png" />
    </Frame>

    <CodeGroup>
      ```dart Custom Errors lines theme={null}
      NeoImagePicker(
        currentImage: imageBytes,
        onChanged: (bytes) {
          imageBytes = bytes;
        },
        onError: (error) => switch (error) {
          .fileTooLarge => "Image must be under 10MB",
          _ => null, // Falls back to default message
        },
      ),
      ```
    </CodeGroup>
  </Tab>
</Tabs>

## Properties

### Required

<ParamField path="onChanged" type="ValueChanged<Uint8List?>" required>
  Called when an image is selected, dropped, or cleared. Receives the raw image bytes, or `null` when the image is removed.
</ParamField>

### Content

<ParamField path="currentImage" type="Uint8List?">
  The currently displayed image as raw bytes. When provided, the image is rendered inside the picker with a swap overlay on hover and an optional clear button.
</ParamField>

<ParamField path="label" type="String?">
  A label displayed above the picker area.
</ParamField>

<ParamField path="description" type="String?">
  Helper text displayed below the picker area.
</ParamField>

<ParamField path="errorText" type="String?">
  External error text displayed below the picker. Overrides any internal error messages.
</ParamField>

<ParamField path="placeholder" type="String?" default="Select or drop an image">
  Custom placeholder text shown when no image is selected.
</ParamField>

<ParamField path="onError" type="String? Function(NeoImagePickerError)?">
  Custom error message resolver. Return a string to override the default message for a specific error, or `null` to use the default.
</ParamField>

### Layout

<ParamField path="maxFileSize" type="int" default="104857600 (100MB)">
  Maximum allowed file size in bytes. Files exceeding this limit trigger a `fileTooLarge` error.
</ParamField>

<ParamField path="showClearButton" type="bool" default="true">
  Whether to show a clear button in the top-right corner when an image is displayed.
</ParamField>

### State

<ParamField path="isEnabled" type="bool" default="true">
  Controls whether the picker responds to taps and drag-and-drop. Disabled pickers show reduced opacity and a forbidden cursor.
</ParamField>

## Enums

### NeoImagePickerError

Error types that can occur during image selection or processing.

* `fileTooLarge`: The selected file exceeds `maxFileSize`.
* `unsupportedFormat`: The dropped file is not a supported image format.
* `pickFailed`: The file picker failed to open or return a result.
* `readFailed`: The file could not be read from disk.
* `dropFailed`: The drag-and-drop operation failed.
* `renderFailed`: The image bytes could not be rendered (invalid format).
* `unknown`: An unexpected error occurred.

## Best Practices

* **Set a reasonable `maxFileSize`**: The default 100MB limit is generous. For profile pictures or thumbnails, set a lower limit (e.g., `5 * 1024 * 1024` for 5MB) or compress on the server side.
* **Provide custom error messages with `onError`**: Tailor error messages to your use case or language for a better user experience.
* **Constrain the height**: When used inside unbounded layouts, the picker defaults to 240px height. Wrap in a `SizedBox` or use within bounded constraints for custom sizing.

## Integration Notes

* **Supported formats**: PNG, JPEG, GIF, WebP, HEIC, HEIF, BMP, and TIFF.
* **Loading state**: The picker automatically shows a loading overlay while processing files or drag-and-drop operations.
* **Image display**: Selected images are displayed with `BoxFit.contain`. On hover, a swap icon overlay appears to indicate the image can be replaced.
