Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

barneo-file-service

barneo-tech301MIT1.1.1TypeScript support: included

Комплексная библиотека Vue 3 для работы с файлами в приложениях Barneo. Предоставляет мощную функциональность для загрузки, управления и обработки файлов с валидацией, отслеживанием прогресса и поддержкой localStorage.

vue, vue3, file-upload, drag-drop, typescript, barneo, file-service, file-management, components, library, ui, file-handling, file-processing, composables, vue-composables

readme

Barneo File Service

Комплексная библиотека Vue 3 для работы с файлами в приложениях Barneo. Предоставляет мощную функциональность для загрузки, управления и обработки файлов с валидацией, отслеживанием прогресса и поддержкой localStorage.

Версия: 1.1.1
Дата релиза: 2 сентября 2025
Лицензия: MIT

🚀 Основные возможности

  • Загрузка файлов: Поддержка drag & drop, множественной загрузки
  • Валидация: Проверка размера, типа и количества файлов
  • Отслеживание прогресса: Детальная информация о процессе загрузки
  • Управление состоянием: Реактивное состояние файлов и ошибок
  • Хранилище: Сохранение файлов в localStorage для повторного использования
  • Обработка ошибок: Возможность повтора неудачных загрузок
  • Кастомизация: Гибкая настройка через props, slots и события

📦 Установка

npm install barneo-file-service

🔧 Быстрый старт

1. Подключение плагина

import { createApp } from "vue";
import BarneoFileService from "barneo-file-service";
import { AppName } from "barneo-file-service";
import "barneo-file-service/style";

const app = createApp(App);

app.use(BarneoFileService, {
  apiUrl: "https://api.example.com/upload",
  appName: AppName.PIM,
  maxFiles: 10,
  maxFileSize: 50 * 1024 * 1024, // 50MB
  allowedTypes: ["image/jpeg", "image/png", "application/pdf"],
  onUploadSuccess: (results) => console.log("Файлы загружены:", results),
});

app.mount("#app");

2. Базовое использование компонента

<template>
  <FileUploader
    title="Загрузить документы"
    @upload-success="handleUploadSuccess"
    @upload-error="handleUploadError"
  />
</template>

<script setup>
const handleUploadSuccess = (files) => {
  console.log("Загружено файлов:", files.length);
};

const handleUploadError = (error) => {
  console.error("Ошибка загрузки:", error);
};
</script>

🎯 Сценарии использования

1. Загрузка документов с валидацией

<template>
  <FileUploader
    title="Загрузить документы"
    :max-files="5"
    :max-file-size="10 * 1024 * 1024"
    :allowed-types="['application/pdf', 'application/msword']"
    @upload-success="handleDocumentsUpload"
  />
</template>

<script setup>
const handleDocumentsUpload = (files) => {
  // Обработка загруженных документов
  files.forEach((file) => {
    console.log(`Документ загружен: ${file.originalName}`);
  });
};
</script>

2. Загрузка изображений с предпросмотром

<template>
  <FileUploader
    button-type="input"
    title="Загрузить изображения"
    :allowed-types="['image/jpeg', 'image/png', 'image/webp']"
    :multiple="true"
    @upload-success="handleImagesUpload"
  />
</template>

<script setup>
const handleImagesUpload = (files) => {
  // Создание предпросмотра изображений
  files.forEach((file) => {
    const img = new Image();
    img.src = file.url;
    // Добавление в галерею
  });
};
</script>

3. Использование с кастомным UI

<template>
  <FileUploader
    button-type="default"
    button-text="Выбрать файлы"
    button-variant="primary"
    @upload-success="handleUpload"
  >
    <template #button="{ openModal, buttonText }">
      <button @click="openModal" class="custom-button">
        {{ buttonText }}
      </button>
    </template>

    <template #modal-header="{ title, closeModal }">
      <div class="custom-header">
        <h2>{{ title }}</h2>
        <button @click="closeModal"></button>
      </div>
    </template>
  </FileUploader>
</template>

4. Работа с сохраненными файлами

<template>
  <FileUploader title="Управление файлами" @upload-success="handleUpload" />
</template>

