diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/NavPanel/BitNavPanel.razor b/src/BlazorUI/Bit.BlazorUI.Extras/Components/NavPanel/BitNavPanel.razor index 7476e5a453..ab7b28e35f 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/NavPanel/BitNavPanel.razor +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/NavPanel/BitNavPanel.razor @@ -21,7 +21,8 @@ Throttle="10" OnMove="HandleOnSwipeMove" OnEnd="HandleOnSwipeEnd" - OnTrigger="HandleOnSwipeTrigger"> + OnTrigger="HandleOnSwipeTrigger" + OrientationLock="BitSwipeOrientation.Horizontal">
@if (Header is not null) { diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/NavPanel/BitNavPanel.razor.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/NavPanel/BitNavPanel.razor.cs index f5557f64d2..0b2e4b1c9e 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/NavPanel/BitNavPanel.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/NavPanel/BitNavPanel.razor.cs @@ -194,22 +194,12 @@ private void SearchNavItems(string? searchText) _filteredNavItems = [.. mainItems, .. subItems]; } - private decimal _oldDiffY = 0; private void HandleOnSwipeMove(BitSwipeTrapEventArgs args) { if (IsOpen is false) return; - if (Math.Abs(args.DiffX) > Math.Abs(args.DiffY)) - { - diffXPanel = args.DiffX; - StateHasChanged(); - } - else - { - var diff = args.DiffY - _oldDiffY; - _js.BitExtrasScrollBy(RootElement, 0, diff > 0 ? -20 : 20); - _oldDiffY = args.DiffY; - } + diffXPanel = args.DiffX; + StateHasChanged(); } private void HandleOnSwipeEnd(BitSwipeTrapEventArgs args) diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Utilities/SwipeTrap/BitSwipeOrientation.cs b/src/BlazorUI/Bit.BlazorUI/Components/Utilities/SwipeTrap/BitSwipeOrientation.cs new file mode 100644 index 0000000000..ea943af7c7 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI/Components/Utilities/SwipeTrap/BitSwipeOrientation.cs @@ -0,0 +1,22 @@ +namespace Bit.BlazorUI; + +/// +/// The lock orientation of the swipe trap component. +/// +public enum BitSwipeOrientation +{ + /// + /// Not orientation lock for swipe trap. + /// + None, + + /// + /// Horizontal orientation lock of trapping the swipe action. + /// + Horizontal, + + /// + /// Vertical orientation lock of trapping the swipe action. + /// + Vertical +} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Utilities/SwipeTrap/BitSwipeTrap.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Utilities/SwipeTrap/BitSwipeTrap.razor.cs index 07acee846f..bfb022e9ba 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Utilities/SwipeTrap/BitSwipeTrap.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Utilities/SwipeTrap/BitSwipeTrap.razor.cs @@ -40,6 +40,11 @@ public partial class BitSwipeTrap : BitComponentBase, IAsyncDisposable /// [Parameter] public EventCallback OnTrigger { get; set; } + /// + /// Specifies the orientation lock in which the swipe trap allows to trap the swipe actions. + /// + [Parameter] public BitSwipeOrientation? OrientationLock { get; set; } + /// /// The threshold in pixel for swiping distance that starts the swipe process process which stops the default behavior. /// @@ -96,7 +101,14 @@ protected override async Task OnAfterRenderAsync(bool firstRender) if (firstRender) { var dotnetObj = DotNetObjectReference.Create(this); - await _js.BitSwipeTrapSetup(UniqueId, RootElement, Trigger ?? 0.25m, Threshold ?? 0, Throttle ?? 0, dotnetObj); + await _js.BitSwipeTrapSetup( + UniqueId, + RootElement, + Trigger ?? 0.25m, + Threshold ?? 0, + Throttle ?? 0, + OrientationLock ?? BitSwipeOrientation.None, + dotnetObj); } await base.OnAfterRenderAsync(firstRender); diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Utilities/SwipeTrap/BitSwipeTrap.ts b/src/BlazorUI/Bit.BlazorUI/Components/Utilities/SwipeTrap/BitSwipeTrap.ts index 730126d793..c31cf9848f 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Utilities/SwipeTrap/BitSwipeTrap.ts +++ b/src/BlazorUI/Bit.BlazorUI/Components/Utilities/SwipeTrap/BitSwipeTrap.ts @@ -8,6 +8,7 @@ trigger: number, threshold: number, throttle: number, + orientationLock: BitSwipeOrientation, dotnetObj: DotNetObject) { const bcr = element.getBoundingClientRect(); @@ -15,6 +16,7 @@ let diffY = 0; let startX = -1; let startY = -1; + let orientation = BitSwipeOrientation.None; const isTouchDevice = Utils.isTouchDevice(); const throttledMove = Utils.throttle((sx: number, sy: number, dx: number, dy: number) => dotnetObj.invokeMethodAsync('OnMove', sx, sy, dx, dy), throttle); @@ -34,12 +36,46 @@ diffX = getX(e) - startX; diffY = getY(e) - startY; - if ((Math.abs(diffX) > threshold || Math.abs(diffY) > threshold) && e.cancelable) { - e.preventDefault(); - e.stopPropagation(); + const absX = Math.abs(diffX); + const absY = Math.abs(diffY); + const thresX = absX > threshold; + const thresY = absY > threshold; + + + if (orientation === BitSwipeOrientation.None) { + if (thresX && !thresY) { + orientation = BitSwipeOrientation.Horizontal; + } else if (!thresX && thresY) { + orientation = BitSwipeOrientation.Vertical; + } + } + + if (orientationLock === BitSwipeOrientation.Horizontal) { + if (orientation === BitSwipeOrientation.Horizontal) { + cancel(); + diffY = 0; + } else { + diffX = 0; + } + } else if (orientationLock === BitSwipeOrientation.Vertical) { + if (orientation === BitSwipeOrientation.Vertical && absY > threshold) { + cancel(); + diffX = 0; + } else { + diffY = 0; + } + } else if ((thresX || thresY)) { + cancel(); } throttledMove(startX, startY, diffX, diffY); + + function cancel() { + if (e.cancelable) { + e.preventDefault(); + e.stopPropagation(); + } + } }; const onEnd = async (e: TouchEvent | PointerEvent): Promise => { @@ -59,6 +95,7 @@ } finally { await dotnetObj.invokeMethodAsync('OnEnd', sX, sY, diffX, diffY); diffX = diffY = 0; + orientation = BitSwipeOrientation.None; } }; @@ -67,6 +104,7 @@ dotnetObj.invokeMethodAsync('OnEnd', startX, startY, diffX, diffY); startX = startY = -1; diffX = diffY = 0; + orientation = BitSwipeOrientation.None; } if (isTouchDevice) { @@ -130,4 +168,11 @@ this.dotnetObj.dispose(); } } + + enum BitSwipeOrientation { + None, + Horizontal, + Vertical + } + } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Utilities/SwipeTrap/BitSwipeTrapJsRuntimeExtensions.cs b/src/BlazorUI/Bit.BlazorUI/Components/Utilities/SwipeTrap/BitSwipeTrapJsRuntimeExtensions.cs index 270c1b512d..486c293aeb 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Utilities/SwipeTrap/BitSwipeTrapJsRuntimeExtensions.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Utilities/SwipeTrap/BitSwipeTrapJsRuntimeExtensions.cs @@ -8,9 +8,10 @@ internal static ValueTask BitSwipeTrapSetup(this IJSRuntime js, decimal trigger, decimal threshold, int throttle, + BitSwipeOrientation orientationLock, DotNetObjectReference? dotnetObjectReference) { - return js.InvokeVoid("BitBlazorUI.SwipeTrap.setup", id, element, trigger, threshold, throttle, dotnetObjectReference); + return js.InvokeVoid("BitBlazorUI.SwipeTrap.setup", id, element, trigger, threshold, throttle, orientationLock, dotnetObjectReference); } internal static ValueTask BitSwipeTrapDispose(this IJSRuntime jsRuntime, string id) diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/SwipeTrap/BitSwipeTrapDemo.razor b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/SwipeTrap/BitSwipeTrapDemo.razor index 12c131a22b..bcb1400491 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/SwipeTrap/BitSwipeTrapDemo.razor +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/SwipeTrap/BitSwipeTrapDemo.razor @@ -98,40 +98,36 @@
- -
- - - - - bit BlazorUI - - - -
-
+
+
+ + + bit BlazorUI + +
+
- +
Swipe left or right - +
-
-
+
+

