Skip to content

Astro

@ecss/astro-adapter генерирует типизированные компоненты Astro из объявлений @block и @element. id адаптера — 'astro'.

В отличие от React/Vue-адаптеров, Astro-адаптер module-based: он генерирует настоящие .astro-файлы в каталог .ecss/astro/, а импорт ./X.ecss перенаправляется на них ECSS-плагином автоматически. Для вас это прозрачно — компонент импортируется из .ecss-файла как обычно.

Установка

sh
npm i -D @ecss/astro-adapter
sh
pnpm add -D @ecss/astro-adapter
sh
yarn add -D @ecss/astro-adapter

Требуется установленный astro версии 4 или 5.

Подключение

Адаптер регистрируется в ecss.config.ts через defineConfig из @ecss/config — конфиг не привязан к конкретному сборщику, его читает ECSS-плагин вашего бандлера. defaultAdapter задаёт адаптер, применяемый к .ecss-файлам по умолчанию:

ts
// ecss.config.ts
import { defineConfig } from '@ecss/config';
import { astroAdapter } from '@ecss/astro-adapter';

export default defineConfig({
  adapters: [astroAdapter()],
  defaultAdapter: 'astro',
});

Использование

Каждый @block превращается в компонент Astro, который импортируется напрямую из .ecss-файла. Имя компонента формируется как {префикс}{BlockName} (по умолчанию префикс E): @block ButtonEButton. Содержимое передаётся через слот по умолчанию.

astro
---
import { EButton } from './Button.ecss';
---

<EButton as="button" params={{ variant: 'primary' }}>
  Нажми меня
</EButton>

Проп params

Параметры блока передаются единственным пропом params. Их типы берутся из сгенерированного интерфейса {Block}Params (например ButtonParams), поэтому передать несуществующее значение @enum не получится.

params обязателен, если у блока есть хотя бы один обязательный @param (без ?); если все параметры опциональны или их нет вовсе — проп можно опустить.

astro
<EButton params={{ variant: 'primary' }} /> <!-- variant обязателен -->
<ECard />                                    <!-- у Card все параметры опциональны -->

Проп as

По умолчанию компонент рендерится как <div>. Проп as принимает имя любого HTML-тега и меняет корневой элемент:

astro
<EButton as="button" type="submit" params={{ variant: 'primary' }}>Отправить</EButton>

<EButton as="a" href="/about" params={{ variant: 'ghost' }}>Ссылка</EButton>

Любые HTML-атрибуты передаются на корневой элемент как есть (типизация пропускает любой атрибут; пер-тег сужения здесь нет).

class, style и атрибуты

ECSS задаёт корневому элементу класс блока, CSS-переменные из params и data-атрибуты. То, что передаёт потребитель, объединяется с этими значениями:

  • class — потребительский класс добавляется к классу блока, не затирая его;
  • style — добавляется к CSS-переменным, сгенерированным из params;
  • остальные атрибуты (id, aria-*, data-*, href, …) прокидываются на корневой элемент и выигрывают при коллизии с data-атрибутами.

Суб-компоненты (@element)

Если @block содержит @element, они становятся вложенными компонентами через статические свойства корневого и доступны в шаблоне через точечную нотацию:

astro
<EButton params={{ withIcon: true }}>
  <EButton.Icon>
    <svg><!-- … --></svg>
  </EButton.Icon>
  <EButton.Text>Нажми меня</EButton.Text>
</EButton>

Суб-компоненты поддерживают тот же проп as (по умолчанию <div>), но не принимают params.

Опции

Единственная опция фабрики — componentNamePrefix (префикс имени компонента, по умолчанию 'E'): astroAdapter({ componentNamePrefix: 'My' })MyButton. Подробнее — в обзоре адаптеров.

Серверный рендеринг

Компоненты Astro рендерятся на сервере — по умолчанию в браузер не уходит ни байта клиентского JS. Класс блока, CSS-переменные и data-атрибуты вычисляются один раз во фронтматтере и инлайнятся прямо в HTML на этапе сборки/SSR, а стили подключаются как <style>. Идеально для статических страниц.

JS попадёт в браузер только если вы явно пометите остров директивой client:*.

См. также