Tutorial sa Angular

Mga standalone na component ng Angular 20 — signal input, OnPush na change detection, inline na template, zero NgModules, zero CSS.

Ang bubuuin mo

Isang maliit na contact form — input na may label, submit button, two-way binding, tunay na gawi ng keyboard at screen reader — una ay hubad, pagkatapos ay may istilo, sa humigit-kumulang 10 minuto.

Bago ka magsimula

Kailangan mo ng git, Node 22 o mas bago, at pnpm 10 o mas bago. Gumagana ang anumang proyektong Angular 20 — Angular CLI o Analog.

Hakbang 1 — Kunin ang code

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

Ang mga component ay mga flat na file sa components/ — Button.ts, TextInput.ts — bawat isa ay standalone na component na may inline na template, kasama ang spec at story nito. Ang barrel index.ts ay muling nag-e-export ng bawat component; pnpm build ay gumagawa ng Angular Package Format bundle sa pamamagitan ng ng-packagr.

Hakbang 2 — Ang una mong 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"); }
}

Nagdedeklara ang bawat component ng lily-* selector at nagre-render ng semantic element na may class hook nito — <button class="button" type="button"> dito. Batay sa signal ang mga input: label() para sa aria-label override, className() para magdagdag ng mga klase.

Hakbang 3 — Bumuo ng maliit na form

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 ay kumukuha ng nakikitang label bilang sarili nitong label input sa halip na nested na label component — ipasa ito nang isang beses, sa field, at ang katugmang lily-text-inputsa label ay nagbibigay ng accessible na pangalan. Naglalantad ang mga component na katulad ng input ng mga model() halaga, kaya ang banana-box [(value)] two-way binding ay gumagana agad — compatible sa zoneless sa kabuuan.

Napatunayan noong 2026-08-29: nag-nest ang naunang draft ng hiwalay na Label component sa loob ng lily-field, na nagre-render ng dalawang label (isang walang laman) dahil lily-field ay nagre-render na ng sarili nito mula sa label input — nahuli sa pamamagitan ng pagsusuri sa source ng component. Ang composed na ruta ng contact-form ay parehong pattern, sinubukan ng tunay na e2e at axe na pagsusuri.

Suriin ang gawa mo: patakbuhin ang app at mukhang payak ang form — eksakto ayon sa layunin: ang istilo ay nasa unahan pa. Pindutin ang Tab: gumagalaw ang focus sa bawat kontrol, naba-balita ang label, at gumagana ang pagsumite. Tapos na ang gawi; sa iyo ang hitsura at iyon ang susunod.

Hakbang 4 — Bigyan ng istilo

Bigyan ng istilo ang mga class hook — .button, .text-input, .label, .field — sa styles.css, o magdagdag ng handa nang tema sa array na styles sa angular.json / i-link ito sa index.html:

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

Hakbang 5 — Tingnan ang lahat na gumagana

Ang Angular + Analog na halimbawang app ay nagpapakita ng buong catalog na may file-based na routing at Vite:

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

Mga susunod na hakbang

May mga tanong habang nasa daan? Ang pahina ng tulong ay puno ng mga sagot — at kung maaaring maging mas malinaw ang isang hakbang, sabihin sa amin at masaya naming pagbubutihin ang tutorial.