mirror of
https://github.com/we-promise/sure.git
synced 2026-07-18 15:55:22 +00:00
Introduce a SureIcon design-system primitive that renders bundled Lucide SVGs via flutter_svg (already a dependency — no new dep), mirroring the web `icon` helper / DS::FilledIcon: tokenized size (SureIconSize xs–2xl = 12–32), color inherited from the ambient IconTheme by default, and accessibility that distinguishes decorative icons (excluded from the semantics tree) from meaningful ones (semanticLabel). A SureIcons registry keeps call sites typo-safe and limited to bundled assets. Migrate the dashboard surface off Material Icons.* onto SureIcon — 24 call sites across net_worth_card, account_card, and dashboard_screen (account-type glyphs, asset/liability trend icons, sync/empty/error states, refresh, collapsible section headers, expand chevrons). Bundle the 17 Lucide SVGs the surface needs under assets/icons/lucide/ with the ISC license. The swipe Undo control and the rest of the app's icons follow in later slices. Part of #2235. Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
68 lines
2.0 KiB
Dart
68 lines
2.0 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_svg/flutter_svg.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:sure_mobile/widgets/sure_icon.dart';
|
|
|
|
void main() {
|
|
SvgPicture svg(WidgetTester tester) =>
|
|
tester.widget<SvgPicture>(find.byType(SvgPicture));
|
|
|
|
testWidgets('renders the named Lucide asset at the requested size',
|
|
(tester) async {
|
|
await tester.pumpWidget(
|
|
const MaterialApp(
|
|
home: SureIcon(SureIcons.wallet, size: SureIconSize.lg),
|
|
),
|
|
);
|
|
expect(svg(tester).width, SureIconSize.lg);
|
|
expect(svg(tester).height, SureIconSize.lg);
|
|
});
|
|
|
|
testWidgets('paints at its size inside a larger tight-constrained parent',
|
|
(tester) async {
|
|
await tester.pumpWidget(
|
|
const MaterialApp(
|
|
home: Center(
|
|
child: SizedBox(
|
|
width: 48,
|
|
height: 48,
|
|
child: SureIcon(SureIcons.landmark, size: SureIconSize.lg),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
// The glyph must stay 24 (not stretch to the 48 container) — regression for
|
|
// the account-card icon rendering at 2x.
|
|
expect(tester.getSize(find.byType(SvgPicture)), const Size(24, 24));
|
|
});
|
|
|
|
testWidgets('falls back to the ambient IconTheme size when size is null',
|
|
(tester) async {
|
|
await tester.pumpWidget(
|
|
const MaterialApp(
|
|
home: IconTheme(
|
|
data: IconThemeData(size: 30),
|
|
child: SureIcon(SureIcons.refresh),
|
|
),
|
|
),
|
|
);
|
|
expect(svg(tester).width, 30);
|
|
expect(svg(tester).height, 30);
|
|
});
|
|
|
|
testWidgets('a meaningful icon exposes its label; a decorative one does not',
|
|
(tester) async {
|
|
await tester.pumpWidget(
|
|
const MaterialApp(
|
|
home: SureIcon(SureIcons.refresh, semanticLabel: 'Refresh'),
|
|
),
|
|
);
|
|
expect(find.bySemanticsLabel('Refresh'), findsOneWidget);
|
|
|
|
await tester.pumpWidget(
|
|
const MaterialApp(home: SureIcon(SureIcons.wallet)),
|
|
);
|
|
expect(find.bySemanticsLabel('wallet'), findsNothing);
|
|
});
|
|
}
|