You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There is no rocket science to contributing to this project. Just open your issue or pull request if needed - but please be descriptive!
2
+
3
+
To submit a PR, follow [these useful guidelines](https://gist.github.com/MarcDiethelm/7303312), respect the dartfmt lint (modifications/exceptions may be discussed), and create an awesome description so we can understand it.
4
+
5
+
Even though there is no "rules" to how you should contribute, there goes my quick tips on it:
6
+
7
+
- If you're experiencing a bug that can be demonstrated visually, please take screenshots and post them alongside the issue;
8
+
- For a quicker/seamless understanding of the issue, please post a sample project, so the evaluation will be bulletproof;
9
+
- This is a git overall tip - do atomic commits with a descriptive message (no more than 50 characters is ideal).
Copy file name to clipboardExpand all lines: README.md
+154-38
Original file line number
Diff line number
Diff line change
@@ -23,8 +23,23 @@ Even though the magic should happen inside the abstract `LayoutResolver`, we nee
23
23
But that's not any reason to not have built-in Layout Resolvers, and these will probably fit the most generic use-cases. To exemplify the resolvers, we can see how the `CommonLayout` works.
24
24
25
25
#### Exemplifying with CommonLayout
26
+
---
27
+
28
+
Before diving into the concepts, you have to make sure to provide a `CommonLayout` for your widgets. This can be done
29
+
in multiple different ways, although the easiest is to just wrap your top-most widget in the `CommonLayoutWidget`:
30
+
31
+
```dart
32
+
import 'package:layoutr/common_layout.dart';
33
+
34
+
// ...
35
+
CommonLayoutWidget(
36
+
child: /* My child, possibly a MaterialApp/WidgetsApp */,
37
+
);
38
+
// ...
39
+
```
40
+
41
+
Now, `CommonLayout` is split in 4 breakpoints: `desktop`, `tablet`, `phone` and `tinyHardware`. A simple usage of returning a responsive `Text` widget that has both its value and style customized based on the current device's constraints may be done like the below:
26
42
27
-
The `CommonLayout` is split in 4 breakpoints: `desktop`, `tablet`, `phone` and `tinyHardware`. A simple usage of returning a responsive `Text` widget that has both its value and style customized based on the current device's constraints may be done like the below:
> You can see that there is no `tablet` supplied to the `layout.value`, and that is intended to exemplify a common scenario, where we may want to just provide two or three arguments - and that means not all possible scenarios are "covered" - and that's where the resolver comes in handy: if the **current breakpoint** value is not passed to `layout.value`, it will fallback to the "nearest" available one, fitting the most suitable layout for your particular value. This "nearest logic" can be confusing, but you can find out more how it works in `LayoutResolver.closestValue`
47
-
48
-
Also, if you want to keep the structure but want to override the sizes of each breakpoint, you can provide your `CommonLayout` instance through the InheritedWidget called `CommonLayoutWidget`:
> You will probably want to add these above the top-most widget of your tree, usually the `MaterialApp`, but be careful that `MediaQuery` may not be available if you don't have any other widget above `CommonLayoutWidget`, which is required when we use the `context.deviceWidth`. You can check out an [`example/`](https://pub.dev/packages/layoutr/example#Common-Layout-Inherited-Widget) that overrides the custom values.
61
+
> **TLDR: all breakpoints don't need to be provided, the layout will automatically find the nearest suitable value for your current breakpoint.**
62
+
>
63
+
> Long version: you can see that there is no `tablet` supplied to the `layout.value`, and that is intended to exemplify a common scenario, where we may want to just provide two or three arguments - and that means not all possible scenarios are "covered" - and that's where the resolver comes in handy: if the **current breakpoint** value is not passed to `layout.value`, it will fallback to the "nearest" available one, fitting the most suitable layout for your particular value. This "nearest logic" can be confusing, but you can find out more how it works in `LayoutResolver.closestValue`
63
64
64
65
Other than `layout.value`, the `CommonLayout` provide utilities for simple boolean comparisons:
Tip: we can easily use this package with common libraries like `provider` (see in [`example/`](https://pub.dev/packages/layoutr/example#`provider`)) and `river_pod` (see in [`example/`](https://pub.dev/packages/layoutr/example#`river_pod`)).
96
+
##### Overriding `CommonLayout` resolver
97
+
---
98
+
99
+
To override the sizes for each breakpoint, you can provide your own `CommonLayout` instance:
> **TLDR: your app don't need to necessarily use `MaterialApp` (or `WidgetsApp`), just add it above your top-most widget.**
112
+
>
113
+
> Long version: it's probably the best to add the resolver widget above the top-most widget of your tree, because the all built-in widgets use a `LayoutBuilder` to provide such responsive features, and this may create inconsistencies if they are created in nested widgets, which will only use the parent's `BoxConstraints`. This could also be useful if you wanted to created a resolver that is not necessarily related to the device's sizes, but I fail to see a useful scenario like this at the moment.
114
+
115
+
##### Overriding `CommonLayout` spacings
116
+
---
117
+
To override the spacings for each breakpoint, you can provide your own `RawSpacings` instance:
Not sure what spacings mean? Check out [spacings](#spacings).
146
+
147
+
----
148
+
Tips:
149
+
- we can easily use this package with common libraries like `provider` (see in [`example/`](example/provider_usage/)) and `river_pod` (see in [`example/`](example/river_pod_usage/`));
150
+
- everything explained here is same for all built-in resolvers (like `GranularLayout`), they just differ in the
151
+
breakpoints amount/types.
99
152
100
153
#### Available Built-in `LayoutResolver`
101
-
-`CommonLayout`: a resolver split in 4 breakpoints: `desktop`, `tablet`, `phone` and `tinyHardware`. Import this resolver through `package:layoutr/common_layout.dart` - (see in [`example/`](https://pub.dev/packages/layoutr/example#Common-Layout));
102
-
-`GranularLayout`: a resolver split in 6 breakpoints: `xxLarge`, `xLarge`, `large`, `medium`, `small` and `xSmall`. Import this resolver through `package:layoutr/granular_layout.dart` - (see in [`example/`](https://pub.dev/packages/layoutr/example#Granular-Layout)).
154
+
---
155
+
156
+
-`CommonLayout`: a resolver split in 4 breakpoints: `desktop`, `tablet`, `phone` and `tinyHardware`. Import this resolver through `package:layoutr/common_layout.dart` - (see in [`example/`](example/common_layout/));
157
+
-`GranularLayout`: a resolver split in 6 breakpoints: `xxLarge`, `xLarge`, `large`, `medium`, `small` and `xSmall`. Import this resolver through `package:layoutr/granular_layout.dart` - (see in [`example/`](example/granular_layout/)).
158
+
159
+
#### Custom `LayoutResolver`
160
+
---
161
+
162
+
If the above built-in resolvers don't match the requirements, `LayoutResolver` can be customized by extending it, taking advantage of the utilities built-in in the abstract class itself. To extend the and implement your custom `LayoutResolver`, import `package:layoutr/layoutr.dart`. Check out a custom implementation example in the [`example/`](example/custom_layout/).
163
+
164
+
### Spacings
165
+
166
+
All spacing features revolve around `Spacing` enumerator. These are named ranges that should usually fit most use-cases
167
+
out there in the wild. They are pretty intuitive: `xxxSmall`, `xxSmall`, `xSmall`, `small`, `medium`, ... and so on.
103
168
104
-
### Custom `LayoutResolver`
169
+
Spacings are an additional help for situations where we need type-safety, responsivity, or both. Being more specific:
170
+
- type-safety: even if you don't want to use it as a responsive value, you will still benefit from having a type-safe
171
+
system that will prevent inconsistent spacings, margins and paddings in your application;
172
+
- responsivity: the spacings can be customized to one, some or all breakpoints, meaning that you won't have to change
173
+
anything if you use the `Spacing` type system.
105
174
106
-
If the above built-in resolvers don't match the requirements, `LayoutResolver` can be customized by extending it, taking advantage of the utilities built-in in the abstract class itself. To extend the and implement your custom `LayoutResolver`, import `package:layoutr/layoutr.dart`. Check out a custom implementation example in the [`example/`](https://pub.dev/packages/layoutr/example#Custom-Layout).
175
+
All built-in `LayoutResolver` will provide the spacings out-of-the-box, so no need to add anything extra other than your root widget. But this might not be the best for most. If wanted, one could use only this package's feature alone (with `SpacingsInheritedWidget`), like so:
176
+
177
+
```dart
178
+
import 'package:layoutr/layoutr.dart';
179
+
180
+
// ...
181
+
LayoutBuilder(
182
+
builder: (context, constraints) {
183
+
// If we wanted, we could use this spacings type-safety/responsivity without the resolver themselves
184
+
final myCustomSpacings = constraints.maxWidth > 800
185
+
? RawSpacings(16, 24, 32, 40, 52, 60, 68, 76, 80)
186
+
: RawSpacings(8, 12, 24, 32, 40, 48, 56, 64, 72);
187
+
188
+
return SpacingsInheritedWidget(
189
+
spacings: myCustomSpacings,
190
+
child: // ... ,
191
+
);
192
+
},
193
+
);
194
+
// ...
195
+
```
196
+
197
+
Alone this can be somewhat useful, but its potential is enhanced with the built-in utilities and resolvers
198
+
widgets - you can even build your own by extending any `BuildContext`, `Widget` or any layout-related element.
199
+
200
+
An example usage with some of the utilities:
201
+
202
+
```dart
203
+
import 'package:layoutr/layoutr.dart';
204
+
205
+
// SpacingMixin just helps you to call spacings like `smallSpacing`, instead of `Spacing.smallSpacing`, making it
206
+
// overall less verbose.
207
+
class MyPage extends StatelessWidget with SpacingMixin {
208
+
@override
209
+
Widget build(BuildContext context) {
210
+
return Scaffold(
211
+
body: Column(
212
+
children: [
213
+
Text('My page'),
214
+
// Creates a vertical responsive/type-safe spacing
215
+
context.verticalBox(xxxLargeSpacing),
216
+
Container(
217
+
// Creates a vertical symmetrical insets responsive/type-safe spacing
- Syntax-sugar for common use-cases, like: `deviceWidth` and `deviceHeight` (plus a couple more that are WIP);
111
-
- Other helper Widgets are WIP.
232
+
- Syntax-sugar for common use-cases, like: `deviceWidth` and `deviceHeight`;
233
+
-[Helpers] for commonly used elements like `EdgeInsets` and `Padding`, using `Spacing`.
234
+
235
+
Check out all [spacing utilities](lib/src/utilities.dart).
112
236
113
237
## Reference OS Projects
114
238
@@ -118,12 +242,4 @@ WIP
118
242
119
243
## Contributing
120
244
121
-
There is no rocket science to contributing to this project. Just open your issue or pull request if needed - but please be descriptive!
122
-
123
-
To submit a PR, follow [these useful guidelines](https://gist.github.com/MarcDiethelm/7303312), respect the dartfmt lint (modifications/exceptions may be discussed), and create an awesome description so we can understand it.
124
-
125
-
Even though there is no "rules" to how you should contribute, there goes my quick tips on it:
126
-
127
-
- If you're experiencing a bug that can be demonstrated visually, please take screenshots and post them alongside the issue;
128
-
- For a quicker/seamless understanding of the issue, please post a sample project, so the evaluation will be bulletproof;
129
-
- This is a git overall tip - do atomic commits with a descriptive message (no more than 50 characters is ideal).
245
+
Want to contribute? Check it out [here](CONTRIBUTING.md).
0 commit comments