device_wrapper 1.0.0
device_wrapper: ^1.0.0 copied to clipboard
A Flutter package to wrap pages with realistic device frames (iPhone 17 Pro, iPad Gen 11) for web/desktop preview. Features auto-scaling, Dynamic Island, and smooth mode switching.
Device Wrapper #
A Flutter package to wrap pages with realistic device frames (iPhone 17 Pro, iPad Gen 11) for web/desktop preview. Features auto-scaling to fit any screen size, Dynamic Island, and smooth mode switching animations.
Features #
- 📱 Realistic Device Frames: iPhone 17 Pro (393×852) and iPad Gen 11 (820×1180) with accurate dimensions
- 🏝️ Dynamic Island: Modern iPhone-style Dynamic Island with camera lens effect
- 📐 Auto-Scaling: Automatically scales device to fit within browser/window size
- 🔄 Mode Toggle: Built-in animated toggle button to switch between mobile and tablet
- 🎨 Titanium Frame: Gradient frame design mimicking real device bezels
- ⚙️ Customizable: Configure device dimensions, colors, and styling
- 🎬 Smooth Animations: Animated transitions when switching between modes
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
device_wrapper: ^1.0.0
Then run:
flutter pub get
Usage #
Basic Usage #
Wrap your MaterialApp with DeviceWrapper for web preview:
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:device_wrapper/device_wrapper.dart';
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final materialApp = MaterialApp(
home: MyHomePage(),
);
// Only use DeviceWrapper on web
if (kIsWeb) {
return DeviceWrapper(
initialMode: DeviceMode.mobile,
showModeToggle: true,
child: materialApp,
);
}
return materialApp;
}
}
With Mode Change Callback #
DeviceWrapper(
initialMode: DeviceMode.mobile,
showModeToggle: true,
onModeChanged: (mode) {
print('Device mode changed to: ${mode.displayName}');
},
child: MyApp(),
)
Custom Device Configuration #
DeviceWrapper(
initialMode: DeviceMode.mobile,
mobileConfig: DeviceConfig(
width: 375,
height: 812,
borderRadius: 44.0,
borderWidth: 5.0,
borderColor: Colors.black,
showNotch: true,
showHomeIndicator: true,
),
tabletConfig: DeviceConfig(
width: 834,
height: 1194,
borderRadius: 20.0,
borderWidth: 6.0,
showNotch: false,
showHomeIndicator: true,
),
child: MyApp(),
)
Custom Background Color #
DeviceWrapper(
backgroundColor: const Color(0xFF0D1117), // GitHub dark theme
child: MyApp(),
)
Disable Wrapper (for production) #
DeviceWrapper(
enabled: false, // Renders child directly without wrapper
child: MyApp(),
)
API Reference #
DeviceWrapper #
| Property | Type | Default | Description |
|---|---|---|---|
child |
Widget |
required | The widget to wrap inside the device frame |
initialMode |
DeviceMode |
DeviceMode.mobile |
Initial device mode |
showModeToggle |
bool |
true |
Whether to show the mode toggle button |
mobileConfig |
DeviceConfig? |
null |
Custom configuration for mobile mode |
tabletConfig |
DeviceConfig? |
null |
Custom configuration for tablet mode |
onModeChanged |
ValueChanged<DeviceMode>? |
null |
Callback when device mode changes |
enabled |
bool |
true |
Whether the wrapper is enabled |
backgroundColor |
Color? |
null |
Background color for the area outside the device |
DeviceMode #
enum DeviceMode {
mobile, // iPhone 17 Pro (393×852)
tablet, // iPad Gen 11 (820×1180)
}
DeviceConfig #
| Property | Type | Default | Description |
|---|---|---|---|
width |
double |
varies | Width of the device screen |
height |
double |
varies | Height of the device screen |
borderRadius |
double |
55.0 / 24.0 |
Border radius for the device frame |
borderWidth |
double |
5.0 / 6.0 |
Border width for the device frame (thin bezel) |
borderColor |
Color |
Color(0xFF1C1C1E) |
Titanium frame color |
backgroundColor |
Color |
Color(0xFF1A1A2E) |
Background color |
shadows |
List<BoxShadow> |
default shadows | Shadow configuration |
showNotch |
bool |
true / false |
Whether to show Dynamic Island (mobile only) |
showHomeIndicator |
bool |
true |
Whether to show the home indicator |
Default Device Configurations #
Mobile - iPhone 17 Pro (393×852) #
- Scaled from actual resolution: 1206×2622
- Border radius: 55px (rounded corners)
- Border width: 5px (thin titanium bezel)
- Dynamic Island with camera lens effect
- Home indicator bar
Tablet - iPad Gen 11 (820×1180) #
- Scaled from actual resolution: 2360×1640
- Border radius: 24px
- Border width: 6px
- Home indicator only (no notch)
Auto-Scaling Behavior #
The device frame automatically scales to fit within the available browser/window size:
- Scales down when window is smaller than device dimensions
- Never scales up beyond original size (max scale = 1.0)
- Maintains aspect ratio - device is never distorted
- Responsive - automatically adjusts when resizing browser window
- Minimum scale: 0.3 (to ensure content remains visible)
Example #
Check out the example folder for a complete demo application:
cd example
flutter run -d chrome
Use Cases #
- Web Development: Preview mobile/tablet layouts when developing on web
- Client Demos: Show clients how the app looks on different devices
- Screenshot Generation: Capture consistent device-framed screenshots
- Responsive Testing: Quickly switch between device sizes during development
- Documentation: Create device mockups for documentation
License #
MIT License - see LICENSE file for details.
Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Author #
Citiasia Inc.
- GitHub: @citiasia-inc