@ecss/dom-adapter
v0.2.0
Published
ECSS DOM adapter — vanilla JS/TS components wrapping ECSS blocks via the native DOM API.
Maintainers
Readme
import { EButton } from './Button.ecss';
const button = new EButton({
as: 'button',
params: { variant: 'primary' },
content: 'Нажми меня',
});
button
.events({ onclick: () => console.log('clicked') })
.appendTo(document.body);📦 Установка
npm i -D @ecss/dom-adapterpnpm add -D @ecss/dom-adapteryarn add -D @ecss/dom-adapterАдаптер не требует фреймворка и работает с чистым DOM в браузере.
🚀 Подключение
Адаптер регистрируется в ecss.config.ts через defineConfig из @ecss/config — конфиг не привязан к конкретному сборщику, его читает ECSS-плагин вашего бандлера (@ecss/vite-plugin и др.). defaultAdapter указывает, какой адаптер применяется к .ecss-файлам по умолчанию; id DOM-адаптера — 'dom':
// ecss.config.ts
import { defineConfig } from '@ecss/config';
import { domAdapter } from '@ecss/dom-adapter';
export default defineConfig({
adapters: [domAdapter()],
defaultAdapter: 'dom',
});🛠 Использование
Каждый @block превращается в класс, который импортируется напрямую из .ecss-файла. Экземпляр создаётся через new, а методы возвращают this — их можно объединять в цепочку:
import { EButton } from './Button.ecss';
const button = new EButton({
as: 'button',
params: { variant: 'primary' },
content: 'Нажми меня',
});
button.appendTo(document.body);Имя класса — это префикс + имя блока: @block Button → EButton, @block Card → ECard. Опции конструктора: as (тег), params (параметры блока) и content (содержимое).
Параметры (params)
Типы параметров берутся из сгенерированного интерфейса {Block}Params (например ButtonParams), поэтому передать несуществующее значение enum не получится. Если у блока есть хотя бы один обязательный @param (без ?), params обязателен; иначе его можно опустить.
Параметры можно менять после создания — каждое изменение перерисовывает class, CSS-переменные и data-атрибуты элемента:
button.setParams({ variant: 'danger' }); // заменить целиком
button.setParams((prev) => ({ ...prev, size: 'lg' })); // функциональный апдейтер
button.params.variant = 'ghost'; // живой прокси → ре-рендерСодержимое (content)
setContent заменяет всё содержимое, append / prepend добавляют в конец / начало. Принимаются строки, числа, DOM-узлы, другие Ecss-элементы, массивы этих значений и null:
button.setContent('Сохранить'); // заменить
button.append(icon, ' готово'); // добавить (icon — другой Ecss-элемент)
button.setContent(null); // очиститьСобытия (events)
events массово назначает on*-обработчики (присваивает свойство элемента, а не addEventListener — повторный вызов заменяет обработчик). Внутри обработчика this — это сам экземпляр компонента, а не DOM-узел:
button.events({
onclick() {
this.setParams({ variant: 'danger' }); // this — экземпляр EButton
},
});Набор доступных обработчиков типизирован по тегу из as (as: 'button' → события HTMLButtonElement). null сбрасывает ранее назначенный обработчик.
Тег (as)
Опция as задаёт HTML-тег корневого элемента (по умолчанию 'div'). От неё зависит точная типизация геттера element и доступных в events обработчиков. Сам DOM-узел всегда доступен через element:
const button = new EButton({ as: 'button', params: { variant: 'primary' } });
button.element.disabled = true; // element типизирован как HTMLButtonElement🧩 Суб-элементы (@element)
Если в @block объявлены @element, они доступны как статические свойства класса. Это самостоятельные классы (без params), которые вставляются в родителя обычными методами:
import { EButton } from './Button.ecss';
const button = new EButton({ as: 'button', params: { withIcon: true } });
const icon = new EButton.Icon({ as: 'span', content: '★' });
button.append(icon).appendTo(document.body);📋 Методы
Все методы, кроме геттеров element и params, возвращают this (поддерживают цепочки):
| Метод | Описание |
| ----------------------------------- | -------------------------------------------------------------- |
| appendTo(parent) / prependTo() | вставить элемент в parent (DOM-узел или другой Ecss-элемент) |
| append(...children) / prepend() | добавить детей в конец / начало |
| setContent(value) | заменить всё содержимое (null — очистить) |
| setParams(obj \| updater) | обновить параметры и перерисовать (только у @block) |
| events(handlers) | назначить on*-обработчики |
| remove() | удалить элемент из DOM |
| element | геттер — нативный DOM-узел, типизированный по as |
| params | живой прокси параметров (btn.params.x = v перерисовывает) |
⚙️ Опции
domAdapter({
componentNamePrefix: 'E', // по умолчанию 'E'
});| Опция | Тип | По умолчанию | Описание |
| --------------------- | -------- | ------------ | -------------------------------------------------------------------------- |
| componentNamePrefix | string | 'E' | Префикс имени класса. Первый символ — [A-Z], остальные — [a-zA-Z0-9_]. |
domAdapter({ componentNamePrefix: 'My' }); // → MyButton, MyCardНекорректный префикс (не подходящий под /^[A-Z][a-zA-Z0-9_]*$/) приводит к ошибке на этапе сборки.
👨💻 Автор
Разработка и поддержка: Руслан Мартынов
Если нашёл баг или есть предложение — открывай issue или отправляй pull request.
📄 Лицензия
Распространяется под лицензией MIT.
