form_field_row.dart 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import '../../core/theme/app_colors.dart';
  2. import 'package:flutter/material.dart';
  3. import '../../core/theme/app_colors_extension.dart';
  4. /// 表单字段行,左侧标签 + 右侧值 + 可选箭头。
  5. ///
  6. /// [required] 为 true 时标签前显示红色星号。
  7. class FormFieldRow extends StatelessWidget {
  8. final String label;
  9. final String? value;
  10. final String? hint;
  11. final bool showArrow;
  12. final bool readOnly;
  13. final bool required;
  14. final VoidCallback? onTap;
  15. const FormFieldRow({
  16. super.key,
  17. required this.label,
  18. this.value,
  19. this.hint,
  20. this.showArrow = true,
  21. this.readOnly = false,
  22. this.required = false,
  23. this.onTap,
  24. });
  25. @override
  26. Widget build(BuildContext context) {
  27. final colors = Theme.of(context).extension<AppColorsExtension>()!;
  28. final hasValue = value != null && value!.isNotEmpty;
  29. return GestureDetector(
  30. onTap: onTap,
  31. behavior: HitTestBehavior.opaque,
  32. child: Container(
  33. padding: EdgeInsets.zero,
  34. child: Row(
  35. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  36. children: [
  37. Text.rich(
  38. TextSpan(
  39. children: [
  40. TextSpan(
  41. text: label,
  42. style: TextStyle(
  43. fontSize: AppFontSizes.subtitle,
  44. color: colors.textSecondary,
  45. ),
  46. ),
  47. if (required)
  48. TextSpan(
  49. text: ' *',
  50. style: TextStyle(
  51. fontSize: AppFontSizes.subtitle,
  52. color: colors.danger,
  53. ),
  54. ),
  55. ],
  56. ),
  57. ),
  58. Row(
  59. mainAxisSize: MainAxisSize.min,
  60. children: [
  61. Text(
  62. hasValue ? value! : (hint ?? '请选择或填写'),
  63. style: TextStyle(
  64. fontSize: AppFontSizes.subtitle,
  65. color: hasValue
  66. ? (readOnly ? colors.textPrimary : colors.textPrimary)
  67. : colors.textPlaceholder,
  68. ),
  69. ),
  70. if (showArrow && !readOnly) ...[
  71. const SizedBox(width: 4),
  72. Icon(
  73. Icons.chevron_right,
  74. size: 14,
  75. color: colors.textPlaceholder,
  76. ),
  77. ],
  78. ],
  79. ),
  80. ],
  81. ),
  82. ),
  83. );
  84. }
  85. }