<script setup>
import { useFileService } from "barneo-file-service";

const fileService = useFileService();

const handleUpload = (files) => {
  // Файлы автоматически сохраняются в localStorage
  console.log("Файлы сохранены в хранилище");

  // Получение сохраненных файлов
  const storedFiles = fileService.storedFiles.value;
  console.log("Сохраненные файлы:", storedFiles);
};
</script>

5. Управление загруженными файлами через props

<template>
  <FileUploader
    button-type="input"
    :uploaded-files="myUploadedFiles"
    @files-cleared="handleFilesCleared"
    @upload-success="handleUploadSuccess"
  />
</template>

<script setup>
import { ref } from "vue";

const myUploadedFiles = ref([
  {
    id: 1,
    originalName: "document.pdf",
    name: "document.pdf",
    size: 1024000,
    type: "application/pdf",
    url: "https://example.com/document.pdf",
  },
]);

const handleFilesCleared = () => {
  // Файлы были очищены пользователем
  console.log("Файлы очищены");
  // Здесь можно обновить состояние в родительском компоненте
  myUploadedFiles.value = [];
};

const handleUploadSuccess = (files) => {
  // Добавляем новые загруженные файлы к существующим
  myUploadedFiles.value.push(...files);
};
</script>

6. Вызов методов компонента из родительского компонента

<template>
  <div>
    <button @click="clearFiles">Очистить файлы</button>
    <button @click="openModal">Открыть модальное окно</button>
    <button @click="closeModal">Закрыть модальное окно</button>

    <FileUploader
      ref="fileUploaderRef"
      button-type="input"
      :uploaded-files="myUploadedFiles"
      @files-cleared="handleFilesCleared"
    />
  </div>
</template>

<script setup>
import { ref } from "vue";

const fileUploaderRef = ref();
const myUploadedFiles = ref([
  {
    id: 1,
    originalName: "document.pdf",
    name: "document.pdf",
    size: 1024000,
    type: "application/pdf",
    url: "https://example.com/document.pdf",
  },
]);

const clearFiles = () => {
  // Вызываем метод clearUploadedFiles из дочернего компонента
  fileUploaderRef.value?.clearUploadedFiles();
};

const openModal = () => {
  // Открываем модальное окно программно
  fileUploaderRef.value?.openModal();
};

const closeModal = () => {
  // Закрываем модальное окно программно
  fileUploaderRef.value?.closeModal();
};

const handleFilesCleared = () => {
  console.log("Файлы очищены");
  myUploadedFiles.value = [];
};
</script>

📋 API Reference

FileUploader Component

Props

Prop Type Default Description
title string 'Загрузка файлов' Заголовок модального окна
buttonText string 'Загрузить файлы' Текст кнопки
buttonSize 'small' | 'medium' | 'large' 'medium' Размер кнопки
buttonVariant 'primary' | 'secondary' | 'outline' | 'ghost' 'primary' Стиль кнопки
buttonType 'default' | 'input' 'default' Тип отображения кнопки
buttonIcon string undefined CSS класс иконки
autoCloseOnSuccess boolean true Автоматически закрывать модальное окно после успешной загрузки
showCancelButton boolean true Показывать ли кнопку отмены
cancelButtonText string 'Отмена' Текст кнопки отмены
modalMaxWidth string '600px' Максимальная ширина модального окна
modalPosition 'center' | 'top' | 'bottom' 'center' Позиция модального окна
closeOnOverlayClick boolean true Закрывать ли модальное окно при клике вне его
showAnimations boolean true Показывать ли анимации
uploadedFiles FileUploadResponse[] undefined Список загруженных файлов для отображения

Events

Event Payload Description
upload-success FileUploadResponse[] Файлы успешно загружены
upload-complete [FileUploadResponse[], string[]] Загрузка завершена (успешно или с ошибками)
upload-error Error Ошибка загрузки
files-selected File[] Файлы выбраны (но еще не загружены)
modal-open void Модальное окно открыто
modal-close void Модальное окно закрыто
files-cleared void Загруженные файлы очищены

Exposed Methods

Методы, которые можно вызывать из родительского компонента через ref:

