Skip to content

fabrik_layout

pub.dev

fabrik_layout provides a lightweight responsive layout foundation for Flutter apps. It classifies the current device as mobile, tablet, or desktop based on screen width, exposes orientation, and optionally applies device-aware minimum text scaling — all available anywhere in the widget tree via context.layout.

Add the package to your pubspec.yaml:

dependencies:
fabrik_layout: ^1.1.0

Then run:

Terminal window
flutter pub get

Import it in your Dart files:

import 'package:fabrik_layout/fabrik_layout.dart';

Wrap your app inside MaterialApp.builder:

MaterialApp(
builder: (context, child) => FabrikLayout(
child: child!,
),
home: const HomePage(),
)

Then access the layout context anywhere in the tree:

final layout = context.layout;
if (layout.isMobile) {
return const MobileView();
}
if (layout.isTablet) {
return const TabletView();
}
return const DesktopView();

Use layout.value<T>() to return different values per device without a chain of if statements:

final padding = context.layout.value<double>(
mobile: 16,
tablet: 24,
desktop: 32,
);
final columns = context.layout.value<int>(
mobile: 1,
tablet: 2,
desktop: 3,
);

tablet and desktop are optional and fall back intelligently:

  • desktop not provided → uses tablet value
  • tablet not provided → uses mobile value

context.layout returns a FabrikLayoutData with:

PropertyTypeDescription
typeFabrikLayoutTypemobile, tablet, or desktop
isMobilebooltrue when on mobile
isTabletbooltrue when on tablet
isDesktopbooltrue when on desktop
screenSizeSizeCurrent screen dimensions
orientationOrientationportrait or landscape
isPortraitbooltrue when portrait
isLandscapebooltrue when landscape
textScalerTextScalerApplied text scaler

Default thresholds (width in logical pixels):

RangeDevice
< 600Mobile
600 – 1023Tablet
≥ 1024Desktop

Override them with FabrikBreakpoints:

FabrikLayout(
breakpoints: const FabrikBreakpoints(
mobile: 480,
tablet: 900,
),
child: child!,
)

final layout = context.layout;
layout.orientation // Orientation.portrait or Orientation.landscape
layout.isPortrait // true
layout.isLandscape // false

By default, text scaling is disabled. Enable it to apply device-aware minimum scale floors that respect the user’s system accessibility settings — they’re never reduced, only raised:

FabrikLayout(
enableTextScaling: true,
child: child!,
)

Default scale floors per device:

DeviceMinimum scale
Mobile1.0×
Tablet1.05×
Desktop1.1×

Customize the floors with FabrikTextScaleConfig:

FabrikLayout(
enableTextScaling: true,
textScaleConfig: const FabrikTextScaleConfig(
mobile: 1.0,
tablet: 1.1,
desktop: 1.2,
),
child: child!,
)

The system accessibility scale is never reduced — FabrikTextScaleConfig values only set a minimum floor.


class ResponsiveScaffold extends StatelessWidget {
const ResponsiveScaffold({super.key});
@override
Widget build(BuildContext context) {
final layout = context.layout;
final padding = layout.value<double>(mobile: 16, tablet: 24, desktop: 40);
final columns = layout.value<int>(mobile: 1, tablet: 2, desktop: 3);
return Scaffold(
body: Padding(
padding: EdgeInsets.all(padding),
child: GridView.count(
crossAxisCount: columns,
children: const [...],
),
),
);
}
}