flutter_responsive_plus
The ultimate Flutter responsive & adaptive toolkit.
One package. Zero boilerplate. Every responsive pattern you'll ever need.
✨ 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';
🎨 Multi-Canvas Figma Setup (recommended)
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