Method Parameters Return Type Description
clearUploadedFiles - void Очищает загруженные файлы
openModal - void Открывает модальное окно
closeModal - void Закрывает модальное окно
uploadSelectedFiles - Promise Загружает выбранные файлы
clearFiles - void Очищает выбранные файлы
clearErrors - void Очищает ошибки валидации
clearCompletedUploads - void Очищает завершенные загрузки
retryFailedUploads - void Повторяет неудачные загрузки

Slots

button - Слот для кнопки (по умолчанию)
<template
  #button="{ openModal, buttonText, buttonSize, buttonVariant, buttonIcon }"
>
  <button @click="openModal" class="custom-button">
    {{ buttonText }}
  </button>
</template>
button-input - Слот для input типа кнопки
<template
  #button-input="{
    openModal,
    title,
    uploadedFiles,
    clearUploadedFiles,
    formatFileSize,
    allowedTypes,
  }"
>
  <div class="custom-input">
    <span>{{ title }}</span>
    <button @click="openModal">Выбрать</button>
    <button @click="clearUploadedFiles">Очистить</button>
  </div>
</template>
<template #modal-header="{ title, closeModal }">
  <div class="custom-header">
    <h2>{{ title }}</h2>
    <button @click="closeModal">Закрыть</button>
  </div>
</template>
file-drop-zone - Слот для области выбора файлов
<template
  #file-drop-zone="{
    selectFiles,
    isDragOver,
    selectedFiles,
    errors,
    triggerFileInput,
    formatFileSize,
    config,
  }"
>
  <div
    @drop="selectFiles"
    @dragover.prevent
    :class="{ 'drag-over': isDragOver }"
  >
    <p>Перетащите файлы сюда</p>
    <button @click="triggerFileInput">Выбрать файлы</button>
  </div>
</template>
file-list - Слот для списка выбранных файлов
<template
  #file-list="{
    selectedFiles,
    removeFile,
    clearFiles,
    isFileUploading,
    formatFileSize,
    isUploading,
  }"
>
  <div class="file-list">
    <div v-for="(file, index) in selectedFiles" :key="index">
      <span>{{ file.name }}</span>
      <span>{{ formatFileSize(file.size) }}</span>
      <button @click="removeFile(index)" :disabled="isFileUploading(file)">
        Удалить
      </button>
    </div>
  </div>
</template>
stored-files - Слот для списка сохраненных файлов
<template
  #stored-files="{
    storedFiles,
    selectedStoredFiles,
    toggleStoredFileSelection,
    isStoredFileSelected,
    removeStoredFile,
    formatFileSize,
    formatDate,
    hasStoredFiles,
  }"
>
  <div v-if="hasStoredFiles" class="stored-files">
    <div v-for="file in storedFiles" :key="file.id">
      <input
        type="checkbox"
        :checked="isStoredFileSelected(file.id)"
        @change="toggleStoredFileSelection(file.id)"
      />
      <span>{{ file.originalName }}</span>
      <span>{{ formatFileSize(file.size) }}</span>
      <span>{{ formatDate(file.uploadedAt) }}</span>
      <button @click="removeStoredFile(file.id)">Удалить</button>
    </div>
  </div>
</template>
action-buttons - Слот для кнопок действий
<template
  #action-buttons="{
    uploadFiles,
    selectStoredFiles,
    clearFiles,
    retryFailedUploads,
    isUploading,
    hasSelectedFiles,
    hasErrors,
    activeMode,
    hasSelectedStoredFiles,
    closeModal,
    showCancelButton,
    cancelButtonText,
  }"
>
  <div class="action-buttons">
    <button v-if="showCancelButton" @click="closeModal">
      {{ cancelButtonText }}
    </button>
    <button
      v-if="activeMode === 'upload'"
      @click="uploadFiles"
      :disabled="!hasSelectedFiles || isUploading"
    >
      {{ isUploading ? "Загрузка..." : "Загрузить" }}
    </button>
    <button
      v-else-if="activeMode === 'select'"
      @click="selectStoredFiles"
      :disabled="!hasSelectedStoredFiles"
    >
      Выбрать
    </button>
  </div>
</template>

Composables

