flutter_responsive_plus

The ultimate Flutter responsive & adaptive toolkit.
One package. Zero boilerplate. Every responsive pattern you'll ever need.

pub version Flutter license


✨ What's inside

Feature Description
Per-breakpoint Figma canvases Give the package your mobile, tablet, desktop, and web Figma frames separately — it auto-switches canvases as the screen size changes
ResKit.builder() Supply all possible layouts in one call; the package picks the right one automatically
Figma-to-device scaling Every .w .h .r .sp scales from the active canvas — no manual math
ResKit global namespace ResKit.width() · ResKit.sp() · ResKit.sw() · ResKit.isTablet · ResKit.isWeb — anywhere, no context
Num extensions 200.w 100.h 12.r 16.sp 0.5.sw 0.1.sh 8.dp
BuildContext extensions context.w() context.isTablet context.responsiveBuilder()
Full breakpoint set mobile · mobileLarge · tabletSmall · tablet · tabletLarge · desktop · desktopLarge · desktopXL
Platform detection isAndroid · isIOS · isWeb · isMacOS · isWindows · isLinux · isFuchsia
ResponsiveBuilder LayoutBuilder-based — reacts to available box width
AdaptiveBuilder Platform-based typed widget switcher
ResKitUtils Grid helpers · text styles · aspect-fit · safe-area · debug
WebContentWrapper Max-width centred web layouts
Full debug dump ResKit.debugPrint() — every value in one call

🚀 Quick Start

# pubspec.yaml
dependencies:
  flutter_responsive_plus: ^1.1.0
import 'package:flutter_responsive_plus/flutter_responsive_plus.dart';

Tell the package which Figma frame you designed for each device category. Scaling automatically uses the right canvas — no code changes needed when the user rotates, resizes, or runs on a different device.

ResponsiveKit(
  config: ResKitConfig(
    designs: ResKitDesignConfig(
      mobile:  ResKitDesignSize(width: 390,  height: 844),   // iPhone 14
      tablet:  ResKitDesignSize(width: 768,  height: 1024),  // iPad Mini
      desktop: ResKitDesignSize(width: 1440, height: 900),   // MacBook Air
      web:     ResKitDesignSize(width: 1280, height: 800),   // Browser
    ),
    maxFontScale: 1.3,
  ),
  child: MaterialApp(…),
)

Named presets — zero magic numbers

designs: ResKitDesignConfig(
  mobile:       ResKitDesignSize.iphone14,          // 390 × 844
  tablet:       ResKitDesignSize.ipadMini,           // 768 × 1024
  desktop:      ResKitDesignSize.macbookAir,         // 1440 × 900
  web:          ResKitDesignSize.webBrowser,         // 1280 × 800
  desktopLarge: ResKitDesignSize.fullHD,             // 1920 × 1080
),

All built-in presets:

Preset constant Size
ResKitDesignSize.iphoneSE 375 × 667
ResKitDesignSize.iphone14 390 × 844
ResKitDesignSize.iphone14ProMax 430 × 932
ResKitDesignSize.androidCommon 360 × 800
ResKitDesignSize.ipadMini 768 × 1024
ResKitDesignSize.ipadPro11 834 × 1194
ResKitDesignSize.ipadPro12 1024 × 1366
ResKitDesignSize.macbookAir 1440 × 900
ResKitDesignSize.webBrowser 1280 × 800
ResKitDesignSize.fullHD 1920 × 1080
ResKitDesignSize.qhd 2560 × 1440

How canvas resolution works

When the screen width changes the package picks the canvas in this order:

isWeb + web set         → web canvas
≥ desktopLarge bp       → desktopLarge canvas
> tabletLarge bp        → desktop → tabletLarge → tablet → … → mobile
> tablet bp             → tabletLarge → tablet → tabletSmall → … → mobile
> mobileLarge bp        → tabletSmall → tablet → mobile
≤ mobileLarge bp        → mobile

Always falls back to the closest larger canvas so something is always active.


🏗️ ResKit.builder() — Multi-Layout in One Call

The central new API. Supply a widget (or builder function) for every layout you want; the package selects the correct one based on the current screen width and platform.

// Static widgets
ResKit.builder(
  mobile:  MobileScreen(),
  tablet:  TabletScreen(),
  desktop: DesktopScreen(),
  web:     WebScreen(),        // platform override: shown on web regardless of width
)

// Builder callbacks (receive BuildContext)
ResKit.builder(
  mobileBuilder:  (ctx) => MobileScreen(),
  tabletBuilder:  (ctx) => TabletScreen(),
  desktopBuilder: (ctx) => DesktopScreen(),
)

