folly_fields 4.1.0 copy "folly_fields: ^4.1.0" to clipboard
folly_fields: ^4.1.0 copied to clipboard

Basic form fields and utilities.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:folly_fields/fields/all_fields.dart';
import 'package:folly_fields/util/icon_helper.dart';
import 'package:folly_fields/util/safe_builder.dart';
import 'package:folly_fields/widgets/circular_waiting.dart';
import 'package:folly_fields/widgets/error_message.dart';
import 'package:folly_fields/widgets/folly_dialogs.dart';
import 'package:folly_fields_example/code_link.dart';
import 'package:folly_fields_example/example_enum.dart';
import 'package:folly_fields_example/example_model.dart';
import 'package:folly_fields_example/views/credit_card.dart';
import 'package:folly_fields_example/views/four_images.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:google_fonts/google_fonts.dart' hide Config;
import 'package:http/http.dart';
import 'package:url_launcher/url_launcher_string.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Folly Fields Example',
      theme: ThemeData(
        colorSchemeSeed: Colors.deepOrange,
        useMaterial3: true,
        brightness: Brightness.dark,
      ),
      initialRoute: '/',
      routes: {
        '/': (_) => const MyHomePage(),
        '/four_images': (_) => const FourImages(),
        '/credit_card': (_) => const CreditCard(),
      },
      localizationsDelegates: const [
        ...GlobalMaterialLocalizations.delegates,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: const [Locale('pt', 'BR')],
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  MyHomePageState createState() => MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> {
  static const githubUrl =
      'https://github.com/edufolly/folly_fields/blob/main/lib/fields';

  final _formKey = GlobalKey<FormState>();

  /// Modelo padrão para o exemplo.
  // ExampleModel model = ExampleModel.generate();
  ExampleModel model = ExampleModel();

  @override
  Widget build(context) {
    List<MyMenuItem> menuItems = [
      /// Github
      MyMenuItem(
        name: 'GitHub',
        iconData: FontAwesomeIcons.github,
        onPressed: (context) {
          CircularWaiting wait = CircularWaiting(context)..show();

          launchUrlString(
                'https://github.com/edufolly/folly_fields/',
                mode: LaunchMode.externalApplication,
              )
              .then((_) {
                Future<void>.delayed(const Duration(seconds: 2), wait.close);
              })
              .catchError((e, s) {
                debugPrintStack(label: e.toString(), stackTrace: s);
              });
        },
      ),

      /// Circular Waiting
      MyMenuItem(
        name: 'Circular Waiting',
        iconData: FontAwesomeIcons.spinner,
        onPressed: (context) {
          final wait = CircularWaiting(
            context,
            message: 'This is the main message.',
            subtitle: 'Wait 3 seconds...',
          )..show();

          Future<void>.delayed(const Duration(seconds: 3), wait.close);
        },
      ),

      /// Four Images
      MyMenuItem(
        name: 'Quatro Imagens',
        iconData: FontAwesomeIcons.image,
        onPressed: (context) => Navigator.of(context).pushNamed('/four_images'),
      ),

      MyMenuItem(
        name: 'Credit Card',
        iconData: FontAwesomeIcons.creditCard,
        onPressed: (context) => Navigator.of(context).pushNamed('/credit_card'),
      ),
    ];

    return Scaffold(
      appBar: AppBar(
        title: const Text('Folly Fields'),
        actions: [
          PopupMenuButton<MyMenuItem>(
            tooltip: 'Menu',
            icon: const Icon(FontAwesomeIcons.ellipsisVertical),
            itemBuilder: (context) =>
                menuItems.map((e) => e.popupMenuItem).toList(),
            onSelected: (item) => item.onPressed(context),
          ),
        ],
      ),
      body: SafeArea(
        child: SafeFutureBuilder<Response>(
          future: get(
            Uri.parse(
              'https://raw.githubusercontent.com/edufolly'
              '/folly_fields/main/example/lib/main.dart',
            ),
          ),
          builder: (context, response, _) {
            int statusCode = response.statusCode;
            if (statusCode < 200 || statusCode > 299) {
              return ErrorMessage(error: 'Status code error: $statusCode');
            }

            String code = response.body;

            return SingleChildScrollView(
              padding: const EdgeInsets.all(24),
              child: Form(
                key: _formKey,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: [
                    /// Título
                    Padding(
                      padding: const EdgeInsets.all(8),
                      child: Text(
                        'Formulário Básico',
                        textAlign: TextAlign.center,
                        style: Theme.of(context).textTheme.headlineMedium,
                      ),
                    ),

                    // [RootCode]
                    CodeLink(
                      code: code,
                      tag: 'StringField',
                      source: '$githubUrl/string_field.dart',
                      child:
                          // [StringField]
                          StringField(
                            label: 'Texto',
                            initialValue: model.text,
                            onSaved: (value) => model.text = value,
                          ),
                      // [/StringField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'EmailField',
                      source: '$githubUrl/email_field.dart',
                      child:
                          // [EmailField]
                          EmailField(
                            label: 'E-mail',
                            required: false,
                            initialValue: model.email,
                            onSaved: (value) => model.email = value,
                          ),
                      // [/EmailField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'PasswordField',
                      source: '$githubUrl/password_field.dart',
                      child:
                          // [PasswordField]
                          PasswordField(
                            label: 'Senha',
                            onSaved: (value) => model.password = value,
                          ),
                      // [/PasswordField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'PasswordVisibleField',
                      source: '$githubUrl/password_visible_field.dart',
                      child:
                          // [PasswordVisibleField]
                          PasswordVisibleField(
                            label: 'Senha Visível',
                            onSaved: (value) => model.visiblePassword = value,
                          ),
                      // [/PasswordVisibleField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'DecimalField',
                      source: '$githubUrl/decimal_field.dart',
                      child:
                          // [DecimalField]
                          DecimalField(
                            label: 'Decimal',
                            initialValue: model.decimal,
                            onSaved: (value) => model.decimal = value!,
                          ),
                      // [/DecimalField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'IntegerField',
                      source: '$githubUrl/integer_field.dart',
                      child:
                          // [IntegerField]
                          IntegerField(
                            label: 'Integer',
                            initialValue: model.integer,
                            onSaved: (value) => model.integer = value,
                          ),
                      // [/IntegerField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'ColorField',
                      source: '$githubUrl/color_field.dart',
                      child:
                          // [ColorField]
                          ColorField(
                            label: 'Cor',
                            required: false,
                            initialValue: model.color,
                            onSaved: (value) => model.color = value,
                          ),
                      // [/ColorField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'CpfField',
                      source: '$githubUrl/cpf_field.dart',
                      child:
                          // [CpfField]
                          CpfField(
                            label: 'CPF',
                            required: false,
                            initialValue: model.cpf,
                            onSaved: (value) => model.cpf = value,
                          ),
                      // [/CpfField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'CnpjField',
                      source: '$githubUrl/cnpj_field.dart',
                      child:
                          // [CnpjField]
                          CnpjField(
                            label: 'CNPJ',
                            required: false,
                            initialValue: model.cnpj,
                            onSaved: (value) => model.cnpj = value,
                          ),
                      // [/CnpjField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'CpfCnpjField',
                      source: '$githubUrl/cpf_cnpj_field.dart',
                      child:
                          // [CpfCnpjField]
                          CpfCnpjField(
                            label: 'CPF ou CNPJ',
                            required: false,
                            initialValue: model.document,
                            onSaved: (value) => model.document = value,
                          ),
                      // [/CpfCnpjField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'PhoneField',
                      source: '$githubUrl/phone_field.dart',
                      child:
                          // [PhoneField]
                          PhoneField(
                            label: 'Telefone',
                            required: false,
                            initialValue: model.phone,
                            onSaved: (value) => model.phone = value,
                          ),
                      // [/PhoneField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'MobilePhoneField',
                      source: '$githubUrl/mobile_local_phone_field.dart',
                      child:
                          // [MobilePhoneField]
                          MobilePhoneField(
                            label: 'Celular',
                            required: false,
                            initialValue: model.mobilePhone,
                            onSaved: (value) => model.mobilePhone = value,
                          ),
                      // [/MobilePhoneField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'DateTimeField',
                      source: '$githubUrl/date_time_field.dart',
                      child:
                          // [DateTimeField]
                          DateTimeField(
                            label: 'Data e Hora',
                            required: false,
                            clearOnCancel: true,
                            initialValue: model.dateTime,
                            onSaved: (value) => model.dateTime = value,
                          ),
                      // [/DateTimeField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'DateField',
                      source: '$githubUrl/date_field.dart',
                      child:
                          // [DateField]
                          DateField(
                            label: 'Data',
                            required: false,
                            clearOnCancel: true,
                            initialValue: model.date,
                            onSaved: (value) => model.date = value,
                          ),
                      // [/DateField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'TimeField',
                      source: '$githubUrl/time_field.dart',
                      child:
                          // [TimeField]
                          TimeField(
                            label: 'Hora',
                            required: false,
                            clearOnCancel: true,
                            initialValue: model.time,
                            onSaved: (value) => model.time = value,
                          ),
                      // [/TimeField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'MacAddressField',
                      source: '$githubUrl/mac_address_field.dart',
                      child:
                          // [MacAddressField]
                          MacAddressField(
                            label: 'Mac Address',
                            required: false,
                            initialValue: model.macAddress,
                            onSaved: (value) => model.macAddress = value,
                          ),
                      // [/MacAddressField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'NcmField',
                      source: '$githubUrl/ncm_field.dart',
                      child:
                          // [NcmField]
                          NcmField(
                            label: 'NCM',
                            required: false,
                            initialValue: model.ncm,
                            onSaved: (value) => model.ncm = value,
                          ),
                      // [/NcmField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'CestField',
                      source: '$githubUrl/cest_field.dart',
                      child:
                          // [CestField]
                          CestField(
                            label: 'CEST',
                            required: false,
                            initialValue: model.cest,
                            onSaved: (value) => model.cest = value,
                          ),
                      // [/CestField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'CnaeField',
                      source: '$githubUrl/cnae_field.dart',
                      child:
                          // [CnaeField]
                          CnaeField(
                            required: false,
                            label: 'CNAE',
                            initialValue: model.cnae,
                            onSaved: (value) => model.cnae = value,
                          ),
                      // [/CnaeField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'CepField',
                      source: '$githubUrl/cep_field.dart',
                      child:
                          // [CepField]
                          CepField(
                            label: 'CEP',
                            required: false,
                            initialValue: model.cep,
                            onSaved: (value) => model.cep = value,
                          ),
                      // [/CepField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'LicencePlateField',
                      source: '$githubUrl/licence_plate_field.dart',
                      child:
                          // [LicencePlateField]
                          LicencePlateField(
                            label: 'Placa de Veiculo',
                            required: false,
                            initialValue: model.licencePlate,
                            onSaved: (value) => model.licencePlate = value,
                          ),
                      // [/LicencePlateField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'Ipv4Field',
                      source: '$githubUrl/ipv4_field.dart',
                      child:
                          // [Ipv4Field]
                          Ipv4Field(
                            label: 'IPv4',
                            required: false,
                            initialValue: model.ipv4,
                            onSaved: (value) => model.ipv4 = value,
                          ),
                      // [/Ipv4Field]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'BoolField',
                      source: '$githubUrl/bool_field.dart',
                      child:
                          // [BoolField]
                          BoolField(
                            label: 'Campo Boleano',
                            initialValue: model.active,
                            onSaved: (value) => model.active = value,
                          ),
                      // [/BoolField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'IconDataField',
                      source: '$githubUrl/icon_data_field.dart',
                      child:
                          // [IconDataField]
                          IconDataField(
                            label: 'Ícone',
                            icons: IconHelper.data,
                            initialValue: model.icon,
                            onSaved: (iconData) => model.icon = iconData,
                          ),
                      // [/IconDataField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'DropdownField',
                      source: '$githubUrl/dropdown_field.dart',
                      child:
                          // [DropdownField]
                          DropdownField<ExampleEnum, Widget>(
                            label: 'Ordinal',
                            items: ExampleEnum.values.asMap().map((
                              _,
                              ExampleEnum value,
                            ) {
                              return MapEntry(value, Text(value.value));
                            }),
                            initialValue: model.ordinal,
                            onSaved: (value) => model.ordinal = value,
                          ),
                      // [/DropdownField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'MultilineField',
                      source: '$githubUrl/multiline_field.dart',
                      child:
                          // [MultilineField]
                          MultilineField(
                            style: GoogleFonts.firaMono(),
                            label: 'Multiline',
                            counterText: null,
                            maxLength: 600,
                            initialValue: model.multiline,
                            onSaved: (value) => model.multiline = value,
                          ),
                      // [/MultilineField]
                    ),

                    CodeLink(
                      code: code,
                      tag: 'ChoiceChipField',
                      source: '$githubUrl/choice_chip_field.dart',
                      child:
                          // [ChoiceChipField]
                          ChoiceChipField<int>(
                            label: 'Frutas',
                            items: const {
                              0: ChipEntry(
                                '🍎Maça',
                                color: Colors.red,
                                selectedColor: Colors.redAccent,
                              ),
                              1: ChipEntry(
                                '🍌Banana',
                                color: Colors.yellow,
                                selectedColor: Colors.yellowAccent,
                              ),
                              2: ChipEntry(
                                '🍊Tangerina',
                                color: Colors.orange,
                                selectedColor: Colors.orangeAccent,
                              ),
                            },
                            onChanged: (value, {required selected}) =>
                                debugPrint(
                                  'ChoiceChipField $value is'
                                  '${selected ? '' : ' NOT'} selected',
                                ),
                            onSaved: (value) => model.fruitIndex = value?.first,
                          ),
                      // [/ChoiceChipField]
                    ),

                    // [/RootCode]

                    /// Botão Enviar
                    Padding(
                      padding: const EdgeInsets.symmetric(
                        vertical: 16,
                        horizontal: 8,
                      ),
                      child: FilledButton.icon(
                        icon: const Icon(Icons.send),
                        label: const Text('ENVIAR'),
                        onPressed: _send,
                      ),
                    ),
                  ],
                ),
              ),
            );
          },
        ),
      ),
    );
  }

  void _send() {
    if (_formKey.currentState!.validate()) {
      _formKey.currentState!.save();

      FollyDialogs.dialogMessage(
        context: context,
        title: 'Result of toMap().',
        message: model
            .toMap()
            .entries
            .map((it) => '${it.key}: ${it.value}')
            .join(',\n'),
      );
    }
  }
}

class MyMenuItem {
  final String name;
  final IconData iconData;
  final Function(BuildContext context) onPressed;

  MyMenuItem({
    required this.name,
    required this.iconData,
    required this.onPressed,
  });

  PopupMenuItem<MyMenuItem> get popupMenuItem => PopupMenuItem<MyMenuItem>(
    value: this,
    child: Row(
      children: <Widget>[
        Padding(
          padding: const EdgeInsets.only(right: 16),
          child: Icon(iconData),
        ),
        Text(name),
      ],
    ),
  );
}