Introduzione a Lily

Scegli un framework, clona il monorepo e apri la sua libreria headless o l'app di esempio, poi inizia a comporre le tue pagine. Preferisci un percorso guidato? Inizia con i tutorial.

Installazione

Lily vive in un unico monorepo Git, con una directory per la libreria headless, i pacchetti helper e l'app di esempio di ciascun framework. Il modo più rapido per provarlo è clonare il monorepo e aprire la libreria headless per il tuo stack:

git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-react-headless
pnpm install

Lo stesso schema vale per gli altri framework:

  • @lilydesignsystem/html-headless – nessuna installazione necessaria; copia i file .html
  • @lilydesignsystem/svelte-headless — pnpm install
  • @lilydesignsystem/react-headless — pnpm install
  • @lilydesignsystem/vue-headless — pnpm install
  • @lilydesignsystem/angular-headless — pnpm install
  • @lilydesignsystem/nunjucks-headless — pnpm install
  • lily-design-system-blazor-headless — dotnet build

Le librerie headless sono pensate per essere clonate o incluse nel progetto: considera il sorgente la fonte di verità e copia ciò che ti serve. helper per le preferenze sono inoltre distribuiti come pacchetti installabili con una pipeline di build e pubblicazione (npm per i framework JS, NuGet per Blazor).

Usare un componente headless

I componenti headless forniscono HTML semantico, ARIA e prop – ma nessun CSS. Ecco un Button in ciascun framework:

HTML

<button class="button" type="button" aria-label="Save">
  Save
</button>

Svelte

<script>
  import Button from "lily-design-system-svelte-headless/components/Button/Button.svelte";
</script>

<Button onclick={save}>Save</Button>

React

import Button from "lily-design-system-react-headless/components/Button";

<Button onClick={save}>Save</Button>

Vue

<script setup>
  import Button from "lily-design-system-vue-headless/components/Button.vue";
</script>

<Button @click="save">Save</Button>

Angular

import { Button } from "@lilydesignsystem/angular-headless";

@Component({
  imports: [Button],
  template: `<lily-button (click)="save()">Save</lily-button>`,
})

Blazor

<Button OnClick="Save">Save</Button>

Nunjucks

{% from "components/button/macro.njk" import button %}

{{ button({ text: "Save", type: "button" }) }}

Usare un esempio con stili

Le app di esempio includono CSS, percorsi e pagine demo complete. Il modo più rapido per sperimentare è avviare l'app di esempio di SvelteKit, Next, Nuxt, Analog o Eleventy e vedere la demo su /components.

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

Poi apri http://localhost:5173 e sfoglia /components.

Stili e design token

Ogni componente viene renderizzato con una sola classe in kebab-case sul suo elemento radice. Ad esempio, <Button> viene renderizzato come <button class="button">. Applica gli stili come preferisci:

.button {
  background: var(--my-primary);
  color: #fff;
  padding: 0.75rem 1.5rem;
  border-radius: 0.5rem;
}
.button:hover { background: var(--my-primary-hover); }

La palette di colori predefinita di Lily (usata nelle app di esempio) è:

  • Primario: #2563eb
  • Pericolo: #dc2626
  • Avviso: #f59e0b
  • Successo: #16a34a
  • Sfondo della pagina: #f9fafb
  • Sfondo della scheda: #ffffff

Sono suggerimenti, non requisiti. Sostituiscili con la palette del tuo brand e Lily si adatta volentieri.

Temi pronti

Non vuoi scrivere il CSS da zero? Lily include 57 temi di riferimento autonomi nella directory themes/ . Ciascuno è un foglio di stile che punta agli hook di classe di Lily: collegalo e hai gli stili:

<link rel="stylesheet" href="/assets/themes/united-kingdom-government-digital-service.css" />

L'insieme comprende:

  • Settore pubblico – NHS England, NHS Scotland e NHS Wales (ciascuno nelle varianti per pazienti e per operatori), GOV.UK GDS e lo U.S. Web Design System.
  • Ispirati ai fornitori – Adobe Spectrum, Mozilla Protocol.
  • Uso generale – light, dark, nord, dracula, wireframe e una trentina di altri.

I selettori dei temi usano :where(...), quindi il tuo CSS vince sempre per specificità. Abbinali all'helper theme-picker qui sotto per il cambio a runtime, oppure segui il tutorial sui temi.

Helper per le preferenze

