diff --git a/mitra_app/lib/features/chat/screens/mitra_chat_screen.dart b/mitra_app/lib/features/chat/screens/mitra_chat_screen.dart index f9d95d8..8e8edc2 100644 --- a/mitra_app/lib/features/chat/screens/mitra_chat_screen.dart +++ b/mitra_app/lib/features/chat/screens/mitra_chat_screen.dart @@ -742,6 +742,11 @@ class _MitraChatBodyContentState extends ConsumerState<_MitraChatBodyContent> { Expanded( child: Container( height: 44, + // alignment.center positions the TextField on the vertical + // midline of the 44dp container. Without this, isDense's + // small intrinsic height docks to the top of the parent + // (no implicit vertical centering for Container children). + alignment: Alignment.center, padding: const EdgeInsets.symmetric(horizontal: 16), decoration: const BoxDecoration( // White bg so the pill stands out against the cream page @@ -756,29 +761,37 @@ class _MitraChatBodyContentState extends ConsumerState<_MitraChatBodyContent> { BorderSide(color: HaloTokens.border), ), ), - // Center wrapper makes the TextField sit on the vertical - // midline of the 44dp pill. `textAlignVertical: center` - // + `isCollapsed: true` alone don't center against the - // parent height — they only center within the field's - // own intrinsic line-box, which then docks to the top of - // the parent. Wrapping in Center delegates the vertical - // alignment to the container's stack. - child: Center( - child: TextField( - controller: widget.messageController, - onChanged: widget.onTextChanged, - textInputAction: TextInputAction.send, - onSubmitted: (_) => widget.onSend(), - style: const TextStyle(fontSize: 13.5, color: HaloTokens.ink), - decoration: const InputDecoration( - hintText: 'ketik balasan...', - hintStyle: TextStyle(color: HaloTokens.inkMuted, fontSize: 13.5), - isCollapsed: true, - border: InputBorder.none, - enabledBorder: InputBorder.none, - focusedBorder: InputBorder.none, - disabledBorder: InputBorder.none, - ), + // Vertical centering recipe: Container.alignment.center + // positions the TextField on the midline; textAlignVertical + // with a positive y (~0.4) nudges the baseline down so the + // optical center of Latin lowercase glyphs lines up with + // the pill midline, not just the baseline. With y=0 (true + // center), the field's line-box centers but Latin text + // bodies sit in the upper half because the baseline is at + // ~75% of line height — leaving descender space empty + // below. y=0.4 shifts down to match the visual midline. + child: TextField( + controller: widget.messageController, + onChanged: widget.onTextChanged, + textInputAction: TextInputAction.send, + onSubmitted: (_) => widget.onSend(), + maxLines: 1, + textAlignVertical: const TextAlignVertical(y: 0.4), + style: const TextStyle( + fontSize: 13.5, + color: HaloTokens.ink, + ), + decoration: const InputDecoration( + hintText: 'ketik balasan...', + hintStyle: TextStyle(color: HaloTokens.inkMuted, fontSize: 13.5), + isDense: true, + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + enabledBorder: InputBorder.none, + focusedBorder: InputBorder.none, + disabledBorder: InputBorder.none, + errorBorder: InputBorder.none, + focusedErrorBorder: InputBorder.none, ), ), ),