Olá pessoal! Neste artigo, falarei descaradamente sobre minha biblioteca para Flutter, que permite criar histórias a partir de widgets e / ou telas isoladas. Algo como um livro de histórias do mundo React. Na verdade, é assim chamado: storybook_flutter .
Por que é necessário?
Primeiro, é mais rápido fazer UI. Claro, o Flutter já tem um recarregamento ativo, mas se o widget estiver enterrado em algum lugar nos confins do aplicativo, você ainda precisa acessá-lo. E se este widget for mostrado apenas sob certas condições, essas condições devem ser reproduzidas. Além disso, o hot reload não funciona em todos os casos. Portanto, é mais conveniente isolar o widget, colocá-lo em uma história separada e trabalhar com essa história. Nesse caso, você terá que pensar em como remover dependências desnecessárias desse widget, para que o código fique mais limpo.
Em segundo lugar, uma demonstração de widgets / telas. Por exemplo, estamos fazendo nossa própria biblioteca de design para o Flutter e gostaríamos de incorporar uma caixa de areia interativa com widgets na documentação, especialmente porque o Flutter para Web já está no ramo estável.
Em terceiro lugar, quero adicionar no futuro (essa ideia foi solicitada nas edições) a capacidade de gerar testes de ouro automaticamente para widgets com diferentes combinações de parâmetros.
Talvez leve algo pronto?
Provavelmente você pode. Mas, em primeiro lugar, ainda não há um favorito claro na comunidade. Em segundo lugar, ninguém cancelou a síndrome NIH. Terceiro, quero poder adicionar rapidamente os recursos de que precisamos.
Como ela se parece?
Algo assim:
Não é muito elegante, mas a aparência ainda não é uma prioridade. E o designer de mim é mais ou menos. Além disso, ainda estou fazendo experiências com o arranjo de barras de ferramentas, botões e menus, portanto, não há motivo para polir o design.
O que é que ela pode fazer?
Navegando nas histórias por categoria.
Parâmetros (botões) de widgets.
Interruptor de tema claro / escuro.
( 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.
?
Mais adiante nos planos - para instalar a API do plugin, pense sobre quais plug-ins ainda são necessários prontos para uso (bem, escreva-os).
Então, provavelmente, começarei a gerar testes, sobre os quais escrevi no início do artigo.
Isso é tudo. Eu ficaria feliz em receber comentários, sugestões e relatórios de bugs (bem, curtidas / asteriscos, é claro, para ser honesto).