Skip to content

Commit

Permalink
[Slider] Fix FluentSlider two-way binding issue [#2609} (#2665)
Browse files Browse the repository at this point in the history
* Skip publish symbols step for now

* fix problem where thumbnail is not being rendered when value is changed programmtically

* limits calls to updateSlider

* missed a file

---------

Co-authored-by: Vincent Baaij <[email protected]>
  • Loading branch information
oneolddev and vnbaaij authored Sep 17, 2024
1 parent 2d301e5 commit e2fc112
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 9 deletions.
8 changes: 4 additions & 4 deletions eng/pipelines/build-all-lib.yml
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,10 @@ extends:

# Index sources and publish symbols

- task: PublishSymbols@2
inputs:
SearchPattern: '**/bin/**/*.pdb' # string. Required. Search pattern. Default: **/bin/**/*.pdb.
SymbolServerType: 'TeamServices'
#- task: PublishSymbols@2
# inputs:
# SearchPattern: '**/bin/**/*.pdb' # string. Required. Search pattern. Default: **/bin/**/*.pdb.
# SymbolServerType: 'TeamServices'

# Since NuGet packages are generated during the build, we need to copy them to the artifacts folder.
- task: CopyFiles@2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8230,6 +8230,12 @@
Gets or sets the content to be rendered inside the component.
</summary>
</member>
<member name="P:Microsoft.FluentUI.AspNetCore.Components.FluentSlider`1.JSRuntime">
<summary />
</member>
<member name="P:Microsoft.FluentUI.AspNetCore.Components.FluentSlider`1._jsModule">
<summary />
</member>
<member name="P:Microsoft.FluentUI.AspNetCore.Components.FluentSlider`1.Min">
<summary>
Gets or sets the slider's minimal value.
Expand All @@ -8247,7 +8253,7 @@
</member>
<member name="P:Microsoft.FluentUI.AspNetCore.Components.FluentSlider`1.Orientation">
<summary>
Gets or sets the orentation of the slider. See <see cref="T:Microsoft.FluentUI.AspNetCore.Components.Orientation"/>
Gets or sets the orientation of the slider. See <see cref="T:Microsoft.FluentUI.AspNetCore.Components.Orientation"/>
</summary>
</member>
<member name="P:Microsoft.FluentUI.AspNetCore.Components.FluentSlider`1.Mode">
Expand Down
111 changes: 107 additions & 4 deletions src/Core/Components/Slider/FluentSlider.razor.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,87 @@
// ------------------------------------------------------------------------
// MIT License - Copyright (c) Microsoft Corporation. All rights reserved.
// ------------------------------------------------------------------------

using System.Diagnostics.CodeAnalysis;
using System.Globalization;

using Microsoft.AspNetCore.Components;
using Microsoft.FluentUI.AspNetCore.Components.Extensions;
using Microsoft.FluentUI.AspNetCore.Components.Utilities;
using Microsoft.JSInterop;

namespace Microsoft.FluentUI.AspNetCore.Components;

public partial class FluentSlider<TValue> : FluentInputBase<TValue>
public partial class FluentSlider<TValue> : FluentInputBase<TValue>, IAsyncDisposable
where TValue : System.Numerics.INumber<TValue>
{
private const string JAVASCRIPT_FILE = "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/Slider/FluentSlider.razor.js";

/// <summary />
[Inject]
private IJSRuntime JSRuntime { get; set; } = default!;

/// <summary />
private IJSObjectReference? _jsModule { get; set; }

private TValue? max;
private TValue? min;
private bool updateSliderThumb = false;
private bool userChangedValue = false;

/// <summary>
/// Gets or sets the slider's minimal value.
/// </summary>
[Parameter, EditorRequired]
public TValue? Min { get; set; }
public TValue? Min
{
get => min;
set
{
if (min != value)
{
min = value;
updateSliderThumb = true;
}
}
}

/// <summary>
/// Gets or sets the slider's maximum value.
/// </summary>
[Parameter, EditorRequired]
public TValue? Max { get; set; }
public TValue? Max
{
get => max;
set
{
if (max != value)
{
max = value;
updateSliderThumb = true;
}
}
}

public override TValue? Value
{
get => base.Value;
set
{
if (base.Value != value)
{
base.Value = value;
if (userChangedValue)
{
userChangedValue = false;
}
else
{
updateSliderThumb = true;
}
}
}
}

/// <summary>
/// Gets or sets the slider's step value.
Expand All @@ -29,7 +90,7 @@ public partial class FluentSlider<TValue> : FluentInputBase<TValue>
public TValue? Step { get; set; }

/// <summary>
/// Gets or sets the orentation of the slider. See <see cref="AspNetCore.Components.Orientation"/>
/// Gets or sets the orientation of the slider. See <see cref="AspNetCore.Components.Orientation"/>
/// </summary>
[Parameter]
public Orientation? Orientation { get; set; }
Expand All @@ -46,6 +107,31 @@ public partial class FluentSlider<TValue> : FluentInputBase<TValue>
[Parameter]
public RenderFragment? ChildContent { get; set; }

protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
_jsModule ??= await JSRuntime.InvokeAsync<IJSObjectReference>("import", JAVASCRIPT_FILE);
}
else
{
if (updateSliderThumb)
{
updateSliderThumb = false;
if (_jsModule is not null)
{
await _jsModule!.InvokeVoidAsync("updateSlider", Element);
}
}
}
}

protected override Task ChangeHandlerAsync(ChangeEventArgs e)
{
userChangedValue = true;
return base.ChangeHandlerAsync(e);
}

protected override string? ClassValue
{
get
Expand Down Expand Up @@ -120,4 +206,21 @@ private static string GetStepAttributeValue()
throw new InvalidOperationException($"The type '{targetType}' is not a supported numeric type.");
}
}

public async ValueTask DisposeAsync()
{
try
{
if (_jsModule is not null)
{
await _jsModule.DisposeAsync();
}
}
catch (Exception ex) when (ex is JSDisconnectedException ||
ex is OperationCanceledException)
{
// The JSRuntime side may routinely be gone already if the reason we're disposing is that
// the client disconnected. This is not an error.
}
}
}

0 comments on commit e2fc112

Please sign in to comment.