// Mix both styles freely
ResKit.builder(
  mobile:         MobileScreen(),
  tabletBuilder:  (ctx) => TabletScreen(onTap: () {}),
  desktop:        DesktopScreen(),
)

All available slots

Slot Screen width range
mobile ≤ mobileLarge breakpoint (default ≤ 600)
mobileLarge mobile < width ≤ mobileLarge (optional fine-tune)
tabletSmall mobileLarge < width ≤ tablet
tablet mobileLarge < width ≤ tabletLarge
tabletLarge tablet < width ≤ tabletLarge
desktop > tabletLarge (default > 1024)
desktopLarge ≥ desktopLarge breakpoint (default ≥ 1440)
desktopXL ≥ desktopXL breakpoint (default ≥ 1920)
web Platform override — shown on web (kIsWeb == true) regardless of width

Only mobile is required. All other slots fall back gracefully toward mobile.

onLayout callback

ResKit.builder(
  mobile:  MobileScreen(),
  desktop: DesktopScreen(),
  onLayout: (ResKitLayoutInfo info) {
    print(info.layoutType);    // ResKitLayoutType.mobile / .tablet / .desktop …
    print(info.activeDesign);  // ResKitDesignSize(390×844)
    print(info.screenWidth);   // 390.0
    print(info.deviceType);    // ResKitDeviceType.mobile
    print(info.isWeb);         // false
  },
)

context shortcut

// Inside any build method:
context.responsiveBuilder(
  mobile:  MobileWidget(),
  tablet:  TabletWidget(),
  desktop: DesktopWidget(),
)

Use at any level

// At the app root (home:)
home: ResKit.builder(mobile: MobileApp(), desktop: DesktopApp())

// Inside any widget tree
child: ResKit.builder(
  mobile:  Text('Small', style: TextStyle(fontSize: 14.sp)),
  desktop: Text('Large', style: TextStyle(fontSize: 22.sp)),
)

// For individual properties
final columns = ResKit.adaptive(mobile: 1, tablet: 2, desktop: 4);

📐 Figma-Style Scaling

// All of these are identical — use whichever style you prefer:
Container(
  width:   ResKit.width(200),     // function style
  width:   ResKit.w(200),         // short alias
  width:   200.w,                 // extension style ← most concise

  height:  100.h,
  padding: EdgeInsets.all(16.r),  // radius/uniform
  child: Text('Hello', style: TextStyle(fontSize: 14.sp)),
)
Method Extension Description
ResKit.width(n) n.w Scale from active Figma width
ResKit.height(n) n.h Scale from active Figma height
ResKit.radius(n) n.r Uniform min(scaleW, scaleH)
ResKit.sp(n) n.sp Font size (clamped by maxFontScale)
ResKit.dp(n) n.dp Raw logical pixels — no scaling
ResKit.sw(f) f.sw Fraction of screen width (0.0–1.0)
ResKit.sh(f) f.sh Fraction of screen height

📱 Screen Info

ResKit.screenWidth / screenHeight / size / devicePixelRatio
ResKit.statusBarHeight / bottomBarHeight / appBarHeight
ResKit.keyboardHeight / isKeyboardOpen / safeAreaPadding
ResKit.diagonal
ResKit.isPortrait / isLandscape
ResKit.activeDesign     // currently active ResKitDesignSize
ResKit.figmaWidth / figmaHeight  // shortcut to activeDesign dimensions
ResKit.scaleW / scaleH / scale / textScale

📏 Breakpoints

// Global
ResKit.isMobileSmall / isMobile / isMobileLarge
ResKit.isTabletSmall / isTablet / isTabletLarge
ResKit.isDesktop / isDesktopLarge / isDesktopXL
ResKit.deviceType   // ResKitDeviceType.mobile / .tablet / .desktop

// On context
context.isMobile / isTablet / isDesktop / …

// Value picker
ResKit.adaptive(mobile: 1, tablet: 2, desktop: 4)

Custom breakpoints:

ResKitConfig(
  breakpoints: ResKitBreakpoints(
    mobile: 520, tablet: 1000, tabletLarge: 1200,
  ),
)
// or use presets:
breakpoints: ResKitBreakpoints.bootstrap()
breakpoints: ResKitBreakpoints.material3()
breakpoints: ResKitBreakpoints.tailwind()

💻 Platform Detection

