Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Carousel updates #437

Merged
merged 4 commits into from
Mar 10, 2021
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
184 changes: 110 additions & 74 deletions src/BlazorStrap/Components/Carousel/BSCarousel.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,26 @@ public partial class BSCarousel : ComponentBase, IDisposable
private const string _carouselFade = "carousel-fade";

private int _activeIndex { get; set; }

private int _prevIndex { get; set; }
public int ActiveIndex
{
get => _activeIndex;
set { _activeIndex = value; ActiveIndexChanged?.Invoke(); DoAnimations(); }
set {
_prevIndex = _activeIndex;
_activeIndex = value;
}
}

private bool _timerEnabled { get; set; } = true;
public bool AnimationRunning { get; set; } = false;
public List<BSCarouselIndicatorItem> CarouselIndicatorItems { get; } = new List<BSCarouselIndicatorItem>();
public List<BSCarouselItem> CarouselItems { get; } = new List<BSCarouselItem>();
public List<BSCarouselIndicatorItem> CarouselIndicatorItems { get; set; }
public List<BSCarouselItem> CarouselItems { get; set; }
[Parameter] public RenderFragment ChildContent { get; set; }
[Parameter] public string Class { get; set; }
[Parameter] public bool Fade { get; set; } = false;
[Parameter] public int Interval { get; set; } = 5000;
[Parameter] public bool Keyboard { get; set; } = true;

[Parameter]
public int NumberOfItems
{
get => _numberOfItems;
set
{
if (_lastNumberItems != _numberOfItems)
{
CarouselItems.Clear();
}
_numberOfItems = value;
}
}

[Parameter] public int NumberOfItems { get; set; }
[Parameter] public EventCallback OnSlide { get; set; }

[Parameter]
Expand All @@ -68,7 +57,7 @@ public string Pause
[Parameter] public bool Touch { get; set; } = true;
[Parameter(CaptureUnmatchedValues = true)] public IDictionary<string, object> UnknownParameters { get; set; }
[Parameter] public bool Wrap { get; set; } = true;
internal Func<Task> ActiveIndexChanged { get; set; }
[Parameter] public EventCallback<int> ActiveIndexChangedEvent { get; set; }
internal int Direction { get; set; }

protected string Classname => new CssBuilder("carousel slide")
Expand All @@ -79,7 +68,6 @@ public string Pause
private int _numberOfItems { get; set; }
private string _pause { get; set; } = "hover";
[Inject] protected Microsoft.JSInterop.IJSRuntime JSRuntime { get; set; }
private int _lastNumberItems { get; set; } = 0;

public void Dispose()
{
Expand All @@ -101,7 +89,7 @@ protected virtual void Dispose(bool disposing)

public async Task Refresh()
{
await InvokeAsync(StateHasChanged).ConfigureAwait(false);
await InvokeAsync(StateHasChanged).ConfigureAwait(true);
}

public void ResetTimer()
Expand Down Expand Up @@ -139,77 +127,56 @@ private async Task DoAnimations()
Timer.Stop();
Timer.Interval = CarouselItems[ActiveIndex].Interval;
}
if (Direction == 0)
{
var oldindex = ActiveIndex == 0 ? NumberOfItems - 1 : ActiveIndex - 1;
new Task(async () =>
{
AnimationRunning = true;
await CarouselItems[ActiveIndex].Clean().ConfigureAwait(false);
CarouselItems[ActiveIndex].Next = true;
await CarouselItems[ActiveIndex].StateChanged().ConfigureAwait(false);
await Task.Delay(300).ConfigureAwait(false); // Gives animation time to shift and be ready to slide.
CarouselItems[ActiveIndex].Left = true;
CarouselItems[oldindex].Left = true;
await CarouselItems[ActiveIndex].StateChanged().ConfigureAwait(false); // makes sure there is no gap
await InvokeAsync(StateHasChanged).ConfigureAwait(false);
}).Start();
}
else if (Direction == 1)
{
var oldindex = (ActiveIndex == NumberOfItems - 1) ? 0 : ActiveIndex + 1;
new Task(async () =>
{
AnimationRunning = true;
await CarouselItems[ActiveIndex].Clean().ConfigureAwait(false);
CarouselItems[ActiveIndex].Prev = true;
await CarouselItems[ActiveIndex].StateChanged().ConfigureAwait(false);
await Task.Delay(300).ConfigureAwait(false); // Gives animation time to shift and be ready to slide.
CarouselItems[ActiveIndex].Right = true;
CarouselItems[oldindex].Right = true;
await CarouselItems[ActiveIndex].StateChanged().ConfigureAwait(false); // makes sure there is no gap
await InvokeAsync(StateHasChanged).ConfigureAwait(false);
}).Start();
}

