diff --git a/.github/workflows/publish_demo.yml b/.github/workflows/publish_demo.yml new file mode 100644 index 0000000..d090861 --- /dev/null +++ b/.github/workflows/publish_demo.yml @@ -0,0 +1,48 @@ +# ------------------------------------------------------------------------------ +# +# +# This code was generated. +# +# - To turn off auto-generation set: +# +# [GitHubActions (AutoGenerate = false)] +# +# - To trigger manual generation invoke: +# +# nuke --generate-configuration GitHubActions_publish_demo --host GitHubActions +# +# +# ------------------------------------------------------------------------------ + +name: publish_demo + +on: [workflow_dispatch] + +permissions: + contents: write + pages: write + +jobs: + ubuntu-latest: + name: ubuntu-latest + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 10000 + - name: 'Cache: .nuke/temp, ~/.nuget/packages' + uses: actions/cache@v3 + with: + path: | + .nuke/temp + ~/.nuget/packages + key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }} + - name: 'Run: Clean, BuildDemo, DeployDemo' + run: ./build.cmd Clean BuildDemo DeployDemo + env: + TokenGithub: ${{ secrets.TOKEN_GITHUB }} + - name: 'Publish: demo.zip' + uses: actions/upload-artifact@v3 + with: + name: demo.zip + path: artifacts/demo.zip diff --git a/.gitignore b/.gitignore index 0f425b8..7e8a8bc 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ obj/ riderModule.iml /_ReSharper.Caches/ artifacts/ -.nuke/temp \ No newline at end of file +.nuke/temp +temp/ \ No newline at end of file diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json index b1bce39..cf70c3f 100644 --- a/.nuke/build.schema.json +++ b/.nuke/build.schema.json @@ -6,6 +6,10 @@ "build": { "type": "object", "properties": { + "BaseUrl": { + "type": "string", + "description": "Base url" + }, "Configuration": { "type": "string", "description": "Configuration to build - Default is 'Debug' (local) or 'Release' (server)", @@ -85,8 +89,10 @@ "items": { "type": "string", "enum": [ + "BuildDemo", "Clean", "Compile", + "DeployDemo", "Pack", "Push", "Restore", @@ -104,8 +110,10 @@ "items": { "type": "string", "enum": [ + "BuildDemo", "Clean", "Compile", + "DeployDemo", "Pack", "Push", "Restore", @@ -113,6 +121,11 @@ ] } }, + "TokenGithub": { + "type": "string", + "description": "Github token", + "default": "Secrets must be entered via 'nuke :secrets [profile]'" + }, "Verbosity": { "type": "string", "description": "Logging verbosity during build execution. Default is 'Normal'", diff --git a/GitVersion.yml b/GitVersion.yml index c47807b..b08df24 100644 --- a/GitVersion.yml +++ b/GitVersion.yml @@ -1,5 +1,11 @@ mode: Mainline -branches: {} +branches: + develop: + is-mainline: true + source-branches: [ ] + increment: Patch + tag: beta + regex: (origin/)?development$ ignore: sha: [] merge-message-formats: {} diff --git a/README.md b/README.md index d7818a1..be8f876 100644 --- a/README.md +++ b/README.md @@ -9,13 +9,14 @@ This package contains a simple blazor dropdown component that supports single an 2. Add the following to the `` of your `App.razor` or `index.html` file: ```html - - + + ``` ## Usage See the project `SimpleBlazorMultiselectDemo` for more examples of how to use the component, or take a look at the properties page on the [wiki](https://github.com/BorisGerretzen/SimpleBlazorMultiselect/wiki/Properties). +The demo project is hosted on [GitHub Pages](https://borisgerretzen.github.io/SimpleBlazorMultiselect/). Below are some short examples, they all use the following `@code` block: ```csharp diff --git a/SimpleBlazorMultiselect.sln b/SimpleBlazorMultiselect.sln index 7df1c1d..6981d47 100644 --- a/SimpleBlazorMultiselect.sln +++ b/SimpleBlazorMultiselect.sln @@ -1,10 +1,10 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleBlazorMultiselect", "SimpleBlazorMultiselect\SimpleBlazorMultiselect.csproj", "{AEFF45E1-DA9E-427F-908F-2C142523BDAA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "_build", "build\_build.csproj", "{49DA0B6E-92AE-41C0-8763-16D0303F2015}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleBlazorMultiselectDemo", "SimpleBlazorMultiselectDemo\SimpleBlazorMultiselectDemo.csproj", "{B04E859C-9794-41AC-BD91-4544276A5FC8}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleBlazorMultiselect", "src\SimpleBlazorMultiselect\SimpleBlazorMultiselect.csproj", "{1F3DCC28-1FD5-4F3C-B43D-564A44DBE398}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "_build", "build\_build.csproj", "{49DA0B6E-92AE-41C0-8763-16D0303F2015}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleBlazorMultiselect.Demo", "src\SimpleBlazorMultiselect.Demo\SimpleBlazorMultiselect.Demo.csproj", "{025632E8-CB51-4E49-B47C-B9C75D35A874}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -14,13 +14,13 @@ Global GlobalSection(ProjectConfigurationPlatforms) = postSolution {49DA0B6E-92AE-41C0-8763-16D0303F2015}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {49DA0B6E-92AE-41C0-8763-16D0303F2015}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AEFF45E1-DA9E-427F-908F-2C142523BDAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AEFF45E1-DA9E-427F-908F-2C142523BDAA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AEFF45E1-DA9E-427F-908F-2C142523BDAA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AEFF45E1-DA9E-427F-908F-2C142523BDAA}.Release|Any CPU.Build.0 = Release|Any CPU - {B04E859C-9794-41AC-BD91-4544276A5FC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B04E859C-9794-41AC-BD91-4544276A5FC8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B04E859C-9794-41AC-BD91-4544276A5FC8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B04E859C-9794-41AC-BD91-4544276A5FC8}.Release|Any CPU.Build.0 = Release|Any CPU + {1F3DCC28-1FD5-4F3C-B43D-564A44DBE398}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1F3DCC28-1FD5-4F3C-B43D-564A44DBE398}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1F3DCC28-1FD5-4F3C-B43D-564A44DBE398}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1F3DCC28-1FD5-4F3C-B43D-564A44DBE398}.Release|Any CPU.Build.0 = Release|Any CPU + {025632E8-CB51-4E49-B47C-B9C75D35A874}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {025632E8-CB51-4E49-B47C-B9C75D35A874}.Debug|Any CPU.Build.0 = Debug|Any CPU + {025632E8-CB51-4E49-B47C-B9C75D35A874}.Release|Any CPU.ActiveCfg = Release|Any CPU + {025632E8-CB51-4E49-B47C-B9C75D35A874}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/SimpleBlazorMultiselectDemo/Components/App.razor b/SimpleBlazorMultiselectDemo/Components/App.razor deleted file mode 100644 index 5501298..0000000 --- a/SimpleBlazorMultiselectDemo/Components/App.razor +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/SimpleBlazorMultiselectDemo/Components/Pages/Error.razor b/SimpleBlazorMultiselectDemo/Components/Pages/Error.razor deleted file mode 100644 index 30c1b33..0000000 --- a/SimpleBlazorMultiselectDemo/Components/Pages/Error.razor +++ /dev/null @@ -1,38 +0,0 @@ -@page "/Error" -@using System.Diagnostics - -Error - -

