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

Начните использовать BlockBuilder за несколько минут

Установка

npm install @mushket-co/block-builder

FREE и PRO версии

BlockBuilder доступен в двух версиях: FREE (бесплатная демо-версия) и PRO (платная версия с полным функционалом).

FREE версия

  • До 5 типов блоков
  • Все стандартные типы полей
  • Spacing поля с дефолтными брекпоинтами
  • Repeater поля
  • Все CRUD операции

PRO версия

  • Неограниченное количество типов блоков
  • Кастомные поля (custom type)
  • API Select поля для интеграции с внешними API
  • Кастомные брекпоинты для spacing полей
  • Все возможности FREE версии

Автоматическая фильтрация

BlockBuilder автоматически скрывает недоступные функции в FREE версии:

  • Кастомные поля (type: 'custom') не отображаются
  • API Select поля (type: 'api-select') не отображаются
  • Кастомные брекпоинты в spacing игнорируются, используются только дефолтные
  • Если типов блоков больше 5, лишние скрываются из UI

Тестовый ключ для демо и проверки

Для демо, проверки и ознакомления с возможностями на localhost доступен тестовый ключ PRO лицензии. Вы можете попробовать все функции, потыкать и посмотреть функционал:

BB-PRO-1234-5678-ABCD

Этот ключ работает только на localhost. Для production используйте ключ, полученный при покупке.

Реактивное обновление

При переходе с FREE на PRO лицензию, UI автоматически обновляется без перезагрузки страницы. Все PRO функции становятся доступными сразу после активации лицензии.

Основные концепции

BlockConfig

Конфигурация типа блока

BlockBuilder

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

onSave Callback

Колбэк для сохранения блоков (localStorage, API и т.д.)

Field Renderers

Рендереры для различных типов полей

Пример использования

