rich_text_controllerx 1.1.0 copy "rich_text_controllerx: ^1.1.0" to clipboard
rich_text_controllerx: ^1.1.0 copied to clipboard

An extended text editing controller that supports different inline styles for custom regex patterns

example/README.md

import 'dart:developer';

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

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

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

  @override
  State<StatefulWidget> createState() => MyAppState();
}

class MyAppState extends State<MyApp> {
  bool enableHighlight = true;
  bool enableOnTapInto = true;
  bool enableOnSelected = true;

  MatchResultItem? matchTappedItem;

  void _onWordMatchTap(MatchResultItem tappedItem) =>
      setState(() => matchTappedItem = tappedItem);

  late final RichTextController controller = RichTextController(
    text:
        'Home sweet home! Do good homework and housework at home. The happyness of an ending.',
    sortTargetsByPatternLength: true,
    mergeOverlappingStyles: true,
    deleteOnBack: true,
    enableHighlight: true,
    enableOnTapInto: true,
    enableOnSelected: true,
    onMatch: (List<MatchResultItem> matches) {
      for (final MatchResultItem match in matches) {
        log(match.toString());
      }
    },
    targets: [
      // --------------------------------------------------------------
      // SINGLE STRING
      // --------------------------------------------------------------

      MatchTargetItem.string(
        'homework',
        style:
            const TextStyle(color: Colors.orange, fontWeight: FontWeight.bold),
        stringMatch: StringMatch.exact,
        caseSensitive: false,
        onSelected: (MatchResultItem match) => _onWordMatchTap(match),
        onTapInto: (MatchResultItem match) => _onWordMatchTap(match),
      ),

      MatchTargetItem.string(
        'Home',
        style: const TextStyle(color: Colors.red),
        stringMatch: StringMatch.any,
        caseSensitive: false,
        onSelected: (MatchResultItem match) => _onWordMatchTap(match),
        onTapInto: (MatchResultItem match) => _onWordMatchTap(match),
      ),

      // Prefix

      MatchTargetItem.string(
        'happy',
        style: const TextStyle(color: Colors.blue),
        stringMatch: StringMatch.prefix,
        caseSensitive: false,
        onSelected: (MatchResultItem match) => _onWordMatchTap(match),
        onTapInto: (MatchResultItem match) => _onWordMatchTap(match),
      ),

      // Postfix

      MatchTargetItem.string(
        'ing',
        style: const TextStyle(color: Colors.blue),
        stringMatch: StringMatch.postfix,
        caseSensitive: false,
        onSelected: (MatchResultItem match) => _onWordMatchTap(match),
        onTapInto: (MatchResultItem match) => _onWordMatchTap(match),
      ),

      // --------------------------------------------------------------
      // MULTIPLE STRINGS
      // --------------------------------------------------------------

      MatchTargetItem.strings(
        ['do', 'at'],
        style: const TextStyle(color: Colors.pink),
        onSelected: (MatchResultItem match) => _onWordMatchTap(match),
        onTapInto: (MatchResultItem match) => _onWordMatchTap(match),
      ),

      // --------------------------------------------------------------
      // SINGLE REGEXP
      // --------------------------------------------------------------

      MatchTargetItem.regex(
        RegExp(r'sweet'),
        style: const TextStyle(color: Colors.indigo),
        onSelected: (MatchResultItem match) => _onWordMatchTap(match),
        onTapInto: (MatchResultItem match) => _onWordMatchTap(match),
      ),

      // --------------------------------------------------------------
      // MUTIPLE REGEXPs
      // --------------------------------------------------------------

      MatchTargetItem.regexes(
        [RegExp(r'good'), RegExp(r'and')],
        style: const TextStyle(
          decoration: TextDecoration.underline,
          decorationStyle: TextDecorationStyle.wavy,
          decorationColor: Colors.indigo,
          decorationThickness: 3,
        ),
        onSelected: (MatchResultItem match) => _onWordMatchTap(match),
        onTapInto: (MatchResultItem match) => _onWordMatchTap(match),
      ),
    ],
  );

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: SafeArea(
        child: Scaffold(
          body: ListView(
            padding: const EdgeInsets.all(16),
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  ElevatedButton.icon(
                      onPressed: () {
                        setState(() => enableHighlight = !enableHighlight);
                        controller.enableHighlight = enableHighlight;
                      },
                      icon: Icon(enableHighlight ? Icons.check : Icons.clear),
                      label: const Text('Highligting')),
                  ElevatedButton.icon(
                      onPressed: () {
                        setState(() => enableOnTapInto = !enableOnTapInto);
                        controller.enableOnTapInto = enableOnTapInto;
                      },
                      icon: Icon(enableOnTapInto ? Icons.check : Icons.clear),
                      label: const Text('On-Tap-Into')),
                  ElevatedButton.icon(
                      onPressed: () {
                        setState(() => enableOnSelected = !enableOnSelected);
                        controller.enableOnSelected = enableOnSelected;
                      },
                      icon: Icon(enableOnSelected ? Icons.check : Icons.clear),
                      label: const Text('On-Selected')),
                ],
              ),
              const SizedBox(height: 16),
              // ------------------------------------------------------------
              // CONTEOLLER EXAMPLE
              // ------------------------------------------------------------
              const Text('TextField'),
              TextField(controller: controller, maxLines: null),
              const SizedBox(height: 16),
              if (matchTappedItem != null)
                Text(matchTappedItem.toString())
              else
                const Text('Select / Tap a matched word!',
                    style: TextStyle(
                        color: Colors.red, fontWeight: FontWeight.bold)),
              const Divider(height: 64),
              // ------------------------------------------------------------
              // WRAPPER EXAMPLE
              // ------------------------------------------------------------
              const Text('RichWrapper'),
              RichWrapper(
                initialText: 'Good morning and good night at Github',
                targets: [
                  MatchTargetItem.string('good',
                      style: const TextStyle(color: Colors.red)),
                  MatchTargetItem.strings(['morning', 'night'],
                      style: const TextStyle(color: Colors.blue)),
                  MatchTargetItem.regex(RegExp(r'and'),
                      style: const TextStyle(color: Colors.orange)),
                  MatchTargetItem.regexes([RegExp(r'at'), RegExp(r'Github')],
                      style: const TextStyle(color: Colors.indigo)),
                ],
                child: (controller) => TextField(controller: controller),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
2
likes
160
points
32
downloads

Publisher

verified publishernovelplotter.com

Weekly Downloads

An extended text editing controller that supports different inline styles for custom regex patterns

Repository (GitHub)

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on rich_text_controllerx