feat: enrich product visual depth
This commit is contained in:
@@ -37,17 +37,16 @@ class JourneyOverviewPanel extends StatelessWidget {
|
||||
return SurfacePanel(
|
||||
elevated: true,
|
||||
padding: EdgeInsets.zero,
|
||||
color: scheme.surfaceContainerLowest,
|
||||
borderColor: scheme.outlineVariant.withValues(alpha: 0.45),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.fromLTRB(18, 16, 16, 18),
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
colors: [
|
||||
scheme.primary.withValues(alpha: 0.12),
|
||||
scheme.surfaceContainerLowest,
|
||||
scheme.secondary.withValues(alpha: 0.07),
|
||||
scheme.primary.withValues(alpha: 0.20),
|
||||
scheme.surfaceContainerLowest.withValues(alpha: 0.96),
|
||||
scheme.secondary.withValues(alpha: 0.14),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -64,23 +63,46 @@ class JourneyOverviewPanel extends StatelessWidget {
|
||||
onReflect: onReflect,
|
||||
);
|
||||
if (compact) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
return Stack(
|
||||
children: [
|
||||
const Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: SeedIllustration(size: 88),
|
||||
const Positioned(
|
||||
right: -18,
|
||||
top: -20,
|
||||
child: Opacity(
|
||||
opacity: 0.58,
|
||||
child: SeedIllustration(size: 128, hero: true),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 17, 106, 18),
|
||||
child: textContent,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
textContent,
|
||||
],
|
||||
);
|
||||
}
|
||||
return Row(
|
||||
return Stack(
|
||||
children: [
|
||||
Expanded(child: textContent),
|
||||
const SizedBox(width: 12),
|
||||
const SeedIllustration(size: 112),
|
||||
Positioned(
|
||||
right: -28,
|
||||
top: -22,
|
||||
bottom: -18,
|
||||
child: Opacity(
|
||||
opacity: 0.96,
|
||||
child: SeedIllustration(
|
||||
size: constraints.maxWidth.clamp(146, 184).toDouble(),
|
||||
hero: true,
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
right: 92,
|
||||
bottom: 18,
|
||||
child: _ProgressBadge(completed: completed),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(18, 17, 168, 18),
|
||||
child: textContent,
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
@@ -140,16 +162,9 @@ class _OverviewText extends StatelessWidget {
|
||||
color: scheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 14),
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(99),
|
||||
child: LinearProgressIndicator(
|
||||
minHeight: 8,
|
||||
value: progressValue,
|
||||
backgroundColor: scheme.surfaceContainerHigh,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
const SizedBox(height: 16),
|
||||
_ProgressSeeds(completed: completed, progressValue: progressValue),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
@@ -172,3 +187,86 @@ class _OverviewText extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ProgressSeeds extends StatelessWidget {
|
||||
const _ProgressSeeds({required this.completed, required this.progressValue});
|
||||
|
||||
final int completed;
|
||||
final double progressValue;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final scheme = Theme.of(context).colorScheme;
|
||||
return Semantics(
|
||||
value: '${(progressValue * 100).round()}%',
|
||||
child: Row(
|
||||
children: List.generate(4, (index) {
|
||||
final filled = index < completed;
|
||||
return Expanded(
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 220),
|
||||
curve: Curves.easeOutCubic,
|
||||
height: 10,
|
||||
margin: EdgeInsets.only(right: index == 3 ? 0 : 7),
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
filled
|
||||
? scheme.primary
|
||||
: scheme.surfaceContainerHigh.withValues(alpha: 0.82),
|
||||
borderRadius: BorderRadius.circular(99),
|
||||
boxShadow:
|
||||
filled
|
||||
? [
|
||||
BoxShadow(
|
||||
color: scheme.primary.withValues(alpha: 0.28),
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
]
|
||||
: null,
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ProgressBadge extends StatelessWidget {
|
||||
const _ProgressBadge({required this.completed});
|
||||
|
||||
final int completed;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final scheme = Theme.of(context).colorScheme;
|
||||
final theme = Theme.of(context);
|
||||
return DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: scheme.surfaceContainerLowest.withValues(alpha: 0.82),
|
||||
borderRadius: BorderRadius.circular(99),
|
||||
border: Border.all(
|
||||
color: scheme.outlineVariant.withValues(alpha: 0.65),
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.10),
|
||||
blurRadius: 14,
|
||||
offset: const Offset(0, 7),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 11, vertical: 7),
|
||||
child: Text(
|
||||
'$completed/4',
|
||||
style: theme.textTheme.labelLarge?.copyWith(
|
||||
color: scheme.primary,
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user