@@ -168,7 +168,14 @@ class _ChatInputAreaState extends State<ChatInputArea> {
168168 super .dispose ();
169169 }
170170
171+ final int _charLimit = 5000 ; // limit
172+ bool _isOverLimit = false ;
173+
171174 void _handleOnChange (String text) {
175+ setState (() {
176+ _isOverLimit = text.length > _charLimit;
177+ });
178+
172179 final hasText = text.trim ().isNotEmpty;
173180
174181 if (hasText && ! _isTyping) {
@@ -197,6 +204,7 @@ class _ChatInputAreaState extends State<ChatInputArea> {
197204 }
198205
199206 void _submit () {
207+ _isOverLimit = false ;
200208 final text = _controller.text.trim ();
201209 if (text.isNotEmpty) {
202210 _typingTimer? .cancel ();
@@ -214,37 +222,87 @@ class _ChatInputAreaState extends State<ChatInputArea> {
214222 @override
215223 Widget build (BuildContext context) {
216224 return SafeArea (
217- child: Padding (
218- padding: const EdgeInsets .all (12.0 ),
219- child: Row (
220- children: [
221- Expanded (
222- child: TextField (
223- controller: _controller,
224- onChanged: _handleOnChange,
225- style: const TextStyle (color: Colors .black87, fontSize: 15 ),
226- decoration: InputDecoration (
227- hintText: "Write a message..." ,
228- hintStyle: const TextStyle (color: Colors .black38),
229- fillColor: const Color (0xFFF5F5F5 ),
230- filled: true ,
231- border: OutlineInputBorder (
232- borderRadius: BorderRadius .circular (24 ),
233- borderSide: BorderSide .none,
234- ),
235- contentPadding: const EdgeInsets .symmetric (
236- horizontal: 16 ,
237- vertical: 10 ,
225+ bottom: false ,
226+ child: ClipRRect (
227+ child: BackdropFilter (
228+ filter: ImageFilter .blur (sigmaX: 15 , sigmaY: 15 ),
229+ child: Container (
230+ color: Colors .transparent,
231+ padding: const EdgeInsets .symmetric (horizontal: 12.0 , vertical: 20 ),
232+ child: Row (
233+ mainAxisAlignment: MainAxisAlignment .center,
234+ crossAxisAlignment: CrossAxisAlignment .start,
235+ children: [
236+ Expanded (
237+ child: TextField (
238+ controller: _controller,
239+ onChanged: _handleOnChange,
240+ keyboardType: TextInputType .multiline,
241+ minLines: 1 ,
242+ maxLines: 5 ,
243+
244+ // 1. Set the limit
245+ maxLength: _charLimit,
246+ // 2. CRITICAL: This allows them to keep typing past the limit so it shows "7000/5000"
247+ maxLengthEnforcement: .none,
248+
249+ style: TextStyle (
250+ // 3. Turn the typed text red if they exceed the limit
251+ color: _isOverLimit ? Colors .red : Colors .black87,
252+ fontSize: 15 ,
253+ ),
254+ decoration: InputDecoration (
255+ hintText: "Write a message..." ,
256+ hintStyle: const TextStyle (color: Colors .black38),
257+
258+ fillColor: _isOverLimit
259+ ? Colors .red.withValues (alpha: 0.1 )
260+ : const Color (0xFFF5F5F5 ),
261+ filled: true ,
262+ errorText: _isOverLimit ? 'character limit exceeded' : '' ,
263+ counterStyle: TextStyle (
264+ color: _isOverLimit ? Colors .red : Colors .black54,
265+ fontWeight: _isOverLimit
266+ ? FontWeight .bold
267+ : FontWeight .normal,
268+ ),
269+
270+ border: OutlineInputBorder (
271+ borderRadius: BorderRadius .circular (24 ),
272+ borderSide: _isOverLimit
273+ ? const BorderSide (color: Colors .red, width: 1.5 )
274+ : BorderSide .none,
275+ ),
276+ focusedBorder: OutlineInputBorder (
277+ borderRadius: BorderRadius .circular (24 ),
278+ borderSide: _isOverLimit
279+ ? const BorderSide (color: Colors .red, width: 2 )
280+ : BorderSide .none,
281+ ),
282+ enabledBorder: OutlineInputBorder (
283+ borderRadius: BorderRadius .circular (24 ),
284+ borderSide: _isOverLimit
285+ ? const BorderSide (color: Colors .red, width: 1.5 )
286+ : BorderSide .none,
287+ ),
288+
289+ contentPadding: const EdgeInsets .symmetric (
290+ horizontal: 16 ,
291+ vertical: 10 ,
292+ ),
293+ ),
238294 ),
239295 ),
240- ),
241- ),
242- const SizedBox (width: 8 ),
243- IconButton (
244- icon: const Icon (Icons .send, color: Color (0xFF1890FF )),
245- onPressed: _submit,
296+ const SizedBox (width: 8 ),
297+ IconButton (
298+ icon: _isOverLimit
299+ ? const Icon (Icons .not_interested)
300+ : const Icon (Icons .send, color: Color (0xFF1890FF )),
301+ onPressed: _isOverLimit ? null : _submit,
302+ ),
303+ ],
246304 ),
247- ] ,
305+ ) ,
248306 ),
249307 ),
250308 );
0 commit comments