1+ // ------------------------------------------------------------------------
2+ // MIT License - Copyright (c) Microsoft Corporation. All rights reserved.
3+ // ------------------------------------------------------------------------
4+
15using System . Diagnostics . CodeAnalysis ;
26using System . Globalization ;
37
48using Microsoft . AspNetCore . Components ;
59using Microsoft . FluentUI . AspNetCore . Components . Extensions ;
610using Microsoft . FluentUI . AspNetCore . Components . Utilities ;
11+ using Microsoft . JSInterop ;
712
813namespace Microsoft . FluentUI . AspNetCore . Components ;
914
10- public partial class FluentSlider < TValue > : FluentInputBase < TValue >
15+ public partial class FluentSlider < TValue > : FluentInputBase < TValue > , IAsyncDisposable
1116 where TValue : System . Numerics . INumber < TValue >
1217{
18+ private const string JAVASCRIPT_FILE = "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/Slider/FluentSlider.razor.js" ;
19+
20+ /// <summary />
21+ [ Inject ]
22+ private IJSRuntime JSRuntime { get ; set ; } = default ! ;
23+
24+ /// <summary />
25+ private IJSObjectReference ? _jsModule { get ; set ; }
26+
27+ private TValue ? max ;
28+ private TValue ? min ;
29+ private bool updateSliderThumb = false ;
30+ private bool userChangedValue = false ;
31+
1332 /// <summary>
1433 /// Gets or sets the slider's minimal value.
1534 /// </summary>
1635 [ Parameter , EditorRequired ]
17- public TValue ? Min { get ; set ; }
36+ public TValue ? Min
37+ {
38+ get => min ;
39+ set
40+ {
41+ if ( min != value )
42+ {
43+ min = value ;
44+ updateSliderThumb = true ;
45+ }
46+ }
47+ }
1848
1949 /// <summary>
2050 /// Gets or sets the slider's maximum value.
2151 /// </summary>
2252 [ Parameter , EditorRequired ]
23- public TValue ? Max { get ; set ; }
53+ public TValue ? Max
54+ {
55+ get => max ;
56+ set
57+ {
58+ if ( max != value )
59+ {
60+ max = value ;
61+ updateSliderThumb = true ;
62+ }
63+ }
64+ }
65+
66+ public override TValue ? Value
67+ {
68+ get => base . Value ;
69+ set
70+ {
71+ if ( base . Value != value )
72+ {
73+ base . Value = value ;
74+ if ( userChangedValue )
75+ {
76+ userChangedValue = false ;
77+ }
78+ else
79+ {
80+ updateSliderThumb = true ;
81+ }
82+ }
83+ }
84+ }
2485
2586 /// <summary>
2687 /// Gets or sets the slider's step value.
@@ -29,7 +90,7 @@ public partial class FluentSlider<TValue> : FluentInputBase<TValue>
2990 public TValue ? Step { get ; set ; }
3091
3192 /// <summary>
32- /// Gets or sets the orentation of the slider. See <see cref="AspNetCore.Components.Orientation"/>
93+ /// Gets or sets the orientation of the slider. See <see cref="AspNetCore.Components.Orientation"/>
3394 /// </summary>
3495 [ Parameter ]
3596 public Orientation ? Orientation { get ; set ; }
@@ -46,6 +107,31 @@ public partial class FluentSlider<TValue> : FluentInputBase<TValue>
46107 [ Parameter ]
47108 public RenderFragment ? ChildContent { get ; set ; }
48109
110+ protected override async Task OnAfterRenderAsync ( bool firstRender )
111+ {
112+ if ( firstRender )
113+ {
114+ _jsModule ??= await JSRuntime . InvokeAsync < IJSObjectReference > ( "import" , JAVASCRIPT_FILE ) ;
115+ }
116+ else
117+ {
118+ if ( updateSliderThumb )
119+ {
120+ updateSliderThumb = false ;
121+ if ( _jsModule is not null )
122+ {
123+ await _jsModule ! . InvokeVoidAsync ( "updateSlider" , Element ) ;
124+ }
125+ }
126+ }
127+ }
128+
129+ protected override Task ChangeHandlerAsync ( ChangeEventArgs e )
130+ {
131+ userChangedValue = true ;
132+ return base . ChangeHandlerAsync ( e ) ;
133+ }
134+
49135 protected override string ? ClassValue
50136 {
51137 get
@@ -120,4 +206,21 @@ private static string GetStepAttributeValue()
120206 throw new InvalidOperationException ( $ "The type '{ targetType } ' is not a supported numeric type.") ;
121207 }
122208 }
209+
210+ public async ValueTask DisposeAsync ( )
211+ {
212+ try
213+ {
214+ if ( _jsModule is not null )
215+ {
216+ await _jsModule . DisposeAsync ( ) ;
217+ }
218+ }
219+ catch ( Exception ex ) when ( ex is JSDisconnectedException ||
220+ ex is OperationCanceledException )
221+ {
222+ // The JSRuntime side may routinely be gone already if the reason we're disposing is that
223+ // the client disconnected. This is not an error.
224+ }
225+ }
123226}
0 commit comments