@mart-dev-test-1/react-adapter
v0.2.2
Published
ECSS React adapter — generates React components from ECSS blocks.
Maintainers
Readme
import { EButton } from './Button.ecss';
<EButton as="button" params={{ variant: 'primary' }} onClick={onClick}>
Нажми меня
</EButton>;📦 Установка
npm i -D @mart-dev-test-1/react-adapterpnpm add -D @mart-dev-test-1/react-adapteryarn add -D @mart-dev-test-1/react-adapter🚀 Подключение
Адаптер регистрируется в ecss.config.ts через defineConfig из @mart-dev-test-1/config — конфиг не привязан к конкретному сборщику, его читает ECSS-плагин вашего бандлера (@mart-dev-test-1/vite-plugin и др.). defaultAdapter указывает, какой адаптер применяется к .ecss-файлам по умолчанию; id React-адаптера — 'react':
// ecss.config.ts
import { defineConfig } from '@mart-dev-test-1/config';
import { reactAdapter } from '@mart-dev-test-1/react-adapter';
export default defineConfig({
adapters: [reactAdapter()],
defaultAdapter: 'react',
});🛠 Использование
Компоненты импортируются напрямую из .ecss-файла — по одному на каждый @block:
import { EButton } from './Button.ecss';
function App() {
return (
<EButton as="button" params={{ variant: 'primary' }}>
Нажми меня
</EButton>
);
}Имя компонента — это префикс + имя блока: @block Button → EButton, @block Card → ECard.
Проп params
Параметры блока передаются единственным пропом params. TypeScript знает их типы из сгенерированного интерфейса {Block}Params (например ButtonParams), поэтому передать несуществующее значение enum не получится.
params обязателен ровно тогда, когда у блока есть хотя бы один обязательный @param (без ?). Если все параметры опциональны или их нет вовсе — проп можно не передавать. Это зеркалит проверку, которую делает рантайм-валидатор.
// у Button есть обязательный @param variant → params обязателен
<EButton params={{ variant: 'primary' }} />
// у Card все параметры опциональны → params можно опустить
<ECard />Проп as
По умолчанию компонент рендерится как <div>. Проп as принимает любой HTML-тег и меняет корневой элемент. Компонент типизирован generic-параметром по выбранному тегу, поэтому набор допустимых HTML-атрибутов сужается автоматически:
<EButton as="button" type="submit" params={{ variant: 'primary' }}>
Отправить
</EButton>
<EButton as="a" href="/about" params={{ variant: 'ghost' }}>
О нас
</EButton>При as="a" становятся доступны href, target и прочие атрибуты <a>; при as="button" — type, disabled и т.д.
className, style, ref и остальные пропы
className— конкатенируется с классом блока, не затирает его.style— мёрджится поверх CSS-переменных, сгенерированных изparams.ref— пробрасывается на корневой DOM-элемент.- Все прочие пропы (
onClick,aria-*,data-*, …) пробрасываются на корневой элемент как есть.
🧩 Суб-компоненты (@element)
Если в @block объявлены @element, они становятся вложенными компонентами через статические свойства корневого компонента:
import { EButton } from './Button.ecss';
<EButton params={{ withIcon: true }}>
<EButton.Icon>
<svg>{/* … */}</svg>
</EButton.Icon>
<EButton.Text>Нажми меня</EButton.Text>
</EButton>;Суб-компоненты поддерживают тот же проп as (по умолчанию <div>), но не принимают params.
⚙️ Опции
reactAdapter({
componentNamePrefix: 'E', // по умолчанию 'E'
});| Опция | Тип | По умолчанию | Описание |
| --------------------- | -------- | ------------ | ------------------------------------------------------------------------------ |
| componentNamePrefix | string | 'E' | Префикс имени компонента. Первый символ — [A-Z], остальные — [a-zA-Z0-9_]. |
reactAdapter({ componentNamePrefix: 'My' }); // → MyButton, MyCardНекорректный префикс (не подходящий под /^[A-Z][a-zA-Z0-9_]*$/) приводит к ошибке на этапе сборки.
⚛️ Поддержка версий React
Адаптер определяет мажорную версию React, установленного в проекте, и подстраивает генерируемый код:
- React 19+ —
refпробрасывается как обычный проп. - React 18 — компонент оборачивается в
forwardRef.
Версия читается из react/package.json относительно корня проекта и кешируется. Если React не удаётся разрешить, адаптер выводит предупреждение и использует React 19 как значение по умолчанию.
👨💻 Автор
Разработка и поддержка: Руслан Мартынов
Если нашёл баг или есть предложение — открывай issue или отправляй pull request.
📄 Лицензия
Распространяется под лицензией MIT.
