/ app / lib / widgets / themed_icon.dart
themed_icon.dart
 1  import 'package:flutter/material.dart';
 2  import 'package:iconify_flutter/iconify_flutter.dart';
 3  
 4  /// Themed wrapper around [Iconify] that inherits color from [IconTheme]
 5  /// just like Material [Icon] does. When no [color] is specified, uses
 6  /// `IconTheme.of(context).color`.
 7  ///
 8  /// The Majesticons `_line` SVGs in iconify_flutter ship with
 9  /// `fill="currentColor"` on closed shapes, making stroke-based icons
10  /// appear solid. This widget patches those SVGs: when an SVG has both
11  /// fill and stroke attributes, fill is set to "none" so only the
12  /// stroke renders. Fill-only SVGs (path-cutout outlines) are left
13  /// untouched.
14  class ThemedIcon extends StatelessWidget {
15    final String icon;
16    final Color? color;
17    final double? size;
18  
19    const ThemedIcon(
20      this.icon, {
21      super.key,
22      this.color,
23      this.size,
24    });
25  
26    /// Patch stroke-based SVGs: when both fill and stroke are present,
27    /// remove fill so only the stroke outline renders. Leave fill-only
28    /// SVGs (path-cutout icons) untouched.
29    static String _patchOutlineSvg(String svg) {
30      if (svg.contains('stroke="currentColor"') &&
31          svg.contains('fill="currentColor"')) {
32        return svg.replaceAll('fill="currentColor"', 'fill="none"');
33      }
34      return svg;
35    }
36  
37    @override
38    Widget build(BuildContext context) {
39      final svgData = _patchOutlineSvg(icon);
40      return Iconify(
41        svgData,
42        color: color ?? IconTheme.of(context).color,
43        size: size ?? IconTheme.of(context).size ?? 24,
44      );
45    }
46  }