Error.

-

An error occurred while processing your request.

- -@if (ShowRequestId) -{ -

- Request ID: @RequestId -

-} - -

Development Mode

-

- Swapping to Development environment will display more detailed information about the error that occurred. -

-

- The Development environment shouldn't be enabled for deployed applications. - It can result in displaying sensitive information from exceptions to end users. - For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development - and restarting the app. -

- -@code{ - - [CascadingParameter] - private HttpContext? HttpContext { get; set; } - - private string? RequestId { get; set; } - private bool ShowRequestId => !string.IsNullOrEmpty(RequestId); - - protected override void OnInitialized() => - RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier; - -} \ No newline at end of file diff --git a/SimpleBlazorMultiselectDemo/Components/Routes.razor b/SimpleBlazorMultiselectDemo/Components/Routes.razor deleted file mode 100644 index bf0ce0b..0000000 --- a/SimpleBlazorMultiselectDemo/Components/Routes.razor +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/SimpleBlazorMultiselectDemo/Program.cs b/SimpleBlazorMultiselectDemo/Program.cs deleted file mode 100644 index 80b4880..0000000 --- a/SimpleBlazorMultiselectDemo/Program.cs +++ /dev/null @@ -1,27 +0,0 @@ -using SimpleBlazorMultiselectDemo.Components; - -var builder = WebApplication.CreateBuilder(args); - -// Add services to the container. -builder.Services.AddRazorComponents() - .AddInteractiveServerComponents(); - -var app = builder.Build(); - -// Configure the HTTP request pipeline. -if (!app.Environment.IsDevelopment()) -{ - app.UseExceptionHandler("/Error", createScopeForErrors: true); - // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. - app.UseHsts(); -} - -app.UseHttpsRedirection(); - -app.UseStaticFiles(); -app.UseAntiforgery(); - -app.MapRazorComponents() - .AddInteractiveServerRenderMode(); - -app.Run(); \ No newline at end of file diff --git a/SimpleBlazorMultiselectDemo/Properties/launchSettings.json b/SimpleBlazorMultiselectDemo/Properties/launchSettings.json deleted file mode 100644 index 8a50e8c..0000000 --- a/SimpleBlazorMultiselectDemo/Properties/launchSettings.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:11997", - "sslPort": 44358 - } - }, - "profiles": { - "http": { - "commandName": "Project", - "dotnetRunMessages": true, - "applicationUrl": "http://localhost:5223", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "https": { - "commandName": "Project", - "dotnetRunMessages": true, - "applicationUrl": "https://localhost:7261;http://localhost:5223", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } - } diff --git a/SimpleBlazorMultiselectDemo/appsettings.Development.json b/SimpleBlazorMultiselectDemo/appsettings.Development.json deleted file mode 100644 index 0c208ae..0000000 --- a/SimpleBlazorMultiselectDemo/appsettings.Development.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - } -} diff --git a/SimpleBlazorMultiselectDemo/appsettings.json b/SimpleBlazorMultiselectDemo/appsettings.json deleted file mode 100644 index 10f68b8..0000000 --- a/SimpleBlazorMultiselectDemo/appsettings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*" -} diff --git a/build/Build.cs b/build/Build.cs index ebbad02..90da7f7 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -1,48 +1,71 @@ using System; using System.Linq; +using System.Threading.Tasks; using Nuke.Common; -using Nuke.Common.CI; using Nuke.Common.CI.GitHubActions; -using Nuke.Common.Execution; +using Nuke.Common.Git; using Nuke.Common.IO; using Nuke.Common.ProjectModel; using Nuke.Common.Tooling; using Nuke.Common.Tools.DotNet; +using Nuke.Common.Tools.GitHub; using Nuke.Common.Tools.GitVersion; +using Nuke.Common.Utilities; using Nuke.Common.Utilities.Collections; -using static Nuke.Common.EnvironmentInfo; -using static Nuke.Common.IO.FileSystemTasks; -using static Nuke.Common.IO.PathConstruction; +using Octokit; +using Octokit.Internal; using static Nuke.Common.Tools.DotNet.DotNetTasks; +using Project = Nuke.Common.ProjectModel.Project; [GitHubActions("test", GitHubActionsImage.UbuntuLatest, On = new[] { GitHubActionsTrigger.PullRequest, GitHubActionsTrigger.WorkflowDispatch }, InvokedTargets = new[] { nameof(Test) }, FetchDepth = 10000)] [GitHubActions("publish", GitHubActionsImage.UbuntuLatest, On = new[] { GitHubActionsTrigger.WorkflowDispatch }, InvokedTargets = new[] { nameof(Pack), nameof(Push) }, ImportSecrets = new[] { nameof(NugetApiKey) }, FetchDepth = 10000)] +[GitHubActions("publish demo", + GitHubActionsImage.UbuntuLatest, + On = new[] { GitHubActionsTrigger.WorkflowDispatch }, + InvokedTargets = new[] { nameof(Clean), nameof(BuildDemo), nameof(DeployDemo) }, + FetchDepth = 10000, + ImportSecrets = new[] {nameof(TokenGithub)}, + WritePermissions = new[] { GitHubActionsPermissions.Contents, GitHubActionsPermissions.Pages } + )] class Build : NukeBuild { - [Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")] readonly Configuration Configuration = IsLocalBuild ? Configuration.Debug : Configuration.Release; + [Nuke.Common.Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")] readonly Configuration Configuration = IsLocalBuild ? Configuration.Debug : Configuration.Release; [GitVersion] readonly GitVersion GitVersion; - [Parameter("API Key for the NuGet server.")] [Secret] readonly string NugetApiKey; + [Nuke.Common.Parameter("API Key for the NuGet server.")] [Secret] readonly string NugetApiKey; - [Parameter("NuGet server URL.")] readonly string NugetSource = "https://api.nuget.org/v3/index.json"; + [Nuke.Common.Parameter("NuGet server URL.")] readonly string NugetSource = "https://api.nuget.org/v3/index.json"; - [Parameter("NuGet package version.")] readonly string PackageVersion; + [Nuke.Common.Parameter("NuGet package version.")] readonly string PackageVersion; + + [Nuke.Common.Parameter("Github token.")] [Secret] readonly string TokenGithub; + [Nuke.Common.Parameter("Base url.")] readonly string BaseUrl = "/SimpleBlazorMultiselect/"; + + [GitRepository] readonly GitRepository Repository; [Solution] readonly Solution Solution; AbsolutePath SourceDirectory => RootDirectory / "src"; - AbsolutePath TestsDirectory => RootDirectory / "tests"; AbsolutePath ArtifactsDirectory => RootDirectory / "artifacts"; - - Project TargetProject => Solution.GetProject("SimpleBlazorMultiselect"); - + AbsolutePath TempDirectory => RootDirectory / "temp"; + AbsolutePath DemoDirectory => TempDirectory / "demo"; + + Project LibProject => Solution.GetProject("SimpleBlazorMultiselect"); + Project DemoProject => Solution.GetProject("SimpleBlazorMultiselect.Demo"); + Target Clean => _ => _ .Before(Restore) .Executes(() => { - SourceDirectory.GlobDirectories("**/bin", "**/obj").ForEach(path => path.DeleteDirectory()); - TestsDirectory.GlobDirectories("**/bin", "**/obj").ForEach(path => path.DeleteDirectory()); + TempDirectory.CreateOrCleanDirectory(); + DemoDirectory.CreateOrCleanDirectory(); + SourceDirectory.GlobDirectories("**/bin", "**/obj") + .ForEach(path => + { + Console.WriteLine($"Removing '{path}'"); + path.DeleteDirectory(); + }); ArtifactsDirectory.CreateOrCleanDirectory(); }); @@ -65,8 +88,22 @@ class Build : NukeBuild .SetAssemblyVersion(GitVersion.AssemblySemVer) .SetFileVersion(GitVersion.AssemblySemFileVer) .SetInformationalVersion(GitVersion.InformationalVersion) + .CombineWith( + from project in new[] { LibProject, DemoProject } + from framework in project.GetTargetFrameworks() + select new { project, framework }, (cs, v) => cs + .SetProjectFile(v.project.Path) + .SetFramework(v.framework) + ) ); + }); + Target BuildDemo => _ => _ + .DependsOn(Restore, Compile) + .Before(DeployDemo) + .Produces(ArtifactsDirectory / "demo.zip") + .Executes(() => + { DotNetPublish(s => s .EnableNoRestore() .EnableNoBuild() @@ -74,16 +111,96 @@ class Build : NukeBuild .SetAssemblyVersion(GitVersion.AssemblySemVer) .SetFileVersion(GitVersion.AssemblySemFileVer) .SetInformationalVersion(GitVersion.InformationalVersion) - .CombineWith( - from project in new[] { TargetProject } - from framework in project.GetTargetFrameworks() - select new { project, framework }, (cs, v) => cs - .SetProject(v.project) - .SetFramework(v.framework) - ) + .SetProject(DemoProject) + .SetOutput(DemoDirectory) ); + + var zipPath = ArtifactsDirectory / "demo.zip"; + zipPath.DeleteFile(); + (DemoDirectory / "wwwroot").CompressTo(zipPath); }); + Target DeployDemo => _ => _ + .Requires(() => Configuration == Configuration.Release) + .Executes(async () => + { + var credentials = new Credentials(TokenGithub); + GitHubTasks.GitHubClient = new GitHubClient(new ProductHeaderValue(nameof(NukeBuild)), + new InMemoryCredentialStore(credentials)); + var client = GitHubTasks.GitHubClient; + + var repoOwner = Repository.GetGitHubOwner(); + var repoName = Repository.GetGitHubName(); + + var ghPagesBranch = await client.Repository.Branch.Get(repoOwner, repoName, "gh-pages"); + var latestCommit = await client.Git.Commit.Get(repoOwner, repoName, ghPagesBranch.Commit.Sha); + + var wwwroot = DemoDirectory / "wwwroot"; + var files = wwwroot.GlobFiles("**/*"); + var newTree = new NewTree(); + newTree.Tree.Add(new NewTreeItem + { + Path = ".nojekyll", + Mode = "100644", + Type = TreeType.Blob, + Content = "" + }); + + newTree.Tree.Add(new NewTreeItem + { + Path = ".gitattributes", + Mode = "100644", + Type = TreeType.Blob, + Content = "* binary" + }); + + // replace base href + var indexHtml = wwwroot / "index.html"; + var indexHtmlContent = indexHtml.ReadAllText(); + indexHtmlContent = indexHtmlContent.ReplaceRegex("()", m => $"{m.Groups[1].Value}{BaseUrl}{m.Groups[3].Value}"); + indexHtml.WriteAllText(indexHtmlContent); + + var tasks = files.Select(async file => + { + var bytes = file.ReadAllBytes(); + var base64String = Convert.ToBase64String(bytes); + if (string.IsNullOrEmpty(base64String)) return; + var blob = new NewBlob + { + Content = base64String, + Encoding = EncodingType.Base64 + }; + + var blobRef = await client.Git.Blob.Create(repoOwner, repoName, blob); + newTree.Tree.Add(new NewTreeItem + { + Path = file.ToString()! + .Replace(wwwroot.ToString()!, "") + .Replace("\\", "/") + .TrimStart('/'), + Mode = "100644", + Type = TreeType.Blob, + Sha = blobRef.Sha + }); + Console.WriteLine($"Added '{file}' to commit"); + }); + + await Task.WhenAll(tasks); + + Console.WriteLine("Creating new tree"); + var newTreeRef = await client.Git.Tree.Create(repoOwner, repoName, newTree); + Console.WriteLine($"Created new tree '{newTreeRef.Sha}'"); + + Console.WriteLine("Creating new commit"); + var newCommit = new NewCommit("Deploying to GitHub Pages", newTreeRef.Sha, latestCommit.Sha); + var commitRef = await client.Git.Commit.Create(repoOwner, repoName, newCommit); + Console.WriteLine($"Created new commit '{commitRef.Sha}'"); + + Console.WriteLine("Updating reference"); + await client.Git.Reference.Update(repoOwner, repoName, "heads/gh-pages", new ReferenceUpdate(commitRef.Sha)); + Console.WriteLine("Reference updated"); + }); + Target Test => _ => _ .DependsOn(Compile) .Executes(() => @@ -107,7 +224,7 @@ from framework in project.GetTargetFrameworks() DotNetPack(s => s .EnableNoRestore() .EnableNoBuild() - .SetProject(TargetProject) + .SetProject(LibProject) .SetConfiguration(Configuration) .SetOutputDirectory(ArtifactsDirectory) .SetProperty("PackageVersion", PackageVersion ?? GitVersion.NuGetVersionV2) diff --git a/build/_build.csproj b/build/_build.csproj index 608ff07..bba68e4 100644 --- a/build/_build.csproj +++ b/build/_build.csproj @@ -13,6 +13,7 @@ + diff --git a/src/SimpleBlazorMultiselect.Demo/App.razor b/src/SimpleBlazorMultiselect.Demo/App.razor new file mode 100644 index 0000000..c7730d1 --- /dev/null +++ b/src/SimpleBlazorMultiselect.Demo/App.razor @@ -0,0 +1,12 @@ + + + + + + + Not found + +

