rounded_background_text 0.6.0 copy "rounded_background_text: ^0.6.0" to clipboard
rounded_background_text: ^0.6.0 copied to clipboard

Text, TextField and TextSpan highlighted with rounded corners

example/lib/main.dart

import 'dart:math';

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

final _primaryAndAccentColors = [...Colors.primaries, ...Colors.accents];

enum _HighlightTextType { field, text, span, selectableText }

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

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late final ScrollController colorsController;
  final controller = TextEditingController();

  double fontSize = 20.0;
  double innerRadius = kDefaultInnerRadius;
  double outerRadius = kDefaultOuterRadius;

  TextAlign textAlign = TextAlign.center;
  FontWeight fontWeight = FontWeight.bold;
  _HighlightTextType type = _HighlightTextType.text;

  late Color selectedColor;

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

    final initialIndex = Random().nextInt(_primaryAndAccentColors.length);
    selectedColor = _primaryAndAccentColors[initialIndex];

    colorsController = ScrollController(
      initialScrollOffset: 40.0 * initialIndex,
    );
  }

  @override
  void dispose() {
    controller.dispose();
    colorsController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Rounded Background Showcase',
      theme: ThemeData(primarySwatch: Colors.blue, brightness: Brightness.dark),
      home: Scaffold(
        body: SafeArea(
          child: Column(
            children: [
              Material(
                child: Row(
                  children: [
                    const VerticalDivider(),
                    Expanded(
                      child: DropdownButton<FontWeight>(
                        isExpanded: true,
                        value: fontWeight,
                        onChanged: (w) => setState(
                          () => fontWeight = w ?? FontWeight.normal,
                        ),
                        icon: const Icon(Icons.format_bold),
                        items: FontWeight.values.map((e) {
                          return DropdownMenuItem(
                            value: e,
                            child: Text('$e'.replaceAll('FontWeight.', '')),
                          );
                        }).toList(),
                      ),
                    ),
                    const VerticalDivider(),
                    Expanded(
                      child: DropdownButton<TextAlign>(
                        value: textAlign,
                        onChanged: (align) => setState(
                          () => textAlign = align ?? TextAlign.center,
                        ),
                        icon: Icon(() {
                          switch (textAlign) {
                            case TextAlign.center:
                              return Icons.format_align_center;
                            case TextAlign.end:
                            case TextAlign.right:
                              return Icons.format_align_right;
                            case TextAlign.start:
                            case TextAlign.left:
                              return Icons.format_align_left;
                            default:
                              return null;
                          }
                        }()),
                        isExpanded: true,
                        items: const [
                          DropdownMenuItem(
                            value: TextAlign.start,
                            child: Text('Start'),
                          ),
                          DropdownMenuItem(
                            value: TextAlign.center,
                            child: Text('Center'),
                          ),
                          DropdownMenuItem(
                            value: TextAlign.end,
                            child: Text('End'),
                          ),
                        ],
                      ),
                    ),
                    const VerticalDivider(),
                    Expanded(
                      child: DropdownButton<_HighlightTextType>(
                        value: type,
                        onChanged: (t) => setState(
                          () => type = t ?? _HighlightTextType.field,
                        ),
                        icon: const Icon(Icons.text_fields),
                        isExpanded: true,
                        items: const [
                          DropdownMenuItem(
                            value: _HighlightTextType.field,
                            child: Text('Field'),
                          ),
                          DropdownMenuItem(
                            value: _HighlightTextType.text,
                            child: Text('Text'),
                          ),
                          DropdownMenuItem(
                            value: _HighlightTextType.selectableText,
                            child: Text('Selectable Text'),
                          ),
                          DropdownMenuItem(
                            value: _HighlightTextType.span,
                            child: Text('Span'),
                          ),
                        ],
                      ),
                    ),
                    const VerticalDivider(),
                  ],
                ),
              ),
              Expanded(
                child: Padding(
                  padding: const EdgeInsets.all(12.0),
                  child: Center(
                    child: () {
                      final textColor = selectedColor.computeLuminance() > 0.5
                          ? Colors.black
                          : Colors.white;
                      switch (type) {
                        case _HighlightTextType.field:
                          return RoundedBackgroundTextField(
                            controller: controller,
                            backgroundColor: selectedColor,
                            textAlign: textAlign,
                            hint: 'Type your text here',
                            style: TextStyle(
                              fontSize: fontSize,
                              fontWeight: fontWeight,
                              color: textColor,
                            ),
                            innerRadius: innerRadius,
                            outerRadius: outerRadius,
                          );
                        case _HighlightTextType.text:
                          return GestureDetector(
                            onTap: () {
                              debugPrint('Text tapped');
                            },
                            child: RoundedBackgroundText(
                              '''Rounded Background Text Showcase
It handles well all font sizes and weights, as well as text alignments
Contributions are welcome!
Done with so much <3 by @bdlukaa''',
                              backgroundColor: selectedColor,
                              textAlign: textAlign,
                              style: TextStyle(
                                fontSize: fontSize,
                                fontWeight: fontWeight,
                                color: textColor,
                              ),
                              innerRadius: innerRadius,
                              outerRadius: outerRadius,
                            ),
                          );
                        case _HighlightTextType.selectableText:
                          return TextSelectionTheme(
                            data: TextSelectionThemeData(
                              selectionColor: Colors.blue.withOpacity(0.7),
                            ),
                            child: RoundedBackgroundText.selectable(
                              '''Rounded Background Text Showcase

It handles well all font sizes and weights, as well as text alignments
Contributions are welcome!
Done with so much <3 by @bdlukaa''',
                              backgroundColor: selectedColor,
                              textAlign: textAlign,
                              style: TextStyle(
                                fontSize: fontSize,
                                fontWeight: fontWeight,
                                color: textColor,
                              ),
                              innerRadius: innerRadius,
                              outerRadius: outerRadius,
                            ),
                          );
                        case _HighlightTextType.span:
                          return RichText(
                            textAlign: textAlign,
                            text: TextSpan(
                              text: 'You can use this to ',
                              style: TextStyle(
                                fontSize: fontSize,
                                fontWeight: fontWeight,
                                color: Colors.white,
                              ),
                              children: [
                                RoundedBackgroundTextSpan(
                                  text:
                                      'highlight important stuff inside a text',
                                  backgroundColor: selectedColor,
                                  innerRadius: innerRadius,
                                  outerRadius: outerRadius,
                                  textAlign: textAlign,
                                  style: TextStyle(
                                    fontSize: fontSize,
                                    fontWeight: fontWeight,
                                    color: textColor,
                                  ),
                                ),
                                const TextSpan(text: ' and stuff like that'),
                              ],
                            ),
                          );
                      }
                    }(),
                  ),
                ),
              ),
              Row(
                children: [
                  GestureDetector(
                    onTap: () {
                      colorsController.animateTo(
                        (colorsController.position.pixels - 40),
                        duration: const Duration(milliseconds: 300),
                        curve: Curves.ease,
                      );
                    },
                    child: const Icon(Icons.chevron_left),
                  ),
                  const Spacer(),
                  GestureDetector(
                    onTap: () {
                      colorsController.animateTo(
                        (colorsController.position.pixels + 40),
                        duration: const Duration(milliseconds: 300),
                        curve: Curves.ease,
                      );
                    },
                    child: const Icon(Icons.chevron_right),
                  ),
                ],
              ),
              Material(
                child: SingleChildScrollView(
                  controller: colorsController,
                  padding: const EdgeInsets.only(
                    left: 8.0,
                    right: 8.0,
                    top: 8.0,
                  ),
                  scrollDirection: Axis.horizontal,
                  child: Wrap(
                    runSpacing: 10.0,
                    spacing: 10.0,
                    alignment: WrapAlignment.center,
                    children: _primaryAndAccentColors.map((color) {
                      return MouseRegion(
                        cursor: SystemMouseCursors.click,
                        child: GestureDetector(
                          onTap: () => setState(() => selectedColor = color),
                          child: AnimatedContainer(
                            duration: kThemeChangeDuration,
                            curve: Curves.bounceInOut,
                            height: 30.0,
                            width: 30.0,
                            decoration: BoxDecoration(
                              color: color,
                              borderRadius: BorderRadius.circular(2.0),
                              border: Border.all(
                                color: color.computeLuminance() > 0.5
                                    ? Colors.black
                                    : Colors.white,
                                width: 2.5,
                                style: selectedColor == color
                                    ? BorderStyle.solid
                                    : BorderStyle.none,
                              ),
                            ),
                          ),
                        ),
                      );
                    }).toList(),
                  ),
                ),
              ),
              Material(
                child: Row(
                  children: [
                    Expanded(
                      child: Slider(
                        onChanged: (v) => setState(() => fontSize = v),
                        value: fontSize,
                        min: 8,
                        max: 30,
                        divisions: 30 - 8,
                        label: '${fontSize.toInt()}',
                      ),
                    ),
                    Expanded(
                      child: Slider(
                        onChanged: (v) => setState(() => innerRadius = v),
                        value: innerRadius,
                        min: 0,
                        max: 20,
                        label: '${innerRadius.toInt()}',
                        divisions: 20,
                      ),
                    ),
                    Expanded(
                      child: Slider(
                        onChanged: (v) => setState(() => outerRadius = v),
                        value: outerRadius,
                        min: 0,
                        max: 20,
                        label: '${outerRadius.toInt()}',
                        divisions: 20,
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
copied to clipboard
92
likes
150
points
2.75k
downloads

Publisher

verified publisherbdlukaa.dev

Weekly Downloads

2024.09.15 - 2025.03.30

Text, TextField and TextSpan highlighted with rounded corners

Repository (GitHub)

Documentation

API reference

License

BSD-3-Clause (license)

Dependencies

flutter

More

Packages that depend on rounded_background_text