# `PhoenixKitWeb.Live.Components.MediaSelectorModal`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.164/lib/phoenix_kit_web/live/components/media_selector_modal.ex#L1)

Media selector modal component.

A reusable modal component for selecting media files from anywhere in the admin panel.
Supports both single and multiple selection modes.

## Usage

    # In parent LiveView, add to socket assigns
    socket
    |> assign(:show_media_selector, false)
    |> assign(:media_selection_mode, :single)
    |> assign(:media_selected_uuids, [])

    # In template (IMPORTANT: Must pass phoenix_kit_current_user for uploads to work)
    <.live_component
      module={PhoenixKitWeb.Live.Components.MediaSelectorModal}
      id="media-selector-modal"
      show={@show_media_selector}
      mode={@media_selection_mode}
      selected_uuids={@media_selected_uuids}
      phoenix_kit_current_user={@phoenix_kit_current_user}
    />

    # To open the modal
    def handle_event("open_media_selector", _params, socket) do
      {:noreply, assign(socket, :show_media_selector, true)}
    end

    # To receive selected media
    def handle_info({:media_selected, file_uuids}, socket) do
      # Handle the selected file UUIDs
      {:noreply, socket |> assign(:gallery_uuids, file_uuids)}
    end

## Required host wiring (do not skip — silent failure otherwise)

This is a `LiveComponent`, so it has no `handle_info` of its own; it
reports the user's choice by sending a **process message to the host
LiveView**. The host MUST handle it, or the selection is silently
dropped (the modal closes, nothing happens — no crash, no warning):

  * `handle_info({:media_selected, file_uuids}, socket)` — **required.**
    Fired when the user confirms; `file_uuids` is the chosen list.
  * `handle_info({:media_selector_closed}, socket)` — recommended (fired
    on cancel/close) so the host can reset its own open-state assign.

Each host does something different with the files (avatar, gallery,
product images…), so there is intentionally no `use ...Embed` macro to
inject this — the handling is yours to write.

Alternative — `:notify`: pass `notify: {SomeComponent, id}` and the
result is delivered to that **component** via `send_update` instead
(`update(%{media_selected: uuids}, socket)` /
`update(%{media_selector_closed: true}, socket)`), for when the
consumer is itself a LiveComponent.

## Attrs

  * `show` — boolean, controls modal visibility
  * `mode` — `:single` or `:multiple`
  * `selected_uuids` — list of already-selected file UUIDs
  * `phoenix_kit_current_user` — required for uploads to attribute the file
  * `file_type_filter` — `:all` (default), `:image`, or `:video`
  * `browse` — `true` (default) shows the library grid + search + type filter;
    `false` is upload-only (dropzone + Confirm; uploaded files auto-select)
  * `user_uuid` — when set, restricts the library to files owned by
    that user; nil (default) shows the full library
  * `scope_folder_id` — when set, restricts both the browse query
    and the post-upload home folder to this folder UUID. Plugins
    scoping the picker to a single domain object (e.g. a catalogue
    item) pass this after lazy-creating their folder; files already
    living elsewhere get a `FolderLink` into the scope folder on
    re-upload rather than being moved out from under their original
    owner. `nil` (default) = no scope, legacy full-library behaviour.

# `handle_event`

# `render`

# `update`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