Sorry, there's nothing at this address.

+
+
+
\ No newline at end of file diff --git a/SimpleBlazorMultiselectDemo/Components/Layout/MainLayout.razor b/src/SimpleBlazorMultiselect.Demo/Layout/MainLayout.razor similarity index 100% rename from SimpleBlazorMultiselectDemo/Components/Layout/MainLayout.razor rename to src/SimpleBlazorMultiselect.Demo/Layout/MainLayout.razor diff --git a/SimpleBlazorMultiselectDemo/Components/Layout/MainLayout.razor.css b/src/SimpleBlazorMultiselect.Demo/Layout/MainLayout.razor.css similarity index 100% rename from SimpleBlazorMultiselectDemo/Components/Layout/MainLayout.razor.css rename to src/SimpleBlazorMultiselect.Demo/Layout/MainLayout.razor.css diff --git a/SimpleBlazorMultiselectDemo/Components/Layout/NavMenu.razor b/src/SimpleBlazorMultiselect.Demo/Layout/NavMenu.razor similarity index 58% rename from SimpleBlazorMultiselectDemo/Components/Layout/NavMenu.razor rename to src/SimpleBlazorMultiselect.Demo/Layout/NavMenu.razor index f1dcebe..19f02f0 100644 --- a/SimpleBlazorMultiselectDemo/Components/Layout/NavMenu.razor +++ b/src/SimpleBlazorMultiselect.Demo/Layout/NavMenu.razor @@ -40,7 +40,34 @@ CustomTemplate + + + + + + + + + + + + + - \ No newline at end of file diff --git a/SimpleBlazorMultiselectDemo/Components/Layout/NavMenu.razor.css b/src/SimpleBlazorMultiselect.Demo/Layout/NavMenu.razor.css similarity index 100% rename from SimpleBlazorMultiselectDemo/Components/Layout/NavMenu.razor.css rename to src/SimpleBlazorMultiselect.Demo/Layout/NavMenu.razor.css diff --git a/SimpleBlazorMultiselectDemo/Models/SimpleItem.cs b/src/SimpleBlazorMultiselect.Demo/Models/SimpleItem.cs similarity index 100% rename from SimpleBlazorMultiselectDemo/Models/SimpleItem.cs rename to src/SimpleBlazorMultiselect.Demo/Models/SimpleItem.cs diff --git a/SimpleBlazorMultiselectDemo/Components/Pages/BasicDropdown.razor b/src/SimpleBlazorMultiselect.Demo/Pages/BasicDropdown.razor similarity index 100% rename from SimpleBlazorMultiselectDemo/Components/Pages/BasicDropdown.razor rename to src/SimpleBlazorMultiselect.Demo/Pages/BasicDropdown.razor diff --git a/src/SimpleBlazorMultiselect.Demo/Pages/BigListNoVirtualize.razor b/src/SimpleBlazorMultiselect.Demo/Pages/BigListNoVirtualize.razor new file mode 100644 index 0000000..8ba5679 --- /dev/null +++ b/src/SimpleBlazorMultiselect.Demo/Pages/BigListNoVirtualize.razor @@ -0,0 +1,26 @@ +@page "/BigListNoVirtualize" +

