unit_number_input 0.1.1 copy "unit_number_input: ^0.1.1" to clipboard
unit_number_input: ^0.1.1 copied to clipboard

A Flutter package for minutes/seconds input with validation, input decoration, and conversion to total seconds.

example/lib/main.dart

import 'package:example/pages/submitted.dart';
import 'package:flutter/material.dart';
import 'package:unit_number_input/unit_number_input.dart';

void main() {
  runApp(const MyApp());
}

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'unit_number_input Example',
      theme: ThemeData(),
      darkTheme: ThemeData.dark(), // standard dark theme
      themeMode: ThemeMode.system,
      home: const MyHomePage(title: 'unit_number_input'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<UnitNumberInputController> _controllers = [];
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  @override
  void initState() {
    super.initState();
    _controllers = [
      UnitNumberInputController(initialSeconds: -1),
      UnitNumberInputController(initialSeconds: 20),
      UnitNumberInputController(),
      UnitNumberInputController(startInMinutesMode: true),
      UnitNumberInputController(initialSeconds: 500, startInMinutesMode: true),
      UnitNumberInputController(),
      UnitNumberInputController(initialSeconds: 45000),
      UnitNumberInputController(),
      UnitNumberInputController(startInMinutesMode: true),
    ];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Form(
        key: _formKey,
        child: Center(
          child: SingleChildScrollView(
            child: ConstrainedBox(
              constraints: BoxConstraints(
                minHeight: MediaQuery.of(context).size.height,
              ),
              child: Column(
                children: [
                  Divider(),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: [
                      const SizedBox(width: 20),
                      Text('Default', style: TextStyle(fontSize: 16)),
                      const Spacer(),
                      FittedBox(
                        fit: BoxFit.contain,
                        child: UnitNumberInput(
                          controller: _controllers[0],
                          prefill: true,
                          valueRequired: false,
                        ),
                      ),
                    ],
                  ),
                  Divider(),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: [
                      const SizedBox(width: 20),
                      Text('External toggle', style: TextStyle(fontSize: 16)),
                      const Spacer(),
                      FittedBox(
                        fit: BoxFit.contain,
                        child: UnitNumberInput(
                          controller: _controllers[1],
                          enableMinutesToggle: false,
                          onChanged: (seconds) {
                            print("Total seconds: $seconds");
                          },
                        ),
                      ),
                      Switch(
                        value: _controllers[1].minutesMode,
                        onChanged: (value) {
                          setState(() {
                            _controllers[1].toggleMode();
                          });
                        },
                      ),
                    ],
                  ),
                  Divider(),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: [
                      const SizedBox(width: 20),
                      Text(
                        'No initial seconds or prefill',
                        style: TextStyle(fontSize: 16),
                      ),
                      const Spacer(),
                      FittedBox(
                        fit: BoxFit.contain,
                        child: UnitNumberInput(
                          controller: _controllers[2],
                          prefill: false,
                          onChanged: (seconds) {
                            print("Total seconds: $seconds");
                          },
                        ),
                      ),
                    ],
                  ),
                  Divider(),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: [
                      const SizedBox(width: 20),
                      Text(
                        'No initial seconds, prefilled',
                        style: TextStyle(fontSize: 16),
                      ),
                      const Spacer(),
                      FittedBox(
                        fit: BoxFit.contain,
                        child: UnitNumberInput(
                          controller: _controllers[3],
                          onChanged: (seconds) {
                            print("Total seconds: $seconds");
                          },
                        ),
                      ),
                    ],
                  ),
                  Divider(),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: [
                      const SizedBox(width: 20),
                      Text(
                        'Initial minutes, seconds',
                        style: TextStyle(fontSize: 16),
                      ),
                      const Spacer(),
                      FittedBox(
                        fit: BoxFit.contain,
                        child: UnitNumberInput(
                          controller: _controllers[4],
                          onChanged: (seconds) {
                            print("Total seconds: $seconds");
                          },
                        ),
                      ),
                    ],
                  ),
                  Divider(),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: [
                      const SizedBox(width: 20),
                      Text(
                        'Field not required, not prefilled',
                        style: TextStyle(fontSize: 16),
                      ),
                      const Spacer(),
                      FittedBox(
                        fit: BoxFit.contain,
                        child: UnitNumberInput(
                          controller: _controllers[5],
                          enableMinutesToggle: false,
                          valueRequired: false,
                          prefill: false,
                          onChanged: (seconds) {
                            print("Total seconds: $seconds");
                          },
                        ),
                      ),
                    ],
                  ),
                  Divider(),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: [
                      const SizedBox(width: 20),
                      Text('5 digits', style: TextStyle(fontSize: 16)),
                      const Spacer(),
                      FittedBox(
                        fit: BoxFit.contain,
                        child: UnitNumberInput(
                          controller: _controllers[6],
                          enableMinutesToggle: false,
                          maxSecondsDigits: 5,
                          onChanged: (seconds) {
                            print("Total seconds: $seconds");
                          },
                        ),
                      ),
                    ],
                  ),
                  Divider(),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: [
                      const SizedBox(width: 20),
                      Text('Disabled', style: TextStyle(fontSize: 16)),
                      const Spacer(),
                      FittedBox(
                        fit: BoxFit.contain,
                        child: UnitNumberInput(
                          controller: _controllers[7],
                          enabled: false,
                          onChanged: (seconds) {
                            print("Total seconds: $seconds");
                          },
                        ),
                      ),
                    ],
                  ),
                  Divider(),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: [
                      const SizedBox(width: 20),
                      Text(
                        'Disabled, minutes mode',
                        style: TextStyle(fontSize: 16),
                      ),
                      const Spacer(),
                      FittedBox(
                        fit: BoxFit.contain,
                        child: UnitNumberInput(
                          controller: _controllers[8],
                          enabled: false,
                          onChanged: (seconds) {
                            print("Total seconds: $seconds");
                          },
                        ),
                      ),
                    ],
                  ),
                  Divider(),
                  ElevatedButton(
                    onPressed: () {
                      if (_formKey.currentState?.validate() ?? false) {
                        final values = _controllers
                            .map((c) => c.totalSeconds)
                            .toList();

                        Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (context) => SubmittedPage(values: values),
                          ),
                        );
                      }
                    },
                    child: Text('Submit'),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}
2
likes
160
points
370
downloads

Publisher

verified publisheramabe.dev

Weekly Downloads

A Flutter package for minutes/seconds input with validation, input decoration, and conversion to total seconds.

Repository (GitHub)
View/report issues
Contributing

Documentation

API reference

Funding

Consider supporting this project:

www.buymeacoffee.com

License

MIT (license)

Dependencies

flutter

More

Packages that depend on unit_number_input