Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
}
}
}