Three reusable rendering widgets in lib/widgets/: - ClideMarkdown: walks markdown AST (GFM tables, task lists, fenced code), renders headings, lists, blockquotes, tables, inline bold/italic/code/links. Delegates code blocks to ClideCodeBlock. - ClideCodeBlock: syntax-highlighted code via TreeSitterService. Async highlight, byte-to-char offset mapping, theme-aware colors from SurfaceTokens. - ClideSvgView: wraps jovial_svg with asset/string constructors and optional sizing. Retrofitted: decision detail body renders as markdown instead of raw text. Markdown viewer uses ClideMarkdown. Welcome logo uses ClideSvgView. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
34 lines
1.0 KiB
Dart
34 lines
1.0 KiB
Dart
import 'package:flutter/services.dart' show rootBundle;
|
|
import 'package:flutter/widgets.dart';
|
|
import 'package:jovial_svg/jovial_svg.dart';
|
|
|
|
class ClideSvgView extends StatelessWidget {
|
|
const ClideSvgView.asset(this.assetPath, {super.key, this.width, this.height}) : svgString = null;
|
|
const ClideSvgView.string(this.svgString, {super.key, this.width, this.height}) : assetPath = null;
|
|
|
|
final String? assetPath;
|
|
final String? svgString;
|
|
final double? width;
|
|
final double? height;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
Widget child;
|
|
if (assetPath != null) {
|
|
child = ScalableImageWidget.fromSISource(
|
|
si: ScalableImageSource.fromSvg(rootBundle, assetPath!),
|
|
);
|
|
} else if (svgString != null) {
|
|
final si = ScalableImage.fromSvgString(svgString!);
|
|
child = ScalableImageWidget(si: si);
|
|
} else {
|
|
return const SizedBox.shrink();
|
|
}
|
|
|
|
if (width != null || height != null) {
|
|
child = SizedBox(width: width, height: height, child: child);
|
|
}
|
|
return child;
|
|
}
|
|
}
|