Руководство по Angular
Автономные компоненты Angular 20 — сигнальные входы, обнаружение изменений OnPush, встроенные шаблоны, ноль NgModules, ноль CSS.
Что вы построите
Небольшая контактная форма — поле с меткой, кнопка отправки, двусторонняя привязка, реальное поведение клавиатуры и программы чтения с экрана — сначала голая, затем оформленная, примерно за 10 минут.
Прежде чем начать
Вам понадобятся git, Node 22 или новее и pnpm 10 или новее. Подойдёт любой проект Angular 20 — Angular CLI или Analog.
Шаг 1 — Получите код
git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-angular-headless
pnpm install
pnpm test # vitest + TestBed, all 571 components
pnpm run build-storybook
Компоненты — это плоские файлы в components/ —
Button.ts, TextInput.ts — каждый является автономным компонентом со встроенным шаблоном, плюс его spec и story. Баррель
index.ts реэкспортирует каждый компонент; pnpm build
создаёт пакет в формате Angular Package Format через ng-packagr.
Шаг 2 — Ваш первый компонент
import { Component } from "@angular/core";
import { Button } from "@lilydesignsystem/angular-headless";
@Component({
selector: "app-save-bar",
standalone: true,
imports: [Button],
template: `<lily-button (click)="save()">Save</lily-button>`,
})
export class SaveBar {
save() { console.log("saved"); }
}
Каждый компонент объявляет селектор lily-* и отображает семантический элемент со своим крючком класса —
<button class="button" type="button"> здесь. Входы основаны на сигналах: label() для aria-label
для переопределения, className() для добавления классов.
Шаг 3 — Составьте небольшую форму
import { Component, signal } from "@angular/core";
import { Form, Field, TextInput, Button } from "@lilydesignsystem/angular-headless";
@Component({
selector: "app-contact-form",
standalone: true,
imports: [Form, Field, TextInput, Button],
template: `
<lily-form label="Contact form" (submit)="handleSubmit($event)">
<lily-field label="Full name" [required]="true">
<lily-text-input id="name" label="Full name" [(value)]="name" />
</lily-field>
<lily-button type="submit">Save</lily-button>
</lily-form>
`,
})
export class ContactForm {
name = signal("");
}
lily-field принимает видимую метку как собственный
label вход, а не как вложенный компонент метки — передайте её один раз, на поле, и соответствующий lily-text-inputиз
label обеспечивает доступное имя. Компоненты, похожие на поля ввода, предоставляют значения model() поэтому двусторонняя привязка banana-box [(value)]
работает сразу — совместимо с zoneless во всём.
Проверено 2026-08-29: в более раннем черновике отдельный компонент Label был вложен в lily-field, что отображало две метки (одну пустую), потому что
lily-field уже отображает свою собственную из входа
label — обнаружено при проверке исходного кода компонента.
Составной маршрут контактной формы
— тот же шаблон, проверенный настоящими тестами e2e и axe.
Проверьте свою работу: запустите приложение, и форма выглядит голой — именно так, как задумано: оформление ещё впереди. Нажмите Tab: фокус проходит через каждый элемент управления, метка озвучивается, а отправка работает. Поведение готово; внешний вид за вами, и это следующий шаг.
Шаг 4 — Оформите её
Оформите крючки классов — .button, .text-input,
.label, .field — в styles.css, или добавьте готовую тему в массив styles в
angular.json / подключите её в index.html:
<link rel="stylesheet" href="/themes/adobe-spectrum.css" />
Шаг 5 — Посмотрите, как всё работает
Пример приложения Angular + Analog показывает полный каталог с файловой маршрутизацией и Vite:
git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-angular-examples
pnpm install && pnpm run dev
Дальнейшие шаги
- Темы — переключение во время выполнения с помощником theme-picker для Angular.
- Помощники настроек — язык и размер текста.
- Каталог компонентов — свойства, ARIA и клавиатура для каждого компонента.
Есть вопросы по ходу дела? Страница справки полна ответов — а если какой-то шаг можно сделать яснее, сообщите нам и мы с радостью улучшим руководство.