Skip to content

Commit 8fd9107

Browse files
committed
compose_box [nfc]: Add RectangularInsetShadowBox
This casts a static shadow on top of a child widget from its top edge and bottom edge. Signed-off-by: Zixuan James Li <[email protected]>
1 parent 701763d commit 8fd9107

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import 'package:flutter/widgets.dart';
2+
3+
/// A widget that overlays rectangular inset shadows on a child.
4+
///
5+
/// The use case of this is casting shadow on scrollable UI elements.
6+
/// For example, when there is a list of items, the shadow could be
7+
/// a visual indicator for over scrolled areas.
8+
///
9+
/// See also:
10+
/// * https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=3860-11890&node-type=frame&t=oOVTdwGZgtvKv9i8-0
11+
class RectangularInsetShadowBox extends StatelessWidget {
12+
const RectangularInsetShadowBox({
13+
super.key,
14+
this.top = 0,
15+
this.bottom = 0,
16+
required this.color,
17+
required this.child,
18+
});
19+
20+
/// The distance that the shadows from the child's top edge grows downwards.
21+
///
22+
/// This does not pad the child widget.
23+
final double top;
24+
25+
/// The distance that the shadows from the child's bottom edge grows upwards.
26+
///
27+
/// This does not pad the child widget.
28+
final double bottom;
29+
30+
/// The shadow color to fade into transparency from the top and bottom borders.
31+
final Color color;
32+
33+
final Widget child;
34+
35+
BoxDecoration _shadowFrom(AlignmentGeometry begin) {
36+
return BoxDecoration(gradient: LinearGradient(
37+
begin: begin, end: -begin,
38+
colors: [color, color.withValues(alpha: 0)]));
39+
}
40+
41+
@override
42+
Widget build(BuildContext context) {
43+
return Stack(children: [
44+
child,
45+
Positioned(top: 0, left: 0, right: 0,
46+
child: Container(height: top, decoration: _shadowFrom(Alignment.topCenter))),
47+
Positioned(bottom: 0, left: 0, right: 0,
48+
child: Container(height: bottom, decoration: _shadowFrom(Alignment.bottomCenter))),
49+
]);
50+
}
51+
}

0 commit comments

Comments
 (0)