Headless-Komponentensystem · Neue Ressource

Kobalte-Designsystem.

Kobalte stellt Headless-Komponenten für Solid bereit, darunter numerische Eingabefelder mit separaten Roh- und formatierten Werten, den Aufbau zusammengesetzter Checkboxen und Buttons mit gedrücktem Zustand. Dieser Leitfaden verbindet diese Grundelemente über einen Rezeptskalierer mit abgeleiteten Mengen und zurücksetzbaren Zutaten-Checkboxen mit Solid-Signals.

OpenDesign-Leitfaden9 Kapitel29 ReferenzeinträgeOriginaler Anwendungsleitfaden
01

Vorschau der Benutzeroberfläche des Kobalte-Designsystems

Passe die Zutatenmengen an, stelle die Zutaten zusammen und hefte ein eigenes Rezept lokal an.

Kobalte 0.13.14 mit Solid 1.9.15; native Headless-Primitiven und vollständiges Original-CSS. · Implementierungsreferenz
02

Designreferenz für das Kobalte-Designsystem

Kobalte 0.13.14 stellt Headless-Primitiven für Solid bereit, aber keine verbindliche visuelle Skala. Jede Farbe und Abmessung mit dem Präfix recipe-* gehört zur vollständigen ursprünglichen Anwendungskonfiguration. Die Namen und Zustandsattribute von API wurden anhand des installierten Pakets und der offiziellen Komponentendokumentation überprüft.

Ursprüngliche semantische Farben

Quelle
Name / RegelWert / KonfigurationVerwendung
--recipe-canvas#f6f2ec Äußerer Hintergrund
--recipe-surface#fffefa Rezept- und Portionsfelder
--recipe-ink#403a30 Primärtext
--recipe-muted#807465 Ergänzender Text
--recipe-line#e6ded2 Trennlinien und Rahmen
--recipe-action#95612f Ausgewählte Checkbox und Aktionstext
--recipe-on-action#fffVordergrund für ausgefüllte Aktionen
--recipe-focus#b88955 Sichtbarer Tastaturfokus
--recipe-soft#f1e4d3 Hintergrund für Schrittsteuerung und gedrückte Stecknadel

Ursprüngliche Typografie und Abmessungen

Quelle
Name / RegelWert / KonfigurationVerwendung
Bodysystem-ui, sans-serifKein Schriftarten-Download
Page heading34px / 1.15; 29px narrowUrsprüngliche Hierarchie
Recipe titleGeorgia, serif; 30px / 1.2Ursprünglicher redaktioneller Akzent
Ingredient copy13px / 1.5; 12px narrowGut lesbare, umgebrochene Beschriftungen
--recipe-space-1 / 2 / 34px / 8px / 12pxKleine Abstände
--recipe-space-4 / 6 / 816px / 24px / 32pxAbstände zwischen Feldern und Seite
Panel radius16pxUrsprüngliche Oberflächengeometrie
Checkbox control21 × 21px; 5px radiusUrsprünglicher sichtbarer Indikator
Stepper trigger42px wideNatives Auslöseelement mit ursprünglicher Geometrie
Layout breakpoint760pxZwei Spalten werden zu einer
Focus ring3px; 3px offsetUrsprüngliche sichtbare Tastaturfokusanzeige

Vertrag für native Komponentenstatus

Quelle
Name / RegelWert / KonfigurationVerwendung
NumberField.rawValuenumberArithmetischer Zustand statt formatiertem Text
NumberField.onRawValueChange(value: number) => voidAktualisiert Mengen und setzt veraltete Markierungen zurück
minValue / maxValue / step1 / 8 / 1Anwendungsgrenzen an das native Zahlenfeld übergeben
formatOptions.maximumFractionDigits0Anzeige ganzer Portionen
validationStatevalid | invalidAnwendungsgültigkeit im nativen Feld abbilden
Checkbox.checked / onChangeboolean / callbackKontrollierte Zutatenauswahl
Checkbox data attributesdata-checked; data-focus-visibleNative Zustände für Auswahl und Tastaturfokus gestalten
ToggleButton.pressed / onChangeboolean / callbackKontrolliertes lokales Anheften
ToggleButton data-pressedpresent when pressedGestaltung für angehefteten Zustand
03

Vollständiger Leitfaden zum Kobalte-Designsystem

Ein praktischer Leitfaden zur Auswahl, Anwendung und Überprüfung dieses Systems für ein echtes Interface.

