Design System - Teaser

Was ist: ein Design System?

🛈

Willkommen zurück! Heute möchte ich euch eine kleine Einführung zum Thema Design Systeme geben. Dabei soll es zunächst darum gehen, was ein Design System im weitesten Sinne ist, und was es beinhaltet. Danach folgt ein kleiner Ausflug in die Welt des atomaren Designs, bevor wir im letzten Teil des Beitrags dann ein Werkzeug verwenden werden, mit dem das eigene Design System dokumentiert werden kann. Wer mich kennt weiß, dass hier natürlich Open Source eine große Rolle spielt.

Es gibt wie immer eine Menge zu lesen, daher lasst uns direkt anfangen.

Wozu ein Design System

Ich muss gestehen, bis vor ungefähr einem halben Jahr, habe ich auch nicht gewusst, dass es so etwas wie Design Systeme in dieser Tiefe gibt. Seitdem ich es weiß, bin ich aber ein Fan davon. Auch beruflich werde ich mich die nächste Zeit sehr ausgiebig damit befassen. Ich war auch überrascht, wie viele Firmen, egal ob groß oder klein, ihre Design Systeme öffentlich zugänglich dokumentiert haben. Eines der bekannteren dürfte wohl das Material Design von Google sein. Aber auch Microsoft, IBM oder Atlassian haben ihre eigenen Systeme. Sehr oft beziehen sich solche Systeme auf webbasierte Software. Natürlich können die Systeme aber auch für Desktop Anwendungen oder Smartphone Apps herangezogen werden.

Es gibt viele Beweggründe, wieso eine Firma ein Design System erstellt. Allen voran bietet es eine gemeinsame Kommunikationsgrundlage wenn es um das Design der eigenen Anwendungen geht. Jeder kann sich die Dokumentation anschauen und sieht sofort, wie Anwendungen aufgebaut sein sollen, und welche Komponenten wie auszusehen haben. Designer können auf dieser Basis Mockups und Prototypen entwerfen, die von Entwicklern auf immer gleiche Weise umgesetzt werden können. So ergibt sich für Endbenutzer ein gleichbleibendes Erlebnis bei der Verwendung aller Anwendungen der jeweiligen Firma.

Wichtig ist, dass ein Design System dabei ein wachsender und sich weiterentwickelnder Organismus ist, genauso wie die Anwendungen selbst. Natürlich bedarf es zu Beginn einer gewissen Basis, die sich jedoch stetig verändert und auch mit der Zeit geht. Dabei sollten gewünschte Änderungen zuerst in das Design System integriert werden, bevor sie auf die einzelnen Anwendungen ausgerollt werden.

Ein Design System geht weit darüber hinaus zu definieren wie ein Button auszusehen hat. Lasst uns also als nächstes einen Blick darauf werfen, welche Bestandteile in einem Design System enthalten sein sollten.

Inhalt eines Design Systems

Begriffe die schon länger existieren sind Corporate Design und Corporate Identity. Damit ist im wesentlichen ein einheitliches Auftreten einer Firma nach außen gemeint. Auch dazu gibt es schon länger entsprechende Richtlinien innerhalb von Firmen, um den Mitarbeitern eine Basis für Kommunikation mit Presse oder Endkunden zu bieten. Bestandteile dieser Richtlinien bilden auch die Basis für die Erstellung eines Design Systems.

Die beiden wichtigsten Definitionen, die wohl auch schon im Rahmen einer Firmengründung entschieden werden sollten, sind Schriftarten und zu verwendende Farben des Unternehmens. Sie sind fester Bestandteil eines jeden Design Systems und auch unabhängig davon für eine Firma von entscheidender Bedeutung.

Ein weiterer Punkt der relativ zu Beginn eines Design Systems festgelegt werden sollte sind Abstände. Dabei sind sowohl die Abstände innerhalb von Elementen, wie Buttons oder Tabellenzellen, als auch zwischen den Elementen zu bestimmen, beispielweise vor oder nach einer Überschrift. Viele Systeme verwenden hier oft ein Vielfaches von 4. Da in der modernen Webentwicklung in CSS oft die Einheit rem verwendet wird, bieten sich bei einer Basis von 16 Pixeln also Werte in 0.25 Schritten an, z.B. 0.25rem, 0.5rem, 0.75rem usw.