useFileService()

Основной composable для работы с файлами.

import { useFileService } from "barneo-file-service";

const fileService = useFileService();

// Состояние
const selectedFiles = fileService.selectedFiles;
const errors = fileService.errors;
const isUploading = fileService.isUploading;
const totalProgress = fileService.totalProgress;

// Методы
const results = await fileService.uploadSelectedFiles();
fileService.selectFiles(files);
fileService.clearFiles();
fileService.clearErrors();

useFileInput(options)

Composable для управления выбором файлов.

import { useFileInput } from "barneo-file-service";

const {
  selectedFiles,
  errors,
  selectFiles,
  removeFile,
  clearFiles,
  isFileSelected,
  totalSize,
} = useFileInput({
  maxFiles: 5,
  maxFileSize: 10 * 1024 * 1024, // 10MB
  allowedTypes: ["image/jpeg", "image/png"],
  multiple: true,
});

useFileUploader(options)

Composable для управления загрузкой файлов.

import { useFileUploader } from "barneo-file-service";

const {
  uploads,
  isUploading,
  totalProgress,
  uploadFile,
  uploadFiles,
  retryUpload,
  clearUploads,
} = useFileUploader({
  apiUrl: "https://api.example.com/upload",
  appName: AppName.PIM,
  onProgress: (progress) => console.log(`Progress: ${progress}%`),
  onError: (error) => console.error("Upload failed:", error),
});

useFileStorage()

Composable для управления хранилищем файлов.

import { useFileStorage } from "barneo-file-service";

const {
  storedFiles,
  selectedStoredFiles,
  addStoredFile,
  removeStoredFile,
  clearStoredFiles,
  addSelectedStoredFile,
  clearSelectedStoredFiles,
} = useFileStorage();

Сервисы

FileUploadService

Сервис для загрузки файлов на сервер.

import { FileUploadService } from "barneo-file-service";

const service = new FileUploadService({
  apiUrl: "https://api.example.com/upload",
  appName: AppName.PIM,
  headers: { Authorization: "Bearer token" },
  timeout: 30000,
});

// Загрузка одного файла
const result = await service.uploadFile(file, {
  appName: AppName.PIM,
  onProgress: (progress) => console.log(`Progress: ${progress}%`),
  onError: (error) => console.error("Upload failed:", error),
});

// Загрузка нескольких файлов
const results = await service.uploadFiles([file1, file2], {
  appName: AppName.PIM,
});

🎨 Кастомизация

CSS переменные

Библиотека использует CSS переменные для кастомизации стилей:

:root {
  --primary-color: #0091ea;
  --primary-hover: #0077cc;
  --gray-50: #fafafa;
  --gray-100: #f9fafb;
  --gray-200: #f3f4f6;
  --gray-300: #e5e7eb;
  --gray-400: #d1d5db;
  --gray-500: #9ca3af;
  --gray-600: #6b7280;
  --gray-700: #374151;
  --gray-900: #111827;
  --error-color: #ef4444;
  --success-color: #10b981;
  --border-radius-sm: 6px;
  --border-radius-md: 8px;
  --border-radius-lg: 10px;
  --border-radius-xl: 12px;
  --transition: all 0.15s ease;
  --shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
  --shadow-lg: 0 25px 50px -12px rgba(0, 0, 0, 0.15);
}

Кастомные стили

<template>
  <FileUploader class="custom-uploader" />
</template>

<style>
.custom-uploader {
  --primary-color: #ff6b6b;
  --border-radius-md: 12px;
}