DESIGN-kobalte.md

Umfassende Anleitung, Einstieg in die Implementierung und Links zu den Quellen.

Leitfaden herunterladen

Kobalte-Designsystem: Kobalte-Komponenten mit Solid Signals verbinden

Kobalte-Komponenten mit Solid Signals verbinden

Die Komponente verwendet Solid Signals für Portionen, zusammengestellte Zutaten und die Stecknadel. createMemo leitet die Gültigkeit aus dem numerischen Signal ab, und For rendert eine stabile Zutatenliste. Die kontrollierten Props von Kobalte greifen direkt auf diese Signals zu; für Aktualisierungen sind weder ein separater Form-Provider noch ein Zustandsadapter nach Art von React erforderlich.

Aus diesem OpenDesign-Leitfaden

NumberField, Checkbox und ToggleButton werden über ihre jeweiligen Komponenteneinstiegspunkte importiert. Sie erfüllen unterschiedliche Aufgaben: Das Zahlenfeld verarbeitet editierbare numerische Eingaben, jede Checkbox steht für eine zusammengestellte Zutat und der Toggle hält die Stecknadel für das Rezept. Die Rechen- und Invalidierungsregeln bleiben in Anwendungsfunktionen, statt in visuelle Selektoren eingebettet zu sein.

Unterstützende Spezifikation lesen

Kobalte-Designsystem: Numerischen Zustand und formatierten Text getrennt halten

Numerischen Zustand und formatierten Text getrennt halten

NumberField erhält rawValue={portions()} und onRawValueChange={update}. Das numerische Signal steuert die Multiplikation direkt, während die Eingabe die Formatierung und die Bearbeitung durch den Benutzer übernimmt. Würde formatierter Anzeigetext wieder in die Berechnung eingespeist, wären Annahmen zu Trennzeichen oder Gebietsschema nötig, die das native Primitiv bereits berücksichtigt.

Das Beispiel erlaubt eine bis acht ganze Portionen, mit einer Schrittweite von eins und maximumFractionDigits auf null gesetzt. Ein separates berechnetes Prädikat prüft zusätzlich Endlichkeit, Ganzzahligkeit und Grenzwerte, da ein bearbeitbares Feld vorübergehend einen unvollständigen oder ungültigen Wert enthalten kann. Solange der Wert ungültig ist, werden die Gesamtmengen als Gedankenstrich angezeigt und die Zutaten-Checkboxen deaktiviert. Die Benutzeroberfläche zeigt keine plausibel wirkende, aber falsche Menge an, als hätte der Benutzer einen gültigen Wert eingegeben.

Unterstützende Spezifikation lesen

Kobalte-Designsystem: Setze das Feld aus seinem nativen Label und seinen Meldungen zusammen

Das Feld aus seinem nativen Label und seinen Meldungen zusammensetzen

Das Zahlenfeld enthält Label, DecrementTrigger, Input, IncrementTrigger, Description und ErrorMessage. Die sichtbare Beschreibung erläutert sowohl den zulässigen Bereich als auch die Folgen einer Änderung der Portionszahl. Die Trigger haben aussagekräftige Beschriftungen: „Weniger Portionen“ und „Mehr Portionen“. Ihre symbolischen Minus- und Pluszeichen müssen daher nicht allein den vollständigen zugänglichen Namen vermitteln.

validationState wechselt anhand des Anwendungsprädikats zwischen valid und invalid. ErrorMessage gehört zu diesem nativen Feld und nicht in einen unabhängigen Absatz an anderer Stelle auf der Seite. Für ein Formular, das übermittelt wird, stellt Kobalte außerdem ein HiddenInput zur Serialisierung des Rohwerts bereit. Dieses lokale Beispiel enthält keines, da es weder einen Übermittlungsendpunkt noch eine Formular-Payload hat.

Unterstützende Spezifikation lesen

Kobalte-Designsystem: Speichere die Zutaten-Auswahl in einem unveränderlichen Set

Die Zutatenauswahl in einem unveränderlichen Set verwalten

Für jede Zutat kommt der vollständige Aufbau einer Checkbox zum Einsatz: Input, Control, Indicator und Label. Das echte Eingabeelement erhält Semantik und Tastaturbedienung, während das sichtbare Steuerelement das Häkchen und die ursprünglichen Zustandsstile übernimmt. Das Label enthält sowohl den Namen der Zutat als auch die Menge, sodass die benötigte Menge Teil des Eintrags ist, den der Leser zusammenstellt.