Die bisher genannten Bestandteile gehören zum sog. Style Guide. Ein weiterer wichtiger Teil eines Design Systems beschäftigt sich mit dessen Komponenten. Dieser umfasst das Aussehen der einzelnen Elemente einer Benutzeroberfläche und auch die Anordnung dieser innerhalb von komplexeren Layouts. Auch ist dieser Teil wohl der interessanteste für einen Entwickler.

Die Basis für diese sogenannte Komponenten-Bibliothek bildet dabei der Style Guide, der definiert, welche Schriften in welcher Größe verwendet werden sollen, und welche Farben z.B. Buttons für bestimmte Zustände haben sollen. Darüber hinaus definiert die Bibliothek auch das Aussehen von Elementen wie Buttons, Checkboxen oder Eingabefeldern. Dazu zählen Rahmen um die Elemente, abgerundete Ecken oder auch ein Schatten. Mit Details möchte ich mich an dieser Stelle noch zurückhalten, da das Ganze schnell sehr technisch wird, und wir das später beim Dokumentieren unseres eigenen kleinen Design Systems noch genauer betrachten werden.

Je nachdem wo man sich umsieht, gibt es neben einem Style Guide und der Komponenten-Bibliothek noch weitere Bestandteile, die zu einem Design System gezählt werden können. An dieser Stelle möchte ich deshalb noch Animationen und Übergänge zwischen den Seiten einer Anwendung anführen und es an dieser Stelle gut sein lassen mit den Inhalten eines Design Systems. Wie die Komponenten-Bibliothek im speziellen strukturiert werden kann, erfahrt ihr im nächsten Abschnitt.

Atomares Design für Beginner

Nachdem ihr nun wisst, dass es die Komponenten-Bibliothek gibt, schauen wir uns als nächstes an, wie sie strukturiert werden kann. Dazu werde ich mich im Wesentlichen auf einen sehr interessanten Artikel zum Thema atomares Design von Brad Frost berufen, dessen Inhalt ich hier etwas verkürzt zusammenfassen möchte.

Die Grundidee dahinter ist Folgende: wir beginnen mit den kleinsten Einheiten unseres Designs (den Atomen) und arbeiten uns Stück für Stück weiter voran. Beispiele für Atome sind Buttons und Eingabefelder.

Die nächste Stufe sind dann sog. Moleküle, also einige wenige Elemente in einer Gruppe. Hier finden wir zum Beispiel ein Suchfeld mit einem Button. Wichtig dabei ist, dass die verwendeten Elemente in einer sehr engen Beziehung stehen.

Auf der nächsten Stufe finden wir dann Organismen. Sie vereinen mehrere Atome und/oder Moleküle zu größeren Einheiten. Die Einzelteile haben dabei keine so enge Beziehung wie innerhalb von Molekülen, erfüllen aber doch einen gemeinsamen Zweck. Ein sehr gutes Beispiel dafür ist eine Navigationsleiste. Mehrere voneinander unabhängige Bestandteile dienen trotzdem dem gemeinsamen Ziel, einen Benutzer auf der Seite navigieren zu lassen. Sei es auf einzelne Unterseiten oder aber zu seinem Profil.

Die letzten beiden Teile des atomaren Designs sind Vorlagen und Seiten. Vorlagen bilden dabei eine abstrakte Anordnung aller bisher genannten Einheiten. Die Seiten verwenden dann diese Vorlagen und füllen sie mit Leben bzw. Inhalten.

Wer mehr zu dem Thema wissen will, sollte sich unbedingt den eingangs in diesem Abschnitt verlinkten Artikel durchlesen.

Genug aber mit der grauen Theorie, lasst uns Farbe ins Spiel bringen, und unser eigenes Design System dokumentieren.

Das eigene Design System

