// widgets/ds/m_search_row.dart — 移动搜索行(镜像原型 m-stock-*-list 搜索区终态): // 搜索框(.m-search 42h, flex) + 纯文字状态钮(选中转 primary)+ 图标详细搜索钮(激活转 primary)。 // 状态/详搜钮为可选;不传对应回调即不渲染(如库存屏只有搜索框)。 import 'package:flutter/material.dart'; import 'package:lucide_icons_flutter/lucide_icons.dart'; import '../../core/theme/app_dims.g.dart'; import '../../core/theme/context_tokens.dart'; class MSearchRow extends StatelessWidget { final TextEditingController? controller; final String hint; final ValueChanged? onChanged; final ValueChanged? onSubmitted; /// 状态筛选钮当前文案(如「全部」「待审核」);null 不渲染该钮。 final String? statusLabel; /// 状态钮是否处于筛选中(非「全部」)→ primary 高亮。 final bool statusActive; final VoidCallback? onStatusTap; /// 详细搜索钮是否有生效条件 → primary 高亮;[onFilterTap] null 不渲染该钮。 final bool filterActive; final VoidCallback? onFilterTap; const MSearchRow({ super.key, this.controller, this.hint = '', this.onChanged, this.onSubmitted, this.statusLabel, this.statusActive = false, this.onStatusTap, this.filterActive = false, this.onFilterTap, }); @override Widget build(BuildContext context) { final t = context.tokens; return Row(children: [ // .m-search:42h / surface / border / r-md / 放大镜 17 // Material 自带(TextField 需 Material 祖先 + golden 直挂无 Scaffold 场景) Expanded( child: Material( color: t.surface, shape: RoundedRectangleBorder( side: BorderSide(color: t.border), borderRadius: BorderRadius.circular(AppDims.rMd), ), child: Container( height: 42, padding: const EdgeInsets.symmetric(horizontal: 12), child: Row(children: [ Icon(LucideIcons.search, size: 17, color: t.muted), const SizedBox(width: 8), Expanded( child: TextField( controller: controller, onChanged: onChanged, onSubmitted: onSubmitted, style: TextStyle(fontSize: AppDims.fsBody, color: t.text), decoration: InputDecoration( isCollapsed: true, contentPadding: EdgeInsets.zero, border: InputBorder.none, enabledBorder: InputBorder.none, focusedBorder: InputBorder.none, filled: false, hintText: hint, hintStyle: TextStyle(fontSize: AppDims.fsBody, color: t.faint), ), ), ), if (controller != null) ValueListenableBuilder( valueListenable: controller!, builder: (context, value, _) { if (value.text.isEmpty) return const SizedBox.shrink(); return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { controller!.clear(); onChanged?.call(''); onSubmitted?.call(''); }, child: Padding( padding: const EdgeInsets.only(left: 6), child: Icon(LucideIcons.x, size: 15, color: t.muted), ), ); }, ), ]), ), ), ), // 状态筛选钮(纯文字,无箭头;筛选中转 primary) if (statusLabel != null) ...[ const SizedBox(width: 8), _pillBtn( t, active: statusActive, onTap: onStatusTap, child: Text(statusLabel!, style: TextStyle( fontSize: AppDims.fsBody, fontWeight: statusActive ? FontWeight.w600 : FontWeight.w500, color: statusActive ? t.primary : t.text)), ), ], // 详细搜索钮(图标;有生效条件转 primary) if (onFilterTap != null) ...[ const SizedBox(width: 8), _pillBtn( t, active: filterActive, onTap: onFilterTap, child: Icon(LucideIcons.listFilter, size: 18, color: filterActive ? t.primary : t.text), ), ], ]); } Widget _pillBtn(dynamic t, {required bool active, VoidCallback? onTap, required Widget child}) { // Material 自带(InkWell 水波 + golden 直挂无 Scaffold 场景) return Material( color: active ? t.brand50 : t.surface, borderRadius: BorderRadius.circular(AppDims.rMd), child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(AppDims.rMd), child: Container( height: 42, padding: const EdgeInsets.symmetric(horizontal: 13), alignment: Alignment.center, decoration: BoxDecoration( border: Border.all(color: active ? t.primary : t.border), borderRadius: BorderRadius.circular(AppDims.rMd), ), child: child, ), ), ); } }