122 lines
4.0 KiB
Dart
122 lines
4.0 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import '../tema/pluriwave_tokens.dart';
|
|
import '../tema/pluriwave_theme.dart';
|
|
|
|
enum PluriIconGlyph { home, search, favorites, alarm, player, settings }
|
|
|
|
enum PluriIconVariant { outline, filled, activeGlow }
|
|
|
|
class PluriIcon extends StatelessWidget {
|
|
const PluriIcon({
|
|
super.key,
|
|
required this.glyph,
|
|
this.variant = PluriIconVariant.outline,
|
|
this.size = 24,
|
|
this.semanticLabel,
|
|
});
|
|
|
|
final PluriIconGlyph glyph;
|
|
final PluriIconVariant variant;
|
|
final double size;
|
|
final String? semanticLabel;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final tokens = context.pluriTokens;
|
|
final asset = _resolveAsset();
|
|
final resolvedColor = _resolveColor(context, tokens);
|
|
final icon =
|
|
asset == null
|
|
? Icon(_resolveData(), size: size, color: resolvedColor)
|
|
: Opacity(
|
|
opacity: variant == PluriIconVariant.outline ? 0.78 : 1,
|
|
child: Image.asset(
|
|
asset,
|
|
width: size,
|
|
height: size,
|
|
fit: BoxFit.contain,
|
|
errorBuilder:
|
|
(_, __, ___) =>
|
|
Icon(_resolveData(), size: size, color: resolvedColor),
|
|
),
|
|
);
|
|
final child =
|
|
variant == PluriIconVariant.activeGlow
|
|
? Container(
|
|
width: size + 14,
|
|
height: size + 14,
|
|
decoration: BoxDecoration(
|
|
shape: BoxShape.circle,
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: tokens.glowColor,
|
|
blurRadius: 18,
|
|
spreadRadius: 1,
|
|
),
|
|
],
|
|
),
|
|
alignment: Alignment.center,
|
|
child: icon,
|
|
)
|
|
: icon;
|
|
|
|
return Semantics(
|
|
label: semanticLabel ?? _fallbackLabel(glyph),
|
|
image: true,
|
|
child: ExcludeSemantics(child: child),
|
|
);
|
|
}
|
|
|
|
String? _resolveAsset() {
|
|
return switch (glyph) {
|
|
PluriIconGlyph.home => 'assets/icons/pluri_home.png',
|
|
PluriIconGlyph.search => 'assets/icons/pluri_search.png',
|
|
PluriIconGlyph.favorites => 'assets/icons/pluri_favorites.png',
|
|
PluriIconGlyph.alarm => 'assets/icons/pluri_alarm.png',
|
|
PluriIconGlyph.player => 'assets/icons/pluri_player.png',
|
|
PluriIconGlyph.settings => 'assets/icons/pluri_settings.png',
|
|
};
|
|
}
|
|
|
|
Color _resolveColor(BuildContext context, PluriWaveTokens tokens) {
|
|
if (variant == PluriIconVariant.activeGlow) return tokens.electricMagenta;
|
|
if (variant == PluriIconVariant.filled) {
|
|
return Theme.of(context).colorScheme.onSurface;
|
|
}
|
|
return Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.78);
|
|
}
|
|
|
|
IconData _resolveData() {
|
|
return switch ((glyph, variant)) {
|
|
(PluriIconGlyph.home, PluriIconVariant.outline) => Icons.home_outlined,
|
|
(PluriIconGlyph.home, _) => Icons.home_rounded,
|
|
(PluriIconGlyph.search, PluriIconVariant.outline) =>
|
|
Icons.search_outlined,
|
|
(PluriIconGlyph.search, _) => Icons.search_rounded,
|
|
(PluriIconGlyph.favorites, PluriIconVariant.outline) =>
|
|
Icons.favorite_border_rounded,
|
|
(PluriIconGlyph.favorites, _) => Icons.favorite_rounded,
|
|
(PluriIconGlyph.alarm, PluriIconVariant.outline) => Icons.alarm_outlined,
|
|
(PluriIconGlyph.alarm, _) => Icons.alarm_rounded,
|
|
(PluriIconGlyph.player, PluriIconVariant.outline) =>
|
|
Icons.play_circle_outline_rounded,
|
|
(PluriIconGlyph.player, _) => Icons.play_circle_rounded,
|
|
(PluriIconGlyph.settings, PluriIconVariant.outline) =>
|
|
Icons.settings_outlined,
|
|
(PluriIconGlyph.settings, _) => Icons.settings_rounded,
|
|
};
|
|
}
|
|
|
|
String _fallbackLabel(PluriIconGlyph glyph) {
|
|
return switch (glyph) {
|
|
PluriIconGlyph.home => 'Inicio',
|
|
PluriIconGlyph.search => 'Buscar',
|
|
PluriIconGlyph.favorites => 'Favoritos',
|
|
PluriIconGlyph.alarm => 'Alarmas',
|
|
PluriIconGlyph.player => 'Reproductor',
|
|
PluriIconGlyph.settings => 'Ajustes',
|
|
};
|
|
}
|
|
}
|