Da die Erstellung und Dokumentation eines eigenen Design Systems sehr viel Zeit in Anspruch nimmt, muss ich mich hier natürlich auf das Wesentliche beschränken. Ich versuche auf Basis der verwendeten Werkzeuge und Frameworks für die wichtigen Teile jeweils ein Beispiel zu geben. Ihr könnt das für eure eigenen Projekte natürlich beliebig erweitern.

Werkzeuge und Frameworks

Im Vorfeld dieses Beitrags habe ich mich ausgiebig mit der Analyse von Werkzeugen zur Dokumentation von Design Systemen befasst. Wie fast überall gibt es dabei bezahlte Angebote, auf die ich hier nicht eingehen werde, aber auch freie Alternativen. Ein sehr gutes Werkzeug der zweiten Kategorie ist mit Sicherheit Storybook.

Da ich aber aus einer Welt komme, in der SPAs (noch) keine Rolle spielen, da grafische Oberflächen nahezu vollständig mit Template Engines auf dem Server erzeugt werden, störte mich dabei die starke Fokussierung auf Web-Komponenten (egal ob HTML5, Vue oder React). Meine Wahl fiel deshalb auf Fractal. Es bietet einen gröberen Rahmen und lässt uns somit mehr Freiheiten. Wie es der Zufall haben will, ist es damit außerdem möglich, Twig als Template Sprache zu verwenden, das in der PHP-Welt derzeit wohl das beste ist, was man finden kann. Solltet ihr direkt mit SPAs loslegen, könnt ihr natürlich auch Storybook verwenden. Ich lese durchweg positives darüber und mit jeder Version wird es wohl noch besser.

Als nächstes brauchen wir noch etwas, um unsere Komponenten auch stylen zu können. Hier bin ich aktuell ein Fan von TailwindCSS. Es ist vor Kurzem in Version 2 erschienen und ist ein sog. Utility Framework. D.h. es gibt nicht, wie z.B. bei Bootstrap üblich, vorgefertigte Organismen (um auf das atomare Design zurückzukommen), sondern lediglich low-level Hilfsklassen, mit denen ihr viel Freiheit genießt, die aber natürlich auch eine gewisse Gefahr mit sich bringt.

Tailwind wird durchaus kontrovers diskutiert, worauf ich hier nicht eingehen will. Wer möchte, kann sich diesen Blog Post durchlesen, der die Ideen und die Entstehung von Tailwind ausführlich erklärt. Ich will hier einige Funktionen herausstellen, die mich von der Verwendung überzeugt haben:

  • Alles ist konfigurierbar. Dazu zählen z.B. die Farben, Basisgröße der generischen Klassen für Schriftgröße oder Abstände. Auch neue Klassen können per Konfiguration hinzugefügt werden.
  • Was ist in dem Paket? Nur das Nötigste! Tailwind integriert in den Buildprozess eine Bereinigung, die nicht verwendete Klassen entfernt und somit für eine kleine CSS Datei sorgt.
  • Abstraktion durch Komponenten. Wenn sich Styles häufig wiederholen, z.B. für die Basis eines Buttons, ist es möglich diese Definitionen über Komponenten zu extrahieren.
  • “Mobile first” responsives Design und Dark Mode inklusive.
  • Lebhafte Community. Wer nicht das Superauge für Design hat (wie ich zum Beispiel), für den gibt es kostenlose Inspirationsquellen: Tailblocks und Tailwind Components.

Mit Fractal und TailwindCSS haben wir das Fundament gelegt. Im nächsten Abschnitt werden wir die beiden nun vereinen, und das Design System zum Leben erwecken.

Installation und Einrichtung

Dieser Abschnitt beschäftigt sich mit der Grundinstallation von Fractal und TailwindCSS. Da Fractal ein NodeJS Projekt ist, initialisieren wir zuerst unser Projekt. Erstellt dazu irgendwo auf eurer Festplatte einen Ordner namens design-system und öffnet ihn in einem Konsolenfenster. Danach führt folgenden Befehl aus:

npm init -y