import { BlockBuilder } from '@mushket-co/block-builder' const blockConfigs = [ { type: 'text', label: 'Текстовый блок', fields: [ { name: 'content', label: 'Содержимое', type: 'text', required: true } ], defaultProps: { content: 'Привет, мир!' }, spacingOptions: { // Автоматически добавит поле spacing в форму enabled: true, spacingTypes: ['padding-top', 'padding-bottom'] } } ] const blockBuilder = new BlockBuilder({ containerId: 'my-app', blockConfigs: blockConfigs, autoInit: true, onSave: async (blocks) => { // Сохранение блоков через колбэк (например, на сервер или в localStorage) localStorage.setItem('blocks', JSON.stringify(blocks)) return true } })

Структура конфигурации блока

Каждый блок в blockConfigs должен иметь следующую структуру:

Полный пример конфигурации

const blockConfigs = { // Ключ объекта - это type блока (обязательно, уникальный) text: { // Основные свойства блока type: 'text', // Тип блока (обязательно, должен совпадать с ключом) label: 'Текстовый блок', // Отображаемое название в UI (обязательно) title: 'Текстовый блок', // Альтернативное название (опционально) icon: '📝', // Иконка блока (опционально) description: 'Блок для текстового контента', // Описание блока (опционально) // Конфигурация рендеринга блока render: { kind: 'html', // 'html' для Pure JS или 'component' для Vue/React template: (props) => { // Функция шаблона (для kind: 'html') return '<div>' + props.content + '</div>' }, // ИЛИ для Vue компонента: // kind: 'component', // framework: 'vue', // component: TextBlockComponent }, // Поля формы редактирования fields: [ { field: 'content', // Имя поля (обязательно) label: 'Содержимое', // Метка поля (обязательно) type: 'textarea', // Тип поля (обязательно) placeholder: 'Введите текст...', defaultValue: '', // Значение по умолчанию rules: [ // Правила валидации { type: 'required' }, { type: 'minLength', value: 10 } ] } ], // Свойства блока по умолчанию defaultProps: { content: 'Привет, мир!', textAlign: 'left' }, // Настройки блока по умолчанию defaultSettings: { visible: true }, // Опции для автоматического добавления spacing полей spacingOptions: { enabled: true, // Включить spacing (по умолчанию true) spacingTypes: [ // Какие типы отступов доступны 'padding-top', 'padding-bottom', 'margin-top', 'margin-bottom' ], config: { min: 0, // Минимальное значение (по умолчанию 0) max: 200, // Максимальное значение (по умолчанию 200) step: 4, // Шаг изменения (по умолчанию 1) breakpoints: [ // Кастомные брекпоинты (только PRO) { name: 'desktop', label: 'Desktop', maxWidth: undefined }, { name: 'tablet', label: 'Tablet', maxWidth: 1024 }, { name: 'mobile', label: 'Mobile', maxWidth: 640 } ] } } } }

Описание свойств конфигурации

type (обязательный)

Уникальный идентификатор типа блока. Должен совпадать с ключом объекта в blockConfigs.

label (обязательный)

Отображаемое название блока в UI (например, в списке доступных типов блоков для добавления).

title (опциональный)

Альтернативное название блока. Если не указано, используется label.

icon (опциональный)

Иконка блока (эмодзи или строка). Отображается в UI рядом с названием блока.

description (опциональный)

Описание блока. Используется для подсказок пользователю о назначении блока.

render (обязательный)

Конфигурация рендеринга блока. Определяет, как будет отображаться блок.

Для Pure JS используйте kind: 'html' с функцией template:

render: { kind: 'html', template: (props) => '<div>' + props.content + '</div>' }

Для Vue используйте kind: 'component':

render: { kind: 'component', framework: 'vue', component: TextBlockComponent // Vue компонент }

fields (опциональный)

Массив полей формы для редактирования блока. Подробное описание типов полей см. в разделе "Поля форм".

defaultProps (опциональный)

Объект со значениями свойств по умолчанию для нового блока. Эти значения будут использоваться при создании блока.

defaultSettings (опциональный)

Объект с настройками блока по умолчанию (например, visible: true).

spacingOptions (опциональный)

Опции для автоматического добавления spacing полей в форму редактирования. Если enabled: true, BlockBuilder автоматически добавит поля для управления отступами блока с поддержкой адаптивности.

💡 Важно

  • Ключ объекта в blockConfigs должен совпадать со значением type
  • Свойства type и label являются обязательными
  • Свойство render обязательно для определения способа рендеринга блока
  • Все остальные свойства опциональны и используются для дополнительной настройки

Отступы блоков (Spacing)

BlockBuilder автоматически управляет отступами блоков через систему spacing. Отступы хранятся в block.props.spacingи автоматически применяются к блоку с поддержкой адаптивности.

Как это работает

  • При настройке spacingOptions в конфигурации блока, BlockBuilder автоматически добавляет поле spacing в форму редактирования
  • Значения отступов сохраняются в block.props.spacing
  • Отступы автоматически применяются к HTML элементу блока
  • Margin применяется напрямую через inline стили
  • Padding передается через CSS переменные для использования внутри блока

Структура spacing данных

// block.props.spacing { desktop: { 'padding-top': 20, 'padding-bottom': 20, 'margin-top': 10, 'margin-bottom': 10 }, tablet: { 'padding-top': 16, 'padding-bottom': 16, 'margin-top': 8, 'margin-bottom': 8 }, mobile: { 'padding-top': 12, 'padding-bottom': 12, 'margin-top': 6, 'margin-bottom': 6 } }

Автоматическое применение в Vue

BlockBuilder автоматически применяет spacing к блоку. В Vue компонентах это происходит через автоматическую генерацию inline стилей:

// BlockBuilder автоматически применяет spacing к элементу блока // Результат: <div class="block-builder-block" style=" margin-top: 10px; margin-bottom: 10px; --spacing-padding-top: 20px; --spacing-padding-bottom: 20px; " > <!-- Ваш контент блока --> <!-- Используйте CSS переменные для padding внутри блока --> <div style="padding-top: var(--spacing-padding-top); padding-bottom: var(--spacing-padding-bottom);"> {{ block.props.content }} </div> </div>

Использование в вашем компоненте

Если вы создаете свой компонент блока, используйте утилиты BlockBuilder:

// Vue 3 компонент import { getBlockInlineStyles } from '@mushket-co/block-builder/core'; export default { props: ['block'], computed: { spacingStyles() { // Получаем стили для текущего брекпоинта return getBlockInlineStyles( this.block.props.spacing, 'spacing', this.customBreakpoints // опционально, свои брекпоинты ); } }, template: '<div :style="spacingStyles"><div style="padding-top: var(--spacing-padding-top);">{{ block.props.content }}</div></div>' } // Pure JS import { applySpacingToElement } from '@mushket-co/block-builder/core'; const element = document.getElementById('my-block'); applySpacingToElement( element, block.props.spacing, 'spacing', customBreakpoints // опционально );

CSS переменные для padding

Padding передается через CSS переменные, чтобы вы могли контролировать, куда именно применить padding внутри блока:

/* Используйте CSS переменные в ваших стилях */ .block-content { padding-top: var(--spacing-padding-top, 0); padding-bottom: var(--spacing-padding-bottom, 0); } /* Или напрямую в inline стилях */ <div style="padding-top: var(--spacing-padding-top);"> Контент блока </div>

Адаптивность

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

API эндпоинты для бэкенда

Для полноценной работы BlockBuilder в продакшене вам необходимо реализовать следующие API эндпоинты на вашем бэкенде:

1. Сохранение блоков

POST/api/blocks/save

Эндпоинт для сохранения массива блоков. Принимает JSON строку с блоками и сохраняет её в вашей базе данных.

Запрос:

POST /api/blocks/save Content-Type: application/json { "blocks": [ { "id": "block-1", "type": "text", "props": { "content": "Текст блока", "spacing": { "desktop": { "padding-top": 20, "padding-bottom": 20 } } } } ] }

Успешный ответ:

HTTP/1.1 200 OK Content-Type: application/json { "success": true, "message": "Блоки успешно сохранены" }

Важно: Блоки передаются как массив объектов. Вы можете сохранять их как JSON строку в базе данных или как отдельные записи для каждого блока. Рекомендуется хранить весь массив блоков как единую JSON строку для конкретной страницы/контекста.

2. Загрузка блоков

GET/api/blocks/load

Эндпоинт для получения сохраненных блоков. Возвращает массив блоков в формате JSON.

Запрос:

GET /api/blocks/load Content-Type: application/json

Успешный ответ:

HTTP/1.1 200 OK Content-Type: application/json { "blocks": [ { "id": "block-1", "type": "text", "props": { "content": "Текст блока", "spacing": { "desktop": { "padding-top": 20, "padding-bottom": 20 } } } } ] }

Примечание: Если блоков нет, верните пустой массив []. Это позволит BlockBuilder корректно инициализироваться с пустым состоянием.

3. Загрузка изображений

POST/api/upload

Эндпоинт для загрузки статических файлов (изображений). Принимает файл через FormData и возвращает URL загруженного файла.

Запрос:

POST /api/upload Content-Type: multipart/form-data FormData: file: [изображение] (опционально) Authorization: Bearer token

Успешный ответ:

HTTP/1.1 200 OK Content-Type: application/json { "url": "https://example.com/uploads/image.jpg", "width": 1920, "height": 1080, "size": 245678 }

Важно: Ответ сервера ОБЯЗАТЕЛЬНО должен содержать поле url(или src) с URL загруженного файла. Если формат ответа отличается, используйтеresponseMapper в конфигурации поля image для преобразования ответа.

Рекомендация: Загружайте файлы на статический сервер (CDN, S3, или вашу файловую систему) и возвращайте полный URL. Это позволяет хранить в блоке только ссылку на файл, а не сами данные изображения.

Дополнительные рекомендации

  • Валидация данных: Проверяйте структуру блоков на бэкенде перед сохранением. Убедитесь, что все обязательные поля присутствуют и имеют корректный формат.
  • Обработка ошибок: Возвращайте понятные сообщения об ошибках с соответствующими HTTP статусами (400 для ошибок валидации, 500 для серверных ошибок).
  • Аутентификация: При необходимости добавьте проверку авторизации для защиты эндпоинтов. Можно использовать заголовки Authorization или токены в запросах.
  • Ограничения размера файлов: Для эндпоинта загрузки изображений установите разумные ограничения на размер файла (например, 5-10MB) и проверяйте тип файла.
  • Хранение данных: Блоки можно хранить как единую JSON строку для конкретной страницы/контекста, или как отдельные записи в базе данных. Выберите подход, который лучше подходит для вашей архитектуры.

Пример обработки ошибок

// Ошибка валидации HTTP/1.1 400 Bad Request Content-Type: application/json { "success": false, "error": "Неверный формат данных блоков", "details": "Поле 'type' обязательно для каждого блока" } // Ошибка загрузки файла HTTP/1.1 400 Bad Request Content-Type: application/json { "success": false, "error": "Файл слишком большой", "maxSize": "5242880" } // Серверная ошибка HTTP/1.1 500 Internal Server Error Content-Type: application/json { "success": false, "error": "Внутренняя ошибка сервера" }