knuspermagier.de
Ein L und zwei P. Philipp!

UI-Komponenten in mehreren Projekten nutzen mit Tailwind

Wenn man kurz nacheinander mehrere Projekte startet, möchte man ungern immer wieder alles von vorne bauen. Vor allem Formularfelder, oder so einen Quatsch.

Ich schrieb mir bei Kioski also schon ein paar Blade-Komponenten und wollte die in Konpasu nun weiterverwenden, doch wie mache ich das am Besten?

Composer

Der erste Schritt war erstmal, die Komponenten in ein eigenes Composer-Package auszulagern. Dazu kopierte ich alles in einen Ordner und legte einen ServiceProvider an, der Laravel mitteilt, wo der Kram nun liegt:

final class PwaBluiServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        Blade::anonymousComponentPath(__DIR__ . '/../resources/views/components', 'pwablui');
        Blade::componentNamespace('PwaBlui\\Views\\Components', 'pwablui');
    }
}

Ja, das ganze heißt PwaBlui. Für Philipp Waldhauer Blade UI. Ich muss das ja abgrenzen von meinen Vue-Componenten, die nur PWUI heißen. Ohne a. Was ist eigentlich los.

Jedenfalls kann ich die Komponenten nun benutzen:

<x-pwablui::form.row>
    <x-pwablui::form.label for="username">Username</x-pwablui::form.label>
    <x-pwablui::form.text name="username" type="text" placeholder=""/>
</x-pwablui::form.row>

Das Composer-Package habe ich mit diesem Trick für die lokale Entwicklung installiert, so wird es direkt lokal per Symlink installiert.

Ich hab noch keine Ahnung, wie das funktioniert, wenn man das jetzt von Github läd, composer install macht und die Daten nicht lokal liegen hat. Muss ich mal noch ausprobieren.

pwaldhauer_an_orc_with_a_sword_looking_like_a_fox_tail_illustra_1c19b0eb-e173-4305-a5ce-77aed7dc06bd.png
Das versteht Midjourney unter Tailwind und Blade. Sorry, ich hab einen Monat subscribed und muss die Stunden leer kriegen.

Tailwind

Nach der kurzen Freude kam direkt die Ernüchterung: Natürlich war im neuen Projekt jetzt auch alles Lila, denn die Komponenten benutzten alle bg-indigo als Farbe. Doch auch dafür gibt es eine Lösung, danke an den Tailwind-Experten Nils an dieser Stelle, denn über die Theme-API kann man Tailwind überzeugen, sowas ganz schlau zu handeln:

theme: {
    extend: {
        backgroundColor: ({ theme }) => ({
            primary:  theme('colors.emerald'),
        }),
        ringColor: ({ theme }) => ({
            primary:  theme('colors.emerald'),
        }),
        textColor: ({ theme }) => ({
            primary:  theme('colors.emerald'),
        }),
        borderColor: ({ theme }) => ({
            primary:  theme('colors.emerald'),
        })
    },
},

Nun kann ich in den Komponenten einfach bg-primary benutzen und in den Projekten einfach die entsprechenden Farben in der Konfiguration einstellen. Fast als würde man eine normale CSS-Datei nehmen und dort Variablen überschreiben.

Verrückt!

Models richtig recyclen in Eloquent Factories

Heute hatte ich ein kleines Verständnisproblem in meinem Seeder und wollte daher mal notieren, wie es richtig geht.

Folgendes Problem: Ich habe, sagen wir mal, ein Model Post, das eine user_id hat.

Wenn ich nun ganz viele Posts in die Datenbank seede, möchte ich zwar, dass jeder mit einem User verbunden ist, aber ich will nicht, dass jeder Post auch seinen ganz eigenen User erstellt. Da kommt nun die recycle-Methode zur Anwendung

// PostFactory.php
public function definition(): array
{
    return [
        'text' => 'Hallo!',
        'user_id' => User::factory(),
    ];
}

// DatabaseSeeder.php
$users = User::factory()->count(10)->create();

Post::factory()
    ->recycle($users)
    ->count(100)
    ->create();

Nutzt man bei der PostFactory, wie dargestellt, nun recycle, führt das dazu, dass er die entsprechenden Models nutzt, statt Neue zu erstellen, wie toll ist das denn!


Damit der Post nicht nur hilfreich, sondern auch unterhaltsam ist, hier noch den Fehler, den ich machte, weshalb alles nicht funktionierte:

// DatabaseSeeder.php
$users = User::factory()->count(10)->create();

Post::factory()
    ->recycle($users)
    ->for(User::factory())
    ->count(100)
    ->create();

Ich versuchte recycle gemeinsam mit for zu benutzen. Das klappt zwar an sich auch, aber jeder Post bekommt leider den gleichen User, weil das for für alles gilt, was aus der Factory fällt. Ist also gar kein Fehler von recycle, sondern nur ganz allein meiner.