Big list without virtualize

+
+
+ +
+
+ You have selected the following items: +
    + @foreach (var item in _selectedItems) + { +
  • @item
  • + } +
+
+
+ + +@code { + private readonly List _items = Enumerable.Range(1, 100_000).Select(i => $"Item {i}").ToList(); + private List _selectedItems = new(); + +} \ No newline at end of file diff --git a/src/SimpleBlazorMultiselect.Demo/Pages/BigListVirtualize.razor b/src/SimpleBlazorMultiselect.Demo/Pages/BigListVirtualize.razor new file mode 100644 index 0000000..9ce4ffd --- /dev/null +++ b/src/SimpleBlazorMultiselect.Demo/Pages/BigListVirtualize.razor @@ -0,0 +1,27 @@ +@page "/BigListVirtualize" +

Big list with virtualize

+
+
+ +
+
+ You have selected the following items: +
    + @foreach (var item in _selectedItems) + { +
  • @item
  • + } +
+
+
+ + +@code { + private readonly List _items = Enumerable.Range(1, 100_000).Select(i => $"Item {i}").ToList(); + private List _selectedItems = new(); + +} \ No newline at end of file diff --git a/src/SimpleBlazorMultiselect.Demo/Pages/CustomStyling.razor b/src/SimpleBlazorMultiselect.Demo/Pages/CustomStyling.razor new file mode 100644 index 0000000..24d5963 --- /dev/null +++ b/src/SimpleBlazorMultiselect.Demo/Pages/CustomStyling.razor @@ -0,0 +1,24 @@ +@page "/CustomStyling" +