Wie ihr seht, verwende ich für diesen Artikel npm, ihr könnt aber gerne auch yarn verwenden. Der obige Befehl bestätigt alle Optionen mit den Standardwerten und erstellt ein Grundgerüst einer package.json Datei. Diese ist nötig, um die benötigten Pakete aufzuzeichnen, und die nötigen Konsolenbefehle registrieren zu können. Wenn ihr wollt, könnt ihr auch noch einen git init Befehl ausführen, um das Ganze versionieren zu können. Wer mit GIT noch wenig bis gar keine Erfahrungen hat, sich aber darüber informieren will, dem empfehle ich die Seite von Atlassian. Hier werdet ihr leicht verständlich in die Thematik eingeführt.

Als nächstes installieren wir Fractal inklusive Twig Template Plugin in unserem NodeJS Projekt. Führt dazu folgendes Kommando auf der Konsole in eurem Ordner aus:

npm install --save @frctl/fractal @frctl/twig

Die Option --save sorgt dafür, dass dieses Paket als Abhängigkeit in der package.json Datei hinzugefügt wird. Solltet ihr GIT verwenden und euer Projekt zu einem späteren Zeitpunkt nochmal installieren wollen, reicht ein git clone und anschließend das Ausführen von npm install im von GIT erstellten Ordner, um den lauffähigen Zustand wiederherzustellen.

Die offizielle Installationsanleitung schlägt als nächstes vor, das Kommandozeilen Werkzeug für Fractal zu installieren. Das werden wir an dieser Stelle nicht machen, da ich kein großer Fan davon bin, nach und nach immer mehr verschiedene Konsolenkommandos global auf einem Rechner zu installieren, solange es nicht nötig ist.

Um Fractal trotzdem starten zu können, fügen wir in den scripts Abschnitt innerhalb der package.json Datei folgende Zeile ein:

"scripts": {
  "start": "fractal start --sync"
},

Das dort existierende test Kommando könnt ihr löschen.

Bevor wir den Fractal Entwicklungsmodus starten können, benötigen wir noch eine Projektkonfiguration. Legt dazu eine Datei namens fractal.config.js mit folgendem Inhalt an:

'use strict'

const fractal = (module.exports = require('@frctl/fractal').create())

Die hier erstellte Instanz werden wir im nächsten Abschnitt verwenden, um Fractal noch weiter unseren Bedürfnissen anzupassen. Für den Moment reicht diese Konfiguration aber aus, um den Server zu starten.

Wenn ihr also auf der Konsole das nachfolgende Kommando ausführt, wird der Entwicklungsserver von Fractal gestartet:

npm start

In der Konsole werden euch dann verschiedene URLs angezeigt, mit denen ihr die Seite im Browser öffnen könnt. In meine Fall verwende ich dazu http://localhost:3000/. Nach dem Öffnen seht ihr eine Platzhalterseite, da wir selbst noch keine Inhalte angelegt haben. Bevor wir damit aber im nächsten Abschnitt fortfahren, lasst uns noch TailwindCSS installieren und in Fractal integrieren. Führt dazu auf der Konsole erneut ein entsprechendes Kommando aus:

npm install --save tailwindcss autoprefixer postcss

Auf der offiziellen Installationsanleitung sind verschiedene Möglichkeiten dokumentiert, wie Tailwind konfiguriert werden kann. Solltet ihr an den Details Interesse haben, könnt ihr euch hier informieren. Ich werde nur das nötigste davon anführen, da es hier primär um Fractal gehen soll, und TailwindCSS lediglich lauffähig sein muss. Ich könnte mindestens einen separaten Beitrag über TailwindCSS alleine schreiben.

Nachdem der oben gezeigte Befehl fertig ausgeführt ist, müssen wir zunächst einige Ordner und Dateien anlegen. Hier eine Liste der Ordner und Dateien, die ihr zunächst anlegen müsst:

/tailwind.config.js
/public/
/src/tailwind/main.css

Über tailwind.config.js lässt sich Tailwind euren Wünschen anpassen. Wir verwenden an dieser Stelle die Standard-Konfiguration, d.h. ihr müsst einfach den folgenden Inhalt in diese Datei kopieren:

module.exports = {
  purge: [],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {}
  },
  variants: {},
  plugins: []
}

Im Ordner public wird die von Tailwind erzeugte Ausgabedatei angelegt bzw. bei Änderungen überschrieben. Diesen Ordner werden wir später in Fractal als Ordner für statische Assets angeben.

