Skip to content

Commit

Permalink
[FluentGrid] Add AdaptiveRendering property (#1899)
Browse files Browse the repository at this point in the history
* Add FluentGrid AdaptiveRendering property

* Add Unit Tests

* Update doc
  • Loading branch information
dvoituron authored Apr 20, 2024
1 parent cf681e7 commit 6206acc
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 11 deletions.
21 changes: 21 additions & 0 deletions examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3557,6 +3557,9 @@
<member name="P:Microsoft.FluentUI.AspNetCore.Components.FluentGrid.Module">
<summary />
</member>
<member name="P:Microsoft.FluentUI.AspNetCore.Components.FluentGrid.CurrentSize">
<summary />
</member>
<member name="P:Microsoft.FluentUI.AspNetCore.Components.FluentGrid.Spacing">
<summary>
Gets or sets the distance between flexbox items, using a multiple of 4px.
Expand All @@ -3568,6 +3571,12 @@
Defines how the browser distributes space between and around content items.
</summary>
</member>
<member name="P:Microsoft.FluentUI.AspNetCore.Components.FluentGrid.AdaptiveRendering">
<summary>
Gets or sets the adaptive rendering, which not render the HTML code when the item is hidden (true) or only hide the item by CSS (false).
Default is false.
</summary>
</member>
<member name="P:Microsoft.FluentUI.AspNetCore.Components.FluentGrid.ChildContent">
<summary>
Gets or sets the child content of component.
Expand Down Expand Up @@ -3631,6 +3640,12 @@
See https://developer.mozilla.org/en-US/docs/Web/CSS/gap
</summary>
</member>
<member name="P:Microsoft.FluentUI.AspNetCore.Components.FluentGridItem.AdaptiveRendering">
<summary>
Gets or sets the adaptive rendering, which not render the HTML code when the item is hidden (true) or only hide the item by CSS (false).
Default is false.
</summary>
</member>
<member name="P:Microsoft.FluentUI.AspNetCore.Components.FluentGridItem.HiddenWhen">
<summary>
Hide the item on the specified sizes (you can combine multiple values: GridItemHidden.Sm | GridItemHidden.Xl).
Expand All @@ -3648,6 +3663,12 @@
<member name="P:Microsoft.FluentUI.AspNetCore.Components.FluentGridItem.HiddenAttribute">
<summary />
</member>
<member name="M:Microsoft.FluentUI.AspNetCore.Components.FluentGridItem.RenderChildContent">
<summary />
</member>
<member name="M:Microsoft.FluentUI.AspNetCore.Components.FluentGridItem.ConvertToHidden(Microsoft.FluentUI.AspNetCore.Components.GridItemSize)">
<summary />
</member>
<member name="M:Microsoft.FluentUI.AspNetCore.Components.FluentGridItem.GetHiddenAttribute(System.Nullable{Microsoft.FluentUI.AspNetCore.Components.GridItemHidden})">
<summary>
Returns the hidden attribute value for the specified <see cref="T:Microsoft.FluentUI.AspNetCore.Components.GridItemHidden"/> value.
Expand Down
2 changes: 1 addition & 1 deletion examples/Demo/Shared/Pages/Grid/Examples/GridDefault.razor
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<FluentSlider @bind-Value="@Spacing" Min="0" Max="10" Step="1" Style="max-width: 300px; margin-top: 18px;" />
</FluentStack>

<FluentGrid Spacing="@Spacing" OnBreakpointEnter="@OnBreakpointEnterHandler" Justify="@Justification" Style="background-color: var(--neutral-layer-3); padding: 4px; ">
<FluentGrid Spacing="@Spacing" OnBreakpointEnter="@OnBreakpointEnterHandler" AdaptiveRendering="true" Justify="@Justification" Style="background-color: var(--neutral-layer-3); padding: 4px; ">
<FluentGridItem xs="12">
<div class="card">
xs="12"
Expand Down
7 changes: 7 additions & 0 deletions examples/Demo/Shared/Pages/Grid/GridPage.razor
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@
To display an element only on a given range of screen sizes, you can combine a these values.
e.g. <code>GridItemHidden.Md | GridItemHidden.Lg</code> will display the element for all screen sizes, except on medium and large devices.
</p>
<p>
<b>AdaptiveRendering</b> allows for not generating HTML code in a <b>FluentGridItem</b> based on the value of the <code>HiddenWhen</code> parameter.
In other words, when <code>AdaptiveRendering=false</code> (default), the content of the <b>FluentGridItem</b> is simply hidden by CSS styles,
whereas if <code>AdaptiveRendering=true</code>, the content of the <b>FluentGridItem</b> is not rendered by Blazor.
This allows for fine-grained control over when HTML is generated or not, for example in a case where rendering the grid item takes
a lot of time or leads to a lot of data being transferred.
</p>
<p>
<FluentDataGrid Items="@AllHiddenValues" GridTemplateColumns="28fr 12fr 12fr 12fr 12fr 12fr 12fr" ItemKey="@(i => new Random().Next())">
<TemplateColumn Align="Align.Start" Style="align-self: unset;">
Expand Down
10 changes: 6 additions & 4 deletions src/Core/Components/Grid/FluentGrid.razor
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
@namespace Microsoft.FluentUI.AspNetCore.Components
@inherits FluentComponentBase

<div class="@ClassValue" style="@StyleValue" @attributes="AdditionalAttributes">
<div id="@GetId()" class="fluent-grid" style="@($"justify-content: {Justify.ToAttributeValue()};")" spacing="@Spacing">
@ChildContent
<CascadingValue IsFixed Value="this">
<div class="@ClassValue" style="@StyleValue" @attributes="AdditionalAttributes">
<div id="@GetId()" class="fluent-grid" style="@($"justify-content: {Justify.ToAttributeValue()};")" spacing="@Spacing">
@ChildContent
</div>
</div>
</div>
</CascadingValue>
17 changes: 15 additions & 2 deletions src/Core/Components/Grid/FluentGrid.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Microsoft.FluentUI.AspNetCore.Components;
public partial class FluentGrid : FluentComponentBase, IAsyncDisposable
{
private const string JAVASCRIPT_FILE = "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/Grid/FluentGrid.razor.js";
private DotNetObjectReference<FluentGrid>? _dotNetHelper = null;
private DotNetObjectReference<FluentGrid>? _dotNetHelper = null;

public FluentGrid()
{
Expand All @@ -30,6 +30,9 @@ public FluentGrid()
/// <summary />
private IJSObjectReference? Module { get; set; }

/// <summary />
internal GridItemSize? CurrentSize { get; private set; }

/// <summary>
/// Gets or sets the distance between flexbox items, using a multiple of 4px.
/// Only values from 0 to 10 are possible.
Expand All @@ -43,6 +46,13 @@ public FluentGrid()
[Parameter]
public JustifyContent Justify { get; set; } = JustifyContent.FlexStart;

/// <summary>
/// Gets or sets the adaptive rendering, which not render the HTML code when the item is hidden (true) or only hide the item by CSS (false).
/// Default is false.
/// </summary>
[Parameter]
public bool AdaptiveRendering { get; set; } = false;

/// <summary>
/// Gets or sets the child content of component.
/// </summary>
Expand Down Expand Up @@ -76,9 +86,12 @@ protected async override Task OnAfterRenderAsync(bool firstRender)
[JSInvokable]
public async Task FluentGrid_MediaChangedAsync(string size)
{
bool valid = Enum.TryParse<GridItemSize>(size, ignoreCase: true, out var sizeEnum);
CurrentSize = valid ? sizeEnum : null;

if (OnBreakpointEnter.HasDelegate)
{
if (Enum.TryParse<GridItemSize>(size, ignoreCase: true, out var sizeEnum))
if (valid)
{
await OnBreakpointEnter.InvokeAsync(sizeEnum);
}
Expand Down
7 changes: 5 additions & 2 deletions src/Core/Components/Grid/FluentGridItem.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@
@inherits FluentComponentBase

<div class="@ClassValue" style="@StyleValue" xs="@(NoBreakpointsDefined() ? 0 : xs)" sm=@sm md=@md lg=@lg xl=@xl xxl=@xxl hidden-when="@HiddenAttribute" @attributes="AdditionalAttributes">
@ChildContent
</div>
@if (RenderChildContent())
{
@ChildContent
}
</div>
43 changes: 43 additions & 0 deletions src/Core/Components/Grid/FluentGridItem.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ public partial class FluentGridItem : FluentComponentBase
#pragma warning restore SA1300
#pragma warning restore IDE1006

[CascadingParameter]
internal FluentGrid? Grid { get; set; }

/// <summary>
/// Defines how the browser distributes space between and around content items.
/// </summary>
Expand All @@ -70,6 +73,13 @@ public partial class FluentGridItem : FluentComponentBase
[Parameter]
public string? Gap { get; set; }

/// <summary>
/// Gets or sets the adaptive rendering, which not render the HTML code when the item is hidden (true) or only hide the item by CSS (false).
/// Default is false.
/// </summary>
[Parameter]
public bool? AdaptiveRendering { get; set; }

/// <summary>
/// Hide the item on the specified sizes (you can combine multiple values: GridItemHidden.Sm | GridItemHidden.Xl).
/// </summary>
Expand Down Expand Up @@ -109,6 +119,39 @@ private string? HiddenAttribute
}
}

/// <summary />
private bool RenderChildContent()
{
if (Grid != null && Grid.CurrentSize != null && HiddenWhen != null && (Grid.AdaptiveRendering == true || AdaptiveRendering == true))
{
return !HiddenWhen.Value.HasFlag(ConvertToHidden(Grid.CurrentSize.Value));
}

return true;
}

/// <summary />
private GridItemHidden ConvertToHidden(GridItemSize size)
{
switch (size)
{
case GridItemSize.Xs:
return GridItemHidden.Xs;
case GridItemSize.Sm:
return GridItemHidden.Sm;
case GridItemSize.Md:
return GridItemHidden.Md;
case GridItemSize.Lg:
return GridItemHidden.Lg;
case GridItemSize.Xl:
return GridItemHidden.Xl;
case GridItemSize.Xxl:
return GridItemHidden.Xxl;
default:
return GridItemHidden.None;
}
}

/// <summary>
/// Returns the hidden attribute value for the specified <see cref="GridItemHidden"/> value.
/// </summary>
Expand Down
45 changes: 43 additions & 2 deletions tests/Core/Grid/FluentGridTests.razor
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@using Xunit;
@using Xunit;
@inherits TestContext
@code
{
Expand Down Expand Up @@ -79,6 +79,7 @@
//Assert
cut.Verify();
}

#pragma warning disable xUnit1025
[Theory]
[InlineData(GridItemHidden.Xs, "xs")]
Expand Down Expand Up @@ -113,4 +114,44 @@
Assert.Equal(assert, hiddenAttribute);
}
#pragma warning restore xUnit1025
}

[Fact]
public async void FluentGrid_Grid_AdaptiveRendering()
{
// Arrange && Act
var cut = Render(
@<FluentGrid AdaptiveRendering="true">
<FluentGridItem HiddenWhen="GridItemHidden.XsAndUp">Cell 1</FluentGridItem>
<FluentGridItem HiddenWhen="GridItemHidden.XxlAndUp">Cell 2</FluentGridItem>
</FluentGrid>
);

// Simulate screen size Medium
var grid = cut.FindComponent<FluentGrid>();
await grid.Instance.FluentGrid_MediaChangedAsync("md");
grid.Render();

//Assert
Assert.DoesNotContain("Cell 1", cut.Markup);
}

[Fact]
public async void FluentGrid_GridItem_AdaptiveRendering()
{
// Arrange && Act
var cut = Render(
@<FluentGrid>
<FluentGridItem AdaptiveRendering="true" HiddenWhen="GridItemHidden.XsAndUp">Cell 1</FluentGridItem>
<FluentGridItem HiddenWhen="GridItemHidden.XxlAndUp">Cell 2</FluentGridItem>
</FluentGrid>
);

// Simulate screen size Medium
var grid = cut.FindComponent<FluentGrid>();
await grid.Instance.FluentGrid_MediaChangedAsync("md");
grid.Render();

//Assert
Assert.DoesNotContain("Cell 1", cut.Markup);
}
}

0 comments on commit 6206acc

Please sign in to comment.