Componi un’interfaccia per i servizi pubblici usando componenti reali dei contributori e un tema esplicito. Questo riferimento usa Utrecht CSS per illustrare la mappatura dei token, la struttura di un elenco di dati e due temi originali con lo stesso flusso di modifica.
Componenti nativi Button e Data List di Utrecht CSS 9.0.15, token del tema originali e interazione dell’applicazione. · Riferimento per l’implementazione
02
Sistema di design NL Riferimento di progettazione
Composizione concreta di un contributore: @utrecht/component-library-css 9.0.15. I nomi dei token pubblici e le classi sono API della libreria consultabili; i valori numerici e i colori indicati come «esempio» sono impostazioni originali dell’applicazione, non una specifica universale di NL Design System.
NL Design System supporta esplicitamente la combinazione dei contributi di più organizzazioni e descrive lo stile caratteristico di ciascuna tramite design token. L’unità pratica di adozione è quindi un’implementazione di componenti selezionata insieme a un tema selezionato. Questa pagina sceglie l’implementazione del contributore Utrecht CSS e un tema dimostrativo originale.
Questa scelta non afferma che Utrecht sia l’implementazione canonica di ogni componente NL Design System. Offre al lettore un percorso riproducibile, senza inventare un font nazionale, un colore blu o una scala di spaziatura. Il pacchetto nativo CSS effettivo è @utrecht/component-library-css 9.0.15.
Token pubblici dei componenti sistema di design NL
Mantieni i valori dell’applicazione separati da CSS
Il tema fornito imposta le proprietà personalizzate pubbliche --utrecht-* su un wrapper. Il pulsante usa questi valori, mentre la sua classe ne determina la struttura. Le variabili che iniziano con --_utrecht- sono calcoli interni nella versione di CSS esaminata; modificarle direttamente legherebbe l’applicazione ai dettagli di implementazione.
Il turchese #005a5b e il viola #57328c dell’esempio sono colori originali dell’applicazione. Dimostrano come sostituire il marchio senza copiare l’identità di un comune. Entrambi usano testo bianco per le azioni e il colore al passaggio del puntatore è definito separatamente. Nessun colore viene descritto come valore ufficiale di un token NL Design System.
css
.example-theme {
/* Original application values, not a national house style. */
--utrecht-document-font-family: Arial, sans-serif;
--utrecht-button-font-size: 1rem;
--utrecht-button-line-height: 1.5;
--utrecht-button-font-weight: 700;
--utrecht-button-border-radius: .25rem;
--utrecht-button-min-block-size: 48px;
--utrecht-button-padding-block-start: .75rem;
--utrecht-button-padding-block-end: .75rem;
--utrecht-button-padding-inline-start: 1.25rem;
--utrecht-button-padding-inline-end: 1.25rem;
--utrecht-button-primary-action-background-color: #005a5b;
--utrecht-button-primary-action-color: #fff;
--utrecht-button-primary-action-hover-background-color: #003f40;
--utrecht-button-primary-action-hover-color: #fff;
--utrecht-focus-outline-color: #111;
--utrecht-focus-outline-width: 3px;
--utrecht-focus-outline-offset: 3px;
--utrecht-focus-outline-style: solid;
}
La demo definisce Arial, sans-serif a 18px con un’interlinea di 1.6 per la lettura dei documenti. Il primo tema usa un’intestazione da 32px e un raggio degli angoli dei pulsanti di 4px; il secondo mantiene la stessa dimensione leggibile del testo principale, con un raggio di 8px e un’intestazione con grazie. Le differenze tra i temi sono volutamente evidenti.
Se il relativo token non è presente, il pulsante nativo usa una dimensione minima in direzione del blocco di 44px. Il nostro tema imposta 48px e padding espliciti in direzione del blocco e in quella in linea. È un vero CSS API con un valore scelto dall’applicazione, non una dimensione ipotizzata per l’intero ecosistema. Il layout usa una larghezza massima dei contenuti di 56rem e spaziature di 24px, definiti in questo esempio.
Struttura dell’elenco di dati sistema di design NL
Un elenco di definizioni per valori identificati
La ricevuta usa un dl con .utrecht-data-list e il modificatore .utrecht-data-list--rows. Ogni .utrecht-data-list__item raggruppa una chiave dt e un valore dd. Il modificatore rows attiva la griglia adattiva, gli spazi tra le righe e i bordi; senza di esso, l’elenco di dati di base non abilita quel layout. HTML mantiene il proprio significato anche prima del caricamento di un tema.
La ricevuta elenca un luogo di ritiro, un riferimento e l’articolo selezionato. Non si tratta di una tabella di record ripetuti: ogni chiave identifica un attributo diverso della stessa richiesta. Sugli schermi stretti, chiave e valore si dispongono uno sotto l’altro. L’applicazione imposta i token delle righe affinché le etichette lunghe dei luoghi siano visibili per intero.
Usa dt per il nome dell’attributo e dd per il suo valore attuale.
Inserisci ogni coppia chiave/valore nel wrapper documentato per gli elementi.
Consenti agli identificativi e ai nomi di luogo lunghi di andare a capo, invece di allargare la pagina.
La classe di un pulsante non definisce un flusso di lavoro
.utrecht-button fornisce il componente di base, mentre .utrecht-button--primary-action seleziona il gruppo di token per l’aspetto primario. Per un’azione locale che non deve inviare il modulo circostante, l’elemento nativo ha comunque bisogno di type=button. L’elenco di dati rimane di sola lettura finché l’applicazione non apre un pannello di modifica.
Il pulsante «Modifica il luogo di ritiro» della demo mostra un fieldset con pulsanti radio nativi. Il salvataggio aggiorna il valore nell’elenco di definizioni e comunica il nuovo luogo tramite un’area di stato con annuncio non urgente. L’annullamento chiude il pannello senza modificare il valore salvato. Questi comportamenti sono gestiti dal codice dell’applicazione: la sola installazione di un pacchetto CSS non li implementa.
Il selettore del tema modifica data-theme sul wrapper esterno. Le classi dei componenti, i valori del record e il pulsante radio selezionato restano invariati. È una dimostrazione concreta della separazione tra identità visiva e contenuti: la stessa ricevuta e la stessa interazione possono supportare identità visive diverse.
Qui il cambio di tema è una dimostrazione a scopo di sviluppo, non un’impostazione che un servizio pubblico debba necessariamente offrire. In un servizio reale rivolto a più organizzazioni, scegli il tema tramite una configurazione attendibile dell’applicazione. I valori del tema non devono modificare i criteri di idoneità, la convalida o il significato di uno stato.
Carica una sola volta il pacchetto versionato di componenti CSS.
Applica i token pertinenti del tema a un elemento contenitore.
Esegui il rendering dello stesso markup semantico dei componenti all’interno di quel contenitore.
Verifica lo stato attivo, il ritorno a capo e i colori degli stati in ogni tema supportato.
Il modello di relay di NL Design System descrive come i contributi progrediscono verso standard condivisi. La presenza di un componente in un repository della community non garantisce, di per sé, che ogni composizione sia pronta per la produzione. Verifica l’implementazione selezionata, gli stati supportati e il livello di maturità attuale consultando la documentazione del componente.
L’anteprima mantiene visibile una legenda per le scelte del luogo, annuncia il risultato salvato e, dopo la modifica, riporta lo stato attivo sul pulsante che l’ha avviata. Il cambio di tema non rimuove lo stato attivo. La schermata rimane utilizzabile con i controlli da tastiera nativi dei pulsanti radio e i contorni dello stato attivo dell’app; queste verifiche integrano i test del componente del contributore, ma non li sostituiscono.
Installa il pacchetto verificato CSS e importa dist/index.css tramite un bundler compatibile con CSS, seguito dal foglio di stile del tema. Per l’elenco di dati e il pulsante usati qui, che usano solo CSS, non sono necessari né un provider React né un inizializzatore di componenti JavaScript. Lo script originale dell’applicazione gestisce modifica, salvataggio, annullamento e cambio del tema.
Il codice sorgente dei componenti inclusi nel pacchetto è distribuito con licenza EUPL-1.2. Quando lo distribuisci, conserva le notifiche relative al codice sorgente e alla licenza; non dedurre da una licenza del codice il permesso di riutilizzare il logo di un comune. Questo esempio fornisce intenzionalmente temi originali e non include simboli comunali.
Il documento completo include layout, controlli e inizializzazione. Estrai l’archivio di esempio collegato per ottenere gli esatti asset vendor relativi, quindi avvialo tramite HTTP.
html
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>NL Design System composition</title><link rel="stylesheet" href="vendor/utrecht-9.0.15/index.css"><style>.example-theme {
/* Original application values, not a national house style. */
--utrecht-document-font-family: Arial, sans-serif;
--utrecht-button-font-size: 1rem;
--utrecht-button-line-height: 1.5;
--utrecht-button-font-weight: 700;
--utrecht-button-border-radius: .25rem;
--utrecht-button-min-block-size: 48px;
--utrecht-button-padding-block-start: .75rem;
--utrecht-button-padding-block-end: .75rem;
--utrecht-button-padding-inline-start: 1.25rem;
--utrecht-button-padding-inline-end: 1.25rem;
--utrecht-button-primary-action-background-color: #005a5b;
--utrecht-button-primary-action-color: #fff;
--utrecht-button-primary-action-hover-background-color: #003f40;
--utrecht-button-primary-action-hover-color: #fff;
--utrecht-focus-outline-color: #111;
--utrecht-focus-outline-width: 3px;
--utrecht-focus-outline-offset: 3px;
--utrecht-focus-outline-style: solid;
}
*{box-sizing:border-box}body{margin:0}.example-theme{font:18px/1.6 Arial,sans-serif;color:#222;--accent:#005a5b;--wash:#eef6f4;--utrecht-data-list-rows-column-min-inline-size:12ch;--utrecht-data-list-rows-column-inline-size:45%;--utrecht-data-list-rows-gap:24px;--utrecht-data-list-rows-border-bottom-width:1px;--utrecht-data-list-rows-border-bottom-color:#ccd4d2;--utrecht-data-list-rows-item-padding-block-start:16px;--utrecht-data-list-rows-item-padding-block-end:16px;--utrecht-data-list-item-key-font-weight:700;--utrecht-data-list-item-value-line-height:1.6}.example-theme[data-theme=plum]{--accent:#57328c;--wash:#f5effa;--utrecht-button-primary-action-background-color:#57328c;--utrecht-button-primary-action-hover-background-color:#3c2262;--utrecht-button-border-radius:8px}.example-theme[data-theme=plum] h1{font-family:Georgia,serif}.toolbar{background:var(--wash);padding:20px 24px;border-bottom:4px solid var(--accent);display:flex;gap:16px;align-items:center;justify-content:space-between;flex-wrap:wrap}.toolbar label{font-size:16px}.toolbar select{font:inherit;max-width:100%;padding:8px}article{max-width:56rem;margin:auto;padding:32px 24px}h1{font-size:32px;line-height:1.3;margin:8px 0 24px}h2{font-size:24px}p{margin:16px 0}.utrecht-data-list__item-value{margin:0;overflow-wrap:anywhere}.utrecht-button{margin-block:8px}.editor{background:var(--wash);padding:24px;margin-block:24px}fieldset{border:0;padding:0;margin:0}legend{font-size:22px;font-weight:700;margin-bottom:16px}.choice{display:flex;align-items:center;gap:12px;padding:12px 0}.choice input{width:24px;height:24px;accent-color:var(--accent)}.buttons{display:flex;gap:24px;flex-wrap:wrap;align-items:center}.cancel{font:inherit;background:none;border:0;text-decoration:underline;min-height:48px;color:var(--accent);cursor:pointer}small{display:block;font-size:14px;margin-top:32px;color:#555}:focus-visible{outline:3px solid #111;outline-offset:3px}[hidden]{display:none!important}#notice{font-weight:700;color:var(--accent)}@media(max-width:600px){.example-theme{--utrecht-data-list-rows-column-min-inline-size:100%;}h1{font-size:28px}.toolbar{align-items:flex-start;flex-direction:column}.editor{padding:16px}}
</style><main class="example-theme" data-theme="teal"><div class="toolbar"><strong>Community collection · Example</strong><label>Original theme <select id="theme"><option value="teal">Teal</option><option value="plum">Plum</option></select></label></div><article><p>CONTRIBUTOR COMPONENTS + YOUR THEME</p><h1>Review your collection details</h1><p>This receipt uses Utrecht CSS components. Switching the theme changes public design tokens and preserves your choices.</p><dl class="utrecht-data-list utrecht-data-list--rows"><div class="utrecht-data-list__item"><dt class="utrecht-data-list__item-key">Item</dt><dd class="utrecht-data-list__item-value">Community reading pack</dd></div><div class="utrecht-data-list__item"><dt class="utrecht-data-list__item-key">Collection location</dt><dd class="utrecht-data-list__item-value" id="location">North library desk</dd></div><div class="utrecht-data-list__item"><dt class="utrecht-data-list__item-key">Reference</dt><dd class="utrecht-data-list__item-value">DEMO-2048</dd></div></dl><button id="edit" type="button" class="utrecht-button utrecht-button--primary-action">Change collection location</button><form class="editor" hidden><fieldset><legend>Choose a collection location</legend><label class="choice"><input type="radio" name="place" value="North library desk" checked>North library desk</label><label class="choice"><input type="radio" name="place" value="Riverside community room">Riverside community room</label><label class="choice"><input type="radio" name="place" value="Central welcome counter">Central welcome counter</label></fieldset><div class="buttons"><button class="utrecht-button utrecht-button--primary-action" type="submit">Save location</button><button type="button" class="cancel" id="cancel">Cancel</button></div></form><p id="notice" role="status"></p><small>Independent OpenDesign specimen. Utrecht CSS 9.0.15; original themes and fictional data. No municipal identity or external submission.</small></article></main><script>
const main=document.querySelector('main'),theme=document.querySelector('#theme'),edit=document.querySelector('#edit'),form=document.querySelector('form'),locationText=document.querySelector('#location'),notice=document.querySelector('#notice');let saved=locationText.textContent;theme.onchange=()=>main.dataset.theme=theme.value;edit.onclick=()=>{form.hidden=false;edit.hidden=true;notice.textContent='';[...form.elements.place].forEach(r=>r.checked=r.value===saved);form.querySelector(':checked').focus()};function close(){form.hidden=true;edit.hidden=false;edit.focus()}form.onsubmit=e=>{e.preventDefault();saved=form.elements.place.value;locationText.textContent=saved;notice.textContent='Collection location updated to '+saved+'.';close()};document.querySelector('#cancel').onclick=()=>{notice.textContent='No changes saved.';close()};
</script></html>
Scarica l’esempio completo dalla sezione Fonti. Il README indica il comando esatto per avviarlo in locale.
Mantieni i percorsi vendor relativi a questo documento; l’archivio include tutti gli asset usati da questa anteprima.
04
Configurazione dell’agente sistema di design NL
Punto di partenza per l’implementazione
L’anteprima autonoma carica localmente la stessa versione del pacchetto nativo CSS. I componenti pulsante/elenco di dati che usano solo CSS non richiedono un provider React. I valori originali del tema devono essere inclusi insieme alla libreria. Il file ZIP completo dell’esempio funzionante, disponibile in Sources, fornisce anche le dipendenze esatte dell’anteprima e il documento completo. Estrailo, esegui python3 -m http.server 8080 in quella directory, quindi apri http://localhost:8080/nl-design-system.html. Non aprire gli esempi basati su moduli tramite file://.
bash
npm install @utrecht/[email protected]
# CSS-aware application entry:
# import '@utrecht/component-library-css/dist/index.css';
# import './example-theme.css';
# Wrap the dl/button composition in <main class="example-theme">.
# Add application event handlers for editing and theme selection.
Un prompt per il tuo progetto
Prompt per l’agente
Usa @utrecht/component-library-css 9.0.15 per un elenco di definizioni per la ricevuta e un pulsante primario. Fornisci un tema originale, limitato al wrapper, tramite i token pubblici --utrecht-* e lascia inalterate le variabili interne --_utrecht-*. Consenti di modificare il luogo tramite opzioni radio etichettate, con funzioni di salvataggio e annullamento, annuncio non urgente dell’aggiornamento e ripristino dello stato attivo. Mostra un secondo tema originale senza sostituire il markup dei componenti o perdere i dati. Specifica che tutti i valori numerici del tema sono scelte dell’applicazione.
05
Fonti e ambito sistema di design NL
NL Design System è un ecosistema indipendente dai marchi. Questo esempio didattico seleziona l’implementazione di un contributore e due temi originali; non rivendica uno stile visivo nazionale e non usa l’identità di un comune.