In die Datei src/tailwind/main.css müsst ihr nun noch folgenden Inhalt einfügen, welcher auch dem Standard von Tailwind entspricht:

@tailwind base;
@tailwind components;
@tailwind utilities;

Um nun die Tailwind Konfiguration zu einer fertigen CSS Datei konvertieren zu können, benötigen wir ein weiteres Skript in der package.json Datei:

"scripts": {
  "start": "fractal start --sync",
  "build:tailwind": "tailwind build src/tailwind/main.css -o public/style.css"
}

Führt nun auf der Konsole folgendes Kommando aus, um das erste Mal eine CSS Datei erzeugen zu lassen:

npm run build:tailwind

Im public Ordner sollte jetzt eine Datei namens style.css existieren, die wir im nächsten Abschnitt dann Fractal bekannt machen werden.

Wichtig: ich habe hier bewusst auf einen watch Modus für Tailwind verzichtet. D.h. wenn ihr etwas in den Dateien tailwind.config.js oder main.css ändert, müsst ihr dieses Kommando erneut ausführen, um die Datei style.css neu erstellen zu lassen.

Konfiguration von Fractal

Nachdem nun alle nötigen Komponenten installiert und soweit nötig konfiguriert und generiert wurden, lasst uns als nächstes das Herzstück unseres Design Systems konfigurieren, nämlich Fractal. Dazu haben wir bereits zuvor die Datei fractal.config.js angelegt, die im folgenden Abschnitt mit Inhalt gefüllt werden soll.

Kopiert den folgenden Inhalt an das Ende der Konfigurationsdatei, ich werde direkt im Anschluss daran auf die einzelnen Bestandteile eingehen:

const twigAdapter = require('@frctl/twig')()

/* Set the title of the project */
fractal.set('project.title', 'Generic Design System')
fractal.set('project.version', '1.0.0')
fractal.set('project.author', 'Generic Company')

/* Tell Fractal where the components will live */
fractal.components.set('path', __dirname + '/src/components')
fractal.components.engine(twigAdapter)
fractal.components.set('ext', '.twig')

/* Define the wrapper of the component preview */
fractal.components.set('default.preview', '@preview')

/* Tell Fractal where the documentation pages will live */
fractal.docs.set('path', __dirname + '/src/docs')
fractal.docs.set('label', 'Design System')

/* Specify a directory of static assets */
fractal.web.set('static.path', __dirname + '/public')

/* Set the static HTML build destination */
fractal.web.set('builder.dest', __dirname + '/build/docs')

Wie erwähnt, werden wir Twig als Template Engine nutzen. Diese Tatsache müssen wir Fractal entsprechend mitteilen. Dazu wird zunächst eine Instanz davon in der Variable twigAdapter erstellt und später für das Rendering der Komponenten registriert. Außerdem wird die Dateiendung auf .twig gestellt:

const twigAdapter = require('@frctl/twig')()
fractal.components.engine(twigAdapter)
fractal.components.set('ext', '.twig')

Es folgen einige allgemeine Projektinformationen, die ihr natürlich nach Belieben ändern könnt:

fractal.set('project.title', 'Generic Design System')
fractal.set('project.version', '1.0.0')
fractal.set('project.author', 'Generic Company')

Diese Informationen bestimmen z.B. den Seitentitel, können aber auch später innerhalb der einzelnen Komponenten ausgelesen und verwendet werden.

Als nächstes müsst ihr noch weitere Ordner anlegen, da diese für die Seiten der Komponenten und für die Seiten des Style Guides benötigt werden:

/src/components/
/src/docs/

Der Vollständigkeit halber, hier die Konfiguration, die die Ordner entsprechend registriert:

fractal.components.set('path', __dirname + '/src/components')
fractal.docs.set('path', __dirname + '/src/docs')

Zum Abschluss noch die Zeilen, die für die statischen Assets und das Ausgabeverzeichnis der Dokumentation benötigt werden:

fractal.web.set('static.path', __dirname + '/public')
fractal.web.set('builder.dest', __dirname + '/build/docs')

