Spreken op events ·

ui_playground: een gegenereerde componentenbibliotheek voor Flutter

Een componentenbibliotheek: knoppen, een schakelaar en checkbox, een tekstveld, een slider, chips en een lijst, elk op een eigen tegel

Elke app die we bouwen, heeft een eigen componentenbibliotheek: knoppen, invoervelden, kaarten, allemaal in de huisstijl van de klant. Om die componenten op zichzelf te bouwen en te controleren, buiten de app, heb je een playground nodig. Widgetbook doet dat, maar het vraagt veel boilerplate, de generators errond voelden nooit juist, en het ziet eruit als Widgetbook, niet als de app die het toont. Dus bouwde Koen ui_playground, en toonde het in een lightning talk op Flutter Belgium Meetup #26 bij A.C.A. Group in Gent. De video staat onderaan.

Waarom een eigen playground

  • In de stijl van de app. Ook designers en product owners gebruiken de playground. Ziet hij eruit als de app, met hetzelfde thema en dezelfde vertalingen, dan voelen ze zich meteen thuis.
  • Een rustigere interface. Alleen de componenten, hun varianten en de inputs om mee te spelen.
  • Geen boilerplate. De playground-code met de hand schrijven, is het deel dat developers overslaan. Kost het één regel, dan doen ze het wel.

Gebouwd met een agent, met de hand afgewerkt

De eerste versie was een test van agentic coding: Koen gaf de uitdaging aan Claude Code, en in anderhalf uur had de agent het basisframework gebouwd. Daarna volgden nog zo'n vijf uur werk met de hand, om het te krijgen zoals hij het wilde. Intussen wordt het in vier projecten gebruikt.

Drie packages

De opzet volgt het patroon van elke build_runner-generator, dus het voelt vertrouwd:

De playground is ingedeeld in secties (knoppen, invoervelden, je huisstijl, je tekststijlen), en elk component heeft een of meer varianten, bijvoorbeeld een primaire en een secundaire knop. Elke variant heeft zijn inputs: de eigenschappen die je kunt aanpassen terwijl je naar het resultaat kijkt. Met de hand geschreven is dat een klasse voor het item, een klasse per variant en een klasse voor de inputs, voor elk component.

Eén annotatie

Met de generator heeft een component één regel nodig:

@UiPlaygroundComponent(title: 'My Button')
class MyButton extends StatelessWidget {
  const MyButton({required this.title, this.isEnabled = true, this.onTap, super.key});

  final String title;
  final bool isEnabled;
  final VoidCallback? onTap;

  @override
  Widget build(BuildContext context) { ... }
}

De generator leest de constructor en maakt een input voor elke parameter: een tekstveld voor de titel, een schakelaar voor isEnabled. Een callback zoals onTap krijgt geen input; wordt hij aangeroepen, dan toont de playground een melding met de waarden van zijn parameters, zodat je meteen ziet of hij aangeroepen werd en waarmee.

Eén bestand vertelt de generator waar hij moet schrijven:

// lib/ui_playground_items.dart
@UiPlaygroundComponents()
library;

import 'package:ui_playground/ui_playground.dart';

Voer dart run build_runner build uit en alles komt in één gegenereerd bestand terecht, met commentaar, zodat het leesbaar blijft. Voeg de gegenereerde items toe aan de secties van je playground:

import 'ui_playground_items.ui_playground.dart';

UiPlaygroundApp(
  title: 'My App Playground',
  sections: [
    UiPlaygroundSection(
      title: 'Buttons',
      items: [
        MyButtonPlaygroundItem(), // generated
      ],
    ),
  ],
)

Wat het ondersteunt

  • String, bool, int en double;
  • enums, als een lijst van al hun waarden;
  • Color, DateTime en IconData;
  • nullable en non-nullable parameters, met hun standaardwaarden;
  • je eigen klassen, met een input die je zelf schrijft en in de config registreert, waarna de generator ze automatisch oppikt.

Wat volgt: standaardwaarden die alleen in de playground gelden. Een icoon met een verplichte grootte krijgt nu grootte 0 in de playground, en dan zie je niets; een extra annotatie zal die daar op 24 zetten, zonder je component aan te passen.

Bekijk de lightning talk

ui_playground, een lightning talk op Flutter Belgium Meetup #26, met een live demo van de generator (in het Engels).

De packages zijn open source: impaktfull/flutter_ui_playground op GitHub. Een componentenbibliotheek zoals deze in je eigen app? Dat hoort bij hoe we apps bouwen.

Alle blogs