veil_ui

iOS 26-style glass app bar and blurred bottom overlay for Flutter. Scroll-driven shadows, dark mode aware, zero boilerplate.

pub.dev License: MIT Flutter


GlassAppBar Modal Sheet BlurredBottomOverlay
GlassAppBar Modal Sheet BlurredBottomOverlay

Features

  • GlassAppBar — transparent app bar with a smooth gradient shadow that fades content scrolling beneath it. Shadow appears on scroll, hides when at top.
  • BlurredBottomOverlay — gradient fade-out over scrollable content with a pinned bottom widget (e.g. a sticky CTA button).
  • showVeilUISheet — native Cupertino sheet presentation.
  • iOS 26 adaptive back button — SF Symbol on iOS 26+, Material circle button below.
  • Full dark mode support — all gradients are derived from the app's scaffold background color.
  • RTL-aware — uses standard Localizations, no third-party locale package required.

Installation

dependencies:
  veil_ui: ^0.0.7
import 'package:veil_ui/veil_ui.dart';

Initialize once before runApp so the iOS version is cached:

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await IosVersionHelper.instance.init();
  runApp(const MyApp());
}

Platform Support

Android iOS macOS

Usage

GlassAppBar

Important: Always set extendBody: true and extendBodyBehindAppBar: true on your Scaffold so the transparent app bar overlays the content correctly on both iOS and Android.

Scaffold(
  extendBody: true,
  extendBodyBehindAppBar: true,
  appBar: GlassAppBar(title: 'Settings'),
  body: ListView(...),
)

Scroll-driven shadow — shadow fades in after the user scrolls past the threshold:

class _MyScreenState extends State<MyScreen> {
  final _scroll = ScrollController();

  @override
  void dispose() {
    _scroll.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      extendBody: true,
      extendBodyBehindAppBar: true,
      appBar: GlassAppBar(
        title: 'Feed',
        scrollController: _scroll,
      ),
      body: ListView.builder(
        controller: _scroll,
        itemBuilder: (_, i) => ListTile(title: Text('Item $i')),
      ),
    );
  }
}

Custom title widget:

GlassAppBar(
  titleWidget: Row(
    mainAxisSize: MainAxisSize.min,
    children: [
      CircleAvatar(radius: 12, backgroundImage: NetworkImage(avatarUrl)),
      SizedBox(width: 8),
      Text('Mohammed'),
    ],
  ),
)

With a TabBar:

GlassAppBar(
  title: 'Explore',
  bottom: TabBar(tabs: [...]),
)

Parameters

Parameter Type Default Description
title String? Plain-text title
titleWidget Widget? Custom title, takes precedence over title
actions List<Widget>? Trailing action buttons
centerTitle bool true Center the title
height double kToolbarHeight App bar height
isModalSheet bool false Shows × instead of ‹
onBack VoidCallback? Navigator.maybePop Override back tap
showShadow bool true Enable gradient shadow
showLeadingButton bool true Show back/close button
scrollController ScrollController? Drives scroll-based shadow reveal
scrollThreshold double 5.0 Pixels before shadow appears
forceShadow bool? Override scroll state from parent
titleTextStyle TextStyle? Override default title style
bottom PreferredSizeWidget? Widget below toolbar (e.g. TabBar)
leadingWidth double? Override leading area width
systemOverlayStyle SystemUiOverlayStyle? Status bar style override

BlurredBottomOverlay

BlurredBottomOverlay(
  bottomWidget: Padding(
    padding: EdgeInsets.all(16),
    child: SizedBox(
      width: double.infinity,
      height: 56,
      child: FilledButton(
        onPressed: () {},
        child: Text('Continue'),
      ),
    ),
  ),
  child: ListView.builder(
    itemBuilder: (_, i) => ListTile(title: Text('Item $i')),
  ),
)

Inside a card (custom overlay colour):

BlurredBottomOverlay(
  overlayColor: Colors.white,
  child: ...,
  bottomWidget: ...,
)

Parameters

Parameter Type Default Description
child Widget required The scrollable content behind the overlay
bottomWidget Widget? Widget pinned above the gradient
overlayColor Color? scaffold bg Override the gradient base colour
gradientHeight double? intrinsic Explicit gradient region height
inverseGradient bool false Flip direction (top fade instead of bottom)
useSafeArea bool true Wrap bottomWidget in SafeArea

showVeilUISheet

Native Cupertino modal sheet — matches the iOS 26 card-stack presentation.

showVeilUISheet<void>(
  context: context,
  builder: (context) => const MySheetContent(),
);

Inside the sheet, use GlassAppBar with isModalSheet: true:

class MySheetContent extends StatelessWidget {
  const MySheetContent({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: GlassAppBar(
        title: 'Edit Profile',
        isModalSheet: true,
      ),
      body: ...,
    );
  }
}

License

MIT © 2026 Mohammed Jaber

Libraries

veil_ui
veil_ui — iOS 26-style glass widgets for Flutter.