Skip to content

Шаблон Подтверждено командой

Семантика

✅ Используй семантические теги

html
<header>
  <h1>Welcome to my Website</h1>
</header>
<main>
  <section>
    <h2>Some important text</h2>
    <p>More details here in this description.</p>
  </section>
</main>
<footer>...</footer>

❌ Не заменяй всё на div и span

html
<div class="header">
  <div>Welcome to my Website</div>
</div>
<div class="content">
  <div class="post">
    <div>Some important text</div>
    <div>More details here in this description.</div>
  </div>
</div>
<div class="footer">...</div>

Вложенность

✅ Держи структуру плоской

html
<section>
  <h2>Title</h2>
</section>

❌ Не добавляй лишние обёртки

html
<div>
  <div>
    <div>
      <h2>Title</h2>
    </div>
  </div>
</div>

Простота шаблона

✅ Шаблон только про отображение

html
{{ isVisible }}

❌ Не пиши составные условия в шаблоне

html
{{ b1 && b2 || !b3 }}

ℹ️

Шаблон — декларативное отображение уже подготовленного состояния.
Любая логика, трансформация и вычисления должны находиться вне шаблона.

Control Flow

✅ Используй встроенный control flow

html
@for (item of items; track item.id) {
  <div>{{ item.name }}</div>
}

❌ Не используй структурные директивы

html
<div *ngFor="let item of items">{{ item.name }}</div>

Условный рендеринг

✅ Управляй отображением на уровне родителя

html
@if (user) {
  <app-profile />
}

❌ Не перекладывай это на дочерний

html
@if (user) {
  <div>Component html...</div>
}

Локальные переменные

✅ Сохраняй в локальные переменные через @if (...; as ...)

html
@if (order().customer.primaryAddress; as address) {
  <div>{{ address.city }}</div>
  <div>{{ address.street }}</div>
  <div>{{ address.postalCode }}</div>

  @if (address.country === 'DE') {
    <span>🇩🇪 Germany</span>
  } 
}

❌ Не дублируй доступ к одним и тем же данным

html
<div>{{ order().customer.primaryAddress.city }}</div>
<div>{{ order().customer.primaryAddress.street }}</div>
<div>{{ order().customer.primaryAddress.postalCode }}</div>

@if (order().customer.primaryAddress.country === 'DE') {
  <span>🇩🇪 Germany</span>
}

Ссылки vs кнопки

✅ Используй <a> для навигации (даже если выглядит как кнопка)

html
<a routerLink="/profile" rtsPrimaryButton> Перейти в профиль </a>

❌ Не делай навигацию через <button>

html
<button rtsPrimaryButton (click)="router.navigate(['/profile'])">Перейти в профиль</button>

✅ Используй <button> для действий (даже если выглядит как ссылка)

html
<button rtsDarkLink (click)="onLogout()">Выйти</button>

❌ Не делай действия через <a>

html
<a rtsDarkLink (click)="onLogout()"> Выйти </a>

Автотесты

✅ Добавляй rts-at на:

  • Контролы формы
html
<rts-password rts-at="passwordControl" />
  • Ключевые действия
html
<button rtsPrimaryButton rts-at="deleteUserButton">Удалить</button>
  • Важные данные
html
<span rts-at="userBalance">100 ₽</span>
  • Ссылки
html
<a rtsSecondaryButton [href]="environment.Poa.ServiceUrl" rts-at="generatePoaLink">
  Сформировать доверенность
</a>
  • Тултипы
html
<rts-tooltip-manual
  rtsTooltipManualHover
  text="Закупка является процедурой торг за единицу товара"
  rts-at="isUnitBiddingTooltip"
>
  ...Content
</rts-tooltip-manual>

✅ Используй camelCase для нейминга