Ogni framework ha otto piccoli selettori, ciascuno un proprio pacchetto lily-design-system-{framework}-{package} (e un picker-bar che li assembla). Ciascuno è un pulsante a icona headless che apre un popup – una listbox, un elenco di link, un modulo di ricerca o (per date-time-picker) una finestra di dialogo per la scelta della data – non un <select>nativo; è sicuro per SSR; e non include CSS:

  • theme-picker – carica i fogli di stile dei temi a runtime sostituendo un <link>gestito, imposta data-theme sul documento e, facoltativamente, salva in localStorage.
  • locale-picker – imposta lang e dir (con rilevamento RTL automatico) così la tua libreria i18n può seguire; non traduce nulla da sola.
  • text-size-picker – imposta data-text-size sul documento; il tuo CSS associa ogni valore a una dimensione del carattere.
  • motion-picker – imposta data-motion sul documento, partendo dall'impostazione di movimento ridotto del visitatore; il tuo CSS e i tuoi script decidono cosa sopprimere.
  • search-picker – un pulsante a icona che apre un campo di ricerca; l'invio porta a una pagina di ricerca. Gestisce un'azione, non una preferenza.
  • link-picker – un'icona della casa che apre un menu dei link alle pagine definiti dalla tua app (Home, Chi siamo, Contattaci, Informativa sulla privacy, …). Gestisce un'azione, non una preferenza.
  • share-picker – apre il foglio di condivisione nativo o un elenco di destinazioni fornito dal consumatore, più la copia dell'URL. Gestisce un'azione, non una preferenza: non applica nulla, non salva nulla.
  • date-time-picker – un campo di testo più una finestra di dialogo APG per la scelta di una data, un'ora o entrambe. Gestisce un valore di modulo, non una preferenza: la stringa ISO viene convertita avanti e indietro in <input type="date">.
git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-svelte-theme-picker

Il catalogo Svelte è il riferimento canonico; i port per React, Vue, Angular, HTML, Nunjucks, Web Components e Blazor lo rispecchiano contratto per contratto. Vedi il tutorial sugli helper.

Accessibilità

I componenti puntano a WCAG 2.2 AAA. Seguono questi pattern:

  • Elementi HTML semantici al posto di <div>s.
  • <label for="id"> generici che collegano le etichette agli input.
  • aria-labelledby / aria-describedby per i riferimenti incrociati.
  • aria-invalid + aria-errormessage per gli stati di errore.
  • role="alert" e aria-live per il contenuto dinamico.
  • aria-pressed, aria-expanded, aria-current per lo stato.
  • Roving tabindex per le griglie.

Gli indicatori di focus sono forniti intenzionalmente dal consumatore: Lily non disegna mai un anello di focus predefinito che contrasti con il tuo design. Le app di esempio mantengono una baseline axe-core pulita su tutti i loro percorsi.

Internazionalizzazione

Ogni etichetta, segnaposto, messaggio di errore e testo di pulsante è una prop. Non ci sono stringhe scritte nel codice. Inserisci il framework di traduzione che preferisci – Paraglide, i18next, vue-i18n, react-intl, file .resx, qualsiasi cosa.

Per date, numeri e valute, i componenti accettano stringhe già formattate: formatti tu con Intl.DateTimeFormat / Intl.NumberFormat / la tua libreria preferita e passi il risultato.

L'helper locale-picker segnala la lingua scelta alla tua libreria i18n impostando lang e dir sulla radice del documento.

Test

Ogni sottoprogetto di framework include i propri test che usano il suo stack idiomatico:

  • HTML: WebDriverIO che esegue browser reali.
  • Svelte: Vitest + @testing-library/svelte.
  • React: Vitest + @testing-library/react.
  • Vue: Vitest + @testing-library/vue.
  • Angular: Vitest + TestBed (tramite il plugin Vite di Analog).
  • Nunjucks: Vitest con un helper di rendering.
  • Blazor: bUnit.

I test usano solo i matcher integrati di Vitest – mai i matcher di jest-dom . Questo mantiene portabili le suite di test. Le app di esempio aggiungono suite end-to-end con Playwright, baseline di accessibilità con axe-core e una scansione dei viewport responsive.

Agenti di IA

Questo sito pubblica llms.txt e llms.json nella sua radice – una mappa curata delle sue pagine più importanti, per qualsiasi strumento che segua la convenzione llms.txt.

Il monorepo canonico include inoltre due Claude Skills: lily-design-system-skill: una skill generale che copre i concetti, la terminologia e i pattern di composizione di Lily per chiunque costruisca con il sistema, e lily-design-system-maintainer-skill, una skill tecnica che copre la struttura dei file obbligatori del monorepo e gli strumenti per chiunque ci lavori. Entrambe si trovano nella radice del monorepo canonico.