.custom-uploader .file-uploader__button {
  background: linear-gradient(45deg, #ff6b6b, #ee5a24);
  border: none;
  color: white;
  font-weight: bold;
}
</style>

🔧 Разработка

# Установка зависимостей
npm install

# Разработка
npm run dev

# Сборка
npm run build

# Проверка типов
npm run type-check

# Линтинг
npm run lint

📄 Лицензия

MIT

changelog

Changelog

Все значимые изменения в проекте будут задокументированы в этом файле.

Формат основан на Keep a Changelog, и проект следует Semantic Versioning.

[1.1.1] - 2025-09-02

Исправлено

  • 🔧 Добавлено значение по умолчанию для пропса uploadedFiles в withDefaults
  • 🔧 Добавлено значение по умолчанию для пропса buttonIcon в withDefaults
  • ✅ Подтверждена корректная работа всех пропсов компонента

[1.1.0] - 2025-09-02

Добавлено

  • 🔧 Props для передачи загруженных файлов (uploadedFiles)
  • 🎛️ Экспортируемые методы для программного управления компонентом
  • 📤 Новое событие files-cleared для отслеживания очистки файлов
  • 🎯 Возможность вызова методов компонента из родительского компонента через ref
  • 📝 Обновленная документация с примерами использования новых возможностей

Изменено

  • Улучшена типизация компонента с поддержкой экспортируемых методов
  • Обновлены глобальные типы Vue для лучшей поддержки IntelliSense

[1.0.0] - 2025-09-01

Добавлено

  • 🎉 Первый релиз библиотеки Barneo File Service
  • ✨ Основной компонент FileUploader с поддержкой drag & drop
  • 🔧 Composable useFileService для управления файловым сервисом
  • 📁 Composable useFileInput для управления выбором файлов
  • 🚀 Composable useFileUploader для управления загрузкой файлов
  • 💾 Composable useFileStorage для работы с localStorage
  • 🌐 Сервис FileUploadService для загрузки файлов на сервер
  • ⚙️ Менеджер конфигурации FileServiceConfigManager (Singleton)
  • 🎨 Два типа отображения: default (кнопка) и input (поле ввода)
  • 🔒 Валидация файлов по размеру, типу и количеству
  • 📊 Отслеживание прогресса загрузки для каждого файла
  • 🗂️ Поддержка множественной загрузки файлов
  • 💿 Автоматическое сохранение файлов в localStorage
  • 🔄 Возможность повтора неудачных загрузок
  • 🎭 Гибкая кастомизация через slots и props
  • 🌈 CSS переменные для легкой настройки стилей
  • 📱 Адаптивный дизайн с поддержкой мобильных устройств
  • 🎯 Поддержка приложений Barneo: PIM, CRM, Chat, Tasks и др.

Технические особенности

  • 🏗️ Построен на Vue 3 Composition API
  • 📝 Полная поддержка TypeScript с детальными типами
  • 🎨 CSS-in-JS с поддержкой CSS переменных
  • 🔌 Vue плагин для глобальной регистрации
  • 📦 Vite для сборки и разработки
  • 🧪 Готов к использованию в production

Поддерживаемые форматы файлов

  • 📄 Документы: .doc, .docx, .pdf
  • 🖼️ Изображения: .jpg, .jpeg, .png
  • 🔧 Расширяемая система типов через конфигурацию

События компонента

  • upload-success - файлы успешно загружены
  • upload-complete - загрузка завершена
  • upload-error - ошибка загрузки
  • files-selected - файлы выбраны
  • modal-open - модальное окно открыто
  • modal-close - модальное окно закрыто

Slots для кастомизации

  • button - кастомная кнопка
  • button-input - кастомное поле ввода
  • modal-header - заголовок модального окна
  • file-drop-zone - область выбора файлов
  • file-list - список выбранных файлов
  • stored-files - список сохраненных файлов
  • action-buttons - кнопки действий
  • modal-footer - футер модального окна
  • mode-switcher - переключатель режимов
  • errors - отображение ошибок
  • upload-results - результаты загрузки

Конфигурация

  • 🌐 URL API для загрузки
  • 🏷️ Название приложения
  • 📏 Максимальный размер файла
  • 🔢 Максимальное количество файлов
  • 📋 Разрешенные типы файлов
  • 🔐 HTTP заголовки
  • ⏱️ Таймаут запросов
  • 💾 Лимит файлов в хранилище
  • 🔄 Callbacks для событий

[Unreleased]

Планируется

  • 🔍 Предпросмотр изображений
  • 🎨 Темная тема

Формат версионирования

  • MAJOR - несовместимые изменения API
  • MINOR - новая функциональность (обратно совместимо)
  • PATCH - исправления ошибок (обратно совместимо)

Ссылки