Showing
15 changed files
with
265 additions
and
8 deletions
| 1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
| 2 | import 'package:flutter/services.dart'; | 2 | import 'package:flutter/services.dart'; |
| 3 | 3 | ||
| 4 | +/// A widget that displays code with syntax highlighting and a copy button. | ||
| 5 | +/// | ||
| 6 | +/// The [CodeField] widget takes a [name] parameter which is displayed as a label | ||
| 7 | +/// above the code block, and a [codes] parameter containing the actual code text | ||
| 8 | +/// to display. | ||
| 9 | +/// | ||
| 10 | +/// Features: | ||
| 11 | +/// - Displays code in a Material container with rounded corners | ||
| 12 | +/// - Shows the code language/name as a label | ||
| 13 | +/// - Provides a copy button to copy code to clipboard | ||
| 14 | +/// - Visual feedback when code is copied | ||
| 15 | +/// - Themed colors that adapt to light/dark mode | ||
| 4 | class CodeField extends StatefulWidget { | 16 | class CodeField extends StatefulWidget { |
| 5 | const CodeField({super.key, required this.name, required this.codes}); | 17 | const CodeField({super.key, required this.name, required this.codes}); |
| 6 | final String name; | 18 | final String name; |
| 1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
| 2 | 2 | ||
| 3 | +/// A custom divider widget that extends LeafRenderObjectWidget. | ||
| 4 | +/// | ||
| 5 | +/// The [CustomDivider] widget is used to create a horizontal divider line in the UI. | ||
| 6 | +/// It takes an optional [color] parameter to specify the color of the divider, | ||
| 7 | +/// and an optional [height] parameter to set the height of the divider. | ||
| 8 | +/// | ||
| 3 | class CustomDivider extends LeafRenderObjectWidget { | 9 | class CustomDivider extends LeafRenderObjectWidget { |
| 4 | const CustomDivider({super.key, this.height, this.color}); | 10 | const CustomDivider({super.key, this.height, this.color}); |
| 11 | + | ||
| 12 | + /// The color of the divider. | ||
| 13 | + /// | ||
| 14 | + /// If not provided, the divider will use the color of the current theme. | ||
| 5 | final Color? color; | 15 | final Color? color; |
| 16 | + | ||
| 17 | + /// The height of the divider. | ||
| 18 | + /// | ||
| 19 | + /// If not provided, the divider will have a default height of 2. | ||
| 6 | final double? height; | 20 | final double? height; |
| 7 | 21 | ||
| 8 | @override | 22 | @override |
| @@ -25,6 +39,12 @@ class CustomDivider extends LeafRenderObjectWidget { | @@ -25,6 +39,12 @@ class CustomDivider extends LeafRenderObjectWidget { | ||
| 25 | } | 39 | } |
| 26 | } | 40 | } |
| 27 | 41 | ||
| 42 | +/// A custom render object for the [CustomDivider] widget. | ||
| 43 | +/// | ||
| 44 | +/// The [RenderDivider] class extends RenderBox and is responsible for | ||
| 45 | +/// painting the divider line. It takes a [color], [width], and [height] | ||
| 46 | +/// and uses them to draw a horizontal line in the UI. | ||
| 47 | +/// | ||
| 28 | class RenderDivider extends RenderBox { | 48 | class RenderDivider extends RenderBox { |
| 29 | RenderDivider(Color color, double width, double height) | 49 | RenderDivider(Color color, double width, double height) |
| 30 | : _color = color, | 50 | : _color = color, |
| @@ -33,6 +53,8 @@ class RenderDivider extends RenderBox { | @@ -33,6 +53,8 @@ class RenderDivider extends RenderBox { | ||
| 33 | Color _color; | 53 | Color _color; |
| 34 | double _height; | 54 | double _height; |
| 35 | double _width; | 55 | double _width; |
| 56 | + | ||
| 57 | + /// The color of the divider. | ||
| 36 | set color(Color value) { | 58 | set color(Color value) { |
| 37 | if (value == _color) { | 59 | if (value == _color) { |
| 38 | return; | 60 | return; |
| @@ -41,6 +63,7 @@ class RenderDivider extends RenderBox { | @@ -41,6 +63,7 @@ class RenderDivider extends RenderBox { | ||
| 41 | markNeedsPaint(); | 63 | markNeedsPaint(); |
| 42 | } | 64 | } |
| 43 | 65 | ||
| 66 | + /// The height of the divider. | ||
| 44 | set height(double value) { | 67 | set height(double value) { |
| 45 | if (value == _height) { | 68 | if (value == _height) { |
| 46 | return; | 69 | return; |
| @@ -49,6 +72,7 @@ class RenderDivider extends RenderBox { | @@ -49,6 +72,7 @@ class RenderDivider extends RenderBox { | ||
| 49 | markNeedsLayout(); | 72 | markNeedsLayout(); |
| 50 | } | 73 | } |
| 51 | 74 | ||
| 75 | + /// The width of the divider. | ||
| 52 | set width(double value) { | 76 | set width(double value) { |
| 53 | if (value == _width) { | 77 | if (value == _width) { |
| 54 | return; | 78 | return; |
| @@ -3,6 +3,13 @@ import 'dart:math'; | @@ -3,6 +3,13 @@ import 'dart:math'; | ||
| 3 | import 'package:flutter/material.dart'; | 3 | import 'package:flutter/material.dart'; |
| 4 | import 'package:flutter/rendering.dart'; | 4 | import 'package:flutter/rendering.dart'; |
| 5 | 5 | ||
| 6 | +/// A custom widget that displays an error image with customizable colors. | ||
| 7 | +/// | ||
| 8 | +/// The [CustomImageError] widget is used to display an error image in the UI. | ||
| 9 | +/// It takes an optional [iconColor], [backgroundColor], and [outlineColor] parameter | ||
| 10 | +/// to customize the appearance of the error image. | ||
| 11 | +/// | ||
| 12 | + | ||
| 6 | class CustomImageError extends LeafRenderObjectWidget { | 13 | class CustomImageError extends LeafRenderObjectWidget { |
| 7 | const CustomImageError({ | 14 | const CustomImageError({ |
| 8 | super.key, | 15 | super.key, |
| @@ -38,6 +45,13 @@ class CustomImageError extends LeafRenderObjectWidget { | @@ -38,6 +45,13 @@ class CustomImageError extends LeafRenderObjectWidget { | ||
| 38 | } | 45 | } |
| 39 | } | 46 | } |
| 40 | 47 | ||
| 48 | +/// A custom render object for the [CustomImageError] widget. | ||
| 49 | +/// | ||
| 50 | +/// The [RenderCustomImageError] class extends RenderProxyBox and is responsible for | ||
| 51 | +/// painting the error image. It takes a [iconColor], [backgroundColor], and [outlineColor] | ||
| 52 | +/// and uses them to draw an error image in the UI. | ||
| 53 | +/// | ||
| 54 | + | ||
| 41 | class RenderCustomImageError extends RenderProxyBox { | 55 | class RenderCustomImageError extends RenderProxyBox { |
| 42 | RenderCustomImageError( | 56 | RenderCustomImageError( |
| 43 | this._iconColor, | 57 | this._iconColor, |
| @@ -47,6 +61,8 @@ class RenderCustomImageError extends RenderProxyBox { | @@ -47,6 +61,8 @@ class RenderCustomImageError extends RenderProxyBox { | ||
| 47 | Color _iconColor; | 61 | Color _iconColor; |
| 48 | Color _outlineColor; | 62 | Color _outlineColor; |
| 49 | Color _backgroundColor; | 63 | Color _backgroundColor; |
| 64 | + | ||
| 65 | + /// The color of the icon. | ||
| 50 | set iconColor(Color value) { | 66 | set iconColor(Color value) { |
| 51 | if (value == _iconColor) { | 67 | if (value == _iconColor) { |
| 52 | return; | 68 | return; |
| @@ -55,6 +71,7 @@ class RenderCustomImageError extends RenderProxyBox { | @@ -55,6 +71,7 @@ class RenderCustomImageError extends RenderProxyBox { | ||
| 55 | markNeedsPaint(); | 71 | markNeedsPaint(); |
| 56 | } | 72 | } |
| 57 | 73 | ||
| 74 | + /// The background color of the error image. | ||
| 58 | set backgroundColor(Color value) { | 75 | set backgroundColor(Color value) { |
| 59 | if (value == _backgroundColor) { | 76 | if (value == _backgroundColor) { |
| 60 | return; | 77 | return; |
| @@ -63,6 +80,7 @@ class RenderCustomImageError extends RenderProxyBox { | @@ -63,6 +80,7 @@ class RenderCustomImageError extends RenderProxyBox { | ||
| 63 | markNeedsPaint(); | 80 | markNeedsPaint(); |
| 64 | } | 81 | } |
| 65 | 82 | ||
| 83 | + /// The outline color of the error image. | ||
| 66 | set outlineColor(Color value) { | 84 | set outlineColor(Color value) { |
| 67 | if (value == _outlineColor) { | 85 | if (value == _outlineColor) { |
| 68 | return; | 86 | return; |
| @@ -125,6 +143,13 @@ class RenderCustomImageError extends RenderProxyBox { | @@ -125,6 +143,13 @@ class RenderCustomImageError extends RenderProxyBox { | ||
| 125 | } | 143 | } |
| 126 | } | 144 | } |
| 127 | 145 | ||
| 146 | +/// A custom widget that displays a loading image with customizable colors. | ||
| 147 | +/// | ||
| 148 | +/// The [CustomImageLoading] widget is used to display a loading image in the UI. | ||
| 149 | +/// It takes an optional [iconColor], [backgroundColor], [outlineColor], and [progress] parameter | ||
| 150 | +/// to customize the appearance of the loading image. | ||
| 151 | +/// | ||
| 152 | + | ||
| 128 | class CustomImageLoading extends LeafRenderObjectWidget { | 153 | class CustomImageLoading extends LeafRenderObjectWidget { |
| 129 | const CustomImageLoading({ | 154 | const CustomImageLoading({ |
| 130 | super.key, | 155 | super.key, |
| @@ -133,9 +158,17 @@ class CustomImageLoading extends LeafRenderObjectWidget { | @@ -133,9 +158,17 @@ class CustomImageLoading extends LeafRenderObjectWidget { | ||
| 133 | this.outlineColor, | 158 | this.outlineColor, |
| 134 | this.progress = 1, | 159 | this.progress = 1, |
| 135 | }); | 160 | }); |
| 161 | + | ||
| 162 | + /// The color of the icon. | ||
| 136 | final Color? iconColor; | 163 | final Color? iconColor; |
| 164 | + | ||
| 165 | + /// The background color of the loading image. | ||
| 137 | final Color? backgroundColor; | 166 | final Color? backgroundColor; |
| 167 | + | ||
| 168 | + /// The outline color of the loading image. | ||
| 138 | final Color? outlineColor; | 169 | final Color? outlineColor; |
| 170 | + | ||
| 171 | + /// The progress of the loading image. | ||
| 139 | final double progress; | 172 | final double progress; |
| 140 | 173 | ||
| 141 | @override | 174 | @override |
| @@ -164,6 +197,13 @@ class CustomImageLoading extends LeafRenderObjectWidget { | @@ -164,6 +197,13 @@ class CustomImageLoading extends LeafRenderObjectWidget { | ||
| 164 | } | 197 | } |
| 165 | } | 198 | } |
| 166 | 199 | ||
| 200 | +/// A custom render object for the [CustomImageLoading] widget. | ||
| 201 | +/// | ||
| 202 | +/// The [RenderCustomImageLoading] class extends RenderProxyBox and is responsible for | ||
| 203 | +/// painting the loading image. It takes a [iconColor], [backgroundColor], [outlineColor], and [progress] | ||
| 204 | +/// and uses them to draw a loading image in the UI. | ||
| 205 | +/// | ||
| 206 | + | ||
| 167 | class RenderCustomImageLoading extends RenderProxyBox { | 207 | class RenderCustomImageLoading extends RenderProxyBox { |
| 168 | RenderCustomImageLoading( | 208 | RenderCustomImageLoading( |
| 169 | this._iconColor, | 209 | this._iconColor, |
| 1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
| 2 | 2 | ||
| 3 | +/// A custom radio button widget that extends StatelessWidget. | ||
| 4 | +/// | ||
| 5 | +/// The [CustomRb] widget is used to create a radio button in the UI. | ||
| 6 | +/// It takes a [child] parameter which is the content of the radio button, | ||
| 7 | +/// a [value] parameter which is the value of the radio button, | ||
| 8 | +/// and an optional [spacing] parameter to set the spacing between the radio button and its label. | ||
| 3 | class CustomRb extends StatelessWidget { | 9 | class CustomRb extends StatelessWidget { |
| 4 | const CustomRb({ | 10 | const CustomRb({ |
| 5 | super.key, | 11 | super.key, |
| @@ -45,6 +51,12 @@ class CustomRb extends StatelessWidget { | @@ -45,6 +51,12 @@ class CustomRb extends StatelessWidget { | ||
| 45 | } | 51 | } |
| 46 | } | 52 | } |
| 47 | 53 | ||
| 54 | +/// A custom checkbox widget that extends StatelessWidget. | ||
| 55 | +/// | ||
| 56 | +/// The [CustomCb] widget is used to create a checkbox in the UI. | ||
| 57 | +/// It takes a [child] parameter which is the content of the checkbox, | ||
| 58 | +/// a [value] parameter which is the value of the checkbox, | ||
| 59 | +/// and an optional [spacing] parameter to set the spacing between the checkbox and its label. | ||
| 48 | class CustomCb extends StatelessWidget { | 60 | class CustomCb extends StatelessWidget { |
| 49 | const CustomCb({ | 61 | const CustomCb({ |
| 50 | super.key, | 62 | super.key, |
| 1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
| 2 | 2 | ||
| 3 | +/// A custom widget that adds an indent to the left or right of its child. | ||
| 4 | +/// | ||
| 5 | +/// The [IndentWidget] widget is used to create a visual indent in the UI. | ||
| 6 | +/// It takes a [child] parameter which is the content of the widget, | ||
| 7 | +/// a [direction] parameter which specifies the direction of the indent, | ||
| 8 | +/// and a [color] parameter to set the color of the indent. | ||
| 3 | class IndentWidget extends StatelessWidget { | 9 | class IndentWidget extends StatelessWidget { |
| 4 | const IndentWidget({ | 10 | const IndentWidget({ |
| 5 | super.key, | 11 | super.key, |
| @@ -7,8 +13,14 @@ class IndentWidget extends StatelessWidget { | @@ -7,8 +13,14 @@ class IndentWidget extends StatelessWidget { | ||
| 7 | required this.direction, | 13 | required this.direction, |
| 8 | required this.color, | 14 | required this.color, |
| 9 | }); | 15 | }); |
| 16 | + | ||
| 17 | + /// The child widget to be indented. | ||
| 10 | final Widget child; | 18 | final Widget child; |
| 19 | + | ||
| 20 | + /// The direction of the indent. | ||
| 11 | final TextDirection direction; | 21 | final TextDirection direction; |
| 22 | + | ||
| 23 | + /// The color of the indent. | ||
| 12 | final Color color; | 24 | final Color color; |
| 13 | 25 | ||
| 14 | @override | 26 | @override |
| @@ -20,6 +32,11 @@ class IndentWidget extends StatelessWidget { | @@ -20,6 +32,11 @@ class IndentWidget extends StatelessWidget { | ||
| 20 | } | 32 | } |
| 21 | } | 33 | } |
| 22 | 34 | ||
| 35 | +/// A custom painter that draws an indent on a canvas. | ||
| 36 | +/// | ||
| 37 | +/// The [IndentPainter] class extends CustomPainter and is responsible for | ||
| 38 | +/// painting the indent on a canvas. It takes a [color] and [direction] parameter | ||
| 39 | +/// and uses them to draw an indent in the UI. | ||
| 23 | class IndentPainter extends CustomPainter { | 40 | class IndentPainter extends CustomPainter { |
| 24 | IndentPainter(this.color, this.direction); | 41 | IndentPainter(this.color, this.direction); |
| 25 | final Color color; | 42 | final Color color; |
| @@ -2,13 +2,33 @@ import 'package:flutter/material.dart'; | @@ -2,13 +2,33 @@ import 'package:flutter/material.dart'; | ||
| 2 | 2 | ||
| 3 | import 'markdown_config.dart'; | 3 | import 'markdown_config.dart'; |
| 4 | 4 | ||
| 5 | +/// A custom button widget that displays a link with customizable colors and styles. | ||
| 6 | +/// | ||
| 7 | +/// The [LinkButton] widget is used to create a button that displays a link in the UI. | ||
| 8 | +/// It takes a [text] parameter which is the text of the link, | ||
| 9 | +/// a [config] parameter which is the configuration for the link, | ||
| 10 | +/// a [color] parameter to set the color of the link, | ||
| 11 | + | ||
| 5 | class LinkButton extends StatefulWidget { | 12 | class LinkButton extends StatefulWidget { |
| 13 | + /// The text of the link. | ||
| 6 | final String text; | 14 | final String text; |
| 15 | + | ||
| 16 | + /// The callback function to be called when the link is pressed. | ||
| 7 | final VoidCallback? onPressed; | 17 | final VoidCallback? onPressed; |
| 18 | + | ||
| 19 | + /// The style of the text. | ||
| 8 | final TextStyle? textStyle; | 20 | final TextStyle? textStyle; |
| 21 | + | ||
| 22 | + /// The URL of the link. | ||
| 9 | final String? url; | 23 | final String? url; |
| 24 | + | ||
| 25 | + /// The configuration for the link. | ||
| 10 | final GptMarkdownConfig config; | 26 | final GptMarkdownConfig config; |
| 27 | + | ||
| 28 | + /// The color of the link. | ||
| 11 | final Color color; | 29 | final Color color; |
| 30 | + | ||
| 31 | + /// The color of the link when hovering. | ||
| 12 | final Color hoverColor; | 32 | final Color hoverColor; |
| 13 | 33 | ||
| 14 | const LinkButton({ | 34 | const LinkButton({ |
| 1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
| 2 | 2 | ||
| 3 | +/// A configuration class for the GPT Markdown component. | ||
| 4 | +/// | ||
| 5 | +/// The [GptMarkdownConfig] class is used to configure the GPT Markdown component. | ||
| 6 | +/// It takes a [style] parameter to set the style of the text, | ||
| 7 | +/// a [textDirection] parameter to set the direction of the text, | ||
| 8 | +/// and an optional [onLinkTab] parameter to handle link clicks. | ||
| 3 | class GptMarkdownConfig { | 9 | class GptMarkdownConfig { |
| 4 | const GptMarkdownConfig({ | 10 | const GptMarkdownConfig({ |
| 5 | this.style, | 11 | this.style, |
| @@ -18,12 +24,26 @@ class GptMarkdownConfig { | @@ -18,12 +24,26 @@ class GptMarkdownConfig { | ||
| 18 | this.maxLines, | 24 | this.maxLines, |
| 19 | this.overflow, | 25 | this.overflow, |
| 20 | }); | 26 | }); |
| 27 | + | ||
| 28 | + /// The direction of the text. | ||
| 21 | final TextDirection textDirection; | 29 | final TextDirection textDirection; |
| 30 | + | ||
| 31 | + /// The style of the text. | ||
| 22 | final TextStyle? style; | 32 | final TextStyle? style; |
| 33 | + | ||
| 34 | + /// The alignment of the text. | ||
| 23 | final TextAlign? textAlign; | 35 | final TextAlign? textAlign; |
| 36 | + | ||
| 37 | + /// The text scaler. | ||
| 24 | final TextScaler? textScaler; | 38 | final TextScaler? textScaler; |
| 39 | + | ||
| 40 | + /// The callback function to handle link clicks. | ||
| 25 | final void Function(String url, String title)? onLinkTab; | 41 | final void Function(String url, String title)? onLinkTab; |
| 42 | + | ||
| 43 | + /// The LaTeX workaround. | ||
| 26 | final String Function(String tex)? latexWorkaround; | 44 | final String Function(String tex)? latexWorkaround; |
| 45 | + | ||
| 46 | + /// The LaTeX builder. | ||
| 27 | final Widget Function( | 47 | final Widget Function( |
| 28 | BuildContext context, | 48 | BuildContext context, |
| 29 | String tex, | 49 | String tex, |
| @@ -31,13 +51,19 @@ class GptMarkdownConfig { | @@ -31,13 +51,19 @@ class GptMarkdownConfig { | ||
| 31 | bool inline, | 51 | bool inline, |
| 32 | )? | 52 | )? |
| 33 | latexBuilder; | 53 | latexBuilder; |
| 54 | + | ||
| 55 | + /// The source tag builder. | ||
| 34 | final Widget Function( | 56 | final Widget Function( |
| 35 | BuildContext context, | 57 | BuildContext context, |
| 36 | String content, | 58 | String content, |
| 37 | TextStyle textStyle, | 59 | TextStyle textStyle, |
| 38 | )? | 60 | )? |
| 39 | sourceTagBuilder; | 61 | sourceTagBuilder; |
| 62 | + | ||
| 63 | + /// Whether to follow the link color. | ||
| 40 | final bool followLinkColor; | 64 | final bool followLinkColor; |
| 65 | + | ||
| 66 | + /// The code builder. | ||
| 41 | final Widget Function( | 67 | final Widget Function( |
| 42 | BuildContext context, | 68 | BuildContext context, |
| 43 | String name, | 69 | String name, |
| @@ -45,8 +71,14 @@ class GptMarkdownConfig { | @@ -45,8 +71,14 @@ class GptMarkdownConfig { | ||
| 45 | bool closed, | 71 | bool closed, |
| 46 | )? | 72 | )? |
| 47 | codeBuilder; | 73 | codeBuilder; |
| 74 | + | ||
| 75 | + /// The maximum number of lines. | ||
| 48 | final int? maxLines; | 76 | final int? maxLines; |
| 77 | + | ||
| 78 | + /// The overflow. | ||
| 49 | final TextOverflow? overflow; | 79 | final TextOverflow? overflow; |
| 80 | + | ||
| 81 | + /// The highlight builder. | ||
| 50 | final Widget Function(BuildContext context, String text, TextStyle style)? | 82 | final Widget Function(BuildContext context, String text, TextStyle style)? |
| 51 | highlightBuilder; | 83 | highlightBuilder; |
| 52 | final Widget Function( | 84 | final Widget Function( |
| @@ -56,8 +88,11 @@ class GptMarkdownConfig { | @@ -56,8 +88,11 @@ class GptMarkdownConfig { | ||
| 56 | TextStyle style, | 88 | TextStyle style, |
| 57 | )? | 89 | )? |
| 58 | linkBuilder; | 90 | linkBuilder; |
| 91 | + | ||
| 92 | + /// The image builder. | ||
| 59 | final Widget Function(BuildContext, String imageUrl)? imageBuilder; | 93 | final Widget Function(BuildContext, String imageUrl)? imageBuilder; |
| 60 | 94 | ||
| 95 | + /// A copy of the configuration with the specified parameters. | ||
| 61 | GptMarkdownConfig copyWith({ | 96 | GptMarkdownConfig copyWith({ |
| 62 | TextStyle? style, | 97 | TextStyle? style, |
| 63 | TextDirection? textDirection, | 98 | TextDirection? textDirection, |
| @@ -118,6 +153,7 @@ class GptMarkdownConfig { | @@ -118,6 +153,7 @@ class GptMarkdownConfig { | ||
| 118 | ); | 153 | ); |
| 119 | } | 154 | } |
| 120 | 155 | ||
| 156 | + /// A method to get a rich text widget from an inline span. | ||
| 121 | Text getRich(InlineSpan span) { | 157 | Text getRich(InlineSpan span) { |
| 122 | return Text.rich( | 158 | return Text.rich( |
| 123 | span, | 159 | span, |
| 1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
| 2 | import 'package:flutter/rendering.dart'; | 2 | import 'package:flutter/rendering.dart'; |
| 3 | 3 | ||
| 4 | +/// A custom widget that allows text selection in a widget. | ||
| 5 | +/// | ||
| 6 | +/// The [SelectableAdapter] widget is used to create a widget that allows text selection. | ||
| 7 | +/// It takes a [child] parameter which is the content of the widget, | ||
| 8 | +/// and a [selectedText] parameter which is the text to be selected. | ||
| 4 | class SelectableAdapter extends StatelessWidget { | 9 | class SelectableAdapter extends StatelessWidget { |
| 5 | const SelectableAdapter({ | 10 | const SelectableAdapter({ |
| 6 | super.key, | 11 | super.key, |
| 1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
| 2 | 2 | ||
| 3 | +/// A custom widget that displays an unordered list of items. | ||
| 4 | +/// | ||
| 5 | +/// The [UnorderedListView] widget is used to create a list of items with bullet points. | ||
| 6 | +/// It takes a [child] parameter which is the content of the list item, | ||
| 7 | +/// a [spacing] parameter to set the spacing between items, | ||
| 8 | +/// a [padding] parameter to set the padding of the list item, | ||
| 3 | class UnorderedListView extends StatelessWidget { | 9 | class UnorderedListView extends StatelessWidget { |
| 4 | const UnorderedListView({ | 10 | const UnorderedListView({ |
| 5 | super.key, | 11 | super.key, |
| @@ -10,11 +16,21 @@ class UnorderedListView extends StatelessWidget { | @@ -10,11 +16,21 @@ class UnorderedListView extends StatelessWidget { | ||
| 10 | this.textDirection = TextDirection.ltr, | 16 | this.textDirection = TextDirection.ltr, |
| 11 | required this.child, | 17 | required this.child, |
| 12 | }); | 18 | }); |
| 19 | + | ||
| 20 | + /// The size of the bullet point. | ||
| 13 | final double bulletSize; | 21 | final double bulletSize; |
| 22 | + | ||
| 23 | + /// The spacing between items. | ||
| 14 | final double spacing; | 24 | final double spacing; |
| 25 | + | ||
| 26 | + /// The padding of the list item. | ||
| 15 | final double padding; | 27 | final double padding; |
| 16 | final TextDirection textDirection; | 28 | final TextDirection textDirection; |
| 29 | + | ||
| 30 | + /// The color of the bullet point. | ||
| 17 | final Color? bulletColor; | 31 | final Color? bulletColor; |
| 32 | + | ||
| 33 | + /// The child widget to be displayed in the list item. | ||
| 18 | final Widget child; | 34 | final Widget child; |
| 19 | 35 | ||
| 20 | @override | 36 | @override |
| @@ -54,6 +70,12 @@ class UnorderedListView extends StatelessWidget { | @@ -54,6 +70,12 @@ class UnorderedListView extends StatelessWidget { | ||
| 54 | } | 70 | } |
| 55 | } | 71 | } |
| 56 | 72 | ||
| 73 | +/// A custom widget that displays an ordered list of items. | ||
| 74 | +/// | ||
| 75 | +/// The [OrderedListView] widget is used to create a list of items with numbered points. | ||
| 76 | +/// It takes a [child] parameter which is the content of the list item, | ||
| 77 | +/// a [spacing] parameter to set the spacing between items, | ||
| 78 | +/// a [padding] parameter to set the padding of the list item, | ||
| 57 | class OrderedListView extends StatelessWidget { | 79 | class OrderedListView extends StatelessWidget { |
| 58 | final String no; | 80 | final String no; |
| 59 | final double spacing; | 81 | final double spacing; |
| @@ -67,8 +89,14 @@ class OrderedListView extends StatelessWidget { | @@ -67,8 +89,14 @@ class OrderedListView extends StatelessWidget { | ||
| 67 | this.textDirection = TextDirection.ltr, | 89 | this.textDirection = TextDirection.ltr, |
| 68 | required this.no, | 90 | required this.no, |
| 69 | }) : _style = style; | 91 | }) : _style = style; |
| 92 | + | ||
| 93 | + /// The style of the text. | ||
| 70 | final TextStyle? _style; | 94 | final TextStyle? _style; |
| 95 | + | ||
| 96 | + /// The direction of the text. | ||
| 71 | final TextDirection textDirection; | 97 | final TextDirection textDirection; |
| 98 | + | ||
| 99 | + /// The child widget to be displayed in the list item. | ||
| 72 | final Widget child; | 100 | final Widget child; |
| 73 | 101 | ||
| 74 | @override | 102 | @override |
| @@ -39,15 +39,33 @@ class GptMarkdown extends StatelessWidget { | @@ -39,15 +39,33 @@ class GptMarkdown extends StatelessWidget { | ||
| 39 | this.maxLines, | 39 | this.maxLines, |
| 40 | this.overflow, | 40 | this.overflow, |
| 41 | }); | 41 | }); |
| 42 | + | ||
| 43 | + /// The direction of the text. | ||
| 42 | final TextDirection textDirection; | 44 | final TextDirection textDirection; |
| 45 | + | ||
| 46 | + /// The data to be displayed. | ||
| 43 | final String data; | 47 | final String data; |
| 48 | + | ||
| 49 | + /// The style of the text. | ||
| 44 | final TextStyle? style; | 50 | final TextStyle? style; |
| 51 | + | ||
| 52 | + /// The alignment of the text. | ||
| 45 | final TextAlign? textAlign; | 53 | final TextAlign? textAlign; |
| 54 | + | ||
| 55 | + /// The text scaler. | ||
| 46 | final TextScaler? textScaler; | 56 | final TextScaler? textScaler; |
| 57 | + | ||
| 58 | + /// The callback function to handle link clicks. | ||
| 47 | final void Function(String url, String title)? onLinkTab; | 59 | final void Function(String url, String title)? onLinkTab; |
| 60 | + | ||
| 61 | + /// The LaTeX workaround. | ||
| 48 | final String Function(String tex)? latexWorkaround; | 62 | final String Function(String tex)? latexWorkaround; |
| 49 | final int? maxLines; | 63 | final int? maxLines; |
| 64 | + | ||
| 65 | + /// The overflow. | ||
| 50 | final TextOverflow? overflow; | 66 | final TextOverflow? overflow; |
| 67 | + | ||
| 68 | + /// The LaTeX builder. | ||
| 51 | final Widget Function( | 69 | final Widget Function( |
| 52 | BuildContext context, | 70 | BuildContext context, |
| 53 | String tex, | 71 | String tex, |
| @@ -55,7 +73,11 @@ class GptMarkdown extends StatelessWidget { | @@ -55,7 +73,11 @@ class GptMarkdown extends StatelessWidget { | ||
| 55 | bool inline, | 73 | bool inline, |
| 56 | )? | 74 | )? |
| 57 | latexBuilder; | 75 | latexBuilder; |
| 76 | + | ||
| 77 | + /// Whether to follow the link color. | ||
| 58 | final bool followLinkColor; | 78 | final bool followLinkColor; |
| 79 | + | ||
| 80 | + /// The code builder. | ||
| 59 | final Widget Function( | 81 | final Widget Function( |
| 60 | BuildContext context, | 82 | BuildContext context, |
| 61 | String name, | 83 | String name, |
| @@ -63,9 +85,15 @@ class GptMarkdown extends StatelessWidget { | @@ -63,9 +85,15 @@ class GptMarkdown extends StatelessWidget { | ||
| 63 | bool closed, | 85 | bool closed, |
| 64 | )? | 86 | )? |
| 65 | codeBuilder; | 87 | codeBuilder; |
| 88 | + | ||
| 89 | + /// The source tag builder. | ||
| 66 | final Widget Function(BuildContext, String, TextStyle)? sourceTagBuilder; | 90 | final Widget Function(BuildContext, String, TextStyle)? sourceTagBuilder; |
| 91 | + | ||
| 92 | + /// The highlight builder. | ||
| 67 | final Widget Function(BuildContext context, String text, TextStyle style)? | 93 | final Widget Function(BuildContext context, String text, TextStyle style)? |
| 68 | highlightBuilder; | 94 | highlightBuilder; |
| 95 | + | ||
| 96 | + /// The link builder. | ||
| 69 | final Widget Function( | 97 | final Widget Function( |
| 70 | BuildContext context, | 98 | BuildContext context, |
| 71 | String text, | 99 | String text, |
| @@ -73,7 +101,11 @@ class GptMarkdown extends StatelessWidget { | @@ -73,7 +101,11 @@ class GptMarkdown extends StatelessWidget { | ||
| 73 | TextStyle style, | 101 | TextStyle style, |
| 74 | )? | 102 | )? |
| 75 | linkBuilder; | 103 | linkBuilder; |
| 104 | + | ||
| 105 | + /// The image builder. | ||
| 76 | final Widget Function(BuildContext, String imageUrl)? imageBuilder; | 106 | final Widget Function(BuildContext, String imageUrl)? imageBuilder; |
| 107 | + | ||
| 108 | + /// A method to remove extra lines inside block LaTeX. | ||
| 77 | String _removeExtraLinesInsideBlockLatex(String text) { | 109 | String _removeExtraLinesInsideBlockLatex(String text) { |
| 78 | return text.replaceAllMapped( | 110 | return text.replaceAllMapped( |
| 79 | RegExp(r"\\\[(.*?)\\\]", multiLine: true, dotAll: true), | 111 | RegExp(r"\\\[(.*?)\\\]", multiLine: true, dotAll: true), |
| @@ -755,11 +755,14 @@ class ImageMd extends InlineMd { | @@ -755,11 +755,14 @@ class ImageMd extends InlineMd { | ||
| 755 | width = double.tryParse(size?[1]?.toString().trim() ?? 'a'); | 755 | width = double.tryParse(size?[1]?.toString().trim() ?? 'a'); |
| 756 | height = double.tryParse(size?[2]?.toString().trim() ?? 'a'); | 756 | height = double.tryParse(size?[2]?.toString().trim() ?? 'a'); |
| 757 | } | 757 | } |
| 758 | - late final Widget image; | 758 | + final Widget image; |
| 759 | if (config.imageBuilder != null) { | 759 | if (config.imageBuilder != null) { |
| 760 | image = config.imageBuilder!(context, '${match?[2]}'); | 760 | image = config.imageBuilder!(context, '${match?[2]}'); |
| 761 | } else { | 761 | } else { |
| 762 | - image = Image( | 762 | + image = SizedBox( |
| 763 | + width: width, | ||
| 764 | + height: height, | ||
| 765 | + child: Image( | ||
| 763 | image: NetworkImage("${match?[2]}"), | 766 | image: NetworkImage("${match?[2]}"), |
| 764 | loadingBuilder: ( | 767 | loadingBuilder: ( |
| 765 | BuildContext context, | 768 | BuildContext context, |
| @@ -781,12 +784,10 @@ class ImageMd extends InlineMd { | @@ -781,12 +784,10 @@ class ImageMd extends InlineMd { | ||
| 781 | errorBuilder: (context, error, stackTrace) { | 784 | errorBuilder: (context, error, stackTrace) { |
| 782 | return const CustomImageError(); | 785 | return const CustomImageError(); |
| 783 | }, | 786 | }, |
| 787 | + ), | ||
| 784 | ); | 788 | ); |
| 785 | } | 789 | } |
| 786 | - return WidgetSpan( | ||
| 787 | - alignment: PlaceholderAlignment.bottom, | ||
| 788 | - child: SizedBox(width: width, height: height, child: image), | ||
| 789 | - ); | 790 | + return WidgetSpan(alignment: PlaceholderAlignment.bottom, child: image); |
| 790 | } | 791 | } |
| 791 | } | 792 | } |
| 792 | 793 |
| @@ -3,7 +3,11 @@ part of 'gpt_markdown.dart'; | @@ -3,7 +3,11 @@ part of 'gpt_markdown.dart'; | ||
| 3 | /// It creates a markdown widget closed to each other. | 3 | /// It creates a markdown widget closed to each other. |
| 4 | class MdWidget extends StatelessWidget { | 4 | class MdWidget extends StatelessWidget { |
| 5 | const MdWidget(this.exp, {super.key, required this.config}); | 5 | const MdWidget(this.exp, {super.key, required this.config}); |
| 6 | + | ||
| 7 | + /// The expression to be displayed. | ||
| 6 | final String exp; | 8 | final String exp; |
| 9 | + | ||
| 10 | + /// The configuration of the markdown widget. | ||
| 7 | final GptMarkdownConfig config; | 11 | final GptMarkdownConfig config; |
| 8 | 12 | ||
| 9 | @override | 13 | @override |
| @@ -32,6 +36,7 @@ class MdWidget extends StatelessWidget { | @@ -32,6 +36,7 @@ class MdWidget extends StatelessWidget { | ||
| 32 | } | 36 | } |
| 33 | } | 37 | } |
| 34 | 38 | ||
| 39 | +/// A custom table column width. | ||
| 35 | class CustomTableColumnWidth extends TableColumnWidth { | 40 | class CustomTableColumnWidth extends TableColumnWidth { |
| 36 | @override | 41 | @override |
| 37 | double maxIntrinsicWidth(Iterable<RenderBox> cells, double containerWidth) { | 42 | double maxIntrinsicWidth(Iterable<RenderBox> cells, double containerWidth) { |
| @@ -16,6 +16,7 @@ class GptMarkdownThemeData extends ThemeExtension<GptMarkdownThemeData> { | @@ -16,6 +16,7 @@ class GptMarkdownThemeData extends ThemeExtension<GptMarkdownThemeData> { | ||
| 16 | required this.linkHoverColor, | 16 | required this.linkHoverColor, |
| 17 | }); | 17 | }); |
| 18 | 18 | ||
| 19 | + /// A factory constructor for `GptMarkdownThemeData`. | ||
| 19 | factory GptMarkdownThemeData({ | 20 | factory GptMarkdownThemeData({ |
| 20 | required Brightness brightness, | 21 | required Brightness brightness, |
| 21 | Color? highlightColor, | 22 | Color? highlightColor, |
| @@ -89,19 +90,38 @@ class GptMarkdownThemeData extends ThemeExtension<GptMarkdownThemeData> { | @@ -89,19 +90,38 @@ class GptMarkdownThemeData extends ThemeExtension<GptMarkdownThemeData> { | ||
| 89 | ); | 90 | ); |
| 90 | } | 91 | } |
| 91 | 92 | ||
| 93 | + /// The highlight color. | ||
| 92 | Color highlightColor; | 94 | Color highlightColor; |
| 95 | + | ||
| 96 | + /// The style of the h1 text. | ||
| 93 | TextStyle? h1; | 97 | TextStyle? h1; |
| 98 | + | ||
| 99 | + /// The style of the h2 text. | ||
| 94 | TextStyle? h2; | 100 | TextStyle? h2; |
| 101 | + | ||
| 102 | + /// The style of the h3 text. | ||
| 95 | TextStyle? h3; | 103 | TextStyle? h3; |
| 104 | + | ||
| 105 | + /// The style of the h4 text. | ||
| 96 | TextStyle? h4; | 106 | TextStyle? h4; |
| 107 | + | ||
| 108 | + /// The style of the h5 text. | ||
| 97 | TextStyle? h5; | 109 | TextStyle? h5; |
| 110 | + | ||
| 111 | + /// The style of the h6 text. | ||
| 98 | TextStyle? h6; | 112 | TextStyle? h6; |
| 99 | double hrLineThickness; | 113 | double hrLineThickness; |
| 114 | + | ||
| 115 | + /// The color of the horizontal line. | ||
| 100 | Color hrLineColor; | 116 | Color hrLineColor; |
| 117 | + | ||
| 118 | + /// The color of the link. | ||
| 101 | Color linkColor; | 119 | Color linkColor; |
| 120 | + | ||
| 121 | + /// The color of the link when hovering. | ||
| 102 | Color linkHoverColor; | 122 | Color linkHoverColor; |
| 103 | 123 | ||
| 104 | - /// Define default attributes. | 124 | + /// A method to copy the `GptMarkdownThemeData`. |
| 105 | @override | 125 | @override |
| 106 | GptMarkdownThemeData copyWith({ | 126 | GptMarkdownThemeData copyWith({ |
| 107 | Color? highlightColor, | 127 | Color? highlightColor, |
| @@ -166,6 +186,7 @@ class GptMarkdownTheme extends InheritedWidget { | @@ -166,6 +186,7 @@ class GptMarkdownTheme extends InheritedWidget { | ||
| 166 | }); | 186 | }); |
| 167 | final GptMarkdownThemeData gptThemeData; | 187 | final GptMarkdownThemeData gptThemeData; |
| 168 | 188 | ||
| 189 | + /// A method to get the `GptMarkdownThemeData` from the `BuildContext`. | ||
| 169 | static GptMarkdownThemeData of(BuildContext context) { | 190 | static GptMarkdownThemeData of(BuildContext context) { |
| 170 | var theme = Theme.of(context); | 191 | var theme = Theme.of(context); |
| 171 | final provider = | 192 | final provider = |
| 1 | name: gpt_markdown | 1 | name: gpt_markdown |
| 2 | description: "Powerful Markdown & LaTeX Renderer for Flutter: Rich Text, Math, Tables, Links, and Text Selection. Ideal for ChatGPT, Gemini, and more." | 2 | description: "Powerful Markdown & LaTeX Renderer for Flutter: Rich Text, Math, Tables, Links, and Text Selection. Ideal for ChatGPT, Gemini, and more." |
| 3 | -version: 1.0.11 | 3 | +version: 1.0.12 |
| 4 | homepage: https://github.com/Infinitix-LLC/gpt_markdown | 4 | homepage: https://github.com/Infinitix-LLC/gpt_markdown |
| 5 | 5 | ||
| 6 | environment: | 6 | environment: |
-
Please register or login to post a comment