smart_textfield 0.0.1 copy "smart_textfield: ^0.0.1" to clipboard
smart_textfield: ^0.0.1 copied to clipboard

TextField that can extract relevant information from the raw text input.

example/lib/main.dart

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

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

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

  @override
  Widget build(BuildContext context) {
    return SmartTextFieldOverlay(
      child: MaterialApp(
        title: 'Material App',
        home: Builder(builder: (context) => const SmartTextFieldScreen()),
      ),
    );
  }
}

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

  @override
  State<SmartTextFieldScreen> createState() => _SmartTextFieldScreenState();
}

class _SmartTextFieldScreenState extends State<SmartTextFieldScreen> {
  late final _controller = SmartTextFieldController(
    tokenizers: [
      ProjectTokenizer(values: _projects),
      LabelTokenizer(values: _labels),
    ],
  );

  // ignore: type_annotate_public_apis
  var dateTime = DateTime.now();
  Project? _selectedProject;
  Label? _selectedLabel;

  @override
  void initState() {
    super.initState();

    _controller.addListener(() {
      if (_controller.highlightedDateTime != null) {
        setState(() {
          dateTime = _controller.highlightedDateTime!;
        });
      }
    });

    _controller.highlightedTokens.addListener(() {
      final _tokens = _controller.highlightedTokens.value;

      if (_tokens['@'] != null) {
        _selectedProject = _tokens['@']?.value as Project?;
      } else {
        _selectedProject = null;
      }

      if (_tokens['#'] != null) {
        _selectedLabel = _tokens['#']?.value as Label?;
      } else {
        _selectedLabel = null;
      }

      Future.delayed(
        Duration.zero,
        () {
          if (mounted) setState(() {});
        },
      );
    });
  }

  @override
  void setState(VoidCallback fn) {
    if (mounted) super.setState(fn);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Smart TextField'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              showFormattedDateTime(dateTime),
              style: const TextStyle(fontSize: 20),
            ),
            Text('Project: ${_selectedProject?.name ?? 'None'}'),
            Text('Label: ${_selectedLabel?.name ?? 'None'}')
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          await showModalBottomSheet<void>(
            context: context,
            showDragHandle: true,
            constraints: BoxConstraints(
              maxHeight: MediaQuery.of(context).size.height * 0.8,
            ),
            builder: (context) {
              return Padding(
                padding:
                    const EdgeInsets.symmetric(horizontal: 20, vertical: 20)
                        .copyWith(
                  bottom: MediaQuery.of(context).viewInsets.bottom + 20,
                ),
                child: SmartTextField(
                  controller: _controller,
                ),
              );
            },
          );
        },
        child: const Icon(Icons.add),
      ),
    );
  }

  String showFormattedDateTime(DateTime dateTime) =>
      '${dateTime.day}/${dateTime.month}/${dateTime.year} ${dateTime.hour}:${dateTime.minute}';
}

@immutable
class ProjectTokenizer extends Tokenizer<Project> {
  ProjectTokenizer({
    required super.values,
    super.prefix = '@',
  });
}

@immutable
// ignore: avoid_implementing_value_types
class Project implements Tokenable {
  const Project({
    required this.name,
  });

  final String name;

  @override
  String get stringValue => name;

  @override
  String get prefix => '@';
}

final _projects = [
  const Project(name: 'John Doe'),
  const Project(name: 'Jane Doe'),
  const Project(name: 'Baz qux'),
  const Project(name: 'Foo bar'),
  const Project(name: 'Foo baz'),
  const Project(name: 'Foo qux'),
  const Project(name: 'Foo foo'),
];

@immutable
class LabelTokenizer extends Tokenizer<Label> {
  LabelTokenizer({
    required super.values,
    super.prefix = '#',
  });
}

@immutable
// ignore: avoid_implementing_value_types
class Label implements Tokenable {
  const Label({required this.name});

  final String name;

  @override
  String get stringValue => name;

  @override
  String get prefix => '#';
}

final _labels = [
  const Label(name: 'Label 1'),
  const Label(name: 'Label 2'),
  const Label(name: 'Label 3'),
  const Label(name: 'Label 4'),
];
40
likes
0
pub points
46%
popularity

Publisher

unverified uploader

TextField that can extract relevant information from the raw text input.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

collection, flutter, flutter_portal, meta

More

Packages that depend on smart_textfield