Libro de cuentos + Flutter = storybook_flutter

¡Hola a todos! En este artículo, hablaré descaradamente sobre mi biblioteca para Flutter, que te permite crear historias a partir de widgets y / o pantallas aisladas. Algo así como un libro de cuentos del mundo React. En realidad, se llama así: storybook_flutter .





¿Por qué es necesario?

Primero, es más rápido crear una interfaz de usuario. Por supuesto, Flutter ya tiene una recarga en caliente, pero si el widget está enterrado en algún lugar de la aplicación, aún debe acceder a él. Y si este widget se muestra solo bajo ciertas condiciones, entonces estas condiciones deben reproducirse. Además, la recarga en caliente no funciona en todos los casos. Por lo tanto, es más conveniente aislar el widget, ponerlo en una historia separada y trabajar con esta historia. En este caso, tendrá que pensar en cómo eliminar las dependencias innecesarias de este widget, para que el código sea finalmente más limpio.





En segundo lugar, una demostración de widgets / pantallas. Por ejemplo, estamos creando nuestra propia biblioteca de diseño para Flutter y nos gustaría incrustar una caja de arena interactiva con widgets en la documentación, especialmente porque Flutter para Web ya está en la rama estable.





En tercer lugar, en el futuro quiero agregar (se me solicitó esta idea en los números) la capacidad de generar automáticamente pruebas doradas para widgets con diferentes combinaciones de parámetros.





¿Quizás llevar algo listo?

Probablemente puedas. Pero, en primer lugar, todavía no hay un favorito claro en la comunidad. En segundo lugar, nadie ha cancelado el síndrome de los NIH. En tercer lugar, quiero poder agregar rápidamente las funciones que necesitamos.





¿Cómo luce ella?

Algo como esto:





No muy elegante, pero la apariencia aún no es una prioridad. Y el diseñador mío es regular. Además, todavía estoy experimentando con la disposición de las barras de herramientas, botones y menús, por lo que no tiene sentido pulir el diseño.





¿Qué puede hacer ella?

  • Navegando historias por categoría.





  • Parámetros (perillas) de widgets.





  • Interruptor de tema claro / oscuro.





  • ( iframe).





  • .





  • ( device_frame) – .





  • – .





?

pubspec.yaml



( -, ):





storybook_flutter: ^0.5.0-dev.0
      
      



( ). - :





import 'package:flutter/material.dart';
import 'package:storybook_flutter/storybook_flutter.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) => Storybook(
        children: [
          Story.simple(
            name: 'Button',
            child: ElevatedButton(
              onPressed: () {},
              child: const Text('Push me'),
            ),
          ),
        ],
      );
}

      
      



, , :





. simple



, builder



child



:





Story(
  name: 'Button',
  builder: (context, k) => ElevatedButton(
    onPressed:
        k.boolean(label: 'Enabled', initial: true) ? () {} : null,
    child: Text(k.text(label: 'Text', initial: 'Push me')),
  ),
),
      
      



, :





, section



:





Story(
  name: 'Button',
  section: 'Buttons',
  builder: (context, k) => ElevatedButton(
    onPressed:
        k.boolean(label: 'Enabled', initial: true) ? () {} : null,
    child: Text(k.text(label: 'Text', initial: 'Push me')),
  ),
),
      
      



section



.





?

Story



padding



background



, , :





Story(
  name: 'Button',
  section: 'Buttons',
  padding: const EdgeInsets.all(8),
  background: Colors.red,
  builder: (context, k) => ElevatedButton(
    onPressed:
        k.boolean(label: 'Enabled', initial: true) ? () {} : null,
    child: Text(k.text(label: 'Text', initial: 'Push me')),
  ),
),
      
      



. wrapperBuilder



Story



, :





Story(
  name: 'Button',
  section: 'Buttons',
  wrapperBuilder: (context, story, child) => Container(
    decoration: BoxDecoration(border: Border.all()),
    margin: const EdgeInsets.all(16),
    child: Center(child: child),
  ),
  builder: (context, k) => ElevatedButton(
    onPressed:
        k.boolean(label: 'Enabled', initial: true) ? () {} : null,
    child: Text(k.text(label: 'Text', initial: 'Push me')),
  ),
),
      
      



storyWrapperBuilder



Storybook



, .





!

, , CustomStorybook



:





class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final decoration = BoxDecoration(
      border: Border(
        right: BorderSide(color: Theme.of(context).dividerColor),
        left: BorderSide(color: Theme.of(context).dividerColor),
      ),
      color: Theme.of(context).cardColor,
    );
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: CustomStorybook(
          builder: (context) => Row(
            children: [
              Container(
                width: 200,
                decoration: decoration,
                child: const Contents(),
              ),
              const Expanded(child: CurrentStory()),
              Container(
                width: 200,
                decoration: decoration,
                child: const KnobPanel(),
              ),
            ],
          ),
          children: [
            Story(
              name: 'Button',
              builder: (context, k) => ElevatedButton(
                onPressed:
                    k.boolean(label: 'Enabled', initial: true) ? () {} : null,
                child: Text(k.text(label: 'Text', initial: 'Push me')),
              ),
            )
          ],
        ),
      ),
    );
  }
}
      
      



Contents



, CurrentStory



KnobPanel



(, , ). :





CustomStorybook



, Storybook , device_preview, . :





?

, 1st party : DeviceFramePlugin



:





, .





, , .





?

, , Flutter'. Android, iOS, Web macOS.





?

Más adelante en los planes: para instalar la API de complementos, piense qué complementos aún se necesitan de fábrica (bueno, escríbalos).





Entonces, lo más probable es que empiece a generar pruebas, sobre las que escribí al principio del artículo.






Eso es todo. Me encantaría recibir comentarios, sugerencias e informes de errores (bueno, me gusta / asteriscos, por supuesto, para ser honesto).








All Articles