mark erstellt aus der vorherigen Auswahl ein neues Set, bevor eine ID hinzugefügt oder entfernt wird. Das vorhandene Set einfach zu verändern, würde kein ebenso zuverlässiges Signal-Update auslösen. Die angezeigte Anzahl liest die Größe des Sets aus, und jede Checkbox prüft anhand der stabilen Zutaten-ID, ob sie darin enthalten ist. Bei einer Änderung der Portionszahl wird die gesamte Auswahl aufgehoben, denn 320 Gramm zusammenzustellen bedeutet nicht, dass damit auch der neue Bedarf von 400 Gramm gedeckt ist.

  • Verknüpfe jeden sichtbaren Zutatenname mit Checkbox.Label.
  • Behalte Checkbox.Input bei, auch wenn das sichtbare Kästchen individuell gestaltet ist.
  • Verwende stabile IDs für die Auswahl und erstelle bei jeder Aktualisierung ein neues Set.

Unterstützende Spezifikation lesen

Kobalte-Designsystem: Verwende für eine dauerhaft gespeicherte lokale Auswahl einen Toggle

Für eine dauerhaft gespeicherte lokale Auswahl einen Toggle verwenden

Die Anheftfunktion ist ein ToggleButton mit pressed und onChange, kein gewöhnlicher Button, der lediglich seine Beschriftung ändert. Der pressed-Zustand wird in der nativen Semantik und im Selektor data-pressed abgebildet. Die Beschriftung ändert sich zu „Angeheftet“ mit einem Häkchen, und der Status daneben erklärt, dass dies nur die lokale Vorschau betrifft.

Das Anheften ändert weder die Zutatenmengen noch die Auswahl. Bei einer Änderung der Portionszahl werden die Zutaten-Checkboxen zurückgesetzt, die Anheftung bleibt jedoch bestehen, da das Rezept unverändert ist. „Standardrezept wiederherstellen“ setzt alle drei Zustandsbereiche gemeinsam zurück: vier Portionen, ein leeres Zutaten-Set und eine nicht gedrückte Anheftung. Diese unterschiedlichen Rücksetzregeln orientieren sich an der Bedeutung des jeweiligen Zustands, statt bei jeder Interaktion alles zu löschen.

Unterstützende Spezifikation lesen

Kobalte-Designsystem: Gib kopflosen Steuerelementen eine reproduzierbare visuelle Gestaltung

Headless-Steuerelementen eine reproduzierbare visuelle Konfiguration geben

Das Rezept-Stylesheet unterscheidet zwischen der Bearbeitungsfläche der numerischen Eingabe, den Stepper-Triggern und der Auswahlfunktion der Checkbox. Der gedämpfte Text der Zutaten wird erst nach dem Abhaken angewendet. Die Mengen bleiben lesbar, damit der Benutzer die zusammengestellte Menge weiterhin mit der aktuellen Portionszahl vergleichen kann.

Die Abstände betragen vier, acht, zwölf, sechzehn, vierundzwanzig und zweiunddreißig Pixel. Die ursprüngliche Typografie kombiniert eine serifenlose Systemschrift für Steuerelemente mit Georgia für den Rezepttitel. Neben einem einundzwanzig Pixel großen visuellen Kontrollkästchen steht ein vollständig zugehöriges Label; das Label bietet die praktischere Aktivierungsfläche. Diese genauen Werte sind im vollständigen CSS enthalten, damit sich das Beispiel ohne Rätselraten anhand eines Screenshots nachbilden lässt.

Unterstützende Spezifikation lesen

Kobalte-Designsystem: Verkleinere das Layout, ohne Informationen auszublenden

Verkleinere das Layout, ohne Informationen auszublenden

Im breiten Layout stehen sich eine flexible Rezeptkarte und ein 280 Pixel breites Portionsfeld gegenüber. Bei 760 Pixeln wird das Layout einspaltig. Die Überschrift der Karte kann umbrechen, Zutatenbeschriftungen können in eine weitere Zeile fließen und die Menge bleibt kompakt und untrennbar. Am kleinsten Breakpoint werden die Innenabstände des Felds und die Schrift der Beschriftungen leicht verkleinert, statt die Mengen auszublenden.

