virnavi_ui_bootstrap

A Flutter UI bootstrap package that provides a responsive Screen/ScreenLayout architecture, adaptive design scaling via flutter_screenutil, composable SectionBox widgets, SVG image helpers, and async stream builder utilities.


Features

  • Screen + ScreenLayout — Structured, responsive base classes that automatically serve different layouts for mobile portrait, mobile landscape, tablet portrait, and tablet landscape. Includes ScreenData for shared, reactive state without StatefulWidget boilerplate.
  • Adaptive scalingVirnaviUIBootstrap.init configures design canvas sizes so flutter_screenutil scales dimensions correctly on every device.
  • SectionBox family — Bordered, rounded containers for building grouped list sections (SectionBox, SectionBoxStart, SectionBoxMid, SectionBoxEnd).
  • AppAutoSizeTextAutoSizeText with a scaled minimum font size applied automatically.
  • AppSvgImage — SVG asset renderer that transparently switches to pre-compiled vector graphics when the path contains precompiled/.
  • Stream buildersFutureModelStreamBuilder, FutureMultiStreamBuilder, FutureOptionalBuilder, and their listener counterparts for reactive async data.
  • ErrorTextSnackBar — Theme-aware error snack bar.
  • DesignNumExtension.dimen and .font extensions on num for consistent scaled values.

Getting started

Add the package to your pubspec.yaml:

dependencies:
  virnavi_ui_bootstrap: ^0.0.1

Call VirnaviUIBootstrap.init once before runApp, passing your design canvas sizes:

void main() {
  VirnaviUIBootstrap.init(
    mobileDesignSize: const Size(390, 844),
    tabletDesignSize: const Size(768, 1024),
  );
  runApp(const MyApp());
}

Usage

Responsive screens

class HomeScreen extends Screen {
  const HomeScreen({super.key});

  // Optional: share reactive data across layouts
  @override
  HomeData createScreenData() => HomeData();

  HomeData get data => screenData as HomeData;

  // Wrap all layouts in shared chrome
  @override
  Widget buildTemplate(BuildContext context, Widget child) {
    return Scaffold(
      appBar: AppBar(title: const Text('Home')),
      body: child,
    );
  }

  // Required: mobile portrait layout
  @override
  ScreenLayout buildMobilePortrait(BuildContext context) =>
      const _HomePortraitLayout();

  // Optional: tablet layout (falls back to portrait if omitted)
  @override
  ScreenLayout? buildTabletPortrait(BuildContext context) =>
      const _HomeTabletLayout();
}

ScreenLayout with lifecycle hooks

class _HomePortraitLayout extends ScreenLayout<HomeScreen> {
  const _HomePortraitLayout();

  @override
  void initState() {
    screen.data.load(); // screen is resolved automatically
  }

  @override
  Widget build(BuildContext context, HomeScreen screen) {
    return Text('count: ${screen.data.counter}');
  }
}

ScreenData — reactive shared state

class HomeData extends ScreenData<HomeScreen> {
  int counter = 0;

  void increment() => setState(() => counter++);
}

SectionBox family

Column(
  children: [
    SectionBoxStart(
      borderColor: Colors.grey,
      color: Colors.white,
      borderRadius: 12,
      padding: const EdgeInsets.all(16),
      child: const Text('First row'),
    ),
    SectionBoxMid(
      borderColor: Colors.grey,
      color: Colors.white,
      padding: const EdgeInsets.all(16),
      child: const Text('Middle row'),
    ),
    SectionBoxEnd(
      borderColor: Colors.grey,
      color: Colors.white,
      borderRadius: 12,
      padding: const EdgeInsets.all(16),
      child: const Text('Last row'),
    ),
  ],
)

AppSvgImage

// Regular SVG
AppSvgImage.asset('assets/icons/logo.svg', width: 48, height: 48)

// Pre-compiled SVG (path must contain 'precompiled')
AppSvgImage.asset('assets/precompiled/logo.svg.vec', width: 48, height: 48)

AppAutoSizeText

AppAutoSizeText(
  'Responsive text that shrinks to fit',
  style: TextStyle(fontSize: 16.sp),
  maxLines: 1,
)

FutureModelStreamBuilder

FutureModelStreamBuilder<UserModel>(
  futureStream: repository.watchUser(),
  buildLoading: (_) => const CircularProgressIndicator(),
  buildEmpty: (_) => const Text('No user found'),
  buildData: (_, user) => Text(user.name),
)

Contributors

Name GitHub Role
Mohammed Shakib @shakib1989 Main Library Development

Additional information