ResKit.isAndroid / isIOS / isWeb / isMacOS / isWindows / isLinux / isFuchsia
ResKit.isNativeMobile / isNativeDesktop
ResKit.platform    // ResKitOS enum

ResKit.perPlatform(android: 4.0, ios: 0.0, web: 2.0, fallback: 1.0)

🧱 Widgets

// LayoutBuilder-based — reacts to available box width
ResponsiveBuilder(
  builder: (ctx, constraints, deviceType) { … },
)
TriStateResponsiveBuilder(mobile: A(), tablet: B(), desktop: C())

// Platform-based
AdaptiveBuilder(android: MD(), ios: Cupertino(), fallback: Default())

// Max-width web wrapper
WebContentWrapper(maxWidth: 1280, child: …)

// Conditional visibility
ResponsiveVisibility(condition: context.isDesktop, child: SideBar())

// Scoped MediaQuery override (tests / previews)
ResKitMediaQuery(size: Size(1440, 900), child: MyScreen())

🔧 BuildContext Extensions

context.screenWidth / screenHeight / devicePixelRatio
context.statusBarHeight / bottomBarHeight / keyboardHeight / isKeyboardOpen
context.w(200) / h(100) / r(12) / sp(16) / sw(0.5) / sh(0.1) / dp(8)
context.scaleW / scaleH / scale / textScale
context.figmaWidth / figmaHeight / activeDesign
context.isPortrait / isLandscape
context.isMobile / isTablet / isDesktop / isDesktopLarge / isDesktopXL / …
context.isAndroid / isIOS / isWeb / isMacOS / isWindows / isLinux / isFuchsia
context.platform / deviceType
context.adaptive(mobile: …, tablet: …, desktop: …)
context.perPlatform(android: …, ios: …, fallback: …)
context.responsiveBuilder(mobile: …, tablet: …, desktop: …, web: …)

🛠️ ResKitUtils

ResKitUtils.gridItemWidth(columns: 3, spacing: 8)
ResKitUtils.adaptiveColumns(minItemWidth: 120)
ResKitUtils.textStyle(16, fontWeight: FontWeight.w600)
ResKitUtils.aspectFitWidth(figmaWidth: 320, figmaHeight: 200)
ResKitUtils.usableHeight   // screenHeight - statusBar - bottomBar - keyboard
ResKitUtils.byOrientation(portrait: 2, landscape: 4)
ResKitUtils.clampWidth(200, min: 100, max: 300)
ResKitUtils.diagnosticMap()  // Map<String, dynamic> — useful in tests

🐛 Debugging

ResKit.debugPrint();
[ResKit] ──────────────────────────────────────────────────────────────
[ResKit] 📱  flutter_responsive_plus — Diagnostic Dump
[ResKit] ── Design Config ──────────────────────────────────────────────
[ResKit]   Mode              : Multi-canvas (per-breakpoint)
[ResKit]   Active canvas     : 390 × 844 dp  (ResKitDesignSize(390×844))
[ResKit]   mobile            : ResKitDesignSize(390×844)
[ResKit]   tablet            : ResKitDesignSize(768×1024)
[ResKit]   desktop           : ResKitDesignSize(1440×900)
[ResKit]   web               : ResKitDesignSize(1280×800)
[ResKit] ── Screen ──────────────────────────────────────────────────────
[ResKit]   Logical size      : 390.0 × 844.0 dp
[ResKit]   Physical size     : 1170 × 2532 px
[ResKit]   Pixel ratio       : 3.00
[ResKit]   Orientation       : Portrait ↕
[ResKit] ── Scale Factors ───────────────────────────────────────────────
[ResKit]   scaleW            : 1.00000
[ResKit]   scaleH            : 1.00000
[ResKit]   scale (uniform)   : 1.00000
[ResKit]   textScale         : 1.00000
...

🔀 Migrating from flutter_screenutil

ScreenUtil flutter_responsive_plus
ScreenUtil.init(…) in build ResponsiveKit(config: …) at app root, once
200.w 100.h 12.r 16.sp ✅ identical extensions
ScreenUtil().screenWidth ResKit.screenWidth
Single Figma canvas ResKitConfig(figmaWidth: 390, figmaHeight: 844)
ResKitConfig(designs: ResKitDesignConfig(mobile:…, tablet:…)) ← new
ResKit.builder(mobile:…, tablet:…, desktop:…) ← new

📄 License

MIT © 2025 Mysterious Coder

Libraries

flutter_responsive_plus
flutter_responsive_plus — The Ultimate Flutter Responsive & Adaptive Toolkit