-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
MudGrid: Support Responsive Layout via Order Parameter #11986
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces a useful feature for responsive grid layouts by adding Order parameters to MudItem. The implementation is clean and relies on CSS for performance, which is great. The new documentation and example are also helpful.
I've left a couple of suggestions for improvement:
- In the new example file, I've suggested a refactoring to reduce code duplication, which will make the example more maintainable and easier for users to follow.
- In the new SCSS file, I've pointed out a violation of the project's style guide regarding the use of
!importantand suggested a more concise, DRY implementation for generating the CSS classes.
Overall, this is a solid contribution. Addressing these points will further improve the code quality.
| $orders: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12; | ||
|
|
||
| @each $o in $orders { | ||
| .order-#{$o} { | ||
| order: $o !important; | ||
| } | ||
| } | ||
|
|
||
| @media (min-width: $breakpoint-sm) { | ||
| @each $o in $orders { | ||
| .order-sm-#{$o} { | ||
| order: $o !important; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| @media (min-width: $breakpoint-md) { | ||
| @each $o in $orders { | ||
| .order-md-#{$o} { | ||
| order: $o !important; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| @media (min-width: $breakpoint-lg) { | ||
| @each $o in $orders { | ||
| .order-lg-#{$o} { | ||
| order: $o !important; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| @media (min-width: $breakpoint-xl) { | ||
| @each $o in $orders { | ||
| .order-xl-#{$o} { | ||
| order: $o !important; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| @media (min-width: $breakpoint-xxl) { | ||
| @each $o in $orders { | ||
| .order-xxl-#{$o} { | ||
| order: $o !important; | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This SCSS file has two areas for improvement:
!importantUsage: The use of!importantviolates the repository's style guide, which states: 'Do not use the!importantkeyword, as it disrupts the natural cascade of styles'.1 While utility classes sometimes need!importantto guarantee they override other styles, it's best to avoid it if possible to adhere to the project's standards.- Code Repetition: The code for generating order classes for different breakpoints is very repetitive. This can be made more concise and maintainable by using SCSS loops and maps to generate the classes for all breakpoints in a DRY (Don't Repeat Yourself) manner.
Here is a suggested refactoring that addresses both points.
$orders: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12;
// Default order classes
@each $o in $orders {
.order-#{$o} {
order: $o;
}
}
// Responsive order classes
@each $breakpoint, $min-width in $breakpoints-css-utilities-only {
@media (min-width: $min-width) {
@each $o in $orders {
.order-#{$breakpoint}-#{$o} {
order: $o;
}
}
}
}Style Guide References
Footnotes
-
The style guide prohibits the use of
!importantto maintain a predictable CSS cascade. ↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mckaragoz Did you look at or try this? Any reason it won't work this implementation is much cleaner and doesn't use !important.
| @code { | ||
| // Item 1 | ||
| private int? Order1 = 1; | ||
| private int? OrderSm1; | ||
| private int? OrderMd1; | ||
| private int? OrderLg1; | ||
|
|
||
| // Item 2 | ||
| private int? Order2 = 2; | ||
| private int? OrderSm2; | ||
| private int? OrderMd2; | ||
| private int? OrderLg2; | ||
|
|
||
| // Item 3 | ||
| private int? Order3 = 3; | ||
| private int? OrderSm3; | ||
| private int? OrderMd3; | ||
| private int? OrderLg3; | ||
|
|
||
| // Item 4 | ||
| private int? Order4 = 4; | ||
| private int? OrderSm4; | ||
| private int? OrderMd4; | ||
| private int? OrderLg4; | ||
|
|
||
| // Item 5 | ||
| private int? Order5 = 5; | ||
| private int? OrderSm5; | ||
| private int? OrderMd5; | ||
| private int? OrderLg5; | ||
|
|
||
| // Item 6 | ||
| private int? Order6 = 6; | ||
| private int? OrderSm6; | ||
| private int? OrderMd6; | ||
| private int? OrderLg6; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This example contains a lot of repetitive code for managing the state of each grid item. To improve readability and maintainability, consider using a model class to represent an item's state and then rendering the items in a loop. This approach makes the example cleaner and easier to understand.
You can replace the current @code block with a view model and a list. Then, you can iterate over this list in the markup to render the MudItem components, which would significantly reduce the amount of duplicated markup as well. For example, you could replace the 6 <MudItem> blocks with a @foreach(var item in _items) loop.
@code {
private class ItemViewModel
{
public int Id { get; set; }
public int? Order { get; set; }
public int? OrderSm { get; set; }
public int? OrderMd { get; set; }
public int? OrderLg { get; set; }
}
private readonly System.Collections.Generic.List<ItemViewModel> _items = new();
protected override void OnInitialized()
{
for (var i = 1; i <= 6; i++)
{
_items.Add(new ItemViewModel { Id = i, Order = i });
}
base.OnInitialized();
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may not work because this example change values dynamically. When tried different kind of iterations i had out of range exceptions so as a last solution wrote the whole example clearly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While it is true it could be written "tighter" I agree with @mckaragoz for demonstration this is a good deconstructed example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this should be added as a feature to the grid itself it feels off for the grid.
Also you are adding duplicated css, we already have breakpoint based order for flexbox.
https://mudblazor.com/utilities/order#breakpoints
Is it not already possible to do this with the built in CSS?
Yes we can order with built in classes, but this PR is not about simple ordering, i offer multiple order classes, like order-sm-0 order-md-0. With multiple order classes we can arrange different order formats with different breakpoints. An example we have a section as third item but we want this section show first on mobile. We can do it with multiple class easily. Otherwise we need breakpoint provider and manipulate order value on breakpoint change, which is less performant i think. And you are right i didn't notice the order classes, we can remove the duplicated ones and add breakpoint-based one. |
Currently there is no option that show MudItems with different order on different screen size like laptop, tablet or mobile. The only way was rearranging items with MudHidden.
With this PR, we announce new parameters like Order, OrderSm, OrderMd, OrderLg, OrderXl and OrderXxl. With this parameters, users can re-arrange item order on different breakpoints. The last item on desktop can be the first item on mobile view with these parameters easily.
The logic only uses CSS to achieve maximum performance.
Also added an example to show clearly how this enhancement works.
Hope you like.
20251021_234450.mp4