Skip to content

Instantly share code, notes, and snippets.

@hectorAguero
Last active November 28, 2025 16:29
Show Gist options
  • Select an option

  • Save hectorAguero/5dacba92d017d8ee42d2583577c77806 to your computer and use it in GitHub Desktop.

Select an option

Save hectorAguero/5dacba92d017d8ee42d2583577c77806 to your computer and use it in GitHub Desktop.
Strip HTML from Text Widget
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HtmlStripConfig(
pattern: RegExp(CustomText.noHtmlPattern),
child: Scaffold(
body: Center(
child: Column(
mainAxisSize: .min,
spacing: 16,
children: [
MyCustomWidget(title: '<p>Hello, World!</p>'),
MyCustomWidget(title: '<p>Hello, World!</p>'),
],
),
),
),
),
);
}
}
class MyCustomWidget extends StatelessWidget {
const MyCustomWidget({super.key, required this.title});
final String title;
@override
Widget build(BuildContext context) {
return Card(
child: Padding(padding: .all(8.0), child: CustomText(title)),
);
}
}
/// A styled [Text] widget to show text
class CustomText extends StatelessWidget {
/// Creates a styled text widget with customizable properties.
const CustomText(
this.text, {
this.style,
this.textAlign,
this.overflow,
this.maxLines,
this.semanticsLabel,
this.htmlStripPattern,
super.key,
});
/// Creates a styled text widget from a value with basic styling.
factory CustomText.noHtml(
String text, {
TextAlign? textAlign,
TextStyle? style,
String? semanticsLabel,
TextOverflow? overflow,
int? maxLines,
}) => CustomText(
text,
style: style,
textAlign: textAlign,
overflow: overflow,
maxLines: maxLines,
semanticsLabel: semanticsLabel,
htmlStripPattern: CustomText.noHtmlPattern,
);
/// Text value to display with default styling.
final String text;
/// style for the text
final TextStyle? style;
/// Text alignment for the text.
final TextAlign? textAlign;
/// Text overflow behavior for the text.
final TextOverflow? overflow;
/// Maximum number of lines for the text.
final int? maxLines;
/// Semantics label for the text, used for accessibility.
final String? semanticsLabel;
/// Regular expression pattern to strip HTML tags from the text.
final String? htmlStripPattern;
/// Default pattern to strip HTML tags from the text.
static const String noHtmlPattern = '<[^>]*>';
@override
Widget build(BuildContext context) {
final inheritedPattern = HtmlStripConfig.of(context);
final pattern = htmlStripPattern ?? inheritedPattern;
final cleanText = pattern != null ? text.replaceAll(pattern, '') : text;
return Text(
cleanText,
textAlign: textAlign,
overflow: overflow,
maxLines: maxLines,
semanticsLabel: semanticsLabel,
style: style,
);
}
}
/// An inherited widget to provide HTML stripping configuration to descendants.
class HtmlStripConfig extends InheritedWidget {
/// Creates an HtmlStripConfig widget.
const HtmlStripConfig({
required this.pattern,
required super.child,
super.key,
});
/// Regular expression pattern to strip HTML tags.
final RegExp pattern;
/// Retrieves the HTML stripping pattern from the nearest HtmlStripConfig.
static RegExp? of(BuildContext context) {
final widget = context
.dependOnInheritedWidgetOfExactType<HtmlStripConfig>();
return widget?.pattern;
}
@override
bool updateShouldNotify(HtmlStripConfig oldWidget) {
return oldWidget.pattern != pattern;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment