diff --git a/src/Connected.Components/Components/ModalDialog.razor b/src/Connected.Components/Components/ModalDialog.razor
new file mode 100644
index 0000000..9bb97ab
--- /dev/null
+++ b/src/Connected.Components/Components/ModalDialog.razor
@@ -0,0 +1,19 @@
+@if (IsVisible)
+{
+
+}
\ No newline at end of file
diff --git a/src/Connected.Components/Components/ModalDialog.razor.cs b/src/Connected.Components/Components/ModalDialog.razor.cs
new file mode 100644
index 0000000..d9e8c88
--- /dev/null
+++ b/src/Connected.Components/Components/ModalDialog.razor.cs
@@ -0,0 +1,77 @@
+using Connected.Services.Modal;
+using Microsoft.AspNetCore.Components;
+
+namespace Connected.Components;
+public partial class ModalDialog: IDisposable
+{
+ [Inject] ModalDialogService? ModalService { get; set; }
+
+ protected bool IsVisible { get; set; }
+ protected string? Title { get; set; }
+ protected RenderFragment? Content { get; set; }
+
+ protected EventCallback OnConfirm { get; set; }
+
+ protected override void OnInitialized()
+ {
+ ModalService.OnShow += ShowModal;
+ ModalService.OnClose += CloseModal;
+ }
+
+ public void ShowModal(string title, RenderFragment content, EventCallback o, string CancelButtonText = "Cancel", string OKButtonText = "OK")
+ {
+ Title = title;
+ Content = content;
+ IsVisible = true;
+
+ this.OKButtonText = OKButtonText;
+ this.CancelButtonText = CancelButtonText;
+
+ OnConfirm = o;
+
+ StateHasChanged();
+ }
+
+ public void ShowModal(string title, MarkupString content, EventCallback o, string CancelButtonText = "Cancel", string OKButtonText = "OK")
+ {
+ Title = title;
+ Content = new RenderFragment(x => x.AddContent(1, content));
+ IsVisible = true;
+
+ this.OKButtonText = OKButtonText;
+ this.CancelButtonText = CancelButtonText;
+
+ OnConfirm = o;
+
+ StateHasChanged();
+ }
+
+ public void CloseModal(bool OkClicked = false)
+ {
+ IsVisible = false;
+ Title = "";
+ Content = null;
+ if (OkClicked)
+ OnConfirm.InvokeAsync();
+ StateHasChanged();
+ }
+
+ public void Dispose()
+ {
+ if (ModalService is not null)
+ {
+ ModalService.OnShow -= ShowModal;
+ ModalService.OnClose -= CloseModal;
+ }
+ }
+
+ [Parameter]
+ public EventCallback OnOkClick { get; set; }
+
+ [Parameter]
+ public string OKButtonText { get; set; } ="OK";
+
+ [Parameter]
+ public string CancelButtonText { get; set; } = "Cancel";
+
+}
\ No newline at end of file
diff --git a/src/Connected.Components/Services/Modal/ModalDialogService.cs b/src/Connected.Components/Services/Modal/ModalDialogService.cs
new file mode 100644
index 0000000..1484a26
--- /dev/null
+++ b/src/Connected.Components/Services/Modal/ModalDialogService.cs
@@ -0,0 +1,24 @@
+using Microsoft.AspNetCore.Components;
+
+namespace Connected.Services.Modal;
+public class ModalDialogService
+{
+ public event Action OnShow;
+ public event Action OnClose;
+
+ public void ShowDialog(string title, RenderFragment content, EventCallback OnConfirm, string CancelButtonText="Cancel", string OKButtonText="OK")
+ {
+ OnShow?.Invoke(title, content, OnConfirm, OKButtonText, CancelButtonText);
+ }
+
+ public void ShowDialog(string title, MarkupString contentMarkup, EventCallback OnConfirm, string CancelButtonText = "Cancel", string OKButtonText = "OK")
+ {
+ var content = new RenderFragment(x => x.AddContent(1, contentMarkup));
+ OnShow?.Invoke(title, content, OnConfirm, OKButtonText, CancelButtonText);
+ }
+
+ public void Close(bool OkClicked)
+ {
+ OnClose?.Invoke(OkClicked);
+ }
+}
diff --git a/src/Connected.Components/Services/ServiceCollectionExtensions.cs b/src/Connected.Components/Services/ServiceCollectionExtensions.cs
new file mode 100644
index 0000000..00dfc2a
--- /dev/null
+++ b/src/Connected.Components/Services/ServiceCollectionExtensions.cs
@@ -0,0 +1,10 @@
+using Connected.Services.Modal;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Connected.Services;
+
+public static class ServiceCollectionExtensions
+{
+ public static IServiceCollection AddModalDialogService(this IServiceCollection services)
+ => services.AddScoped();
+}
\ No newline at end of file