CustomStyling

+ +
+
+ +
+
+ You have selected the following items: +
    + @foreach (var item in _selectedItems) + { +
  • @item
  • + } +
+
+
+ +@code { + private readonly List _items = new() { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", "Item 9", "Item 10" }; + private List _selectedItems = new(); +} \ No newline at end of file diff --git a/src/SimpleBlazorMultiselect.Demo/Pages/CustomStyling.razor.css b/src/SimpleBlazorMultiselect.Demo/Pages/CustomStyling.razor.css new file mode 100644 index 0000000..a3818f9 --- /dev/null +++ b/src/SimpleBlazorMultiselect.Demo/Pages/CustomStyling.razor.css @@ -0,0 +1,54 @@ +::deep .simple-dropdown .btn-outline-secondary { + --bs-btn-color: red; + --bs-btn-bg: black; + --bs-btn-border-color: green; + --bs-btn-border-width: 10px; + + animation: rainbow 2.5s linear; + animation-iteration-count: infinite; +} + +::deep .simple-dropdown .dropdown-item { + --bs-btn-color: red; + --bs-dropdown-link-hover-bg: yellow; +} + + +@keyframes rainbow{ + 100%,0%{ + --bs-btn-color: rgb(255,0,0); + } + 8%{ + --bs-btn-color: rgb(255,127,0); + } + 16%{ + --bs-btn-color: rgb(255,255,0); + } + 25%{ + --bs-btn-color: rgb(127,255,0); + } + 33%{ + --bs-btn-color: rgb(0,255,0); + } + 41%{ + --bs-btn-color: rgb(0,255,127); + } + 50%{ + --bs-btn-color: rgb(0,255,255); + } + 58%{ + --bs-btn-color: rgb(0,127,255); + } + 66%{ + --bs-btn-color: rgb(0,0,255); + } + 75%{ + --bs-btn-color: rgb(127,0,255); + } + 83%{ + --bs-btn-color: rgb(255,0,255); + } + 91%{ + --bs-btn-color: rgb(255,0,127); + } +} \ No newline at end of file diff --git a/SimpleBlazorMultiselectDemo/Components/Pages/CustomTemplate.razor b/src/SimpleBlazorMultiselect.Demo/Pages/CustomTemplate.razor similarity index 97% rename from SimpleBlazorMultiselectDemo/Components/Pages/CustomTemplate.razor rename to src/SimpleBlazorMultiselect.Demo/Pages/CustomTemplate.razor index dd12cbc..70993a7 100644 --- a/SimpleBlazorMultiselectDemo/Components/Pages/CustomTemplate.razor +++ b/src/SimpleBlazorMultiselect.Demo/Pages/CustomTemplate.razor @@ -13,7 +13,7 @@ Click on a selected item to remove it from the selection. @foreach (var item in options) { @item diff --git a/SimpleBlazorMultiselectDemo/Components/Pages/FilteredDropdown.razor b/src/SimpleBlazorMultiselect.Demo/Pages/FilteredDropdown.razor similarity index 100% rename from SimpleBlazorMultiselectDemo/Components/Pages/FilteredDropdown.razor rename to src/SimpleBlazorMultiselect.Demo/Pages/FilteredDropdown.razor diff --git a/SimpleBlazorMultiselectDemo/Components/Pages/Home.razor b/src/SimpleBlazorMultiselect.Demo/Pages/Home.razor similarity index 100% rename from SimpleBlazorMultiselectDemo/Components/Pages/Home.razor rename to src/SimpleBlazorMultiselect.Demo/Pages/Home.razor diff --git a/src/SimpleBlazorMultiselect.Demo/Pages/MultipleDropdowns.razor b/src/SimpleBlazorMultiselect.Demo/Pages/MultipleDropdowns.razor new file mode 100644 index 0000000..71421bc --- /dev/null +++ b/src/SimpleBlazorMultiselect.Demo/Pages/MultipleDropdowns.razor @@ -0,0 +1,16 @@ +@page "/MultipleDropdowns" +

MultipleDropdowns

+ +
+ @foreach(var _ in Enumerable.Range(0, 9)) + { +
+ +
+ } +
+ +@code { + private const string Classes = "col-4 mb-4"; + private readonly List _items = new() { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", "Item 9", "Item 10" }; +} \ No newline at end of file diff --git a/SimpleBlazorMultiselectDemo/Components/Pages/SingleSelect.razor b/src/SimpleBlazorMultiselect.Demo/Pages/SingleSelect.razor similarity index 100% rename from SimpleBlazorMultiselectDemo/Components/Pages/SingleSelect.razor rename to src/SimpleBlazorMultiselect.Demo/Pages/SingleSelect.razor diff --git a/src/SimpleBlazorMultiselect.Demo/Program.cs b/src/SimpleBlazorMultiselect.Demo/Program.cs new file mode 100644 index 0000000..5415f6c --- /dev/null +++ b/src/SimpleBlazorMultiselect.Demo/Program.cs @@ -0,0 +1,14 @@ +using System; +using System.Net.Http; +using Microsoft.AspNetCore.Components.Web; +using Microsoft.AspNetCore.Components.WebAssembly.Hosting; +using Microsoft.Extensions.DependencyInjection; +using SimpleBlazorMultiselect.Demo; + +var builder = WebAssemblyHostBuilder.CreateDefault(args); +builder.RootComponents.Add("#app"); +builder.RootComponents.Add("head::after"); + +builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); + +await builder.Build().RunAsync(); \ No newline at end of file diff --git a/src/SimpleBlazorMultiselect.Demo/Properties/launchSettings.json b/src/SimpleBlazorMultiselect.Demo/Properties/launchSettings.json new file mode 100644 index 0000000..a8dc3c2 --- /dev/null +++ b/src/SimpleBlazorMultiselect.Demo/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:62962", + "sslPort": 44329 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", + "applicationUrl": "http://localhost:5106", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", + "applicationUrl": "https://localhost:7019;http://localhost:5106", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/SimpleBlazorMultiselectDemo/SimpleBlazorMultiselectDemo.csproj b/src/SimpleBlazorMultiselect.Demo/SimpleBlazorMultiselect.Demo.csproj similarity index 50% rename from SimpleBlazorMultiselectDemo/SimpleBlazorMultiselectDemo.csproj rename to src/SimpleBlazorMultiselect.Demo/SimpleBlazorMultiselect.Demo.csproj index c8d1870..1f6d5a8 100644 --- a/SimpleBlazorMultiselectDemo/SimpleBlazorMultiselectDemo.csproj +++ b/src/SimpleBlazorMultiselect.Demo/SimpleBlazorMultiselect.Demo.csproj @@ -1,4 +1,4 @@ - + net8.0 @@ -7,7 +7,11 @@ - + + + + + diff --git a/SimpleBlazorMultiselectDemo/Components/_Imports.razor b/src/SimpleBlazorMultiselect.Demo/_Imports.razor similarity index 61% rename from SimpleBlazorMultiselectDemo/Components/_Imports.razor rename to src/SimpleBlazorMultiselect.Demo/_Imports.razor index bec5154..772c458 100644 --- a/SimpleBlazorMultiselectDemo/Components/_Imports.razor +++ b/src/SimpleBlazorMultiselect.Demo/_Imports.razor @@ -3,9 +3,8 @@ @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web -@using static Microsoft.AspNetCore.Components.Web.RenderMode @using Microsoft.AspNetCore.Components.Web.Virtualization +@using Microsoft.AspNetCore.Components.WebAssembly.Http @using Microsoft.JSInterop -@using SimpleBlazorMultiselectDemo -@using SimpleBlazorMultiselectDemo.Components -@using SimpleBlazorMultiselect; \ No newline at end of file +@using SimpleBlazorMultiselect.Demo +@using SimpleBlazorMultiselect.Demo.Layout \ No newline at end of file diff --git a/SimpleBlazorMultiselectDemo/wwwroot/app.css b/src/SimpleBlazorMultiselect.Demo/wwwroot/css/app.css similarity index 65% rename from SimpleBlazorMultiselectDemo/wwwroot/app.css rename to src/SimpleBlazorMultiselect.Demo/wwwroot/css/app.css index 2bd9b78..54a8aa3 100644 --- a/SimpleBlazorMultiselectDemo/wwwroot/app.css +++ b/src/SimpleBlazorMultiselect.Demo/wwwroot/css/app.css @@ -2,8 +2,12 @@ html, body { font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; } +h1:focus { + outline: none; +} + a, .btn-link { - color: #006bb7; + color: #0071c1; } .btn-primary { @@ -20,22 +24,37 @@ a, .btn-link { padding-top: 1.1rem; } -h1:focus { - outline: none; -} - .valid.modified:not([type=checkbox]) { outline: 1px solid #26b050; } .invalid { - outline: 1px solid #e50000; + outline: 1px solid red; } .validation-message { - color: #e50000; + color: red; } +#blazor-error-ui { + background: lightyellow; + bottom: 0; + box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); + display: none; + left: 0; + padding: 0.6rem 1.25rem 0.7rem 1.25rem; + position: fixed; + width: 100%; + z-index: 1000; +} + + #blazor-error-ui .dismiss { + cursor: pointer; + position: absolute; + right: 0.75rem; + top: 0.5rem; + } + .blazor-error-boundary { background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121; padding: 1rem 1rem 1rem 3.7rem; @@ -46,6 +65,39 @@ h1:focus { content: "An error has occurred." } -.darker-border-checkbox.form-check-input { - border-color: #929292; +.loading-progress { + position: relative; + display: block; + width: 8rem; + height: 8rem; + margin: 20vh auto 1rem auto; +} + + .loading-progress circle { + fill: none; + stroke: #e0e0e0; + stroke-width: 0.6rem; + transform-origin: 50% 50%; + transform: rotate(-90deg); + } + + .loading-progress circle:last-child { + stroke: #1b6ec2; + stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%; + transition: stroke-dasharray 0.05s ease-in-out; + } + +.loading-progress-text { + position: absolute; + text-align: center; + font-weight: bold; + inset: calc(20vh + 3.25rem) 0 auto 0.2rem; +} + + .loading-progress-text:after { + content: var(--blazor-load-percentage-text, "Loading"); + } + +code { + color: #c02d76; } diff --git a/SimpleBlazorMultiselectDemo/wwwroot/bootstrap/bootstrap.min.css b/src/SimpleBlazorMultiselect.Demo/wwwroot/css/bootstrap/bootstrap.min.css similarity index 100% rename from SimpleBlazorMultiselectDemo/wwwroot/bootstrap/bootstrap.min.css rename to src/SimpleBlazorMultiselect.Demo/wwwroot/css/bootstrap/bootstrap.min.css diff --git a/SimpleBlazorMultiselectDemo/wwwroot/bootstrap/bootstrap.min.css.map b/src/SimpleBlazorMultiselect.Demo/wwwroot/css/bootstrap/bootstrap.min.css.map similarity index 100% rename from SimpleBlazorMultiselectDemo/wwwroot/bootstrap/bootstrap.min.css.map rename to src/SimpleBlazorMultiselect.Demo/wwwroot/css/bootstrap/bootstrap.min.css.map diff --git a/SimpleBlazorMultiselectDemo/wwwroot/favicon.png b/src/SimpleBlazorMultiselect.Demo/wwwroot/favicon.png similarity index 100% rename from SimpleBlazorMultiselectDemo/wwwroot/favicon.png rename to src/SimpleBlazorMultiselect.Demo/wwwroot/favicon.png diff --git a/src/SimpleBlazorMultiselect.Demo/wwwroot/icon-192.png b/src/SimpleBlazorMultiselect.Demo/wwwroot/icon-192.png new file mode 100644 index 0000000..166f56d Binary files /dev/null and b/src/SimpleBlazorMultiselect.Demo/wwwroot/icon-192.png differ diff --git a/src/SimpleBlazorMultiselect.Demo/wwwroot/index.html b/src/SimpleBlazorMultiselect.Demo/wwwroot/index.html new file mode 100644 index 0000000..8aaf231 --- /dev/null +++ b/src/SimpleBlazorMultiselect.Demo/wwwroot/index.html @@ -0,0 +1,34 @@ + + + + + + + SimpleBlazorMultiselect.Demo + + + + + + + + + + +
+ + + + +
+
+ +
+ An unhandled error has occurred. + Reload + 🗙 +
+ + + + diff --git a/src/SimpleBlazorMultiselect.Demo/wwwroot/sample-data/weather.json b/src/SimpleBlazorMultiselect.Demo/wwwroot/sample-data/weather.json new file mode 100644 index 0000000..b745973 --- /dev/null +++ b/src/SimpleBlazorMultiselect.Demo/wwwroot/sample-data/weather.json @@ -0,0 +1,27 @@ +[ + { + "date": "2022-01-06", + "temperatureC": 1, + "summary": "Freezing" + }, + { + "date": "2022-01-07", + "temperatureC": 14, + "summary": "Bracing" + }, + { + "date": "2022-01-08", + "temperatureC": -13, + "summary": "Freezing" + }, + { + "date": "2022-01-09", + "temperatureC": -16, + "summary": "Balmy" + }, + { + "date": "2022-01-10", + "temperatureC": -2, + "summary": "Chilly" + } +] diff --git a/SimpleBlazorMultiselect/SimpleBlazorMultiselect.csproj b/src/SimpleBlazorMultiselect/SimpleBlazorMultiselect.csproj similarity index 91% rename from SimpleBlazorMultiselect/SimpleBlazorMultiselect.csproj rename to src/SimpleBlazorMultiselect/SimpleBlazorMultiselect.csproj index 0787f30..b241678 100644 --- a/SimpleBlazorMultiselect/SimpleBlazorMultiselect.csproj +++ b/src/SimpleBlazorMultiselect/SimpleBlazorMultiselect.csproj @@ -1,6 +1,6 @@ - net6.0;net7.0;net8.0 + net8.0;net6.0;net7.0; enable enable true @@ -26,11 +26,11 @@
- + True \ - + True \ diff --git a/SimpleBlazorMultiselect/SimpleMultiselect.razor b/src/SimpleBlazorMultiselect/SimpleMultiselect.razor similarity index 92% rename from SimpleBlazorMultiselect/SimpleMultiselect.razor rename to src/SimpleBlazorMultiselect/SimpleMultiselect.razor index d0c3476..4ce17c4 100644 --- a/SimpleBlazorMultiselect/SimpleMultiselect.razor +++ b/src/SimpleBlazorMultiselect/SimpleMultiselect.razor @@ -3,8 +3,8 @@ @inject IJSRuntime JsRuntime @typeparam TItem -
-