Files
Dmitry 62d36aa3e8 feat(app): новый визуальный язык, верхняя навигация, портфели, создание счетов и ручные события
Тема и общие виджеты (AssetIcon, ServiceMark, HelpTip, глоссарий), верхняя панель TopNav и вкладки Аналитики вместо NavSidebar, иконки PWA. Экраны: портфели, создание брокерского счёта, ручное событие, правка инструмента, Обзор карточками по скоупам и таблица активов, пересчёт метрик с опросом /metrics/status. design-system.md обновлён.
2026-09-19 22:14:21 +03:00

111 lines
2.9 KiB
Dart

import 'package:flutter/material.dart';
import 'help_tip.dart';
/// A titled card section, the layout unit the phase-4 screens are built from (the same
/// shape Портфель already uses inline).
class SectionCard extends StatelessWidget {
const SectionCard({
required this.title,
required this.child,
this.subtitle,
this.trailing,
super.key,
});
final String title;
final String? subtitle;
final Widget? trailing;
final Widget child;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TermLabel(title, style: theme.textTheme.titleMedium),
if (subtitle != null)
Padding(
padding: const EdgeInsets.only(top: 2),
child: Text(
subtitle!,
style: theme.textTheme.bodySmall?.copyWith(
color: theme.hintColor,
),
),
),
],
),
),
?trailing,
],
),
const SizedBox(height: 12),
child,
],
),
),
);
}
}
/// A compact labelled number, used for the summary rows of the phase-4 screens.
class StatTile extends StatelessWidget {
const StatTile({
required this.label,
required this.value,
this.note,
this.width = 184,
super.key,
});
final String label;
final Widget value;
final String? note;
final double width;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return SizedBox(
width: width,
child: Card(
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TermLabel(label, style: theme.textTheme.bodySmall),
const SizedBox(height: 4),
DefaultTextStyle(
style: theme.textTheme.titleMedium!,
child: value,
),
if (note != null) ...[
const SizedBox(height: 2),
Text(
note!,
style: theme.textTheme.bodySmall?.copyWith(
color: theme.hintColor,
),
maxLines: 3,
),
],
],
),
),
),
);
}
}