Tutorial Angular

Komponen kendiri Angular 20 — input isyarat, pengesanan perubahan OnPush, templat sebaris, sifar NgModules, sifar CSS.

Apa yang akan anda bina

Borang hubungan kecil — input berlabel, butang hantar, pengikatan dua hala, tingkah laku papan kekunci dan pembaca skrin yang sebenar — mula-mula kosong, kemudian digayakan, dalam kira-kira 10 minit.

Sebelum anda bermula

Anda memerlukan git, Node 22 atau lebih baharu, dan pnpm 10 atau lebih baharu. Mana-mana projek Angular 20 boleh digunakan — Angular CLI atau Analog.

Langkah 1 — Dapatkan kod

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

Komponen ialah fail rata dalam components/ — Button.ts, TextInput.ts — masing-masing komponen kendiri dengan templat sebaris, ditambah spec dan story-nya. Barrel index.ts mengeksport semula setiap komponen; pnpm build menghasilkan bundel Angular Package Format melalui ng-packagr.

Langkah 2 — Komponen pertama anda

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

Setiap komponen mengisytiharkan lily-* pemilih dan memaparkan elemen semantik dengan cangkuk kelasnya — <button class="button" type="button"> di sini. Input berasaskan isyarat: label() untuk aria-label penggantian, className() untuk menambah kelas.

Langkah 3 — Gubah borang kecil

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 mengambil label kelihatan sebagai label inputnya sendiri dan bukannya komponen label bersarang — hantar sekali, pada medan, dan lily-text-inputyang sepadan pada label membekalkan nama boleh diakses. Komponen seperti input mendedahkan model() nilai, jadi banana-box [(value)] pengikatan dua hala berfungsi serta-merta — serasi zoneless sepenuhnya.

Disahkan 2026-08-29: draf awal menyarangkan komponen Label berasingan di dalam lily-field, yang memaparkan dua label (satu kosong) kerana lily-field sudah memaparkan labelnya sendiri daripada label input — dikesan dengan menyemak sumber komponen. laluan borang hubungan gubahan ialah corak yang sama, diuji dengan e2e dan ujian axe sebenar.

Semak kerja anda: jalankan aplikasi dan borang kelihatan biasa sahaja — tepat seperti dimaksudkan: penggayaan masih di hadapan. Tekan Tab: fokus bergerak melalui setiap kawalan, label diumumkan dan penghantaran berfungsi. Tingkah laku sudah siap; rupanya milik anda dan itu seterusnya.

Langkah 4 — Gayakan

Gayakan cangkuk kelas — .button, .text-input, .label, .field — dalam styles.css, atau tambah tema siap pakai pada tatasusunan styles dalam angular.json / pautkan dalam index.html:

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

Langkah 5 — Lihat semuanya berfungsi

Aplikasi contoh Angular + Analog menunjukkan katalog penuh dengan penghalaan berasaskan fail dan Vite:

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

Langkah seterusnya

Ada soalan di sepanjang jalan? halaman bantuan penuh dengan jawapan — dan jika sesuatu langkah boleh dijelaskan lagi, beritahu kami dan kami dengan senang hati akan memperbaiki tutorial.