Nun fügen wir noch ein letztes Kommando in die scripts Sektion unserer package.json Datei hinzu, um die Dokumentation für die produktive Version erstellen zu können:

"scripts": {
  "start": "fractal start --sync",
  "build:doc": "fractal build",
  "build:tailwind": "tailwind build src/tailwind/main.css -o public/style.css"
}

Mit npm run build:doc wird ein produktiver Build unseres Projekts im Ordner build erstellt. Dieser Ordner beinhaltet alles, was ihr benötigt, um die Seite online zu stellen.

Wie ihr vielleicht bemerkt habt, haben wir zwar die TailwindCSS Datei zuvor erzeugt, bisher weiß aber Fractal nichts von dieser Datei. Das erledigen wir mit einer letzten Konfiguration, die ihr ans Ende von fractal.config.js einfügen könnt:

const mandelbrot = require('@frctl/mandelbrot')

const myCustomisedTheme = mandelbrot({
  skin: 'navy',
  nav: ['search', 'docs', 'components'],
  styles: ['default', '/style.css']
})

fractal.web.theme(myCustomisedTheme)

Gleichzeitig seht ihr hier, wie ihr ein anderes Farbschema (navy) verwenden könnt, und wie die Reihenfolge der Abschnitte der Seitenleiste geändert werden können. In unserem Fall kommt hier zunächst das Suchfeld, dann der Inhalt des docs Ordners, worüber wir den Style Guide erstellen werden, und zum Schluss die Komponenten, welche wir im Ordner components erstellen werden.

Kleiner Nachtrag zum Thema Stylesheet. Um die erzeugte style.css Datei auch innerhalb der Komponentenvorschau verwenden zu können, gibt es in der oben gezeigten Konfiguration eine wichtige Zeile:

fractal.components.set('default.preview', '@preview')

Das definiert eine Datei mit HTML-Grundgerüst, die wir später beim Erstellen unserer Komponenten-Bibliothek anlegen werden.

Die Einrichtung aller Bestandteile wäre damit abgeschlossen. Ihr könnt den Zwischenstand nochmal über npm start im Browser begutachten, bevor wir nun an das Erstellen der Inhalte gehen werden. Am besten lasst ihr dieses Kommando ab sofort dauerhaft laufen, damit sich eure Dokumentation nach jeder Änderung automatisch aktualisiert.

Style Guide

Neue Seiten in den Style Guide einzufügen ist sehr einfach. Ihr müsst dazu lediglich eine Datei mit der Endung .md innerhalb des docs Ordners anlegen. Um Abschnitte zu erstellen, können wir auch Unterordner anlegen.

Warum beginnen wir nicht damit, eine Einstiegsseite zu erstellen. Nennt die Datei index.md und fügt folgenden Inhalt ein:

---
title: Übersicht
label: Übersicht
---

Das ist unser eigenes Design System.

Am Anfang der Datei kann jeweils ein Bereich namens YAML front-matter eingefügt werden, in dem ihr einige Seiteneinstellungen definieren könnt. Klickt auf den Link, um zu sehen welche Einstellungen möglich sind. In unserem Beispiel habe ich den Titel der Seite definiert, und über das Label festgelegt, wie die Seite in der linken Navigationsleiste angezeigt wird.

Um die einzelnen Punkte des Style Guides zu gruppieren, legt ihr als nächstes einen Ordner namens style-guide unter docs an. Darin erstellt ihr eine Datei mit dem Namen colors.md mit folgendem Inhalt:

---
title: Farben
label: Farben
---

Hier eine Übersicht unserer Farben

<h1>Blau</h1>

<div class="w-full h-10 flex items-center bg-blue-400 pl-2 text-white">bg-blue-400</div>
<div class="w-full h-10 flex items-center bg-blue-500 pl-2 text-white">bg-blue-500</div>

<h1>Rot</h1>

<div class="w-full h-10 flex items-center bg-red-400"></div>
<div class="w-full h-10 flex items-center bg-red-500"></div>

<h1>Grün</h1>
<div class="w-full h-10 flex items-center bg-green-400"></div>
<div class="w-full h-10 flex items-center bg-green-500"></div>

