Skip to content

Commit 0425a9a

Browse files
Merge pull request #175 from syncfusion/BottomSheetAnimationDuration
Provide animation duration support for Bottom sheet control
2 parents c9691b1 + 8f16e3c commit 0425a9a

File tree

2 files changed

+71
-4
lines changed

2 files changed

+71
-4
lines changed

maui/src/BottomSheet/SfBottomSheet.cs

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,19 @@ public partial class SfBottomSheet : SfView, IParentThemeElement
489489
BindingMode.Default
490490
);
491491

492+
/// <summary>
493+
/// Identifies the <see cref="AnimationDuration"/> bindable property.
494+
/// </summary>
495+
/// <value>
496+
/// The identifier for <see cref="AnimationDuration"/> bindable property.
497+
/// </value>
498+
public static readonly BindableProperty AnimationDurationProperty = BindableProperty.Create(
499+
nameof(AnimationDuration),
500+
typeof(double),
501+
typeof(SfBottomSheet),
502+
150d,
503+
BindingMode.Default);
504+
492505
#endregion
493506

494507
#region Internal Bindable Properties
@@ -1183,6 +1196,19 @@ public bool CollapseOnOverlayTap
11831196
set => SetValue(CollapseOnOverlayTapProperty, value);
11841197
}
11851198

1199+
/// <summary>
1200+
/// Gets or sets the duration, in milliseconds, for the opening and closing animations.
1201+
/// </summary>
1202+
/// <value>
1203+
/// It accepts double values, and the default value is 150ms.
1204+
/// </value>
1205+
1206+
public double AnimationDuration
1207+
{
1208+
get => (double)GetValue(AnimationDurationProperty);
1209+
set => SetValue(AnimationDurationProperty, value);
1210+
}
1211+
11861212
#endregion
11871213

11881214
#region Internal Properties
@@ -1256,6 +1282,17 @@ public void Close()
12561282
}
12571283
}
12581284

1285+
/// <summary>
1286+
/// Returns the value of <c>AnimationDuration</c>, ensuring it is clamped to a non-negative integer.
1287+
/// This method is useful when passing the duration to animation APIs that require a <c>uint</c> value,
1288+
/// preventing issues caused by negative durations.
1289+
/// </summary>
1290+
/// <returns>A non-negative integer representing the animation duration.</returns>
1291+
int GetClampedAnimationDuration()
1292+
{
1293+
return (int)Math.Max(0, AnimationDuration);
1294+
}
1295+
12591296
#endregion
12601297

12611298
#region Internal Methods
@@ -2093,13 +2130,13 @@ void AnimateBottomSheet(double targetPosition, Action? onFinish = null)
20932130
_overlayGrid.AbortAnimation("overlayGridAnimation");
20942131
}
20952132

2096-
const int animationDuration = 150;
2097-
const int topPadding = 2;
2133+
int animationDuration = this.GetClampedAnimationDuration();
2134+
const int topPadding = 2;
20982135
_isSheetOpen = true;
20992136
if (_bottomSheet is not null)
21002137
{
21012138
var bottomSheetAnimation = new Animation(d => _bottomSheet.TranslationY = d, _bottomSheet.TranslationY, targetPosition + topPadding);
2102-
_bottomSheet?.Animate("bottomSheetAnimation", bottomSheetAnimation, length: animationDuration, easing: Easing.Linear, finished: (v, e) =>
2139+
_bottomSheet?.Animate("bottomSheetAnimation", bottomSheetAnimation, length: (uint)animationDuration, easing: Easing.Linear, finished: (v, e) =>
21032140
{
21042141
UpdateBottomSheetHeight();
21052142
onFinish?.Invoke();
@@ -2133,7 +2170,15 @@ void AnimateOverlay(int animationDuration)
21332170
endValue = DefaultOverlayOpacity;
21342171
}
21352172

2136-
var overlayGridAnimation = new Animation(d => _overlayGrid.Opacity = d, startValue, endValue);
2173+
var overlayGridAnimation = new Animation(d =>
2174+
{
2175+
// Ensure the opacity is only updated with valid numeric values to avoid rendering issues.
2176+
if (!double.IsNaN(d))
2177+
{
2178+
_overlayGrid.Opacity = d;
2179+
}
2180+
}
2181+
, startValue, endValue);
21372182
_overlayGrid.Animate("overlayGridAnimation", overlayGridAnimation,
21382183
length: (uint)animationDuration,
21392184
easing: Easing.Linear,

maui/tests/Syncfusion.Maui.Toolkit.UnitTest/Navigation/SfBottomSheetUnitTests.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public void Constructor_InitializesDefaultsCorrectly()
3838
Assert.Equal(4d, _bottomSheet.GrabberHeight);
3939
Assert.Equal(32d, _bottomSheet.GrabberWidth);
4040
Assert.Equal(12d, _bottomSheet.GrabberCornerRadius);
41+
Assert.Equal(150d, _bottomSheet.AnimationDuration);
4142
if (_bottomSheet.GrabberBackground is SolidColorBrush grabberBrush)
4243
{
4344
var grabberColor = grabberBrush.Color;
@@ -475,6 +476,19 @@ public void CollapseOnOverlayTap(bool input, bool expected)
475476
Assert.Equal(expected, actual);
476477
}
477478

479+
[Theory]
480+
[InlineData(500d, 500d)]
481+
[InlineData(0d, 0d)]
482+
[InlineData(-500d, -500d)]
483+
public void AnimationDurationProperty_ReturnsSetValue(double input, double expected)
484+
{
485+
_bottomSheet.AnimationDuration = input;
486+
487+
var actual = _bottomSheet.AnimationDuration;
488+
489+
Assert.Equal(expected, actual);
490+
}
491+
478492
#endregion
479493

480494
#region Internal Properties
@@ -733,6 +747,14 @@ public void UpdateGrabberHeightProperty(double input, double expected)
733747
Assert.Equal(expected, actual);
734748
}
735749

750+
[Fact]
751+
public void GetClampedAnimationDuration()
752+
{
753+
_bottomSheet.AnimationDuration = -500;
754+
var actual = InvokePrivateMethod(_bottomSheet, "GetClampedAnimationDuration");
755+
Assert.Equal(0, actual);
756+
}
757+
736758
[Theory]
737759
[InlineData(48, 48)]
738760
[InlineData(0, 32)]

0 commit comments

Comments
 (0)