Die Salatillustration ist ein Original von CSS und als dekorativ gekennzeichnet. Rezeptname, Portionszahl und Zutatenmengen vermitteln die Bedeutung unabhängig von der Illustration. Achte darauf, dass die vollständigen Zutatenbeschriftungen und Mengen erhalten bleiben, wenn du die Illustration änderst oder die Karte schmaler machst; sie sind die eigentlichen Eingaben für die Aufgabe des Zusammenstellens.

Unterstützende Spezifikation lesen

Kobalte-Designsystem: Behandle Änderungen der Menge als Aktualisierung abhängiger Zustände

Mengenänderungen als Aktualisierung abhängiger Zustände behandeln

Jede Portion trägt insgesamt 250 Gramm zu den fünf Zutaten bei. Der Wechsel von vier auf fünf Portionen erhöht die angezeigte Gesamtmenge von 1.000 auf 1.250 Gramm und den Bedarf an Orangen von 320 auf 400 Gramm. Bereits abgehakte Zutaten werden zurückgesetzt, da sich die Auswahl auf die alten Mengen bezog. Die Anheftung des Rezepts bleibt unverändert, da es sich weiterhin um dasselbe Rezept handelt.

Die Aktualisierungsfunktion vergleicht den eingehenden Wert zunächst mithilfe von Object.is mit dem aktuellen Signalwert. Ein unveränderter Rückruf sollte weder die Checkliste zurücksetzen noch eine Mengenänderung ankündigen. Bei ungültigen Werten werden Mengen ausgeblendet und das Zusammenstellen deaktiviert; die Fehlermeldung erläutert dann den zulässigen Bereich. So lassen sich Zwischenschritte der Eingabe berücksichtigen, ohne dass eine ungültige Zahl eine irreführende Gesamtmenge ergibt.

  1. Wähle bei vier Portionen „Orangenspalten“ aus.
  2. Erhöhe die Portionszahl auf fünf und bestätige 400 g Orange, insgesamt 1.250 g und null zusammengestellte Zutaten.
  3. Pinne das Rezept an, setze dann die Standardwerte zurück und bestätige, dass der gesamte lokale Zustand zurückgesetzt wird.

Unterstützende Spezifikation lesen

Kobalte Designsystem: Solid-Build verwenden und das vollständige Stylesheet einbinden

Einen Solid-Build verwenden und das vollständige Stylesheet einbinden

Die Einrichtung verwendet das Vite-Solid-Template, legt die verifizierten Versionen von Solid und Kobalte fest und mountet die Anwendung in einem expliziten App-Root. Die oben gezeigte Komponente und das Stylesheet sind vollständige Dateien. Für dieses Beispiel sind weder ein Theme-Provider noch ein Icon-Paket, eine externe Schriftart oder ein Backend erforderlich.

Achte bei der Integration in eine andere Anwendung darauf, Framework-Compiler und Komponentengenerierung aufeinander abzustimmen. Ein React-Transform wandelt Solid JSX nicht in eine korrekte Kobalte-Anwendung um. Ebenso solltest du eine künftige Hauptversion von Kobalte API anhand der zugehörigen Dokumentation prüfen, bevor du die festgelegte Abhängigkeit ersetzt. Die Rezeptmengen und die Palette sind Beispieldaten der Anwendung. Sie lassen sich anpassen, ohne den Vertrag der nativen Primitive zu ändern.

Unterstützende Spezifikation lesen

Kobalte Designsystem-Komponentenbeispiele

Vollständige reaktive Rezeptkomponente

Natives Zahlenfeld, Checkbox-Aufbau und Umschaltfläche mit explizitem Verhalten bei ungültigen Eingaben und beim Zurücksetzen.