Risoluzione dei problemi

Un componente viene renderizzato ma sembra senza stili

È l'headless che funziona come previsto – con il componente non viene fornito alcun CSS. Scrivi il CSS per la classe in kebab-case del componente (mostrata in ogni pagina del catalogo) oppure collega uno dei 57 temi pronti.

Il mio CSS non sembra applicarsi sopra un tema

Dovrebbe – i selettori dei temi sono racchiusi in :where(...), che ha specificità zero. Se una regola perde comunque, controlla che il tuo foglio di stile venga caricato dopo il <link> del tema e che il selettore corrisponda davvero all'hook di classe del componente.

pnpm install fallisce con un errore di peer o di versione

Usa un pnpm aggiornato (v10+) e Node 22+. Ogni sottoprogetto fissa le versioni dei propri framework nel proprio package.json; se la tua toolchain globale è più vecchia, pnpm env use --global lts è la soluzione più rapida.

Lo screen reader annuncia il nome sbagliato per un controllo

Controlla la prop obbligatoria label del componente – i componenti privi di testo visibile ne richiedono una, e aria-label / aria-labelledby forniti dal consumatore e passati tramite rest-props prevalgono intenzionalmente sul collegamento integrato. Ogni pagina del catalogo documenta il contratto ARIA del componente.

L'helper theme-picker non cambia i fogli di stile

Verifica che themesUrl punti a una directory che il browser può recuperare (servi i file themes/ come risorse statiche) e che gli slug dei temi nella tua prop themes corrispondano ai nomi dei file. L'helper sostituisce l'attributo href di un solo <link data-lily-theme-picker> gestito – ispezionalo negli strumenti per sviluppatori per vedere l'URL richiesto.

Qualcos'altro non funziona

Apri una issue con una riproduzione minima su github.com/LilyDesignSystem/lily-design-system – oppure vedi community e supporto.

Contribuire

Lily è giovane e accoglie la collaborazione. I contributi più utili al momento sono:

  • Nuovi componenti (in particolare pattern di design system consolidati).
  • Nuovi temi – ciascuno è un foglio di stile autonomo, una prima PR ben delimitata.
  • Stili di esempio migliori – mostra cosa è possibile.
  • Traduzioni delle stringhe delle app di esempio.
  • Segnalazioni di bug con una riproduzione minima.
  • Audit di accessibilità con screen reader e tecnologie assistive.

Apri issue e PR su github.com/LilyDesignSystem/lily-design-system.

Community e supporto

FAQ

Perché headless invece che con stili?

I componenti con stili preconfezionati sono comodi – finché non si adattano al tuo brand. I componenti headless richiedono un po' più di lavoro all'inizio ma ti danno il controllo totale sul design visivo. Le app di esempio e i 57 temi mostrano modi per applicare gli stili; puoi usarli o sostituirli del tutto. L'argomentazione più estesa è su Perché Lily.

Perché così tanti componenti?

Lily punta a coprire i pattern di cui hanno bisogno la maggior parte delle app senza costringerti a costruirli da zero – compresi casi specialistici come gli input di identificativi nazionali e lo scrollytelling editoriale. Il catalogo attinge da una dozzina di design system consolidati più lavoro originale – vedi Informazioni.

Posso usare Lily con Tailwind?

Sì. Ogni componente espone una singola classe radice in kebab-case più un className / classfornito dal consumatore. Sovrapponi le utility di Tailwind come preferisci.

Posso usare Lily con framework CSS semantici come DaisyUI?

Sì. I nomi di classe in kebab-case sull'elemento radice funzionano come hook CSS semantici. Abbina Lily a un framework semantico e ottieni componenti già con stili che rispettano comunque ARIA e i18n.

Esiste un pacchetto npm?

Gli helper per le preferenze sono distribuiti come pacchetti con una pipeline di pubblicazione npm/NuGet. Le librerie di componenti headless sono pensate per essere clonate o incluse nel progetto: il sorgente è il prodotto consegnato, così puoi leggere, sfoltire e possedere esattamente ciò che distribuisci. La pubblicazione su registry per le librerie headless resta nella roadmap.

Perché più licenze?

Progetti diversi hanno esigenze di licenza diverse. BSD e MIT sono permissive, Apache-2.0 prevede una concessione di brevetto e le opzioni GPL supportano il copyleft. Scegli quella più adatta alla tua situazione.

Come segnalo un bug o richiedo una funzionalità?

Apri una issue sul repository GitHub oppure scrivi a joel@joelparkerhenderson.com.