flutter_richify 0.0.2 copy "flutter_richify: ^0.0.2" to clipboard
flutter_richify: ^0.0.2 copied to clipboard

A Flutter package to make it easy to create links, mentions, hashtags, emails, phones, and custom patterns.

flutter_richify #

pub package

A lightweight Flutter package for creating rich text patterns in TextField. Style mentions, hashtags, links, emails, phone numbers, or any custom pattern with full interaction support.

Should you use flutter_richify? #

Use flutter_richify for:

  • Pattern detection in text inputs (mentions, hashtags, emails, links, phone numbers)
  • Clickable elements in chat, social, or messaging UI
  • Email recipient chips or tag inputs
  • Lightweight enhancement of standard TextField widgets

Not recommended for:

  • Full document editors with formatting toolbars and rich content blocks
  • Large text documents
  • Heavy content where performance is critical

Usage #

Social Media Mentions & Hashtags #

RichifyController(
  text: 'Hey @john! Check out #flutter_richify',
  matchers: [
    RegexMatcher(
      pattern: RegExp(r'@\w+'),
      spanBuilder: (candidate) => TextSpan(
        text: candidate.text,
        style: const TextStyle(color: Colors.blue, fontWeight: FontWeight.bold),
      ),
      options: const TextMatcherOptions(deleteOnBack: true),
    ),
    RegexMatcher(
      pattern: RegExp(r'#\w+'),
      spanBuilder: (candidate) => TextSpan(
        text: candidate.text,
        style: const TextStyle(color: Colors.green, fontWeight: FontWeight.w600),
      ),
    ),
  ],
  onMatch: (matches) => print('Detected: $matches'),
)

Email Chips #

RichifyController(
  blockCursorMovement: true, // Lock cursor after chips
  matchers: [
    RegexMatcher(
      pattern: RegExp(r'\S+@\S+\.\S+'),
      spanBuilder: (candidate) => WidgetSpan(
        child: Container(
          padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
          decoration: BoxDecoration(
            color: Colors.blue.shade100,
            borderRadius: BorderRadius.circular(16),
          ),
          child: Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              Text(candidate.text),
              GestureDetector(
                onTap: () { /* Remove chip */ },
                child: Icon(Icons.close, size: 16),
              ),
            ],
          ),
        ),
      ),
      options: const TextMatcherOptions(deleteOnBack: true),
    ),
  ],
)
RichifyController(
  text: 'Visit https://flutter.dev or call +1-234-567-8900',
  matchers: [
    RegexMatcher(
      pattern: RegExp(r'https?://[^\s]+'),
      spanBuilder: (candidate) => WidgetSpan(
        child: GestureDetector(
          onTap: () => launchUrl(Uri.parse(candidate.text)),
          child: Text(
            candidate.text,
            style: const TextStyle(
              color: Colors.blue,
              decoration: TextDecoration.underline,
            ),
          ),
        ),
      ),
      priority: 2, // Higher priority wins conflicts
    ),
    RegexMatcher(
      pattern: RegExp(r'\+?\d{1,3}[-.\\s]?\(?\d{1,4}\)?[-.\\s]?\d{1,4}[-.\\s]?\d{1,9}'),
      spanBuilder: (candidate) => WidgetSpan(
        child: GestureDetector(
          onTap: () => launchUrl(Uri.parse('tel:${candidate.text}')),
          child: Text(
            candidate.text,
            style: const TextStyle(color: Colors.orange),
          ),
        ),
      ),
      priority: 1,
    ),
  ],
)

Use with TextField #

TextField(
  controller: richifyController,
  decoration: const InputDecoration(
    hintText: 'Type @username or #hashtag...',
  ),
  maxLines: 3,
)

More Examples #

Custom Validation #

RegexMatcher(
  pattern: RegExp(r'@\w+'),
  validator: (candidate) {
    // Return null to skip invalid matches
    if (candidate.text == '@system') return null;
    // Return data map to accept and pass context
    return {'username': candidate.text.substring(1)};
  },
  spanBuilder: (candidate) => TextSpan(text: candidate.text),
)

Custom Matchers #

FunctionMatcher(
  finder: (context) {
    // Build your own matching logic, return list of MatchResult
    return [
      MatchResult(start: 0, end: 5, priority: 1),
    ];
  },
  spanBuilder: (candidate) => TextSpan(text: candidate.text),
)

Options #

TextMatcherOptions(
  deleteOnBack: true,  // Delete entire match on backspace
  jumpOver: true,      // Skip cursor over matches when navigating
)

RichifyController(
  blockCursorMovement: true,  // Force cursor after all matches
  matchers: [...],
)

RegexMatcher(
  priority: 2,  // Higher priority wins when patterns overlap
  ...
)
0
likes
150
points
46
downloads

Publisher

verified publisherdegenk.com

Weekly Downloads

A Flutter package to make it easy to create links, mentions, hashtags, emails, phones, and custom patterns.

Repository (GitHub)
View/report issues

Topics

#rich-text #textfield

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on flutter_richify