Skip to content

Commit ab78d07

Browse files
committed
Create Migration Guide
- Create Migration from v0.2.0 to v1.0.0 guide.
1 parent c8f6a74 commit ab78d07

File tree

1 file changed

+221
-0
lines changed

1 file changed

+221
-0
lines changed

migration_0.2.0_to_1.0.0.md

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
# v1.0.0 Migration Guide
2+
3+
The legacy ResponsiveWrapper combined multiple features into one widget. This made it difficult to use at times when custom behavior was required. The updated V1 implementation separates each feature into its own widget.
4+
5+
**Before**
6+
7+
- ResponsiveWrapper
8+
9+
**After**
10+
- ResponsiveBreakpoints
11+
- ResponsiveScaledBox
12+
- MaxWidthBox
13+
14+
## Example
15+
16+
**Before**
17+
18+
```dart
19+
MaterialApp(
20+
builder: (context, child) => ResponsiveWrapper.builder(
21+
BouncingScrollWrapper.builder(context, child!),
22+
maxWidth: 1200,
23+
minWidth: 450,
24+
defaultScale: true,
25+
breakpoints: [
26+
const ResponsiveBreakpoint.resize(450, name: MOBILE),
27+
const ResponsiveBreakpoint.autoScale(800, name: TABLET),
28+
const ResponsiveBreakpoint.resize(1920, name: DESKTOP),
29+
const ResponsiveBreakpoint.autoScale(2460, name: "4K"),
30+
],
31+
background: Container(color: const Color(0xFFF5F5F5))),
32+
);
33+
```
34+
35+
**After**
36+
37+
```dart
38+
MaterialApp(
39+
builder: (context, child) => ResponsiveBreakpoints.builder(
40+
child: child!,
41+
breakpoints: [
42+
const Breakpoint(start: 0, end: 450, name: MOBILE),
43+
const Breakpoint(start: 451, end: 800, name: TABLET),
44+
const Breakpoint(start: 801, end: 1920, name: DESKTOP),
45+
const Breakpoint(start: 1921, end: double.infinity, name: '4K'),
46+
],
47+
),
48+
onGenerateRoute: (RouteSettings settings) {
49+
return MaterialPageRoute(builder: (context) {
50+
// The following code implements the legacy ResponsiveWrapper AutoScale functionality
51+
// using the new ResponsiveScaledBox. The ResponsiveScaledBox widget preserves
52+
// the legacy ResponsiveWrapper behavior, scaling the UI instead of resizing.
53+
//
54+
// **MaxWidthBox** - A widget that limits the maximum width.
55+
// This is used to create a gutter area on either side of the content.
56+
//
57+
// **ResponsiveScaledBox** - A widget that renders its child
58+
// with a FittedBox set to the `width` value. Set the fixed width value
59+
// based on the active breakpoint.
60+
return MaxWidthBox(
61+
maxWidth: 1200,
62+
background: Container(color: const Color(0xFFF5F5F5)),
63+
child: ResponsiveScaledBox(
64+
width: ResponsiveValue<double>(context, conditionalValues: [
65+
Condition.equals(name: MOBILE, value: 450),
66+
Condition.between(start: 800, end: 1100, value: 800),
67+
Condition.between(start: 1000, end: 1200, value: 1000),
68+
// There are no conditions for width over 1200
69+
// because the `maxWidth` is set to 1200 via the MaxWidthBox.
70+
]).value,
71+
child: BouncingScrollWrapper.builder(
72+
context, buildPage(settings.name ?? ''),
73+
dragWithMouse: true),
74+
),
75+
);
76+
});
77+
},
78+
);
79+
```
80+
81+
82+
#### ResponsiveScaledBox
83+
> ResponsiveScaledBox(width: width, child: child);
84+
85+
Replaces the core AutoScale functionality of ResponsiveWrapper. ResponsiveScaledBox renders the `child` widget with the specified `width`.
86+
87+
This widget wraps the Flutter `FittedBox` widget with a `LayoutBuilder` and `MediaQuery`.
88+
89+
**Why should you use a `ResponsiveScaledBox`?**
90+
91+
Use a `ResponsiveScaledBox` instead of a `FittedBox` if the layout is full screen as the widget helps calculate correctly scaled `MediaQueryData`.
92+
93+
#### MaxWidthBox
94+
> MaxWidthBox(maxWidth: maxWidth, background: background, child: child);
95+
96+
Limit the `child` widget to the `maxWidth` and paints an optional `background` behind the widget.
97+
98+
This widget is helpful for limiting the content width on large desktop displays and creating gutters on the left and right side of the page.
99+
100+
## Walkthrough
101+
102+
### Core Concept
103+
104+
The v0.2.0 ResponsiveWrapper is deprecated and the old `AutoScale` functionality has been moved to `ResponsiveScaledBox`.
105+
Now, breakpoints and `AutoScale` behavior are separated. This enables "page-level" responsiveness and more customizability in v1.0.0 which was a limitation of v0.2.0.
106+
107+
The `maxWidth` feature has been moved to `MaxWidthBox`.
108+
109+
### Step 1: Migrate ResponsiveWrapper to ResponsiveBreakpoints
110+
111+
```dart
112+
ResponsiveBreakpoints.builder(
113+
child: child!,
114+
breakpoints: [
115+
const Breakpoint(start: 0, end: 450, name: MOBILE),
116+
const Breakpoint(start: 451, end: 800, name: TABLET),
117+
const Breakpoint(start: 801, end: 1920, name: DESKTOP),
118+
const Breakpoint(start: 1921, end: double.infinity, name: '4K'),
119+
],
120+
)
121+
```
122+
123+
#### Breakpoints
124+
125+
**Old**
126+
```dart
127+
const ResponsiveBreakpoint.resize(450, name: MOBILE)
128+
```
129+
130+
**New**
131+
```dart
132+
const Breakpoint(start: 0, end: 450, name: MOBILE)
133+
```
134+
135+
In v1.0.0, breakpoints are explicit and clearly define a `start` and `end`.
136+
It's highly recommended to create contiguous breakpoints from `0` to `double.infinity`.
137+
138+
#### Tags
139+
140+
**Old**
141+
```dart
142+
const ResponsiveBreakpoint.tag(900, name: 'EXPAND_SIDE_PANEL')
143+
```
144+
145+
**New**
146+
```dart
147+
const Breakpoint(start: 900, end: 900, name: 'EXPAND_SIDE_PANEL')
148+
```
149+
150+
To create a "TAG", set the start and end breakpoints to the same value.
151+
For example, if you're building a Material 3 Navigation Rail and want to expand the menu to full width once there is enough room, you can add a custom `EXPAND_SIDE_PANEL` breakpoint.
152+
153+
Then, in your code, show the Rail based on the breakpoint condition.
154+
155+
> expand: ResponsiveBreakpoints.of(context).largerThan('EXPAND_SIDE_PANEL')
156+
157+
## Step 2: Migrate AutoScale to ResponsiveScaledBox
158+
159+
The `ResponsiveScaledBox` replaces the AutoScale functionality from `ResponsiveWrapper`.
160+
161+
**Before**
162+
163+
```dart
164+
ResponsiveWrapper.builder(
165+
child: child,
166+
maxWidth: 1200,
167+
minWidth: 450,
168+
defaultScale: true,
169+
breakpoints: [...],
170+
)
171+
```
172+
173+
**After**
174+
175+
```dart
176+
ResponsiveScaledBox(
177+
width: ResponsiveValue<double>(context, conditionalValues: [
178+
Condition.equals(name: MOBILE, value: 450),
179+
Condition.between(start: 800, end: 1100, value: 800),
180+
Condition.between(start: 1000, end: 1200, value: 1000),
181+
]).value,
182+
child: child,
183+
)
184+
```
185+
186+
The ResponsiveScaledBox takes a ResponsiveValue<double> for its width property. The ResponsiveValue looks up the value based on breakpoint conditions.
187+
188+
For example:
189+
190+
> Condition.equals(name: MOBILE, value: 450),
191+
192+
The first condition checks if the active breakpoint name equals "MOBILE". If true, it will return the value 450.
193+
194+
When the MOBILE breakpoint is active (the screen width is between 0 and 450), this condition will match and the ResponsiveScaledBox width will be set to 450. This is useful for AutoScaling on screens that are too small and avoiding layout errors.
195+
196+
The ResponsiveValue allows you to define different width values for each breakpoint. It will find the first condition that matches the current active breakpoint, and return that conditional value.
197+
198+
Define fixed width values per breakpoint with Conditions. `Condition.equals()`, `Condition.between()`, etc.
199+
200+
## Step 3: Migrate MaxWidth to MaxWidthBox
201+
The `MaxWidthBox` replaces the maxWidth property from `ResponsiveWrapper`.
202+
203+
**Before**
204+
205+
```dart
206+
ResponsiveWrapper.builder(
207+
maxWidth: 1200,
208+
child: child
209+
)
210+
```
211+
212+
**After**
213+
214+
```dart
215+
MaxWidthBox(
216+
maxWidth: 1200,
217+
child: child
218+
)
219+
```
220+
221+
Wrap the `MaxWidthBox` around a page to limit the max width.

0 commit comments

Comments
 (0)