Skip to content

Модульная система

ECSS поддерживает разбивку стилей на несколько файлов. Один файл может импортировать перечисления и блоки из другого: перечисления — как типы для @param, блоки — для наследования (extends) и контекстных стилей (@external).

@import

Директива @import импортирует именованные объявления из другого .ecss-файла.

ecss
@import { Name1, Name2 } from "./path/to/file.ecss";

Что можно импортировать:

  • @enum — для использования как тип в @param
  • @block — для наследования через extends
  • @const — для использования значений из другого файла

Пример: общие перечисления

ecss
// tokens.ecss
@enum Size {
  values: "sm", "md", "lg";
}

@enum Variant {
  values: "primary", "danger", "ghost";
}
ecss
// Button.ecss
@import { Size, Variant } from "./tokens.ecss";

@block Button {
  @param --variant Variant;
  @param --size Size;

  @if (--size == "sm") {
    padding: 4px 8px;
  }

  @if (--size == "md") {
    padding: 8px 16px;
  }

  @if (--size == "lg") {
    padding: 14px 28px;
  }
}

Наследование

@block может наследовать стили другого блока через ключевое слово extends. Родительский блок должен быть из того же файла или импортирован через @import.

ecss
@block Child extends Parent {
  /* дополнительные стили */
}

Потомок получает все параметры родителя и может добавлять собственные.

Пример

ecss
// Shadow.ecss
@enum ShadowLevel {
  values: "sm", "md", "lg";
}

@block Shadow {
  @param --shadow ShadowLevel;

  @if (--shadow == "sm") {
    box-shadow: 0 1px 3px rgb(0 0 0 / 0.12);
  }

  @if (--shadow == "md") {
    box-shadow: 0 4px 12px rgb(0 0 0 / 0.15);
  }

  @if (--shadow == "lg") {
    box-shadow: 0 8px 24px rgb(0 0 0 / 0.2);
  }
}
ecss
// Button.ecss
@import { Shadow } from "./Shadow.ecss";

@enum Variant {
  values: "primary", "ghost";
}

@block Button extends Shadow {
  @param --variant Variant;

  display: inline-flex;
  padding: 8px 16px;
  border-radius: 6px;

  @if (--variant == "primary") {
    background: #646cff;
    color: #fff;
  }
}
tsx
import { EButton } from './Button.ecss';

<EButton as="button" params={{ variant: 'primary', shadow: 'md' }}>
  Кнопка
</EButton>;

EButton принимает параметры и Button, и Shadow — TypeScript знает все допустимые значения.

@external

@external позволяет дополнить стили другого блока в контексте текущего. Объявляется внутри @block. Блок, на который ссылается @external, должен быть предварительно импортирован:

ecss
@import { Button } from "./Button.ecss";

@block Toolbar {
  @param --dense? boolean;

  @external Button {
    border-radius: 4px;

    @if (--dense) {
      padding: 4px 8px;
    }
  }

  @external Button.Text {
    font-size: 13px;
  }
}

Запись Button.Text обращается к вложенному элементу Text блока Button — такие элементы объявляются через @element.

Внутри @external доступны параметры текущего блока (Toolbar), но не внешнего (Button).

Что дальше?