Angular-vejledning

Angular 20 selvstændige komponenter — signal-input, OnPush-ændringsregistrering, indlejrede skabeloner, nul NgModules, nul CSS.

Det her bygger du

En lille kontaktformular — felt med etiket, send-knap, tovejsbinding, ægte tastatur- og skærmlæseradfærd — først nøgen, derefter formgivet, på omkring 10 minutter.

Før du går i gang

Du skal bruge git, Node 22 eller nyere og pnpm 10 eller nyere. Ethvert Angular 20-projekt virker — Angular CLI eller Analog.

Trin 1 — Hent koden

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

Komponenterne er flade filer i components/ — Button.ts, TextInput.ts — hver er en selvstændig komponent med en indlejret skabelon, plus sin spec og sin story. Barrel-filen index.ts eksporterer alle komponenter igen; pnpm build laver en pakke i Angular Package Format via ng-packagr.

Trin 2 — Din første komponent

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

Hver komponent erklærer en lily-* -selektor og gengiver det semantiske element med sin klassekrog — <button class="button" type="button"> her. Input er signalbaserede: label() for et aria-label til at tilsidesætte, className() til at tilføje klasser.

Trin 3 — Sæt en lille formular sammen

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 tager den synlige etiket som sit eget label -input i stedet for en indlejret etiketkomponent — send den én gang, på feltet, og den matchende lily-text-inputfra label giver det tilgængelige navn. Inputlignende komponenter eksponerer model() -værdier, så banana-box [(value)] -tovejsbinding virker med det samme — zoneless-kompatibelt hele vejen.

Verificeret 2026-08-29: et tidligere udkast indlejrede en separat Label -komponent i lily-field, hvilket gengiver to etiketter (en tom), fordi lily-field allerede gengiver sin egen fra label -input — opdaget ved at tjekke komponentens kildekode. Den sammensatte kontaktformularrute er det samme mønster, afprøvet med ægte e2e- og axe-tests.

Tjek dit arbejde: kør appen, og formularen ser nøgen ud — præcis som tilsigtet: formgivningen kommer endnu. Tryk på Tab: fokus flytter sig gennem hver kontrol, etiketten oplæses, og afsendelse virker. Adfærden er færdig; udseendet er dit og er næste skridt.

Trin 4 — Giv den stil

Formgiv klassekrogene — .button, .text-input, .label, .field — i styles.css, eller tilføj et færdigt tema til styles -arrayet i angular.json / link det i index.html:

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

Trin 5 — Se det hele virke

Angular + Analog eksempelapp viser hele kataloget med filbaseret routing og Vite:

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

Næste skridt

Spørgsmål undervejs? Siden Hjælp er fuld af svar — og hvis et trin kan blive tydeligere, så fortæl os det og vi forbedrer gerne vejledningen.