Left Menu

Item1
Item2
Item3
-
-
+
+

Right Menu

Item1
Item2
@@ -139,8 +135,8 @@
-
-
+
+
diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/SwipeTrap/BitSwipeTrapDemo.razor.cs b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/SwipeTrap/BitSwipeTrapDemo.razor.cs index 7295603970..db909f0dd8 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/SwipeTrap/BitSwipeTrapDemo.razor.cs +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/SwipeTrap/BitSwipeTrapDemo.razor.cs @@ -48,6 +48,15 @@ public partial class BitSwipeTrapDemo Href = "#swipetrap-trigger-args", }, new() + { + Name = "OrientationLock", + Type = "BitSwipeOrientation?", + DefaultValue = "null", + Description = "Specifies the orientation lock in which the swipe trap allows to trap the swipe actions.", + LinkType = LinkType.Link, + Href = "#swipe-orientation", + }, + new() { Name = "Threshold", Type = "decimal?", @@ -146,6 +155,33 @@ public partial class BitSwipeTrapDemo private readonly List componentSubEnums = [ + new() + { + Id = "swipe-orientation", + Name = "BitSwipeOrientation", + Description = "The lock orientation of the swipe trap component.", + Items = + [ + new() + { + Name = "None", + Value = "0", + Description = "Not orientation lock for swipe trap." + }, + new() + { + Name = "Horizontal", + Value = "1", + Description = "Horizontal orientation lock of trapping the swipe action." + }, + new() + { + Name = "Vertical", + Value = "2", + Description = "Vertical orientation lock of trapping the swipe action." + }, + ] + }, new() { Id = "swipe-direction-enum", diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/SwipeTrap/BitSwipeTrapDemo.razor.samples.cs b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/SwipeTrap/BitSwipeTrapDemo.razor.samples.cs index 68af948649..0579ba20d4 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/SwipeTrap/BitSwipeTrapDemo.razor.samples.cs +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/SwipeTrap/BitSwipeTrapDemo.razor.samples.cs @@ -276,14 +276,14 @@ private void ResetList() private readonly string example4RazorCode = @"