@@ -299,29 +299,88 @@ class _ContentInput extends StatelessWidget {
299299 narrow: narrow,
300300 controller: controller,
301301 focusNode: focusNode,
302- fieldViewBuilder: (context) => SingleChildScrollView (
303- // While the [TextField] is scrollable, we need to wrap it with
304- // [SingleChildScrollView] to insert a fixed-height padding that can
305- // be scrolled along with the text.
306- child: Padding (
307- padding: const EdgeInsets .only (top: topPadding, left: 16 , right: 16 ),
308- child: TextField (
309- controller: controller,
310- focusNode: focusNode,
311- decoration: InputDecoration .collapsed (
312- border: InputBorder .none,
313- hintText: hintText,
314- hintStyle: TextStyle (color: designVariables.textInput.withOpacity (0.5 ))),
315- minLines: 2 ,
316- maxLines: null ,
317- textCapitalization: TextCapitalization .sentences,
318- style: TextStyle (
319- fontSize: 17 ,
320- height: (contentLineHeight / 17 ),
321- color: designVariables.textInput))))));
302+ fieldViewBuilder: (context) => _ShadowBox (
303+ color: designVariables.bgComposeBox,
304+ child: SingleChildScrollView (
305+ // While the [TextField] is scrollable, we need to wrap it with
306+ // [SingleChildScrollView] to insert a fixed-height padding that can
307+ // be scrolled along with the text.
308+ child: Padding (
309+ padding: const EdgeInsets .only (top: topPadding, left: 16 , right: 16 ),
310+ child: TextField (
311+ controller: controller,
312+ focusNode: focusNode,
313+ decoration: InputDecoration .collapsed (
314+ border: InputBorder .none,
315+ hintText: hintText,
316+ hintStyle: TextStyle (color: designVariables.textInput.withOpacity (0.5 ))),
317+ minLines: 2 ,
318+ maxLines: null ,
319+ textCapitalization: TextCapitalization .sentences,
320+ style: TextStyle (
321+ fontSize: 17 ,
322+ height: (contentLineHeight / 17 ),
323+ color: designVariables.textInput)))))));
322324 }
323325}
324326
327+ /// Overlay inset shadows on the child from all scrollable directions.
328+ class _ShadowBox extends StatefulWidget {
329+ const _ShadowBox ({required this .color, required this .child});
330+
331+ final Color color;
332+ final Widget child;
333+
334+ @override
335+ State <_ShadowBox > createState () => _ShadowBoxState ();
336+ }
337+
338+ class _ShadowBoxState extends State <_ShadowBox > {
339+ bool showTopShadow = false ; bool showBottomShadow = false ;
340+ bool showLeftShadow = false ; bool showRightShadow = false ;
341+
342+ bool handleScroll (ScrollNotification notification) {
343+ final metrics = notification.metrics;
344+ setState (() {
345+ switch (metrics.axisDirection) {
346+ case AxisDirection .up:
347+ case AxisDirection .down:
348+ showTopShadow = metrics.extentBefore != 0 ;
349+ showBottomShadow = metrics.extentAfter != 0 ;
350+ case AxisDirection .right:
351+ case AxisDirection .left:
352+ showLeftShadow = metrics.extentBefore != 0 ;
353+ showRightShadow = metrics.extentAfter != 0 ;
354+ }
355+ });
356+ return false ;
357+ }
358+
359+ @override
360+ Widget build (BuildContext context) {
361+ BoxDecoration shadowFrom (AlignmentGeometry begin) =>
362+ BoxDecoration (gradient: LinearGradient (begin: begin, end: - begin,
363+ colors: [widget.color, widget.color.withOpacity (0 )]));
364+
365+ return NotificationListener <ScrollNotification >(
366+ onNotification: handleScroll,
367+ child: Stack (
368+ children: [
369+ widget.child,
370+ if (showTopShadow) Positioned (top: 0 , left: 0 , right: 0 ,
371+ child: Container (height: 8 , decoration: shadowFrom (Alignment .topCenter))),
372+ if (showBottomShadow) Positioned (bottom: 0 , left: 0 , right: 0 ,
373+ child: Container (height: 8 , decoration: shadowFrom (Alignment .bottomCenter))),
374+ if (showLeftShadow) Positioned (left: 0 , top: 0 , bottom: 0 ,
375+ child: Container (width: 8 , decoration: shadowFrom (Alignment .centerLeft))),
376+ if (showRightShadow) Positioned (right: 0 , top: 0 , bottom: 0 ,
377+ child: Container (width: 8 , decoration: shadowFrom (Alignment .centerRight))),
378+ ],
379+ ));
380+ }
381+ }
382+
383+
325384/// The content input for _StreamComposeBox.
326385class _StreamContentInput extends StatefulWidget {
327386 const _StreamContentInput ({
0 commit comments