andyduke / styled_text_package

Text widget with formatted text using tags. Makes it easier to use formatted text in multilingual applications.
https://pub.dev/packages/styled_text
BSD 3-Clause "New" or "Revised" License
74 stars 48 forks source link

Add SelectionArea compatibility #59

Closed BenjaminMeyerUA closed 1 year ago

BenjaminMeyerUA commented 1 year ago

Flutter 3.3 added the SelectionArea() widget, allowing all compatible child widget contents to be selectable (and allowing a selection to encompass multiple widgets). The styled_text_package uses an older implementation of .selectable, requiring an explicit per-widget choice of selectable and which is not compatible with SelectionArea().

For your consideration, I would like to suggest a small change in styled_text_package to enable SelectionArea compatibility:

In styled_text.dart, change the RichText() widget on line 369 to a Text.rich() widget, which includes the same functionality as RichText() and also has built-in integration with SelectionArea(). After this change, StyledText() is selectable or not based on whether it is a child widget of a SelectionArea().

Minimal reproducible example:


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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                StyledText(
                  text: 'Should not be selectable at all'
                ),
                SelectionArea(
                  child: Column(
                    children: <Widget>[
                      StyledText(
                        text: 'Can this text be selected?',
                      ),
                      StyledText(
                        text: 'How about this one?',
                      ),
                      StyledText(
                        text: '<bold>Or</bold> <italic>this</italic> one<big>?</big>',
                        tags:{
                          'bold': StyledTextTag(
                              style: TextStyle(fontWeight: FontWeight.bold)
                          ),
                          'italic': StyledTextTag(
                              style: TextStyle(fontStyle: FontStyle.italic)
                          ),
                          'big': StyledTextTag(
                              style: TextStyle(fontSize: 24)
                          )
                        }
                      ),
                    ]
                  ),
                ),
              ],
          ),
        ),
      ),
    );
  }
}

Suggested change (lines 369 to 388 in styled_text.dart, just changing to Text.rich and changing span to a positional argument):

return Text.rich(
    span,
    textAlign:
       widget.textAlign ?? defaultTextStyle.textAlign ?? TextAlign.start,
    textDirection: widget.textDirection,
    softWrap: widget.softWrap ?? defaultTextStyle.softWrap,
    overflow: widget.overflow ??
       effectiveTextStyle?.overflow ??
       defaultTextStyle.overflow,
    textScaleFactor:
        widget.textScaleFactor ?? MediaQuery.textScaleFactorOf(context),
    maxLines: widget.maxLines ?? defaultTextStyle.maxLines,
    locale: widget.locale,
    strutStyle: widget.strutStyle,
    textWidthBasis:
        widget.textWidthBasis ?? defaultTextStyle.textWidthBasis,
    textHeightBehavior: widget.textHeightBehavior ??
        defaultTextStyle.textHeightBehavior ??
        DefaultTextHeightBehavior.of(context),
);

Before changing styled_text.dart, the entire text is unselectable. After the suggested change, everything within the SelectionArea() is selectable. My example includes a StyledText() with multiple tags, to show that it still works across text composed of multiple spans.

I love styled_text_package, as it makes complex text formatting so much easier in Flutter. Hopefully this suggestion is implementable. Thanks!

andyduke commented 1 year ago

@BenjaminMeyerUA Check out version 6.0.0 which adds support for SelectionArea.

BenjaminMeyerUA commented 1 year ago

Looks good, thanks!