دليل 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 الخاصين به. الـ barrel 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

الخطوات التالية

أسئلة في الطريق؟ صفحة المساعدة مليئة بالإجابات — وإن أمكن توضيح خطوة أكثر، أخبرنا وسنحسّن الدليل بكل سرور.