AnimationRunning = true;
CarouselItems[ActiveIndex].Clean();

Direction = GetDirection();

//Add new item to DOM on appropriate side
CarouselItems[ActiveIndex].Next = Direction == 0;
CarouselItems[ActiveIndex].Prev = Direction == 1;
this.StateHasChanged();
await Task.Delay(300).ConfigureAwait(true); //Ensure new item is rendered on DOM before continuing

//Trigger Animation
CarouselItems[ActiveIndex].Left = Direction == 0;
CarouselItems[_prevIndex].Left = Direction == 0;

CarouselItems[ActiveIndex].Right = Direction == 1;
CarouselItems[_prevIndex].Right = Direction == 1;
this.StateHasChanged();

}

public async Task AnimationEnd(BSCarouselItem sender)
{
if (sender == CarouselItems[ActiveIndex])
{
AnimationRunning = false;
int oldindex = -1;
if (Direction == 0)
oldindex = ActiveIndex == 0 ? NumberOfItems - 1 : ActiveIndex - 1;
else if (Direction == 1)
oldindex = (ActiveIndex == NumberOfItems - 1) ? 0 : ActiveIndex + 1;

await CarouselItems[oldindex].Clean().ConfigureAwait(false);
await CarouselItems[oldindex].StateChanged().ConfigureAwait(false);
await CarouselItems[ActiveIndex].Clean().ConfigureAwait(false);

CarouselItems[_prevIndex].Clean();
CarouselItems[ActiveIndex].Clean();
CarouselItems[ActiveIndex].Active = true;
await InvokeAsync(StateHasChanged).ConfigureAwait(false);
this.StateHasChanged();

if (_timerEnabled)
Timer.Start();

await ActiveIndexChangedEvent.InvokeAsync(ActiveIndex).ConfigureAwait(false);
}
}

protected async Task OnKeyPress(KeyboardEventArgs e)
{
if (!Keyboard) return;
if (e?.Code == "37")
{
if (ActiveIndex - 1 < 0)
ActiveIndex = NumberOfItems - 1;
else
ActiveIndex--;
await GoToPrevItem().ConfigureAwait(true);
}
else if (e?.Code == "39")
{
if (ActiveIndex == NumberOfItems - 1)
ActiveIndex = 0;
else
ActiveIndex++;
await GoToNextItem().ConfigureAwait(true);
}
}

Expand All @@ -225,6 +192,17 @@ protected void OnMouseLeave()

protected override void OnParametersSet()
{

if (CarouselItems == null)
{
CarouselItems = new List<BSCarouselItem>();
}

if (CarouselIndicatorItems == null)
{
CarouselIndicatorItems = new List<BSCarouselIndicatorItem>();
}

if (Interval != 0)
_timerEnabled = true;

Expand All @@ -234,6 +212,30 @@ protected override void OnParametersSet()
Timer.Start();
}
}

public async Task GoToSpecificItem(int index)
{
if (AnimationRunning) return;
ResetTimer();
ActiveIndex = index;
await DoAnimations().ConfigureAwait(true);
}

public async Task GoToNextItem()
{
if (AnimationRunning) return;
ResetTimer();
ActiveIndex = ActiveIndex == NumberOfItems - 1 ? 0 : ActiveIndex + 1;
await DoAnimations().ConfigureAwait(true);
}

public async Task GoToPrevItem()
{
if (AnimationRunning) return;
ResetTimer();
ActiveIndex = ActiveIndex == 0 ? NumberOfItems - 1 : ActiveIndex - 1;
await DoAnimations().ConfigureAwait(true);
}

private async void OnTimerEvent(object source, ElapsedEventArgs e)
{
Expand All @@ -245,8 +247,42 @@ private async void OnTimerEvent(object source, ElapsedEventArgs e)
}

ActiveIndex = ActiveIndex == NumberOfItems - 1 ? 0 : ActiveIndex + 1;
Direction = 0;
await OnSlide.InvokeAsync(null).ConfigureAwait(false);
await InvokeAsync(DoAnimations).ConfigureAwait(true);
await OnSlide.InvokeAsync(null).ConfigureAwait(true);
}

