Kay ist Softwareentwicklerin in einem großen Industriekonzern, der mittlerweile einen erheblichen Anteil seines Umsatzes durch den Verkauf von Hardware-begleitenden Anwendungen macht. Sie arbeitet in einem von vielen Teams an einem konkreten Produkt zur Unterstützung ihrer Kunden. Der Konzern ist weltbekannt und besticht nicht nur durch die allseits bekannte Unternehmensidentität, die sich im Design der Webseite, Anwendungen und Maschinen wiederfindet, sondern auch durch seine durchgängig exzellente Qualität und Bedienbarkeit der gesamten Produktpalette.
Unter anderem aus diesem Grund ist es eines der wichtigsten Ziele, dass die Projektteams (wie das von Kay) Anwendungen entwickeln können, die sowohl in ihrem Erscheinungsbild als auch in der Benutzerfreundlichkeit einheitlich und hochwertig sind. Damit dies erreicht werden kann, wurde ein Team ins Leben gerufen, dass aus diesen Eigenschaften heraus ein sogenanntes Design-System konzipiert, entwickelt und kontinuierlich wartet.
Kurzer Überblick: Design-Systeme
Ein Design-System ist ein sich ständig weiterentwickelndes Produkt, welches von unterschiedlichsten Interessenvertreter:innen befüllt und benutzt wird. In unserem Kontext möchten wir es als eine Kombination aus nutzerorientierter, interaktiver Dokumentation und einsetzbaren Software-Bestandteilen sehen. Es enthält textuelle und interaktiv erfahrbare Beschreibungen zu generellen Anforderungen bezüglich des Erscheinungsbildes und der User Experience (UX) der Anwendungen, was man häufig auch als Style-Guide bezeichnet.
Darüber hinaus beinhaltet das System einen Satz von wiederverwendbaren Bedienelementen, Layouts und unternehmensweit gültiger Primitiven (wie Icons, Schriftarten, festgelegten Maßeinheiten etc.), die den Anwendungsentwickler:innen (wie Kay) als Bibliothek zur Verfügung gestellt werden. Diesen Bestandteil möchten wir Komponentenbibliothek nennen.
Style-Guide und Komponentenbibliothek beeinflussen sich gegenseitig: Zum Beispiel folgen die Komponenten in der Software-Bibliothek den UX-Vorgaben aus dem Style-Guide, dieser enthält wiederum Sammlungen von typische Einsatzszenarien und Anwendungsmustern für die Software-Komponenten. Bestandteil des Design-Systems sind dabei auch Prozesse und Werkzeuge, die allen Beteiligten den Zugang zum und den Einsatz des Systems ermöglichen und vereinfachen. Mit dem System interagieren die verschiedenste Personen, wie z.B. die Geschäftsleitung, das Marketing, Projektleiter:innen, Product Owner:innen, Entwickler:innen und natürlich auch die Endnutzer:innen.
In diesem Artikel schauen wir uns an, wie wir ein solches Design-System aus software-technischer Sicht mit Hilfe von Storybook.js realisieren können. Notwendige Anforderungen an Unternehmensprozesse und wie die dem Design-System zugrundeliegenden Informationen überhaupt erfasst werden können, können wir andeuten, aber nicht in aller Tiefe behandeln.
Storybook.js
Storybook ist zunächst ein Open-Source-Tool für die isolierte Entwicklung von UI-Komponenten und Seiten. Es vereinfacht das Erstellen, Dokumentieren und Testen von Benutzeroberflächen.
In einem ersten Schritt schauen wir uns an, wie wir mit Storybook ein Bedienelement in Isolation entwickeln und ausprobieren können (ohne direkt eine lauffähige Gesamt-Applikation zu benötigen). Komponenten, die wir auf diese Art entwickeln, können wir später unseren Anwendungsentwicklern:innen wie Kay über eine Bibliothek zum Einsatz im Projektkontext bereitstellen.
Während Storybook die meisten modernen Frameworks offiziell (und durch Mithilfe der Community inoffiziell) unterstützt, nehmen wir an, dass sich unser Softwarekonzern momentan auf React als Framework festgelegt hat. Folgende Beispiele nutzen dies als Implementierungsgrundlage. Die dahinterliegenden Konzepte, gerade in Bezug auf Storybook mit dem Ziel ein Design-System aufzubauen, sind übertragbar, z.B. auch auf Angular oder Vue.
Ein wiederverwendbares Bedienelement
Nehmen wir an, das Design-System unseres Konzerns hört auf den Namen PunzeUI. Als ein mögliches Bedienelement dieses Systems und im Folgenden als Beispiel betrachten wir einen Expander (oft auch Accordion oder Collapsible Container genannt).
Der Expander dient dazu, nicht jederzeit relevante Informationen auf der Benutzeroberfläche zu verstecken, zugänglich zu lassen und nur bei Bedarf sichtbar zu machen. Er hat demnach die zwei Zustände “Eingeklappt” und “Ausgeklappt”. Im eingeklappten Zustand verhält sich das Element ähnlich einem Button. Wird er betätigt, wird der Inhalt sichtbar und der Expander klappt sich aus. Als Inhalt soll beliebiger andere Inhalt übergeben werden können. Wurde kein Inhalt übergeben, kann der Expander nicht aufgeklappt werden. Das Control hat folgende konfigurierbare Eigenschaften:
- Titel: zur Anzeige eines Textes im Expander-Button
- Icon (optional): zur Anzeige eines Icons als Zusatz vor dem Titel
- Disabled (optional): gibt an, ob mit dem Expander interagiert werden kann
Neben den konzeptionellen Anforderungen (siehe folgende Abbildung) bekommen wir vom Marketing und der Design-Abteilung visuelle Vorgaben gemäß der Unternehmensidentität, u.a. mit Festlegungen zu Schriftart, Farbgebung, Abständen, Animationen und deren verschiedenen Belegungen in den unterschiedlichen Zuständen des Controls (siehe folgende Abbildung).
Aufgabe der Framework-Entwicklung wäre es nun, diese konzeptionellen und visuellen Vorgaben umzusetzen und das Bedienelement samt Dokumentation in einer Komponentenbibliothek für die Anwendungsentwicklung zur Verfügung zu stellen. Die konkreten Implementierungsdetails lassen wir außen vor, möchten an dieser Stelle aber darauf eingehen, wie wir Storybook nutzen können, um den Expander unabhängig von einer Anwendung entwickeln und die an ihn gestellten Anforderungen erfüllen können.
Installation von Storybook
Als Basis dient uns eine über Create-React-App erstellte TypeScript-React-Applikation namens PunzeUI:
npx create-react-app punze-ui --template typescript
Mit Start der Applikation über npm start
erscheint nur das übliche React-Beispielprogramm. Da wir keine echte Applikation benötigen, kann dies auch so bleiben, denn wir wollen dem Projekt nun Storybook hinzufügen. Hierfür reicht der folgende Aufruf, der in gängigen Projekten alle erforderlichen Konfigurationen für uns übernimmt:
npx sb init
Hierbei wird Storybook als Abhängigkeit hinzugefügt, alle React-spezifischen Einstellungen vorgenommen und ein paar Storybook-Beispieldateien bereitgestellt. Anschließend kann Storybook über npm run storybook
gestartet werden. Da wir die aktuellen Beispiele nicht benötigen, können wir sie entfernen oder einfach ignorieren.
Bevor wir mit der eigentlichen Umsetzung des Expanders beginnen, treffen wir noch zwei Vorkehrungen, um Roboto als Schriftart und FontAwesome als Icon-Bibliothek verwenden zu können. Da Storybook einer alleinstehenden Anwendung ähnelt, sind dies anwendungsspezifische Anpassungen, die beispielsweise auch Kay in ihrem Anwendungsprojekt vornehmen müsste. Es ist ein wichtiges technisches Detail, das auch im Rahmen der Dokumentation zur Komponentenbibliothek interessant sein könnte.
Um die Schriftart einzubinden, erstellen wir die Datei preview-head.html
im Ordner .storybook/
, welche beim Start von Storybook dem HTML-Kopf hinzugefügt wird (siehe folgendes Code-Beispiel).
Um FontAwesome einzubinden, folgen wir der Installationsanweisung zu React und führen den folgenden Befehl aus:
npm i --save @fortawesome/fontawesome-svg-core @fortawesome/free-solid-svg-icons @fortawesome/react-fontawesome
Schließlich aktivieren wir noch eines der Icon-Pakete global (siehe folgendes Code-Beispiel) in der Datei .storybook/preview.js
.
Control-Implementierung mit Hilfe von Storybook
Nach der initialen Vorbereitung können wir nun unsere Bedienelemente der Komponentenbibliothek hinzufügen und beginnen mit dem oben beschriebenen Expander. Wir nutzen Storybook, um die Anforderungen an diesen in Form von sogenannten Stories zu definieren und entlang derer unser Control zu implementieren. Eine Story beschreibt dabei einen bestimmten Zustand (der alleinstehend interessant ist) unseres Expanders. Eine Story kann dabei konfigurierbar gestaltet werden, sodass man auch durch wenige Stories komplexe Zustände eines Elements interaktiv herstellen kann. Stories können auch sehr starr und an konkreten Szenarien orientiert sein.
Zunächst erstellen wir unter src/components/Expander/Expander.tsx
eine leere Hülle für unser Control (Code-Beispiel 3), sodass wir es gleich einbinden können.
Parallel zu jeder Komponente in unserer Bibliothek legen wir jeweils eine Story-Datei an, in diesem Fall src/components/Expander/Expander.stories.tsx
. Storybook geht standardmäßig von genau dieser Namensendung aus (.storybook\main.js
).
Füllen wir nun diese Datei mit erstem Inhalt, sollte der Expander in Storybook sichtbar werden (folgendes Code-Beispiel, folgende Abbildung).
Im default export
definieren wir, auf welches Bedienelement diese Story ausgelegt ist und wie sie in der Baumansicht eingeordnet werden soll. Aktuell haben wir nur eine einzige Story namens Standard umgesetzt und stellen mit ihr unseren Expander dar. In dieser Form definieren wir nun noch die folgenden drei Stories, um jeweils einen speziellen Anwendungsfall des Controls abzubilden:
WithIcon
: Da das Icon optional ist, möchten wir diesen Zustand gesondert darstellen.Disabled
: Dadurch kann der Expander bei Bedarf komplett deaktiviert werden.WithContent
: Der wichtigste Anwendungsfall, bei dem der Expander von außen den dort übergebenen Inhalt in seinem ausklappbaren Bereich darstellt.
Die in Code-Beispiel 5 dargestellten Stories zeigen dabei, wie der Expander später von einem Anwendungsentwickler genutzt werden soll. Wir können hierüber bestimmen, wie die Eigenschaften heißen sollen und wie man beispielsweise den Inhalt an den Expander übergibt (in unserem Fall als HTML-Inhalt).
Im jetzigen Zustand wird es wahrscheinlich auch Fehler bezüglich der TypeScript Typ-Prüfung geben. Diese gilt es zu beheben und die vollständige Implementierung des Expanders inklusive der visuellen Anforderungen anhand der jeweiligen Stories als Fallbeispiele durchzuführen. Die vollständige Implementierung kann im GitHub-Projekt dazu eingesehen werden.
Die hier dargestellten Stories sind zunächst fest mit den Beispieldaten verbunden, können aber gemäß der Storybook-Dokumentation konfigurierbar gehalten werden. Im Wesentlichen muss dazu bestimmt werden, welche Bedienelemente mit welchen Werten zur Konfiguration in Storybook dargestellt werden sollen (folgendes Code-Beispiel):
Während und natürlich auch nach erfolgreicher Umsetzung aller Anforderungen an den Expander können diese interaktiv in Storybook erlebt werden (Siehe folgende Abbildung).
Weitere Features von Storybook
In dieser Form können einer echten Komponentenbibliothek natürlich noch weitere Bedienelement hinzugefügt und diese alle übersichtlich und interaktiv ausprobiert werden. Allein damit ist Storybook bereits für UI-Entwickler:innen ein sehr mächtiges Werkzeug. Über die hier gezeigten Funktionalitäten hinaus gibt es eine Reihe von Erweiterungen, die entweder mit Storybook mitkommen oder nachträglich hinzugefügt werden können:
- Accessibility: zum Testen von Standards der Barrierefreiheit im Web
- Designs: Besserer Design-Entwicklungs-Fluss durch Anzeige externer Design-Webseiten (wie z.B. Figma, Zeplin, Adobe XD) in einem parallelen Panel
- Pseudo States: direkt über Schaltflächen aktivierbare CSS-Pseudo States, wie z.B.
:hover
,:focus
, … - Docs: Möglichkeit, über Markdown-Komponenten deren Eigenschaften und Einsatzmöglichkeiten zu dokumentieren
Insbesondere das Docs-Addon (welches im Zuge der Storybook-Versionen 5 und 6 Einzug in den Kern des Tools gefunden hat) wollen wir uns im Folgenden bei der Umsetzung unseres Design-Systems zu Nutze machen.
Inhalte des Design-Systems
Nehmen wir an, die gesamte Komponentenbibliothek wurde über den soeben beschriebenen Prozess implementiert und dann unternehmensweit als NPM-Paket bereitgestellt. Die dort genutzten Stories sind nicht für alle Nutzer:innen der Bibliothek interessant, aber mit ein wenig Aufbereitung wichtige Elemente im Design-System.
Ein Design-System kann je nach Ausrichtung und Ziel verschiedenste Inhalte vermitteln. Als ein Beispiel typischer Bestandteile soll sich unser Design-System aus Folgendem zusammensetzen:
- Einführung: Genereller Einstieg, der allen Interessenvertreter:innen das Ziel des Design-Systems, eine erste Orientierung oder Installationsanweisungen bietet
- Design-Guidelines: Grundlegende Festlegungen aus dem Style-Guide, welche nicht direkt durch Code-Hilfsmittel abgedeckt werden können oder Hintergrundinformationen zur Begründung der Festlegung, z.B. Nutzungsstudien und daraus resultierende vorgegeben Prinzipien, etwa dass auf jeder Seite einer Applikationen immer nur ein “Bestätigen”-Knopf positioniert sein darf o.ä.
- Generelles: Beschreibungen zu, auch durch Code abbildbaren, primitiven Werten und Elementen, wie z.B. Icons, Abständen, Schriftarten, vorgegebene Layouts
- Bedienelemente: Ausführliche Beschreibungen zu konkreten Bedienelementen, die Teil der Komponentenbibliothek sind, wie zum Beispiel unser Expander
- Ansprechpartner: Kontaktmöglichkeiten zu Framework-Entwickler:innen, der Projektleitung von PunzeUI, Verknüpfung zu einem Ticket-System
- Changelog: Änderungsbeschreibungen der Versionen der PunzeUI-Bibliothek
Über diese inhaltlichen Teile hinaus soll die Darstellung des Design-Systems natürlich auch die Unternehmensidentität abbilden: Das Unternehmenslogo und die entsprechenden Unternehmensfarben sollen dort wiedererkennbar sein. Unsere Anwendungsentwicklerin Kay soll eine vertraute Umgebung wiederfinden und ihr soll die Berührungsangst genommen werden. Das oberste Ziel des Design-Systems muss es sein, eine Erleichterung und keine Belastung darzustellen.
Umsetzung des Design-Systems
Wir wollen nun mit Hilfe von Storybook den Grundstein für ein Design-System nach eben beschriebenen Aufbau legen. Unser mächtigstes Werkzeug ist dabei das Docs-Addon von Storybook. Es bietet uns die Möglichkeit, textuelle Dokumentationen im Markdown-Format mit Code anzureichern (über sogenannte MDX-Dateien). Damit können wir nicht nur die zuvor genutzten Stories mit Dokumentations-Seiten verknüpfen, wir können sogar davon unabhängige programmierte Bestandteile in unsere Dokumentation verweben.
Eine erste Dokumentations-Seite
Unseren Einstieg in das Design-System bilden wir durch eine einfache Markdown-Seite ab. Auf dieser beschreiben wir die Mission des Systems und wie man als Anwendungsentwickler:in die zur Verfügung gestellte Bibliothek in einem Projekt verwenden kann.
Alle Seiten unserer Design-System-Dokumentation sind sogenannte DocsPages im MDX-Format. Diese möchten wir unter src/docs
ablegen. Dort erstellen wir nun die erste DocsPage intro.stories.md
x (siehe folgendes Code-Beispiel). Die Standard-Endung *.stories.mdx
sorgt dafür, dass unsere Seite in Storybook erkannt wird. Damit diese dann in der Übersicht erscheint, müssen wir noch das Meta-Tag aus @storybook/addon-docs
hinzufügen. Über den Schrägstrich im Titel können wir die Seite innerhalb des Dokumentations-Baumes einordnen.
Der Rest dieser Datei ist gängiges Markdown und beschreibt beispielhaft ein paar Hintergrundinformationen zum Design-System sowie über eine Code-Passage das Kommando, um die Software-Bibliothek im Projekt einzubinden.
Sortierung der Navigationsleiste
Im nächsten Schritt fügen wir zwei Seiten zur Beschreibung und Verwendung von Farben und Schriftarten hinzu. Unter src/docs/general
wollen wir diese in einem eigenen Bereich zusammenführen und legen dort zwei weitere DocsPages an. Zwar können wir über den Titel (z.B. Punze UI / General / Colors
) die Zielebene der Seite im Navigationsmenü beeinflussen, die konkrete Reihenfolge der Einträge darin können wir damit jedoch nicht festlegen. Um dies zu erreichen, schreiben wir uns eine eigene Sortier-Funktion und können dann durch Angabe eines order
-Parameters auf unserer DocsPage die genaue Positionierung festlegen. Das folgende Code-Beispiel zeigt die Sortier-Funktion, welche in der Datei preview.js
hinzugefügt wird:
Durch die Vergabe von Ordnungsnummern in 10er Schritten sorgen wir dafür, dass wir auch im Nachhinein noch recht flexibel Zwischenelemente einführen können (siehe folgendes Code-Beispiel für die Sortierung der Farbseite an zweiter Position).
Nutzung von Doc Blocks
Da die Darstellung von Schriftarten und Farben in Design-Systemen ein gängiger Anwendungsfall ist, gibt es hierzu von Storybook bereits mitgelieferte sogenannte Doc Blocks. So ein Block (technisch gesehen eine React-Komponente) lässt sich innerhalb der MDX-Datei ähnlich eines HTML-Elements nutzen und mit den entsprechenden Parametern versehen. Storybook sorgt dann für die korrekte Darstellung. Die in Code-Beispiel 10 genutzte ColorPalett
e und die darin enthaltenen ColorItems
ergeben eine schöne Übersicht über die Farbpalette, die der Style-Guide vorgibt (folgende Abbildung):
Auch für die Schriftarten gibt es mit Typeset
bereits einen fertig nutzbaren Block. Dadurch, dass ein Block prinzipiell nur eine React-Komponente ist, können durch Umsetzung eines eigenen Storybook-Addons eigene Doc Blocks für sehr spezifische Anwendungsfälle geschrieben werden. Als Inspiration bietet sich ein Blick in den Quellcode von Storybook an.
Erstellen von DocsPages für Bedienelemente
Den eigentlichen Kern unseres Design-Systems stellen Dokumentations-Seiten für all unsere Controls dar. Auf diesen wollen wir Hintergründe und Einsatzzwecke, die eigentlichen Nutzungsweise der Bedienelemente, Code-Schnipsel und verschiedene Beispiele ideal aufbereitet für die Anwendungsentwicklung bereitstellen.
Am Beispiel unseres Expanders setzen wir dies um, indem wir eine MDX-Datei (docs/components/expander.stories.mdx
) mit Beschreibungen, Control- und Code-Beispielen versehen:
Zunächst beschreiben wir unser Bedienelement durch etwas Fließtext. Hierzu schreiben wir direkt Markdown in die Datei. Zur Demonstration des Controls können wir die bereits existierenden Stories einbinden, indem wir den Story
-Block verwenden. Dabei wählen wir die Story WithContent
als unseren Standard-Fall, der die Funktionalität des Expanders am besten demonstriert. Die id der Story ergibt sich dabei aus dem Titel und Namen der Story selbst oder kann der URL der jeweiligen Story entnommen werden.
Möchte man mehrere Stories nebeneinander darstellen, so müssen diese in einen Canvas
-Block geschachtelt werden. Dies machen wir, um die anderen Zustände des Controls darzustellen. Dieser Block hat den Vorteil, dass automatisch der dazugehörige Code-Schnipsel angezeigt werden kann.
Neben der direkten Einbindung existierender Stories könnten wir für Dokumentationszwecke auch komplett neue direkt in die MDX-Datei schreiben. Ebenso können wir einfache Quellcode-Ausschnitte über Markdown bereitstellen. Zuletzt können wir über einen ArgsTable
-Block ohne viel Aufwand alle Eigenschaften der React-Komponente tabellarisch darstellen. Hierbei werden die Props und deren Dokumentation aus der ursprünglichen Implementierung in Expander.tsx
herangezogen.
Die DocsPage des Expanders im Design-System.
In dieser Form sollten wir für alle Komponenten in unserer Bibliothek Seiten umsetzen, sodass die Nutzer:innen der Bibliothek alle notwendigen Informationen gut zugänglich präsentiert bekommen.
Einbindung existierender Markdown-Seiten
Nehmen wir an, dass die Framework-Entwicklung bereits eine Markdown-Datei CHANGELOG.md
erstellt, die jeweils die Änderungen neuerer Bibliotheks-Versionen beschreibt. Diese Informationen wollen wir in unserem Design-System verknüpfen. Der Description
-Block kann als Inhalt externes Markdown rendern, was uns erlaubt, beispielsweise das gesamte Change-Log unverändert darzustellen:
Theming des Design-Systems
Da wir nun wissen, wie wir die Inhalte für unser Design-System aufbauen können, möchten wir zuletzt noch das äußere Erscheinungsbild so anpassen, dass sich auch das Design-System selbst am unternehmensweiten Style-Guide orientiert.
Dazu erstellen wir zunächst ein eigenes Theme, in dem wir u.a. Name, Logo, Schriftarten und Farbgebung definieren:
Das Theme binden wir dann in der per Namenskonvention über Storybook vorgegebenen Datei manager.js
ein. Dort können wir auch die standardmäßig angezeigte Toolbar ausblenden, da wir Umschaltung zwischen Canvas und Docs innerhalb der Story-Seiten nicht benötigen und den Fokus auf die Dokumentation legen wollen:
Zuletzt möchten wir noch den Eintrag Components, den eigentlich nur die Framework-Entwicklung benötigt, im Design-System ausblenden. Hier bietet Storybook leider keine direkte Möglichkeit: Zunächst blenden wir die Story selbst aus, indem wir in der Expander.stories.tsx
den Parameter docsOnly
setzen. Darüber hinaus setzen wir die order auf einen hohen Wert und stellen so sicher, dass die Story nicht als erste auftaucht (denn sonst würde diese eventuell als Startseite gewählt werden). Um den Eintrag Components auf der Navigation zu entfernen, nutzen wir CSS. Einfluss auf das Stylesheet für Storybook selbst können wir über eine Datei manager-head.html
nehmen:
Ein tragfähiges Design-System mit Storybook.js erschaffen – Endergebnis
Nachdem wir jetzt noch das Aussehen unseres Design-Systems ausgearbeitet haben, könnten wir dieses über das Skript npm run build-storybook
bauen (z.B. auch automatisiert über ein Build-System) und es über einem Web-Server ausliefern. So könnten jederzeit alle Interessenvertreter:innen jegliche Informationen zum Design-System einsehen.
Endergebnis des Beispiel Design-Systems PunzeUI.
Die Anforderungen an ein Design-System sind sehr hoch. Es kann schnell sehr komplex werden, die verschiedenen Inhalte sind oft unterschiedlichster Natur. Es beinhaltet textuelle, visuelle und interaktive Informationen. Sicherzustellen, dass die implementierten Artefakte und die dazugehörige Dokumentation nicht auseinanderlaufen, ist häufig eine große Herausforderung. Storybook bietet hierfür einen idealen Ansatz. Es ist nicht nur ein Werkzeug, das in der eigentlichen Entwicklung hilft, sondern kann darüber hinaus eine Verknüpfung der Code-Artefakte zu einer interaktiven Dokumentation mit wenigen Mitteln herstellen.
Kay kann PunzeUI nun bequem in ihrem Anwendungsprojekt einsetzen. Wenn sie Hintergrundinformationen zum Style-Guide benötigt oder Fragen zur Verwendung von Bedienelementen oder anderen Bestandteilen der Komponentenbibliothek hat, kann sie diese über das Design-System einsehen. Auch kann sie hierüber den Kontakt zum Framework-Team aufnehmen und Feedback geben. Das PunzeUI-Design-System ist ihre Single Source of Truth.
Das hier gezeigte Vorgehen sollte beispielhaft demonstriert haben, welche Teile von Storybook man wie einsetzen kann, um ein solches Design-System skalierbar aufzubauen. Der gesamte Quellcode des PunzeUI-Projekts ist auf GitHub verfügbar.
- Komfortable Reaktivität mit Angular Signals: So schreiben Sie einfacher performanten Code - 11. April 2024
- Die Programmiersprache Rust – ein Erfahrungsbericht - 1. August 2022
- Ein tragfähiges Design-System mit Storybook.js erschaffen - 3. Februar 2022