/// 轻量分段选择器(UI06 对齐 app-preview .tabs)。 /// /// 形态:#EDF1F6 轨道、padding 4、整体圆角 9;选中实底、未选次文字色。 /// 两种选中风格: /// - [SegmentTabsStyle.solid]:主蓝实底白字(上传中心筛选等状态筛选); /// - [SegmentTabsStyle.light]:#DBEAFF 底 + #145BB9 字(Details/Access 类 /// 内容页签——与状态筛选区分,见 app-preview .tabs.light)。 /// /// 替换默认 [SegmentedButton](M3 黑边胶囊形态与示例不符)。 library; import 'package:flutter/material.dart'; import '../tokens.dart'; enum SegmentTabsStyle { solid, light } class SegmentTabs extends StatelessWidget { const SegmentTabs({ required this.value, required this.onChanged, required this.segments, this.style = SegmentTabsStyle.solid, super.key, }); /// 当前值;null = 无高亮(次级筛选接管时的中间态)。 final T? value; final ValueChanged onChanged; /// 选项:值 + 本地化标签。 final List<(T, String)> segments; final SegmentTabsStyle style; @override Widget build(BuildContext context) { final theme = Theme.of(context); final light = style == SegmentTabsStyle.light; return Container( padding: const EdgeInsets.all(4), decoration: BoxDecoration( color: kColorSegTrack, borderRadius: BorderRadius.circular(9), ), child: Row( children: [ for (final (v, label) in segments) Expanded( child: _TabButton( label: label, selected: v == value, light: light, primary: theme.colorScheme.primary, onTap: () => onChanged(v), ), ), ], ), ); } } class _TabButton extends StatelessWidget { const _TabButton({ required this.label, required this.selected, required this.light, required this.primary, required this.onTap, }); final String label; final bool selected; final bool light; final Color primary; final VoidCallback onTap; @override Widget build(BuildContext context) { final Color bg; final Color fg; if (selected) { bg = light ? kColorSegLightActive : primary; fg = light ? kColorSegLightActiveText : Colors.white; } else { bg = Colors.transparent; fg = kColorTextSecondary; } return Semantics( button: true, selected: selected, child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(7), child: Container( alignment: Alignment.center, height: 36, padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 5), decoration: BoxDecoration( color: bg, borderRadius: BorderRadius.circular(7), ), child: Text( label, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 12, fontWeight: selected ? FontWeight.w600 : FontWeight.w500, color: fg, ), ), ), ), ); } }