Ограничение размера файлов

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

Для реализации ограничения размера файлов в Svelte с использованием Carbon Components необходимо подключить компонент FileUploader. В Svelte это делается следующим образом:

<script>
  import { FileUploaderItem, FileUploaderDropContainer } from "carbon-components-svelte";
  
  let files = [];
  let maxFileSize = 5 * 1024 * 1024; // Максимальный размер файла 5 МБ
</script>

FileUploaderDropContainer отвечает за область перетаскивания и загрузки файлов, а FileUploaderItem отображает каждый загруженный файл.


Настройка ограничения размера

Carbon Components Svelte не предоставляет встроенную проверку размера файлов по умолчанию, поэтому её нужно реализовать вручную через обработку события on:change:

<FileUploaderDropContainer
  labelText="Перетащите файлы или выберите их"
  on:change="{handleFileChange}"
>
  {#each files as file (file.name)}
    <FileUploaderItem
      filename="{file.name}"
      invalid="{file.invalid}"
      invalidText="{file.invalidText}"
    />
  {/each}
</FileUploaderDropContainer>

<script>
  function handleFileChange(event) {
    const selectedFiles = Array.from(event.target.files);
    files = selectedFiles.map(file => {
      if (file.size > maxFileSize) {
        return {
          ...file,
          invalid: true,
          invalidText: `Файл превышает максимальный размер ${maxFileSize / (1024 * 1024)} МБ`
        };
      }
      return { ...file, invalid: false };
    });
  }
</script>

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


Поддержка нескольких файлов и ограничения на каждый

Для поддержки множественной загрузки с индивидуальной проверкой размера каждого файла необходимо использовать массив files и присваивать каждому объекту свойства invalid и invalidText. Это позволяет Carbon корректно отображать ошибки и визуально сигнализировать пользователю о проблеме с конкретным файлом.

<FileUploaderDropContainer
  labelText="Загрузите несколько файлов"
  multiple
  on:change="{handleFileChange}"
>
  {#each files as file (file.name)}
    <FileUploaderItem
      filename="{file.name}"
      invalid="{file.invalid}"
      invalidText="{file.invalidText}"
    />
  {/each}
</FileUploaderDropContainer>

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

Помимо размера, часто требуется ограничивать и типы файлов. Для этого добавляется проверка MIME-типа:

const allowedTypes = ["image/png", "image/jpeg", "application/pdf"];

function handleFileChange(event) {
  const selectedFiles = Array.from(event.target.files);
  files = selectedFiles.map(file => {
    if (!allowedTypes.includes(file.type)) {
      return {
        ...file,
        invalid: true,
        invalidText: "Недопустимый тип файла"
      };
    }
    if (file.size > maxFileSize) {
      return {
        ...file,
        invalid: true,
        invalidText: `Файл превышает ${maxFileSize / (1024 * 1024)} МБ`
      };
    }
    return { ...file, invalid: false };
  });
}

Это гарантирует, что пользователь не сможет загрузить запрещённые форматы, а также файлы, превышающие лимит по размеру.


Визуальная индикация ошибок

Carbon Components Svelte автоматически применяет стили для файлов с invalid: true. Для дополнительной кастомизации можно использовать CSS-классы:

.file-invalid {
  border-color: #e41e26;
  background-color: #fff1f0;
}

Применение классов к FileUploaderItem:

<FileUploaderItem
  class:file-invalid="{file.invalid}"
  filename="{file.name}"
  invalid="{file.invalid}"
  invalidText="{file.invalidText}"
/>

Асинхронная проверка перед загрузкой на сервер

Если требуется проверять размер и тип файлов на сервере перед фактической загрузкой, можно использовать промисы:

async function validateFile(file) {
  if (file.size > maxFileSize) {
    throw new Error(`Файл ${file.name} слишком большой`);
  }
  if (!allowedTypes.includes(file.type)) {
    throw new Error(`Недопустимый тип файла ${file.type}`);
  }
  return file;
}

async function handleFileChange(event) {
  const selectedFiles = Array.from(event.target.files);
  files = [];

  for (const file of selectedFiles) {
    try {
      const validFile = await validateFile(file);
      files.push({ ...validFile, invalid: false });
    } catch (error) {
      files.push({ ...file, invalid: true, invalidText: error.message });
    }
  }
}

Это позволяет интегрировать сложные проверки, например, анализ содержимого файла, перед его загрузкой на сервер.


Резюме ключевых моментов

  • FileUploaderDropContainer создаёт интерфейс для загрузки файлов.
  • Проверка размера и типа файла реализуется через обработчик on:change.
  • Множественные файлы проверяются индивидуально, с возможностью отображения ошибок для каждого.
  • Визуальная индикация ошибок интегрирована и может быть кастомизирована через CSS.
  • Асинхронная валидация позволяет выполнять дополнительные проверки перед загрузкой на сервер.

Эта архитектура обеспечивает строгий контроль над загружаемыми файлами и легко масштабируется под сложные требования интерфейса.