Директива wire:drop⚓︎
wire:drop превращает любой элемент в зону перетаскивания. Он отслеживает перетаскивание объектов над элементом, отражает состояние перетаскивания, чтобы вы могли оформить оверлей, и вычисляет своё выражение, когда объект отпускается.
В отличие от обычного обработчика события drop, которое браузер не вызывает, пока вручную не отменено событие dragover, wire:drop самостоятельно управляет всем жизненным циклом перетаскивания.
Использование⚓︎
Самый распространённый вариант использования зоны перетаскивания — приём файлов. Для этого применяется модификатор .file вместе с действием $upload, которое загружает перетащенные файлы в свойство компонента:
<?php
use Livewire\Attributes\Validate;
use Livewire\WithFileUploads;
use Livewire\Component;
new class extends Component {
use WithFileUploads;
#[Validate(['photos.*' => 'image|max:10240'])]
public $photos = [];
};
Модификатор .file ограничивает зону перетаскивания только случаями, когда перетаскиваются файлы, — при перетаскивании выделенного текста над элементом ничего не происходит. Перетащенные файлы проходят через стандартный механизм загрузки файлов: временные загрузки, валидацию, предпросмотры и полноценные объекты загрузки — всё работает точно так же, как если бы файлы были выбраны через поле выбора файлов.
Оформление состояния перетаскивания⚓︎
Пока объект перетаскивается над зоной перетаскивания, Livewire добавляет элементу атрибут data-dragging. Его можно использовать для оформления с помощью обычного CSS — никакого JavaScript не требуется:
<div wire:drop.file="$upload('photos')" class="border-dashed data-dragging:border-blue-500">
Перетащите фотографии сюда
</div>
Или используйте in-*-варианты Tailwind для стилизации дочернего элемента:
<div wire:drop.file="$upload('photos')">
<div class="opacity-0 in-data-dragging:opacity-100">
Отпустите, чтобы загрузить
</div>
</div>
При использовании .file этот атрибут появляется только при перетаскивании файлов, поэтому оверлей никогда не будет мигать, когда пользователь перетаскивает текст по странице.
Приём файлов, перетаскиваемых в любую область страницы⚓︎
Интерфейсы чатов и редакторов часто принимают файлы, перетаскиваемые в любую область окна, а не только в определённую зону. Добавьте модификатор .window, чтобы прослушивать события на уровне окна:
<div wire:drop.file.window="$upload('attachments')">
{ Полноэкранный оверлей, отображаемый, пока файлы перетаскиваются над страницей... }
<div class="hidden in-data-dragging:grid fixed inset-0 place-items-center bg-black/50 text-white">
Перетащите файлы, чтобы прикрепить их
</div>
{ ... }
</div>
Атрибут data-dragging по-прежнему добавляется к элементу, на котором указан директива, поэтому у оверлея всегда есть элемент, к которому можно привязать стили.
Универсальные зоны перетаскивания⚓︎
Без .file директива wire:drop работает как универсальная зона перетаскивания: любое перетаскивание активирует её, а при отпускании объекта вычисляется указанное выражение. Событие drop при этом доступно через $event. Такой режим подходит для обработки объектов, не являющихся файлами, например текста, ссылок или изображений, перетаскиваемых из другой вкладки.
<div wire:drop="importFromUrl($event.dataTransfer.getData('text/uri-list'))">
Перетащите ссылку сюда
</div>
Стоит знать о двух особенностях поведения по умолчанию:
- Для файлов, перетаскиваемых в зону, стандартное поведение браузера всегда отменяется — ведь никто не ожидает, что при перетаскивании файла в приложение браузер покинет текущую страницу и откроет этот файл.
- Для всех остальных объектов сохраняется стандартное поведение браузера (например, при перетаскивании текста в поле ввода он будет вставлен), если только ваше выражение не вызывает
$event.preventDefault().
Загрузка файлов через универсальную зону перетаскивания тоже работает
$upload самостоятельно выполняет необходимую фильтрацию — при использовании обычного wire:drop="$upload('photos')" он загрузит перетащенные файлы и молча проигнорирует всё остальное. Используйте .file, если хотите, чтобы сама зона перетаскивания реагировала только на файлы, а data-dragging (и, соответственно, ваш оверлей) появлялся только при перетаскивании файлов.
Справочник⚓︎
| Модификатор | Описание |
|---|---|
.file |
Ограничивает зону перетаскивания только случаями, когда перетаскиваются файлы: только при перетаскивании файлов появляется data-dragging, и только при их отпускании вычисляется выражение |
.window |
Принимает объекты, перетаскиваемые в любую область страницы, а не только на этот элемент |