feat(app): SectionHeader и TileCarousel — общие виджеты редизайна
SectionHeader — заголовок блока с короткой акцентной полоской вместо разделителя. TileCarousel — горизонтальная прокрутка StatTile вместо Wrap, не требует общей высоты у детей. Оба без экрана-потребителя пока не влияют на вид приложения.
This commit is contained in:
@@ -0,0 +1,44 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// A bold section title with a short accent underline beneath its left edge — the
|
||||||
|
/// Grimmory-style marker for "a new block starts here" that replaces a divider line.
|
||||||
|
/// For a titled card use [SectionCard] instead; this is for a bare block of content
|
||||||
|
/// (a chart, a row of tiles, a list) that isn't wrapped in a card of its own.
|
||||||
|
class SectionHeader extends StatelessWidget {
|
||||||
|
const SectionHeader({required this.title, this.trailing, super.key});
|
||||||
|
|
||||||
|
final String title;
|
||||||
|
final Widget? trailing;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
return Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
title,
|
||||||
|
style: theme.textTheme.titleLarge?.copyWith(fontWeight: FontWeight.w800),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 6),
|
||||||
|
Container(
|
||||||
|
width: 28,
|
||||||
|
height: 3,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: theme.colorScheme.primary,
|
||||||
|
borderRadius: BorderRadius.circular(2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
?trailing,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// A horizontally scrolling row of tiles — the Grimmory-style carousel, used on the
|
||||||
|
/// dashboard in place of a [Wrap] of [StatTile]s so a long row of metrics scrolls
|
||||||
|
/// instead of wrapping onto a second, uneven line.
|
||||||
|
class TileCarousel extends StatelessWidget {
|
||||||
|
const TileCarousel({required this.children, super.key});
|
||||||
|
|
||||||
|
final List<Widget> children;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: IntrinsicHeight(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
for (var i = 0; i < children.length; i++) ...[
|
||||||
|
if (i > 0) const SizedBox(width: 12),
|
||||||
|
children[i],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user