Untersuchen Sie Duets Farb- und Abstandsskalen von LocalTapiola anhand eines Datumsbereichsablaufs mit ISO-Datumswerten, expliziter Bereichsvalidierung, Fokusmethoden der Komponente und klar abgegrenztem Open-Source-Picker.
Offline-Interpretation von HTML mit nativen Datumseingabefeldern und geprüften Standardwerten des Duet-Themes; dies ist nicht die Duet-Kalenderlaufzeit. · Implementierungsreferenz
02
Designreferenz für Duet Designsystem
Snapshot der öffentlichen Duet-Dokumentation: Komponenten des Hauptsystems, LocalTapiola-Standardtokens und dokumentierte Integration mit 10.7.0/CDN. Dies ist nicht das separate Paket @duetds/date-picker 1.x. Einige Radius-Tokens sind weiterhin als In Review gekennzeichnet.
Duet Designsystem: Das Hauptsystem Duet und die Open-Source-Datumsauswahl sind getrennt
Den Paketvertrag beim Beispiel beibehalten
Duet stellt LocalTapiola und Turva thematisierte Komponenten und Grundlagen bereit. Das separat veröffentlichte Projekt @duetds/date-picker ist eine enger gefasste Open-Source-Distribution. Ein gemeinsamer Tag-Name macht die Eigenschaften, die Lokalisierungseinrichtung oder die CSS-Variablen nicht mit dem aktuellen Hauptdesignsystem austauschbar.
Der Integrationscode auf dieser Seite zielt auf das Hauptsystem. Die Offline-Vorschau verwendet native Datumseingabefelder und ein eigens gestaltetes Styling auf Grundlage der verlinkten Duet-Tokens. Sie veranschaulicht Regeln für Zeiträume, ohne vorzugeben, das Kalender-Popup oder das Tastaturmodell von Duet auszuführen.
Markenblau und Statusrot von Duet Designsystem haben unterschiedliche Aufgaben
Ein Theme verwenden, statt nur eine Akzentfarbe auszutauschen
Das LocalTapiola-Standardtheme kombiniert eine blaue Aktion mit dunkelblauem Fließtext. Turva hat eine eigene rote Aktionsfarbe und eine sekundäre Textrolle. Nur die Aktionsfarbe zu ändern, würde die übrigen Theme-Beziehungen außer Acht lassen. In der aktuellen Tabelle sind außerdem ältere Turva-Tönungen als veraltet gekennzeichnet. Alle historischen Paletteeinträge zu übernehmen, würde veraltete Vorgaben beibehalten.
Unser eigenständiges Beispiel für Reisedaten verwendet Blau für die nächste Aktion und Rot nur dann, wenn ein ausgewählter Zeitraum korrigiert werden muss. Es dient der Veranschaulichung einer Terminplanung und ist weder eine Versicherungsempfehlung noch ein Angebot oder Kauf.
Ein Fließtextwert von 16 px verankert die Hierarchie von Duet Designsystem
Die Typografieskala verlangt nicht überall eine übergroße Überschrift
Die Tabelle von Duet steigt auf den größeren Stufen in 16, 20, 24, 36, 48 und 72 px an. Ein eingebettetes Planungsfeld nutzt die 24-px-Stufe, damit Aktions- und Datumsbeschriftungen gut sichtbar bleiben. Die für Marketing vorgesehene 72-px-Stufe ist keine Standardgröße für ein kompaktes Formular.
Die Schriftpakete von LocalTapiola und Turva sind separate Ressourcen. Die Offline-Umsetzung verwendet eine Systemersatzschrift und enthält diese Markenschriftdateien nicht. Eine autorisierte Anwendung sollte die gewählte Schriftfamilie über den dokumentierten Schriftpfad laden und anschließend die dazugehörigen Schriftschnitt-Tokens verwenden.
Duet Designsystem Die tatsächlichen 20-px- und 28-px-Stufen verwenden
Duet verwendet keine generische Acht-Pixel-Skala
Zusätzlich zu den bekannten Zweierpotenzen umfasst die Skala auch 12, 20, 28 und 36 px. Diese Zwischenabstände sind wichtig, um den Formularrhythmus des Systems nachzubilden. Verwenden Sie im breiten Layout einen Abstand von 20 px zwischen den beiden Feldern und ordnen Sie beim Stapeln jedes Label weiterhin seinem Feld zu. Der Breakpoint des Beispiels ist eine Entscheidung auf Anwendungsebene.
Standard-Steuerelemente haben abgerundete Ecken mit 4 px, während Schaltflächen den Pillenradius verwenden. Einige neuere Werte für den Radius von Containern sind in der Token-Referenz ausdrücklich als „In Prüfung“ gekennzeichnet. Dieser Leitfaden übernimmt diesen Status, statt alle aufgeführten Tokens als freigegeben darzustellen.
Duet Designsystem ISO-Werte speichern und das sichtbare Format beschreiben
Lokalisierte Anzeigewerte nicht als Daten parsen
Der Wert und die Grenzen der Komponente verwenden das Format YYYY-MM-DD. Das Ereignis für ein ausgewähltes Datum enthält sowohl eine Zeichenfolge als auch ein Date-Objekt. Verwenden Sie die Zeichenfolge für Vergleiche und zum Speichern; die lokalisierte Anzeige im Feld ist eine Frage der Darstellung. Die Dokumentsprache ist der aktuelle Einstiegspunkt für die Lokalisierung, während die frühere Spracheigenschaft veraltet ist.
Das Beispiel lässt nur Datumsangaben im Juni 2027 zu. Dieses feste Intervall ermöglicht reproduzierbare Tests und ist klar als Einschränkung des Beispiels gekennzeichnet. In einem produktiven Formular würde das zulässige Intervall aus den Produktregeln abgeleitet und neben dem Feld erläutert.
Duet Designsystem Ein gültiges Datum bedeutet nicht zwangsläufig einen gültigen Zeitraum
Die Beziehung zwischen den Feldern prüfen, sobald beide gültig sind
Das Validitätsobjekt der Komponente beschreibt einzelne Feldfehler. Ein Rückreisedatum, das vor dem Abreisedatum liegt, kann trotzdem ein gültiges Kalenderdatum sein; daher muss die Anwendung die beiden Werte separat prüfen. Das native Beispiel weist einen eindeutigen Fehler zu und verwendet setFocus(), die dokumentierte Methode, mit der das innere Eingabefeld fokussiert wird.
Die Anzahl ist einschließlich beider Tage berechnet: Bei Abreise und Rückreise am selben Tag ergibt sich ein Kalendertag. Werden ISO-Daten um Mitternacht UTC umgerechnet, wird verhindert, dass eine Umstellung auf Sommerzeit ein Kalenderintervall in eine gebrochene Dauer verwandelt. Diese Berechnung ist eigene Anwendungslogik und keine Preisregel von Duet.
Fehlende, fehlerhafte oder außerhalb der Grenzen liegende Endpunkte zurückweisen.
Eine Rückreise vor der Abreise zurückweisen.
Den Fokus auf das Feld setzen, das korrigiert werden muss.
Den einschließlich berechneten Zeitraum erst vorbereiten, nachdem beide Prüfungen bestanden wurden.
Duet Designsystem Eine primäre Aktion bedeutet nicht automatisch, dass das Formular abgeschickt wird
Duet verwendet eine explizite submit-Eigenschaft
Die Schaltfläche im Hauptsystem aktiviert das Absenden des Formulars ausdrücklich über submit; standardmäßig ist der Wert false. Die bereitgestellte Komposition verwendet eine Klickaktion, die ein lokales Ergebnis vorbereitet, und benötigt diese Eigenschaft daher nicht. Ein Ziel gehört in url, wodurch ein Link erzeugt wird.
Die Vorschau löscht die vorbereitete Meldung, sobald sich eines der Eingabefelder ändert. Andernfalls könnte die Meldung scheinbar Werte bestätigen, die die Person bereits geändert hat. Es wird kein Ladeindikator angezeigt, da kein asynchroner Vorgang stattfindet.
Eine einzige primäre Vorbereitungsaktion verwenden.
Darauf hinweisen, dass das Ergebnis lokal ist.
Erfolgsmeldungen nicht wiederverwenden, um den Eindruck zu erwecken, es sei eine Police erstellt worden.
Duet Designsystem Die Ressourcen des Hauptsystems als kompatiblen Satz festlegen
Das Beispiel ist eine dokumentierte Momentaufnahme und keine Zusage für die neueste Version
Die geprüfte Nutzungsseite enthält Komponenten 10.7.0 mit CSS 5.1.4; Momentaufnahmen des Suchindex verweisen bereits auf spätere Versionen. Das Beispiel verwendet bewusst das direkt geprüfte Versionspaar. Wählen Sie für den produktiven Einsatz eine Version aus und überprüfen Sie, ob das passende CSS, die Schriftarten und das Verhalten der Komponenten dazu passen.
Die Datumsfelder sind benutzerdefinierte Elemente. Warten Sie vor Methodenaufrufen auf ihre Definition, fügen Sie Listener für duetChange hinzu und lesen Sie die dokumentierte Nutzlast aus, statt ein natives change-Ereignis vorauszusetzen. Verwenden Sie das CDN-Modul des Hauptsystems nicht zusammen mit dem eigenständigen Date Picker auf derselben Seite: Beide definieren dasselbe Tag.
Duet Designsystem Beispiele für Duet-Design-System-Komponenten
Vollständige, eigenständige interaktive Demo
Speichern Sie das vollständige Dokument als index.html und öffnen Sie es in einem Browser. Offline-Interpretation von HTML mit nativen Datumseingabefeldern und geprüften Standardwerten des Duet-Themes; dies ist nicht die Duet-Kalenderlaufzeit.
html
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Duet travel period interpretation</title><style>*{box-sizing:border-box}body{margin:0;background:#f0f7fa;color:#082a4d;font:16px/1.5 system-ui,sans-serif}main{max-width:1000px;margin:auto;padding:36px 28px}.eyebrow{font-size:12px;letter-spacing:2px;text-transform:uppercase;margin-bottom:12px}h1{font-size:36px;line-height:1.2;font-weight:600;margin:0 0 20px}p{margin:0 0 20px}.hero{display:grid;grid-template-columns:1fr 300px;gap:28px;align-items:center;margin-bottom:28px}.art{height:170px;position:relative;overflow:hidden;border-radius:50%;background:#c6e1ee}.sun{position:absolute;top:25px;right:60px;width:36px;height:36px;border-radius:50%;background:white}.hill{position:absolute;background:#0077b3;width:210px;height:170px;bottom:-95px;left:-10px;transform:rotate(25deg);border-radius:24px}.hill.two{left:135px;background:#00619b;bottom:-110px;transform:rotate(-25deg)}.road{position:absolute;width:150px;height:200px;border:12px solid white;border-radius:50%;top:65px;left:95px;transform:rotate(25deg)}.card{background:white;border-radius:4px;padding:28px;box-shadow:0 2px 8px #082a4d0d;display:grid;grid-template-columns:1fr 230px;gap:28px}h2{font-size:24px;line-height:1.3;margin:0 0 20px}.fields{display:grid;grid-template-columns:1fr 1fr;gap:20px}label{display:block;font-weight:600;margin-bottom:8px}input{width:100%;max-width:100%;min-width:0;border:1px solid #909599;border-radius:4px;font:inherit;color:inherit;padding:12px;background:white}input[aria-invalid=true]{border-color:#d61c52}button{background:#0077b3;color:white;border:0;border-radius:20rem;padding:12px 36px;font:600 16px/1.5 system-ui;cursor:pointer}button:hover{background:#004b81}button:focus-visible,input:focus-visible{outline:3px solid #082a4d;outline-offset:3px}.error{font-size:14px;color:#d61c52;min-height:24px;margin:8px 0 20px}.calendar{background:#f0f7fa;border-radius:4px;padding:20px}.calendar strong{display:block;margin-bottom:12px}.grid{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;font-size:12px;text-align:center}.grid span{padding:3px 0}.grid .in-range{background:#c6e1ee}.grid .endpoint{background:#0077b3;color:white;border-radius:50%}.caption{font-size:12px;margin:12px 0 0}.result{margin-top:20px;background:#e4f1f7;padding:20px;border-radius:4px}.result:empty{display:none}.boundary{font-size:12px;margin-top:28px}.hint{font-size:14px}@media(max-width:650px){main{padding:24px 16px}.hero{grid-template-columns:1fr}.art{display:none}h1{font-size:28px}.card{grid-template-columns:1fr;padding:20px}.fields{grid-template-columns:1fr;gap:16px}.calendar{max-width:300px;width:100%}button{width:100%;padding:12px 20px}}
</style><main><div class="hero"><div><div class="eyebrow">Travel period planner</div><h1>Make time for a change of scenery.</h1><p>Choose a departure and return date to explore an inclusive calendar-day count.</p></div><div class="art" aria-hidden="true"><div class="sun"></div><div class="hill"></div><div class="hill two"></div><div class="road"></div></div></div><div class="card"><section><h2>When will you travel?</h2><p class="hint" id="hint">Use dates from 1–30 June 2027. This fixed month is for demonstration.</p><form novalidate><div class="fields"><div><label for="start">Departure</label><input id="start" type="date" min="2027-06-01" max="2027-06-30" value="2027-06-10" required aria-describedby="hint error"></div><div><label for="end">Return</label><input id="end" type="date" min="2027-06-01" max="2027-06-30" value="2027-06-17" required aria-describedby="hint error"></div></div><div class="error" id="error" role="alert"></div><button type="submit">Prepare date range</button></form></section><aside class="calendar"><strong>June 2027</strong><div class="grid" id="calendar" aria-hidden="true"></div><p class="caption" id="range-caption">10–17 June selected</p></aside></div><div class="result" id="result" role="status"></div><p class="boundary">Independent HTML interpretation of Duet tokens with native date fields. The calendar image is a non-interactive range overview. No insurance quote, booking or policy is created.</p></main><script>const start=document.querySelector('#start'),end=document.querySelector('#end'),result=document.querySelector('#result'),error=document.querySelector('#error');function valid(){return start.validity.valid&&end.validity.valid&&start.value&&end.value&&end.value>=start.value}function draw(){let days=['M','T','W','T','F','S','S'].map(d=>'<span>'+d+'</span>').join('')+'<span></span>';for(let i=1;i<=30;i++){let iso='2027-06-'+String(i).padStart(2,'0'),range=valid()&&iso>=start.value&&iso<=end.value,edge=range&&(iso===start.value||iso===end.value);days+='<span class="'+(edge?'endpoint':range?'in-range':'')+'">'+i+'</span>'}document.querySelector('#calendar').innerHTML=days;document.querySelector('#range-caption').textContent=valid()?start.value+' to '+end.value:'Choose a valid range to highlight it.'}function changed(){result.textContent='';error.textContent='';start.removeAttribute('aria-invalid');end.removeAttribute('aria-invalid');draw()}[start,end].forEach(el=>el.oninput=changed);document.querySelector('form').onsubmit=e=>{e.preventDefault();let bad;if(!start.value||!start.validity.valid){error.textContent='Choose a departure date in June 2027.';bad=start}else if(!end.value||!end.validity.valid){error.textContent='Choose a return date in June 2027.';bad=end}else if(end.value<start.value){error.textContent='Return must be on or after departure.';bad=end}if(bad){bad.setAttribute('aria-invalid','true');bad.focus();result.textContent='';return}const days=(Date.parse(end.value+'T00:00:00Z')-Date.parse(start.value+'T00:00:00Z'))/86400000+1;result.textContent=days+' calendar '+(days===1?'day':'days')+', including departure and return. Local draft: '+start.value+' to '+end.value+'. No policy created.'};draw();</script></html>
Dieses Dokument verwendet native Datumseingaben des Browsers. Das separate Duet-Beispiel nutzt den Date Picker des Hauptsystems und darf nicht mit dem eigenständigen Open-Source-Paket für den Date Picker verwechselt werden.
Ein Paar Date Picker des Hauptsystems validieren
Zwei beschriftete Felder, begrenzte Datumsangaben im Juni, chronologisch geordnete Endpunkte, Fokus auf den ungültigen Date Picker und eine einschließlich berechnete Anzahl von Tagen.
html
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Date range draft</title>
<link rel="stylesheet" href="https://cdn.duetds.com/api/css/5.1.4/lib/duet.min.css">
<script type="module" src="https://cdn.duetds.com/api/components/10.7.0/lib/duet/duet.esm.js"></script>
<style>main{max-width:680px;margin:auto;padding:28px}.range{display:grid;grid-template-columns:1fr 1fr;gap:20px}@media(max-width:576px){.range{grid-template-columns:1fr}}</style>
<main><h1>Choose a travel period</h1><p>Demonstration only. No insurance is quoted or purchased.</p><div class="range">
<duet-date-picker id="start" label="Departure" required expand value="2027-06-10" min="2027-06-01" max="2027-06-30"></duet-date-picker>
<duet-date-picker id="end" label="Return" required expand value="2027-06-17" min="2027-06-01" max="2027-06-30"></duet-date-picker></div>
<duet-button id="prepare" variation="primary">Prepare date range</duet-button>
<p id="result" role="status"></p></main><script type="module">
await customElements.whenDefined('duet-date-picker');
const start=document.querySelector('#start'),end=document.querySelector('#end'),result=document.querySelector('#result');
function error(picker){const v=picker.validity;if(!picker.value)return 'Choose a date.';if(v&&!v.valid)return 'Choose a valid date in June 2027.';return '';}
function validate(){start.error=error(start);end.error=error(end);if(!start.error&&!end.error&&end.value<start.value)end.error='Return must be on or after departure.';return !start.error&&!end.error;}
[start,end].forEach(p=>p.addEventListener('duetChange',()=>{result.textContent='';validate()}));
document.querySelector('#prepare').addEventListener('click',async()=>{if(!validate()){await(start.error?start:end).setFocus();return;}const a=Date.parse(start.value+'T00:00:00Z'),b=Date.parse(end.value+'T00:00:00Z');result.textContent=`Local range: ${start.value} to ${end.value}, ${(b-a)/86400000+1} calendar days inclusive. No policy created.`;});
</script></html>
Dieses Beispiel verwendet @duetds/components über das CDN des Hauptsystems, nicht @duetds/date-picker 1.x.
Zeiträume am selben Tag umfassen einen Kalendertag einschließlich beider Endpunkte.
Die UTC-Berechnung vermeidet Abweichungen durch die Sommerzeit bei der Tageszählung.
04
Duet Designsystem AI-Agent einrichten
Ausgangspunkt für die Implementierung
Vollständige Komposition über das CDN des Hauptsystems, mit den Versionen, die ausdrücklich auf der geprüften Integrationsseite angegeben sind. Öffentliche Suchmomentaufnahmen zeigen auch neuere Versionen; legen Sie eine kompatible Version fest, statt anzunehmen, dass dies die neueste ist. Schriftarten werden hier nicht weitergegeben.
html
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Date range draft</title>
<link rel="stylesheet" href="https://cdn.duetds.com/api/css/5.1.4/lib/duet.min.css">
<script type="module" src="https://cdn.duetds.com/api/components/10.7.0/lib/duet/duet.esm.js"></script>
<style>main{max-width:680px;margin:auto;padding:28px}.range{display:grid;grid-template-columns:1fr 1fr;gap:20px}@media(max-width:576px){.range{grid-template-columns:1fr}}</style>
<main><h1>Choose a travel period</h1><p>Demonstration only. No insurance is quoted or purchased.</p><div class="range">
<duet-date-picker id="start" label="Departure" required expand value="2027-06-10" min="2027-06-01" max="2027-06-30"></duet-date-picker>
<duet-date-picker id="end" label="Return" required expand value="2027-06-17" min="2027-06-01" max="2027-06-30"></duet-date-picker></div>
<duet-button id="prepare" variation="primary">Prepare date range</duet-button>
<p id="result" role="status"></p></main><script type="module">
await customElements.whenDefined('duet-date-picker');
const start=document.querySelector('#start'),end=document.querySelector('#end'),result=document.querySelector('#result');
function error(picker){const v=picker.validity;if(!picker.value)return 'Choose a date.';if(v&&!v.valid)return 'Choose a valid date in June 2027.';return '';}
function validate(){start.error=error(start);end.error=error(end);if(!start.error&&!end.error&&end.value<start.value)end.error='Return must be on or after departure.';return !start.error&&!end.error;}
[start,end].forEach(p=>p.addEventListener('duetChange',()=>{result.textContent='';validate()}));
document.querySelector('#prepare').addEventListener('click',async()=>{if(!validate()){await(start.error?start:end).setFocus();return;}const a=Date.parse(start.value+'T00:00:00Z'),b=Date.parse(end.value+'T00:00:00Z');result.textContent=`Local range: ${start.value} to ${end.value}, ${(b-a)/86400000+1} calendar days inclusive. No policy created.`;});
</script></html>
Ein Prompt für dein Projekt
Agenten-Prompt
Erstellen Sie einen Datumszeitraum mit dem Duet-Hauptsystem und zwei beschrifteten Date Pickern, ISO-Werten und Validitätsprüfungen. Prüfen Sie die Reihenfolge der Endpunkte separat, rufen Sie bei Fehlern setFocus auf und verwenden Sie eine ausdrücklich festgelegte primäre Aktion zur lokalen Vorbereitung. Binden Sie das eigenständige Picker-Paket nicht auf derselben Seite ein.
05
Duet Designsystem Quellen und Geltungsbereich
Unabhängige Referenz von OpenDesign. Eigenständiger Planer; es wird keine Police, Buchung oder kein Angebot erstellt. Das Duet-Hauptsystem und sein separates Open-Source-Paket für den Date Picker haben unterschiedliche Verträge.