jsx
import {createSignal,createMemo,For} from 'solid-js';
import {NumberField} from '@kobalte/core/number-field';
import {Checkbox} from '@kobalte/core/checkbox';
import {ToggleButton} from '@kobalte/core/toggle-button';
export default function App(){
 const[portions,setPortions]=createSignal(4),[checked,setChecked]=createSignal(new Set()),[pinned,setPinned]=createSignal(false),[notice,setNotice]=createSignal('');
 const ingredients=[{id:'orange',name:'Orange segments',grams:80},{id:'beans',name:'Cooked white beans',grams:90},{id:'leaves',name:'Salad leaves',grams:25},{id:'fennel',name:'Thinly sliced fennel',grams:40},{id:'dressing',name:'Citrus dressing',grams:15}];
 const valid=createMemo(()=>Number.isFinite(portions())&&Number.isInteger(portions())&&portions()>=1&&portions()<=8);
 function update(value){if(Object.is(value,portions()))return;setPortions(value);setChecked(new Set());setNotice('Portions changed. Ingredient checks were cleared for the new quantities.')}
 function mark(id,value){setChecked(previous=>{const next=new Set(previous);value?next.add(id):next.delete(id);return next})}
 function reset(){setPortions(4);setChecked(new Set());setPinned(false);setNotice('Restored four portions and an unchecked ingredient list.')}
 return <main class="recipe-shell"><header><p class="eyebrow">KITCHEN NOTEBOOK · REACTIVE RECIPE CARD</p><h1>A brighter bowl, sized for your table.</h1><p>Change the portions, check the scaled ingredients and pin the recipe locally. The quantities are original sample data for this interface.</p></header><div class="recipe-layout"><section class="recipe-card"><div class="salad-art" aria-hidden="true"><div class="plate"><i/><b/><em/><span/><strong/></div></div><div class="recipe-heading"><div><p class="eyebrow">CITRUS & WHITE BEAN SALAD</p><h2>Fresh, crisp, generous.</h2></div><ToggleButton class="pin" pressed={pinned()} onChange={value=>{setPinned(value);setNotice(value?'Recipe pinned in this local preview.':'Recipe unpinned in this local preview.')}} aria-label="Pin recipe">{pinned()?'Pinned ✓':'Pin recipe'}</ToggleButton></div><p class="recipe-description">Sweet citrus, tender beans and crisp fennel. Use the checklist to gather the amounts for your chosen portion count.</p><div class="ingredient-title"><h3>Ingredients</h3><span>{checked().size} / 5 gathered</span></div><div class="ingredients"><For each={ingredients}>{ingredient=><Checkbox class="ingredient" checked={checked().has(ingredient.id)} onChange={value=>mark(ingredient.id,value)} disabled={!valid()}><Checkbox.Input/><Checkbox.Control class="check-control"><Checkbox.Indicator>✓</Checkbox.Indicator></Checkbox.Control><Checkbox.Label class="ingredient-label"><span>{ingredient.name}</span><strong>{valid()?ingredient.grams*portions()+' g':'—'}</strong></Checkbox.Label></Checkbox>}</For></div></section><aside class="portion-panel"><h2>Make it yours</h2><NumberField rawValue={portions()} onRawValueChange={update} minValue={1} maxValue={8} step={1} formatOptions={{maximumFractionDigits:0}} validationState={valid()?'valid':'invalid'} class="portion-field"><NumberField.Label class="field-label">Portions</NumberField.Label><div class="stepper"><NumberField.DecrementTrigger aria-label="Fewer portions">−</NumberField.DecrementTrigger><NumberField.Input/><NumberField.IncrementTrigger aria-label="More portions">+</NumberField.IncrementTrigger></div><NumberField.Description class="field-description">Choose 1–8 whole portions. Changing the quantity clears ingredient checks.</NumberField.Description><NumberField.ErrorMessage class="field-error">Enter a whole number from 1 to 8.</NumberField.ErrorMessage></NumberField><div class="portion-total"><span>Total ingredients</span><strong>{valid()?ingredients.reduce((s,x)=>s+x.grams,0)*portions()+' g':'—'}</strong></div><h3>A simple preparation order</h3><ol><li>Gather the scaled amounts and drain the cooked beans.</li><li>Combine the orange, fennel and leaves in a bowl.</li><li>Add the beans and dressing, then toss gently.</li></ol><button class="reset" onClick={reset}>Restore default recipe</button><p role="status" class="notice">{notice()||(pinned()?'Recipe pinned in this local preview.':'No shopping order or account update is created.')}</p></aside></div></main>
}

Code-Referenz

  • Verwende das Solid-Vite-Template, keinen React-JSX-Compiler.
  • rawValue enthält den numerischen Zustand; alle Zutatenmengen werden aus diesem Signal abgeleitet.
  • Beim Ändern der Portionen wird das Set der markierten Zutaten geleert, da die bisherigen Mengen nicht mehr aktuell sind.

Vollständige ursprüngliche visuelle Konfiguration

Semantische benutzerdefinierte Eigenschaften, typografische Hierarchie, Abstände, Zustandsformatierung und eine eigens erstellte CSS-Illustration.

