-
-
Notifications
You must be signed in to change notification settings - Fork 232
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
Showing
27 changed files
with
695 additions
and
112 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
src/BlazorUI/Bit.BlazorUI.Extras/Components/ModalService/BitModalContainer.razor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
@namespace Bit.BlazorUI | ||
|
||
@foreach (var modalReference in _modalRefs) | ||
{ | ||
<CascadingValue Value="modalReference"> | ||
<CascadingValue Value="BitModalParameters.Merge(modalReference.Parameters, ModalParameters)"> | ||
@modalReference.Modal | ||
</CascadingValue> | ||
</CascadingValue> | ||
} |
63 changes: 63 additions & 0 deletions
63
src/BlazorUI/Bit.BlazorUI.Extras/Components/ModalService/BitModalContainer.razor.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
using System.Collections.Concurrent; | ||
using System.Threading.Tasks; | ||
|
||
namespace Bit.BlazorUI; | ||
|
||
public partial class BitModalContainer : IDisposable | ||
{ | ||
private readonly List<BitModalReference> _modalRefs = []; | ||
|
||
|
||
|
||
[Parameter] public BitModalParameters ModalParameters { get; set; } = new(); | ||
|
||
|
||
|
||
[Inject] private BitModalService _modalService { get; set; } = default!; | ||
|
||
|
||
|
||
internal void InjectPersistentModals(ConcurrentQueue<BitModalReference> queue) | ||
{ | ||
while (queue.TryDequeue(out var modalRef)) | ||
{ | ||
_modalRefs.Add(modalRef); | ||
} | ||
} | ||
|
||
|
||
|
||
protected override void OnInitialized() | ||
{ | ||
base.OnInitialized(); | ||
|
||
_modalService.InitContainer(this); | ||
|
||
_modalService.OnAddModal += OnModalAdd; | ||
_modalService.OnCloseModal += OnCloseModal; | ||
} | ||
|
||
|
||
|
||
private Task OnModalAdd(BitModalReference modalRef) | ||
{ | ||
if (_modalRefs.Contains(modalRef)) return Task.CompletedTask; | ||
|
||
_modalRefs.Add(modalRef); | ||
return InvokeAsync(StateHasChanged); | ||
} | ||
|
||
private Task OnCloseModal(BitModalReference modalRef) | ||
{ | ||
_modalRefs.Remove(modalRef); | ||
return InvokeAsync(StateHasChanged); | ||
} | ||
|
||
|
||
|
||
public void Dispose() | ||
{ | ||
_modalService.OnAddModal -= OnModalAdd; | ||
_modalService.OnCloseModal -= OnCloseModal; | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
src/BlazorUI/Bit.BlazorUI.Extras/Components/ModalService/BitModalReference.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
namespace Bit.BlazorUI; | ||
|
||
public class BitModalReference | ||
{ | ||
private readonly BitModalService _modalService; | ||
|
||
|
||
|
||
public string Id { get; init; } | ||
|
||
public bool Persistent { get; private set; } | ||
|
||
public object? Content { get; private set; } | ||
|
||
public RenderFragment? Modal { get; private set; } | ||
|
||
public BitModalParameters? Parameters { get; private set; } | ||
|
||
|
||
|
||
|
||
public BitModalReference(BitModalService modalService, bool persistent) | ||
{ | ||
Id = BitShortId.NewId(); | ||
_modalService = modalService; | ||
Persistent = persistent; | ||
} | ||
|
||
|
||
|
||
public void SetContent(object content) | ||
{ | ||
Content = content; | ||
} | ||
|
||
public void SetModal(RenderFragment modal) | ||
{ | ||
Modal = modal; | ||
} | ||
|
||
public void SetParameters(BitModalParameters? parameters) | ||
{ | ||
Parameters = parameters; | ||
} | ||
|
||
public void Close() | ||
{ | ||
_modalService.Close(this); | ||
} | ||
} |
150 changes: 150 additions & 0 deletions
150
src/BlazorUI/Bit.BlazorUI.Extras/Components/ModalService/BitModalService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
using System.Collections.Concurrent; | ||
using System.Diagnostics.CodeAnalysis; | ||
|
||
namespace Bit.BlazorUI; | ||
|
||
public class BitModalService | ||
{ | ||
private BitModalContainer? _container; | ||
private readonly ConcurrentQueue<BitModalReference> _persistentModalsQueue = new(); | ||
|
||
|
||
|
||
/// <summary> | ||
/// The event for when a new modal gets added through calling the Show method. | ||
/// </summary> | ||
public event Func<BitModalReference, Task>? OnAddModal; | ||
|
||
/// <summary> | ||
/// The event for when a modal gets removed through calling the Close method. | ||
/// </summary> | ||
public event Func<BitModalReference, Task>? OnCloseModal; | ||
|
||
|
||
|
||
/// <summary> | ||
/// Initializes the current modal container that is responsible for rendering the modals. | ||
/// </summary> | ||
public void InitContainer(BitModalContainer container) | ||
{ | ||
_container = container; | ||
_container.InjectPersistentModals(_persistentModalsQueue); | ||
} | ||
|
||
/// <summary> | ||
/// Closes an already opened modal using its reference. | ||
/// </summary> | ||
public async Task Close(BitModalReference modalRef) | ||
{ | ||
var modalClose = OnCloseModal; | ||
if (modalClose is not null) | ||
{ | ||
await modalClose(modalRef); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Shows a new persistent BitModal that will persist through the lifecycle of the application until it gets shown. | ||
/// </summary> | ||
public Task<BitModalReference> Show<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>( | ||
bool persistent = false) | ||
{ | ||
return Show<T>(null, null, persistent); | ||
} | ||
|
||
/// <summary> | ||
/// Shows a new BitModal with a custom component with parameters as its content. | ||
/// </summary> | ||
public Task<BitModalReference> Show<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>( | ||
Dictionary<string, object>? parameters, bool persistent = false) | ||
{ | ||
return Show<T>(parameters, null, persistent); | ||
} | ||
|
||
/// <summary> | ||
/// Shows a new BitModal with a custom component with parameters as its content. | ||
/// </summary> | ||
public Task<BitModalReference> Show<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>( | ||
Dictionary<string, object> parameters) | ||
{ | ||
return Show<T>(parameters, null, false); | ||
} | ||
|
||
/// <summary> | ||
/// Shows a new BitModal with a custom component as its content with custom parameters for the modal. | ||
/// </summary> | ||
public Task<BitModalReference> Show<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>( | ||
BitModalParameters modalParameters) | ||
{ | ||
return Show<T>(null, modalParameters, false); | ||
} | ||
|
||
/// <summary> | ||
/// Shows a new BitModal with a custom component as its content with custom parameters for the modal. | ||
/// </summary> | ||
public Task<BitModalReference> Show<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>( | ||
BitModalParameters? modalParameters, bool persistent = false) | ||
{ | ||
return Show<T>(null, modalParameters, persistent); | ||
} | ||
|
||
/// <summary> | ||
/// Shows a new BitModal with a custom component as its content with custom parameters for the custom component and the modal. | ||
/// </summary> | ||
public async Task<BitModalReference> Show<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>( | ||
Dictionary<string, object>? parameters, | ||
BitModalParameters? modalParameters, | ||
bool persistent = false) | ||
{ | ||
var componentType = typeof(T); | ||
|
||
if (typeof(IComponent).IsAssignableFrom(componentType) is false) | ||
{ | ||
throw new ArgumentException($"Type {componentType.Name} must be a Blazor component"); | ||
} | ||
|
||
var modalReference = new BitModalReference(this, persistent); | ||
modalReference.SetParameters(modalParameters); | ||
|
||
var content = new RenderFragment(builder => | ||
{ | ||
var i = 0; | ||
builder.OpenComponent(i++, componentType); | ||
|
||
if (parameters is not null) | ||
{ | ||
foreach (var parameter in parameters) | ||
{ | ||
builder.AddAttribute(i++, parameter.Key, parameter.Value); | ||
} | ||
} | ||
|
||
builder.AddComponentReferenceCapture(i, c => { modalReference.SetContent((T)c); }); | ||
builder.CloseComponent(); | ||
}); | ||
|
||
var modal = new RenderFragment(builder => | ||
{ | ||
builder.OpenComponent<BitModal>(0); | ||
builder.SetKey(modalReference.Id); | ||
builder.AddComponentParameter(1, nameof(BitModal.IsOpen), true); | ||
builder.AddComponentParameter(2, nameof(BitModal.OnOverlayClick), EventCallback.Factory.Create<MouseEventArgs>(modalReference, () => modalReference.Close())); | ||
builder.AddComponentParameter(3, nameof(BitModal.ChildContent), content); | ||
builder.CloseComponent(); | ||
}); | ||
modalReference.SetModal(modal); | ||
|
||
var modalAdd = OnAddModal; | ||
if (modalAdd is not null) | ||
{ | ||
await modalAdd(modalReference); | ||
} | ||
|
||
if (persistent && _container is null) | ||
{ | ||
_persistentModalsQueue.Enqueue(modalReference); | ||
} | ||
|
||
return modalReference; | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/BlazorUI/Bit.BlazorUI.Extras/IServiceCollectionExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.DependencyInjection.Extensions; | ||
|
||
namespace Bit.BlazorUI; | ||
|
||
public static class IServiceCollectionExtensions | ||
{ | ||
public static IServiceCollection AddBitBlazorUIExtrasServices(this IServiceCollection services, bool singleton = false) | ||
{ | ||
if (singleton) | ||
{ | ||
services.TryAddSingleton<BitModalService>(); | ||
} | ||
else | ||
{ | ||
services.TryAddScoped<BitModalService>(); | ||
} | ||
|
||
return services; | ||
} | ||
} |
Oops, something went wrong.