├── .github ├── FUNDING.yml ├── workflows │ └── release-drafter.yml ├── release-drafter.yml └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── screenshot.png ├── src └── Blazored.Modal │ ├── icon.png │ ├── _Imports.razor │ ├── ModalPosition.cs │ ├── BlazoredModal.razor │ ├── ModalOptions.cs │ ├── ServiceCollectionExtensions.cs │ ├── Services │ ├── ModalResult.cs │ ├── IModalService.cs │ └── ModalService.cs │ ├── ModalParameters.cs │ ├── Blazored.Modal.csproj │ ├── ModalReference.cs │ ├── wwwroot │ └── blazored-modal.css │ ├── BlazoredModal.razor.cs │ └── BlazoredModalInstance.razor ├── docs └── src │ ├── images │ ├── screenshot.png │ ├── blazored-logo.png │ └── blazored-modal-logo.png │ ├── templates │ └── blazored │ │ ├── favicon.ico │ │ ├── partials │ │ ├── dd-li.tmpl.partial │ │ ├── toc.tmpl.partial │ │ ├── logo.tmpl.partial │ │ ├── _toc.liquid │ │ ├── scripts.tmpl.partial │ │ ├── searchResults.tmpl.partial │ │ ├── _scripts.liquid │ │ ├── _logo.liquid │ │ ├── footer.tmpl.partial │ │ ├── _footer.liquid │ │ ├── _navbar.liquid │ │ ├── affix.tmpl.partial │ │ ├── li.tmpl.partial │ │ ├── _affix.liquid │ │ ├── head.tmpl.partial │ │ ├── enum.tmpl.partial │ │ ├── _head.liquid │ │ └── navbar.tmpl.partial │ │ └── layout │ │ └── _master.tmpl │ ├── .gitignore │ ├── index.md │ ├── getting-started │ ├── basic-usage.md │ ├── toc.yml │ └── installation.md │ ├── usage │ ├── long-running-task.md │ ├── returning-data-from-modals.md │ ├── toc.yml │ ├── passing-data-to-modals.md │ └── multiple-modals.md │ ├── docfx.json │ └── customisation-options │ ├── class.md │ ├── toc.yml │ ├── hide-header.md │ ├── disable-background-cancel.md │ ├── hide-close-button.md │ └── position.md ├── samples ├── BlazorServer │ ├── wwwroot │ │ ├── favicon.ico │ │ └── css │ │ │ ├── open-iconic │ │ │ ├── font │ │ │ │ ├── fonts │ │ │ │ │ ├── open-iconic.eot │ │ │ │ │ ├── open-iconic.otf │ │ │ │ │ ├── open-iconic.ttf │ │ │ │ │ └── open-iconic.woff │ │ │ │ └── css │ │ │ │ │ └── open-iconic-bootstrap.min.css │ │ │ ├── ICON-LICENSE │ │ │ ├── README.md │ │ │ └── FONT-LICENSE │ │ │ └── site.css │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── BlazorServer.csproj │ ├── Shared │ │ ├── MainLayout.razor │ │ ├── Confirm.razor │ │ ├── DisplayMessage.razor │ │ ├── YesNoPrompt.razor │ │ ├── MessageForm.razor │ │ ├── NavMenu.razor │ │ └── Loading.razor │ ├── _Imports.razor │ ├── App.razor │ ├── Program.cs │ ├── Pages │ │ ├── Index.razor │ │ ├── MultipleModals.razor │ │ ├── _Host.cshtml │ │ ├── CustomStyle.razor │ │ ├── ReturnDataFromModal.razor │ │ ├── PassDataToModal.razor │ │ ├── HideCloseButton.razor │ │ ├── BackgroundCancel.razor │ │ ├── Position.razor │ │ └── LongRunningTask.razor │ └── Startup.cs └── BlazorWebAssembly │ ├── wwwroot │ ├── css │ │ ├── open-iconic │ │ │ ├── font │ │ │ │ ├── fonts │ │ │ │ │ ├── open-iconic.eot │ │ │ │ │ ├── open-iconic.otf │ │ │ │ │ ├── open-iconic.ttf │ │ │ │ │ └── open-iconic.woff │ │ │ │ └── css │ │ │ │ │ └── open-iconic-bootstrap.min.css │ │ │ ├── ICON-LICENSE │ │ │ ├── README.md │ │ │ └── FONT-LICENSE │ │ └── site.css │ └── index.html │ ├── _Imports.razor │ ├── App.razor │ ├── Shared │ ├── MainLayout.razor │ ├── Confirm.razor │ ├── DisplayMessage.razor │ ├── YesNoPrompt.razor │ ├── MessageForm.razor │ ├── NavMenu.razor │ └── Loading.razor │ ├── Program.cs │ ├── Pages │ ├── Index.razor │ ├── MultipleModals.razor │ ├── CustomStyle.razor │ ├── ReturnDataFromModal.razor │ ├── PassDataToModal.razor │ ├── HideCloseButton.razor │ ├── BackGroundCancel.razor │ ├── Position.razor │ └── LongRunningTask.razor │ └── BlazorWebAssembly.csproj ├── Directory.Build.props ├── tests └── src │ └── Blazored.Modal.Tests │ ├── _Imports.razor │ ├── Assets │ ├── TestComponent.razor │ └── MockNavigationManager.cs │ ├── Blazored.Modal.Tests.csproj │ ├── DisplayTests.cs │ └── ModalOptionsTests.cs ├── LICENSE ├── azure-pipelines.yml ├── Blazored.Modal.sln ├── .gitignore └── README.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [chrissainty] 2 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tossnet/Modal/master/screenshot.png -------------------------------------------------------------------------------- /src/Blazored.Modal/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tossnet/Modal/master/src/Blazored.Modal/icon.png -------------------------------------------------------------------------------- /docs/src/images/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tossnet/Modal/master/docs/src/images/screenshot.png -------------------------------------------------------------------------------- /src/Blazored.Modal/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Components.Web 2 | @using Blazored.Modal.Services -------------------------------------------------------------------------------- /docs/src/images/blazored-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tossnet/Modal/master/docs/src/images/blazored-logo.png -------------------------------------------------------------------------------- /docs/src/images/blazored-modal-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tossnet/Modal/master/docs/src/images/blazored-modal-logo.png -------------------------------------------------------------------------------- /docs/src/templates/blazored/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tossnet/Modal/master/docs/src/templates/blazored/favicon.ico -------------------------------------------------------------------------------- /samples/BlazorServer/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tossnet/Modal/master/samples/BlazorServer/wwwroot/favicon.ico -------------------------------------------------------------------------------- /docs/src/templates/blazored/partials/dd-li.tmpl.partial: -------------------------------------------------------------------------------- 1 | {{#items}} 2 |
  • {{name}}
  • 3 | {{/items}} 4 | -------------------------------------------------------------------------------- /samples/BlazorServer/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tossnet/Modal/master/samples/BlazorServer/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /samples/BlazorServer/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tossnet/Modal/master/samples/BlazorServer/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /samples/BlazorServer/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tossnet/Modal/master/samples/BlazorServer/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /docs/src/.gitignore: -------------------------------------------------------------------------------- 1 | ############### 2 | # folder # 3 | ############### 4 | /**/DROP/ 5 | /**/TEMP/ 6 | /**/packages/ 7 | /**/bin/ 8 | /**/obj/ 9 | _site 10 | _exported_templates 11 | -------------------------------------------------------------------------------- /samples/BlazorServer/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tossnet/Modal/master/samples/BlazorServer/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tossnet/Modal/master/samples/BlazorWebAssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tossnet/Modal/master/samples/BlazorWebAssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tossnet/Modal/master/samples/BlazorWebAssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tossnet/Modal/master/samples/BlazorWebAssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /samples/BlazorServer/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /docs/src/index.md: -------------------------------------------------------------------------------- 1 | # **Blazored Modal** Docs 2 | A beautiful and customizable modal implementation for [Blazor](https://blazor.net) applications. 3 | 4 | --- 5 | 6 | ![Screenshot of the component in action](/images/screenshot.png) 7 | -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 3.1.2 5 | 3.2.0-preview3.20168.3 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Blazored.Modal/ModalPosition.cs: -------------------------------------------------------------------------------- 1 | namespace Blazored.Modal 2 | { 3 | public enum ModalPosition 4 | { 5 | Center, 6 | TopLeft, 7 | TopRight, 8 | BottomLeft, 9 | BottomRight 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /samples/BlazorServer/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /src/Blazored.Modal/BlazoredModal.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | @foreach (var modal in Modals) 4 | { 5 | @modal.ModalInstance 6 | } 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/src/Blazored.Modal.Tests/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Components.Web 2 | @using Microsoft.Extensions.DependencyInjection 3 | 4 | @using Bunit 5 | @using Bunit.Mocking.JSInterop 6 | @using Xunit 7 | 8 | @using Blazored.Modal 9 | @using Blazored.Modal.Services 10 | @using Blazored.Modal.Tests.Assets -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using Microsoft.AspNetCore.Components.Routing 3 | @using Microsoft.AspNetCore.Components.Web 4 | @using Microsoft.JSInterop 5 | @using BlazorWebAssembly 6 | @using BlazorWebAssembly.Shared 7 | 8 | @using Blazored.Modal 9 | @using Blazored.Modal.Services 10 | -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name: Release Drafter 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | update_release_draft: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: release-drafter/release-drafter@v5 13 | env: 14 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /samples/BlazorServer/BlazorServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/App.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

    Page not found

    7 |

    Sorry, but there's nothing here!

    8 |
    9 |
    -------------------------------------------------------------------------------- /docs/src/templates/blazored/partials/toc.tmpl.partial: -------------------------------------------------------------------------------- 1 | {{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} 2 | 3 |
    4 |
    5 |
    6 |
    7 |
    8 | -------------------------------------------------------------------------------- /docs/src/templates/blazored/partials/logo.tmpl.partial: -------------------------------------------------------------------------------- 1 | {{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} 2 | 3 | 4 | Blazored Modal Logo 5 | 6 | -------------------------------------------------------------------------------- /docs/src/templates/blazored/partials/_toc.liquid: -------------------------------------------------------------------------------- 1 | {% comment -%}Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.{% endcomment -%} 2 |
    3 |
    4 |
    5 |
    6 |
    7 | -------------------------------------------------------------------------------- /src/Blazored.Modal/ModalOptions.cs: -------------------------------------------------------------------------------- 1 | namespace Blazored.Modal 2 | { 3 | public class ModalOptions 4 | { 5 | public ModalPosition? Position { get; set; } 6 | public string Class { get; set; } 7 | public bool? DisableBackgroundCancel { get; set; } 8 | public bool? HideHeader { get; set; } 9 | public bool? HideCloseButton { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /samples/BlazorServer/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 | 4 | 5 |
    6 | 7 |
    8 | 9 |
    10 |
    11 | About 12 |
    13 | 14 |
    15 | @Body 16 |
    17 |
    18 | -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 | 4 | 5 |
    6 | 7 |
    8 | 9 |
    10 |
    11 | About 12 |
    13 | 14 |
    15 | @Body 16 |
    17 |
    18 | -------------------------------------------------------------------------------- /docs/src/templates/blazored/partials/scripts.tmpl.partial: -------------------------------------------------------------------------------- 1 | {{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /docs/src/templates/blazored/partials/searchResults.tmpl.partial: -------------------------------------------------------------------------------- 1 | {{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} 2 | 3 |
    4 |
    5 |
    6 |

    7 |
    8 |
      9 |
      10 | -------------------------------------------------------------------------------- /docs/src/templates/blazored/partials/_scripts.liquid: -------------------------------------------------------------------------------- 1 | {% comment -%}Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.{% endcomment -%} 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /samples/BlazorServer/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using Microsoft.AspNetCore.Authorization 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Authorization 6 | @using Microsoft.AspNetCore.Components.Web 7 | @using Microsoft.JSInterop 8 | @using BlazorServer 9 | @using BlazorServer.Shared 10 | 11 | @using Blazored.Modal 12 | @using Blazored.Modal.Services 13 | -------------------------------------------------------------------------------- /src/Blazored.Modal/ServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using Blazored.Modal.Services; 2 | using Microsoft.Extensions.DependencyInjection; 3 | 4 | namespace Blazored.Modal 5 | { 6 | public static class ServiceCollectionExtensions 7 | { 8 | public static IServiceCollection AddBlazoredModal(this IServiceCollection services) 9 | { 10 | return services.AddScoped(); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/src/Blazored.Modal.Tests/Assets/TestComponent.razor: -------------------------------------------------------------------------------- 1 |
      2 |

      @Title

      3 | 4 |
      5 | 6 | @code { 7 | [CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; } 8 | 9 | [Parameter] public string Title { get; set; } = DefaultTitle; 10 | 11 | public static string DefaultTitle = "My Test Component"; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name-template: 'v$NEXT_PATCH_VERSION' 2 | tag-template: 'v$NEXT_PATCH_VERSION' 3 | template: | 4 | # What's Changed 5 | 6 | $CHANGES 7 | categories: 8 | - title: '🚀 Features' 9 | labels: 10 | - 'Feature' 11 | - title: '🐛 Bug Fixes' 12 | labels: 13 | - 'Bug' 14 | - title: '🧰 Maintenance' 15 | label: 'Maintenance' 16 | - title: '📖 Documentation' 17 | label: 'Docs' 18 | change-template: '- (#$NUMBER) $TITLE - Thanks to @$AUTHOR ' -------------------------------------------------------------------------------- /docs/src/templates/blazored/partials/_logo.liquid: -------------------------------------------------------------------------------- 1 | {% comment -%}Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.{% endcomment -%} 2 | 3 | {%- if _appLogoPath -%} 4 | {{_appName}} 5 | {%- else -%} 6 | {{_appName}} 7 | {%- endif -%} 8 | 9 | -------------------------------------------------------------------------------- /samples/BlazorServer/App.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |

      Sorry, there's nothing at this address.

      9 |
      10 |
      11 |
      12 |
      -------------------------------------------------------------------------------- /samples/BlazorServer/Shared/Confirm.razor: -------------------------------------------------------------------------------- 1 |
      2 |

      Please click one of the buttons below to close or cancel the modal.

      3 | 4 | 5 | 6 |
      7 | 8 | @code { 9 | 10 | [CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; } 11 | 12 | void Close() => BlazoredModal.Close(ModalResult.Ok(true)); 13 | void Cancel() => BlazoredModal.Cancel(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/Shared/Confirm.razor: -------------------------------------------------------------------------------- 1 |
      2 |

      Please click one of the buttons below to close or cancel the modal.

      3 | 4 | 5 | 6 |
      7 | 8 | @code { 9 | 10 | [CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; } 11 | 12 | void Close() => BlazoredModal.Close(ModalResult.Ok(true)); 13 | void Cancel() => BlazoredModal.Cancel(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /docs/src/templates/blazored/partials/footer.tmpl.partial: -------------------------------------------------------------------------------- 1 | {{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} 2 | 3 |
      4 |
      5 |
      6 | 7 | Back to top 8 | 9 | {{{_appFooter}}} 10 | {{^_appFooter}}Generated by DocFX{{/_appFooter}} 11 |
      12 |
      13 |
      14 | -------------------------------------------------------------------------------- /samples/BlazorServer/Shared/DisplayMessage.razor: -------------------------------------------------------------------------------- 1 |
      2 | 3 |

      @Message

      4 | 5 | 6 | 7 |
      8 | 9 | @code { 10 | 11 | [CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; } 12 | 13 | [Parameter] public string Message { get; set; } 14 | 15 | void SubmitForm() => BlazoredModal.Close(); 16 | void Cancel() => BlazoredModal.Cancel(); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /docs/src/getting-started/basic-usage.md: -------------------------------------------------------------------------------- 1 | # Basic Usage 2 | Simple example of creating a modal 3 | 4 | --- 5 | 6 | ```html 7 | @page "/" 8 | @inject IModalService Modal 9 | 10 |

      Blazored Modal Sample

      11 | 12 |
      13 | 14 |

      15 | This is an example of using Blazored Modal in its most simplistic form. 16 |

      17 | 18 | 19 | 20 | @code { 21 | 22 | void ShowModal() => Modal.Show("Welcome to Blazored Modal"); 23 | 24 | } 25 | ``` -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/Shared/DisplayMessage.razor: -------------------------------------------------------------------------------- 1 |
      2 | 3 |

      @Message

      4 | 5 | 6 | 7 |
      8 | 9 | @code { 10 | 11 | [CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; } 12 | 13 | [Parameter] public string Message { get; set; } 14 | 15 | void SubmitForm() => BlazoredModal.Close(); 16 | void Cancel() => BlazoredModal.Cancel(); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/Program.cs: -------------------------------------------------------------------------------- 1 | using Blazored.Modal; 2 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; 3 | using System.Threading.Tasks; 4 | 5 | namespace BlazorWebAssembly 6 | { 7 | public class Program 8 | { 9 | public static async Task Main(string[] args) 10 | { 11 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 12 | builder.RootComponents.Add("app"); 13 | builder.Services.AddBlazoredModal(); 14 | 15 | await builder.Build().RunAsync(); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Blazored Modal (Wasm) 7 | 8 | 9 | 10 | 11 | 12 | 13 | Loading... 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /samples/BlazorServer/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Hosting; 3 | 4 | namespace BlazorServer 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | CreateHostBuilder(args).Build().Run(); 11 | } 12 | 13 | public static IHostBuilder CreateHostBuilder(string[] args) => 14 | Host.CreateDefaultBuilder(args) 15 | .ConfigureWebHostDefaults(webBuilder => 16 | { 17 | webBuilder.UseStartup(); 18 | }); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /docs/src/templates/blazored/partials/_footer.liquid: -------------------------------------------------------------------------------- 1 | {% comment -%}Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.{% endcomment -%} 2 |
      3 |
      4 |
      5 |
      6 | 7 | Back to top 8 | 9 | {%- if _appFooter -%} 10 | {{_appFooter}} 11 | {%- else -%} 12 | Copyright © Microsoft.
      Generated by DocFX
      13 | {%- endif -%} 14 |
      15 |
      16 |
      17 | -------------------------------------------------------------------------------- /samples/BlazorServer/Pages/Index.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @inject IModalService Modal 3 | 4 |

      Blazored Modal Sample

      5 | 6 |
      7 | 8 |

      9 | This is an example of using Blazored Modal in its most simplistic form. 10 |

      11 | 12 |
      13 |
      14 |

      15 | 16 | @("Modal.Show(\"Welcome to Blazored Modal\", options);") 17 | 18 |

      19 |
      20 |
      21 | 22 | 23 | 24 | @code { 25 | 26 | void ShowModal() => Modal.Show("Welcome to Blazored Modal"); 27 | 28 | } -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/Pages/Index.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @inject IModalService Modal 3 | 4 |

      Blazored Modal Sample

      5 | 6 |
      7 | 8 |

      9 | This is an example of using Blazored Modal in its most simplistic form. 10 |

      11 | 12 |
      13 |
      14 |

      15 | 16 | @("Modal.Show(\"Welcome to Blazored Modal\", options);") 17 | 18 |

      19 |
      20 |
      21 | 22 | 23 | 24 | @code { 25 | 26 | void ShowModal() => Modal.Show("Welcome to Blazored Modal"); 27 | 28 | } -------------------------------------------------------------------------------- /docs/src/templates/blazored/partials/_navbar.liquid: -------------------------------------------------------------------------------- 1 | {% comment -%}Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.{% endcomment -%} 2 |
      3 |
      4 |
      5 | 11 | {% include partials/logo -%} 12 |
      13 |
      14 |
      15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[Feature Request]" 5 | labels: Feature Request, Triage 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /samples/BlazorServer/Shared/YesNoPrompt.razor: -------------------------------------------------------------------------------- 1 | @inject IModalService ModalService 2 | 3 |
      4 |

      Are you sure you want to delete the record?

      5 | 6 | 7 | 8 |
      9 | 10 | @code { 11 | 12 | [CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; } 13 | 14 | async Task Yes() 15 | { 16 | var confirmationModal = ModalService.Show("Second Modal"); 17 | var result = await confirmationModal.Result; 18 | 19 | if (result.Cancelled) 20 | return; 21 | 22 | BlazoredModal.Close(); 23 | } 24 | 25 | void No() => BlazoredModal.Cancel(); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/Shared/YesNoPrompt.razor: -------------------------------------------------------------------------------- 1 | @inject IModalService ModalService 2 | 3 |
      4 |

      Are you sure you want to delete the record?

      5 | 6 | 7 | 8 |
      9 | 10 | @code { 11 | 12 | [CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; } 13 | 14 | async Task Yes() 15 | { 16 | var confirmationModal = ModalService.Show("Second Modal"); 17 | var result = await confirmationModal.Result; 18 | 19 | if (result.Cancelled) 20 | return; 21 | 22 | BlazoredModal.Close(); 23 | } 24 | 25 | void No() => BlazoredModal.Cancel(); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /samples/BlazorServer/Pages/MultipleModals.razor: -------------------------------------------------------------------------------- 1 | @page "/multiplemodals" 2 | @inject IModalService Modal 3 | 4 |

      Multiple Modals

      5 | 6 |
      7 | 8 |

      9 | It is possible to show multiple modals at the same time. Each new modal needs to be shown from the currently active modal. 10 | In this example an initial confirmation modal is shown, if you select Yes then a second confirmation modal is shown. 11 | When you Close the second modal both modals will be closed. If you Cancel the second modal, only the second 12 | modal will be closed. 13 |

      14 | 15 | 16 | 17 | @code { 18 | 19 | void ShowModal() => Modal.Show("First Modal"); 20 | 21 | } -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/Pages/MultipleModals.razor: -------------------------------------------------------------------------------- 1 | @page "/multiplemodals" 2 | @inject IModalService Modal 3 | 4 |

      Multiple Modals

      5 | 6 |
      7 | 8 |

      9 | It is possible to show multiple modals at the same time. Each new modal needs to be shown from the currently active modal. 10 | In this example an initial confirmation modal is shown, if you select Yes then a second confirmation modal is shown. 11 | When you Close the second modal both modals will be closed. If you Cancel the second modal, only the second 12 | modal will be closed. 13 |

      14 | 15 | 16 | 17 | @code { 18 | 19 | void ShowModal() => Modal.Show("First Modal"); 20 | 21 | } -------------------------------------------------------------------------------- /samples/BlazorServer/Pages/_Host.cshtml: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @namespace BlazorServer.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | 5 | 6 | 7 | 8 | 9 | 10 | Blazored Modal (Server) 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | @(await Html.RenderComponentAsync(RenderMode.ServerPrerendered)) 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/Blazored.Modal/Services/ModalResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Blazored.Modal.Services 4 | { 5 | public class ModalResult 6 | { 7 | public object Data { get; } 8 | public Type DataType { get; } 9 | public bool Cancelled { get; } 10 | 11 | protected ModalResult(object data, Type resultType, bool cancelled) 12 | { 13 | Data = data; 14 | DataType = resultType; 15 | Cancelled = cancelled; 16 | } 17 | 18 | public static ModalResult Ok(T result) => Ok(result, default); 19 | 20 | public static ModalResult Ok(T result, Type modalType) => new ModalResult(result, modalType, false); 21 | 22 | public static ModalResult Cancel() => new ModalResult(default, typeof(object), true); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[Bug]" 5 | labels: Bug, Triage 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Hosting Model (is this issue happening with a certain hosting model?):** 27 | - Blazor Server 28 | - Blazor WebAssembly 29 | - etc... 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /samples/BlazorServer/Shared/MessageForm.razor: -------------------------------------------------------------------------------- 1 |
      2 | 3 |
      4 | 5 | 6 |
      7 | 8 | 9 | 10 |
      11 | 12 | @code { 13 | 14 | [CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; } 15 | 16 | string Message { get; set; } 17 | 18 | protected override void OnInitialized() => BlazoredModal.SetTitle("Enter a Message"); 19 | 20 | void SubmitForm() => BlazoredModal.Close(ModalResult.Ok(Message)); 21 | void Cancel() => BlazoredModal.Cancel(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /docs/src/usage/long-running-task.md: -------------------------------------------------------------------------------- 1 | # Long running task 2 | How to open a modal, execute a long-running task and close the modal after it. 3 | 4 | --- 5 | 6 | We can open a modal and using its `ModalReference` we can also close it from outside of the actual Modal itself. 7 | 8 | ```html 9 | 10 | 11 | @code { 12 | 13 | string _message; 14 | 15 | async Task ShowModal() 16 | { 17 | var loadingModal = Modal.Show(); 18 | 19 | await Task.Delay(5000); //Do your long running task, here we just wait 5 seconds 20 | 21 | loadingModal.Close(); 22 | 23 | var result = await loadingModal.Result; 24 | //Do something with the result. 25 | //In this case we won't as we just showed a loading dialog 26 | } 27 | 28 | } 29 | ``` -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/Shared/MessageForm.razor: -------------------------------------------------------------------------------- 1 |
      2 | 3 |
      4 | 5 | 6 |
      7 | 8 | 9 | 10 |
      11 | 12 | @code { 13 | 14 | [CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; } 15 | 16 | string Message { get; set; } 17 | 18 | protected override void OnInitialized() => BlazoredModal.SetTitle("Enter a Message"); 19 | 20 | void SubmitForm() => BlazoredModal.Close(ModalResult.Ok(Message)); 21 | void Cancel() => BlazoredModal.Cancel(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /tests/src/Blazored.Modal.Tests/Assets/MockNavigationManager.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components; 2 | 3 | namespace Blazored.Modal.Tests.Assets 4 | { 5 | internal class MockNavigationManager : NavigationManager 6 | { 7 | public MockNavigationManager() 8 | { 9 | } 10 | 11 | public MockNavigationManager(string baseUri = null, string uri = null) 12 | { 13 | Initialize(baseUri ?? "http://example.com/", uri ?? baseUri ?? "http://example.com/welcome-page"); 14 | } 15 | 16 | public new void Initialize(string baseUri, string uri) 17 | { 18 | base.Initialize(baseUri, uri); 19 | } 20 | 21 | protected override void NavigateToCore(string uri, bool forceLoad) 22 | { 23 | throw new System.NotImplementedException(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/src/Blazored.Modal.Tests/Blazored.Modal.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | all 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/BlazorWebAssembly.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.1 5 | 3.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/src/usage/returning-data-from-modals.md: -------------------------------------------------------------------------------- 1 | # Returning Data From Modals 2 | How to return data from the component being displayed in the modal. 3 | 4 | --- 5 | 6 | Data can be returned from a modal by using the `ModalResult.Data` property. You can return simple strings as well as complex objects. In the example below, you can add a message in the modal that will be show here when you close the modal. 7 | 8 | ```html 9 | 10 | 11 | @if (!string.IsNullOrWhiteSpace(_message)) 12 | { 13 |

      Your message was:

      14 |

      @_message

      15 | } 16 | 17 | @code { 18 | 19 | string _message; 20 | 21 | async Task ShowModal() 22 | { 23 | var messageForm = Modal.Show(); 24 | var result = await messageForm.Result; 25 | 26 | if (!result.Cancelled) 27 | _message = result.Data.ToString(); 28 | } 29 | 30 | } 31 | ``` -------------------------------------------------------------------------------- /docs/src/docfx.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "content": [ 4 | { 5 | "files": [ 6 | "**/*.md", 7 | "**/*.yml" 8 | ], 9 | "exclude": [ 10 | "obj/**", 11 | "_site/**" 12 | ], 13 | "src": "." 14 | } 15 | ], 16 | "resource": [ 17 | { 18 | "files": [ 19 | "images/**" 20 | ] 21 | } 22 | ], 23 | "dest": "_site", 24 | "globalMetadata": { 25 | "_gitContribute": { 26 | "repo": "https://github.com/blazored/modal.git", 27 | "branch": "master" 28 | } 29 | }, 30 | "fileMetadataFiles": [], 31 | "template": [ 32 | "default", 33 | "templates/blazored" 34 | ], 35 | "postProcessors": [], 36 | "markdownEngineName": "markdig", 37 | "noLangKeyword": false, 38 | "keepFileLink": false, 39 | "cleanupCacheHistory": false, 40 | "disableGitFeatures": false 41 | } 42 | } -------------------------------------------------------------------------------- /docs/src/customisation-options/class.md: -------------------------------------------------------------------------------- 1 | # Class 2 | How to customise the look of modals. 3 | 4 | --- 5 | 6 | Blazored Modal comes with a default look and feel which is deliberately plain. If you want to customise how the modal looks to match the rest of your application you can set a top level class and then use CSS selectors to add custom styles. 7 | 8 | ## Setting Class Globally 9 | 10 | To set a global class for all modals in your application, you can set the `Class` parameter on the `BlazoredModal` component in your `MainLayout`. 11 | 12 | ```html 13 | @inherits LayoutComponentBase 14 | 15 | 16 | 17 | 18 | ``` 19 | 20 | ## Setting Class Per Modal 21 | 22 | To set the class of a specific modal instance you can pass in a `ModalOptions` object when calling `Show`. 23 | 24 | ```csharp 25 | var options = new ModalOptions { Class = "my-custom-class" }; 26 | 27 | _ = Modal.Show("My Modal", options); 28 | ``` 29 | 30 | -------------------------------------------------------------------------------- /docs/src/templates/blazored/partials/affix.tmpl.partial: -------------------------------------------------------------------------------- 1 | {{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} 2 | 3 |
      4 |
      5 | {{^_disableContribution}} 6 |
      7 |
        8 | {{#docurl}} 9 |
      • 10 | {{__global.improveThisDoc}} 11 |
      • 12 | {{/docurl}} 13 | {{#sourceurl}} 14 |
      • 15 | {{__global.viewSource}} 16 |
      • 17 | {{/sourceurl}} 18 |
      19 |
      20 | {{/_disableContribution}} 21 |
      22 | 23 |
      24 |
      25 |
      26 | -------------------------------------------------------------------------------- /docs/src/customisation-options/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Home 2 | href: ../index.md 3 | - name: Getting Started 4 | items: 5 | - name: Installation 6 | href: ../getting-started/installation.md 7 | - name: Basic Usage 8 | href: ../getting-started/basic-usage.md 9 | - name: Usage Scenarios 10 | items: 11 | - name: Passing Data To Modals 12 | href: ../usage/passing-data-to-modals.md 13 | - name: Returning Data From Modals 14 | href: ../usage/returning-data-from-modals.md 15 | - name: Multiple Modals 16 | href: ../usage/multiple-modals.md 17 | - name: Long-running Tasks 18 | href: ../usage/long-running-task.md 19 | - name: Customisation Options 20 | items: 21 | - name: Position 22 | href: position.md 23 | - name: Class 24 | href: class.md 25 | - name: Disable Background Cancel 26 | href: disable-background-cancel.md 27 | - name: Hide Header 28 | href: hide-header.md 29 | - name: Hide Close Button 30 | href: hide-close-button.md -------------------------------------------------------------------------------- /docs/src/templates/blazored/partials/li.tmpl.partial: -------------------------------------------------------------------------------- 1 | {{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} 2 | 3 |
        4 | {{#items}} 5 | {{^dropdown}} 6 |
      • 7 | {{#topicHref}} 8 | {{name}} 9 | {{/topicHref}} 10 | {{^topicHref}} 11 |
        {{{name}}}
        12 | {{/topicHref}} 13 | {{^leaf}} 14 | {{>partials/li}} 15 | {{/leaf}} 16 |
      • 17 | {{/dropdown}} 18 | {{#dropdown}} 19 |
      • 20 | {{name}} 21 |
          22 | {{>partials/dd-li}} 23 |
        24 |
      • 25 | {{/dropdown}} 26 | {{/items}} 27 |
      28 | -------------------------------------------------------------------------------- /docs/src/templates/blazored/partials/_affix.liquid: -------------------------------------------------------------------------------- 1 | {% comment -%}Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.{% endcomment -%} 2 |
      3 |
      4 | {%- if not _disableContribution -%} 5 |
      6 |
        7 | {%- if docurl -%} 8 |
      • 9 | {{__global.improveThisDoc}} 10 |
      • 11 | {%- endif -%} 12 | {%- if sourceurl -%} 13 |
      • 14 | {{__global.viewSource}} 15 |
      • 16 | {%- endif -%} 17 |
      18 |
      19 | {%- endif -%} 20 |
      21 | 22 |
      23 |
      24 |
      25 | -------------------------------------------------------------------------------- /docs/src/customisation-options/hide-header.md: -------------------------------------------------------------------------------- 1 | # Hide Header 2 | How to control visibility of the modal header. 3 | 4 | --- 5 | 6 | By default, the modal has a header which displays the title you specify when you call `Show`. However, you can choose to hide this header to give the modal a more compact look. Just set the `HideHeader` option to `true`. 7 | 8 | ## Setting HideHeader Globally 9 | 10 | To control the visibility of the header globally for all modals in your application, you can set the `HideHeader` parameter on the `BlazoredModal` component in your `MainLayout`. 11 | 12 | ```html 13 | @inherits LayoutComponentBase 14 | 15 | 16 | 17 | 18 | ``` 19 | 20 | ## Setting HideHeader Per Modal 21 | 22 | To set the visibility of the header for a specific modal instance you can pass in a `ModalOptions` object when calling `Show`. 23 | 24 | ```csharp 25 | var options = new ModalOptions { HideHeader = true }; 26 | 27 | _ = Modal.Show("My Modal", options); 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/src/customisation-options/disable-background-cancel.md: -------------------------------------------------------------------------------- 1 | # Disable Background Cancel 2 | How to control the background cancel feature. 3 | 4 | --- 5 | 6 | By default, a modal is cancelled if the user clicks anywhere outside the modal. This behaviour can be disabled by setting `DisableBackgroundCancel` to `true`. 7 | 8 | ## Setting DisableBackgroundCancel Globally 9 | 10 | To control background cancel globally for all modals in your application, you can set the `DisableBackgroundCancel` parameter on the `BlazoredModal` component in your `MainLayout`. 11 | 12 | ```html 13 | @inherits LayoutComponentBase 14 | 15 | 16 | 17 | 18 | ``` 19 | 20 | ## Setting DisableBackgroundCancel Per Modal 21 | 22 | To set the background cancel of a specific modal instance you can pass in a `ModalOptions` object when calling `Show`. 23 | 24 | ```csharp 25 | var options = new ModalOptions { DisableBackgroundCancel = true }; 26 | 27 | _ = Modal.Show("My Modal", options); 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/src/customisation-options/hide-close-button.md: -------------------------------------------------------------------------------- 1 | # Hide Close Button 2 | How to control visibility of the close button. 3 | 4 | --- 5 | 6 | By default, a close button is shown in the top right of the modal. If you prefer, the button can be hidden and you can handle closing the modal yourself by setting `HideCloseButton` to `true`. 7 | 8 | ## Setting HideCloseButton Globally 9 | 10 | To control the visibility of the close button globally for all modals in your application, you can set the `HideCloseButton` parameter on the `BlazoredModal` component in your `MainLayout`. 11 | 12 | ```html 13 | @inherits LayoutComponentBase 14 | 15 | 16 | 17 | 18 | ``` 19 | 20 | ## Setting HideCloseButton Per Modal 21 | 22 | To set the visibility of the close button for a specific modal instance you can pass in a `ModalOptions` object when calling `Show`. 23 | 24 | ```csharp 25 | var options = new ModalOptions { HideCloseButton = true }; 26 | 27 | _ = Modal.Show("My Modal", options); 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/src/usage/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Home 2 | href: ../index.md 3 | - name: Getting Started 4 | items: 5 | - name: Installation 6 | href: ../getting-started/installation.md 7 | - name: Basic Usage 8 | href: ../getting-started/basic-usage.md 9 | - name: Usage Scenarios 10 | items: 11 | - name: Passing Data To Modals 12 | href: passing-data-to-modals.md 13 | - name: Returning Data From Modals 14 | href: returning-data-from-modals.md 15 | - name: Multiple Modals 16 | href: multiple-modals.md 17 | - name: Long-running Tasks 18 | href: long-running-task.md 19 | - name: Customisation Options 20 | items: 21 | - name: Position 22 | href: ../customisation-options/position.md 23 | - name: Class 24 | href: ../customisation-options/class.md 25 | - name: Disable Background Cancel 26 | href: ../customisation-options/disable-background-cancel.md 27 | - name: Hide Header 28 | href: ../customisation-options/hide-header.md 29 | - name: Hide Close Button 30 | href: ../customisation-options/hide-close-button.md -------------------------------------------------------------------------------- /docs/src/getting-started/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Home 2 | href: ../index.md 3 | - name: Getting Started 4 | items: 5 | - name: Installation 6 | href: installation.md 7 | - name: Basic Usage 8 | href: basic-usage.md 9 | - name: Usage Scenarios 10 | items: 11 | - name: Passing Data To Modals 12 | href: ../usage/passing-data-to-modals.md 13 | - name: Returning Data From Modals 14 | href: ../usage/returning-data-from-modals.md 15 | - name: Multiple Modals 16 | href: ../usage/multiple-modals.md 17 | - name: Long-running Tasks 18 | href: ../usage/long-running-task.md 19 | - name: Customisation Options 20 | items: 21 | - name: Position 22 | href: ../customisation-options/position.md 23 | - name: Class 24 | href: ../customisation-options/class.md 25 | - name: Disable Background Cancel 26 | href: ../customisation-options/disable-background-cancel.md 27 | - name: Hide Header 28 | href: ../customisation-options/hide-header.md 29 | - name: Hide Close Button 30 | href: ../customisation-options/hide-close-button.md -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Blazored 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/src/customisation-options/position.md: -------------------------------------------------------------------------------- 1 | # Position 2 | How to customise where modals are displayed. 3 | 4 | --- 5 | 6 | By default, modals are shown in the center of the viewport. However, you can customise where modals are shown using the `ModalOptions.Position` setting. The available options are `Center`, `TopLeft`, `TopRight`, `BottomLeft` and `BottomRight`. You can define this setting both at a global level, to effect all modals, or on a modal by modal basis. 7 | 8 | ## Setting Position Globally 9 | 10 | To set a global default position for all modals in your application, you can set the `Position` parameter on the `BlazoredModal` component in your `MainLayout`. 11 | 12 | ```html 13 | @inherits LayoutComponentBase 14 | 15 | 16 | 17 | 18 | ``` 19 | 20 | ## Setting Position Per Modal 21 | 22 | To set the position of a specific modal instance you can pass in a `ModalOptions` object when calling `Show`. 23 | 24 | ```csharp 25 | var options = new ModalOptions { Position = ModalPosition.TopRight }; 26 | 27 | _ = Modal.Show("My Modal", options); 28 | ``` 29 | -------------------------------------------------------------------------------- /src/Blazored.Modal/ModalParameters.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Blazored.Modal 4 | { 5 | public class ModalParameters 6 | { 7 | internal Dictionary _parameters; 8 | 9 | public ModalParameters() 10 | { 11 | _parameters = new Dictionary(); 12 | } 13 | 14 | public void Add(string parameterName, object value) 15 | { 16 | _parameters[parameterName] = value; 17 | } 18 | 19 | public T Get(string parameterName) 20 | { 21 | if (_parameters.TryGetValue(parameterName, out var value)) 22 | { 23 | return (T)value; 24 | } 25 | 26 | throw new KeyNotFoundException($"{parameterName} does not exist in modal parameters"); 27 | } 28 | 29 | public T TryGet(string parameterName) 30 | { 31 | if (_parameters.TryGetValue(parameterName, out var value)) 32 | { 33 | return (T)value; 34 | } 35 | 36 | return default; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /samples/BlazorServer/wwwroot/css/open-iconic/ICON-LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/wwwroot/css/open-iconic/ICON-LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /samples/BlazorServer/Pages/CustomStyle.razor: -------------------------------------------------------------------------------- 1 | @page "/custom" 2 | @inject IModalService Modal 3 | 4 |

      Custom Styling

      5 | 6 |
      7 | 8 |

      9 | Custom CSS classes can be set globally or on a per modal basis to change the look of modals. 10 |

      11 | 12 |
      13 |
      Setting on a per modal basis
      14 |
      15 |

      16 | 17 | @("var options = new ModalOptions() { Class = \"my-custom-class\" };") 18 |
      19 | @("Modal.Show(\"Custom Styling\", options);") 20 |
      21 |

      22 |
      23 |
      24 | 25 |
      26 |
      Setting globally for all modals
      27 |
      28 |

      29 | 30 | @("") 31 | 32 |

      33 |
      34 |
      35 | 36 | 37 | 38 | @code { 39 | 40 | void ShowModalCustomStyle() 41 | { 42 | var options = new ModalOptions { Class = "blazored-prompt-modal" }; 43 | Modal.Show("Custom Style", options); 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/Pages/CustomStyle.razor: -------------------------------------------------------------------------------- 1 | @page "/custom" 2 | @inject IModalService Modal 3 | 4 |

      Custom Styling

      5 | 6 |
      7 | 8 |

      9 | Custom CSS classes can be set globally or on a per modal basis to change the look of modals. 10 |

      11 | 12 |
      13 |
      Setting on a per modal basis
      14 |
      15 |

      16 | 17 | @("var options = new ModalOptions() { Class = \"my-custom-class\" };") 18 |
      19 | @("Modal.Show(\"Custom Styling\", options);") 20 |
      21 |

      22 |
      23 |
      24 | 25 |
      26 |
      Setting globally for all modals
      27 |
      28 |

      29 | 30 | @("") 31 | 32 |

      33 |
      34 |
      35 | 36 | 37 | 38 | @code { 39 | 40 | void ShowModalCustomStyle() 41 | { 42 | var options = new ModalOptions { Class = "blazored-prompt-modal" }; 43 | Modal.Show("Custom Style", options); 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | trigger: 2 | - master 3 | 4 | pool: 5 | vmImage: 'vs2017-win2016' 6 | 7 | variables: 8 | buildConfiguration: 'Release' 9 | 10 | steps: 11 | - task: UseDotNet@2 12 | displayName: 'Use .NET Core sdk' 13 | inputs: 14 | packageType: sdk 15 | version: 3.1.201 16 | installationPath: $(Agent.ToolsDirectory)/dotnet 17 | 18 | - task: NuGetToolInstaller@0 19 | displayName: 'Installing Nuget Tools...' 20 | inputs: 21 | versionSpec: '4.9.2' 22 | 23 | - script: dotnet build --configuration $(buildConfiguration) src/Blazored.Modal/Blazored.Modal.csproj 24 | displayName: 'Building $(buildConfiguration)...' 25 | 26 | - script: dotnet test ./tests/src/Blazored.Modal.Tests/Blazored.Modal.Tests.csproj --configuration $(buildConfiguration) 27 | displayName: 'Testing $(buildConfiguration)...' 28 | 29 | - task: DotNetCoreCLI@2 30 | displayName: 'Generating Nuget Package... ' 31 | inputs: 32 | command: pack 33 | arguments: --no-build 34 | packagesToPack: src/Blazored.Modal/Blazored.Modal.csproj 35 | configuration: $(buildConfiguration) 36 | 37 | - task: PublishBuildArtifacts@1 38 | displayName: 'Publishing Build Artifacts...' 39 | 40 | - powershell: | 41 | choco install docfx -y 42 | docfx docs/src/docfx.json 43 | if ($lastexitcode -ne 0){ 44 | throw ("Error generating document") 45 | } 46 | displayName: "docfx build" 47 | 48 | - task: PublishBuildArtifacts@1 49 | inputs: 50 | pathToPublish: docs/src/_site 51 | artifactName: docs -------------------------------------------------------------------------------- /docs/src/templates/blazored/partials/head.tmpl.partial: -------------------------------------------------------------------------------- 1 | {{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} 2 | 3 | 4 | 5 | 6 | {{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}} | Blazored Modal 7 | 8 | 9 | 10 | {{#_description}}{{/_description}} 11 | 12 | 13 | 14 | 15 | 16 | 17 | {{#_noindex}}{{/_noindex}} 18 | {{#_enableSearch}}{{/_enableSearch}} 19 | {{#_enableNewTab}}{{/_enableNewTab}} 20 | 21 | -------------------------------------------------------------------------------- /src/Blazored.Modal/Blazored.Modal.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 3.0 6 | 7 | Chris Sainty 8 | 9 | Copyright 2018 (c) Chris Sainty. All rights reserved. 10 | MIT 11 | https://github.com/Blazored/Modal 12 | icon.png 13 | https://github.com/Blazored/Modal 14 | git 15 | Blazored Blazor Razor Components Modal Dialogue 16 | A JavaScript free modal library for Blazor and Razor Components applications. 17 | true 18 | 4.1.0 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /samples/BlazorServer/Pages/ReturnDataFromModal.razor: -------------------------------------------------------------------------------- 1 | @page "/returningdata" 2 | @inject IModalService Modal 3 | 4 |

      Returning Data From a Modal

      5 | 6 |
      7 | 8 |

      9 | Data can be returned from a modal by using the ModalResult.Data property. You can return simple strings as well as complex objects. 10 | In the example below, you can add a message in the modal that will be show here when you close the modal. 11 |

      12 | 13 |
      14 |
      15 |

      16 | 17 | @("var messageForm = Modal.Show();")
      18 | @("var result = await messageForm.Result;")
      19 |
      20 | @("if (!result.Cancelled)")
      21 | @(" _message = result.Data.ToString();") 22 |
      23 |

      24 |
      25 |
      26 | 27 | 28 | 29 | @if (!string.IsNullOrWhiteSpace(_message)) 30 | { 31 |
      32 |

      Your message was:

      33 |

      @_message

      34 | } 35 | 36 | @code { 37 | 38 | string _message; 39 | 40 | async Task ShowModal() 41 | { 42 | var messageForm = Modal.Show(); 43 | var result = await messageForm.Result; 44 | 45 | if (!result.Cancelled) 46 | _message = result.Data?.ToString() ?? string.Empty; 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/Pages/ReturnDataFromModal.razor: -------------------------------------------------------------------------------- 1 | @page "/returningdata" 2 | @inject IModalService Modal 3 | 4 |

      Returning Data From a Modal

      5 | 6 |
      7 | 8 |

      9 | Data can be returned from a modal by using the ModalResult.Data property. You can return simple strings as well as complex objects. 10 | In the example below, you can add a message in the modal that will be show here when you close the modal. 11 |

      12 | 13 |
      14 |
      15 |

      16 | 17 | @("var messageForm = Modal.Show();")
      18 | @("var result = await messageForm.Result;")
      19 |
      20 | @("if (!result.Cancelled)")
      21 | @(" _message = result.Data.ToString();") 22 |
      23 |

      24 |
      25 |
      26 | 27 | 28 | 29 | @if (!string.IsNullOrWhiteSpace(_message)) 30 | { 31 |
      32 |

      Your message was:

      33 |

      @_message

      34 | } 35 | 36 | @code { 37 | 38 | string _message; 39 | 40 | async Task ShowModal() 41 | { 42 | var messageForm = Modal.Show(); 43 | var result = await messageForm.Result; 44 | 45 | if (!result.Cancelled) 46 | _message = result.Data?.ToString() ?? string.Empty; 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /src/Blazored.Modal/ModalReference.cs: -------------------------------------------------------------------------------- 1 | using Blazored.Modal.Services; 2 | using Microsoft.AspNetCore.Components; 3 | using System; 4 | using System.Threading.Tasks; 5 | 6 | namespace Blazored.Modal 7 | { 8 | public class ModalReference 9 | { 10 | private readonly TaskCompletionSource _resultCompletion = new TaskCompletionSource(); 11 | 12 | private readonly Action _closed; 13 | 14 | private readonly ModalService _modalService; 15 | 16 | public ModalReference(Guid modalInstanceId, RenderFragment modalInstance, ModalService modalService) 17 | { 18 | Id = modalInstanceId; 19 | ModalInstance = modalInstance; 20 | _closed = HandleClosed; 21 | _modalService = modalService; 22 | } 23 | 24 | public void Close() 25 | { 26 | _modalService.Close(this); 27 | } 28 | 29 | public void Close(ModalResult result) 30 | { 31 | _modalService.Close(this, result); 32 | } 33 | 34 | private void HandleClosed(ModalResult obj) 35 | { 36 | _ = _resultCompletion.TrySetResult(obj); 37 | } 38 | 39 | internal Guid Id { get; } 40 | internal RenderFragment ModalInstance { get; } 41 | 42 | public Task Result => _resultCompletion.Task; 43 | 44 | internal void Dismiss(ModalResult result) 45 | { 46 | _closed.Invoke(result); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /docs/src/templates/blazored/partials/enum.tmpl.partial: -------------------------------------------------------------------------------- 1 | {{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} 2 | 3 | {{>partials/class.header}} 4 | {{#children}} 5 |

      {{>partials/classSubtitle}}

      6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | {{#children}} 15 | 16 | 17 | 18 | 19 | {{/children}} 20 | 21 |
      {{__global.name}}{{__global.description}}
      {{name.0.value}}{{{summary}}}
      22 | {{/children}} 23 | {{#seealso.0}} 24 |
      {{__global.seealso}}
      25 |
      26 | {{/seealso.0}} 27 | {{#seealso}} 28 | {{#isCref}} 29 |
      {{{type.specName.0.value}}}
      30 | {{/isCref}} 31 | {{^isCref}} 32 |
      {{{url}}}
      33 | {{/isCref}} 34 | {{/seealso}} 35 | {{#seealso.0}} 36 |
      37 | {{/seealso.0}} 38 | {{#extensionMethods.0}} 39 |

      {{__global.extensionMethods}}

      40 | {{/extensionMethods.0}} 41 | {{#extensionMethods}} 42 |
      43 | {{#definition}} 44 | 45 | {{/definition}} 46 | {{^definition}} 47 | 48 | {{/definition}} 49 |
      50 | {{/extensionMethods}} 51 | -------------------------------------------------------------------------------- /samples/BlazorServer/Pages/PassDataToModal.razor: -------------------------------------------------------------------------------- 1 | @page "/passingdata" 2 | @inject IModalService Modal 3 | 4 |

      Passing Data to a Modal

      5 | 6 |
      7 | 8 |

      9 | Data can be passed to a modal by using the ModalParameters object. The items you add to this collection must match the parameters 10 | defined on the component being displayed in the modal. In the example below, you can type a message and see it displayed in the modal. 11 |

      12 | 13 |
      14 |
      15 |

      16 | 17 | @("var messageForm = Modal.Show();")
      18 | @("var result = await messageForm.Result;")
      19 |
      20 | @("if (!result.Cancelled)")
      21 | @(" _message = result.Data.ToString();") 22 |
      23 |

      24 |
      25 |
      26 | 27 |
      28 | 29 | 30 |
      31 | 32 | 33 | 34 | @code { 35 | 36 | string _message; 37 | 38 | async Task ShowModal() 39 | { 40 | var parameters = new ModalParameters(); 41 | parameters.Add(nameof(DisplayMessage.Message), _message); 42 | 43 | var messageForm = Modal.Show("Passing Data", parameters); 44 | var result = await messageForm.Result; 45 | 46 | _message = ""; 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/Pages/PassDataToModal.razor: -------------------------------------------------------------------------------- 1 | @page "/passingdata" 2 | @inject IModalService Modal 3 | 4 |

      Passing Data to a Modal

      5 | 6 |
      7 | 8 |

      9 | Data can be passed to a modal by using the ModalParameters object. The items you add to this collection must match the parameters 10 | defined on the component being displayed in the modal. In the example below, you can type a message and see it displayed in the modal. 11 |

      12 | 13 |
      14 |
      15 |

      16 | 17 | @("var messageForm = Modal.Show();")
      18 | @("var result = await messageForm.Result;")
      19 |
      20 | @("if (!result.Cancelled)")
      21 | @(" _message = result.Data.ToString();") 22 |
      23 |

      24 |
      25 |
      26 | 27 |
      28 | 29 | 30 |
      31 | 32 | 33 | 34 | @code { 35 | 36 | string _message; 37 | 38 | async Task ShowModal() 39 | { 40 | var parameters = new ModalParameters(); 41 | parameters.Add(nameof(DisplayMessage.Message), _message); 42 | 43 | var messageForm = Modal.Show("Passing Data", parameters); 44 | var result = await messageForm.Result; 45 | 46 | _message = ""; 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /samples/BlazorServer/Pages/HideCloseButton.razor: -------------------------------------------------------------------------------- 1 | @page "/closebutton" 2 | @inject IModalService Modal 3 | 4 |

      Hiding the modal close button

      5 | 6 |
      7 | 8 |

      9 | By default, a close button is shown in the modal. If you prefer, the button can be hidden and you can handle closing the modal yourself. 10 |

      11 | 12 |
      13 |
      Setting on a per modal basis
      14 |
      15 |

      16 | 17 | @("var options = new ModalOptions() { HideCloseButton = true };") 18 |
      19 | @("Modal.Show(\"Hiding Close Button\", options);") 20 |
      21 |

      22 |
      23 |
      24 | 25 |
      26 |
      Setting globally for all modals
      27 |
      28 |

      29 | 30 | @("") 31 | 32 |

      33 |
      34 |
      35 | 36 | 37 | 38 | 39 | @code { 40 | 41 | void CloseButtonShown() 42 | { 43 | Modal.Show("Showing Close Button (default)"); 44 | } 45 | 46 | void CloseButtonHidden() 47 | { 48 | var options = new ModalOptions { HideCloseButton = true }; 49 | Modal.Show("Hiding Close Button", options); 50 | } 51 | } -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/Pages/HideCloseButton.razor: -------------------------------------------------------------------------------- 1 | @page "/closebutton" 2 | @inject IModalService Modal 3 | 4 |

      Hiding the modal close button

      5 | 6 |
      7 | 8 |

      9 | By default, a close button is shown in the modal. If you prefer, the button can be hidden and you can handle closing the modal yourself. 10 |

      11 | 12 |
      13 |
      Setting on a per modal basis
      14 |
      15 |

      16 | 17 | @("var options = new ModalOptions() { HideCloseButton = true };") 18 |
      19 | @("Modal.Show(\"Hiding Close Button\", options);") 20 |
      21 |

      22 |
      23 |
      24 | 25 |
      26 |
      Setting globally for all modals
      27 |
      28 |

      29 | 30 | @("") 31 | 32 |

      33 |
      34 |
      35 | 36 | 37 | 38 | 39 | @code { 40 | 41 | void CloseButtonShown() 42 | { 43 | Modal.Show("Showing Close Button (default)"); 44 | } 45 | 46 | void CloseButtonHidden() 47 | { 48 | var options = new ModalOptions { HideCloseButton = true }; 49 | Modal.Show("Hiding Close Button", options); 50 | } 51 | } -------------------------------------------------------------------------------- /docs/src/templates/blazored/partials/_head.liquid: -------------------------------------------------------------------------------- 1 | {% comment -%}Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.{% endcomment -%} 2 | 3 | 4 | 5 | {%- if title and _appTitle -%} 6 | {{title}} | {{appTitle}} 7 | 8 | {%- else -%} 9 | {%- if title or _appTitle -%} 10 | {{title}}{{appTitle}} 11 | 12 | {%- endif -%} 13 | {%- endif -%} 14 | 15 | 16 | {%- if _description -%} 17 | 18 | {%- endif -%} 19 | {%- if _appFaviconPath -%} 20 | 21 | {%- else -%} 22 | 23 | {%- endif -%} 24 | 25 | 26 | 27 | 28 | 29 | {%- if _noindex -%} 30 | 31 | {%- endif -%} 32 | {%- if _enableSearch -%} 33 | 34 | {%- endif -%} 35 | {%- if _enableNewTab -%} 36 | 37 | {%- endif -%} 38 | 39 | -------------------------------------------------------------------------------- /samples/BlazorServer/Pages/BackgroundCancel.razor: -------------------------------------------------------------------------------- 1 | @page "/backgroundcancel" 2 | @inject IModalService Modal 3 | 4 |

      Background Click

      5 | 6 |
      7 | 8 |

      9 | By default, a modal is cancelled if the user clicks anywhere outside the modal. This behavior can 10 | be disabled by setting DisableBackgroundCancel to true. 11 |

      12 | 13 |
      14 |
      Setting on a per modal basis
      15 |
      16 |

      17 | 18 | @("var options = new ModalOptions() { DisableBackgroundCancel = true };") 19 |
      20 | @("Modal.Show(\"Background Cancel Disabled\", options);") 21 |
      22 |

      23 |
      24 |
      25 | 26 |
      27 |
      Setting globally for all modals
      28 |
      29 |

      30 | 31 | @("") 32 | 33 |

      34 |
      35 |
      36 | 37 | 38 | 39 | 40 | @code { 41 | 42 | void BackgroundCancelEnabled() 43 | { 44 | Modal.Show("Background Cancel Enabled (Default)"); 45 | } 46 | 47 | void BackgroundCancelDisabled() 48 | { 49 | var options = new ModalOptions { DisableBackgroundCancel = true }; 50 | 51 | Modal.Show("Background Cancel Disabled", options); 52 | } 53 | } -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/Pages/BackGroundCancel.razor: -------------------------------------------------------------------------------- 1 | @page "/backgroundcancel" 2 | @inject IModalService Modal 3 | 4 |

      Background Click

      5 | 6 |
      7 | 8 |

      9 | By default, a modal is cancelled if the user clicks anywhere outside the modal. This behavior can 10 | be disabled by setting DisableBackgroundCancel to true. 11 |

      12 | 13 |
      14 |
      Setting on a per modal basis
      15 |
      16 |

      17 | 18 | @("var options = new ModalOptions() { DisableBackgroundCancel = true };") 19 |
      20 | @("Modal.Show(\"Background Cancel Disabled\", options);") 21 |
      22 |

      23 |
      24 |
      25 | 26 |
      27 |
      Setting globally for all modals
      28 |
      29 |

      30 | 31 | @("") 32 | 33 |

      34 |
      35 |
      36 | 37 | 38 | 39 | 40 | @code { 41 | 42 | void BackgroundCancelEnabled() 43 | { 44 | Modal.Show("Background Cancel Enabled (Default)"); 45 | } 46 | 47 | void BackgroundCancelDisabled() 48 | { 49 | var options = new ModalOptions { DisableBackgroundCancel = true }; 50 | 51 | Modal.Show("Background Cancel Disabled", options); 52 | } 53 | } -------------------------------------------------------------------------------- /docs/src/templates/blazored/layout/_master.tmpl: -------------------------------------------------------------------------------- 1 | {{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} 2 | {{!include(/^styles/.*/)}} 3 | {{!include(/^fonts/.*/)}} 4 | {{!include(favicon.ico)}} 5 | {{!include(logo.svg)}} 6 | {{!include(search-stopwords.json)}} 7 | 8 | 9 | 10 | {{>partials/head}} 11 | 12 |
      13 |
      14 | {{^_disableNavbar}} 15 | {{>partials/navbar}} 16 | {{/_disableNavbar}} 17 |
      18 | {{#_enableSearch}} 19 |
      20 | {{>partials/searchResults}} 21 |
      22 | {{/_enableSearch}} 23 |
      24 | {{^_disableToc}} 25 | {{>partials/toc}} 26 |
      27 | {{/_disableToc}} 28 | {{#_disableToc}} 29 |
      30 | {{/_disableToc}} 31 | {{#_disableAffix}} 32 |
      33 | {{/_disableAffix}} 34 | {{^_disableAffix}} 35 |
      36 | {{/_disableAffix}} 37 |
      38 | {{!body}} 39 |
      40 |
      41 | {{^_disableAffix}} 42 | {{>partials/affix}} 43 | {{/_disableAffix}} 44 |
      45 |
      46 | {{^_disableFooter}} 47 | {{>partials/footer}} 48 | {{/_disableFooter}} 49 |
      50 | {{>partials/scripts}} 51 | 52 | 53 | -------------------------------------------------------------------------------- /docs/src/usage/passing-data-to-modals.md: -------------------------------------------------------------------------------- 1 | # Passing Data To Modals 2 | How to pass data into the component being displayed in the modal. 3 | 4 | --- 5 | 6 | Data can be passed to a component displayed in a modal by using the `ModalParameters` class. Once you create an instance, you can add values to it via the `Add` method which takes two arguments, `parameterName` and `value`. The `parameterName` must match the name of a parameter on the component being displayed in the modal. 7 | 8 | Lets look at an example. 9 | 10 | If we wanted to display a modal containing the following `DisplayMessage` component. 11 | 12 | ```html 13 |
      14 | 15 |

      @Message

      16 | 17 | 18 | 19 |
      20 | 21 | @code { 22 | 23 | [CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; } 24 | 25 | [Parameter] public string Message { get; set; } 26 | 27 | void SubmitForm() => BlazoredModal.Close(); 28 | void Cancel() => BlazoredModal.Close(); 29 | 30 | } 31 | ``` 32 | 33 | We can pass a value for the `Message` parameter like this. 34 | 35 | ```html 36 |
      37 | 38 | 39 |
      40 | 41 | 42 | 43 | @code { 44 | 45 | string _message; 46 | 47 | async Task ShowModal() 48 | { 49 | var parameters = new ModalParameters(); 50 | parameters.Add(nameof(DisplayMessage.Message), _message); 51 | 52 | _ = Modal.Show("Passing Data", parameters); 53 | } 54 | 55 | } 56 | ``` 57 | 58 | **Note:** The use of `nameof` is recommended, where possible, to give a bit of compile time help when referencing parameters on components. -------------------------------------------------------------------------------- /docs/src/usage/multiple-modals.md: -------------------------------------------------------------------------------- 1 | # Multiple Modals 2 | How to show multiple modals at once. 3 | 4 | --- 5 | 6 | It is possible to show multiple modals at the same time. Each new modal needs to be shown from the currently active modal. In this example an inital confirmation modal is shown, if you select *Yes* then a second confirmation modal is shown. When you `Close` the second modal both modals will be closed. If you `Cancel` the second modal, only the second modal will be closed. 7 | 8 | ```html 9 | 10 | 11 | @code { 12 | 13 | void ShowModal() => Modal.Show("First Modal"); 14 | 15 | } 16 | ``` 17 | 18 | ```html 19 |
      20 |

      Are you sure you want to delete the record?

      21 | 22 | 23 | 24 |
      25 | 26 | @code { 27 | 28 | [CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; } 29 | 30 | async Task Yes() 31 | { 32 | var confirmationModal = ModalService.Show("Second Modal"); 33 | var result = await confirmationModal.Result; 34 | 35 | if (result.Cancelled) 36 | return; 37 | 38 | BlazoredModal.Close(); 39 | } 40 | 41 | void No() => BlazoredModal.Cancel(); 42 | 43 | } 44 | ``` 45 | 46 | ```html 47 |
      48 |

      Please click one of the buttons below to close or cancel the modal.

      49 | 50 | 51 | 52 |
      53 | 54 | @code { 55 | 56 | [CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; } 57 | 58 | void Close() => BlazoredModal.Close(ModalResult.Ok(true)); 59 | void Cancel() => BlazoredModal.Close(ModalResult.Cancel()); 60 | 61 | } 62 | ``` -------------------------------------------------------------------------------- /src/Blazored.Modal/wwwroot/blazored-modal.css: -------------------------------------------------------------------------------- 1 | .blazored-modal-container { 2 | display: flex; 3 | position: fixed; 4 | width: 100%; 5 | height: 100%; 6 | z-index: 100; 7 | } 8 | 9 | .blazored-modal-overlay { 10 | display: block; 11 | position: fixed; 12 | width: 100%; 13 | height: 100%; 14 | z-index: 101; 15 | background-color: rgba(0,0,0,0.5); 16 | } 17 | 18 | .blazored-modal { 19 | display: flex; 20 | flex-direction: column; 21 | background-color: #fff; 22 | border-radius: 4px; 23 | border: 1px solid #fff; 24 | padding: 1.5rem; 25 | box-shadow: 0 2px 2px rgba(0,0,0,.25); 26 | } 27 | 28 | .blazored-modal-header { 29 | display: flex; 30 | align-items: flex-start; 31 | justify-content: space-between; 32 | padding: 0 0 2rem 0; 33 | } 34 | 35 | .blazored-modal-title { 36 | margin-bottom: 0; 37 | } 38 | 39 | .blazored-modal-close { 40 | padding: 1rem; 41 | margin: -1rem -1rem -1rem auto; 42 | background-color: transparent; 43 | border: 0; 44 | -webkit-appearance: none; 45 | cursor: pointer; 46 | font-size: 1.5rem; 47 | font-weight: bold; 48 | } 49 | 50 | .blazored-modal-wrapper { 51 | z-index: 102; 52 | } 53 | 54 | .blazored-modal-center { 55 | align-items: center; 56 | justify-content: center; 57 | } 58 | 59 | .blazored-modal-topleft .blazored-modal-wrapper { 60 | position: absolute; 61 | top: 32px; 62 | left: 32px; 63 | } 64 | 65 | .blazored-modal-topright .blazored-modal-wrapper { 66 | position: absolute; 67 | top: 32px; 68 | right: 32px; 69 | } 70 | 71 | .blazored-modal-bottomleft .blazored-modal-wrapper { 72 | position: absolute; 73 | bottom: 32px; 74 | left: 32px; 75 | } 76 | 77 | .blazored-modal-bottomright .blazored-modal-wrapper { 78 | position: absolute; 79 | bottom: 32px; 80 | right: 32px; 81 | } 82 | -------------------------------------------------------------------------------- /samples/BlazorServer/Startup.cs: -------------------------------------------------------------------------------- 1 | using Blazored.Modal; 2 | using Microsoft.AspNetCore.Builder; 3 | using Microsoft.AspNetCore.Hosting; 4 | using Microsoft.Extensions.Configuration; 5 | using Microsoft.Extensions.DependencyInjection; 6 | using Microsoft.Extensions.Hosting; 7 | 8 | namespace BlazorServer 9 | { 10 | public class Startup 11 | { 12 | public Startup(IConfiguration configuration) 13 | { 14 | Configuration = configuration; 15 | } 16 | 17 | public IConfiguration Configuration { get; } 18 | 19 | // This method gets called by the runtime. Use this method to add services to the container. 20 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 21 | public void ConfigureServices(IServiceCollection services) 22 | { 23 | services.AddRazorPages(); 24 | services.AddServerSideBlazor(o => o.DetailedErrors = true); 25 | services.AddBlazoredModal(); 26 | } 27 | 28 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 29 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 30 | { 31 | if (env.IsDevelopment()) 32 | { 33 | app.UseDeveloperExceptionPage(); 34 | } 35 | else 36 | { 37 | app.UseExceptionHandler("/Home/Error"); 38 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 39 | app.UseHsts(); 40 | } 41 | 42 | app.UseHttpsRedirection(); 43 | app.UseStaticFiles(); 44 | 45 | app.UseRouting(); 46 | 47 | app.UseEndpoints(endpoints => 48 | { 49 | endpoints.MapBlazorHub(); 50 | endpoints.MapFallbackToPage("/_Host"); 51 | }); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /samples/BlazorServer/Pages/Position.razor: -------------------------------------------------------------------------------- 1 | @page "/position" 2 | @inject IModalService Modal 3 | 4 |

      Positioning the modal

      5 | 6 |
      7 | 8 |

      9 | By default, the modal is shown in the center of the viewport. The modal can be shown 10 | in a number of different positions by setting the Position option. 11 |

      12 | 13 |
      14 |
      Setting on a per modal basis
      15 |
      16 |

      17 | 18 | @("var options = new ModalOptions() { Position = ModalPosition.TopLeft };") 19 |
      20 | @("Modal.Show(\"Position: TopLeft\", options);") 21 |
      22 |

      23 |
      24 |
      25 | 26 |
      27 |
      Setting globally for all modals
      28 |
      29 |

      30 | 31 | @("") 32 | 33 |

      34 |
      35 |
      36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | @code { 44 | 45 | void PositionCenter() 46 | { 47 | Modal.Show("Centered Modal (Default)"); 48 | } 49 | 50 | void PositionCustom(ModalPosition position) 51 | { 52 | var options = new ModalOptions { Position = position }; 53 | 54 | Modal.Show($"Position: {position}", options); 55 | } 56 | } -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/Pages/Position.razor: -------------------------------------------------------------------------------- 1 | @page "/position" 2 | @inject IModalService Modal 3 | 4 |

      Positioning the modal

      5 | 6 |
      7 | 8 |

      9 | By default, the modal is shown in the center of the viewport. The modal can be shown 10 | in a number of different positions by setting the Position option. 11 |

      12 | 13 |
      14 |
      Setting on a per modal basis
      15 |
      16 |

      17 | 18 | @("var options = new ModalOptions() { Position = ModalPosition.TopLeft };") 19 |
      20 | @("Modal.Show(\"Position: TopLeft\", options);") 21 |
      22 |

      23 |
      24 |
      25 | 26 |
      27 |
      Setting globally for all modals
      28 |
      29 |

      30 | 31 | @("") 32 | 33 |

      34 |
      35 |
      36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | @code { 44 | 45 | void PositionCenter() 46 | { 47 | Modal.Show("Centered Modal (Default)"); 48 | } 49 | 50 | void PositionCustom(ModalPosition position) 51 | { 52 | var options = new ModalOptions { Position = position }; 53 | 54 | Modal.Show($"Position: {position}", options); 55 | } 56 | } -------------------------------------------------------------------------------- /docs/src/templates/blazored/partials/navbar.tmpl.partial: -------------------------------------------------------------------------------- 1 | {{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} 2 | 3 |
      4 |
      5 |
      6 | 12 | {{>partials/logo}} 13 |
      14 |
      15 | 16 | 17 | GitHub 18 | 19 | 20 | 21 | 22 | 23 | Twitter 24 | 25 | 26 | 27 |
      28 |
      29 |
      30 | -------------------------------------------------------------------------------- /docs/src/getting-started/installation.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | How to get up and running with Blazored Modal. 3 | 4 | --- 5 | 6 | ## 1. Installation 7 | You can install the package via the nuget package manager just search for *Blazored.Modal*. You can also install via powershell using the following command. 8 | 9 | ```powershell 10 | Install-Package Blazored.Modal 11 | ``` 12 | 13 | Or via the dotnet CLI. 14 | 15 | ```bash 16 | dotnet add package Blazored.Modal 17 | ``` 18 | 19 | ## 2. Register Services 20 | 21 | ### Blazor Server 22 | You will need to add the following using statement and add a call to register the Blazored Modal services in your applications `Startup.ConfigureServices` method. 23 | 24 | ```csharp 25 | using Blazored.Modal; 26 | 27 | public void ConfigureServices(IServiceCollection services) 28 | { 29 | services.AddBlazoredModal(); 30 | } 31 | ``` 32 | 33 | ### Blazor WebAssembly 34 | You will need to add the following using statement and add a call to register the Blazored Modal services in your applications `Program.Main` method. 35 | 36 | ```csharp 37 | using Blazored.Modal; 38 | 39 | public static async Task Main(string[] args) 40 | { 41 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 42 | builder.RootComponents.Add("app"); 43 | 44 | builder.Services.AddBlazoredModal(); 45 | 46 | await builder.Build().RunAsync(); 47 | } 48 | ``` 49 | 50 | ## 3. Reference Stylesheet 51 | 52 | Add the following line to the `head` tag of your `_Host.cshtml` (Blazor Server) or `index.html` (Blazor WebAssembly). 53 | 54 | ```html 55 | 56 | ``` 57 | 58 | ## 4. Add Component To Layout 59 | 60 | Add the `BlazoredModal` component to your applications `MainLayout.razor`. 61 | 62 | ```html 63 | @inherits LayoutComponentBase 64 | 65 | 66 | 67 | 68 | ``` 69 | 70 | ## 5. Import Namespaces (optional) 71 | 72 | To make life a little easier you can add the following using statements to your root `_Imports.razor`. This save you having to reference the fully qualified name of Blazored Modal components and services in your components. 73 | 74 | ```razor 75 | @using Blazored 76 | @using Blazored.Modal 77 | @using Blazored.Modal.Services 78 | ``` -------------------------------------------------------------------------------- /samples/BlazorServer/Shared/NavMenu.razor: -------------------------------------------------------------------------------- 1 |
      2 | Blazor Server 3 | 6 |
      7 | 8 |
      9 |
        10 |
      • 11 | 12 | Home 13 | 14 | 15 | Styling 16 | 17 | 18 | Close button 19 | 20 | 21 | Background click 22 | 23 | 24 | Position 25 | 26 | 27 | Multiple Modals 28 | 29 | 30 | Passing Data 31 | 32 | 33 | Returning Data 34 | 35 | 36 | Long running task 37 | 38 |
      • 39 |
      40 |
      41 | 42 | @code { 43 | bool collapseNavMenu = true; 44 | 45 | string NavMenuCssClass => collapseNavMenu ? "collapse" : null; 46 | 47 | void ToggleNavMenu() 48 | { 49 | collapseNavMenu = !collapseNavMenu; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/Shared/NavMenu.razor: -------------------------------------------------------------------------------- 1 |
      2 | Blazor Server 3 | 6 |
      7 | 8 |
      9 |
        10 |
      • 11 | 12 | Home 13 | 14 | 15 | Styling 16 | 17 | 18 | Close button 19 | 20 | 21 | Background click 22 | 23 | 24 | Position 25 | 26 | 27 | Multiple Modals 28 | 29 | 30 | Passing Data 31 | 32 | 33 | Returning Data 34 | 35 | 36 | Long running task 37 | 38 |
      • 39 |
      40 |
      41 | 42 | @code { 43 | bool collapseNavMenu = true; 44 | 45 | string NavMenuCssClass => collapseNavMenu ? "collapse" : null; 46 | 47 | void ToggleNavMenu() 48 | { 49 | collapseNavMenu = !collapseNavMenu; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /samples/BlazorServer/Pages/LongRunningTask.razor: -------------------------------------------------------------------------------- 1 | @page "/longrunningtask" 2 | @inject IModalService Modal 3 | 4 |

      Closing Modal after long-running task

      5 | 6 |
      7 | 8 |

      9 | A long-running task can be executed and a modal can be closed programatically after it. 10 |

      11 | 12 |
      13 |
      14 |

      15 | 16 | @("var loading = Modal.Show();")
      17 | @("await Task.Delay(5000);")
      18 |
      19 | @("loading.Close();")
      20 |
      21 |

      22 |
      23 |
      24 | 25 |

      Result: @_result;

      26 | 27 | 28 | 29 | 30 | 31 | 32 | @code { 33 | 34 | string _result; 35 | 36 | async Task ShowModal() 37 | { 38 | var options = new ModalOptions 39 | { 40 | HideCloseButton = false, 41 | DisableBackgroundCancel = true, 42 | HideHeader = true 43 | }; 44 | var loading = Modal.Show(string.Empty, options); 45 | 46 | await Task.Delay(5000); 47 | 48 | loading.Close(); 49 | var result = await loading.Result; 50 | if (result.Data == null && result.DataType == typeof(object)) 51 | _result = "Modal returned with default ModalResult"; 52 | 53 | StateHasChanged(); 54 | } 55 | 56 | async Task ShowOkResultModal() 57 | { 58 | var options = new ModalOptions 59 | { 60 | HideCloseButton = false, 61 | DisableBackgroundCancel = true, 62 | HideHeader = true 63 | }; 64 | var loading = Modal.Show(string.Empty, options); 65 | 66 | await Task.Delay(5000); 67 | 68 | loading.Close(ModalResult.Ok("Closed with OK result")); 69 | var result = await loading.Result; 70 | if (result.DataType == typeof(string)) 71 | _result = result.Data.ToString(); 72 | 73 | StateHasChanged(); 74 | } 75 | 76 | async Task ShowCancelModal() 77 | { 78 | var options = new ModalOptions 79 | { 80 | HideCloseButton = false, 81 | DisableBackgroundCancel = true, 82 | HideHeader = true 83 | }; 84 | var loading = Modal.Show(string.Empty, options); 85 | 86 | await Task.Delay(5000); 87 | 88 | loading.Close(ModalResult.Cancel()); 89 | var result = await loading.Result; 90 | if (result.Cancelled) 91 | _result = "Closed with Cancelled result"; 92 | 93 | StateHasChanged(); 94 | } 95 | 96 | } -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/Pages/LongRunningTask.razor: -------------------------------------------------------------------------------- 1 | @page "/longrunningtask" 2 | @inject IModalService Modal 3 | 4 |

      Closing Modal after long-running task

      5 | 6 |
      7 | 8 |

      9 | A long-running task can be executed and a modal can be closed programatically after it. 10 |

      11 | 12 |
      13 |
      14 |

      15 | 16 | @("var loading = Modal.Show();")
      17 | @("await Task.Delay(5000);")
      18 |
      19 | @("loading.Close();")
      20 |
      21 |

      22 |
      23 |
      24 | 25 |

      Result: @_result;

      26 | 27 | 28 | 29 | 30 | 31 | 32 | @code { 33 | 34 | string _result; 35 | 36 | async Task ShowModal() 37 | { 38 | var options = new ModalOptions 39 | { 40 | HideCloseButton = false, 41 | DisableBackgroundCancel = true, 42 | HideHeader = true 43 | }; 44 | var loading = Modal.Show(string.Empty, options); 45 | 46 | await Task.Delay(5000); 47 | 48 | loading.Close(); 49 | var result = await loading.Result; 50 | if (result.Data == null && result.DataType == typeof(object)) 51 | _result = "Modal returned with default ModalResult"; 52 | 53 | StateHasChanged(); 54 | } 55 | 56 | async Task ShowOkResultModal() 57 | { 58 | var options = new ModalOptions 59 | { 60 | HideCloseButton = false, 61 | DisableBackgroundCancel = true, 62 | HideHeader = true 63 | }; 64 | var loading = Modal.Show(string.Empty, options); 65 | 66 | await Task.Delay(5000); 67 | 68 | loading.Close(ModalResult.Ok("Closed with OK result")); 69 | var result = await loading.Result; 70 | if (result.DataType == typeof(string)) 71 | _result = result.Data.ToString(); 72 | 73 | StateHasChanged(); 74 | } 75 | 76 | async Task ShowCancelModal() 77 | { 78 | var options = new ModalOptions 79 | { 80 | HideCloseButton = false, 81 | DisableBackgroundCancel = true, 82 | HideHeader = true 83 | }; 84 | var loading = Modal.Show(string.Empty, options); 85 | 86 | await Task.Delay(5000); 87 | 88 | loading.Close(ModalResult.Cancel()); 89 | var result = await loading.Result; 90 | if (result.Cancelled) 91 | _result = "Closed with Cancelled result"; 92 | 93 | StateHasChanged(); 94 | } 95 | 96 | } -------------------------------------------------------------------------------- /tests/src/Blazored.Modal.Tests/DisplayTests.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using Bunit; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Microsoft.AspNetCore.Components; 5 | using Blazored.Modal.Tests.Assets; 6 | using Blazored.Modal.Services; 7 | 8 | namespace Blazored.Modal.Tests 9 | { 10 | public class DisplayTests : ComponentTestFixture 11 | { 12 | public DisplayTests() 13 | { 14 | Services.AddScoped(); 15 | Services.AddBlazoredModal(); 16 | } 17 | 18 | [Fact] 19 | public void ModalIsNotVisibleByDefault() 20 | { 21 | // Arrange / Act 22 | var cut = RenderComponent(); 23 | 24 | // Assert 25 | Assert.Empty(cut.FindAll(".blazored-modal-container")); 26 | } 27 | 28 | [Fact] 29 | public void ModalIsVisibleWhenShowCalled() 30 | { 31 | // Arrange 32 | var modalService = Services.GetService(); 33 | var cut = RenderComponent(); 34 | 35 | // Act 36 | modalService.Show(); 37 | 38 | // Assert 39 | Assert.Equal(1, cut.FindAll(".blazored-modal-container").Count); 40 | } 41 | 42 | [Fact] 43 | public void MultipleModalsAreVisibleWhenShowCalledMultipleTimes() 44 | { 45 | // Arrange 46 | var modalService = Services.GetService(); 47 | var cut = RenderComponent(); 48 | 49 | // Act 50 | modalService.Show(); 51 | modalService.Show(); 52 | 53 | // Assert 54 | Assert.Equal(2, cut.FindAll(".blazored-modal-container").Count); 55 | } 56 | 57 | [Fact] 58 | public void ModalHidesWhenCloseCalled() 59 | { 60 | // Arrange 61 | var modalService = Services.GetService(); 62 | var cut = RenderComponent(); 63 | 64 | // Act 65 | modalService.Show(); 66 | Assert.Equal(1, cut.FindAll(".blazored-modal-container").Count); 67 | 68 | var closeButton = cut.Find(".test-component__close-button"); 69 | closeButton.Click(); 70 | 71 | // Assert 72 | Assert.Empty(cut.FindAll(".blazored-modal-container")); 73 | } 74 | 75 | [Fact] 76 | public void ModalHidesWhenCancelCalled() 77 | { 78 | // Arrange 79 | var modalService = Services.GetService(); 80 | var cut = RenderComponent(); 81 | 82 | // Act 83 | modalService.Show(); 84 | Assert.Equal(1, cut.FindAll(".blazored-modal-container").Count); 85 | 86 | var closeButton = cut.Find(".blazored-modal-close"); 87 | closeButton.Click(); 88 | 89 | // Assert 90 | Assert.Empty(cut.FindAll(".blazored-modal-container")); 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /src/Blazored.Modal/BlazoredModal.razor.cs: -------------------------------------------------------------------------------- 1 | using Blazored.Modal.Services; 2 | using Microsoft.AspNetCore.Components; 3 | using Microsoft.AspNetCore.Components.Routing; 4 | using System; 5 | using System.Collections.ObjectModel; 6 | using System.Linq; 7 | 8 | namespace Blazored.Modal 9 | { 10 | public partial class BlazoredModal 11 | { 12 | [Inject] private IModalService ModalService { get; set; } 13 | [Inject] private NavigationManager NavigationManager { get; set; } 14 | 15 | [Parameter] public bool? HideHeader { get; set; } 16 | [Parameter] public bool? HideCloseButton { get; set; } 17 | [Parameter] public bool? DisableBackgroundCancel { get; set; } 18 | [Parameter] public ModalPosition? Position { get; set; } 19 | [Parameter] public string Class { get; set; } 20 | 21 | private readonly Collection Modals = new Collection(); 22 | private readonly ModalOptions GlobalModalOptions = new ModalOptions(); 23 | 24 | protected override void OnInitialized() 25 | { 26 | ((ModalService)ModalService).OnModalInstanceAdded += Update; 27 | ((ModalService) ModalService).OnModalCloseRequested += CloseInstance; 28 | NavigationManager.LocationChanged += CancelModals; 29 | 30 | GlobalModalOptions.Class = Class; 31 | GlobalModalOptions.DisableBackgroundCancel = DisableBackgroundCancel; 32 | GlobalModalOptions.HideCloseButton = HideCloseButton; 33 | GlobalModalOptions.HideHeader = HideHeader; 34 | GlobalModalOptions.Position = Position; 35 | } 36 | 37 | internal void CloseInstance(ModalReference modal, ModalResult result) 38 | { 39 | DismissInstance(modal.Id, result); 40 | } 41 | 42 | internal void CloseInstance(Guid Id) 43 | { 44 | DismissInstance(Id, ModalResult.Ok(null)); 45 | } 46 | 47 | internal void CancelInstance(Guid Id) 48 | { 49 | DismissInstance(Id, ModalResult.Cancel()); 50 | } 51 | 52 | internal void DismissInstance(Guid Id, ModalResult result) 53 | { 54 | var reference = Modals.SingleOrDefault(x => x.Id == Id); 55 | 56 | if (reference != null) 57 | { 58 | reference.Dismiss(result); 59 | Modals.Remove(reference); 60 | StateHasChanged(); 61 | } 62 | } 63 | 64 | private async void CancelModals(object sender, LocationChangedEventArgs e) 65 | { 66 | foreach (var modalReference in Modals) 67 | { 68 | modalReference.Dismiss(ModalResult.Cancel()); 69 | } 70 | 71 | Modals.Clear(); 72 | await InvokeAsync(StateHasChanged); 73 | } 74 | 75 | private async void Update(ModalReference modalReference) 76 | { 77 | Modals.Add(modalReference); 78 | await InvokeAsync(StateHasChanged); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | @import url('open-iconic/font/css/open-iconic-bootstrap.min.css'); 2 | 3 | html, body { 4 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 5 | } 6 | 7 | app { 8 | position: relative; 9 | display: flex; 10 | flex-direction: column; 11 | } 12 | 13 | .top-row { 14 | height: 3.5rem; 15 | display: flex; 16 | align-items: center; 17 | } 18 | 19 | .main { 20 | flex: 1; 21 | } 22 | 23 | .main .top-row { 24 | background-color: #e6e6e6; 25 | border-bottom: 1px solid #d6d5d5; 26 | } 27 | 28 | .sidebar { 29 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); 30 | } 31 | 32 | .sidebar .top-row { 33 | background-color: rgba(0,0,0,0.4); 34 | } 35 | 36 | .sidebar .navbar-brand { 37 | font-size: 1.1rem; 38 | } 39 | 40 | .sidebar .oi { 41 | width: 2rem; 42 | font-size: 1.1rem; 43 | vertical-align: text-top; 44 | top: -2px; 45 | } 46 | 47 | .nav-item { 48 | font-size: 0.9rem; 49 | padding-bottom: 0.5rem; 50 | } 51 | 52 | .nav-item:first-of-type { 53 | padding-top: 1rem; 54 | } 55 | 56 | .nav-item:last-of-type { 57 | padding-bottom: 1rem; 58 | } 59 | 60 | .nav-item a { 61 | color: #d7d7d7; 62 | border-radius: 4px; 63 | height: 3rem; 64 | display: flex; 65 | align-items: center; 66 | line-height: 3rem; 67 | } 68 | 69 | .nav-item a.active { 70 | background-color: rgba(255,255,255,0.25); 71 | color: white; 72 | } 73 | 74 | .nav-item a:hover { 75 | background-color: rgba(255,255,255,0.1); 76 | color: white; 77 | } 78 | 79 | .content { 80 | padding-top: 1.1rem; 81 | } 82 | 83 | .navbar-toggler { 84 | background-color: rgba(255, 255, 255, 0.1); 85 | } 86 | 87 | @media (max-width: 767.98px) { 88 | .main .top-row { 89 | display: none; 90 | } 91 | } 92 | 93 | @media (min-width: 768px) { 94 | app { 95 | flex-direction: row; 96 | } 97 | 98 | .sidebar { 99 | width: 250px; 100 | height: 100vh; 101 | position: sticky; 102 | top: 0; 103 | } 104 | 105 | .main .top-row { 106 | position: sticky; 107 | top: 0; 108 | } 109 | 110 | .main > div { 111 | padding-left: 2rem !important; 112 | padding-right: 1.5rem !important; 113 | } 114 | 115 | .navbar-toggler { 116 | display: none; 117 | } 118 | 119 | .sidebar .collapse { 120 | /* Never collapse the sidebar for wide screens */ 121 | display: block; 122 | } 123 | } 124 | 125 | .blazored-custom-modal { 126 | display: flex; 127 | flex-direction: column; 128 | width: 60vw; 129 | height: 60vh; 130 | background-color: #fafafa; 131 | border-radius: 12px; 132 | border: 1px solid #fff; 133 | padding: 0.5rem; 134 | z-index: 102; 135 | box-shadow: 0 2px 2px rgba(0,0,0,.75); 136 | } 137 | 138 | .blazored-prompt-modal { 139 | display: flex; 140 | flex-direction: column; 141 | width: 600px; 142 | background-color: #fefefe; 143 | border-radius: 4px; 144 | border: 1px solid #fff; 145 | padding: 0.5rem; 146 | z-index: 102; 147 | box-shadow: 0 2px 2px rgba(0,0,0,.75); 148 | } 149 | 150 | .blazored-prompt-modal .blazored-modal-header { 151 | display: none; 152 | } -------------------------------------------------------------------------------- /samples/BlazorServer/Shared/Loading.razor: -------------------------------------------------------------------------------- 1 | 107 | 108 |
      109 |
      110 |
      111 | 112 | @code { 113 | 114 | [CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; } 115 | } 116 | -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/Shared/Loading.razor: -------------------------------------------------------------------------------- 1 | 107 | 108 |
      109 |
      110 |
      111 | 112 | @code { 113 | 114 | [CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; } 115 | } 116 | -------------------------------------------------------------------------------- /samples/BlazorServer/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | @import url('open-iconic/font/css/open-iconic-bootstrap.min.css'); 2 | 3 | html, body { 4 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 5 | } 6 | 7 | a { 8 | color: #0366d6; 9 | } 10 | 11 | .btn-primary { 12 | color: #fff; 13 | background-color: #1b6ec2; 14 | border-color: #1861ac; 15 | } 16 | 17 | app { 18 | position: relative; 19 | display: flex; 20 | flex-direction: column; 21 | } 22 | 23 | .top-row { 24 | height: 3.5rem; 25 | display: flex; 26 | align-items: center; 27 | } 28 | 29 | .main { 30 | flex: 1; 31 | } 32 | 33 | .main .top-row { 34 | background-color: #f7f7f7; 35 | border-bottom: 1px solid #d6d5d5; 36 | justify-content: flex-end; 37 | } 38 | 39 | .main .top-row > a { 40 | margin-left: 1.5rem; 41 | } 42 | 43 | .sidebar { 44 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); 45 | } 46 | 47 | .sidebar .top-row { 48 | background-color: rgba(0,0,0,0.4); 49 | } 50 | 51 | .sidebar .navbar-brand { 52 | font-size: 1.1rem; 53 | } 54 | 55 | .sidebar .oi { 56 | width: 2rem; 57 | font-size: 1.1rem; 58 | vertical-align: text-top; 59 | top: -2px; 60 | } 61 | 62 | .nav-item { 63 | font-size: 0.9rem; 64 | padding-bottom: 0.5rem; 65 | } 66 | 67 | .nav-item:first-of-type { 68 | padding-top: 1rem; 69 | } 70 | 71 | .nav-item:last-of-type { 72 | padding-bottom: 1rem; 73 | } 74 | 75 | .nav-item a { 76 | color: #d7d7d7; 77 | border-radius: 4px; 78 | height: 3rem; 79 | display: flex; 80 | align-items: center; 81 | line-height: 3rem; 82 | } 83 | 84 | .nav-item a.active { 85 | background-color: rgba(255,255,255,0.25); 86 | color: white; 87 | } 88 | 89 | .nav-item a:hover { 90 | background-color: rgba(255,255,255,0.1); 91 | color: white; 92 | } 93 | 94 | .content { 95 | padding-top: 1.1rem; 96 | } 97 | 98 | .navbar-toggler { 99 | background-color: rgba(255, 255, 255, 0.1); 100 | } 101 | 102 | .valid.modified:not([type=checkbox]) { 103 | outline: 1px solid #26b050; 104 | } 105 | 106 | .invalid { 107 | outline: 1px solid red; 108 | } 109 | 110 | .validation-message { 111 | color: red; 112 | } 113 | 114 | @media (max-width: 767.98px) { 115 | .main .top-row { 116 | display: none; 117 | } 118 | } 119 | 120 | @media (min-width: 768px) { 121 | app { 122 | flex-direction: row; 123 | } 124 | 125 | .sidebar { 126 | width: 250px; 127 | height: 100vh; 128 | position: sticky; 129 | top: 0; 130 | } 131 | 132 | .main .top-row { 133 | position: sticky; 134 | top: 0; 135 | } 136 | 137 | .main > div { 138 | padding-left: 2rem !important; 139 | padding-right: 1.5rem !important; 140 | } 141 | 142 | .navbar-toggler { 143 | display: none; 144 | } 145 | 146 | .sidebar .collapse { 147 | /* Never collapse the sidebar for wide screens */ 148 | display: block; 149 | } 150 | } 151 | 152 | .blazored-custom-modal { 153 | display: flex; 154 | flex-direction: column; 155 | width: 60vw; 156 | height: 60vh; 157 | background-color: #fafafa; 158 | border-radius: 12px; 159 | border: 1px solid #fff; 160 | padding: 0.5rem; 161 | z-index: 102; 162 | box-shadow: 0 2px 2px rgba(0,0,0,.75); 163 | } 164 | 165 | .blazored-prompt-modal { 166 | display: flex; 167 | flex-direction: column; 168 | width: 600px; 169 | background-color: #fefefe; 170 | border-radius: 4px; 171 | border: 1px solid #fff; 172 | padding: 0.5rem; 173 | z-index: 102; 174 | box-shadow: 0 2px 2px rgba(0,0,0,.75); 175 | } 176 | 177 | .blazored-prompt-modal .blazored-modal-header { 178 | display: none; 179 | } -------------------------------------------------------------------------------- /samples/BlazorServer/wwwroot/css/open-iconic/README.md: -------------------------------------------------------------------------------- 1 | [Open Iconic v1.1.1](http://useiconic.com/open) 2 | =========== 3 | 4 | ### Open Iconic is the open source sibling of [Iconic](http://useiconic.com). It is a hyper-legible collection of 223 icons with a tiny footprint—ready to use with Bootstrap and Foundation. [View the collection](http://useiconic.com/open#icons) 5 | 6 | 7 | 8 | ## What's in Open Iconic? 9 | 10 | * 223 icons designed to be legible down to 8 pixels 11 | * Super-light SVG files - 61.8 for the entire set 12 | * SVG sprite—the modern replacement for icon fonts 13 | * Webfont (EOT, OTF, SVG, TTF, WOFF), PNG and WebP formats 14 | * Webfont stylesheets (including versions for Bootstrap and Foundation) in CSS, LESS, SCSS and Stylus formats 15 | * PNG and WebP raster images in 8px, 16px, 24px, 32px, 48px and 64px. 16 | 17 | 18 | ## Getting Started 19 | 20 | #### For code samples and everything else you need to get started with Open Iconic, check out our [Icons](http://useiconic.com/open#icons) and [Reference](http://useiconic.com/open#reference) sections. 21 | 22 | ### General Usage 23 | 24 | #### Using Open Iconic's SVGs 25 | 26 | We like SVGs and we think they're the way to display icons on the web. Since Open Iconic are just basic SVGs, we suggest you display them like you would any other image (don't forget the `alt` attribute). 27 | 28 | ``` 29 | icon name 30 | ``` 31 | 32 | #### Using Open Iconic's SVG Sprite 33 | 34 | Open Iconic also comes in a SVG sprite which allows you to display all the icons in the set with a single request. It's like an icon font, without being a hack. 35 | 36 | Adding an icon from an SVG sprite is a little different than what you're used to, but it's still a piece of cake. *Tip: To make your icons easily style able, we suggest adding a general class to the* `` *tag and a unique class name for each different icon in the* `` *tag.* 37 | 38 | ``` 39 | 40 | 41 | 42 | ``` 43 | 44 | Sizing icons only needs basic CSS. All the icons are in a square format, so just set the `` tag with equal width and height dimensions. 45 | 46 | ``` 47 | .icon { 48 | width: 16px; 49 | height: 16px; 50 | } 51 | ``` 52 | 53 | Coloring icons is even easier. All you need to do is set the `fill` rule on the `` tag. 54 | 55 | ``` 56 | .icon-account-login { 57 | fill: #f00; 58 | } 59 | ``` 60 | 61 | To learn more about SVG Sprites, read [Chris Coyier's guide](http://css-tricks.com/svg-sprites-use-better-icon-fonts/). 62 | 63 | #### Using Open Iconic's Icon Font... 64 | 65 | 66 | ##### …with Bootstrap 67 | 68 | You can find our Bootstrap stylesheets in `font/css/open-iconic-bootstrap.{css, less, scss, styl}` 69 | 70 | 71 | ``` 72 | 73 | ``` 74 | 75 | 76 | ``` 77 | 78 | ``` 79 | 80 | ##### …with Foundation 81 | 82 | You can find our Foundation stylesheets in `font/css/open-iconic-foundation.{css, less, scss, styl}` 83 | 84 | ``` 85 | 86 | ``` 87 | 88 | 89 | ``` 90 | 91 | ``` 92 | 93 | ##### …on its own 94 | 95 | You can find our default stylesheets in `font/css/open-iconic.{css, less, scss, styl}` 96 | 97 | ``` 98 | 99 | ``` 100 | 101 | ``` 102 | 103 | ``` 104 | 105 | 106 | ## License 107 | 108 | ### Icons 109 | 110 | All code (including SVG markup) is under the [MIT License](http://opensource.org/licenses/MIT). 111 | 112 | ### Fonts 113 | 114 | All fonts are under the [SIL Licensed](http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web). 115 | -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/wwwroot/css/open-iconic/README.md: -------------------------------------------------------------------------------- 1 | [Open Iconic v1.1.1](http://useiconic.com/open) 2 | =========== 3 | 4 | ### Open Iconic is the open source sibling of [Iconic](http://useiconic.com). It is a hyper-legible collection of 223 icons with a tiny footprint—ready to use with Bootstrap and Foundation. [View the collection](http://useiconic.com/open#icons) 5 | 6 | 7 | 8 | ## What's in Open Iconic? 9 | 10 | * 223 icons designed to be legible down to 8 pixels 11 | * Super-light SVG files - 61.8 for the entire set 12 | * SVG sprite—the modern replacement for icon fonts 13 | * Webfont (EOT, OTF, SVG, TTF, WOFF), PNG and WebP formats 14 | * Webfont stylesheets (including versions for Bootstrap and Foundation) in CSS, LESS, SCSS and Stylus formats 15 | * PNG and WebP raster images in 8px, 16px, 24px, 32px, 48px and 64px. 16 | 17 | 18 | ## Getting Started 19 | 20 | #### For code samples and everything else you need to get started with Open Iconic, check out our [Icons](http://useiconic.com/open#icons) and [Reference](http://useiconic.com/open#reference) sections. 21 | 22 | ### General Usage 23 | 24 | #### Using Open Iconic's SVGs 25 | 26 | We like SVGs and we think they're the way to display icons on the web. Since Open Iconic are just basic SVGs, we suggest you display them like you would any other image (don't forget the `alt` attribute). 27 | 28 | ``` 29 | icon name 30 | ``` 31 | 32 | #### Using Open Iconic's SVG Sprite 33 | 34 | Open Iconic also comes in a SVG sprite which allows you to display all the icons in the set with a single request. It's like an icon font, without being a hack. 35 | 36 | Adding an icon from an SVG sprite is a little different than what you're used to, but it's still a piece of cake. *Tip: To make your icons easily style able, we suggest adding a general class to the* `` *tag and a unique class name for each different icon in the* `` *tag.* 37 | 38 | ``` 39 | 40 | 41 | 42 | ``` 43 | 44 | Sizing icons only needs basic CSS. All the icons are in a square format, so just set the `` tag with equal width and height dimensions. 45 | 46 | ``` 47 | .icon { 48 | width: 16px; 49 | height: 16px; 50 | } 51 | ``` 52 | 53 | Coloring icons is even easier. All you need to do is set the `fill` rule on the `` tag. 54 | 55 | ``` 56 | .icon-account-login { 57 | fill: #f00; 58 | } 59 | ``` 60 | 61 | To learn more about SVG Sprites, read [Chris Coyier's guide](http://css-tricks.com/svg-sprites-use-better-icon-fonts/). 62 | 63 | #### Using Open Iconic's Icon Font... 64 | 65 | 66 | ##### …with Bootstrap 67 | 68 | You can find our Bootstrap stylesheets in `font/css/open-iconic-bootstrap.{css, less, scss, styl}` 69 | 70 | 71 | ``` 72 | 73 | ``` 74 | 75 | 76 | ``` 77 | 78 | ``` 79 | 80 | ##### …with Foundation 81 | 82 | You can find our Foundation stylesheets in `font/css/open-iconic-foundation.{css, less, scss, styl}` 83 | 84 | ``` 85 | 86 | ``` 87 | 88 | 89 | ``` 90 | 91 | ``` 92 | 93 | ##### …on its own 94 | 95 | You can find our default stylesheets in `font/css/open-iconic.{css, less, scss, styl}` 96 | 97 | ``` 98 | 99 | ``` 100 | 101 | ``` 102 | 103 | ``` 104 | 105 | 106 | ## License 107 | 108 | ### Icons 109 | 110 | All code (including SVG markup) is under the [MIT License](http://opensource.org/licenses/MIT). 111 | 112 | ### Fonts 113 | 114 | All fonts are under the [SIL Licensed](http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web). 115 | -------------------------------------------------------------------------------- /samples/BlazorServer/wwwroot/css/open-iconic/FONT-LICENSE: -------------------------------------------------------------------------------- 1 | SIL OPEN FONT LICENSE Version 1.1 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | PREAMBLE 6 | The goals of the Open Font License (OFL) are to stimulate worldwide 7 | development of collaborative font projects, to support the font creation 8 | efforts of academic and linguistic communities, and to provide a free and 9 | open framework in which fonts may be shared and improved in partnership 10 | with others. 11 | 12 | The OFL allows the licensed fonts to be used, studied, modified and 13 | redistributed freely as long as they are not sold by themselves. The 14 | fonts, including any derivative works, can be bundled, embedded, 15 | redistributed and/or sold with any software provided that any reserved 16 | names are not used by derivative works. The fonts and derivatives, 17 | however, cannot be released under any other type of license. The 18 | requirement for fonts to remain under this license does not apply 19 | to any document created using the fonts or their derivatives. 20 | 21 | DEFINITIONS 22 | "Font Software" refers to the set of files released by the Copyright 23 | Holder(s) under this license and clearly marked as such. This may 24 | include source files, build scripts and documentation. 25 | 26 | "Reserved Font Name" refers to any names specified as such after the 27 | copyright statement(s). 28 | 29 | "Original Version" refers to the collection of Font Software components as 30 | distributed by the Copyright Holder(s). 31 | 32 | "Modified Version" refers to any derivative made by adding to, deleting, 33 | or substituting -- in part or in whole -- any of the components of the 34 | Original Version, by changing formats or by porting the Font Software to a 35 | new environment. 36 | 37 | "Author" refers to any designer, engineer, programmer, technical 38 | writer or other person who contributed to the Font Software. 39 | 40 | PERMISSION & CONDITIONS 41 | Permission is hereby granted, free of charge, to any person obtaining 42 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 43 | redistribute, and sell modified and unmodified copies of the Font 44 | Software, subject to the following conditions: 45 | 46 | 1) Neither the Font Software nor any of its individual components, 47 | in Original or Modified Versions, may be sold by itself. 48 | 49 | 2) Original or Modified Versions of the Font Software may be bundled, 50 | redistributed and/or sold with any software, provided that each copy 51 | contains the above copyright notice and this license. These can be 52 | included either as stand-alone text files, human-readable headers or 53 | in the appropriate machine-readable metadata fields within text or 54 | binary files as long as those fields can be easily viewed by the user. 55 | 56 | 3) No Modified Version of the Font Software may use the Reserved Font 57 | Name(s) unless explicit written permission is granted by the corresponding 58 | Copyright Holder. This restriction only applies to the primary font name as 59 | presented to the users. 60 | 61 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 62 | Software shall not be used to promote, endorse or advertise any 63 | Modified Version, except to acknowledge the contribution(s) of the 64 | Copyright Holder(s) and the Author(s) or with their explicit written 65 | permission. 66 | 67 | 5) The Font Software, modified or unmodified, in part or in whole, 68 | must be distributed entirely under this license, and must not be 69 | distributed under any other license. The requirement for fonts to 70 | remain under this license does not apply to any document created 71 | using the Font Software. 72 | 73 | TERMINATION 74 | This license becomes null and void if any of the above conditions are 75 | not met. 76 | 77 | DISCLAIMER 78 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 79 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 80 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 81 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 82 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 83 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 84 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 85 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 86 | OTHER DEALINGS IN THE FONT SOFTWARE. 87 | -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/wwwroot/css/open-iconic/FONT-LICENSE: -------------------------------------------------------------------------------- 1 | SIL OPEN FONT LICENSE Version 1.1 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | PREAMBLE 6 | The goals of the Open Font License (OFL) are to stimulate worldwide 7 | development of collaborative font projects, to support the font creation 8 | efforts of academic and linguistic communities, and to provide a free and 9 | open framework in which fonts may be shared and improved in partnership 10 | with others. 11 | 12 | The OFL allows the licensed fonts to be used, studied, modified and 13 | redistributed freely as long as they are not sold by themselves. The 14 | fonts, including any derivative works, can be bundled, embedded, 15 | redistributed and/or sold with any software provided that any reserved 16 | names are not used by derivative works. The fonts and derivatives, 17 | however, cannot be released under any other type of license. The 18 | requirement for fonts to remain under this license does not apply 19 | to any document created using the fonts or their derivatives. 20 | 21 | DEFINITIONS 22 | "Font Software" refers to the set of files released by the Copyright 23 | Holder(s) under this license and clearly marked as such. This may 24 | include source files, build scripts and documentation. 25 | 26 | "Reserved Font Name" refers to any names specified as such after the 27 | copyright statement(s). 28 | 29 | "Original Version" refers to the collection of Font Software components as 30 | distributed by the Copyright Holder(s). 31 | 32 | "Modified Version" refers to any derivative made by adding to, deleting, 33 | or substituting -- in part or in whole -- any of the components of the 34 | Original Version, by changing formats or by porting the Font Software to a 35 | new environment. 36 | 37 | "Author" refers to any designer, engineer, programmer, technical 38 | writer or other person who contributed to the Font Software. 39 | 40 | PERMISSION & CONDITIONS 41 | Permission is hereby granted, free of charge, to any person obtaining 42 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 43 | redistribute, and sell modified and unmodified copies of the Font 44 | Software, subject to the following conditions: 45 | 46 | 1) Neither the Font Software nor any of its individual components, 47 | in Original or Modified Versions, may be sold by itself. 48 | 49 | 2) Original or Modified Versions of the Font Software may be bundled, 50 | redistributed and/or sold with any software, provided that each copy 51 | contains the above copyright notice and this license. These can be 52 | included either as stand-alone text files, human-readable headers or 53 | in the appropriate machine-readable metadata fields within text or 54 | binary files as long as those fields can be easily viewed by the user. 55 | 56 | 3) No Modified Version of the Font Software may use the Reserved Font 57 | Name(s) unless explicit written permission is granted by the corresponding 58 | Copyright Holder. This restriction only applies to the primary font name as 59 | presented to the users. 60 | 61 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 62 | Software shall not be used to promote, endorse or advertise any 63 | Modified Version, except to acknowledge the contribution(s) of the 64 | Copyright Holder(s) and the Author(s) or with their explicit written 65 | permission. 66 | 67 | 5) The Font Software, modified or unmodified, in part or in whole, 68 | must be distributed entirely under this license, and must not be 69 | distributed under any other license. The requirement for fonts to 70 | remain under this license does not apply to any document created 71 | using the Font Software. 72 | 73 | TERMINATION 74 | This license becomes null and void if any of the above conditions are 75 | not met. 76 | 77 | DISCLAIMER 78 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 79 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 80 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 81 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 82 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 83 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 84 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 85 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 86 | OTHER DEALINGS IN THE FONT SOFTWARE. 87 | -------------------------------------------------------------------------------- /src/Blazored.Modal/Services/IModalService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.AspNetCore.Components; 3 | 4 | namespace Blazored.Modal.Services 5 | { 6 | public interface IModalService 7 | { 8 | /// 9 | /// Shows a modal containing the specified . 10 | /// 11 | ModalReference Show() where TComponent : ComponentBase; 12 | 13 | /// 14 | /// Shows a modal containing a with the specified . 15 | /// 16 | /// Modal title 17 | ModalReference Show(string title) where TComponent : ComponentBase; 18 | 19 | /// 20 | /// Shows a modal containing a with the specified and . 21 | /// 22 | /// Modal title 23 | /// Options to configure the modal 24 | ModalReference Show(string title, ModalOptions options) where TComponent : ComponentBase; 25 | 26 | /// 27 | /// Shows a modal containing a with the specified and . 28 | /// 29 | /// Modal title 30 | /// Key/Value collection of parameters to pass to component being displayed 31 | ModalReference Show(string title, ModalParameters parameters) where TComponent : ComponentBase; 32 | 33 | /// 34 | /// Shows a modal containing a with the specified , 35 | /// and . 36 | /// 37 | /// Modal title. 38 | /// Key/Value collection of parameters to pass to component being displayed. 39 | /// Options to configure the modal. 40 | ModalReference Show(string title, ModalParameters parameters = null, ModalOptions options = null) where TComponent : ComponentBase; 41 | 42 | /// 43 | /// Shows a modal containing a . 44 | /// 45 | /// Type of component to display. 46 | ModalReference Show(Type component); 47 | 48 | /// 49 | /// Shows a modal containing a with the specified . 50 | /// 51 | /// Type of component to display. 52 | /// Modal title. 53 | ModalReference Show(Type component, string title); 54 | 55 | /// 56 | /// Shows a modal containing a with the specified and . 57 | /// 58 | /// Modal title. 59 | /// Type of component to display. 60 | /// Options to configure the modal. 61 | ModalReference Show(Type component, string title, ModalOptions options); 62 | 63 | /// 64 | /// Shows a modal containing a with the specified and . 65 | /// 66 | /// Modal title. 67 | /// Type of component to display. 68 | /// Key/Value collection of parameters to pass to component being displayed. 69 | ModalReference Show(Type component, string title, ModalParameters parameters); 70 | 71 | /// 72 | /// Shows a modal containing a with the specified , 73 | /// and . 74 | /// 75 | /// Modal title. 76 | /// Key/Value collection of parameters to pass to component being displayed. 77 | /// Options to configure the modal. 78 | ModalReference Show(Type component, string title, ModalParameters parameters, ModalOptions options); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /tests/src/Blazored.Modal.Tests/ModalOptionsTests.cs: -------------------------------------------------------------------------------- 1 | using Blazored.Modal.Services; 2 | using Blazored.Modal.Tests.Assets; 3 | using Bunit; 4 | using Microsoft.AspNetCore.Components; 5 | using Microsoft.Extensions.DependencyInjection; 6 | using Xunit; 7 | 8 | namespace Blazored.Modal.Tests 9 | { 10 | public class ModalOptionsTests : ComponentTestFixture 11 | { 12 | public ModalOptionsTests() 13 | { 14 | Services.AddScoped(); 15 | Services.AddBlazoredModal(); 16 | } 17 | 18 | [Fact] 19 | public void ModalDisplaysSpecifiedTitle() 20 | { 21 | // Arrange 22 | var testTitle = "Title"; 23 | var modalService = Services.GetService(); 24 | var cut = RenderComponent(); 25 | 26 | // Act 27 | modalService.Show(testTitle); 28 | 29 | // Assert 30 | Assert.Equal(testTitle, cut.Find(".blazored-modal-title").InnerHtml); 31 | } 32 | 33 | [Fact] 34 | public void ModalDisplaysCorrectPositionClass() 35 | { 36 | // Arrange 37 | var options = new ModalOptions { Position = ModalPosition.TopLeft }; 38 | var modalService = Services.GetService(); 39 | var cut = RenderComponent(); 40 | 41 | // Act 42 | modalService.Show("", options); 43 | 44 | // Assert 45 | Assert.NotNull(cut.Find(".blazored-modal-container.blazored-modal-topleft")); 46 | } 47 | 48 | [Fact] 49 | public void ModalDisplaysCustomStyles() 50 | { 51 | // Arrange 52 | var modalService = Services.GetService(); 53 | var customStyle = "my-custom-style"; 54 | var options = new ModalOptions { Class = customStyle }; 55 | var cut = RenderComponent(); 56 | 57 | // Act 58 | modalService.Show("", options); 59 | 60 | // Assert 61 | Assert.NotNull(cut.Find($"div.{customStyle}")); 62 | } 63 | 64 | [Fact] 65 | public void ModalDisplaysCloseButtonByDefault() 66 | { 67 | // Arrange 68 | var modalService = Services.GetService(); 69 | var cut = RenderComponent(); 70 | 71 | // Act 72 | modalService.Show(); 73 | 74 | // Assert 75 | Assert.NotNull(cut.Find(".blazored-modal-close")); 76 | } 77 | 78 | [Fact] 79 | public void ModalDoesNotDisplayCloseButtonWhenSetToFalseInOptions() 80 | { 81 | // Arrange 82 | var modalService = Services.GetService(); 83 | var options = new ModalOptions { HideCloseButton = true }; 84 | var cut = RenderComponent(); 85 | 86 | // Act 87 | modalService.Show("", options); 88 | 89 | // Assert 90 | Assert.Empty(cut.FindAll(".blazored-modal-close")); 91 | } 92 | 93 | [Fact] 94 | public void ModalDisplaysHeaderByDefault() 95 | { 96 | // Arrange 97 | var modalService = Services.GetService(); 98 | var cut = RenderComponent(); 99 | 100 | // Act 101 | modalService.Show(); 102 | 103 | // Assert 104 | Assert.NotNull(cut.Find(".blazored-modal-header")); 105 | } 106 | 107 | [Fact] 108 | public void ModalDoesNotDisplayHeaderWhenSetToFalseInOptions() 109 | { 110 | // Arrange 111 | var modalService = Services.GetService(); 112 | var options = new ModalOptions { HideHeader = true }; 113 | var cut = RenderComponent(); 114 | 115 | // Act 116 | modalService.Show("", options); 117 | 118 | // Assert 119 | Assert.Empty(cut.FindAll(".blazored-modal-header")); 120 | } 121 | 122 | [Fact] 123 | public void ModalDisplaysCorrectContent() 124 | { 125 | // Arrange 126 | var modalService = Services.GetService(); 127 | var cut = RenderComponent(); 128 | 129 | // Act 130 | modalService.Show(""); 131 | 132 | // Assert 133 | Assert.Equal(TestComponent.DefaultTitle, cut.Find(".test-component h1").InnerHtml); 134 | } 135 | 136 | [Fact] 137 | public void ModalDisplaysCorrectContentWhenUsingModalParameters() 138 | { 139 | var testTitle = "Testing Components"; 140 | 141 | // Arrange 142 | var modalService = Services.GetService(); 143 | 144 | var parameters = new ModalParameters(); 145 | parameters.Add("Title", testTitle); 146 | var cut = RenderComponent(); 147 | 148 | // Act 149 | modalService.Show("", parameters); 150 | 151 | // Assert 152 | Assert.Equal(testTitle, cut.Find(".test-component h1").InnerHtml); 153 | } 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/Blazored.Modal/BlazoredModalInstance.razor: -------------------------------------------------------------------------------- 1 |
      2 | 3 |
      4 | 5 |
      6 |
      7 | @if (!HideHeader) 8 | { 9 |
      10 |

      @Title

      11 | @if (!HideCloseButton) 12 | { 13 | 16 | } 17 |
      18 | } 19 |
      20 | 21 | @Content 22 | 23 |
      24 |
      25 |
      26 |
      27 | 28 | @code { 29 | [CascadingParameter] private BlazoredModal Parent { get; set; } 30 | [CascadingParameter] private ModalOptions GlobalModalOptions { get; set; } 31 | 32 | [Parameter] public ModalOptions Options { get; set; } 33 | [Parameter] public string Title { get; set; } 34 | [Parameter] public RenderFragment Content { get; set; } 35 | [Parameter] public Guid Id { get; set; } 36 | 37 | private string Position { get; set; } 38 | private string Class { get; set; } 39 | private bool HideHeader { get; set; } 40 | private bool HideCloseButton { get; set; } 41 | private bool DisableBackgroundCancel { get; set; } 42 | 43 | protected override void OnInitialized() 44 | { 45 | ConfigureInstance(); 46 | } 47 | 48 | /// 49 | /// Sets the title for the modal being displayed 50 | /// 51 | /// Text to display as the title of the modal 52 | public void SetTitle(string title) 53 | { 54 | Title = title; 55 | StateHasChanged(); 56 | } 57 | 58 | /// 59 | /// Closes the modal with a default Ok result />. 60 | /// 61 | public void Close() 62 | { 63 | Close(ModalResult.Ok(null)); 64 | } 65 | 66 | /// 67 | /// Closes the modal with the specified . 68 | /// 69 | /// 70 | public void Close(ModalResult modalResult) 71 | { 72 | Parent.DismissInstance(Id, modalResult); 73 | } 74 | 75 | /// 76 | /// Closes the modal and returns a cancelled ModalResult. 77 | /// 78 | public void Cancel() 79 | { 80 | Parent.DismissInstance(Id, ModalResult.Cancel()); 81 | } 82 | 83 | private void ConfigureInstance() 84 | { 85 | Position = SetPosition(); 86 | Class = SetClass(); 87 | HideHeader = SetHideHeader(); 88 | HideCloseButton = SetHideCloseButton(); 89 | DisableBackgroundCancel = SetDisableBackgroundCancel(); 90 | } 91 | 92 | private string SetPosition() 93 | { 94 | ModalPosition position; 95 | if (Options.Position.HasValue) 96 | { 97 | position = Options.Position.Value; 98 | } 99 | else if (GlobalModalOptions.Position.HasValue) 100 | { 101 | position = GlobalModalOptions.Position.Value; 102 | } 103 | else 104 | { 105 | position = ModalPosition.Center; 106 | } 107 | 108 | switch (position) 109 | { 110 | case ModalPosition.Center: 111 | return "blazored-modal-center"; 112 | case ModalPosition.TopLeft: 113 | return "blazored-modal-topleft"; 114 | case ModalPosition.TopRight: 115 | return "blazored-modal-topright"; 116 | case ModalPosition.BottomLeft: 117 | return "blazored-modal-bottomleft"; 118 | case ModalPosition.BottomRight: 119 | return "blazored-modal-bottomright"; 120 | default: 121 | return "blazored-modal-center"; 122 | } 123 | } 124 | 125 | private string SetClass() 126 | { 127 | if (!string.IsNullOrWhiteSpace(Options.Class)) 128 | return Options.Class; 129 | 130 | if (!string.IsNullOrWhiteSpace(GlobalModalOptions.Class)) 131 | return GlobalModalOptions.Class; 132 | 133 | return "blazored-modal"; 134 | } 135 | 136 | private bool SetHideHeader() 137 | { 138 | if (Options.HideHeader.HasValue) 139 | return Options.HideHeader.Value; 140 | 141 | if (GlobalModalOptions.HideHeader.HasValue) 142 | return GlobalModalOptions.HideHeader.Value; 143 | 144 | return false; 145 | } 146 | 147 | private bool SetHideCloseButton() 148 | { 149 | if (Options.HideCloseButton.HasValue) 150 | return Options.HideCloseButton.Value; 151 | 152 | if (GlobalModalOptions.HideCloseButton.HasValue) 153 | return GlobalModalOptions.HideCloseButton.Value; 154 | 155 | return false; 156 | } 157 | 158 | private bool SetDisableBackgroundCancel() 159 | { 160 | if (Options.DisableBackgroundCancel.HasValue) 161 | return Options.DisableBackgroundCancel.Value; 162 | 163 | if (GlobalModalOptions.DisableBackgroundCancel.HasValue) 164 | return GlobalModalOptions.DisableBackgroundCancel.Value; 165 | 166 | return false; 167 | } 168 | 169 | private void HandleBackgroundClick() 170 | { 171 | if (DisableBackgroundCancel) return; 172 | 173 | Parent.CancelInstance(Id); 174 | } 175 | 176 | } -------------------------------------------------------------------------------- /Blazored.Modal.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.28531.58 5 | MinimumVisualStudioVersion = 15.0.26124.0 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blazored.Modal", "src\Blazored.Modal\Blazored.Modal.csproj", "{997CB0B4-2B3F-4625-9259-A560CD82AC8C}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{AC842EAA-F630-4597-A0FC-6758FE9F6268}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorWebAssembly", "samples\BlazorWebAssembly\BlazorWebAssembly.csproj", "{4ECB8E84-B0FF-4DC0-9929-D0BE5922E97D}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorServer", "samples\BlazorServer\BlazorServer.csproj", "{6290EEF7-69B6-43D0-8FA9-999045336637}" 13 | EndProject 14 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E8AD9151-AB7E-4531-A1DF-8952B1D5580D}" 15 | ProjectSection(SolutionItems) = preProject 16 | azure-pipelines.yml = azure-pipelines.yml 17 | README.md = README.md 18 | EndProjectSection 19 | EndProject 20 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{DF45C5D5-16E0-47FC-A764-08ED8AF713E2}" 21 | EndProject 22 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blazored.Modal.Tests", "tests\src\Blazored.Modal.Tests\Blazored.Modal.Tests.csproj", "{14B17729-C172-4F0C-90FF-65479AF6408F}" 23 | EndProject 24 | Global 25 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 26 | Debug|Any CPU = Debug|Any CPU 27 | Debug|x64 = Debug|x64 28 | Debug|x86 = Debug|x86 29 | Release|Any CPU = Release|Any CPU 30 | Release|x64 = Release|x64 31 | Release|x86 = Release|x86 32 | EndGlobalSection 33 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 34 | {997CB0B4-2B3F-4625-9259-A560CD82AC8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {997CB0B4-2B3F-4625-9259-A560CD82AC8C}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {997CB0B4-2B3F-4625-9259-A560CD82AC8C}.Debug|x64.ActiveCfg = Debug|Any CPU 37 | {997CB0B4-2B3F-4625-9259-A560CD82AC8C}.Debug|x64.Build.0 = Debug|Any CPU 38 | {997CB0B4-2B3F-4625-9259-A560CD82AC8C}.Debug|x86.ActiveCfg = Debug|Any CPU 39 | {997CB0B4-2B3F-4625-9259-A560CD82AC8C}.Debug|x86.Build.0 = Debug|Any CPU 40 | {997CB0B4-2B3F-4625-9259-A560CD82AC8C}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {997CB0B4-2B3F-4625-9259-A560CD82AC8C}.Release|Any CPU.Build.0 = Release|Any CPU 42 | {997CB0B4-2B3F-4625-9259-A560CD82AC8C}.Release|x64.ActiveCfg = Release|Any CPU 43 | {997CB0B4-2B3F-4625-9259-A560CD82AC8C}.Release|x64.Build.0 = Release|Any CPU 44 | {997CB0B4-2B3F-4625-9259-A560CD82AC8C}.Release|x86.ActiveCfg = Release|Any CPU 45 | {997CB0B4-2B3F-4625-9259-A560CD82AC8C}.Release|x86.Build.0 = Release|Any CPU 46 | {4ECB8E84-B0FF-4DC0-9929-D0BE5922E97D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {4ECB8E84-B0FF-4DC0-9929-D0BE5922E97D}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {4ECB8E84-B0FF-4DC0-9929-D0BE5922E97D}.Debug|x64.ActiveCfg = Debug|Any CPU 49 | {4ECB8E84-B0FF-4DC0-9929-D0BE5922E97D}.Debug|x64.Build.0 = Debug|Any CPU 50 | {4ECB8E84-B0FF-4DC0-9929-D0BE5922E97D}.Debug|x86.ActiveCfg = Debug|Any CPU 51 | {4ECB8E84-B0FF-4DC0-9929-D0BE5922E97D}.Debug|x86.Build.0 = Debug|Any CPU 52 | {4ECB8E84-B0FF-4DC0-9929-D0BE5922E97D}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {4ECB8E84-B0FF-4DC0-9929-D0BE5922E97D}.Release|Any CPU.Build.0 = Release|Any CPU 54 | {4ECB8E84-B0FF-4DC0-9929-D0BE5922E97D}.Release|x64.ActiveCfg = Release|Any CPU 55 | {4ECB8E84-B0FF-4DC0-9929-D0BE5922E97D}.Release|x64.Build.0 = Release|Any CPU 56 | {4ECB8E84-B0FF-4DC0-9929-D0BE5922E97D}.Release|x86.ActiveCfg = Release|Any CPU 57 | {4ECB8E84-B0FF-4DC0-9929-D0BE5922E97D}.Release|x86.Build.0 = Release|Any CPU 58 | {6290EEF7-69B6-43D0-8FA9-999045336637}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 59 | {6290EEF7-69B6-43D0-8FA9-999045336637}.Debug|Any CPU.Build.0 = Debug|Any CPU 60 | {6290EEF7-69B6-43D0-8FA9-999045336637}.Debug|x64.ActiveCfg = Debug|Any CPU 61 | {6290EEF7-69B6-43D0-8FA9-999045336637}.Debug|x64.Build.0 = Debug|Any CPU 62 | {6290EEF7-69B6-43D0-8FA9-999045336637}.Debug|x86.ActiveCfg = Debug|Any CPU 63 | {6290EEF7-69B6-43D0-8FA9-999045336637}.Debug|x86.Build.0 = Debug|Any CPU 64 | {6290EEF7-69B6-43D0-8FA9-999045336637}.Release|Any CPU.ActiveCfg = Release|Any CPU 65 | {6290EEF7-69B6-43D0-8FA9-999045336637}.Release|Any CPU.Build.0 = Release|Any CPU 66 | {6290EEF7-69B6-43D0-8FA9-999045336637}.Release|x64.ActiveCfg = Release|Any CPU 67 | {6290EEF7-69B6-43D0-8FA9-999045336637}.Release|x64.Build.0 = Release|Any CPU 68 | {6290EEF7-69B6-43D0-8FA9-999045336637}.Release|x86.ActiveCfg = Release|Any CPU 69 | {6290EEF7-69B6-43D0-8FA9-999045336637}.Release|x86.Build.0 = Release|Any CPU 70 | {14B17729-C172-4F0C-90FF-65479AF6408F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 71 | {14B17729-C172-4F0C-90FF-65479AF6408F}.Debug|Any CPU.Build.0 = Debug|Any CPU 72 | {14B17729-C172-4F0C-90FF-65479AF6408F}.Debug|x64.ActiveCfg = Debug|Any CPU 73 | {14B17729-C172-4F0C-90FF-65479AF6408F}.Debug|x64.Build.0 = Debug|Any CPU 74 | {14B17729-C172-4F0C-90FF-65479AF6408F}.Debug|x86.ActiveCfg = Debug|Any CPU 75 | {14B17729-C172-4F0C-90FF-65479AF6408F}.Debug|x86.Build.0 = Debug|Any CPU 76 | {14B17729-C172-4F0C-90FF-65479AF6408F}.Release|Any CPU.ActiveCfg = Release|Any CPU 77 | {14B17729-C172-4F0C-90FF-65479AF6408F}.Release|Any CPU.Build.0 = Release|Any CPU 78 | {14B17729-C172-4F0C-90FF-65479AF6408F}.Release|x64.ActiveCfg = Release|Any CPU 79 | {14B17729-C172-4F0C-90FF-65479AF6408F}.Release|x64.Build.0 = Release|Any CPU 80 | {14B17729-C172-4F0C-90FF-65479AF6408F}.Release|x86.ActiveCfg = Release|Any CPU 81 | {14B17729-C172-4F0C-90FF-65479AF6408F}.Release|x86.Build.0 = Release|Any CPU 82 | EndGlobalSection 83 | GlobalSection(SolutionProperties) = preSolution 84 | HideSolutionNode = FALSE 85 | EndGlobalSection 86 | GlobalSection(NestedProjects) = preSolution 87 | {4ECB8E84-B0FF-4DC0-9929-D0BE5922E97D} = {AC842EAA-F630-4597-A0FC-6758FE9F6268} 88 | {6290EEF7-69B6-43D0-8FA9-999045336637} = {AC842EAA-F630-4597-A0FC-6758FE9F6268} 89 | {14B17729-C172-4F0C-90FF-65479AF6408F} = {DF45C5D5-16E0-47FC-A764-08ED8AF713E2} 90 | EndGlobalSection 91 | GlobalSection(ExtensibilityGlobals) = postSolution 92 | SolutionGuid = {FB2D90F4-21CF-4118-82E7-479E89C15FB3} 93 | EndGlobalSection 94 | EndGlobal 95 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015/2017 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # Visual Studio 2017 auto generated files 33 | Generated\ Files/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | **/Properties/launchSettings.json 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_i.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *.log 81 | *.vspscc 82 | *.vssscc 83 | .builds 84 | *.pidb 85 | *.svclog 86 | *.scc 87 | 88 | # Chutzpah Test files 89 | _Chutzpah* 90 | 91 | # Visual C++ cache files 92 | ipch/ 93 | *.aps 94 | *.ncb 95 | *.opendb 96 | *.opensdf 97 | *.sdf 98 | *.cachefile 99 | *.VC.db 100 | *.VC.VC.opendb 101 | 102 | # Visual Studio profiler 103 | *.psess 104 | *.vsp 105 | *.vspx 106 | *.sap 107 | 108 | # Visual Studio Trace Files 109 | *.e2e 110 | 111 | # TFS 2012 Local Workspace 112 | $tf/ 113 | 114 | # Guidance Automation Toolkit 115 | *.gpState 116 | 117 | # ReSharper is a .NET coding add-in 118 | _ReSharper*/ 119 | *.[Rr]e[Ss]harper 120 | *.DotSettings.user 121 | 122 | # JustCode is a .NET coding add-in 123 | .JustCode 124 | 125 | # TeamCity is a build add-in 126 | _TeamCity* 127 | 128 | # DotCover is a Code Coverage Tool 129 | *.dotCover 130 | 131 | # AxoCover is a Code Coverage Tool 132 | .axoCover/* 133 | !.axoCover/settings.json 134 | 135 | # Visual Studio code coverage results 136 | *.coverage 137 | *.coveragexml 138 | 139 | # NCrunch 140 | _NCrunch_* 141 | .*crunch*.local.xml 142 | nCrunchTemp_* 143 | 144 | # MightyMoose 145 | *.mm.* 146 | AutoTest.Net/ 147 | 148 | # Web workbench (sass) 149 | .sass-cache/ 150 | 151 | # Installshield output folder 152 | [Ee]xpress/ 153 | 154 | # DocProject is a documentation generator add-in 155 | DocProject/buildhelp/ 156 | DocProject/Help/*.HxT 157 | DocProject/Help/*.HxC 158 | DocProject/Help/*.hhc 159 | DocProject/Help/*.hhk 160 | DocProject/Help/*.hhp 161 | DocProject/Help/Html2 162 | DocProject/Help/html 163 | 164 | # Click-Once directory 165 | publish/ 166 | 167 | # Publish Web Output 168 | *.[Pp]ublish.xml 169 | *.azurePubxml 170 | # Note: Comment the next line if you want to checkin your web deploy settings, 171 | # but database connection strings (with potential passwords) will be unencrypted 172 | *.pubxml 173 | *.publishproj 174 | 175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 176 | # checkin your Azure Web App publish settings, but sensitive information contained 177 | # in these scripts will be unencrypted 178 | PublishScripts/ 179 | 180 | # NuGet Packages 181 | *.nupkg 182 | # The packages folder can be ignored because of Package Restore 183 | **/[Pp]ackages/* 184 | # except build/, which is used as an MSBuild target. 185 | !**/[Pp]ackages/build/ 186 | # Uncomment if necessary however generally it will be regenerated when needed 187 | #!**/[Pp]ackages/repositories.config 188 | # NuGet v3's project.json files produces more ignorable files 189 | *.nuget.props 190 | *.nuget.targets 191 | 192 | # Microsoft Azure Build Output 193 | csx/ 194 | *.build.csdef 195 | 196 | # Microsoft Azure Emulator 197 | ecf/ 198 | rcf/ 199 | 200 | # Windows Store app package directories and files 201 | AppPackages/ 202 | BundleArtifacts/ 203 | Package.StoreAssociation.xml 204 | _pkginfo.txt 205 | *.appx 206 | 207 | # Visual Studio cache files 208 | # files ending in .cache can be ignored 209 | *.[Cc]ache 210 | # but keep track of directories ending in .cache 211 | !*.[Cc]ache/ 212 | 213 | # Others 214 | ClientBin/ 215 | ~$* 216 | *~ 217 | *.dbmdl 218 | *.dbproj.schemaview 219 | *.jfm 220 | *.pfx 221 | *.publishsettings 222 | orleans.codegen.cs 223 | 224 | # Including strong name files can present a security risk 225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 226 | #*.snk 227 | 228 | # Since there are multiple workflows, uncomment next line to ignore bower_components 229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 230 | #bower_components/ 231 | 232 | # RIA/Silverlight projects 233 | Generated_Code/ 234 | 235 | # Backup & report files from converting an old project file 236 | # to a newer Visual Studio version. Backup files are not needed, 237 | # because we have git ;-) 238 | _UpgradeReport_Files/ 239 | Backup*/ 240 | UpgradeLog*.XML 241 | UpgradeLog*.htm 242 | ServiceFabricBackup/ 243 | *.rptproj.bak 244 | 245 | # SQL Server files 246 | *.mdf 247 | *.ldf 248 | *.ndf 249 | 250 | # Business Intelligence projects 251 | *.rdl.data 252 | *.bim.layout 253 | *.bim_*.settings 254 | *.rptproj.rsuser 255 | 256 | # Microsoft Fakes 257 | FakesAssemblies/ 258 | 259 | # GhostDoc plugin setting file 260 | *.GhostDoc.xml 261 | 262 | # Node.js Tools for Visual Studio 263 | .ntvs_analysis.dat 264 | node_modules/ 265 | 266 | # Visual Studio 6 build log 267 | *.plg 268 | 269 | # Visual Studio 6 workspace options file 270 | *.opt 271 | 272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 273 | *.vbw 274 | 275 | # Visual Studio LightSwitch build output 276 | **/*.HTMLClient/GeneratedArtifacts 277 | **/*.DesktopClient/GeneratedArtifacts 278 | **/*.DesktopClient/ModelManifest.xml 279 | **/*.Server/GeneratedArtifacts 280 | **/*.Server/ModelManifest.xml 281 | _Pvt_Extensions 282 | 283 | # Paket dependency manager 284 | .paket/paket.exe 285 | paket-files/ 286 | 287 | # FAKE - F# Make 288 | .fake/ 289 | 290 | # JetBrains Rider 291 | .idea/ 292 | *.sln.iml 293 | 294 | # CodeRush 295 | .cr/ 296 | 297 | # Python Tools for Visual Studio (PTVS) 298 | __pycache__/ 299 | *.pyc 300 | 301 | # Cake - Uncomment if you are using it 302 | # tools/** 303 | # !tools/packages.config 304 | 305 | # Tabs Studio 306 | *.tss 307 | 308 | # Telerik's JustMock configuration file 309 | *.jmconfig 310 | 311 | # BizTalk build output 312 | *.btp.cs 313 | *.btm.cs 314 | *.odx.cs 315 | *.xsd.cs 316 | 317 | # OpenCover UI analysis results 318 | OpenCover/ 319 | 320 | # Azure Stream Analytics local run output 321 | ASALocalRun/ 322 | 323 | # MSBuild Binary and Structured Log 324 | *.binlog 325 | 326 | # NVidia Nsight GPU debugger configuration file 327 | *.nvuser 328 | 329 | # MFractors (Xamarin productivity tool) working folder 330 | .mfractor/ 331 | -------------------------------------------------------------------------------- /src/Blazored.Modal/Services/ModalService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components; 2 | using System; 3 | 4 | namespace Blazored.Modal.Services 5 | { 6 | public class ModalService : IModalService 7 | { 8 | internal event Action OnModalInstanceAdded; 9 | internal event Action OnModalCloseRequested; 10 | 11 | /// 12 | /// Shows the modal with the component type. 13 | /// 14 | public ModalReference Show() where T : ComponentBase 15 | { 16 | return Show(string.Empty, new ModalParameters(), new ModalOptions()); 17 | } 18 | 19 | /// 20 | /// Shows the modal with the component type using the specified title. 21 | /// 22 | /// Modal title. 23 | public ModalReference Show(string title) where T : ComponentBase 24 | { 25 | return Show(title, new ModalParameters(), new ModalOptions()); 26 | } 27 | 28 | /// 29 | /// Shows the modal with the component type using the specified title. 30 | /// 31 | /// Modal title. 32 | /// Options to configure the modal. 33 | public ModalReference Show(string title, ModalOptions options) where T : ComponentBase 34 | { 35 | return Show(title, new ModalParameters(), options); 36 | } 37 | 38 | /// 39 | /// Shows the modal with the component type using the specified , 40 | /// passing the specified . 41 | /// 42 | /// Modal title. 43 | /// Key/Value collection of parameters to pass to component being displayed. 44 | public ModalReference Show(string title, ModalParameters parameters) where T : ComponentBase 45 | { 46 | return Show(title, parameters, new ModalOptions()); 47 | } 48 | 49 | /// 50 | /// Shows the modal with the component type using the specified , 51 | /// passing the specified and setting a custom CSS style. 52 | /// 53 | /// Modal title. 54 | /// Key/Value collection of parameters to pass to component being displayed. 55 | /// Options to configure the modal. 56 | public ModalReference Show(string title, ModalParameters parameters, ModalOptions options) where T : ComponentBase 57 | { 58 | return Show(typeof(T), title, parameters, options); 59 | } 60 | 61 | /// 62 | /// Shows the modal with the specific component type. 63 | /// 64 | /// Type of component to display. 65 | public ModalReference Show(Type contentComponent) 66 | { 67 | return Show(contentComponent, string.Empty, new ModalParameters(), new ModalOptions()); 68 | } 69 | 70 | /// 71 | /// Shows the modal with the component type using the specified title. 72 | /// 73 | /// Type of component to display. 74 | /// Modal title. 75 | public ModalReference Show(Type contentComponent, string title) 76 | { 77 | return Show(contentComponent, title, new ModalParameters(), new ModalOptions()); 78 | } 79 | 80 | /// 81 | /// Shows the modal with the component type using the specified title. 82 | /// 83 | /// Modal title. 84 | /// Type of component to display. 85 | /// Options to configure the modal. 86 | public ModalReference Show(Type contentComponent, string title, ModalOptions options) 87 | { 88 | return Show(contentComponent, title, new ModalParameters(), options); 89 | } 90 | 91 | /// 92 | /// Shows the modal with the component type using the specified , 93 | /// passing the specified . 94 | /// 95 | /// Modal title. 96 | /// Type of component to display. 97 | /// Key/Value collection of parameters to pass to component being displayed. 98 | public ModalReference Show(Type contentComponent, string title, ModalParameters parameters) 99 | { 100 | return Show(contentComponent, title, parameters, new ModalOptions()); 101 | } 102 | 103 | /// 104 | /// Shows the modal with the component type using the specified , 105 | /// passing the specified and setting a custom CSS style. 106 | /// 107 | /// Modal title. 108 | /// Key/Value collection of parameters to pass to component being displayed. 109 | /// Options to configure the modal. 110 | public ModalReference Show(Type contentComponent, string title, ModalParameters parameters, ModalOptions options) 111 | { 112 | if (!typeof(ComponentBase).IsAssignableFrom(contentComponent)) 113 | { 114 | throw new ArgumentException($"{contentComponent.FullName} must be a Blazor Component"); 115 | } 116 | 117 | var modalInstanceId = Guid.NewGuid(); 118 | var modalContent = new RenderFragment(builder => 119 | { 120 | var i = 0; 121 | builder.OpenComponent(i++, contentComponent); 122 | foreach (var parameter in parameters._parameters) 123 | { 124 | builder.AddAttribute(i++, parameter.Key, parameter.Value); 125 | } 126 | builder.CloseComponent(); 127 | }); 128 | var modalInstance = new RenderFragment(builder => 129 | { 130 | builder.OpenComponent(0); 131 | builder.AddAttribute(1, "Options", options); 132 | builder.AddAttribute(2, "Title", title); 133 | builder.AddAttribute(3, "Content", modalContent); 134 | builder.AddAttribute(4, "Id", modalInstanceId); 135 | builder.CloseComponent(); 136 | }); 137 | var modalReference = new ModalReference(modalInstanceId, modalInstance, this); 138 | 139 | OnModalInstanceAdded?.Invoke(modalReference); 140 | 141 | return modalReference; 142 | } 143 | 144 | internal void Close(ModalReference modal) 145 | { 146 | Close(modal, ModalResult.Ok(null)); 147 | } 148 | 149 | internal void Close(ModalReference modal, ModalResult result) 150 | { 151 | OnModalCloseRequested?.Invoke(modal, result); 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /samples/BlazorServer/wwwroot/css/open-iconic/font/css/open-iconic-bootstrap.min.css: -------------------------------------------------------------------------------- 1 | @font-face{font-family:Icons;src:url(../fonts/open-iconic.eot);src:url(../fonts/open-iconic.eot?#iconic-sm) format('embedded-opentype'),url(../fonts/open-iconic.woff) format('woff'),url(../fonts/open-iconic.ttf) format('truetype'),url(../fonts/open-iconic.otf) format('opentype'),url(../fonts/open-iconic.svg#iconic-sm) format('svg');font-weight:400;font-style:normal}.oi{position:relative;top:1px;display:inline-block;speak:none;font-family:Icons;font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.oi:empty:before{width:1em;text-align:center;box-sizing:content-box}.oi.oi-align-center:before{text-align:center}.oi.oi-align-left:before{text-align:left}.oi.oi-align-right:before{text-align:right}.oi.oi-flip-horizontal:before{-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.oi.oi-flip-vertical:before{-webkit-transform:scale(1,-1);-ms-transform:scale(-1,1);transform:scale(1,-1)}.oi.oi-flip-horizontal-vertical:before{-webkit-transform:scale(-1,-1);-ms-transform:scale(-1,1);transform:scale(-1,-1)}.oi-account-login:before{content:'\e000'}.oi-account-logout:before{content:'\e001'}.oi-action-redo:before{content:'\e002'}.oi-action-undo:before{content:'\e003'}.oi-align-center:before{content:'\e004'}.oi-align-left:before{content:'\e005'}.oi-align-right:before{content:'\e006'}.oi-aperture:before{content:'\e007'}.oi-arrow-bottom:before{content:'\e008'}.oi-arrow-circle-bottom:before{content:'\e009'}.oi-arrow-circle-left:before{content:'\e00a'}.oi-arrow-circle-right:before{content:'\e00b'}.oi-arrow-circle-top:before{content:'\e00c'}.oi-arrow-left:before{content:'\e00d'}.oi-arrow-right:before{content:'\e00e'}.oi-arrow-thick-bottom:before{content:'\e00f'}.oi-arrow-thick-left:before{content:'\e010'}.oi-arrow-thick-right:before{content:'\e011'}.oi-arrow-thick-top:before{content:'\e012'}.oi-arrow-top:before{content:'\e013'}.oi-audio-spectrum:before{content:'\e014'}.oi-audio:before{content:'\e015'}.oi-badge:before{content:'\e016'}.oi-ban:before{content:'\e017'}.oi-bar-chart:before{content:'\e018'}.oi-basket:before{content:'\e019'}.oi-battery-empty:before{content:'\e01a'}.oi-battery-full:before{content:'\e01b'}.oi-beaker:before{content:'\e01c'}.oi-bell:before{content:'\e01d'}.oi-bluetooth:before{content:'\e01e'}.oi-bold:before{content:'\e01f'}.oi-bolt:before{content:'\e020'}.oi-book:before{content:'\e021'}.oi-bookmark:before{content:'\e022'}.oi-box:before{content:'\e023'}.oi-briefcase:before{content:'\e024'}.oi-british-pound:before{content:'\e025'}.oi-browser:before{content:'\e026'}.oi-brush:before{content:'\e027'}.oi-bug:before{content:'\e028'}.oi-bullhorn:before{content:'\e029'}.oi-calculator:before{content:'\e02a'}.oi-calendar:before{content:'\e02b'}.oi-camera-slr:before{content:'\e02c'}.oi-caret-bottom:before{content:'\e02d'}.oi-caret-left:before{content:'\e02e'}.oi-caret-right:before{content:'\e02f'}.oi-caret-top:before{content:'\e030'}.oi-cart:before{content:'\e031'}.oi-chat:before{content:'\e032'}.oi-check:before{content:'\e033'}.oi-chevron-bottom:before{content:'\e034'}.oi-chevron-left:before{content:'\e035'}.oi-chevron-right:before{content:'\e036'}.oi-chevron-top:before{content:'\e037'}.oi-circle-check:before{content:'\e038'}.oi-circle-x:before{content:'\e039'}.oi-clipboard:before{content:'\e03a'}.oi-clock:before{content:'\e03b'}.oi-cloud-download:before{content:'\e03c'}.oi-cloud-upload:before{content:'\e03d'}.oi-cloud:before{content:'\e03e'}.oi-cloudy:before{content:'\e03f'}.oi-code:before{content:'\e040'}.oi-cog:before{content:'\e041'}.oi-collapse-down:before{content:'\e042'}.oi-collapse-left:before{content:'\e043'}.oi-collapse-right:before{content:'\e044'}.oi-collapse-up:before{content:'\e045'}.oi-command:before{content:'\e046'}.oi-comment-square:before{content:'\e047'}.oi-compass:before{content:'\e048'}.oi-contrast:before{content:'\e049'}.oi-copywriting:before{content:'\e04a'}.oi-credit-card:before{content:'\e04b'}.oi-crop:before{content:'\e04c'}.oi-dashboard:before{content:'\e04d'}.oi-data-transfer-download:before{content:'\e04e'}.oi-data-transfer-upload:before{content:'\e04f'}.oi-delete:before{content:'\e050'}.oi-dial:before{content:'\e051'}.oi-document:before{content:'\e052'}.oi-dollar:before{content:'\e053'}.oi-double-quote-sans-left:before{content:'\e054'}.oi-double-quote-sans-right:before{content:'\e055'}.oi-double-quote-serif-left:before{content:'\e056'}.oi-double-quote-serif-right:before{content:'\e057'}.oi-droplet:before{content:'\e058'}.oi-eject:before{content:'\e059'}.oi-elevator:before{content:'\e05a'}.oi-ellipses:before{content:'\e05b'}.oi-envelope-closed:before{content:'\e05c'}.oi-envelope-open:before{content:'\e05d'}.oi-euro:before{content:'\e05e'}.oi-excerpt:before{content:'\e05f'}.oi-expand-down:before{content:'\e060'}.oi-expand-left:before{content:'\e061'}.oi-expand-right:before{content:'\e062'}.oi-expand-up:before{content:'\e063'}.oi-external-link:before{content:'\e064'}.oi-eye:before{content:'\e065'}.oi-eyedropper:before{content:'\e066'}.oi-file:before{content:'\e067'}.oi-fire:before{content:'\e068'}.oi-flag:before{content:'\e069'}.oi-flash:before{content:'\e06a'}.oi-folder:before{content:'\e06b'}.oi-fork:before{content:'\e06c'}.oi-fullscreen-enter:before{content:'\e06d'}.oi-fullscreen-exit:before{content:'\e06e'}.oi-globe:before{content:'\e06f'}.oi-graph:before{content:'\e070'}.oi-grid-four-up:before{content:'\e071'}.oi-grid-three-up:before{content:'\e072'}.oi-grid-two-up:before{content:'\e073'}.oi-hard-drive:before{content:'\e074'}.oi-header:before{content:'\e075'}.oi-headphones:before{content:'\e076'}.oi-heart:before{content:'\e077'}.oi-home:before{content:'\e078'}.oi-image:before{content:'\e079'}.oi-inbox:before{content:'\e07a'}.oi-infinity:before{content:'\e07b'}.oi-info:before{content:'\e07c'}.oi-italic:before{content:'\e07d'}.oi-justify-center:before{content:'\e07e'}.oi-justify-left:before{content:'\e07f'}.oi-justify-right:before{content:'\e080'}.oi-key:before{content:'\e081'}.oi-laptop:before{content:'\e082'}.oi-layers:before{content:'\e083'}.oi-lightbulb:before{content:'\e084'}.oi-link-broken:before{content:'\e085'}.oi-link-intact:before{content:'\e086'}.oi-list-rich:before{content:'\e087'}.oi-list:before{content:'\e088'}.oi-location:before{content:'\e089'}.oi-lock-locked:before{content:'\e08a'}.oi-lock-unlocked:before{content:'\e08b'}.oi-loop-circular:before{content:'\e08c'}.oi-loop-square:before{content:'\e08d'}.oi-loop:before{content:'\e08e'}.oi-magnifying-glass:before{content:'\e08f'}.oi-map-marker:before{content:'\e090'}.oi-map:before{content:'\e091'}.oi-media-pause:before{content:'\e092'}.oi-media-play:before{content:'\e093'}.oi-media-record:before{content:'\e094'}.oi-media-skip-backward:before{content:'\e095'}.oi-media-skip-forward:before{content:'\e096'}.oi-media-step-backward:before{content:'\e097'}.oi-media-step-forward:before{content:'\e098'}.oi-media-stop:before{content:'\e099'}.oi-medical-cross:before{content:'\e09a'}.oi-menu:before{content:'\e09b'}.oi-microphone:before{content:'\e09c'}.oi-minus:before{content:'\e09d'}.oi-monitor:before{content:'\e09e'}.oi-moon:before{content:'\e09f'}.oi-move:before{content:'\e0a0'}.oi-musical-note:before{content:'\e0a1'}.oi-paperclip:before{content:'\e0a2'}.oi-pencil:before{content:'\e0a3'}.oi-people:before{content:'\e0a4'}.oi-person:before{content:'\e0a5'}.oi-phone:before{content:'\e0a6'}.oi-pie-chart:before{content:'\e0a7'}.oi-pin:before{content:'\e0a8'}.oi-play-circle:before{content:'\e0a9'}.oi-plus:before{content:'\e0aa'}.oi-power-standby:before{content:'\e0ab'}.oi-print:before{content:'\e0ac'}.oi-project:before{content:'\e0ad'}.oi-pulse:before{content:'\e0ae'}.oi-puzzle-piece:before{content:'\e0af'}.oi-question-mark:before{content:'\e0b0'}.oi-rain:before{content:'\e0b1'}.oi-random:before{content:'\e0b2'}.oi-reload:before{content:'\e0b3'}.oi-resize-both:before{content:'\e0b4'}.oi-resize-height:before{content:'\e0b5'}.oi-resize-width:before{content:'\e0b6'}.oi-rss-alt:before{content:'\e0b7'}.oi-rss:before{content:'\e0b8'}.oi-script:before{content:'\e0b9'}.oi-share-boxed:before{content:'\e0ba'}.oi-share:before{content:'\e0bb'}.oi-shield:before{content:'\e0bc'}.oi-signal:before{content:'\e0bd'}.oi-signpost:before{content:'\e0be'}.oi-sort-ascending:before{content:'\e0bf'}.oi-sort-descending:before{content:'\e0c0'}.oi-spreadsheet:before{content:'\e0c1'}.oi-star:before{content:'\e0c2'}.oi-sun:before{content:'\e0c3'}.oi-tablet:before{content:'\e0c4'}.oi-tag:before{content:'\e0c5'}.oi-tags:before{content:'\e0c6'}.oi-target:before{content:'\e0c7'}.oi-task:before{content:'\e0c8'}.oi-terminal:before{content:'\e0c9'}.oi-text:before{content:'\e0ca'}.oi-thumb-down:before{content:'\e0cb'}.oi-thumb-up:before{content:'\e0cc'}.oi-timer:before{content:'\e0cd'}.oi-transfer:before{content:'\e0ce'}.oi-trash:before{content:'\e0cf'}.oi-underline:before{content:'\e0d0'}.oi-vertical-align-bottom:before{content:'\e0d1'}.oi-vertical-align-center:before{content:'\e0d2'}.oi-vertical-align-top:before{content:'\e0d3'}.oi-video:before{content:'\e0d4'}.oi-volume-high:before{content:'\e0d5'}.oi-volume-low:before{content:'\e0d6'}.oi-volume-off:before{content:'\e0d7'}.oi-warning:before{content:'\e0d8'}.oi-wifi:before{content:'\e0d9'}.oi-wrench:before{content:'\e0da'}.oi-x:before{content:'\e0db'}.oi-yen:before{content:'\e0dc'}.oi-zoom-in:before{content:'\e0dd'}.oi-zoom-out:before{content:'\e0de'} -------------------------------------------------------------------------------- /samples/BlazorWebAssembly/wwwroot/css/open-iconic/font/css/open-iconic-bootstrap.min.css: -------------------------------------------------------------------------------- 1 | @font-face{font-family:Icons;src:url(../fonts/open-iconic.eot);src:url(../fonts/open-iconic.eot?#iconic-sm) format('embedded-opentype'),url(../fonts/open-iconic.woff) format('woff'),url(../fonts/open-iconic.ttf) format('truetype'),url(../fonts/open-iconic.otf) format('opentype'),url(../fonts/open-iconic.svg#iconic-sm) format('svg');font-weight:400;font-style:normal}.oi{position:relative;top:1px;display:inline-block;speak:none;font-family:Icons;font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.oi:empty:before{width:1em;text-align:center;box-sizing:content-box}.oi.oi-align-center:before{text-align:center}.oi.oi-align-left:before{text-align:left}.oi.oi-align-right:before{text-align:right}.oi.oi-flip-horizontal:before{-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.oi.oi-flip-vertical:before{-webkit-transform:scale(1,-1);-ms-transform:scale(-1,1);transform:scale(1,-1)}.oi.oi-flip-horizontal-vertical:before{-webkit-transform:scale(-1,-1);-ms-transform:scale(-1,1);transform:scale(-1,-1)}.oi-account-login:before{content:'\e000'}.oi-account-logout:before{content:'\e001'}.oi-action-redo:before{content:'\e002'}.oi-action-undo:before{content:'\e003'}.oi-align-center:before{content:'\e004'}.oi-align-left:before{content:'\e005'}.oi-align-right:before{content:'\e006'}.oi-aperture:before{content:'\e007'}.oi-arrow-bottom:before{content:'\e008'}.oi-arrow-circle-bottom:before{content:'\e009'}.oi-arrow-circle-left:before{content:'\e00a'}.oi-arrow-circle-right:before{content:'\e00b'}.oi-arrow-circle-top:before{content:'\e00c'}.oi-arrow-left:before{content:'\e00d'}.oi-arrow-right:before{content:'\e00e'}.oi-arrow-thick-bottom:before{content:'\e00f'}.oi-arrow-thick-left:before{content:'\e010'}.oi-arrow-thick-right:before{content:'\e011'}.oi-arrow-thick-top:before{content:'\e012'}.oi-arrow-top:before{content:'\e013'}.oi-audio-spectrum:before{content:'\e014'}.oi-audio:before{content:'\e015'}.oi-badge:before{content:'\e016'}.oi-ban:before{content:'\e017'}.oi-bar-chart:before{content:'\e018'}.oi-basket:before{content:'\e019'}.oi-battery-empty:before{content:'\e01a'}.oi-battery-full:before{content:'\e01b'}.oi-beaker:before{content:'\e01c'}.oi-bell:before{content:'\e01d'}.oi-bluetooth:before{content:'\e01e'}.oi-bold:before{content:'\e01f'}.oi-bolt:before{content:'\e020'}.oi-book:before{content:'\e021'}.oi-bookmark:before{content:'\e022'}.oi-box:before{content:'\e023'}.oi-briefcase:before{content:'\e024'}.oi-british-pound:before{content:'\e025'}.oi-browser:before{content:'\e026'}.oi-brush:before{content:'\e027'}.oi-bug:before{content:'\e028'}.oi-bullhorn:before{content:'\e029'}.oi-calculator:before{content:'\e02a'}.oi-calendar:before{content:'\e02b'}.oi-camera-slr:before{content:'\e02c'}.oi-caret-bottom:before{content:'\e02d'}.oi-caret-left:before{content:'\e02e'}.oi-caret-right:before{content:'\e02f'}.oi-caret-top:before{content:'\e030'}.oi-cart:before{content:'\e031'}.oi-chat:before{content:'\e032'}.oi-check:before{content:'\e033'}.oi-chevron-bottom:before{content:'\e034'}.oi-chevron-left:before{content:'\e035'}.oi-chevron-right:before{content:'\e036'}.oi-chevron-top:before{content:'\e037'}.oi-circle-check:before{content:'\e038'}.oi-circle-x:before{content:'\e039'}.oi-clipboard:before{content:'\e03a'}.oi-clock:before{content:'\e03b'}.oi-cloud-download:before{content:'\e03c'}.oi-cloud-upload:before{content:'\e03d'}.oi-cloud:before{content:'\e03e'}.oi-cloudy:before{content:'\e03f'}.oi-code:before{content:'\e040'}.oi-cog:before{content:'\e041'}.oi-collapse-down:before{content:'\e042'}.oi-collapse-left:before{content:'\e043'}.oi-collapse-right:before{content:'\e044'}.oi-collapse-up:before{content:'\e045'}.oi-command:before{content:'\e046'}.oi-comment-square:before{content:'\e047'}.oi-compass:before{content:'\e048'}.oi-contrast:before{content:'\e049'}.oi-copywriting:before{content:'\e04a'}.oi-credit-card:before{content:'\e04b'}.oi-crop:before{content:'\e04c'}.oi-dashboard:before{content:'\e04d'}.oi-data-transfer-download:before{content:'\e04e'}.oi-data-transfer-upload:before{content:'\e04f'}.oi-delete:before{content:'\e050'}.oi-dial:before{content:'\e051'}.oi-document:before{content:'\e052'}.oi-dollar:before{content:'\e053'}.oi-double-quote-sans-left:before{content:'\e054'}.oi-double-quote-sans-right:before{content:'\e055'}.oi-double-quote-serif-left:before{content:'\e056'}.oi-double-quote-serif-right:before{content:'\e057'}.oi-droplet:before{content:'\e058'}.oi-eject:before{content:'\e059'}.oi-elevator:before{content:'\e05a'}.oi-ellipses:before{content:'\e05b'}.oi-envelope-closed:before{content:'\e05c'}.oi-envelope-open:before{content:'\e05d'}.oi-euro:before{content:'\e05e'}.oi-excerpt:before{content:'\e05f'}.oi-expand-down:before{content:'\e060'}.oi-expand-left:before{content:'\e061'}.oi-expand-right:before{content:'\e062'}.oi-expand-up:before{content:'\e063'}.oi-external-link:before{content:'\e064'}.oi-eye:before{content:'\e065'}.oi-eyedropper:before{content:'\e066'}.oi-file:before{content:'\e067'}.oi-fire:before{content:'\e068'}.oi-flag:before{content:'\e069'}.oi-flash:before{content:'\e06a'}.oi-folder:before{content:'\e06b'}.oi-fork:before{content:'\e06c'}.oi-fullscreen-enter:before{content:'\e06d'}.oi-fullscreen-exit:before{content:'\e06e'}.oi-globe:before{content:'\e06f'}.oi-graph:before{content:'\e070'}.oi-grid-four-up:before{content:'\e071'}.oi-grid-three-up:before{content:'\e072'}.oi-grid-two-up:before{content:'\e073'}.oi-hard-drive:before{content:'\e074'}.oi-header:before{content:'\e075'}.oi-headphones:before{content:'\e076'}.oi-heart:before{content:'\e077'}.oi-home:before{content:'\e078'}.oi-image:before{content:'\e079'}.oi-inbox:before{content:'\e07a'}.oi-infinity:before{content:'\e07b'}.oi-info:before{content:'\e07c'}.oi-italic:before{content:'\e07d'}.oi-justify-center:before{content:'\e07e'}.oi-justify-left:before{content:'\e07f'}.oi-justify-right:before{content:'\e080'}.oi-key:before{content:'\e081'}.oi-laptop:before{content:'\e082'}.oi-layers:before{content:'\e083'}.oi-lightbulb:before{content:'\e084'}.oi-link-broken:before{content:'\e085'}.oi-link-intact:before{content:'\e086'}.oi-list-rich:before{content:'\e087'}.oi-list:before{content:'\e088'}.oi-location:before{content:'\e089'}.oi-lock-locked:before{content:'\e08a'}.oi-lock-unlocked:before{content:'\e08b'}.oi-loop-circular:before{content:'\e08c'}.oi-loop-square:before{content:'\e08d'}.oi-loop:before{content:'\e08e'}.oi-magnifying-glass:before{content:'\e08f'}.oi-map-marker:before{content:'\e090'}.oi-map:before{content:'\e091'}.oi-media-pause:before{content:'\e092'}.oi-media-play:before{content:'\e093'}.oi-media-record:before{content:'\e094'}.oi-media-skip-backward:before{content:'\e095'}.oi-media-skip-forward:before{content:'\e096'}.oi-media-step-backward:before{content:'\e097'}.oi-media-step-forward:before{content:'\e098'}.oi-media-stop:before{content:'\e099'}.oi-medical-cross:before{content:'\e09a'}.oi-menu:before{content:'\e09b'}.oi-microphone:before{content:'\e09c'}.oi-minus:before{content:'\e09d'}.oi-monitor:before{content:'\e09e'}.oi-moon:before{content:'\e09f'}.oi-move:before{content:'\e0a0'}.oi-musical-note:before{content:'\e0a1'}.oi-paperclip:before{content:'\e0a2'}.oi-pencil:before{content:'\e0a3'}.oi-people:before{content:'\e0a4'}.oi-person:before{content:'\e0a5'}.oi-phone:before{content:'\e0a6'}.oi-pie-chart:before{content:'\e0a7'}.oi-pin:before{content:'\e0a8'}.oi-play-circle:before{content:'\e0a9'}.oi-plus:before{content:'\e0aa'}.oi-power-standby:before{content:'\e0ab'}.oi-print:before{content:'\e0ac'}.oi-project:before{content:'\e0ad'}.oi-pulse:before{content:'\e0ae'}.oi-puzzle-piece:before{content:'\e0af'}.oi-question-mark:before{content:'\e0b0'}.oi-rain:before{content:'\e0b1'}.oi-random:before{content:'\e0b2'}.oi-reload:before{content:'\e0b3'}.oi-resize-both:before{content:'\e0b4'}.oi-resize-height:before{content:'\e0b5'}.oi-resize-width:before{content:'\e0b6'}.oi-rss-alt:before{content:'\e0b7'}.oi-rss:before{content:'\e0b8'}.oi-script:before{content:'\e0b9'}.oi-share-boxed:before{content:'\e0ba'}.oi-share:before{content:'\e0bb'}.oi-shield:before{content:'\e0bc'}.oi-signal:before{content:'\e0bd'}.oi-signpost:before{content:'\e0be'}.oi-sort-ascending:before{content:'\e0bf'}.oi-sort-descending:before{content:'\e0c0'}.oi-spreadsheet:before{content:'\e0c1'}.oi-star:before{content:'\e0c2'}.oi-sun:before{content:'\e0c3'}.oi-tablet:before{content:'\e0c4'}.oi-tag:before{content:'\e0c5'}.oi-tags:before{content:'\e0c6'}.oi-target:before{content:'\e0c7'}.oi-task:before{content:'\e0c8'}.oi-terminal:before{content:'\e0c9'}.oi-text:before{content:'\e0ca'}.oi-thumb-down:before{content:'\e0cb'}.oi-thumb-up:before{content:'\e0cc'}.oi-timer:before{content:'\e0cd'}.oi-transfer:before{content:'\e0ce'}.oi-trash:before{content:'\e0cf'}.oi-underline:before{content:'\e0d0'}.oi-vertical-align-bottom:before{content:'\e0d1'}.oi-vertical-align-center:before{content:'\e0d2'}.oi-vertical-align-top:before{content:'\e0d3'}.oi-video:before{content:'\e0d4'}.oi-volume-high:before{content:'\e0d5'}.oi-volume-low:before{content:'\e0d6'}.oi-volume-off:before{content:'\e0d7'}.oi-warning:before{content:'\e0d8'}.oi-wifi:before{content:'\e0d9'}.oi-wrench:before{content:'\e0da'}.oi-x:before{content:'\e0db'}.oi-yen:before{content:'\e0dc'}.oi-zoom-in:before{content:'\e0dd'}.oi-zoom-out:before{content:'\e0de'} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Blazored Modal 2 | 3 | A beautiful and customizable modal implementation for [Blazor](https://blazor.net) applications. It's free-range, gluten-free and 100% JavaScript free. 4 | 5 | [![Build Status](https://dev.azure.com/blazored/Modal/_apis/build/status/Blazored.Modal?branchName=master)](https://dev.azure.com/blazored/Modal/_build/latest?definitionId=4&branchName=master) 6 | 7 | ![Nuget](https://img.shields.io/nuget/v/blazored.modal.svg) 8 | 9 | ![Screenshot of the component in action](screenshot.png) 10 | 11 | ## Getting Setup 12 | 13 | You can install the package via the nuget package manager just search for *Blazored.Modal*. You can also install via powershell using the following command. 14 | 15 | ```powershell 16 | Install-Package Blazored.Modal 17 | ``` 18 | 19 | Or via the dotnet CLI. 20 | 21 | ```bash 22 | dotnet add package Blazored.Modal 23 | ``` 24 | 25 | ### 1. Register Services 26 | 27 | **For Blazor Server**: You will need to add the following using statement and add a call to register the Blazored Modal services in your applications `Startup.ConfigureServices` method. 28 | 29 | ```csharp 30 | using Blazored.Modal; 31 | 32 | public void ConfigureServices(IServiceCollection services) 33 | { 34 | services.AddBlazoredModal(); 35 | } 36 | ``` 37 | 38 | **For Blazor WebAssembly**: You will need to add the following using statement and add a call to register the Blazored Modal services in your applications `Program.Main` method. 39 | 40 | ```csharp 41 | using Blazored.Modal; 42 | 43 | public static async Task Main(string[] args) 44 | { 45 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 46 | builder.RootComponents.Add("app"); 47 | 48 | builder.Services.AddBlazoredModal(); 49 | 50 | await builder.Build().RunAsync(); 51 | } 52 | ``` 53 | 54 | ### 2. Add Imports 55 | 56 | Add the following to your *_Imports.razor* 57 | 58 | ```razor 59 | @using Blazored 60 | @using Blazored.Modal 61 | @using Blazored.Modal.Services 62 | ``` 63 | 64 | ### 3. Add Modal Component 65 | 66 | Add the `` tag into your applications *MainLayout.razor*. 67 | 68 | ### 4. Add reference to style sheet 69 | 70 | Add the following line to the `head` tag of your `_Host.cshtml` (Blazor Server) or `index.html` (Blazor WebAssembly). 71 | 72 | ```html 73 | 74 | ``` 75 | 76 | ## Usage 77 | Please checkout the [sample projects](https://github.com/Blazored/Modal/tree/master/samples) in this repo to see working examples of the features in the modal. 78 | 79 | ### Displaying the modal 80 | 81 | In order to show a modal, you need to inject the `IModalService` into the component or service you want to invoke the modal. You can then call the `Show` method passing in the title for the modal and the type of the component you want the modal to display. 82 | 83 | For example, if I have a component called `Movies` which I want to display in the modal and I want to call it from the `Index` component on a button click. 84 | 85 | ```razor 86 | @page "/" 87 | @inject IModalService Modal 88 | 89 |

      Hello, world!

      90 | 91 | Welcome to Blazored Modal. 92 | 93 | 94 | ``` 95 | 96 | ### Passing Parameters 97 | 98 | If you want to pass values to the component you're displaying in the modal, then you can use the `ModalParameters` object. The name you provide must match the name of a parameter defined on the component being displayed. 99 | 100 | #### Index Component 101 | 102 | ```razor 103 | @page "/" 104 | @inject IModalService Modal 105 | 106 |

      My Movies

      107 | 108 |
        109 | @foreach (var movie in Movies) 110 | { 111 |
      • @movie.Name (@movie.Year) -
      • 112 | } 113 |
      114 | 115 | @code { 116 | 117 | List Movies { get; set; } 118 | 119 | void ShowEditMovie(int movieId) 120 | { 121 | var parameters = new ModalParameters(); 122 | parameters.Add(nameof(EditMovie.MovieId), movieId); 123 | 124 | Modal.Show("Edit Movie", parameters); 125 | } 126 | 127 | } 128 | ``` 129 | 130 | #### EditMovie Component 131 | 132 | ```razor 133 | @inject IMovieService MovieService 134 | @inject IModalService ModalService 135 | 136 |
      137 | 138 |
      139 | 140 | 141 |
      142 | 143 |
      144 | 145 | 146 |
      147 | 148 | 149 | 150 |
      151 | 152 | @code { 153 | 154 | [CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; } 155 | 156 | [Parameter] public int MovieId { get; set; } 157 | 158 | Movie Movie { get; set; } 159 | 160 | protected override void OnInitialized() 161 | { 162 | Movie = MovieService.Load(MovieId); 163 | } 164 | 165 | void SaveMovie() 166 | { 167 | MovieService.Save(Movie); 168 | BlazoredModal.Close(ModalResult.Ok(Movie)); 169 | } 170 | 171 | } 172 | ``` 173 | 174 | ### Modal Reference 175 | 176 | When you open a modal you can capture a reference to it and await the result of that modal. This is useful when you want to perform an action when a modal is closed or cancelled. 177 | 178 | ```razor 179 | @page "/" 180 | @inject IModalService Modal 181 | 182 |

      My Movies

      183 | 184 | 185 | 186 | @code { 187 | async Task ShowModal() 188 | { 189 | var moviesModal = Modal.Show("My Movies"); 190 | var result = await moviesModal.Result; 191 | 192 | if (result.Cancelled) 193 | { 194 | Console.WriteLine("Modal was cancelled"); 195 | } 196 | else 197 | { 198 | Console.WriteLine("Modal was closed"); 199 | } 200 | } 201 | } 202 | ``` 203 | 204 | ### Returning objects back to the calling code 205 | 206 | It is common to want to return messages or objects back from a modal to the calling code. This is achieved using the `ModalResult` class. 207 | 208 | In the example below, when the form is submitted a `ModalResult.Ok` containing the string "Form was submitted successfully." will be returned back to the calling code. If it is cancelled a `ModalResult.Cancelled` will be returned. 209 | 210 | ```razor 211 |
      212 | 213 |
      214 | 215 | 216 |
      217 | 218 |
      219 | 220 | 221 |
      222 | 223 | 224 | 225 |
      226 | 227 | @code { 228 | 229 | [CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; } 230 | 231 | bool ShowForm { get; set; } = true; 232 | string FirstName { get; set; } 233 | string LastName { get; set; } 234 | int FormId { get; set; } 235 | 236 | void SubmitForm() 237 | { 238 | BlazoredModal.Close(ModalResult.Ok($"Form was submitted successfully.")); 239 | } 240 | 241 | void Cancel() 242 | { 243 | BlazoredModal.Cancel(); 244 | } 245 | 246 | } 247 | ``` 248 | 249 | Below is the caller for the component above. When the result is returned the string set in the `Ok` method can be access via the `Data` property on the `ModalResult`. 250 | 251 | ```razor 252 | @page "/" 253 | @inject IModalService Modal 254 | 255 | 256 | 257 | @code { 258 | async Task ShowModal() 259 | { 260 | var formModal = Modal.Show("Please SignUp"); 261 | var result = await formModal.Result; 262 | 263 | if (result.Cancelled) 264 | { 265 | Console.WriteLine("Modal was cancelled"); 266 | } 267 | else 268 | { 269 | Console.WriteLine(result.Data); 270 | } 271 | } 272 | } 273 | ``` 274 | 275 | The example above is only using a string value but you can also pass complex objects back as well. 276 | 277 | ### Customizing the modal 278 | 279 | The modals can be customized to fit a wide variety of uses. These options can be set globally or changed programatically on a per modal basis. 280 | 281 | #### Hiding the close button 282 | 283 | A modal has a close button in the top right hand corner by default. The close button can be hidden by using the `HideCloseButton` parameter: 284 | 285 | `` 286 | 287 | Or in the `Modal.Show()` method: 288 | 289 | ```razor 290 | @code { 291 | void ShowModal() 292 | { 293 | var options = new ModalOptions() 294 | { 295 | HideCloseButton = false 296 | }; 297 | 298 | Modal.Show("My Movies", options); 299 | } 300 | } 301 | ``` 302 | 303 | #### Disabling background click cancellation 304 | 305 | You can disable cancelling the modal by clicking on the background using the `DisableBackgroundCancel` parameter. 306 | 307 | `` 308 | 309 | Or in the `Modal.Show()` method: 310 | 311 | ```razor 312 | @code { 313 | void ShowModal() 314 | { 315 | var options = new ModalOptions() 316 | { 317 | DisableBackgroundCancel = true 318 | }; 319 | 320 | Modal.Show("My Movies", options); 321 | } 322 | } 323 | ``` 324 | 325 | #### Styling the modal 326 | 327 | You can set an alternative CSS style for the modal if you want to customize the look and feel. This is useful when your web application requires different kinds of modals, like a warning, confirmation or an input form. 328 | 329 | Use the `Class` parameter to set the custom styling globally: 330 | 331 | `` 332 | 333 | Or in the `Modal.Show()` method: 334 | 335 | ```razor 336 | @code { 337 | void ShowModal() 338 | { 339 | var options = new ModalOptions() 340 | { 341 | Class = "blazored-modal-movies" 342 | }; 343 | 344 | Modal.Show("My Movies", options); 345 | } 346 | } 347 | ``` 348 | 349 | #### Setting the position 350 | 351 | Modals are shown in the center of the viewport by default. The modal can be shown in different positions if needed. The positioning is flexible as it is set using CSS styling. 352 | 353 | The following positioning styles are available out of the box: `blazored-modal-center`, `blazored-modal-topleft`, `blazored-modal-topright`, `blazored-modal-bottomleft` and `blazored-modal-bottomright`. 354 | 355 | Use the `Style` parameter to set the custom styling globally: 356 | 357 | `` 358 | 359 | Or in the `Modal.Show()` method: 360 | 361 | ```razor 362 | @code { 363 | void ShowModal() 364 | { 365 | var options = new ModalOptions() 366 | { 367 | Position = "blazored-modal-bottomleft" 368 | }; 369 | 370 | Modal.Show("My Movies", options); 371 | } 372 | } 373 | ``` 374 | 375 | ### Multiple Modals 376 | 377 | It's possible to have multiple active modal instances at a time. You can find a working example of this in the sample projects but here is some sample code. 378 | 379 | Below is a component which being displayed inside a Blazored Modal instance. When a user clicks on the _Delete_ button the `Yes` method is invoked and creates a new modal instance. 380 | 381 | ```razor 382 | @inject IModalService ModalService 383 | 384 |
      385 |
      386 | Are you sure you want to delete the record? 387 |
      388 | 389 | 390 | 391 |
      392 | 393 | @code { 394 | 395 | [CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; } 396 | 397 | async Task Yes() 398 | { 399 | var confirmationModal = ModalService.Show(); 400 | var result = await confirmationModal.Result; 401 | 402 | if (result.Cancelled) 403 | return; 404 | 405 | BlazoredModal.Close(ModalResult.Ok($"The user said 'Yes'")); 406 | } 407 | 408 | void No() 409 | { 410 | BlazoredModal.Close(ModalResult.Cancel()); 411 | } 412 | 413 | } 414 | ``` 415 | --------------------------------------------------------------------------------