The Garage SDKs, in the open

garage_auth, garage_entitlements, garage_iap and garage_ui, moved out of
Garage-Services and Metro-Map-Maker into one public repo. MIT, one readme,
docs under docs/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013F4NWNvYcdeSgqbWMT1VQ7
This commit is contained in:
ImBenji
2026-09-23 18:49:21 +01:00
co-authored by Claude Opus 5.5
commit b269201919
117 changed files with 26944 additions and 0 deletions
+44
View File
@@ -0,0 +1,44 @@
import "package:flutter/widgets.dart";
/// Wraps a scrollable panel body so content approaching the top or bottom
/// edge fades to transparent over [fadeExtent] pixels instead of getting cut
/// off flat by the scroll view's own default hard clip. Purely a paint
/// effect - the scroll views clip still keeps everything contained, this
/// just masks the alpha near each edge on top of that.
///
/// Colour-blind on purpose: the gradient only carries alpha (dstIn blends
/// against whatever's already painted), so it works unchanged over any panel
/// background/scheme rather than needing its own colour token.
class ScrollEdgeFade extends StatelessWidget {
const ScrollEdgeFade({super.key, required this.child, this.fadeExtent = 6});
final Widget child;
final double fadeExtent;
@override
Widget build(BuildContext context) {
return ShaderMask(
shaderCallback: (bounds) {
// fraction of the box height the fade eats into from each end - a
// fixed pixel extent thats clamped so a very short panel doesnt end
// up with the two fades overlapping and cancelling out the middle.
final fraction = bounds.height > 0
? (fadeExtent / bounds.height).clamp(0.0, 0.5)
: 0.0;
return LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
stops: [0.0, fraction, 1 - fraction, 1.0],
colors: const [
Color(0x00ffffff),
Color(0xffffffff),
Color(0xffffffff),
Color(0x00ffffff),
],
).createShader(bounds);
},
blendMode: BlendMode.dstIn,
child: child,
);
}
}