Schaut euch das Ergebnis im Browser an!

Da Markdown intern zu HTML konvertiert wird, ist es möglich, direkt innerhalb der Dateien eigenes HTML Markup zu schreiben. Hier seht ihr auch die Utility Klassen von TailwindCSS im Einsatz. Ich habe beispielhaft für die beiden blauen Boxen auch den Namen der verwendeten Klassen hinzugefügt, dass z.B. ein Entwickler sich direkt die Definition kopieren kann.

Ich denke als Einstieg ist das erst einmal ausreichend. Alle weiteren Möglichkeiten für Dokumentationsseiten findet ihr in der offiziellen Dokumentation.

Komponenten-Bibliothek

Kommen wir nun zum Herzstück des Design Systems, der Komponenten-Bibliothek. Auch hier gelten ähnliche Konventionen wie zuvor. Seiten die ihr direkt im Verzeichnis components anlegt, erscheinen auf der Hauptebene der Navigation, während ihr mit Unterverzeichnissen weitere Ebenen erstellen könnt.

Bevor wir mit einer Beispielkomponente beginnen, möchte ich auf die zuvor erwähnte Datei mit dem HTML-Grundgerüst zurückkommen, die wir benötigen um TailwindCSS für die Vorschau der Komponenten laden zu können. Erstellt dazu eine Datei namens _preview.twig im Ordner components und fügt folgenden Inhalt ein:

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="{{ '/style.css'|path }}" />
    <title>Preview</title>
  </head>
  <body class="bg-white p-4">
    {{ yield | raw }}
  </body>
</html>

Wie ihr sehen könnt, wird unsere CSS Datei eingebunden, und auf den body ein weißer Hintergrund und etwas Abstand zu den Rändern mittels padding hinzugefügt. Der Unterstrich im Dateinamen sorgt übrigens dafür, dass die Seite nicht als normale Komponente interpretiert wird.

Komponente: Infobox

Als erstes möchte ich euch eine Komponente für Infoboxen zeigen. Erstellt dazu die Datei alert.twig direkt im components Ordner, mit folgendem Inhalt:

<div
  class="p-3 bg-{{modifier}}-200 border-l-4 border-{{modifier}}-900 text-{{modifier}}-900 flex items-center relative"
>
  <span class="text-4xl mr-4">
    <i class="fa fa-warning text-4xl"></i>
  </span>
  <span>
    <span class="block mb-2 text-2xl">
      {{title}}
    </span>
    <span class="text-base">
      {{ message }}
    </span>
  </span>
</div>

Ihr seht hier im Markup einige Twig Platzhalter, z.B. {{modifier}}. Das schöne an Fractal ist, ihr könnt ein Markup für mehrere Ausprägungen einer Komponente schreiben. Um diese Platzhalter dann mit Inhalten zu füllen, gibt es Konfigurationsdateien. Für dieses Beispiel könnt ihr dazu im Ordner components eine Datei mit dem Namen alert.config.json erstellen und darin folgenden Inhalt einfügen:

{
  "title": "Alert message",
  "status": "1_0_0",
  "context": {
    "modifier": "blue",
    "message": "This is the info message"
  },
  "variants": [
    {
      "name": "default",
      "label": "Info",
      "context": {
        "modifier": "blue",
        "title": "Info",
        "name": "info"
      }
    },
    {
      "name": "success",
      "context": {
        "modifier": "green",
        "message": "This is a success message",
        "title": "Success",
        "name": "success"
      }
    }
  ]
}

Wenn ihr euch die Dokumentation jetzt im Browser anschaut, solltet ihr in der linken Navigationsleiste sehen, dass es pro Ausprägung einen eigenen Menüeintrag gibt. Klickt euch ruhig etwas durch die einzelnen Reiter, das habt ihr euch mittlerweile verdient.

Entwickler können sich hier später auch den erzeugten Quellcode einfach rauskopieren, somit sieht eine Erfolgsmeldung immer gleich aus. Wie kurz bei den Erläuterungen zu TailwindCSS erwähnt, könnte man die einzelnen Definitionen auch als Tailwind Komponente extrahieren. Dadurch wären nicht so viele Utility Klassen im Markup nötig.

