Tutorial Angular
Componenti standalone Angular 20 — input a segnale, rilevamento delle modifiche OnPush, template inline, zero NgModule, zero CSS.
Cosa costruirai
Un piccolo modulo di contatto — campo con etichetta, pulsante di invio, binding bidirezionale, comportamento reale di tastiera e screen reader — prima spoglio, poi stilizzato, in circa 10 minuti.
Prima di iniziare
Servono git, Node 22 o successivo e pnpm 10 o successivo. Va bene qualsiasi progetto Angular 20 — Angular CLI o Analog.
Passo 1 — Ottieni il codice
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
I componenti sono file piatti in components/ —
Button.ts, TextInput.ts — ognuno è un componente standalone con template inline, più il suo spec e la sua story. Il barrel
index.ts riesporta ogni componente; pnpm build
produce un bundle Angular Package Format tramite ng-packagr.
Passo 2 — Il tuo primo componente
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"); }
}
Ogni componente dichiara un selettore lily-* e rende l'elemento semantico con il suo hook di classe —
<button class="button" type="button"> qui. Gli input sono basati su segnali: label() per un aria-label
per sostituire, className() per aggiungere classi.
Passo 3 — Componi un piccolo modulo
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 riceve l'etichetta visibile come proprio
label input invece di un componente etichetta annidato — passala una sola volta, sul campo, e lily-text-inputcorrispondente
label fornisce il nome accessibile. I componenti simili a input espongono valori model() quindi il banana-box [(value)]
binding bidirezionale funziona subito — compatibile con zoneless ovunque.
Verificato il 2026-08-29: una bozza precedente annidava un componente Label separato dentro lily-field, che rendeva due etichette (una vuota) perché
lily-field rende già la propria dall'input
label — individuato controllando il sorgente del componente.
La rotta composta del modulo di contatto
è lo stesso schema, collaudato da veri test e2e e axe.
Controlla il lavoro: avvia l'app e il modulo appare spoglio — esattamente come previsto: lo stile deve ancora venire. Premi Tab: il focus si sposta su ogni controllo, l'etichetta viene annunciata e l'invio funziona. Il comportamento è fatto; l'aspetto è tuo, ed è il prossimo passo.
Passo 4 — Dagli uno stile
Stilizza gli hook di classe — .button, .text-input,
.label, .field — in styles.css, oppure aggiungi un tema pronto all'array styles in
angular.json / collegalo in index.html:
<link rel="stylesheet" href="/themes/adobe-spectrum.css" />
Passo 5 — Guarda tutto in funzione
App di esempio Angular + Analog mostra il catalogo completo con routing basato su file e Vite:
git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-angular-examples
pnpm install && pnpm run dev
Prossimi passi
- Temi — cambio a runtime con l'helper theme-picker per Angular.
- Helper delle preferenze — lingua e dimensione del testo.
- Catalogo dei componenti — proprietà, ARIA e tastiera per ogni componente.
Domande lungo la strada? La pagina di aiuto è piena di risposte — e se un passo può essere più chiaro, faccelo sapere e miglioreremo volentieri il tutorial.