Множественная загрузка

Множественная загрузка файлов в интерфейсах является распространённой задачей, особенно при работе с формами, системами управления контентом или приложениями для обмена файлами. Carbon Components Svelte предоставляет удобный компонент FileUploader с поддержкой множественной загрузки, что позволяет гибко управлять процессом добавления файлов.


Настройка компонента FileUploader

Для включения множественной загрузки необходимо использовать свойство multiple. Пример базовой конфигурации:

<script>
  import { FileUploaderItem, FileUploader } from 'carbon-components-svelte';
  let files = [];
</script>

<FileUploader
  bind:files
  multiple
  labelText="Выберите файлы для загрузки"
  buttonLabel="Обзор..."
/>

Ключевые моменты:

  • bind:files — двусторонняя привязка массива файлов, выбранных пользователем.
  • multiple — активирует возможность выбора нескольких файлов.
  • labelText и buttonLabel — текстовые подписи для интерфейса.

При выборе нескольких файлов они автоматически добавляются в массив files, где каждый элемент представляет объект типа File.


Отображение загруженных файлов

Для визуализации списка выбранных файлов используется компонент FileUploaderItem:

{#each files as file, index (file.name)}
  <FileUploaderItem
    name={file.name}
    size={file.size}
    status="edit"
    on:delete={() => files.splice(index, 1)}
  />
{/each}

Особенности использования:

  • Атрибут status может принимать значения "edit", "uploading", "complete", "error", что позволяет отображать текущий этап загрузки.
  • Событие delete удаляет файл из массива files при нажатии на кнопку удаления.
  • Привязка key через (file.name) обеспечивает корректное обновление списка при динамическом изменении массива.

Загрузка файлов на сервер

Множественные файлы можно отправлять через fetch или любую библиотеку для работы с HTTP-запросами, например axios. Пример с fetch:

<script>
  async function uploadFiles() {
    const formData = new FormData();
    files.forEach(file => formData.append('files[]', file));

    const response = await fetch('/upload', {
      method: 'POST',
      body: formData
    });

    if (response.ok) {
      files = []; // очищаем список после успешной загрузки
      console.log('Файлы успешно загружены');
    } else {
      console.error('Ошибка при загрузке файлов');
    }
  }
</script>

<button on:click={uploadFiles}>Загрузить все файлы</button>

Важно:

  • FormData позволяет отправлять несколько файлов на сервер под одним ключом files[].
  • После успешной загрузки массив files можно очищать для сброса состояния компонента.

Валидация и ограничения

Carbon Components Svelte поддерживает ограничение по типу и размеру файлов через свойства:

  • accept — список MIME-типа или расширений файлов.
  • sizeLimit — максимальный размер одного файла в байтах.

Пример ограничения типов и размера:

<FileUploader
  bind:files
  multiple
  labelText="Загрузите изображения"
  buttonLabel="Выберите файлы"
  accept="image/png, image/jpeg"
  sizeLimit={5 * 1024 * 1024} 
/>

Здесь можно загружать только PNG и JPEG файлы размером до 5 МБ. Файлы, не соответствующие условиям, автоматически помечаются как error.


Отслеживание статуса загрузки по файлам

Для реализации пошаговой загрузки каждого файла можно использовать динамический status:

<script>
  async function uploadFile(file, index) {
    files[index].status = 'uploading';
    const formData = new FormData();
    formData.append('file', file);

    try {
      const response = await fetch('/upload', {
        method: 'POST',
        body: formData
      });
      files[index].status = response.ok ? 'complete' : 'error';
    } catch (e) {
      files[index].status = 'error';
    }
  }

  function uploadAll() {
    files.forEach((file, index) => uploadFile(file, index));
  }
</script>

<button on:click={uploadAll}>Загрузить все файлы</button>

Особенности подхода:

  • Каждому файлу присваивается собственный статус, что упрощает отображение прогресса.
  • В случае ошибки пользователь видит, какие файлы не удалось загрузить.

Настройка кастомного интерфейса

Компонент FileUploader допускает гибкую кастомизацию через слоты:

<FileUploader bind:files multiple>
  <div slot="file-item" let:file let:index>
    <span>{file.name} ({(file.size / 1024).toFixed(2)} KB)</span>
    <button on:click={() => files.splice(index, 1)}>Удалить</button>
  </div>
</FileUploader>
  • Слот file-item позволяет полностью контролировать отображение каждого файла.
  • Доступны переменные file и index для генерации динамического контента.

Поддержка drag-and-drop

Для улучшения UX можно включить поддержку перетаскивания файлов:

<FileUploader
  bind:files
  multiple
  labelText="Перетащите файлы сюда или выберите через кнопку"
  dropLabelText="Отпустите файлы для загрузки"
/>
  • dropLabelText меняет подсказку при наведении файлов на зону загрузки.
  • Механизм drag-and-drop полностью совместим с множественной загрузкой.

Примеры интеграции с Svelte Stores

Для крупных приложений удобно хранить файлы в store:

<script>
  import { writable } from 'svelte/store';
  import { FileUploader } from 'carbon-components-svelte';

  export const uploadedFiles = writable([]);
</script>

<FileUploader bind:files={$uploadedFiles} multiple />
  • Привязка к store позволяет управлять файлами глобально.
  • Обновления списка автоматически отражаются во всех компонентах, использующих $uploadedFiles.

Множественная загрузка в Carbon Components Svelte обеспечивает полный контроль над процессом добавления, отображения и отправки файлов, позволяя создавать сложные и интерактивные интерфейсы с минимальными усилиями. Она сочетает визуальную аккуратность, гибкость кастомизации и встроенные механизмы валидации, что делает её удобным инструментом для современных веб-приложений.