device_preview 3.0.0-prerelease5
device_preview: ^3.0.0-prerelease5 copied to clipboard
A custom WidgetsBinding that simulates device characteristics (screen metrics, safe areas, locale, brightness, text scale, accessibility flags, target platform) at the engine-abstraction level. No in- [...]
Changelog #
3.0.0-prerelease5 #
- The built-in
DevicePresetsare now generated from the shared device spec catalog (device_specs/at the repository root) and carry the complete spec — frame artwork and system UI included — identical to what the DevTools panel pushes.applyPresettherefore shows the framed device without DevTools attached (golden tests, CI). Every preset keeps its name and id; unreferenced presets still tree-shake away, artwork included. Regenerate withdart run tool/generate_presets.dartafter editing a spec (a guard test fails when the checked-in catalog is stale). - The area around the simulated device is now painted by default with the
new
DotGridDecoration: a dark grey with a subtle dot pattern (in real pixels, so its density does not change with the device or the fit scale), which keeps dark device bodies readable where the engine's plain black swallowed them.DevicePreview.enable'sbackgroundDecorationnow accepts anyDecoration(not onlyBoxDecoration), is painted in real logical pixels, andnullnow explicitly leaves the area unpainted. - New
DevicePreviewController.applyJson(json): decodes a device spec (a JSON string or map in thedevice_specs/*.json/DevicePreset.toJson()format, frame artwork and system UI included), registers it as a preset and applies it. - DevTools: the device picker gains a "New device from JSON…" entry. Pasted specs are validated, applied immediately, saved in the browser and listed under "My devices" in later sessions (with a remove button).
- The Apple catalog now mirrors the iOS 26.5 simulator line-up (21 devices,
33 in all), every one derived from its real simulator: added iPhone 17 Pro
Max, iPhone SE (3rd gen) — back as
DevicePresets.iPhoneSe3, with the Home-button chassis, a 20 pt status bar and no other safe area — iPad Pro 11"/13" (M5), iPad Air 11"/13" (M2) and (M4), iPad (A16) and iPad (10th gen). The iPad Airs' M3 entries became the M4 generation (same chassis and metrics). Removed iPhone 16e (DevicePresets.iPhone16e), which Xcode no longer offers as an iOS 26.5 destination. - Breaking: the iPad ids and preset names now carry their chip so the
generations can coexist:
apple-ipad-pro-11→apple-ipad-pro-11-m4(DevicePresets.iPadPro11M4),apple-ipad-air-11→apple-ipad-air-11-m4(iPadAir11M4), and likewise for the 13" models;apple-ipad-minikeeps its id but is named "iPad mini (A17 Pro)".
3.0.0-prerelease4 #
- The iPhone and iPad frames are now derived from the official iOS
Simulator bezel artwork (Xcode's "Show Device Bezels" chrome): exact
body sizes, bezel borders, Apple's own outer corner radii, and the true
continuous-curvature display outlines from the simulator framebuffer
masks, notch and Dynamic Island included. See
.claude/skills/extract-cupertino-specs/for the extraction process. - Apple metrics are now verified against a live simulator: a probe app is
booted per device type and reports the safe areas UIKit actually applies.
The iPhone values were confirmed exact; every iPad's bottom safe-area
inset was corrected from 20 to 25 logical pixels (both orientations), in
the specs and the built-in
DevicePresets. - Every Apple device in the catalog now has its own real simulator (Xcode
26.6 device profiles, probed on iOS 26.5): the iPhone 16e, 17, 17 Pro,
17e and Air no longer borrow another model's artwork or hand-modelled
metrics — the 16e/17e notch outline and the Air's squircle come from
Apple's own framebuffer masks, and the iPad Airs use the M3 chassis (59
pt bezel). Safe areas follow iOS 26: every iPad's top inset is 32 (was
24), landscape iPhones report a 20 pt bottom inset (was 21), and the
iPhone Air's Dynamic Island band is 68 (was 62). Specs,
DevicePresets, fixtures and the bundled catalog updated together. - The Google Pixel specs are now derived the same way, by an Android
counterpart skill (
.claude/skills/extract-pixel-specs/): frame artwork, screen shape and the camera punch-hole cutout come from the official emulator device skins (Android Studio 2026.1), and the metrics from a booted Android 16 emulator. Pixel 9/10 sizes are now the exact 411.43×923.43 a device reports (was the rounded 412×923), the fold is 851.69×882.87 with its crease recentred accordingly, and the safe areas match today's Android 16 system bars — including its taller status bar (54 dp portrait / 52 landscape on the slabs; 36/56 on the fold, bottom 24 and 32 respectively). Specs, built-inDevicePresetsand the bundled catalog all updated together; the frames now show each device's punch hole (top-centre on the slabs, top-right on the fold's inner display). - Compatibility with Flutter 3.47:
PreviewPlatformDispatcherforwards the newPlatformDispatcher.onHitTestcallback. The minimum Flutter version is now 3.47.0. - Four foldable presets — the catalog's first: Pixel 10 Pro Fold
(
DevicePresets.pixel10ProFold), Galaxy Z Fold8 (galaxyZFold8), Galaxy Z Fold8 Ultra (galaxyZFold8Ultra) and Galaxy Z Flip8 (galaxyZFlip8), 26 devices in all. Each simulates its unfolded inner display and reports the crease as afolddisplay feature (postureFlat), so hinge-aware layouts such as two-pane split at the fold, in both orientations. package:device_preview/presets.dartnow re-exportsSimulatedDisplayFeature, which the foldable presets carry.
3.0.0-prerelease3 #
DevicePreview.enablegainedpaddingandbackgroundDecorationparameters:paddingreserves room around the simulated device when it is fitted into the real window, andbackgroundDecorationpaints the window behind the device (the letterbox). Both are latched at enable time, likeenabled.- The safe areas of the hosting platform (a real notch, status bar, or home indicator) are now automatically added to the padding, so the simulated device stays clear of the host's own system UI.
- Breaking:
DevicePreview.enable's positional flag became the namedenabledparameter —DevicePreview.enable(kDebugMode)is nowDevicePreview.enable(enabled: kDebugMode). - The example gained a "device lab" showcase app (
example/lib/showcase.dart) that makes every simulated characteristic visible: labeled safe-area bands, a locale- and 24-hour-aware clock, a hinge-aware two-pane layout, and an animation that honorsdisableAnimations.
3.0.0-prerelease2 #
Device catalog refreshed to the two latest generations — 22 devices:
- Added iPhone 16 Plus and iPhone 16e (completing the 16 line), iPad Pro 11", iPad Air 11" and 13", Pixel 10, Galaxy S25, and the Galaxy Tab S10+ and Tab S11 tablets.
- Removed iPhone SE (3rd gen) (
DevicePresets.iPhoneSe3), Pixel 8 (DevicePresets.pixel8) and Pixel Tablet (DevicePresets.pixelTablet); the generic desktop windows remain. Apps that referenced the removed presets can keep the metrics as customDevicePresets viaregisterPreset. - The bundled DevTools extension ships the matching regenerated catalog (frame artwork included) for every device above.
3.0.0-prerelease1 #
The 3.0 release is a from-scratch rebuild: a custom WidgetsBinding that
simulates device characteristics (screen metrics, safe areas, locale,
brightness, text scale, accessibility flags, target platform) at the
engine-abstraction level. There is no in-app UI — the simulation is driven
programmatically through DevicePreview.controller and from the bundled
Flutter DevTools extension. See the README for the full feature tour and the
2.x migration notes, and the 3.0.0-dev.* entries below for the rebuild's
incremental history.
Changes since 3.0.0-dev.2:
DevicePreviewBindingMixin.latchConfigurationis now sentinel-based:DevicePreview.enable()afterlatchConfiguration(initialSimulation: ...)no longer silently discards the latched simulation (the documented golden/CI startup sequence).setOrientationkeeps the activeframeandsystemUiartwork when the simulation was pushed from DevTools (rotation is not a device switch).applyPresetandsetOrientationnow preservetouchInputandshowSystemUi, matching the DevTools panel's definition of device-switch-surviving overrides.- Simulated
MediaQuery.paddingnow collapses where the real keyboard'sviewInsetsoverlap it, matching real engine behavior. - SVG artwork:
fill="currentColor"now follows the paint-time tint (the app'sSystemUiOverlayStyle) even nested under groups with an explicit ornonefill, per CSScurrentColorsemantics. - DevTools panel: landscape
viewPaddingnow falls back throughlandscapePaddingexactly likeDevicePreset.resolve, so DevTools andapplyPresetproduce identical metrics for every catalog device. - DevTools panel: a rejected payload (
invalidParams) no longer flips the panel to the "isolate paused" empty state; the panel re-fetches the app's actual state instead. - DevTools panel: the in-memory simulation stash is cleared on disconnect, so a previous app's simulation is never pushed into a different app on reconnect (the persisted stash stays keyed per VM-service URI).
- New test layers: a VM-service e2e smoke over the real service-extension
glue (
tool/check_release.shruns it), a production-composition host-resize seam test, and screenshot capture tests.
3.0.0-dev.2 #
- Simulated system UI:
DeviceSimulation.systemUi(SystemUiSimulation) draws a static status bar and gesture pill over the app, laid out from the simulated safe areas, and tinted from the app's liveSystemUiOverlayStyle(SystemUiColors.resolve). The binding tracks that style through bothSystemChrome.setSystemUIOverlayStyleandAnnotatedRegion— the latter needing its own annotation lookup, since the framework's probes assume a plain device-pixel-ratio root transform and miss under scale-to-fit. DeviceSimulation.showSystemUishows or hides those bars without touching the safe areas they occupy.DeviceSimulation.touchInput(bool?) reports the host's pointers to the app as touches, so dragging scrolls (the mouse is not a drag device on desktop or the web). Unset — the default — means auto: the simulated device decides, through the newDeviceSimulation.deviceKindthat presets fill in. A phone, tablet or foldable is a touchscreen; a desktop window is not, and neither is a custom size that names no device. Hovers are dropped rather than relabelled, pointer signals (wheel, trackpad) keep their real kind, and the host's hover state is released when the mode changes.DeviceKindmoved to the core library (still exported frompresets.dart), since a simulation carries it too. Protocol version 3.SvgDrawing.paint(currentColor:)tints every shape that inherited its fill, which is what makes one drawing serve as a tintable icon set.- Device frames:
DeviceSimulation.frame(DeviceFrame) carries the screen outline the app is clipped to and the SVG body painted behind it, described in portrait and rotated with the device. The scale-to-fit letterbox and the screenshot capture now cover the whole body (DeviceSimulation.contentBounds,FitTransform.compute(contentBounds:)). DevicePreviewFrame/RenderDevicePreviewFrame, installed automatically by the binding around the root widget.- Embedded, dependency-free SVG subset renderer exported as
package:device_preview/svg.dart(SvgDrawing,parseSvgPathData,parseXmlDocument). DevicePresetgainsbrandandframe; the JSON form matches thedevice_specs/catalog at the root of the repository.- Protocol version 2:
simulation.frameand theframecapability flag.
3.0.0-dev.1 #
- From-scratch rebuild (work in progress).
- Pure model layer:
DeviceSimulation,SimulatedAccessibilityFeatures,SimulatedDisplayFeature,RealDeviceInfo,FitTransform, pointer rewrite, and theDevicePresetscatalog. - Binding layer:
DevicePreviewandDevicePreviewBindingMixinwith the wrapperPlatformDispatcher/FlutterViewpair, the scale-to-fitViewConfiguration, and pointer remapping. DevicePreviewController(apply/update/applyPreset/setOrientation/reset, liverealDevice,fitTransform, custom preset registration).ext.device_preview.*service extensions:getState,setSimulation,reset,listPresets, plus the optional capability-flaggedscreenshotmodule, and thedevice_preview.ready/stateChanged/presetsChangedevents.