css
:root{--recipe-canvas:#f6f2ec;--recipe-surface:#fffefa;--recipe-ink:#403a30;--recipe-muted:#807465;--recipe-line:#e6ded2;--recipe-action:#95612f;--recipe-on-action:#fff;--recipe-focus:#b88955;--recipe-soft:#f1e4d3;--recipe-space-1:4px;--recipe-space-2:8px;--recipe-space-3:12px;--recipe-space-4:16px;--recipe-space-6:24px;--recipe-space-8:32px}html,body,#app{height:auto;min-height:0;margin:0}*{box-sizing:border-box}body{font-family:system-ui,sans-serif;color:var(--recipe-ink);background:var(--recipe-canvas)}button,input{font:inherit}button{cursor:pointer}button:disabled{opacity:.4;cursor:default}button:focus-visible,input:focus-visible{outline:3px solid var(--recipe-focus);outline-offset:3px}.recipe-shell{max-width:1090px;margin:auto;padding:32px}.eyebrow{font-size:10px;font-weight:700;letter-spacing:.13em;color:var(--recipe-muted)}h1{font-size:34px;line-height:1.15;max-width:700px;margin:12px 0}header>p:last-child{font-size:14px;line-height:1.7;color:var(--recipe-muted);max-width:630px}.recipe-layout{display:grid;grid-template-columns:minmax(0,1fr) 280px;gap:24px;margin-top:28px}.recipe-card,.portion-panel{background:var(--recipe-surface);border:1px solid var(--recipe-line);border-radius:16px;padding:24px;min-width:0}.portion-panel{align-self:start}.salad-art{height:180px;background:#e8e4d5;border-radius:10px;position:relative;overflow:hidden;margin-bottom:24px}.plate{position:absolute;width:210px;height:210px;left:50%;top:18px;transform:translateX(-50%);border:18px solid #faf8f0;border-radius:50%;background:#dedcbf;box-shadow:0 10px 25px #5e584b1c}.plate i,.plate b,.plate em,.plate span,.plate strong{position:absolute;display:block}.plate i{width:85px;height:42px;border-radius:0 0 85px 85px;background:#dc9658;border:6px solid #f7c888;left:14px;top:18px;transform:rotate(-23deg)}.plate b{width:72px;height:36px;border-radius:0 0 72px 72px;background:#dc9658;border:6px solid #f7c888;left:75px;top:83px;transform:rotate(28deg)}.plate em{width:50px;height:77px;background:#83976a;border-radius:80% 0 80% 0;left:108px;top:4px;transform:rotate(20deg)}.plate span{width:30px;height:50px;background:#667f56;border-radius:80% 0 80% 0;left:25px;top:88px;transform:rotate(-23deg)}.plate strong{width:24px;height:34px;background:#fff3d7;border-radius:50%;left:80px;top:46px;box-shadow:-34px 14px 0 #fff3d7,25px 28px 0 #fff3d7}.recipe-heading{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap}.recipe-heading h2{font:400 30px/1.2 Georgia,serif;margin:8px 0}.pin{border:1px solid var(--recipe-line);background:white;border-radius:999px;padding:9px 13px;font-size:11px;color:var(--recipe-action)}.pin[data-pressed]{background:var(--recipe-soft);border-color:var(--recipe-action)}.recipe-description{font-size:13px;line-height:1.7;color:var(--recipe-muted)}.ingredient-title{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-top:24px}.ingredient-title h3{font-size:16px;margin:0}.ingredient-title span{font-size:11px;color:var(--recipe-muted)}.ingredients{margin-top:14px}.ingredient{display:flex;gap:12px;align-items:center;border-top:1px solid var(--recipe-line);padding:16px 0;cursor:pointer}.check-control{height:21px;width:21px;border:1px solid #b9ab98;border-radius:5px;flex-shrink:0;display:flex;justify-content:center;align-items:center;font-size:13px}.check-control[data-checked]{background:var(--recipe-action);color:white;border-color:var(--recipe-action)}.check-control[data-focus-visible]{outline:3px solid var(--recipe-focus);outline-offset:3px}.ingredient-label{display:flex;justify-content:space-between;gap:12px;width:100%;font-size:13px;line-height:1.5;cursor:pointer}.ingredient-label strong{white-space:nowrap;font-size:12px}.ingredient[data-checked] .ingredient-label>span{text-decoration:line-through;color:var(--recipe-muted)}.portion-panel>h2{font-size:20px;margin:0 0 24px}.field-label{font-size:13px;font-weight:600}.stepper{display:flex;margin-top:10px;border:1px solid var(--recipe-line);border-radius:8px;overflow:hidden}.stepper button{width:42px;flex-shrink:0;background:var(--recipe-soft);border:0;font-size:21px}.stepper input{width:100%;min-width:0;text-align:center;border:0;padding:12px 0;background:white;color:var(--recipe-ink)}.field-description{font-size:11px;line-height:1.7;color:var(--recipe-muted);margin:10px 0 0}.field-error{font-size:12px;color:#a73324}.portion-total{display:flex;justify-content:space-between;gap:12px;margin:24px 0;padding:18px 0;border-top:1px solid var(--recipe-line);border-bottom:1px solid var(--recipe-line);font-size:12px}.portion-total strong{font-size:19px;white-space:nowrap}.portion-panel h3{font-size:13px;line-height:1.6}.portion-panel ol{padding-left:18px;font-size:12px;line-height:1.7;color:var(--recipe-muted)}.portion-panel li{margin-bottom:12px}.reset{width:100%;padding:12px;border:1px solid var(--recipe-line);border-radius:8px;background:white;color:var(--recipe-action);font-size:12px;margin-top:16px}.notice{font-size:11px;line-height:1.7;color:var(--recipe-muted)}@media(max-width:760px){.recipe-layout{grid-template-columns:minmax(0,1fr)}.recipe-shell{padding:20px}h1{font-size:29px}}@media(max-width:360px){.recipe-shell{padding:14px}.recipe-card,.portion-panel{padding:16px}.ingredient-label{gap:8px;font-size:12px}.ingredient{gap:8px}.ingredient-label strong{font-size:11px}.recipe-heading h2{font-size:27px}}

Code-Referenz

  • Diese Werte mit dem Präfix recipe-* sind eigene Anwendungsentscheidungen, keine offiziellen Kobalte-Tokens.
  • Das vollständige Stylesheet umfasst ein responsives Layout und sichtbare Fokuszustände.
04

Kobalte Designsystem: Einrichtung des AI-Agenten

Ausgangspunkt für die Implementierung

Das Solid-Vite-Template stellt den erforderlichen Solid-JSX-Compiler bereit. Die vollständigen Beispiele für App.jsx und style.css oben enthalten den gesamten Anwendungscode und alle Stile. Ein Provider oder externer Dienst ist nicht erforderlich.

javascript
// npm create vite@latest kobalte-recipe -- --template solid
// cd kobalte-recipe && npm install
// npm install [email protected] @kobalte/[email protected]
// Save the complete examples as src/App.jsx and src/style.css.
// src/index.jsx:
import {render} from 'solid-js/web';
import App from './App.jsx';
import './style.css';
render(() => <App />, document.getElementById('app'));
// index.html: <div id="app"></div><script type="module" src="/src/index.jsx"></script>
// npm run dev

Ein Prompt für dein Projekt

Agenten-Prompt
Verwende Kobalte 0.13.14 mit Solid 1.9.15, um die reaktive Rezeptkarte nachzubilden. Behalte NumberField rawValue/onRawValueChange, die Grenzen von eins bis acht, die Validierung ganzer Portionen und den vollständigen Aufbau aus Label/Description/ErrorMessage bei. Leite Zutatenmengen in Gramm und Summen aus dem Portionssignal ab. Bei einer tatsächlichen Mengenänderung wird das unveränderliche Set markierter IDs geleert, die Rezept-Pin bleibt jedoch erhalten. Verwende die nativen Checkbox-Teile sowie ToggleButton pressed/onChange. Deaktiviere das Zusammenstellen, wenn die Menge ungültig ist, und setze beim Zurücksetzen vier Portionen, keine Markierungen und keinen Pin. Binde das vollständige Originalrezept CSS ein; der gesamte Zustand bleibt lokal.
05

Kobalte Designsystem: Quellen und Geltungsbereich

Verifiziert mit Kobalte 0.13.14 und Solid 1.9.15. Alle recipe-*-Tokens, die CSS-Illustration und die Zutatenmengen sind eigens erstellte Beispieldaten. Anpinnen und Zusammenstellen bleiben lokaler Zustand; es ist weder ein Konto noch ein Einkaufsdienst oder ein dauerhaft gespeicherter Rezeptbestand angebunden.