private int GetDirection()
{
if (_prevIndex == 0)
{
if (ActiveIndex == NumberOfItems - 1)
{
return 1;
} else
{
return 0;
}
}

if (_prevIndex == NumberOfItems - 1)
{
if (ActiveIndex == 0)
{
return 0;
} else
{
return 1;
}
}

if (ActiveIndex > _prevIndex)
{
return 0;
} else
{
return 1;
}
}

}
}
12 changes: 3 additions & 9 deletions src/BlazorStrap/Components/Carousel/BSCarouselControl.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,23 @@ public partial class BSCarouselControl : ComponentBase

protected string DirectionName => CarouselDirection == CarouselDirection.Previous ? "Previous" : "Next";

[Parameter] public int NumberOfItems { get; set; }
[Parameter] public CarouselDirection CarouselDirection { get; set; } = CarouselDirection.Previous;
[Parameter] public string Class { get; set; }
[CascadingParameter] internal BSCarousel Parent { get; set; }

[Parameter] public EventCallback<int> ActiveIndexChanged { get; set; }

protected async Task OnClick()
{
if (Parent.AnimationRunning) return;
if (CarouselDirection == CarouselDirection.Previous)
{
Parent.Direction = 1;
Parent.ResetTimer();
Parent.ActiveIndex = Parent.ActiveIndex == 0 ? NumberOfItems - 1 : Parent.ActiveIndex - 1;
await Parent.GoToPrevItem().ConfigureAwait(true);
}
else
{
Parent.Direction = 0;
Parent.ResetTimer();
Parent.ActiveIndex = Parent.ActiveIndex == NumberOfItems - 1 ? 0 : Parent.ActiveIndex + 1;
await Parent.GoToNextItem().ConfigureAwait(true);
}
await ActiveIndexChanged.InvokeAsync(Parent.ActiveIndex).ConfigureAwait(false);
await ActiveIndexChanged.InvokeAsync(Parent.ActiveIndex).ConfigureAwait(true);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ protected override void OnInitialized()

protected async Task OnClick()
{
await ActiveIndexChangedEvent.InvokeAsync(Index).ConfigureAwait(false);
await Parent.GoToSpecificItem(Index).ConfigureAwait(true);
await ActiveIndexChangedEvent.InvokeAsync(Index).ConfigureAwait(true);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@namespace BlazorStrap

<DynamicElement @attributes="@UnknownParameters" TagName="ol" class="@Classname">
@for (var i = 0; i < NumberOfItems; i++)
@for (var i = 0; i < _numberOfItems; i++)
{
<BSCarouselIndicatorItem IsActive="@(i == ActiveIndex)" Index="@i" ActiveIndexChangedEvent="@ClickEventActiveIndex" />
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,19 @@ namespace BlazorStrap
public partial class BSCarouselIndicators : ComponentBase
{
[Parameter(CaptureUnmatchedValues = true)] public IDictionary<string, object> UnknownParameters { get; set; }
[CascadingParameter] protected BSCarousel Parent { get; set; }

protected string Classname =>
new CssBuilder("carousel-indicators")
.AddClass(Class)
.Build();

[Parameter] public int NumberOfItems { get; set; }
[Parameter] public int ActiveIndex { get; set; }
[Parameter] public string Class { get; set; }
[Parameter] public RenderFragment ChildContent { get; set; }
[Parameter] public EventCallback<int> ActiveIndexChanged { get; set; }
[Parameter] public EventCallback<int> ActiveIndexChangedEvent { get; set; }
private int _numberOfItems { get => Parent.NumberOfItems; }

protected void ClickEventActiveIndex(int index)
{
Expand Down
16 changes: 7 additions & 9 deletions src/BlazorStrap/Components/Carousel/BSCarouselItem.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ public partial class BSCarouselItem : ComponentBase
[Parameter] public string ActionLinkTarget { get; set; } = "_self";
[Parameter] public RenderFragment ChildContent { get; set; }

protected override void OnInitialized()
protected override Task OnParametersSetAsync()
{
SetSvg();
Parent.CarouselItems.Add(this);
return base.OnParametersSetAsync();
}

public async Task StateChanged()
protected override void OnInitialized()
{
await InvokeAsync(StateHasChanged).ConfigureAwait(false);
SetSvg();
Parent.CarouselItems.Add(this);
}

public Task AnimationEnd()
Expand All @@ -65,19 +65,17 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
if(Parent.CarouselItems[0] == this)
{
Active = true;
await InvokeAsync(StateHasChanged).ConfigureAwait(false);
await InvokeAsync(StateHasChanged).ConfigureAwait(true);
}
}
}
public Task Clean()
public void Clean()
{
Active = false;
Left = false;
Right = false;
Prev = false;
Next = false;

return Task.CompletedTask;
}

private void SetSvg()
Expand Down
Loading