// Author: fruit.com.cn import 'package:flutter/material.dart'; import '../../core/theme/app_colors.dart'; import '../../core/theme/app_dimens.dart'; import '../../l10n/app_localizations.dart'; import 'account_deactivate_logic.dart'; /// 注销原因:固定选项在标题下换行排列,补充说明留在输入框内。 class DeactivateReasonField extends StatelessWidget { const DeactivateReasonField({ super.key, required this.controller, required this.onChanged, }); final TextEditingController controller; final VoidCallback onChanged; @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; final options = _options(l10n); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( l10n.accountDeactivateReason, style: const TextStyle( color: AppColors.textPrimary, fontSize: AppDimens.listTitle, fontWeight: FontWeight.w600, ), ), const SizedBox(height: AppDimens.spaceSm), Wrap( spacing: AppDimens.spaceSm, runSpacing: AppDimens.spaceSm, children: [ for (var index = 0; index < options.length; index++) _chip(options[index], index, options), ], ), const SizedBox(height: AppDimens.spaceMd), TextField( key: const Key('account-deactivate-reason'), controller: controller, maxLength: AccountDeactivateLogic.maxReasonLength, minLines: 3, maxLines: 4, textAlignVertical: TextAlignVertical.top, onChanged: (_) => onChanged(), decoration: InputDecoration( hintText: l10n.accountDeactivateReasonHint, floatingLabelBehavior: FloatingLabelBehavior.never, alignLabelWithHint: true, contentPadding: const EdgeInsets.all(AppDimens.cardPadding), ), ), ], ); } Widget _chip(_ReasonOption option, int index, List<_ReasonOption> options) { final selected = option.custom ? _customSelected(options) : controller.text == option.label; return ChoiceChip( key: Key('account-deactivate-reason-$index'), label: Text(option.label), selected: selected, onSelected: (_) => _select(option), ); } bool _customSelected(List<_ReasonOption> options) { final text = controller.text.trim(); if (text.isEmpty) return false; return options .where((item) => !item.custom) .every((item) => item.label != text); } void _select(_ReasonOption option) { controller.text = option.custom ? '' : option.label; controller.selection = TextSelection.collapsed( offset: controller.text.length, ); onChanged(); } List<_ReasonOption> _options(AppLocalizations l10n) => [ _ReasonOption(l10n.accountDeactivateReasonUnused), _ReasonOption(l10n.accountDeactivateReasonContent), _ReasonOption(l10n.accountDeactivateReasonPrivacy), _ReasonOption(l10n.accountDeactivateReasonOther, custom: true), ]; } class _ReasonOption { const _ReasonOption(this.label, {this.custom = false}); final String label; final bool custom; }