Komponente: Button

Ihr habt es fast geschafft, haltet nur noch ein wenig durch. Zum Abschluss möchte ich euch noch eine Button Komponente zeigen, und zwar in zweifacher Ausführung. Einmal werden wir verschiedene Farben verwenden, einmal verschiedene Größen umsetzen.

Button: Verschiedene Farben

Dieses Beispiel geht in die Richtung der zuvor gezeigten Infobox Komponente. Erstellt zunächst im Ordner components einen Unterordner button. Darin erstellt ihr einen weiteren Unterordner namens 01-styles. Die 01- im Ordnernamen kann man in Fractal nutzen, um manuell eine Reihenfolge von Komponenten zu definieren. Das funktioniert sowohl für Datei- als auch Ordnernamen. Die Nummer wird später in der Oberfläche nicht angezeigt.

Legt als nächstes die Datei styles.twig im zuvor erstellen Unterordner an und fügt folgenden Inhalt ein:

<button class="px-4 py-2 bg-{{modifier}}-800 text-white hover:bg-{{modifier}}-700">
    {{title}}
</button>

Auch hier seht ihr wieder Platzhalter, die gefüllt werden wollen. Deshalb solltet ihr eine Datei namens styles.config.json anlegen und dort folgende Konfiguration einfügen:

{
  "title": "Button",
  "status": "1_0_0",
  "context": {
    "modifier": "blue"
  },
  "handle": "button",
  "default": "info",
  "variants": [
    {
      "name": "info",
      "context": {
        "modifier": "blue",
        "title": "Show more"
      }
    },
    {
      "name": "success",
      "context": {
        "modifier": "green",
        "title": "OK"
      }
    }
  ]
}
Button: Verschiedene Größen

Nun zum letzten Beispiel. Da ihr das Vorgehen mittlerweile kennt, hier die Anweisungen, die ihr strikt befolgen müsst!

Erstellt im button Ordner einen neuen Unterordner und nennt ihn 02-sizes. Darin erstellt ihr jetzt die Datei sizes.twig mit dem Inhalt:

<button class="px-{{px}} py-{{py}} text-{{text}} bg-blue-800 text-white hover:bg-blue-700">
    {{title}}
</button>

Als letztes fehlt noch die Konfiguration für diese Komponente, die ihr in der Datei sizes.config.json mit folgendem Inhalt definiert:

{
  "title": "Button",
  "status": "1_0_0",
  "context": {
    "modifier": "blue"
  },
  "collated": true,
  "handle": "button-size",
  "default": "small",
  "variants": [
    {
      "name": "small",
      "label": "Small",
      "context": {
        "title": "Small",
        "text": "sm",
        "px": "2",
        "py": "0"
      }
    },
    {
      "name": "normal",
      "context": {
        "title": "Normal",
        "text": "base",
        "px": "4",
        "py": "1"
      }
    },
    {
      "name": "large",
      "context": {
        "title": "Large",
        "text": "xl",
        "px": "6",
        "py": "2"
      }
    }
  ]
}

Das wars! Ihr habt es geschafft! Wenn ihr mich bis hier hin verfolgt habt, dann sollte das fertige Ergebnis in etwa so aussehen:

Fertiges Design System

In der Konfiguration der letzten Komponente seht ihr übrigens "collated": true, was dafür sorgt, dass die Ausprägungen alle auf der gleichen Seite zu finden sind, nicht auf einzelnen Unterseiten.

Fazit

Obwohl dieser Beitrag etwas länger geworden ist als ursprünglich vermutet, kratzt er natürlich nur an der Oberfläche der Themen. Ich hoffe, ich konnte euch trotzdem einen spannenden Einblick geben, und euch dafür begeistern, euch das Ganze selbst ausführlicher anzusehen. Ich freue mich bereits auf die beruflichen Herausforderungen der nächsten Monate und wünsche euch viel Spaß bei der Erstellung eures eigenen Design Systems auf Basis der hier gezeigten Werkzeuge.

Nun will ich euch aber nicht länger aufhalten. Bis bald auf Next Direction!