Tutorial Angular

Componente independente Angular 20 — intrări de tip semnal, detectare a modificărilor OnPush, șabloane inline, zero NgModules, zero CSS.

Ce vei construi

Un mic formular de contact — câmp cu etichetă, buton de trimitere, legare bidirecțională, comportament real al tastaturii și al cititorului de ecran — mai întâi simplu, apoi stilizat, în aproximativ 10 minute.

Înainte să începi

Ai nevoie de git, Node 22 sau mai nou și pnpm 10 sau mai nou. Orice proiect Angular 20 merge — Angular CLI sau Analog.

Pasul 1 — Obține codul

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

Componentele sunt fișiere plate în components/ — Button.ts, TextInput.ts — fiecare este o componentă independentă cu șablon inline, plus spec-ul și story-ul ei. Barrel-ul index.ts reexportă fiecare componentă; pnpm build produce un pachet în Angular Package Format prin ng-packagr.

Pasul 2 — Prima ta componentă

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"); }
}

Fiecare componentă declară un selector lily-* și randează elementul semantic cu cârligul ei de clasă — <button class="button" type="button"> aici. Intrările sunt bazate pe semnale: label() pentru un aria-label pentru suprascriere, className() pentru a adăuga clase.

Pasul 3 — Compune un formular mic

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 primește eticheta vizibilă ca propria label intrare, în loc de o componentă etichetă imbricată — transmite-o o singură dată, pe câmp, iar lily-text-inputcorespunzător din label oferă numele accesibil. Componentele asemănătoare câmpurilor expun valori model() deci banana-box [(value)] legarea bidirecțională funcționează pe loc — compatibilă zoneless peste tot.

Verificat la 2026-08-29: o ciornă anterioară imbrica o componentă Label separată în lily-field, ceea ce randa două etichete (una goală) deoarece lily-field randează deja propria etichetă din intrarea label — descoperit verificând codul sursă al componentei. Ruta compusă a formularului de contact este același tipar, exersat cu teste e2e și axe reale.

Verifică-ți munca: rulează aplicația și formularul arată simplu — exact cum era intenționat: stilizarea urmează. Apasă Tab: focalizarea trece prin fiecare control, eticheta este anunțată, iar trimiterea funcționează. Comportamentul este gata; aspectul este al tău și urmează.

Pasul 4 — Stilizează-l

Stilizează cârligele de clasă — .button, .text-input, .label, .field — în styles.csssau adaugă o temă gata făcută în matricea styles din angular.json / leag-o în index.html:

<link rel="stylesheet" href="/themes/adobe-spectrum.css" />

Pasul 5 — Vezi totul funcționând

Aplicația-exemplu Angular + Analog arată catalogul complet cu rutare bazată pe fișiere și Vite:

git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-angular-examples
pnpm install && pnpm run dev

Pașii următori

Întrebări pe parcurs? Pagina de ajutor este plină de răspunsuri — iar dacă un pas poate fi mai clar, spune-ne și vom îmbunătăți cu plăcere tutorialul.